diff --git a/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_Output_cff.py b/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_Output_cff.py index 5c2b81e68b6a5..3ed7add1c59b7 100644 --- a/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_Output_cff.py +++ b/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_Output_cff.py @@ -6,14 +6,17 @@ OutALCARECOTkAlCosmics0T_noDrop = cms.PSet( SelectEvents = cms.untracked.PSet( SelectEvents = cms.vstring('pathALCARECOTkAlCosmicsCTF0T', - 'pathALCARECOTkAlCosmicsCosmicTF0T', - 'pathALCARECOTkAlCosmicsRegional0T') + 'pathALCARECOTkAlCosmicsCosmicTF0T', + 'pathALCARECOTkAlCosmicsRegional0T', + 'pathALCARECOTkAlCosmicsDuringCollisions0T' + ) ), outputCommands = cms.untracked.vstring( #'keep *_ALCARECOTkAlCosmics*0T_*_*', 'keep *_ALCARECOTkAlCosmicsCTF0T_*_*', 'keep *_ALCARECOTkAlCosmicsCosmicTF0T_*_*', 'keep *_ALCARECOTkAlCosmicsRegional0T_*_*', + 'keep *_ALCARECOTkAlCosmicsDuringCollisions0T_*_*', 'keep siStripDigis_DetIdCollection_*_*', 'keep L1AcceptBunchCrossings_*_*_*', 'keep L1GlobalTriggerReadoutRecord_gtDigis_*_*', diff --git a/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_cff.py b/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_cff.py index 9988df3909c63..2519602d28c7a 100644 --- a/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_cff.py +++ b/Alignment/CommonAlignmentProducer/python/ALCARECOTkAlCosmics0T_cff.py @@ -46,7 +46,14 @@ src = 'regionalCosmicTracks' ) +# AlCaReco for track based alignment using Cosmic muons reconstructed by Cosmics During Collisions Algorithm +# (same cuts) +ALCARECOTkAlCosmicsDuringCollisions0T = ALCARECOTkAlCosmicsCTF0T.clone( + src = 'cosmicDCTracks' + ) + #________________________________Sequences____________________________________ seqALCARECOTkAlCosmicsCTF0T = cms.Sequence(ALCARECOTkAlCosmicsCTF0T) seqALCARECOTkAlCosmicsCosmicTF0T = cms.Sequence(ALCARECOTkAlCosmicsCosmicTF0T) seqALCARECOTkAlCosmicsRegional0T = cms.Sequence(ALCARECOTkAlCosmicsRegional0T) +seqALCARECOTkAlCosmicsDuringCollisions0T = cms.Sequence(ALCARECOTkAlCosmicsDuringCollisions0T) diff --git a/Alignment/MillePedeAlignmentAlgorithm/scripts/mps_fire.py b/Alignment/MillePedeAlignmentAlgorithm/scripts/mps_fire.py index 1b68b781dd61f..379d2d1db67ee 100755 --- a/Alignment/MillePedeAlignmentAlgorithm/scripts/mps_fire.py +++ b/Alignment/MillePedeAlignmentAlgorithm/scripts/mps_fire.py @@ -264,6 +264,15 @@ def write_HTCondor_submit_file_mille(path, script, lib, proxy_path=None): resources = '-q'+resources+' -m g_cmscaf' elif "htcondor" in resources: fire_htcondor = True + schedinfo = subprocess.check_output(["myschedd","show"]) + if 'cafalca' in resources: + if not 'tzero' in schedinfo: + print("\nMPS fire: request to use CAF pool which has not been set up. Call `module load lxbatch/tzero` and try again") + exit(1) + else: + if not 'share' in schedinfo: + print("\nMPS fire: request to use standard pool when CAF pool is set up. Call `module load lxbatch/share` and try again") + exit(1) else: resources = '-q '+resources @@ -322,6 +331,11 @@ def write_HTCondor_submit_file_mille(path, script, lib, proxy_path=None): resources = '-q cmscafalcamille' elif "htcondor" in resources: fire_htcondor = True + schedinfo = subprocess.check_output(["myschedd","show"]) + if 'bigmem' in resources: + if not 'share' in schedinfo: + print("\nMPS fire: CAF pool is set up, but request to use high-memory machines which live in the standard pool. Call `module load lxbatch/share` and try again") + exit(1) else: resources = '-q '+resources diff --git a/Alignment/OfflineValidation/python/TkAlAllInOneTool/helperFunctions.py b/Alignment/OfflineValidation/python/TkAlAllInOneTool/helperFunctions.py index 6e0bea068dc08..1953c0d4c76c5 100644 --- a/Alignment/OfflineValidation/python/TkAlAllInOneTool/helperFunctions.py +++ b/Alignment/OfflineValidation/python/TkAlAllInOneTool/helperFunctions.py @@ -202,9 +202,12 @@ def getTagsMap(db): con = conddblib.connect(url = conddblib.make_url(db)) session = con.session() TAG = session.get_dbtype(conddblib.Tag) - q1 = session.query(TAG.object_type).order_by(TAG.name).all()[0] - q2 = session.query(TAG.name).order_by(TAG.name).all()[0] - dictionary = dict(zip(q1, q2)) + dictionary = {} + for i in range(0,len(session.query(TAG.object_type).order_by(TAG.name).all())): + q1 = session.query(TAG.object_type).order_by(TAG.name).all()[i][0] + q2 = session.query(TAG.name).order_by(TAG.name).all()[i][0] + dictionary[q1]=q2 + return dictionary def clean_name(s): diff --git a/Alignment/OfflineValidation/scripts/validateAlignments.py b/Alignment/OfflineValidation/scripts/validateAlignments.py index 8d5d64427b5c4..e38967e67e388 100755 --- a/Alignment/OfflineValidation/scripts/validateAlignments.py +++ b/Alignment/OfflineValidation/scripts/validateAlignments.py @@ -646,6 +646,13 @@ def main(argv = None): (options, args) = optParser.parse_args(argv) + if not options.dryRun: + schedinfo = subprocess.check_output(["myschedd","show"]) + if not 'tzero' in schedinfo: + print("\nAll-In-One Tool: you need to call `module load lxbatch/tzero` before trying to submit jobs. Please do so and try again") + exit(1) + + if not options.restrictTo == None: options.restrictTo = options.restrictTo.split(",") diff --git a/Alignment/OfflineValidation/test/test_all.sh b/Alignment/OfflineValidation/test/test_all.sh index 7a70bc72962a6..ed9a27885be61 100755 --- a/Alignment/OfflineValidation/test/test_all.sh +++ b/Alignment/OfflineValidation/test/test_all.sh @@ -12,6 +12,7 @@ fi ## copy into local sqlite file the ideal alignment echo "COPYING locally Ideal Alignment ..." conddb --yes --db pro copy TrackerAlignment_Upgrade2017_design_v4 --destdb myfile.db +conddb --yes --db pro copy TrackerAlignmentErrorsExtended_Upgrade2017_design_v0 --destdb myfile.db echo "GENERATING all-in-one tool configuration ..." cat <> validation_config.ini @@ -29,6 +30,7 @@ style = 2001 title = express globaltag = 92X_dataRun2_Express_v2 condition TrackerAlignmentRcd = sqlite_file:myfile.db,TrackerAlignment_Upgrade2017_design_v4 +condition TrackerAlignmentErrorExtendedRcd = sqlite_file:myfile.db,TrackerAlignmentErrorsExtended_Upgrade2017_design_v0 color = 2 style = 2402 diff --git a/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h b/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h index f9540d85a3981..0efca1cb3ad6d 100644 --- a/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h +++ b/CalibCalorimetry/HcalAlgos/interface/HcalPulseShapes.h @@ -106,8 +106,9 @@ class HcalPulseShapes { const HcalPulseShape& computeSiPMShapeHE206(); void computeSiPMShapeData2017(); void computeSiPMShapeData2018(); + void computeSiPMShapeMCRecoRun3(); Shape hpdShape_, hfShape_, siPMShapeHO_; - Shape siPMShapeData2017_, siPMShapeData2018_; + Shape siPMShapeData2017_, siPMShapeData2018_, siPMShapeMCRecoRun3_; Shape hpdShape_v2, hpdShapeMC_v2; Shape hpdShape_v3, hpdShapeMC_v3; Shape hpdBV30Shape_v2, hpdBV30ShapeMC_v2; diff --git a/CalibCalorimetry/HcalAlgos/src/HcalPulseShapes.cc b/CalibCalorimetry/HcalAlgos/src/HcalPulseShapes.cc index c03d7578502d0..79c23c43a0198 100644 --- a/CalibCalorimetry/HcalAlgos/src/HcalPulseShapes.cc +++ b/CalibCalorimetry/HcalAlgos/src/HcalPulseShapes.cc @@ -27,6 +27,7 @@ Reco MC 202 202 =201, SiPMs Hamamatsu shape (HO) 205 203 siPMShapeData2017_,siPMShapeMC2017_ SiPMs from Data, Hamamatsu shape (HE 2017) 207 206 siPMShapeData2018_,siPMShapeMC2018_ SiPMs from Data, Hamamatsu shape (HE 2018) +207 208 siPMShapeData2018_,siPMShapeMCRecoRun3_ SiPMs from Data, 2021 MC phase scan 301 301 hfShape_ regular HF PMT shape 401 401 regular ZDC shape ------------------------------------------------------------------------------------------- @@ -124,6 +125,7 @@ Reco MC computeSiPMShapeHO(); computeSiPMShapeData2017(); computeSiPMShapeData2018(); + computeSiPMShapeMCRecoRun3(); theShapes[201] = &siPMShapeHO_; theShapes[202] = theShapes[201]; @@ -131,6 +133,7 @@ Reco MC theShapes[205] = &siPMShapeData2017_; theShapes[206] = &(computeSiPMShapeHE206()); theShapes[207] = &siPMShapeData2018_; + theShapes[208] = &siPMShapeMCRecoRun3_; theShapes[301] = &hfShape_; //theShapes[401] = new CaloCachedShapeIntegrator(&theZDCShape); } @@ -271,6 +274,56 @@ void HcalPulseShapes::computeHFShape() { hfShape_.setShapeBin(j, ntmp[j]); } } +void HcalPulseShapes::computeSiPMShapeMCRecoRun3() { + //modified shape 206 + //7.2 ns shift in 206 + unsigned int nbin = 250; + std::array nt{ + {0, 0, 0, 0, 0, 0, 0, 0.000117468, + 0.0031549, 0.0117368, 0.0219974, 0.0305776, 0.0365429, 0.0400524, 0.0415915, 0.0416765, + 0.0408111, 0.0394627, 0.0379353, 0.0363688, 0.0348152, 0.0332891, 0.0317923, 0.0303237, + 0.028883, 0.0274714, 0.0260914, 0.0247462, 0.0234392, 0.0221738, 0.0209531, 0.0197793, + 0.0186544, 0.0175796, 0.0165556, 0.0155823, 0.0146596, 0.0137866, 0.0129623, 0.0121853, + 0.0114539, 0.0107665, 0.0101213, 0.0095162, 0.00894934, 0.00841873, 0.0079224, 0.00745841, + 0.00702487, 0.00661995, 0.00624189, 0.00588898, 0.00555961, 0.00525223, 0.00496539, 0.0046977, + 0.00444786, 0.00421464, 0.00399689, 0.00379353, 0.00360355, 0.00342602, 0.00326004, 0.0031048, + 0.00295954, 0.00282355, 0.00269616, 0.00257676, 0.00246479, 0.00235972, 0.00226106, 0.00216834, + 0.00208117, 0.00199914, 0.00192189, 0.0018491, 0.00178044, 0.00171565, 0.00165445, 0.00159659, + 0.00154186, 0.00149003, 0.00144092, 0.00139435, 0.00135015, 0.00130816, 0.00126825, 0.00123027, + 0.00119412, 0.00115966, 0.0011268, 0.00109544, 0.00106548, 0.00103685, 0.00100946, 0.000983242, + 0.000958125, 0.000934047, 0.000910949, 0.000888775, 0.000867475, 0.000847, 0.000827306, 0.000808352, + 0.000790097, 0.000772506, 0.000755545, 0.000739182, 0.000723387, 0.000708132, 0.00069339, 0.000679138, + 0.000665352, 0.00065201, 0.000639091, 0.000626577, 0.00061445, 0.000602692, 0.000591287, 0.00058022, + 0.000569477, 0.000559044, 0.000548908, 0.000539058, 0.000529481, 0.000520167, 0.000511106, 0.000502288, + 0.000493704, 0.000485344, 0.000477201, 0.000469266, 0.000459912, 0.000448544, 0.000437961, 0.000428079, + 0.000418825, 0.000410133, 0.000401945, 0.00039421, 0.000386883, 0.000379924, 0.000373298, 0.000366973, + 0.000360922, 0.00035512, 0.000349545, 0.000344179, 0.000339003, 0.000334002, 0.000329163, 0.000324475, + 0.000319925, 0.000315504, 0.000311204, 0.000307017, 0.000302935, 0.000298954, 0.000295066, 0.000291267, + 0.000287553, 0.000283919, 0.000280361, 0.000276877, 0.000273462, 0.000270114, 0.000266831, 0.000263609, + 0.000260447, 0.000257343, 0.000254295, 0.0002513, 0.000248358, 0.000245467, 0.000242625, 0.000239831, + 0.000237083, 0.000234381, 0.000231723, 0.000229109, 0.000226536, 0.000224005, 0.000221514, 0.000219062, + 0.000216648, 0.000214272, 0.000211933, 0.00020963, 0.000207362, 0.000205129, 0.000202929, 0.000200763, + 0.000198629, 0.000196526, 0.000194455, 0.000192415, 0.000190405, 0.000188424, 0.000186472, 0.000184548, + 0.000182653, 0.000180784, 0.000178943, 0.000177127, 0.000175338, 0.000173574, 0.000171835, 0.00017012, + 0.000168429, 0.000166762, 0.000165119, 0.000163498, 0.000161899, 0.000160322, 0.000158767, 0.000157233, + 0.000155721, 0.000154228, 0.000152756, 0.000151304, 0.000149871, 0.000148457, 0.000147062, 0.000145686, + 0.000144327, 0.000142987, 0.000141664, 0.000140359, 0.000139071, 0.000137799, 0.000136544, 0.000135305, + 0.000134082, 0.000132874, 0.000131682, 0.000130505, 0.000129344, 0.000128196, 0.000127064, 0.000125945, + 0.00012484, 0.00012375, 0.000122672, 0.000121608, 0.000120558, 0.00011952, 0.000118495, 0.000117482, + 0.000116482, 0.000115493}}; + + siPMShapeMCRecoRun3_.setNBin(nbin); + + double norm = 0.; + for (unsigned int j = 0; j < nbin; ++j) { + norm += (nt[j] > 0) ? nt[j] : 0.; + } + + for (unsigned int j = 0; j < nbin; ++j) { + nt[j] /= norm; + siPMShapeMCRecoRun3_.setShapeBin(j, nt[j]); + } +} void HcalPulseShapes::computeSiPMShapeData2018() { //Combination of all phase scan data (May,Jul,Oct2017) diff --git a/CommonTools/PileupAlgos/interface/PuppiAlgo.h b/CommonTools/PileupAlgos/interface/PuppiAlgo.h index e2d43be36ba62..8e484994e29a3 100644 --- a/CommonTools/PileupAlgos/interface/PuppiAlgo.h +++ b/CommonTools/PileupAlgos/interface/PuppiAlgo.h @@ -35,6 +35,8 @@ class PuppiAlgo { inline double rms() const { return cur_RMS; } inline double median() const { return cur_Med; } + inline double etaMaxExtrap() const { return fEtaMaxExtrap; } + private: unsigned int fNAlgos; std::vector fEtaMax; diff --git a/CommonTools/PileupAlgos/interface/PuppiCandidate.h b/CommonTools/PileupAlgos/interface/PuppiCandidate.h index 552cbe2f16320..2e99bbd9d3772 100644 --- a/CommonTools/PileupAlgos/interface/PuppiCandidate.h +++ b/CommonTools/PileupAlgos/interface/PuppiCandidate.h @@ -1,29 +1,13 @@ -#ifndef CommonTools_PileupAlgos_PuppiCandidate -#define CommonTools_PileupAlgos_PuppiCandidate - -#include "fastjet/PseudoJet.hh" - -// Extension of fastjet::PseudoJet that caches eta and some other info -// Puppi uses register to decide between NHs, PV CHs, and PU CHs. -class PuppiCandidate : public fastjet::PseudoJet { -public: - using fastjet::PseudoJet::PseudoJet; - double pseudorapidity() const { - _ensure_valid_eta(); - return _eta; - } - double eta() const { return pseudorapidity(); } - void _ensure_valid_eta() const { - if (_eta == fastjet::pseudojet_invalid_rap) - _eta = fastjet::PseudoJet::pseudorapidity(); - } - void set_info(int puppi_register) { _puppi_register = puppi_register; } - inline int puppi_register() const { return _puppi_register; } - -private: - // variable names in fastjet style - mutable double _eta = fastjet::pseudojet_invalid_rap; - int _puppi_register; +#ifndef CommonTools_PileupAlgos_PuppiCandidate_h +#define CommonTools_PileupAlgos_PuppiCandidate_h + +struct PuppiCandidate { + double pt{0}; + double eta{0}; + double phi{0}; + double m{0}; + double rapidity{0}; + int id{0}; }; #endif diff --git a/CommonTools/PileupAlgos/interface/PuppiContainer.h b/CommonTools/PileupAlgos/interface/PuppiContainer.h index ecdee774e294b..d28d7a06db3b6 100644 --- a/CommonTools/PileupAlgos/interface/PuppiContainer.h +++ b/CommonTools/PileupAlgos/interface/PuppiContainer.h @@ -2,8 +2,8 @@ #define COMMONTOOLS_PUPPI_PUPPICONTAINER_H_ #include "CommonTools/PileupAlgos/interface/PuppiAlgo.h" -#include "CommonTools/PileupAlgos/interface/RecoObj.h" #include "CommonTools/PileupAlgos/interface/PuppiCandidate.h" +#include "CommonTools/PileupAlgos/interface/RecoObj.h" class PuppiContainer { public: @@ -13,7 +13,6 @@ class PuppiContainer { void setNPV(int iNPV) { fNPV = iNPV; } std::vector const &pfParticles() const { return fPFParticles; } - std::vector const &pvParticles() const { return fChargedPV; } std::vector const &puppiWeights(); const std::vector &puppiRawAlphas() { return fRawAlphas; } const std::vector &puppiAlphas() { return fVals; } @@ -43,7 +42,8 @@ class PuppiContainer { bool fPuppiDiagnostics; const std::vector *fRecoParticles; std::vector fPFParticles; - std::vector fChargedPV; + std::vector fPFParticlesForVar; + std::vector fPFParticlesForVarChargedPV; std::vector fWeights; std::vector fVals; std::vector fRawAlphas; @@ -62,7 +62,6 @@ class PuppiContainer { double fPtMaxNeutralsStartSlope; int fNAlgos; int fNPV; - double fPVFrac; std::vector fPuppiAlgo; }; #endif diff --git a/CommonTools/PileupAlgos/plugins/PuppiProducer.cc b/CommonTools/PileupAlgos/plugins/PuppiProducer.cc index 750b4983a3369..444d390de1166 100644 --- a/CommonTools/PileupAlgos/plugins/PuppiProducer.cc +++ b/CommonTools/PileupAlgos/plugins/PuppiProducer.cc @@ -18,7 +18,6 @@ #include "DataFormats/Common/interface/Association.h" //Main File #include "CommonTools/PileupAlgos/plugins/PuppiProducer.h" -#include "CommonTools/PileupAlgos/interface/PuppiCandidate.h" // ------------------------------------------------------------------------------------------ PuppiProducer::PuppiProducer(const edm::ParameterSet& iConfig) { @@ -32,6 +31,8 @@ PuppiProducer::PuppiProducer(const edm::ParameterSet& iConfig) { fEtaMaxCharged = iConfig.getParameter("EtaMaxCharged"); fPtMaxPhotons = iConfig.getParameter("PtMaxPhotons"); fEtaMaxPhotons = iConfig.getParameter("EtaMaxPhotons"); + fNumOfPUVtxsForCharged = iConfig.getParameter("NumOfPUVtxsForCharged"); + fDZCutForChargedFromPUVtxs = iConfig.getParameter("DeltaZCutForChargedFromPUVtxs"); fUseExistingWeights = iConfig.getParameter("useExistingWeights"); fClonePackedCands = iConfig.getParameter("clonePackedCands"); fVtxNdofCut = iConfig.getParameter("vtxNdofCut"); @@ -97,8 +98,7 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { const reco::Vertex* closestVtx = nullptr; double pDZ = -9999; double pD0 = -9999; - int pVtxId = -9999; - bool lFirst = true; + uint pVtxId = 0; bool isLepton = ((std::abs(pReco.pdgId) == 11) || (std::abs(pReco.pdgId) == 13)); const pat::PackedCandidate* lPack = dynamic_cast(&aPF); if (lPack == nullptr) { @@ -106,6 +106,7 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { double curdz = 9999; int closestVtxForUnassociateds = -9999; const reco::TrackRef aTrackRef = pPF->trackRef(); + bool lFirst = true; for (auto const& aV : *pvCol) { if (lFirst) { if (aTrackRef.isNonnull()) { @@ -157,10 +158,12 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { pReco.id = 3; else if (tmpFromPV == 0) { pReco.id = 2; - } // 0 is associated to PU vertex - else if (tmpFromPV == 3) { + if (fNumOfPUVtxsForCharged > 0 and (pVtxId <= fNumOfPUVtxsForCharged) and + (std::abs(pDZ) < fDZCutForChargedFromPUVtxs)) + pReco.id = 1; + } else if (tmpFromPV == 3) pReco.id = 1; - } else if (tmpFromPV == 1 || tmpFromPV == 2) { + else if (tmpFromPV == 1 || tmpFromPV == 2) { pReco.id = 0; if ((fPtMaxCharged > 0) and (pReco.pt > fPtMaxCharged)) pReco.id = 1; @@ -185,12 +188,20 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { pReco.id = 0; } if (std::abs(pReco.charge) > 0) { - if (fPuppiNoLep && isLepton) + if (fPuppiNoLep && isLepton) { pReco.id = 3; - else if (lPack->fromPV() == 0) { + } else if (lPack->fromPV() == 0) { pReco.id = 2; - } // 0 is associated to PU vertex - else if (lPack->fromPV() == (pat::PackedCandidate::PVUsedInFit)) { + if ((fNumOfPUVtxsForCharged > 0) and (std::abs(pDZ) < fDZCutForChargedFromPUVtxs)) { + for (size_t puVtx_idx = 1; puVtx_idx <= fNumOfPUVtxsForCharged && puVtx_idx < pvCol->size(); + ++puVtx_idx) { + if (lPack->fromPV(puVtx_idx) >= 2) { + pReco.id = 1; + break; + } + } + } + } else if (lPack->fromPV() == (pat::PackedCandidate::PVUsedInFit)) { pReco.id = 1; } else if (lPack->fromPV() == (pat::PackedCandidate::PVTight) || lPack->fromPV() == (pat::PackedCandidate::PVLoose)) { @@ -373,6 +384,8 @@ void PuppiProducer::fillDescriptions(edm::ConfigurationDescriptions& description desc.add("EtaMaxPhotons", 2.5); desc.add("PtMaxNeutrals", 200.); desc.add("PtMaxNeutralsStartSlope", 0.); + desc.add("NumOfPUVtxsForCharged", 0); + desc.add("DeltaZCutForChargedFromPUVtxs", 0.2); desc.add("useExistingWeights", false); desc.add("clonePackedCands", false); desc.add("vtxNdofCut", 4); diff --git a/CommonTools/PileupAlgos/plugins/PuppiProducer.h b/CommonTools/PileupAlgos/plugins/PuppiProducer.h index 9447db575ed23..7fcd3d9d54644 100644 --- a/CommonTools/PileupAlgos/plugins/PuppiProducer.h +++ b/CommonTools/PileupAlgos/plugins/PuppiProducer.h @@ -68,6 +68,8 @@ class PuppiProducer : public edm::stream::EDProducer<> { double fEtaMaxCharged; double fPtMaxPhotons; double fEtaMaxPhotons; + uint fNumOfPUVtxsForCharged; + double fDZCutForChargedFromPUVtxs; bool fUseExistingWeights; bool fClonePackedCands; int fVtxNdofCut; diff --git a/CommonTools/PileupAlgos/python/Puppi_cff.py b/CommonTools/PileupAlgos/python/Puppi_cff.py index 023ca7f9366cf..1fca1e4c96def 100644 --- a/CommonTools/PileupAlgos/python/Puppi_cff.py +++ b/CommonTools/PileupAlgos/python/Puppi_cff.py @@ -31,6 +31,8 @@ UseDeltaZCut = cms.bool(True), EtaMinUseDeltaZ = cms.double(2.4), DeltaZCut = cms.double(0.3), + NumOfPUVtxsForCharged = cms.uint32(0), + DeltaZCutForChargedFromPUVtxs = cms.double(0.2), PtMaxCharged = cms.double(20.), EtaMaxCharged = cms.double(99999.), PtMaxPhotons = cms.double(-1.), diff --git a/CommonTools/PileupAlgos/python/customizePuppiTune_cff.py b/CommonTools/PileupAlgos/python/customizePuppiTune_cff.py index 4b0addbfa7048..edb4249e884a4 100644 --- a/CommonTools/PileupAlgos/python/customizePuppiTune_cff.py +++ b/CommonTools/PileupAlgos/python/customizePuppiTune_cff.py @@ -1,10 +1,10 @@ import FWCore.ParameterSet.Config as cms -def UpdatePuppiTuneV14(process): +def UpdatePuppiTuneV15(process, runOnMC=True): # # Adapt for re-running PUPPI # - print("customizePuppiTune_cff::UpdatePuppiTuneV14: Recomputing PUPPI with Tune v14, slimmedJetsPuppi and slimmedMETsPuppi") + print("customizePuppiTune_cff::UpdatePuppiTuneV15: Recomputing PUPPI with Tune v15, slimmedJetsPuppi and slimmedMETsPuppi") from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask, addToProcessAndTask task = getPatAlgosToolsTask(process) from PhysicsTools.PatAlgos.slimming.puppiForMET_cff import makePuppiesFromMiniAOD @@ -26,11 +26,25 @@ def UpdatePuppiTuneV14(process): del process.updatedPatJetsPuppiJetSpecific process.puppiSequence = cms.Sequence(process.puppiMETSequence+process.fullPatMetSequencePuppi+process.patPuppiJetSpecificProducer+process.slimmedJetsPuppi) # - # Adapt for PUPPI tune V14 + # Adapt for PUPPI tune V15 # process.puppi.PtMaxCharged = 20. process.puppi.EtaMinUseDeltaZ = 2.4 process.puppi.PtMaxNeutralsStartSlope = 20. + process.puppi.NumOfPUVtxsForCharged = 2 + process.puppi.algos[0].etaMin[0] = -0.01 process.puppiNoLep.PtMaxCharged = 20. process.puppiNoLep.EtaMinUseDeltaZ = 2.4 process.puppiNoLep.PtMaxNeutralsStartSlope = 20. + process.puppiNoLep.NumOfPUVtxsForCharged = 2 + process.puppiNoLep.algos[0].etaMin[0] = -0.01 + + from Configuration.Eras.Modifier_phase2_common_cff import phase2_common + phase2_common.toModify( process.puppi, EtaMinUseDeltaZ = 4.0) + phase2_common.toModify( process.puppiNoLep, EtaMinUseDeltaZ = 4.0) + +def UpdatePuppiTuneV15_MC(process): + UpdatePuppiTuneV15(process,runOnMC=True) + +def UpdatePuppiTuneV15_Data(process): + UpdatePuppiTuneV15(process,runOnMC=False) diff --git a/CommonTools/PileupAlgos/src/PuppiAlgo.cc b/CommonTools/PileupAlgos/src/PuppiAlgo.cc index 3d3c482175c0e..d5a9f47e8cd20 100644 --- a/CommonTools/PileupAlgos/src/PuppiAlgo.cc +++ b/CommonTools/PileupAlgos/src/PuppiAlgo.cc @@ -85,24 +85,24 @@ void PuppiAlgo::fixAlgoEtaBin(int i_eta) { } void PuppiAlgo::add(const PuppiCandidate &iParticle, const double &iVal, const unsigned int iAlgo) { - if (iParticle.pt() < fRMSPtMin[iAlgo]) + if (iParticle.pt < fRMSPtMin[iAlgo]) return; // Change from SRR : Previously used fastjet::PseudoJet::user_index to decide the particle type. // In CMSSW we use the user_index to specify the index in the input collection, so I invented // a new mechanism using the fastjet UserInfo functionality. Of course, it's still just an integer // but that interface could be changed (or augmented) if desired / needed. - int puppi_id = iParticle.puppi_register(); + int puppi_id = iParticle.id; if (puppi_id == std::numeric_limits::lowest()) { throw cms::Exception("PuppiRegisterNotSet") << "The puppi register is not set. This must be set before use.\n"; } // added by Nhan -- for all eta regions, compute mean/RMS from the central charged PU - if ((std::abs(iParticle.eta()) < fEtaMaxExtrap) && (puppi_id == 2)) { + if ((std::abs(iParticle.eta) < fEtaMaxExtrap) && (puppi_id == 2)) { fPups.push_back(iVal); fNCount[iAlgo]++; } // for the low PU case, correction. for checking that the PU-only median will be below the PV particles - if (std::abs(iParticle.eta()) < fEtaMaxExtrap && (puppi_id == 1)) + if (std::abs(iParticle.eta) < fEtaMaxExtrap && (puppi_id == 1)) fPupsPV.push_back(iVal); } @@ -158,7 +158,6 @@ void PuppiAlgo::computeMedRMS(const unsigned int &iAlgo) { if (fAdjust[iAlgo]) { //Adjust the p-value to correspond to the median - std::sort(fPupsPV.begin(), fPupsPV.end()); int lNPV = 0; for (unsigned int i0 = 0; i0 < fPupsPV.size(); i0++) if (fPupsPV[i0] <= lMed) diff --git a/CommonTools/PileupAlgos/src/PuppiCandidate.cc b/CommonTools/PileupAlgos/src/PuppiCandidate.cc deleted file mode 100644 index 3bbe555cba83b..0000000000000 --- a/CommonTools/PileupAlgos/src/PuppiCandidate.cc +++ /dev/null @@ -1 +0,0 @@ -#include "CommonTools/PileupAlgos/interface/PuppiCandidate.h" diff --git a/CommonTools/PileupAlgos/src/PuppiContainer.cc b/CommonTools/PileupAlgos/src/PuppiContainer.cc index f64deda04e928..adef51c6d2805 100644 --- a/CommonTools/PileupAlgos/src/PuppiContainer.cc +++ b/CommonTools/PileupAlgos/src/PuppiContainer.cc @@ -7,6 +7,8 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/isFinite.h" +#include "fastjet/PseudoJet.hh" + using namespace std; PuppiContainer::PuppiContainer(const edm::ParameterSet &iConfig) { @@ -30,39 +32,49 @@ PuppiContainer::PuppiContainer(const edm::ParameterSet &iConfig) { void PuppiContainer::initialize(const std::vector &iRecoObjects) { //Clear everything fPFParticles.resize(0); - fChargedPV.resize(0); + fPFParticlesForVar.resize(0); + fPFParticlesForVarChargedPV.resize(0); fWeights.resize(0); fVals.resize(0); fRawAlphas.resize(0); fAlphaMed.resize(0); fAlphaRMS.resize(0); - //fChargedNoPV.resize(0); - //Link to the RecoObjects - fPVFrac = 0.; fNPV = 1.; + //Link to the RecoObjects fRecoParticles = &iRecoObjects; + fPFParticles.reserve(iRecoObjects.size()); + fPFParticlesForVar.reserve(iRecoObjects.size()); + fPFParticlesForVarChargedPV.reserve(iRecoObjects.size()); for (auto const &rParticle : *fRecoParticles) { - PuppiCandidate curPseudoJet; - // float nom = sqrt((rParticle.m)*(rParticle.m) + (rParticle.pt)*(rParticle.pt)*(cosh(rParticle.eta))*(cosh(rParticle.eta))) + (rParticle.pt)*sinh(rParticle.eta);//hacked - // float denom = sqrt((rParticle.m)*(rParticle.m) + (rParticle.pt)*(rParticle.pt));//hacked - // float rapidity = log(nom/denom);//hacked + fastjet::PseudoJet curPseudoJet; if (edm::isFinite(rParticle.rapidity)) { curPseudoJet.reset_PtYPhiM(rParticle.pt, rParticle.rapidity, rParticle.phi, rParticle.m); //hacked } else { curPseudoJet.reset_PtYPhiM(0, 99., 0, 0); //skipping may have been a better choice } - //curPseudoJet.reset_PtYPhiM(rParticle.pt,rParticle.eta,rParticle.phi,rParticle.m); - // fill puppi_register - curPseudoJet.set_info(rParticle.id); - // fill vector of pseudojets for internal references - fPFParticles.push_back(curPseudoJet); - //Take Charged particles associated to PV + PuppiCandidate pCand; + pCand.pt = curPseudoJet.pt(); + pCand.eta = curPseudoJet.eta(); + pCand.rapidity = curPseudoJet.rap(); + pCand.phi = curPseudoJet.phi(); + pCand.m = curPseudoJet.m(); + pCand.id = rParticle.id; + + fPFParticles.push_back(pCand); + + // skip candidates to be ignored in the computation + // of PUPPI's alphas (e.g. electrons and muons if puppiNoLep=True) + if (std::abs(rParticle.id) == 3) + continue; + + fPFParticlesForVar.push_back(pCand); + // charged candidates assigned to LV if (std::abs(rParticle.id) == 1) - fChargedPV.push_back(curPseudoJet); - //if(rParticle.id == 3) _chargedNoPV.push_back(curPseudoJet); + fPFParticlesForVarChargedPV.push_back(pCand); // if(fNPV < rParticle.vtxId) fNPV = rParticle.vtxId; } } + PuppiContainer::~PuppiContainer() {} double PuppiContainer::goodVar(PuppiCandidate const &iPart, @@ -77,70 +89,51 @@ double PuppiContainer::var_within_R(int iId, const PuppiCandidate ¢re, const double R) { if (iId == -1) - return 1; + return 1.; - //this is a circle in rapidity-phi - //it would make more sense to have var definition consistent - //fastjet::Selector sel = fastjet::SelectorCircle(R); - //sel.set_reference(centre); - //the original code used Selector infrastructure: it is too heavy here - //logic of SelectorCircle is preserved below + double const r2 = R * R; + double var = 0.; - vector near_dR2s; - near_dR2s.reserve(std::min(50UL, particles.size())); - vector near_pts; - near_pts.reserve(std::min(50UL, particles.size())); - const double r2 = R * R; - for (auto const &part : particles) { - if (part.puppi_register() == 3) - continue; - //squared_distance is in (y,phi) coords: rap() has faster access -> check it first - if (std::abs(part.rap() - centre.rap()) < R && part.squared_distance(centre) < r2) { - near_dR2s.push_back(reco::deltaR2(part, centre)); - near_pts.push_back(part.pt()); + for (auto const &cand : particles) { + if (std::abs(cand.rapidity - centre.rapidity) < R) { + auto const dr2y = reco::deltaR2(cand.rapidity, cand.phi, centre.rapidity, centre.phi); + if (dr2y < r2) { + auto const dr2 = reco::deltaR2(cand.eta, cand.phi, centre.eta, centre.phi); + if (dr2 < 0.0001) + continue; + auto const pt = cand.pt; + if (iId == 5) + var += (pt * pt / dr2); + else if (iId == 4) + var += pt; + else if (iId == 3) + var += (1. / dr2); + else if (iId == 2) + var += (1. / dr2); + else if (iId == 1) + var += pt; + else if (iId == 0) + var += (pt / dr2); + } } } - double var = 0; - //double lSumPt = 0; - //if(iId == 1) for(auto pt : near_pts) lSumPt += pt; - auto nParts = near_dR2s.size(); - for (auto i = 0UL; i < nParts; ++i) { - auto dr2 = near_dR2s[i]; - auto pt = near_pts[i]; - if (dr2 < 0.0001) - continue; - if (iId == 0) - var += (pt / dr2); - else if (iId == 1) - var += pt; - else if (iId == 2) - var += (1. / dr2); - else if (iId == 3) - var += (1. / dr2); - else if (iId == 4) - var += pt; - else if (iId == 5) - var += (pt * pt / dr2); - } - if (iId == 1) - var += centre.pt(); //Sum in a cone - else if (iId == 0 && var != 0) - var = log(var); - else if (iId == 3 && var != 0) - var = log(var); - else if (iId == 5 && var != 0) + + if ((var != 0.) and ((iId == 0) or (iId == 3) or (iId == 5))) var = log(var); + else if (iId == 1) + var += centre.pt; + return var; } + //In fact takes the median not the average void PuppiContainer::getRMSAvg(int iOpt, std::vector const &iConstits, std::vector const &iParticles, std::vector const &iChargedParticles) { for (unsigned int i0 = 0; i0 < iConstits.size(); i0++) { - double pVal = -1; //Calculate the Puppi Algo to use - int pPupId = getPuppiId(iConstits[i0].pt(), iConstits[i0].eta()); + int pPupId = getPuppiId(iConstits[i0].pt, iConstits[i0].eta); if (pPupId == -1 || fPuppiAlgo[pPupId].numAlgos() <= iOpt) { fVals.push_back(-1); continue; @@ -149,41 +142,46 @@ void PuppiContainer::getRMSAvg(int iOpt, int pAlgo = fPuppiAlgo[pPupId].algoId(iOpt); bool pCharged = fPuppiAlgo[pPupId].isCharged(iOpt); double pCone = fPuppiAlgo[pPupId].coneSize(iOpt); - //Compute the Puppi Metric - if (!pCharged) - pVal = goodVar(iConstits[i0], iParticles, pAlgo, pCone); - if (pCharged) - pVal = goodVar(iConstits[i0], iChargedParticles, pAlgo, pCone); + // compute the Puppi metric: + // - calculate goodVar only for candidates that (1) will not be assigned a predefined weight (e.g 0, 1), + // or (2) are required for computations inside puppi-algos (see call to PuppiAlgo::add below) + double pVal = -1; + bool const getsDefaultWgtIfApplyCHS = iConstits[i0].id == 1 or iConstits[i0].id == 2; + if (not((fApplyCHS and getsDefaultWgtIfApplyCHS) or iConstits[i0].id == 3) or + (std::abs(iConstits[i0].eta) < fPuppiAlgo[pPupId].etaMaxExtrap() and getsDefaultWgtIfApplyCHS)) { + pVal = goodVar(iConstits[i0], pCharged ? iChargedParticles : iParticles, pAlgo, pCone); + } fVals.push_back(pVal); - //if(std::isnan(pVal) || std::isinf(pVal)) cerr << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt() << " -- " << iConstits[i0].eta() << endl; + if (!edm::isFinite(pVal)) { - LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt() << " -- " - << iConstits[i0].eta() << endl; + LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt << " -- " << iConstits[i0].eta + << endl; continue; } - // // fPuppiAlgo[pPupId].add(iConstits[i0],pVal,iOpt); - //code added by Nhan, now instead for every algorithm give it all the particles + // code added by Nhan: now instead for every algorithm give it all the particles for (int i1 = 0; i1 < fNAlgos; i1++) { - pAlgo = fPuppiAlgo[i1].algoId(iOpt); - pCharged = fPuppiAlgo[i1].isCharged(iOpt); - pCone = fPuppiAlgo[i1].coneSize(iOpt); - double curVal = -1; + // skip cands outside of algo's etaMaxExtrap, as they would anyway be ignored inside PuppiAlgo::add (see end of the block) + if (not(std::abs(iConstits[i0].eta) < fPuppiAlgo[i1].etaMaxExtrap() and getsDefaultWgtIfApplyCHS)) + continue; + + auto curVal = pVal; + // recompute goodVar if algo has changed if (i1 != pPupId) { - if (!pCharged) - curVal = goodVar(iConstits[i0], iParticles, pAlgo, pCone); - if (pCharged) - curVal = goodVar(iConstits[i0], iChargedParticles, pAlgo, pCone); - } else { //no need to repeat the computation - curVal = pVal; + pAlgo = fPuppiAlgo[i1].algoId(iOpt); + pCharged = fPuppiAlgo[i1].isCharged(iOpt); + pCone = fPuppiAlgo[i1].coneSize(iOpt); + curVal = goodVar(iConstits[i0], pCharged ? iChargedParticles : iParticles, pAlgo, pCone); } - //std::cout << "i1 = " << i1 << ", curVal = " << curVal << ", eta = " << iConstits[i0].eta() << ", pupID = " << pPupId << std::endl; + fPuppiAlgo[i1].add(iConstits[i0], curVal, iOpt); } } + for (int i0 = 0; i0 < fNAlgos; i0++) fPuppiAlgo[i0].computeMedRMS(iOpt); } + //In fact takes the median not the average void PuppiContainer::getRawAlphas(int iOpt, std::vector const &iConstits, @@ -191,25 +189,22 @@ void PuppiContainer::getRawAlphas(int iOpt, std::vector const &iChargedParticles) { for (int j0 = 0; j0 < fNAlgos; j0++) { for (unsigned int i0 = 0; i0 < iConstits.size(); i0++) { - double pVal = -1; //Get the Puppi Sub Algo (given iteration) int pAlgo = fPuppiAlgo[j0].algoId(iOpt); bool pCharged = fPuppiAlgo[j0].isCharged(iOpt); double pCone = fPuppiAlgo[j0].coneSize(iOpt); //Compute the Puppi Metric - if (!pCharged) - pVal = goodVar(iConstits[i0], iParticles, pAlgo, pCone); - if (pCharged) - pVal = goodVar(iConstits[i0], iChargedParticles, pAlgo, pCone); + double const pVal = goodVar(iConstits[i0], pCharged ? iChargedParticles : iParticles, pAlgo, pCone); fRawAlphas.push_back(pVal); if (!edm::isFinite(pVal)) { - LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt() << " -- " - << iConstits[i0].eta() << endl; + LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt << " -- " + << iConstits[i0].eta << endl; continue; } } } } + int PuppiContainer::getPuppiId(float iPt, float iEta) { int lId = -1; for (int i0 = 0; i0 < fNAlgos; i0++) { @@ -257,10 +252,10 @@ std::vector const &PuppiContainer::puppiWeights() { lNMaxAlgo = std::max(fPuppiAlgo[i0].numAlgos(), lNMaxAlgo); //Run through all compute mean and RMS for (int i0 = 0; i0 < lNMaxAlgo; i0++) { - getRMSAvg(i0, fPFParticles, fPFParticles, fChargedPV); + getRMSAvg(i0, fPFParticles, fPFParticlesForVar, fPFParticlesForVarChargedPV); } if (fPuppiDiagnostics) - getRawAlphas(0, fPFParticles, fPFParticles, fChargedPV); + getRawAlphas(0, fPFParticles, fPFParticlesForVar, fPFParticlesForVarChargedPV); std::vector pVals; pVals.reserve(lNParticles); @@ -309,18 +304,16 @@ std::vector const &PuppiContainer::puppiWeights() { << " -- id : " << rParticle.id << " -- NAlgos: " << lNAlgos << std::endl; } //Basic Cuts - if (pWeight * fPFParticles[i0].pt() < fPuppiAlgo[pPupId].neutralPt(fNPV) && rParticle.id == 0) + if (pWeight * fPFParticles[i0].pt < fPuppiAlgo[pPupId].neutralPt(fNPV) && rParticle.id == 0) pWeight = 0; //threshold cut on the neutral Pt // Protect high pT photons (important for gamma to hadronic recoil balance) - if ((fPtMaxPhotons > 0) && (rParticle.pdgId == 22) && (std::abs(fPFParticles[i0].eta()) < fEtaMaxPhotons) && - (fPFParticles[i0].pt() > fPtMaxPhotons)) + if (fPtMaxPhotons > 0 && rParticle.pdgId == 22 && std::abs(fPFParticles[i0].eta) < fEtaMaxPhotons && + fPFParticles[i0].pt > fPtMaxPhotons) pWeight = 1.; // Protect high pT neutrals else if ((fPtMaxNeutrals > 0) && (rParticle.id == 0)) - pWeight = - std::clamp((fPFParticles[i0].pt() - fPtMaxNeutralsStartSlope) / (fPtMaxNeutrals - fPtMaxNeutralsStartSlope), - pWeight, - 1.); + pWeight = std::clamp( + (fPFParticles[i0].pt - fPtMaxNeutralsStartSlope) / (fPtMaxNeutrals - fPtMaxNeutralsStartSlope), pWeight, 1.); if (pWeight < fPuppiWeightCut) pWeight = 0; //==> Elminate the low Weight stuff if (fInvert) diff --git a/CondCore/CondDB/interface/ConnectionPool.h b/CondCore/CondDB/interface/ConnectionPool.h index f9340e0a47da5..f291d9cf2ba11 100644 --- a/CondCore/CondDB/interface/ConnectionPool.h +++ b/CondCore/CondDB/interface/ConnectionPool.h @@ -15,6 +15,7 @@ namespace edm { namespace coral { class IConnectionServiceConfiguration; class ISessionProxy; + class IMsgReporter; } // namespace coral namespace cond { @@ -25,6 +26,9 @@ namespace cond { namespace persistency { // + class CoralMsgReporter; + class Logger; + enum DbAuthenticationSystem { UndefinedAuthentication = 0, CondDbKey, CoralXMLFile }; // a wrapper for the coral connection service. @@ -34,6 +38,7 @@ namespace cond { ~ConnectionPool(); void setMessageVerbosity(coral::MsgLevel level); + void setLogDestination(Logger& logger); void setAuthenticationPath(const std::string& p); void setAuthenticationSystem(int authSysCode); void setFrontierSecurity(const std::string& signature); @@ -59,6 +64,7 @@ namespace cond { std::string m_authPath = std::string(""); int m_authSys = 0; coral::MsgLevel m_messageLevel = coral::Error; + std::unique_ptr m_msgReporter; bool m_loggingEnabled = false; //The frontier security option is turned on for all sessions //usig this wrapper of the CORAL connection setup for configuring the server access diff --git a/CondCore/CondDB/interface/Logger.h b/CondCore/CondDB/interface/Logger.h new file mode 100644 index 0000000000000..399db18216d2d --- /dev/null +++ b/CondCore/CondDB/interface/Logger.h @@ -0,0 +1,137 @@ +#ifndef CondCore_CondDB_Logger_h +#define CondCore_CondDB_Logger_h +// +// Package: CondDB +// Class : O2OLogger +// +/**\class Logger Logger.h CondCore/CondDB/interface/Logger.h + Description: utility for collecting log information and store them into the Condition DB. +*/ +// +// Author: Giacomo Govi +// Created: Sep 2020 +// +#include "FWCore/MessageLogger/interface/MessageLogger.h" +// +#include +#include + +namespace cond { + + namespace persistency { + + class ConnectionPool; + + template + class EchoedLogStream { + public: + EchoedLogStream() = delete; + explicit EchoedLogStream(const std::string& jobName, std::stringstream& buffer) + : m_edmLogger(jobName), m_buffer(&buffer) {} + virtual ~EchoedLogStream() {} + template + EchoedLogStream& operator<<(const T& t) { + *m_buffer << t; + m_edmLogger << t; + return *this; + } + EchoedLogStream& operator<<(std::ostream& (*f)(std::ostream&)) { + *m_buffer << f; + m_edmLogger << f; + return *this; + } + EchoedLogStream& operator<<(std::ios_base& (*f)(std::ios_base&)) { + *m_buffer << f; + m_edmLogger << f; + return *this; + } + + private: + EdmLogger m_edmLogger; + std::stringstream* m_buffer; + }; + + template <> + class EchoedLogStream { + public: + EchoedLogStream() = delete; + explicit EchoedLogStream(const std::string& jobName, std::stringstream& buffer) + : m_edmLogger(jobName, __FILE__, __LINE__), m_buffer(&buffer) {} + virtual ~EchoedLogStream() {} + template + EchoedLogStream& operator<<(const T& t) { + *m_buffer << t; + m_edmLogger << t; + return *this; + } + EchoedLogStream& operator<<(std::ostream& (*f)(std::ostream&)) { + *m_buffer << f; + m_edmLogger << f; + return *this; + } + EchoedLogStream& operator<<(std::ios_base& (*f)(std::ios_base&)) { + *m_buffer << f; + m_edmLogger << f; + return *this; + } + + private: + edm::LogDebug_ m_edmLogger; + std::stringstream* m_buffer; + }; + + // + class Logger { + public: + // default constructor is suppressed + Logger() = delete; + + // constructor + explicit Logger(const std::string& jobName); + + // + virtual ~Logger(); + + // + void setDbDestination(const std::string& connectionString, ConnectionPool& connectionPool); + + // + void start(); + + // + void end(int retCode); + + // + void saveOnDb(); + + // + void saveOnFile(); + + // + void save(); + + // + std::iostream& log(const std::string& tag); + + EchoedLogStream logInfo(); + EchoedLogStream logDebug(); + EchoedLogStream logError(); + EchoedLogStream logWarning(); + + private: + void clearBuffer(); + + private: + std::string m_jobName; + std::string m_connectionString; + ConnectionPool* m_sharedConnectionPool; + bool m_started; + boost::posix_time::ptime m_startTime; + boost::posix_time::ptime m_endTime; + int m_retCode; + std::stringstream m_log; + }; + + } // namespace persistency +} // namespace cond +#endif diff --git a/CondCore/CondDB/interface/Session.h b/CondCore/CondDB/interface/Session.h index 1b6d4e9839ffc..100ec179bd4e1 100644 --- a/CondCore/CondDB/interface/Session.h +++ b/CondCore/CondDB/interface/Session.h @@ -158,7 +158,7 @@ namespace cond { RunInfoProxy getRunInfo(cond::Time_t start, cond::Time_t end); // get the ongoing run - cond::RunInfo_t getCurrentRun(); + cond::RunInfo_t getLastRun(); // runinfo write access RunInfoEditor editRunInfo(); diff --git a/CondCore/CondDB/interface/Types.h b/CondCore/CondDB/interface/Types.h index 202e5cd8d8324..ac597f32509e9 100644 --- a/CondCore/CondDB/interface/Types.h +++ b/CondCore/CondDB/interface/Types.h @@ -13,7 +13,7 @@ // #include -#include +#include // #include "CondCore/CondDB/interface/Time.h" @@ -123,7 +123,7 @@ namespace cond { std::size_t hashvalue() const { // Derived from CondDB v1 TagMetadata implementation. // Unique Keys constructed with Record and Labels - allowing for multiple references of the same Tag in a GT - boost::hash hasher; + std::hash hasher; std::string key = recordName(); if (!recordLabel().empty()) key = key + "_" + recordLabel(); @@ -137,8 +137,15 @@ namespace cond { }; struct RunInfo_t { + RunInfo_t() : run(0), start(), end() {} RunInfo_t(const std::tuple& data) : run(std::get<0>(data)), start(std::get<1>(data)), end(std::get<2>(data)) {} + bool isOnGoing() { + if (run == 0) + return false; + auto now = boost::posix_time::second_clock::universal_time(); + return (start < now) && (end == start); + } Time_t run; boost::posix_time::ptime start; boost::posix_time::ptime end; diff --git a/CondCore/CondDB/src/ConnectionPool.cc b/CondCore/CondDB/src/ConnectionPool.cc index 23dfc08d0b3e9..247bf2d1c841b 100644 --- a/CondCore/CondDB/src/ConnectionPool.cc +++ b/CondCore/CondDB/src/ConnectionPool.cc @@ -2,6 +2,7 @@ #include "DbConnectionString.h" #include "SessionImpl.h" #include "IOVSchema.h" +#include "CoralMsgReporter.h" // #include "CondCore/CondDB/interface/CoralServiceManager.h" #include "CondCore/CondDB/interface/Auth.h" @@ -15,8 +16,6 @@ #include "CoralKernel/Context.h" #include "CoralKernel/IProperty.h" #include "CoralKernel/IPropertyManager.h" -// externals -#include namespace cond { @@ -74,6 +73,11 @@ namespace cond { coralConfig.disableConnectionSharing(); // message streaming coral::MessageStream::setMsgVerbosity(m_messageLevel); + if (m_msgReporter.get() != nullptr) { + m_msgReporter->setOutputLevel(m_messageLevel); + coral::MessageStream::installMsgReporter(static_cast(m_msgReporter.get())); + } + // authentication std::string authServiceName("CORAL/Services/EnvironmentAuthenticationService"); std::string authPath = m_authPath; // authentication @@ -167,5 +171,9 @@ namespace cond { void ConnectionPool::setMessageVerbosity(coral::MsgLevel level) { m_messageLevel = level; } + void ConnectionPool::setLogDestination(Logger& logger) { + m_msgReporter = std::make_unique(logger); + } + } // namespace persistency } // namespace cond diff --git a/CondCore/CondDB/src/CoralMsgReporter.cc b/CondCore/CondDB/src/CoralMsgReporter.cc new file mode 100644 index 0000000000000..603a23be845ae --- /dev/null +++ b/CondCore/CondDB/src/CoralMsgReporter.cc @@ -0,0 +1,136 @@ +// Include files +#include +#include // fix bug #58581 +#include // fix bug #58581 + +// Local include files +#include "CondCore/CondDB/interface/Logger.h" +#include "CoralMsgReporter.h" + +/// Default constructor +cond::persistency::CoralMsgReporter::CoralMsgReporter(Logger& logger) + : m_logger(logger), m_level(coral::Error), m_format(0), m_mutex() { + // Use a non-default format? + //char* msgformat = getenv ( "CORAL_MSGFORMAT" ); + if (getenv("CORAL_MESSAGEREPORTER_FORMATTED")) + m_format = 1; + + // Use a non-default message level? + if (getenv("CORAL_MSGLEVEL")) { + // Check only the first char of the environment variable + switch (*getenv("CORAL_MSGLEVEL")) { + case '0': + case 'n': + case 'N': + m_level = coral::Nil; + break; + + case '1': + case 'v': + case 'V': + m_level = coral::Verbose; + break; + + case '2': + case 'd': + case 'D': + m_level = coral::Debug; + break; + + case '3': + case 'i': + case 'I': + m_level = coral::Info; + break; + + case '4': + case 'w': + case 'W': + m_level = coral::Warning; + break; + + case '5': + case 'e': + case 'E': + m_level = coral::Error; + break; + + case '6': + case 'f': + case 'F': + m_level = coral::Fatal; + break; + + case '7': + case 'a': + case 'A': + m_level = coral::Always; + break; + + default: + break; // keep the default + } + } +} + +/// Access output level +coral::MsgLevel cond::persistency::CoralMsgReporter::outputLevel() const { return m_level; } + +/// Modify output level +void cond::persistency::CoralMsgReporter::setOutputLevel(coral::MsgLevel lvl) { m_level = lvl; } + +/// Report message to stdout +void cond::persistency::CoralMsgReporter::report(int lvl, const std::string& src, const std::string& msg) { + if (lvl < m_level) + return; + std::lock_guard lock(m_mutex); + + std::stringstream out; + /** + if ( m_format == 1 ) // COOL format + { + // Formatted CORAL reporter (as in COOL) + //std::ostream& out = std::cout; + const std::string::size_type src_name_maxsize = 36; + if ( src.size() <= src_name_maxsize ) + { + out << src << std::string( src_name_maxsize-src.size(), ' ' ); + } + else + { + out << src.substr( 0, src_name_maxsize-3 ) << "..."; + } + switch ( lvl ) + { + case 0: out << " Nil "; break; + case 1: out << " Verbose "; break; + case 2: out << " Debug "; break; + case 3: out << " Info "; break; + case 4: out << " Warning "; break; + case 5: out << " Error "; break; + case 6: out << " Fatal "; break; + case 7: out << " Always "; break; + default: out << " Unknown "; break; + } + out << msg << std::endl; + } + else{ + **/ + // Default CORAL reporter + switch (lvl) { + case coral::Nil: + case coral::Verbose: + case coral::Debug: + m_logger.logDebug() << "CORAL: " << msg; + break; + case coral::Info: + m_logger.logInfo() << "CORAL: " << msg; + break; + case coral::Warning: + m_logger.logWarning() << "CORAL: " << msg; + break; + case coral::Error: + m_logger.logError() << "CORAL: " << msg; + break; + } +} diff --git a/CondCore/CondDB/src/CoralMsgReporter.h b/CondCore/CondDB/src/CoralMsgReporter.h new file mode 100644 index 0000000000000..aef1aaa9c2c58 --- /dev/null +++ b/CondCore/CondDB/src/CoralMsgReporter.h @@ -0,0 +1,55 @@ +#ifndef CondCore_CondDB_CoralMsgReporter_h +#define CondCore_CondDB_CoralMsgReporter_h + +//#include "CondCore/CondDB/interface/Logger.h" + +#include +#include "CoralBase/MessageStream.h" + +namespace cond { + + namespace persistency { + + class Logger; + + class CoralMsgReporter : public coral::IMsgReporter { + public: + // Empty ctr is suppressed + CoralMsgReporter() = delete; + + /// Default constructor + explicit CoralMsgReporter(Logger& logger); + + /// Destructor + ~CoralMsgReporter() override {} + + /// Release reference to reporter + void release() override { delete this; } + + /// Access output level + coral::MsgLevel outputLevel() const override; + + /// Modify output level + void setOutputLevel(coral::MsgLevel lvl) override; + + /// Report a message + void report(int lvl, const std::string& src, const std::string& msg) override; + + private: + // the destination of the streams... + Logger& m_logger; + + /// The current message level threshold + coral::MsgLevel m_level; + + /// Use a different format output + size_t m_format; + + /// The mutex lock + std::recursive_mutex m_mutex; + }; + + } // namespace persistency + +} // namespace cond +#endif diff --git a/CondCore/CondDB/src/IDbSchema.h b/CondCore/CondDB/src/IDbSchema.h index 8300661e33b9b..3edd4f1bc1270 100644 --- a/CondCore/CondDB/src/IDbSchema.h +++ b/CondCore/CondDB/src/IDbSchema.h @@ -219,7 +219,7 @@ namespace cond { virtual bool exists() = 0; virtual void create() = 0; virtual bool select(cond::Time_t runNumber, boost::posix_time::ptime& start, boost::posix_time::ptime& end) = 0; - virtual cond::Time_t getLastInserted() = 0; + virtual cond::Time_t getLastInserted(boost::posix_time::ptime& start, boost::posix_time::ptime& end) = 0; virtual bool getInclusiveRunRange( cond::Time_t lower, cond::Time_t upper, diff --git a/CondCore/CondDB/src/Logger.cc b/CondCore/CondDB/src/Logger.cc new file mode 100644 index 0000000000000..8d6a592e1fa60 --- /dev/null +++ b/CondCore/CondDB/src/Logger.cc @@ -0,0 +1,171 @@ +#include "CondCore/CondDB/interface/Logger.h" +#include "CondCore/CondDB/interface/ConnectionPool.h" +#include "CondCore/CondDB/interface/Exception.h" +// +#include "DbCore.h" +#include "RelationalAccess/ITransaction.h" +// +#include +#include +// +namespace cond { + + namespace persistency { + + conddb_table(O2O_RUN) { + conddb_column(JOB_NAME, std::string); + conddb_column(START_TIME, boost::posix_time::ptime); + conddb_column(END_TIME, boost::posix_time::ptime); + conddb_column(STATUS_CODE, int); + conddb_column(LOG, std::string); + class Table { + public: + explicit Table(coral::ISchema& schema) : m_schema(schema) {} + ~Table() {} + void insert(const std::string& jobName, + const boost::posix_time::ptime& start, + const boost::posix_time::ptime& end, + int retCode, + const std::string& log) { + RowBuffer dataToInsert( + std::tie(jobName, start, end, retCode, log)); + insertInTable(m_schema, tname, dataToInsert.get()); + } + + private: + coral::ISchema& m_schema; + }; + } + + void Logger::clearBuffer() { + m_log.str(""); + m_log.clear(); + } + + Logger::Logger(const std::string& jobName) + : m_jobName(jobName), + m_connectionString(""), + m_sharedConnectionPool(nullptr), + m_started(false), + m_startTime(), + m_endTime(), + m_retCode(0), + m_log() {} + + // + Logger::~Logger() {} + + void Logger::setDbDestination(const std::string& connectionString, ConnectionPool& connectionPool) { + m_connectionString = connectionString; + m_sharedConnectionPool = &connectionPool; + } + + // + void Logger::start() { + if (!m_started) { + if (!m_log.str().empty()) + clearBuffer(); + m_startTime = boost::posix_time::microsec_clock::universal_time(); + m_started = true; + log("START_JOB") << " " << m_jobName; + } + } + + // + void Logger::end(int retCode) { + if (m_started) { + m_endTime = boost::posix_time::microsec_clock::universal_time(); + m_started = false; + m_retCode = retCode; + log("END_JOB") << ": return code:" << retCode; + save(); + clearBuffer(); + } + } + + std::string print_timestamp(const boost::posix_time::ptime& t, const char* format_s = "%Y-%m-%d %H:%M:%S.%f") { + boost::posix_time::time_facet* facet = new boost::posix_time::time_facet(); + facet->format(format_s); + std::stringstream timestamp; + timestamp.imbue(std::locale(std::locale::classic(), facet)); + timestamp << t; + return timestamp.str(); + } + + std::string get_timestamp() { + auto now = boost::posix_time::microsec_clock::universal_time(); + return print_timestamp(now); + } + std::string get_timestamp_for_filename() { + auto now = boost::posix_time::microsec_clock::universal_time(); + return print_timestamp(now, "%Y-%m-%d_%H-%M-%S"); + } + + // + void Logger::saveOnFile() { + if (!m_log.str().empty()) { + std::string fileName(get_timestamp_for_filename() + ".log"); + std::ofstream fout(fileName, std::ofstream::app); + fout << m_log.str() << std::endl; + fout.close(); + } + } + + // + void Logger::saveOnDb() { + if (!m_log.str().empty()) { + if (m_sharedConnectionPool == nullptr) { + throwException("Connection pool handle has not been provided.", "Logger::saveOnDb"); + } + if (m_connectionString.empty()) { + throwException("Connection string for destination database has not been provided.", "Logger::saveOnDb"); + } + auto coralSession = m_sharedConnectionPool->createCoralSession(m_connectionString, true); + coralSession->transaction().start(false); + try { + O2O_RUN::Table destinationTable(coralSession->nominalSchema()); + destinationTable.insert(m_jobName, m_startTime, m_endTime, m_retCode, m_log.str()); + coralSession->transaction().commit(); + } catch (const std::exception& e) { + coralSession->transaction().rollback(); + // dump on file on this circumstance... + logError() << e.what(); + saveOnFile(); + throwException(std::string("Failure while saving log on database:") + e.what(), "Logger::saveOnDb"); + } + } + } + + void Logger::save() { + if (!m_connectionString.empty()) + saveOnDb(); + else + saveOnFile(); + } + + std::iostream& Logger::log(const std::string& tag) { + if (std::size(m_log.str()) != 0) + m_log << std::endl; + m_log << "[" << get_timestamp() << "] " << tag << ": "; + return m_log; + } + + EchoedLogStream Logger::logInfo() { + log("INFO"); + return EchoedLogStream(m_jobName, m_log); + } + EchoedLogStream Logger::logDebug() { + log("DEBUG"); + return EchoedLogStream(m_jobName, m_log); + } + EchoedLogStream Logger::logError() { + log("ERROR"); + return EchoedLogStream(m_jobName, m_log); + } + EchoedLogStream Logger::logWarning() { + log("WARNING"); + return EchoedLogStream(m_jobName, m_log); + } + + } // namespace persistency +} // namespace cond diff --git a/CondCore/CondDB/src/RunInfoEditor.cc b/CondCore/CondDB/src/RunInfoEditor.cc index 63ebbc59d5eff..49579878d15a9 100644 --- a/CondCore/CondDB/src/RunInfoEditor.cc +++ b/CondCore/CondDB/src/RunInfoEditor.cc @@ -40,7 +40,8 @@ namespace cond { cond::Time_t RunInfoEditor::getLastInserted() { if (m_data.get()) { checkTransaction("RunInfoEditor::getLastInserted"); - return m_session->runInfoSchema().runInfoTable().getLastInserted(); + boost::posix_time::ptime start, end; + return m_session->runInfoSchema().runInfoTable().getLastInserted(start, end); } return cond::time::MIN_VAL; } diff --git a/CondCore/CondDB/src/RunInfoProxy.cc b/CondCore/CondDB/src/RunInfoProxy.cc index 358b2c12c0620..57277f045f1e9 100644 --- a/CondCore/CondDB/src/RunInfoProxy.cc +++ b/CondCore/CondDB/src/RunInfoProxy.cc @@ -73,7 +73,10 @@ namespace cond { checkTransaction("RunInfoProxy::load(Time_t,Time_t)"); std::string dummy; - m_session->runInfoSchema().runInfoTable().getInclusiveRunRange(low, up, m_data->runList); + if (!m_session->runInfoSchema().runInfoTable().getInclusiveRunRange(low, up, m_data->runList)) { + throwException("No runs have been found in the range (" + std::to_string(low) + "," + std::to_string(up) + ")", + "RunInfoProxy::load(Time_t,Time_t)"); + } } void RunInfoProxy::load(const boost::posix_time::ptime& low, const boost::posix_time::ptime& up) { @@ -86,7 +89,11 @@ namespace cond { checkTransaction("RunInfoProxy::load(const boost::posix_time::ptime&,const boost::posix_time::ptime&)"); std::string dummy; - m_session->runInfoSchema().runInfoTable().getInclusiveTimeRange(low, up, m_data->runList); + if (!m_session->runInfoSchema().runInfoTable().getInclusiveTimeRange(low, up, m_data->runList)) { + throwException("No runs have been found in the interval (" + boost::posix_time::to_simple_string(low) + "," + + boost::posix_time::to_simple_string(up) + ")", + "RunInfoProxy::load(boost::posix_time::ptime&,const boost::posix_time::ptime&)"); + } } void RunInfoProxy::reset() { diff --git a/CondCore/CondDB/src/RunInfoSchema.cc b/CondCore/CondDB/src/RunInfoSchema.cc index 274156acaea05..6c0cd97d181a2 100644 --- a/CondCore/CondDB/src/RunInfoSchema.cc +++ b/CondCore/CondDB/src/RunInfoSchema.cc @@ -33,7 +33,7 @@ namespace cond { return ret; } - cond::Time_t RUN_INFO::Table::getLastInserted() { + cond::Time_t RUN_INFO::Table::getLastInserted(boost::posix_time::ptime& start, boost::posix_time::ptime& end) { cond::Time_t run = cond::time::MIN_VAL; Query q0(m_schema); try { @@ -46,6 +46,7 @@ namespace cond { if (message.find("Attempt to access data of NULL attribute") != 0) throw; } + select(run, start, end); return run; } @@ -93,12 +94,6 @@ namespace cond { return runData.size() > prevSize; } - //bool RUN_INFO::Table::getRunForTime( const boost::posix_time::ptime& time, - // cond::Time_t& runNumber, boost::posix_time::ptime& start, boost::posix_time::ptime& end ){ - // Query< RUN_NUMBER, START_TIME, END_TIME > q(m_schema); - // q.addCondition< START_TIME >( upper,"<=" ); - // } - void RUN_INFO::Table::insertOne(cond::Time_t runNumber, const boost::posix_time::ptime& start, const boost::posix_time::ptime& end) { diff --git a/CondCore/CondDB/src/RunInfoSchema.h b/CondCore/CondDB/src/RunInfoSchema.h index c637d35f82717..53c431e8a3515 100644 --- a/CondCore/CondDB/src/RunInfoSchema.h +++ b/CondCore/CondDB/src/RunInfoSchema.h @@ -43,7 +43,7 @@ namespace cond { bool exists() override; void create() override; bool select(cond::Time_t runNumber, boost::posix_time::ptime& start, boost::posix_time::ptime& end) override; - cond::Time_t getLastInserted() override; + cond::Time_t getLastInserted(boost::posix_time::ptime& start, boost::posix_time::ptime& end) override; bool getInclusiveRunRange( cond::Time_t lower, cond::Time_t upper, diff --git a/CondCore/CondDB/src/Session.cc b/CondCore/CondDB/src/Session.cc index 694be2d4a30ae..013a5ee5d1ca3 100644 --- a/CondCore/CondDB/src/Session.cc +++ b/CondCore/CondDB/src/Session.cc @@ -198,13 +198,13 @@ namespace cond { return proxy; } - cond::RunInfo_t Session::getCurrentRun() { + cond::RunInfo_t Session::getLastRun() { if (!m_session->transaction.get()) throwException("The transaction is not active.", "Session::getRunInfo"); - RunInfoProxy proxy(m_session); - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - proxy.load(now, now); - return proxy.get(now); + m_session->openRunInfoDb(); + cond::RunInfo_t ret; + ret.run = m_session->runInfoSchema().runInfoTable().getLastInserted(ret.start, ret.end); + return ret; } RunInfoEditor Session::editRunInfo() { diff --git a/CondCore/CondDB/src/SessionImpl.h b/CondCore/CondDB/src/SessionImpl.h index faf1aefab4cbf..d925fc467cdf6 100644 --- a/CondCore/CondDB/src/SessionImpl.h +++ b/CondCore/CondDB/src/SessionImpl.h @@ -33,7 +33,7 @@ namespace cond { bool gtDbExists = false; bool gtDbOpen = false; bool runInfoDbExists = false; - bool runInfoDbOpen = true; + bool runInfoDbOpen = false; size_t clients = 0; }; diff --git a/CondCore/CondDB/test/BuildFile.xml b/CondCore/CondDB/test/BuildFile.xml index fefd98059b06b..eb81a6ea7cae9 100644 --- a/CondCore/CondDB/test/BuildFile.xml +++ b/CondCore/CondDB/test/BuildFile.xml @@ -1,6 +1,4 @@ - - @@ -31,9 +29,15 @@ + + + + + + diff --git a/CondCore/CondDB/test/testLogger.cpp b/CondCore/CondDB/test/testLogger.cpp new file mode 100644 index 0000000000000..3f98e83998f95 --- /dev/null +++ b/CondCore/CondDB/test/testLogger.cpp @@ -0,0 +1,20 @@ + +#include "CondCore/CondDB/interface/Logger.h" +// +#include + +using namespace cond::persistency; + +int main(int argc, char** argv) { + Logger logger("TestO2O_gg_code"); + logger.start(); + std::string s("XYZ"); + logger.logInfo() << "Step #" << 1 << " and string is [" << s << "]"; + ::sleep(2); + logger.logError() << "Step #" << 2; + logger.logWarning() << "Step #" << 3; + logger.log("SPECIAL") << "Blabla val=" << 77 << " and more stuff: " << std::string("ciao"); + logger.end(-1); + logger.saveOnFile(); + return 0; +} diff --git a/CondCore/CondDB/test/testRunInfo2.cpp b/CondCore/CondDB/test/testRunInfo2.cpp new file mode 100644 index 0000000000000..2f3fa9c7200e1 --- /dev/null +++ b/CondCore/CondDB/test/testRunInfo2.cpp @@ -0,0 +1,56 @@ +#include "FWCore/PluginManager/interface/PluginManager.h" +#include "FWCore/PluginManager/interface/standard.h" +#include "FWCore/PluginManager/interface/SharedLibrary.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h" +// +#include "CondCore/CondDB/interface/ConnectionPool.h" +// +#include +#include +#include +#include + +using namespace cond::persistency; + +int run(const std::string& connectionString) { + try { + //************* + std::cout << "> Connecting with db in " << connectionString << std::endl; + ConnectionPool connPool; + connPool.setMessageVerbosity(coral::Debug); + connPool.configure(); + Session session = connPool.createSession(connectionString); + session.transaction().start(); + cond::RunInfo_t r = session.getLastRun(); + std::cout << "Last run: " << r.run << " start:" << r.start << std::endl; + if (r.isOnGoing()) + std::cout << "Run is ongoing" << std::endl; + else + std::cout << "Run was ending on " << r.end << std::endl; + session.transaction().commit(); + } catch (cond::Exception& e) { + std::cout << "ERROR: " << e.what() << std::endl; + return 1; + } + //std::cout << "## RunInfo test successfully completed." << std::endl; + return 0; +} + +int main(int argc, char** argv) { + edmplugin::PluginManager::Config config; + edmplugin::PluginManager::configure(edmplugin::standard::config()); + + std::vector psets; + edm::ParameterSet pSet; + pSet.addParameter("@service_type", std::string("SiteLocalConfigService")); + psets.push_back(pSet); + static const edm::ServiceToken services(edm::ServiceRegistry::createSet(psets)); + static const edm::ServiceRegistry::Operate operate(services); + int ret = 0; + std::string connectionString0("frontier://FrontierProd/CMS_CONDITIONS"); + //std::string connectionString0("frontier://FrontierProd/CMS_CONDITIONS"); + //std::string connectionString0("oracle://cms_orcoff_prep/CMS_CONDITIONS"); + ret = run(connectionString0); + return ret; +} diff --git a/CondCore/DBOutputService/BuildFile.xml b/CondCore/DBOutputService/BuildFile.xml index 04fe96eebe874..e8fc9cfd0e210 100644 --- a/CondCore/DBOutputService/BuildFile.xml +++ b/CondCore/DBOutputService/BuildFile.xml @@ -1,4 +1,3 @@ - diff --git a/CondCore/DBOutputService/interface/OnlineDBOutputService.h b/CondCore/DBOutputService/interface/OnlineDBOutputService.h index 2c8dcab1688aa..910fe2acd900a 100644 --- a/CondCore/DBOutputService/interface/OnlineDBOutputService.h +++ b/CondCore/DBOutputService/interface/OnlineDBOutputService.h @@ -21,14 +21,9 @@ namespace cond { - cond::Time_t getLatestLumiFromFile(const std::string& fileName) { - cond::Time_t lastLumiProcessed = cond::time::MIN_VAL; - std::ifstream lastLumiFile(fileName); - if (lastLumiFile) { - lastLumiFile >> lastLumiProcessed; - } - return lastLumiProcessed; - } + cond::Time_t getLatestLumiFromFile(const std::string& fileName); + + cond::Time_t getLastLumiFromOMS(const std::string& omsServiceUrl); namespace service { @@ -45,7 +40,7 @@ namespace cond { bool writeForNextLumisection(const PayloadType* payload, const std::string& recordName) { cond::Time_t targetTime = getLastLumiProcessed() + m_latencyInLumisections; auto t0 = std::chrono::high_resolution_clock::now(); - edm::LogInfo(MSGSOURCE) << "Updating lumisection " << targetTime; + logger().logInfo() << "Updating lumisection " << targetTime; cond::Hash payloadId = PoolDBOutputService::writeOne(payload, targetTime, recordName); bool ret = true; if (payloadId.empty()) { @@ -53,28 +48,28 @@ namespace cond { } auto t1 = std::chrono::high_resolution_clock::now(); auto w_lat = std::chrono::duration_cast(t1 - t0).count(); - edm::LogInfo(MSGSOURCE) << "Update has taken " << w_lat << " microsecs."; + logger().logInfo() << "Update has taken " << w_lat << " microsecs."; // check for late updates... cond::Time_t lastProcessed = getLastLumiProcessed(); - edm::LogInfo(MSGSOURCE) << "Last lumisection processed after update: " << lastProcessed; + logger().logInfo() << "Last lumisection processed after update: " << lastProcessed; // check the pre-loaded iov - edm::LogInfo(MSGSOURCE) << "Preloading lumisection " << targetTime; + logger().logInfo() << "Preloading lumisection " << targetTime; auto t2 = std::chrono::high_resolution_clock::now(); cond::Iov_t usedIov = preLoadIov(recordName, targetTime); auto t3 = std::chrono::high_resolution_clock::now(); - edm::LogInfo(MSGSOURCE) << "Iov for preloaded lumisection " << targetTime << " is " << usedIov.since; + logger().logInfo() << "Iov for preloaded lumisection " << targetTime << " is " << usedIov.since; auto p_lat = std::chrono::duration_cast(t3 - t2).count(); - edm::LogInfo(MSGSOURCE) << "Preload has taken " << p_lat << " microsecs."; + logger().logInfo() << "Preload has taken " << p_lat << " microsecs."; if (usedIov.since < targetTime) { - edm::LogWarning(MSGSOURCE) << "Found a late update for lumisection " << targetTime << "(found since " - << usedIov.since << "). A revert is required."; + logger().logWarning() << "Found a late update for lumisection " << targetTime << "(found since " + << usedIov.since << "). A revert is required."; PoolDBOutputService::eraseSinceTime(payloadId, targetTime, recordName); PoolDBOutputService::commitTransaction(); ret = false; } auto t4 = std::chrono::high_resolution_clock::now(); auto t_lat = std::chrono::duration_cast(t4 - t0).count(); - edm::LogInfo(MSGSOURCE) << "Total update time: " << t_lat << " microsecs."; + logger().logInfo() << "Total update time: " << t_lat << " microsecs."; return ret; } @@ -84,12 +79,11 @@ namespace cond { cond::persistency::Session getReadOnlyCache(cond::Time_t targetTime); private: - static constexpr const char* const MSGSOURCE = "OnlineDBOuputService"; cond::Time_t m_runNumber; size_t m_latencyInLumisections; + std::string m_omsServiceUrl; std::string m_lastLumiUrl; std::string m_lastLumiFile; - //std::chrono::time_point m_startRunTime; std::string m_preLoadConnectionString; bool m_debug; diff --git a/CondCore/DBOutputService/interface/PoolDBOutputService.h b/CondCore/DBOutputService/interface/PoolDBOutputService.h index 5fd1e98de7d0c..d7c87728db99c 100644 --- a/CondCore/DBOutputService/interface/PoolDBOutputService.h +++ b/CondCore/DBOutputService/interface/PoolDBOutputService.h @@ -4,6 +4,7 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "CondCore/CondDB/interface/ConnectionPool.h" #include "CondCore/CondDB/interface/Session.h" +#include "CondCore/CondDB/interface/Logger.h" #include #include #include @@ -57,13 +58,13 @@ namespace cond { if (!payload) throwException("Provided payload pointer is invalid.", "PoolDBOutputService::writeOne"); std::lock_guard lock(m_mutex); - std::cout << "WriteOne: opening trans..." << std::endl; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); Hash thePayloadHash(""); try { this->initDB(); Record& myrecord = this->lookUpRecord(recordName); + m_logger.logInfo() << "Tag mapped to record " << recordName << ": " << myrecord.m_tag; bool newTag = isNewTagRequest(recordName); if (myrecord.m_onlyAppendUpdatePolicy && !newTag) { cond::TagInfo_t tInfo; @@ -72,10 +73,11 @@ namespace cond { if (lastSince == cond::time::MAX_VAL) lastSince = 0; if (time <= lastSince) { - edm::LogInfo(MSGSOURCE) << "Won't append iov with since " << std::to_string(time) - << ", because is less or equal to last available since = " << lastSince; + m_logger.logInfo() << "Won't append iov with since " << std::to_string(time) + << ", because is less or equal to last available since = " << lastSince; if (m_autoCommit) doCommitTransaction(); + scope.close(); return thePayloadHash; } } @@ -88,7 +90,7 @@ namespace cond { } if (m_autoCommit) { if (m_writeTransactionDelay) { - edm::LogWarning(MSGSOURCE) << "Waiting " << m_writeTransactionDelay << "s before commit the changes..."; + m_logger.logWarning() << "Waiting " << m_writeTransactionDelay << "s before commit the changes..."; ::sleep(m_writeTransactionDelay); } doCommitTransaction(); @@ -116,7 +118,6 @@ namespace cond { if (!myrecord.m_isNewTag) { cond::throwException(myrecord.m_tag + " is not a new tag", "PoolDBOutputService::createNewIOV"); } - std::cout << "createNewIOV: opening trans..." << std::endl; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); try { @@ -129,12 +130,6 @@ namespace cond { scope.close(); } - // this one we need to avoid to adapt client code around... to be removed in the long term! - //void createNewIOV(const std::string& firstPayloadId, - // cond::Time_t firstSinceTime, - // cond::Time_t firstTillTime, - // const std::string& recordName); - // template void appendSinceTime(const T* payloadObj, cond::Time_t sinceTime, const std::string& recordName) { @@ -146,7 +141,6 @@ namespace cond { cond::throwException(std::string("Cannot append to non-existing tag ") + myrecord.m_tag, "PoolDBOutputService::appendSinceTime"); } - std::cout << "appendSinceTime: opening trans..." << std::endl; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); try { @@ -192,6 +186,8 @@ namespace cond { void forceInit(); + cond::persistency::Logger& logger() { return m_logger; } + private: struct Record { Record() @@ -212,13 +208,7 @@ namespace cond { // bool getTagInfo(const std::string& recordName, cond::TagInfo_t& result); - /** - void createNewIOV(const std::string& firstPayloadId, - const std::string payloadType, - cond::Time_t firstSinceTime, - cond::Time_t firstTillTime, - const std::string& recordName); - **/ + // void createNewIOV(const std::string& firstPayloadId, const std::string payloadType, cond::Time_t firstSinceTime, @@ -228,11 +218,6 @@ namespace cond { // Note: the iov index appended to MUST pre-existing and the existing // conditions data are retrieved from the DB // - /** - void appendSinceTime(const std::string& payloadId, - cond::Time_t sinceTime, - const std::string& recordName); - **/ bool appendSinceTime(const std::string& payloadId, cond::Time_t sinceTime, Record& record); //use these to control transaction interval @@ -250,10 +235,9 @@ namespace cond { cond::UserLogInfo& lookUpUserLogInfo(const std::string& recordName); private: - static constexpr const char* const MSGSOURCE = "PoolDBOuputService"; + cond::persistency::Logger m_logger; std::recursive_mutex m_mutex; cond::TimeType m_timetype; - //std::string m_timetypestr; std::vector m_currentTimes; cond::persistency::ConnectionPool m_connection; @@ -264,8 +248,6 @@ namespace cond { bool m_dbInitialised; std::map m_records; - //std::vector > m_newtags; - //bool m_closeIOV; std::map m_logheaders; }; //PoolDBOutputService diff --git a/CondCore/DBOutputService/src/OnlineDBOutputService.cc b/CondCore/DBOutputService/src/OnlineDBOutputService.cc index 9f8065c5f4411..24f109d043a3a 100644 --- a/CondCore/DBOutputService/src/OnlineDBOutputService.cc +++ b/CondCore/DBOutputService/src/OnlineDBOutputService.cc @@ -3,34 +3,13 @@ #include // -cond::service::OnlineDBOutputService::OnlineDBOutputService(const edm::ParameterSet& iConfig, - edm::ActivityRegistry& iAR) - : PoolDBOutputService(iConfig, iAR), - m_latencyInLumisections(iConfig.getUntrackedParameter("latency", 1)), - m_lastLumiUrl(iConfig.getUntrackedParameter("lastLumiUrl", "")), - m_preLoadConnectionString(iConfig.getUntrackedParameter("preLoadConnectionString", "")), - m_debug(iConfig.getUntrackedParameter("debugLogging", false)) { - if (!m_lastLumiUrl.empty()) { - startTransaction(); - m_runNumber = PoolDBOutputService::session().getCurrentRun().run; - } else { - m_lastLumiFile = iConfig.getUntrackedParameter("lastLumiFile", ""); - //if( m_lastLumiFile.size() == 0 ){ - // m_runNumber = iConfig.getUntrackedParameter("runNumber",100000); - // m_startRunTime = std::chrono::steady_clock::now(); - //} - } -} - -cond::service::OnlineDBOutputService::~OnlineDBOutputService() {} - static size_t getHtmlCallback(void* contents, size_t size, size_t nmemb, void* ptr) { // Cast ptr to std::string pointer and append contents to that string ((std::string*)ptr)->append((char*)contents, size * nmemb); return size * nmemb; } -bool getLatestLumiFromDAQ(const std::string& urlString, std::string& info) { +bool getInfoFromDAQ(const std::string& urlString, std::string& info) { CURL* curl; CURLcode res; std::string htmlBuffer; @@ -63,30 +42,91 @@ bool getLatestLumiFromDAQ(const std::string& urlString, std::string& info) { return ret; } +namespace cond { + + cond::Time_t getLatestLumiFromFile(const std::string& fileName) { + cond::Time_t lastLumiProcessed = cond::time::MIN_VAL; + std::ifstream lastLumiFile(fileName); + if (lastLumiFile) { + lastLumiFile >> lastLumiProcessed; + } else { + throw Exception(std::string("Can't access lastLumi file ") + fileName); + } + return lastLumiProcessed; + } + + cond::Time_t getLastLumiFromOMS(const std::string& omsServiceUrl) { + cond::Time_t lastLumiProcessed = cond::time::MIN_VAL; + std::string info(""); + if (!getInfoFromDAQ(omsServiceUrl, info)) + throw Exception("Can't get data from OMS Service."); + std::istringstream sinfo(info); + std::string srun; + if (!std::getline(sinfo, srun, ',')) { + throw Exception("Can't get run runmber info from OMS Service."); + } + std::string slumi; + if (!std::getline(sinfo, slumi, ',')) { + throw Exception("Can't get lumi id from OMS Service."); + } + unsigned int run = boost::lexical_cast(srun); + unsigned int lumi = boost::lexical_cast(slumi); + lastLumiProcessed = cond::time::lumiTime(run, lumi); + return lastLumiProcessed; + } + +} // namespace cond + +cond::service::OnlineDBOutputService::OnlineDBOutputService(const edm::ParameterSet& iConfig, + edm::ActivityRegistry& iAR) + : PoolDBOutputService(iConfig, iAR), + m_runNumber(iConfig.getUntrackedParameter("runNumber", 0)), + m_latencyInLumisections(iConfig.getUntrackedParameter("latency", 1)), + m_omsServiceUrl(iConfig.getUntrackedParameter("omsServiceUrl", "")), + m_lastLumiUrl(iConfig.getUntrackedParameter("lastLumiUrl", "")), + m_preLoadConnectionString(iConfig.getUntrackedParameter("preLoadConnectionString", "")), + m_debug(iConfig.getUntrackedParameter("debugLogging", false)) { + if (m_omsServiceUrl.empty()) { + if (!m_lastLumiUrl.empty()) { + startTransaction(); + auto lastRun = PoolDBOutputService::session().getLastRun(); + if (lastRun.isOnGoing()) { + m_runNumber = lastRun.run; + } + } else { + m_lastLumiFile = iConfig.getUntrackedParameter("lastLumiFile", ""); + } + } +} + +cond::service::OnlineDBOutputService::~OnlineDBOutputService() {} + cond::Time_t cond::service::OnlineDBOutputService::getLastLumiProcessed() { cond::Time_t lastLumiProcessed = cond::time::MIN_VAL; - unsigned int lastL = 0; - if (!m_lastLumiUrl.empty()) { - std::string info(""); - if (!getLatestLumiFromDAQ(m_lastLumiUrl, info)) - throw Exception("Can't get last Lumisection from DAQ."); - lastL = boost::lexical_cast(info); - lastLumiProcessed = cond::time::lumiTime(m_runNumber, lastL); - edm::LogInfo(MSGSOURCE) << "Last lumi: " << lastLumiProcessed << " Current run: " << m_runNumber - << " lumi id:" << lastL; + std::string info(""); + if (!m_omsServiceUrl.empty()) { + lastLumiProcessed = cond::getLastLumiFromOMS(m_omsServiceUrl); + logger().logInfo() << "Last lumi: " << lastLumiProcessed + << " Current run: " << cond::time::unpack(lastLumiProcessed).first + << " lumi id:" << cond::time::unpack(lastLumiProcessed).second; } else { - if (m_lastLumiFile.empty()) { - //auto t1 = std::chrono::steady_clock::now(); - //auto deltat = std::chrono::duration_cast( t1 - m_startRunTime ).count(); - //lastL = (unsigned int)(deltat/23); - //lastLumiProcessed = cond::time::lumiTime( m_runNumber, lastL ); - //edm::LogInfo( MSGSOURCE ) << "Last lumi: "<(info); + lastLumiProcessed = cond::time::lumiTime(m_runNumber, lastL); + logger().logInfo() << "Last lumi: " << lastLumiProcessed << " Current run: " << m_runNumber + << " lumi id:" << lastL; } else { - lastLumiProcessed = cond::getLatestLumiFromFile(m_lastLumiFile); - auto upkTime = cond::time::unpack(lastLumiProcessed); - edm::LogInfo(MSGSOURCE) << "Last lumi: " << lastLumiProcessed << " Current run: " << upkTime.first - << " lumi id:" << upkTime.second; + if (m_lastLumiFile.empty()) { + throw Exception("File name for last lumi has not been provided."); + } else { + lastLumiProcessed = cond::getLatestLumiFromFile(m_lastLumiFile); + auto upkTime = cond::time::unpack(lastLumiProcessed); + logger().logInfo() << "Last lumi: " << lastLumiProcessed << " Current run: " << upkTime.first + << " lumi id:" << upkTime.second; + } } } return lastLumiProcessed; diff --git a/CondCore/DBOutputService/src/PoolDBOutputService.cc b/CondCore/DBOutputService/src/PoolDBOutputService.cc index ee7f1e94718ea..f9e4d4c75a707 100644 --- a/CondCore/DBOutputService/src/PoolDBOutputService.cc +++ b/CondCore/DBOutputService/src/PoolDBOutputService.cc @@ -35,7 +35,13 @@ void cond::service::PoolDBOutputService::fillRecord(edm::ParameterSet& recordPse } cond::service::PoolDBOutputService::PoolDBOutputService(const edm::ParameterSet& iConfig, edm::ActivityRegistry& iAR) - : m_currentTimes{}, m_session(), m_transactionActive(false), m_dbInitialised(false), m_records(), m_logheaders() { + : m_logger(iConfig.getUntrackedParameter("jobName", "DBOutputService")), + m_currentTimes{}, + m_session(), + m_transactionActive(false), + m_dbInitialised(false), + m_records(), + m_logheaders() { std::string timetypestr = iConfig.getUntrackedParameter("timetype", "runnumber"); m_timetype = cond::time::timeTypeFromName(timetypestr); m_autoCommit = iConfig.getUntrackedParameter("autoCommit", false); @@ -43,9 +49,13 @@ cond::service::PoolDBOutputService::PoolDBOutputService(const edm::ParameterSet& edm::ParameterSet connectionPset = iConfig.getParameter("DBParameters"); m_connection.setParameters(connectionPset); + m_connection.setLogDestination(m_logger); m_connection.configure(); std::string connectionString = iConfig.getParameter("connect"); m_session = m_connection.createSession(connectionString, true); + bool saveLogsOnDb = iConfig.getUntrackedParameter("saveLogsOnDB", false); + if (saveLogsOnDb) + m_logger.setDbDestination(connectionString, m_connection); // implicit start doStartTransaction(); @@ -122,7 +132,6 @@ void cond::service::PoolDBOutputService::initDB() { m_session.createDatabase(); else { for (auto& iR : m_records) { - std::cout << "CHECK TAG " << iR.second.m_tag << std::endl; if (m_session.existsIov(iR.second.m_tag)) iR.second.m_isNewTag = false; } @@ -130,39 +139,6 @@ void cond::service::PoolDBOutputService::initDB() { m_dbInitialised = true; } } -/** -void cond::service::PoolDBOutputService::initDB() { - std::lock_guard lock(m_mutex); - if (!m_dbstarted) { - cond::persistency::TransactionScope scope(m_session.transaction()); - scope.start(false); - try { - if (!m_session.existsDatabase()) - m_session.createDatabase(); - else { - for (auto& iR : m_records) { - std::cout <<"CHECK TAG "< lock(m_mutex); - if (m_dbstarted) { - m_session.transaction().commit(); - m_dbstarted = false; - } - m_dbstarted = true; -} -**/ void cond::service::PoolDBOutputService::postEndJob() { commitTransaction(); } @@ -192,11 +168,7 @@ void cond::service::PoolDBOutputService::preGlobalBeginLumi(edm::GlobalContext c } } -cond::service::PoolDBOutputService::~PoolDBOutputService() { - //if (m_dbstarted) { - // m_session.transaction().rollback(); - //} -} +cond::service::PoolDBOutputService::~PoolDBOutputService() {} void cond::service::PoolDBOutputService::forceInit() { std::lock_guard lock(m_mutex); @@ -227,9 +199,8 @@ void cond::service::PoolDBOutputService::createNewIOV(const std::string& firstPa if (!myrecord.m_isNewTag) { cond::throwException(myrecord.m_tag + " is not a new tag", "PoolDBOutputService::createNewIOV"); } - edm::LogInfo(MSGSOURCE) << "Creating new tag " << myrecord.m_tag << ", adding iov with since " << firstSinceTime - << " pointing to payload id " << firstPayloadId; - std::cout << "CreateNewIOV II: opening trans..." << std::endl; + m_logger.logInfo() << "Creating new tag " << myrecord.m_tag << ", adding iov with since " << firstSinceTime + << " pointing to payload id " << firstPayloadId; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); try { @@ -251,20 +222,8 @@ void cond::service::PoolDBOutputService::createNewIOV(const std::string& firstPa const std::string payloadType, cond::Time_t firstSinceTime, Record& myrecord) { - //std::lock_guard lock(m_mutex); - //startTransaction(); - //cond::persistency::TransactionScope scope(m_session.transaction()); - //try { - // initDB(); - //Record& myrecord = this->lookUpRecord(recordName); - //if (!myrecord.m_isNewTag) { - // cond::throwException(myrecord.m_tag + " is not a new tag", "PoolDBOutputService::createNewIOV"); - //} - //std::string iovToken; - - //try { - edm::LogInfo(MSGSOURCE) << "Creating new tag " << myrecord.m_tag << " for payload type " << payloadType - << ", adding iov with since " << firstSinceTime; + m_logger.logInfo() << "Creating new tag " << myrecord.m_tag << " for payload type " << payloadType + << ", adding iov with since " << firstSinceTime; // FIX ME: synchronization type and description have to be passed as the other parameters? cond::persistency::IOVEditor editor = m_session.createIov(payloadType, myrecord.m_tag, myrecord.m_timetype, cond::SYNCH_ANY); @@ -273,43 +232,7 @@ void cond::service::PoolDBOutputService::createNewIOV(const std::string& firstPa cond::UserLogInfo a = this->lookUpUserLogInfo(myrecord.m_idName); editor.flush(a.usertext); myrecord.m_isNewTag = false; - //} catch (const std::exception& er) { - // cond::throwException(std::string(er.what()) + " from PoolDBOutputService::createNewIOV ", - // "PoolDBOutputService::createNewIOV"); - //} - //scope.close(); -} - -/** -void cond::service::PoolDBOutputService::createNewIOV(const std::string& firstPayloadId, - cond::Time_t firstSinceTime, - cond::Time_t firstTillTime, - const std::string& recordName) { - std::lock_guard lock(m_mutex); - cond::persistency::TransactionScope scope(m_session.transaction()); - Record& myrecord = this->lookUpRecord(recordName); - if (!myrecord.m_isNewTag) { - cond::throwException(myrecord.m_tag + " is not a new tag", "PoolDBOutputService::createNewIOV"); - } - std::string iovToken; - std::string payloadType(""); - try { - // FIX ME: synchronization type and description have to be passed as the other parameters? - cond::persistency::IOVEditor editor = - m_session.createIovForPayload(firstPayloadId, myrecord.m_tag, myrecord.m_timetype, cond::SYNCH_ANY); - editor.setDescription("New Tag"); - payloadType = editor.payloadType(); - editor.insert(firstSinceTime, firstPayloadId); - cond::UserLogInfo a = this->lookUpUserLogInfo(recordName); - editor.flush(a.usertext); - myrecord.m_isNewTag = false; - } catch (const std::exception& er) { - cond::throwException(std::string(er.what()) + " from PoolDBOutputService::createNewIOV ", - "PoolDBOutputService::createNewIOV"); - } - scope.close(); } -**/ bool cond::service::PoolDBOutputService::appendSinceTime(const std::string& payloadId, cond::Time_t time, @@ -321,7 +244,6 @@ bool cond::service::PoolDBOutputService::appendSinceTime(const std::string& payl "PoolDBOutputService::appendSinceTime"); } bool ret = false; - std::cout << "appendSinceTime II: opening trans..." << std::endl; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); try { @@ -336,14 +258,7 @@ bool cond::service::PoolDBOutputService::appendSinceTime(const std::string& payl bool cond::service::PoolDBOutputService::appendSinceTime(const std::string& payloadId, cond::Time_t time, Record& myrecord) { - //std::lock_guard lock(m_mutex); - //cond::persistency::TransactionScope scope(m_session.transaction()); - //Record& myrecord = this->lookUpRecord(recordName); - //if (myrecord.m_isNewTag) { - // cond::throwException(std::string("Cannot append to non-existing tag ") + myrecord.m_tag, - // "PoolDBOutputService::appendSinceTime"); - //} - edm::LogInfo(MSGSOURCE) << "Updating existing tag " << myrecord.m_tag << ", adding iov with since " << time; + m_logger.logInfo() << "Updating existing tag " << myrecord.m_tag << ", adding iov with since " << time; std::string payloadType(""); try { cond::persistency::IOVEditor editor = m_session.editIov(myrecord.m_tag); @@ -355,7 +270,6 @@ bool cond::service::PoolDBOutputService::appendSinceTime(const std::string& payl cond::throwException(std::string(er.what()), "PoolDBOutputService::appendSinceTime"); } return true; - //scope.close(); } void cond::service::PoolDBOutputService::eraseSinceTime(const std::string& payloadId, @@ -367,8 +281,8 @@ void cond::service::PoolDBOutputService::eraseSinceTime(const std::string& paylo cond::throwException(std::string("Cannot delete from non-existing tag ") + myrecord.m_tag, "PoolDBOutputService::appendSinceTime"); } - edm::LogInfo(MSGSOURCE) << "Updating existing tag " << myrecord.m_tag << ", removing iov with since " << sinceTime - << " pointing to payload id " << payloadId; + m_logger.logInfo() << "Updating existing tag " << myrecord.m_tag << ", removing iov with since " << sinceTime + << " pointing to payload id " << payloadId; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); try { @@ -385,21 +299,11 @@ void cond::service::PoolDBOutputService::eraseSinceTime(const std::string& paylo cond::service::PoolDBOutputService::Record& cond::service::PoolDBOutputService::lookUpRecord( const std::string& recordName) { - //std::lock_guard lock(m_mutex); - //if (!m_dbstarted) - // this->initDB(); - //cond::persistency::TransactionScope scope(m_session.transaction()); std::map::iterator it = m_records.find(recordName); if (it == m_records.end()) { cond::throwException("The record \"" + recordName + "\" has not been registered.", "PoolDBOutputService::lookUpRecord"); } - //if (!m_session.existsIov(it->second.m_tag)) { - // it->second.m_isNewTag = true; - //} else { - // it->second.m_isNewTag = false; - //} - //scope.close(); return it->second; } @@ -413,14 +317,12 @@ cond::UserLogInfo& cond::service::PoolDBOutputService::lookUpUserLogInfo(const s void cond::service::PoolDBOutputService::closeIOV(Time_t lastTill, const std::string& recordName) { std::lock_guard lock(m_mutex); - // not fully working.. not be used for now... Record& myrecord = lookUpRecord(recordName); if (myrecord.m_isNewTag) { cond::throwException(std::string("Cannot close non-existing tag ") + myrecord.m_tag, "PoolDBOutputService::closeIOV"); } - edm::LogInfo(MSGSOURCE) << "Updating existing tag " << myrecord.m_tag << ", closing with end of validity " - << lastTill; + m_logger.logInfo() << "Updating existing tag " << myrecord.m_tag << ", closing with end of validity " << lastTill; doStartTransaction(); cond::persistency::TransactionScope scope(m_session.transaction()); try { @@ -445,8 +347,7 @@ void cond::service::PoolDBOutputService::setLogHeaderForRecord(const std::string bool cond::service::PoolDBOutputService::getTagInfo(const std::string& recordName, cond::TagInfo_t& result) { Record& record = lookUpRecord(recordName); result.name = record.m_tag; - LogDebug(MSGSOURCE) << "Fetching tag info for " << record.m_tag; - std::cout << "getTagInfo: opening trans..." << std::endl; + m_logger.logDebug() << "Fetching tag info for " << record.m_tag; doStartTransaction(); bool ret = false; cond::persistency::TransactionScope scope(m_session.transaction()); diff --git a/CondCore/DBOutputService/test/BuildFile.xml b/CondCore/DBOutputService/test/BuildFile.xml index 3217bb8ed7f3b..d1c05f97d1352 100644 --- a/CondCore/DBOutputService/test/BuildFile.xml +++ b/CondCore/DBOutputService/test/BuildFile.xml @@ -1,7 +1,6 @@ - diff --git a/CondCore/DBOutputService/test/python/testIOVPayloadAnalyzer_example_oracle_cfg.py b/CondCore/DBOutputService/test/python/testIOVPayloadAnalyzer_example_oracle_cfg.py index 8c58376d64557..4c973208147f6 100644 --- a/CondCore/DBOutputService/test/python/testIOVPayloadAnalyzer_example_oracle_cfg.py +++ b/CondCore/DBOutputService/test/python/testIOVPayloadAnalyzer_example_oracle_cfg.py @@ -2,7 +2,7 @@ process = cms.Process("TEST") process.load("CondCore.CondDB.CondDB_cfi") -process.CondDB.connect = 'oracle://cms_orcoff_prep/CMS_COND_WEB' +process.CondDB.connect = 'oracle://cms_orcoff_prep/CMS_CONDITIONS' process.CondDB.DBParameters.authenticationPath = '/afs/cern.ch/cms/DB/conddb' #process.CondDB.DBParameters.messageLevel = cms.untracked.int32(3) diff --git a/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_cfg.py b/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_cfg.py index d87e4e514ec4e..5cc6c027a4622 100644 --- a/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_cfg.py +++ b/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_cfg.py @@ -8,15 +8,23 @@ interval = cms.uint64(11) ) +process.MessageLogger = cms.Service("MessageLogger", + cout = cms.untracked.PSet(threshold = cms.untracked.string('DEBUG')), + destinations = cms.untracked.vstring('cout') +) + process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", DBParameters = cms.PSet( - messageLevel = cms.untracked.int32(0), + messageLevel = cms.untracked.int32(2), authenticationPath = cms.untracked.string('.') ), #timetype = cms.untracked.string('runnumber'), + jobName = cms.untracked.string("TestLumiBasedUpdate"), + autoCommit = cms.untracked.bool(True), connect = cms.string('sqlite_file:test_lumi.db'), preLoadConnectionString = cms.untracked.string('sqlite_file:test_lumi.db'), - runNumber = cms.untracked.uint64(120000), + #omsServiceUrl = cms.untracked.string('http://cmsoms-services.cms:9949/urn:xdaq-application:lid=100/getRunAndLumiSection'), + lastLumiFile = cms.untracked.string('lastLumi.txt'), toPut = cms.VPSet(cms.PSet( record = cms.string('PedestalsRcd'), tag = cms.string('mytest'), @@ -26,7 +34,9 @@ ) process.mytest = cms.EDAnalyzer("LumiBasedUpdateAnalyzer", - record = cms.string('PedestalsRcd') + record = cms.string('PedestalsRcd'), + lastLumiFile = cms.untracked.string('lastLumi.txt') + #omsServiceUrl = cms.untracked.string('http://cmsoms-services.cms:9949/urn:xdaq-application:lid=100/getRunAndLumiSection') ) process.p = cms.Path(process.mytest) diff --git a/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_oracle.cfg.py b/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_oracle.cfg.py index 776a3a241c6da..9b2843be2a2b5 100644 --- a/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_oracle.cfg.py +++ b/CondCore/DBOutputService/test/python/testLumiBasedUpdateAnalyzer_oracle.cfg.py @@ -29,16 +29,19 @@ process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", DBParameters = cms.PSet( - messageLevel = cms.untracked.int32(0), + messageLevel = cms.untracked.int32(1), authenticationPath = cms.untracked.string('/build/gg') ), #timetype = cms.untracked.string('runnumber'), + jobName = cms.untracked.string("TestLumiBasedUpdate"), connect = cms.string('oracle://cms_orcoff_prep/CMS_CONDITIONS'), preLoadConnectionString = cms.untracked.string('frontier://FrontierPrep/CMS_CONDITIONS'), - runNumber = cms.untracked.uint64(options.runNumber), - lastLumiFile = cms.untracked.string('/build/gg/last_lumi.txt'), - writeTransactionDelay = cms.untracked.uint32(options.transDelay), + runNumber = cms.untracked.uint64(options.runNumber), + #lastLumiFile = cms.untracked.string('/build/gg/last_lumi.txt'), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), autoCommit = cms.untracked.bool(True), + lastLumiFile = cms.untracked.string('lastLumi.txt'), + saveLogsOnDB = cms.untracked.bool(True), toPut = cms.VPSet(cms.PSet( record = cms.string('PedestalsRcd'), tag = cms.string('BeamSpot_test_updateByLumi_00'), diff --git a/CondCore/DBOutputService/test/python/writeInt_cfg.py b/CondCore/DBOutputService/test/python/writeInt_cfg.py index babbb4f133a54..3cf585086e70e 100644 --- a/CondCore/DBOutputService/test/python/writeInt_cfg.py +++ b/CondCore/DBOutputService/test/python/writeInt_cfg.py @@ -24,7 +24,7 @@ ) process.mytest = cms.EDAnalyzer("writeInt", - Number=cms.int32(_CurrentRun_) + Number=cms.int32(100000) ) process.p = cms.Path(process.mytest) diff --git a/CondCore/DBOutputService/test/python/writeMultipleRecords_oracle_cfg.py b/CondCore/DBOutputService/test/python/writeMultipleRecords_oracle_cfg.py index 3df29d550a0fc..6cf95f2ce4cb0 100644 --- a/CondCore/DBOutputService/test/python/writeMultipleRecords_oracle_cfg.py +++ b/CondCore/DBOutputService/test/python/writeMultipleRecords_oracle_cfg.py @@ -2,8 +2,8 @@ process = cms.Process("TEST") process.load("CondCore.CondDB.CondDB_cfi") -process.CondDB.connect = cms.string('oracle://cms_orcoff_prep/CMS_COND_WEB') -process.CondDB.DBParameters.authenticationPath = '/afs/cern.ch/cms/DB/conddb/test' +process.CondDB.connect = cms.string('oracle://cms_orcoff_prep/CMS_CONDITIONS') +process.CondDB.DBParameters.authenticationPath = '/afs/cern.ch/cms/DB/conddb' process.source = cms.Source("EmptyIOVSource", lastValue = cms.uint64(1), diff --git a/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.cc b/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.cc index a910a81222454..de009ad66a14b 100644 --- a/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.cc +++ b/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.cc @@ -14,6 +14,7 @@ LumiBasedUpdateAnalyzer::LumiBasedUpdateAnalyzer(const edm::ParameterSet& iConfi std::cout << "LumiBasedUpdateAnalyzer::LumiBasedUpdateAnalyzer" << std::endl; m_prevLumi = 0; m_prevLumiTime = std::chrono::steady_clock::now(); + m_omsServiceUrl = iConfig.getUntrackedParameter("omsServiceUrl", ""); } LumiBasedUpdateAnalyzer::~LumiBasedUpdateAnalyzer() { std::cout << "LumiBasedUpdateAnalyzer::~LumiBasedUpdateAnalyzer" << std::endl; @@ -25,27 +26,44 @@ void LumiBasedUpdateAnalyzer::analyze(const edm::Event& evt, const edm::EventSet std::cout << "Service is unavailable" << std::endl; return; } + mydbservice->logger().start(); unsigned int irun = evt.id().run(); - cond::Time_t lastLumi = cond::getLatestLumiFromFile(m_lastLumiFile); - if (lastLumi == m_prevLumi) { - return; + cond::Time_t lastLumi = cond::time::MIN_VAL; + if (!m_omsServiceUrl.empty()) { + lastLumi = cond::getLastLumiFromOMS(m_omsServiceUrl); + } else { + lastLumi = cond::getLatestLumiFromFile(m_lastLumiFile); + if (lastLumi == m_prevLumi) { + mydbservice->logger().logInfo() << "Last lumi:" << lastLumi << " Prev lumi:" << m_prevLumi; + mydbservice->logger().end(1); + return; + } + m_prevLumi = lastLumi; + m_prevLumiTime = std::chrono::steady_clock::now(); } - m_prevLumi = lastLumi; - m_prevLumiTime = std::chrono::steady_clock::now(); unsigned int lumiId = cond::time::unpack(lastLumi).second; - std::cout << "## last lumi: " << lastLumi << " run: " << cond::time::unpack(lastLumi).first << " lumiid:" << lumiId - << std::endl; + mydbservice->logger().logInfo() << "Last lumi: " << lastLumi << " run: " << cond::time::unpack(lastLumi).first + << " lumiid:" << lumiId; std::string tag = mydbservice->tag(m_record); std::cout << "tag " << tag << std::endl; std::cout << "run " << irun << std::endl; + mydbservice->logger().logDebug() << "Tag: " << tag << " Run: " << irun; BeamSpotObjects mybeamspot; mybeamspot.SetPosition(0.053, 0.1, 0.13); mybeamspot.SetSigmaZ(3.8); mybeamspot.SetType(int(lumiId)); std::cout << mybeamspot.GetBeamType() << std::endl; - - mydbservice->writeForNextLumisection(&mybeamspot, m_record); + mydbservice->logger().logDebug() << "BeamType: " << mybeamspot.GetBeamType(); + int ret = 0; + try { + mydbservice->writeForNextLumisection(&mybeamspot, m_record); + } catch (const std::exception& e) { + std::cout << "Error:" << e.what() << std::endl; + mydbservice->logger().logError() << e.what(); + ret = -1; + } //::sleep(13); + mydbservice->logger().end(ret); } void LumiBasedUpdateAnalyzer::endJob() {} DEFINE_FWK_MODULE(LumiBasedUpdateAnalyzer); diff --git a/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.h b/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.h index b245bbccb8f82..1da4c4a57f92f 100644 --- a/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.h +++ b/CondCore/DBOutputService/test/stubs/LumiBasedUpdateAnalyzer.h @@ -25,6 +25,7 @@ class LumiBasedUpdateAnalyzer : public edm::EDAnalyzer { std::string m_lastLumiFile; cond::Time_t m_prevLumi; std::chrono::time_point m_prevLumiTime; + std::string m_omsServiceUrl; // ----------member data --------------------------- }; #endif diff --git a/CondCore/L1TPlugins/src/UpgradeRecords4.cc b/CondCore/L1TPlugins/src/UpgradeRecords4.cc index 394f24751a381..db2b75311d154 100644 --- a/CondCore/L1TPlugins/src/UpgradeRecords4.cc +++ b/CondCore/L1TPlugins/src/UpgradeRecords4.cc @@ -18,3 +18,9 @@ REGISTER_PLUGIN(L1TGlobalParametersRcd, L1TGlobalParameters); #include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosO2ORcd.h" REGISTER_PLUGIN(L1TGlobalPrescalesVetosRcd, L1TGlobalPrescalesVetos); REGISTER_PLUGIN(L1TGlobalPrescalesVetosO2ORcd, L1TGlobalPrescalesVetos); + +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h" +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h" +REGISTER_PLUGIN(L1TGlobalPrescalesVetosFractRcd, L1TGlobalPrescalesVetosFract); +REGISTER_PLUGIN(L1TGlobalPrescalesVetosFractO2ORcd, L1TGlobalPrescalesVetosFract); \ No newline at end of file diff --git a/CondCore/PopCon/src/PopCon.cc b/CondCore/PopCon/src/PopCon.cc index be9d5ad0653a4..7934274d6cfea 100644 --- a/CondCore/PopCon/src/PopCon.cc +++ b/CondCore/PopCon/src/PopCon.cc @@ -37,6 +37,7 @@ namespace popcon { if (!m_dbService.isAvailable()) throw Exception("DBService not available"); const std::string& connectionStr = m_dbService->session().connectionString(); + m_dbService->forceInit(); m_tag = m_dbService->tag(m_record); m_tagInfo.name = m_tag; if (m_targetConnectionString.empty()) @@ -51,15 +52,15 @@ namespace popcon { } if (m_targetSession.existsDatabase() && m_targetSession.existsIov(m_tag)) { cond::persistency::IOVProxy iov = m_targetSession.readIov(m_tag); - size_t tagSize = iov.sequenceSize(); - if (tagSize > 0) { + m_tagInfo.size = iov.sequenceSize(); + if (m_tagInfo.size > 0) { m_tagInfo.lastInterval = iov.getLast(); } edm::LogInfo("PopCon") << "destination DB: " << connectionStr << ", target DB: " << (m_targetConnectionString.empty() ? connectionStr : m_targetConnectionString) << "\n" << "TAG: " << m_tag << ", last since/till: " << m_tagInfo.lastInterval.since << "/" - << m_tagInfo.lastInterval.till << ", size: " << tagSize << "\n" + << m_tagInfo.lastInterval.till << ", size: " << m_tagInfo.size << "\n" << std::endl; } else { edm::LogInfo("PopCon") << "destination DB: " << connectionStr << ", target DB: " diff --git a/CondCore/SiPixelPlugins/interface/Phase1PixelMaps.h b/CondCore/SiPixelPlugins/interface/Phase1PixelMaps.h index 3c5835e6589a4..168049075babc 100644 --- a/CondCore/SiPixelPlugins/interface/Phase1PixelMaps.h +++ b/CondCore/SiPixelPlugins/interface/Phase1PixelMaps.h @@ -28,7 +28,7 @@ class Phase1PixelMaps { ~Phase1PixelMaps() {} //============================================================================ - void bookBarrelHistograms(const std::string& currentHistoName, const char* what) { + void bookBarrelHistograms(const std::string& currentHistoName, const char* what, const char* zaxis) { std::string histName; std::shared_ptr th2p; @@ -46,8 +46,8 @@ class Phase1PixelMaps { th2p->GetXaxis()->SetTitle("z [cm]"); th2p->GetYaxis()->SetTitle("ladder"); - //th2p->GetXaxis()->SetTitleOffset(0.09); - //th2p->GetYaxis()->SetTitleOffset(0.09); + th2p->GetZaxis()->SetTitle(zaxis); + th2p->GetZaxis()->CenterTitle(); th2p->SetStats(false); th2p->SetOption(m_option); pxbTh2PolyBarrel[currentHistoName].push_back(th2p); @@ -64,7 +64,7 @@ class Phase1PixelMaps { } //============================================================================ - void bookForwardHistograms(const std::string& currentHistoName, const char* what) { + void bookForwardHistograms(const std::string& currentHistoName, const char* what, const char* zaxis) { std::string histName; std::shared_ptr th2p; @@ -81,8 +81,8 @@ class Phase1PixelMaps { th2p->SetFloat(); th2p->GetXaxis()->SetTitle("x [cm]"); th2p->GetYaxis()->SetTitle("y [cm]"); - //th2p->GetXaxis()->SetTitleOffset(0.09); - //th2p->GetYaxis()->SetTitleOffset(0.09); + th2p->GetZaxis()->SetTitle(zaxis); + th2p->GetZaxis()->CenterTitle(); th2p->SetStats(false); th2p->SetOption(m_option); pxfTh2PolyForward[currentHistoName].push_back(th2p); @@ -208,6 +208,8 @@ class Phase1PixelMaps { SiPixelPI::makeNicePlotStyle(plot.get()); plot->GetXaxis()->SetTitleOffset(0.9); plot->GetYaxis()->SetTitleOffset(0.9); + plot->GetZaxis()->SetTitleOffset(1.2); + plot->GetZaxis()->SetTitleSize(0.05); } } @@ -216,10 +218,54 @@ class Phase1PixelMaps { SiPixelPI::makeNicePlotStyle(plot.get()); plot->GetXaxis()->SetTitleOffset(0.9); plot->GetYaxis()->SetTitleOffset(0.9); + plot->GetZaxis()->SetTitleOffset(1.2); + plot->GetZaxis()->SetTitleSize(0.05); } } } + //============================================================================ + void rescaleAllBarrel(const std::string& currentHistoName) { + std::vector maxima; + std::transform(pxbTh2PolyBarrel[currentHistoName].begin(), + pxbTh2PolyBarrel[currentHistoName].end(), + std::back_inserter(maxima), + [](std::shared_ptr thp) -> float { return thp->GetMaximum(); }); + std::vector minima; + std::transform(pxbTh2PolyBarrel[currentHistoName].begin(), + pxbTh2PolyBarrel[currentHistoName].end(), + std::back_inserter(minima), + [](std::shared_ptr thp) -> float { return thp->GetMinimum(); }); + + auto globalMax = *std::max_element(maxima.begin(), maxima.end()); + auto globalMin = *std::min_element(minima.begin(), minima.end()); + + for (auto& histo : pxbTh2PolyBarrel[currentHistoName]) { + histo->GetZaxis()->SetRangeUser(globalMin, globalMax); + } + } + + //============================================================================ + void rescaleAllForward(const std::string& currentHistoName) { + std::vector maxima; + std::transform(pxfTh2PolyForward[currentHistoName].begin(), + pxfTh2PolyForward[currentHistoName].end(), + std::back_inserter(maxima), + [](std::shared_ptr thp) -> float { return thp->GetMaximum(); }); + std::vector minima; + std::transform(pxfTh2PolyForward[currentHistoName].begin(), + pxfTh2PolyForward[currentHistoName].end(), + std::back_inserter(minima), + [](std::shared_ptr thp) -> float { return thp->GetMinimum(); }); + + auto globalMax = *std::max_element(maxima.begin(), maxima.end()); + auto globalMin = *std::min_element(minima.begin(), minima.end()); + + for (auto& histo : pxfTh2PolyForward[currentHistoName]) { + histo->GetZaxis()->SetRangeUser(globalMin, globalMax); + } + } + //============================================================================ void DrawBarrelMaps(const std::string& currentHistoName, TCanvas& canvas) { canvas.Divide(2, 2); @@ -229,7 +275,8 @@ class Phase1PixelMaps { canvas.cd(i)->SetRightMargin(0.02); pxbTh2PolyBarrel[currentHistoName].at(i - 1)->SetMarkerColor(kRed); } else { - SiPixelPI::adjustCanvasMargins(canvas.cd(i), 0.07, 0.12, 0.10, 0.14); + rescaleAllBarrel(currentHistoName); + SiPixelPI::adjustCanvasMargins(canvas.cd(i), 0.07, 0.12, 0.10, 0.18); } pxbTh2PolyBarrel[currentHistoName].at(i - 1)->Draw(); } @@ -244,7 +291,8 @@ class Phase1PixelMaps { canvas.cd(i)->SetRightMargin(0.02); pxfTh2PolyForward[currentHistoName].at(i - 1)->SetMarkerColor(kRed); } else { - SiPixelPI::adjustCanvasMargins(canvas.cd(i), 0.07, 0.12, 0.10, 0.16); + rescaleAllForward(currentHistoName); + SiPixelPI::adjustCanvasMargins(canvas.cd(i), 0.07, 0.12, 0.10, 0.18); } pxfTh2PolyForward[currentHistoName].at(i - 1)->Draw(); } diff --git a/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h b/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h index d80b88458b303..83215f55d5ad2 100644 --- a/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h +++ b/CondCore/SiPixelPlugins/interface/PixelRegionContainers.h @@ -200,7 +200,7 @@ namespace PixelRegions { } //============================================================================ - void draw(TCanvas& canv, bool isBarrel, const char* option = "bar2", bool isComparison = false) { + void draw(TCanvas& canv, bool isBarrel, const char* option = "bar2", bool isPhase1Comparison = false) { if (isBarrel) { for (int j = 1; j <= 4; j++) { if (!m_isLog) { @@ -208,7 +208,7 @@ namespace PixelRegions { } else { canv.cd(j)->SetLogy(); } - if ((j == 4) && !m_isPhase1 && !isComparison) { + if ((j == 4) && !m_isPhase1 && !isPhase1Comparison) { m_theMap.at(PixelIDs[j - 1])->Draw("AXIS"); TLatex t2; t2.SetTextAlign(22); @@ -228,7 +228,7 @@ namespace PixelRegions { } else { canv.cd(j)->SetLogy(); } - if ((j % 6 == 5 || j % 6 == 0) && !m_isPhase1 && !isComparison) { + if ((j % 6 == 5 || j % 6 == 0) && !m_isPhase1 && !isPhase1Comparison) { m_theMap.at(PixelIDs[j + 3])->Draw("AXIS"); TLatex t2; t2.SetTextAlign(22); diff --git a/CondCore/SiPixelPlugins/interface/SiPixelGainCalibHelper.h b/CondCore/SiPixelPlugins/interface/SiPixelGainCalibHelper.h index f2cf840075a7c..a5d60e691d0dc 100644 --- a/CondCore/SiPixelPlugins/interface/SiPixelGainCalibHelper.h +++ b/CondCore/SiPixelPlugins/interface/SiPixelGainCalibHelper.h @@ -334,7 +334,7 @@ namespace gainCalibHelper { auto iov = tag.iovs.front(); // parse first if log - bool setLog(false); + bool setLog(true); auto paramValues = cond::payloadInspector::PlotBase::inputParamValues(); auto ip = paramValues.find("SetLog"); if (ip != paramValues.end()) { @@ -404,7 +404,7 @@ namespace gainCalibHelper { if (setLog) { myPlots.setLogScale(); } - myPlots.beautify(kBlue, 10); + myPlots.beautify(kBlue, -1); myPlots.draw(canvas, isBarrel, "HIST"); TLegend legend = TLegend(0.45, 0.88, 0.91, 0.92); @@ -418,7 +418,7 @@ namespace gainCalibHelper { unsigned int maxPads = isBarrel ? 4 : 12; for (unsigned int c = 1; c <= maxPads; c++) { canvas.cd(c); - SiPixelPI::adjustCanvasMargins(canvas.cd(c), 0.07, 0.12, 0.12, 0.05); + SiPixelPI::adjustCanvasMargins(canvas.cd(c), 0.06, 0.12, 0.12, 0.05); legend.Draw("same"); canvas.cd(c)->Update(); } @@ -453,12 +453,16 @@ namespace gainCalibHelper { /******************************************************************* 1d histograms comparison per region of SiPixelGainCalibration for Gains of 2 IOV ********************************************************************/ - template + template class SiPixelGainCalibrationValuesComparisonPerRegion - : public cond::payloadInspector::PlotImage { + : public cond::payloadInspector::PlotImage { public: SiPixelGainCalibrationValuesComparisonPerRegion() - : cond::payloadInspector::PlotImage( + : cond::payloadInspector::PlotImage( Form("SiPixelGainCalibration %s Values Per Region %i tag(s)", TypeName[myType], ntags)) { cond::payloadInspector::PlotBase::addInputParam("SetLog"); @@ -495,7 +499,7 @@ namespace gainCalibHelper { } // parse first if log - bool setLog(false); + bool setLog(true); auto paramValues = cond::payloadInspector::PlotBase::inputParamValues(); auto ip = paramValues.find("SetLog"); if (ip != paramValues.end()) { @@ -545,13 +549,15 @@ namespace gainCalibHelper { canvas.Divide(isBarrel ? 2 : 4, isBarrel ? 2 : 3); canvas.cd(); - const char* path_toTopologyXML = (l_detids.size() == SiPixelPI::phase0size) - ? "Geometry/TrackerCommonData/data/trackerParameters.xml" - : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; + bool is_l_phase0 = (l_detids.size() == SiPixelPI::phase0size); + bool is_f_phase0 = (f_detids.size() == SiPixelPI::phase0size); + + const char* path_toTopologyXML = is_l_phase0 ? "Geometry/TrackerCommonData/data/trackerParameters.xml" + : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; auto l_tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath()); - auto l_myPlots = PixelRegions::PixelRegionContainers(&l_tTopo, (l_detids.size() == SiPixelPI::phase1size)); + auto l_myPlots = PixelRegions::PixelRegionContainers(&l_tTopo, !is_l_phase0); l_myPlots.bookAll( Form("Last SiPixel Gain Calibration %s - %s", (isForHLT_ ? "ForHLT" : "Offline"), TypeName[myType]), Form("per %s %s", (isForHLT_ ? "Column" : "Pixel"), TypeName[myType]), @@ -560,13 +566,12 @@ namespace gainCalibHelper { minimum, maximum); - path_toTopologyXML = (f_detids.size() == SiPixelPI::phase0size) - ? "Geometry/TrackerCommonData/data/trackerParameters.xml" - : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; + path_toTopologyXML = is_f_phase0 ? "Geometry/TrackerCommonData/data/trackerParameters.xml" + : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; auto f_tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath()); - auto f_myPlots = PixelRegions::PixelRegionContainers(&f_tTopo, (f_detids.size() == SiPixelPI::phase1size)); + auto f_myPlots = PixelRegions::PixelRegionContainers(&f_tTopo, !is_f_phase0); f_myPlots.bookAll( Form("First SiPixel Gain Calibration %s - %s", (isForHLT_ ? "ForHLT" : "Offline"), TypeName[myType]), Form("per %s %s", (isForHLT_ ? "Column" : "Pixel"), TypeName[myType]), @@ -577,8 +582,8 @@ namespace gainCalibHelper { // fill the histograms for (const auto& pixelId : PixelRegions::PixelIDs) { - auto f_wantedDets = PixelRegions::attachedDets(pixelId, &f_tTopo, (f_detids.size() == SiPixelPI::phase1size)); - auto l_wantedDets = PixelRegions::attachedDets(pixelId, &l_tTopo, (l_detids.size() == SiPixelPI::phase1size)); + auto f_wantedDets = PixelRegions::attachedDets(pixelId, &f_tTopo, !is_f_phase0); + auto l_wantedDets = PixelRegions::attachedDets(pixelId, &l_tTopo, !is_l_phase0); gainCalibPI::fillTheHisto(first_payload, f_myPlots.getHistoFromMap(pixelId), myType, f_wantedDets); gainCalibPI::fillTheHisto(last_payload, l_myPlots.getHistoFromMap(pixelId), myType, l_wantedDets); } @@ -591,8 +596,8 @@ namespace gainCalibHelper { l_myPlots.beautify(kRed, -1); f_myPlots.beautify(kAzure, -1); - l_myPlots.draw(canvas, isBarrel, "HIST", true); - f_myPlots.draw(canvas, isBarrel, "HISTsames", true); + l_myPlots.draw(canvas, isBarrel, "HIST", (!is_f_phase0 || !is_l_phase0)); + f_myPlots.draw(canvas, isBarrel, "HISTsames", (!is_f_phase0 || !is_l_phase0)); // rescale the y-axis ranges in order to fit the canvas l_myPlots.rescaleMax(f_myPlots); @@ -857,7 +862,6 @@ namespace gainCalibHelper { hBPix->SetFillColor(kBlue); hBPix->SetMarkerStyle(20); hBPix->SetMarkerSize(1); - //hBPix->Draw("bar2"); hBPix->Draw("hist"); SiPixelPI::makeNicePlotStyle(hBPix.get()); @@ -869,7 +873,6 @@ namespace gainCalibHelper { hFPix->SetFillColor(kBlue); hFPix->SetMarkerStyle(20); hFPix->SetMarkerSize(1); - //hFPix->Draw("bar2"); hFPix->Draw("hist"); SiPixelPI::makeNicePlotStyle(hFPix.get()); @@ -1011,16 +1014,13 @@ namespace gainCalibHelper { hfirst->GetYaxis()->SetRangeUser(1., extrema.second * 10); hfirst->SetTitle(""); - //hfirst->SetFillColor(kRed); hfirst->SetLineColor(kRed); hfirst->SetBarWidth(0.95); - //hfirst->Draw("histbar"); hfirst->Draw("hist"); hlast->SetTitle(""); hlast->SetFillColorAlpha(kBlue, 0.20); hlast->SetBarWidth(0.95); - //hlast->Draw("histbarsame"); hlast->Draw("histsames"); SiPixelPI::makeNicePlotStyle(hfirst.get()); diff --git a/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h b/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h index 6fccd04684e94..a5567179deba0 100644 --- a/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h +++ b/CondCore/SiPixelPlugins/interface/SiPixelPayloadInspectorHelper.h @@ -804,14 +804,10 @@ namespace SiPixelPI { /*--------------------------------------------------------------------*/ { std::vector> rocsToMask; - - //int nblade_list[2] = {11, 17}; int nybins_list[2] = {92, 140}; - //int nblade = nblade_list[ring - 1]; int nybins = nybins_list[ring - 1]; int start_x = disk > 0 ? ((disk + 3) * 8) + 1 : ((3 - (std::abs(disk))) * 8) + 1; - //int start_y = blade > 0 ? ((blade+nblade)*4)-panel*2 : ((nblade-(std::abs(blade)))*4)-panel*2; int start_y = blade > 0 ? (nybins / 2) + (blade * 4) - (panel * 2) + 3 : ((nybins / 2) - (std::abs(blade) * 4) - panel * 2) + 3; @@ -839,14 +835,10 @@ namespace SiPixelPI { /*--------------------------------------------------------------------*/ { std::vector> rocsToMask; - - //int nblade_list[2] = {11, 17}; int nybins_list[2] = {92, 140}; - //int nblade = nblade_list[ring - 1]; int nybins = nybins_list[ring - 1]; int start_x = disk > 0 ? ((disk + 3) * 8) + 1 : ((3 - (std::abs(disk))) * 8) + 1; - //int start_y = blade > 0 ? ((blade+nblade)*4)-panel*2 : ((nblade-(std::abs(blade)))*4)-panel*2; int start_y = blade > 0 ? (nybins / 2) + (blade * 4) - (panel * 2) + 3 : ((nybins / 2) - (std::abs(blade) * 4) - panel * 2) + 3; diff --git a/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationForHLT_PayloadInspector.cc b/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationForHLT_PayloadInspector.cc index fd48d675aa07c..c8e9fd710e9b9 100644 --- a/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationForHLT_PayloadInspector.cc +++ b/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationForHLT_PayloadInspector.cc @@ -57,48 +57,56 @@ namespace { using SiPixelGainCalibForHLTGainComparisonBarrelSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTPedestalComparisonBarrelSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTGainComparisonBarrelTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTPedestalComparisonBarrelTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTGainComparisonEndcapSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTPedestalComparisonEndcapSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTGainComparisonEndcapTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibForHLTPedestalComparisonEndcapTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; diff --git a/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationOffline_PayloadInspector.cc b/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationOffline_PayloadInspector.cc index bf84f66cfe4b3..525be85463a0e 100644 --- a/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationOffline_PayloadInspector.cc +++ b/CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationOffline_PayloadInspector.cc @@ -57,48 +57,56 @@ namespace { using SiPixelGainCalibOfflineGainComparisonBarrelSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflinePedestalComparisonBarrelSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflineGainComparisonBarrelTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflinePedestalComparisonBarrelTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflineGainComparisonEndcapSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflinePedestalComparisonEndcapSingleTag = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflineGainComparisonEndcapTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; using SiPixelGainCalibOfflinePedestalComparisonEndcapTwoTags = gainCalibHelper::SiPixelGainCalibrationValuesComparisonPerRegion; diff --git a/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc b/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc index cab6fa6f2fe3c..6eef014179f0c 100644 --- a/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc +++ b/CondCore/SiPixelPlugins/plugins/SiPixelLorentzAngle_PayloadInspector.cc @@ -199,7 +199,7 @@ namespace { unsigned int maxPads = isBarrel ? 4 : 12; for (unsigned int c = 1; c <= maxPads; c++) { canvas.cd(c); - SiPixelPI::adjustCanvasMargins(canvas.cd(c), 0.07, 0.12, 0.12, 0.05); + SiPixelPI::adjustCanvasMargins(canvas.cd(c), 0.06, 0.12, 0.12, 0.05); legend.Draw("same"); canvas.cd(c)->Update(); } @@ -233,12 +233,12 @@ namespace { /************************************************ 1d histogram of SiPixelLorentzAngle of 2 IOV per region *************************************************/ - template + template class SiPixelLorentzAngleValuesComparisonPerRegion - : public cond::payloadInspector::PlotImage { + : public cond::payloadInspector::PlotImage { public: SiPixelLorentzAngleValuesComparisonPerRegion() - : cond::payloadInspector::PlotImage( + : cond::payloadInspector::PlotImage( Form("SiPixelLorentzAngle Values Comparisons per region %i tags(s)", ntags)) {} bool fill() override { @@ -287,16 +287,18 @@ namespace { canvas.Divide(isBarrel ? 2 : 4, isBarrel ? 2 : 3); canvas.cd(); + bool is_l_phase0 = (l_LAMap_.size() == SiPixelPI::phase0size); + bool is_f_phase0 = (f_LAMap_.size() == SiPixelPI::phase0size); + // deal with last IOV - const char *path_toTopologyXML = (l_LAMap_.size() == SiPixelPI::phase0size) - ? "Geometry/TrackerCommonData/data/trackerParameters.xml" - : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; + const char *path_toTopologyXML = is_l_phase0 ? "Geometry/TrackerCommonData/data/trackerParameters.xml" + : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; auto l_tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath()); - auto l_myPlots = PixelRegions::PixelRegionContainers(&l_tTopo, (l_LAMap_.size() == SiPixelPI::phase1size)); + auto l_myPlots = PixelRegions::PixelRegionContainers(&l_tTopo, !is_l_phase0); l_myPlots.bookAll("SiPixel LA,last", "SiPixel LorentzAngle #mu_{H}(tan#theta_{L}/B) [1/T]", "#modules", @@ -304,25 +306,22 @@ namespace { min * 0.9, max * 1.1); - //canvas.Modified(); - for (const auto &element : l_LAMap_) { l_myPlots.fill(element.first, element.second); } l_myPlots.beautify(); - l_myPlots.draw(canvas, isBarrel, "bar2", true); + l_myPlots.draw(canvas, isBarrel, "bar2", (!is_f_phase0 || !is_l_phase0)); // deal with first IOV - path_toTopologyXML = (f_LAMap_.size() == SiPixelPI::phase0size) - ? "Geometry/TrackerCommonData/data/trackerParameters.xml" - : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; + path_toTopologyXML = is_f_phase0 ? "Geometry/TrackerCommonData/data/trackerParameters.xml" + : "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml"; auto f_tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath()); - auto f_myPlots = PixelRegions::PixelRegionContainers(&f_tTopo, (f_LAMap_.size() == SiPixelPI::phase1size)); + auto f_myPlots = PixelRegions::PixelRegionContainers(&f_tTopo, !is_f_phase0); f_myPlots.bookAll("SiPixel LA,first", "SiPixel LorentzAngle #mu_{H}(tan#theta_{L}/B) [1/T]", "#modules", @@ -330,14 +329,12 @@ namespace { min * 0.9, max * 1.1); - //canvas.Modified(); - for (const auto &element : f_LAMap_) { f_myPlots.fill(element.first, element.second); } f_myPlots.beautify(kAzure, kBlue); - f_myPlots.draw(canvas, isBarrel, "HISTsames", true); + f_myPlots.draw(canvas, isBarrel, "HISTsames", (!is_f_phase0 || !is_l_phase0)); // rescale the y-axis ranges in order to fit the canvas l_myPlots.rescaleMax(f_myPlots); @@ -396,11 +393,15 @@ namespace { } }; - using SiPixelLorentzAngleValuesBarrelCompareSingleTag = SiPixelLorentzAngleValuesComparisonPerRegion; - using SiPixelLorentzAngleValuesEndcapCompareSingleTag = SiPixelLorentzAngleValuesComparisonPerRegion; + using SiPixelLorentzAngleValuesBarrelCompareSingleTag = + SiPixelLorentzAngleValuesComparisonPerRegion; + using SiPixelLorentzAngleValuesEndcapCompareSingleTag = + SiPixelLorentzAngleValuesComparisonPerRegion; - using SiPixelLorentzAngleValuesBarrelCompareTwoTags = SiPixelLorentzAngleValuesComparisonPerRegion; - using SiPixelLorentzAngleValuesEndcapCompareTwoTags = SiPixelLorentzAngleValuesComparisonPerRegion; + using SiPixelLorentzAngleValuesBarrelCompareTwoTags = + SiPixelLorentzAngleValuesComparisonPerRegion; + using SiPixelLorentzAngleValuesEndcapCompareTwoTags = + SiPixelLorentzAngleValuesComparisonPerRegion; /************************************************ 1d histogram of SiPixelLorentzAngle of 1 IOV @@ -470,21 +471,11 @@ namespace { hfirst->SetBarWidth(0.95); hfirst->Draw("histbar"); - //hfirst->SetMarkerStyle(kFullCircle); - //hfirst->SetMarkerSize(1.5); - //hfirst->SetMarkerColor(kRed); - //hfirst->Draw("Psame"); - hlast->SetTitle(""); hlast->SetFillColorAlpha(kBlue, 0.20); hlast->SetBarWidth(0.95); hlast->Draw("histbarsame"); - //hlast->SetMarkerStyle(kOpenCircle); - //hlast->SetMarkerSize(1.5); - //hlast->SetMarkerColor(kBlue); - //hlast->Draw("Psame"); - SiPixelPI::makeNicePlotStyle(hfirst.get()); SiPixelPI::makeNicePlotStyle(hlast.get()); diff --git a/CondCore/SiPixelPlugins/plugins/SiPixelTemplateDBObject_PayloadInspector.cc b/CondCore/SiPixelPlugins/plugins/SiPixelTemplateDBObject_PayloadInspector.cc index 39167d56086ba..bdd7fbf27e1f8 100644 --- a/CondCore/SiPixelPlugins/plugins/SiPixelTemplateDBObject_PayloadInspector.cc +++ b/CondCore/SiPixelPlugins/plugins/SiPixelTemplateDBObject_PayloadInspector.cc @@ -227,7 +227,7 @@ namespace { "SiPixelTemplate assumed value of uH") {} bool fill() override { - gStyle->SetPalette(kBlackBody); + gStyle->SetPalette(kRainBow); TGaxis::SetMaxDigits(2); auto tag = PlotBase::getTag<0>(); @@ -268,10 +268,10 @@ namespace { Phase1PixelMaps theMaps("COLZ L"); if (myType == t_barrel) { - theMaps.bookBarrelHistograms("templateLABarrel", "#muH"); + theMaps.bookBarrelHistograms("templateLABarrel", "#muH", "#mu_{H} [1/T]"); theMaps.bookBarrelBins("templateLABarrel"); } else if (myType == t_forward) { - theMaps.bookForwardHistograms("templateLAForward", "#muH"); + theMaps.bookForwardHistograms("templateLAForward", "#muH", "#mu_{H} [1/T]"); theMaps.bookForwardBins("templateLAForward"); } @@ -344,11 +344,11 @@ namespace { // Book the TH2Poly Phase1PixelMaps theMaps("text"); if (myType == t_barrel) { - theMaps.bookBarrelHistograms("templateIDsBarrel", "IDs"); + theMaps.bookBarrelHistograms("templateIDsBarrel", "IDs", "template IDs"); // book the barrel bins of the TH2Poly theMaps.bookBarrelBins("templateIDsBarrel"); } else if (myType == t_forward) { - theMaps.bookForwardHistograms("templateIDsForward", "IDs"); + theMaps.bookForwardHistograms("templateIDsForward", "IDs", "template IDs"); // book the forward bins of the TH2Poly theMaps.bookForwardBins("templateIDsForward"); } diff --git a/CondCore/SiPixelPlugins/test/testSiPixelPayloadInspector.cpp b/CondCore/SiPixelPlugins/test/testSiPixelPayloadInspector.cpp index 241e50c2556c7..22a6a63d1bc31 100644 --- a/CondCore/SiPixelPlugins/test/testSiPixelPayloadInspector.cpp +++ b/CondCore/SiPixelPlugins/test/testSiPixelPayloadInspector.cpp @@ -5,6 +5,7 @@ #include "CondCore/SiPixelPlugins/plugins/SiPixelQuality_PayloadInspector.cc" #include "CondCore/SiPixelPlugins/plugins/SiPixelGainCalibrationOffline_PayloadInspector.cc" #include "CondCore/SiPixelPlugins/plugins/SiPixelTemplateDBObject_PayloadInspector.cc" +#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/PluginManager/interface/PluginManager.h" #include "FWCore/PluginManager/interface/standard.h" #include "FWCore/PluginManager/interface/SharedLibrary.h" @@ -31,27 +32,27 @@ int main(int argc, char** argv) { cond::Time_t start = boost::lexical_cast(303790); cond::Time_t end = boost::lexical_cast(324245); - std::cout << "## Exercising Lorentz Angle plots " << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << "## Exercising Lorentz Angle plots " << std::endl; SiPixelLorentzAngleValues histo1; histo1.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo1.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo1.data() << std::endl; SiPixelLorentzAngleValueComparisonSingleTag histo2; histo2.process(connectionString, PI::mk_input(tag, start, end)); - std::cout << histo2.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo2.data() << std::endl; SiPixelLorentzAngleByRegionComparisonSingleTag histo3; histo3.process(connectionString, PI::mk_input(tag, start, end)); - std::cout << histo3.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo3.data() << std::endl; SiPixelBPixLorentzAngleMap histo4; histo4.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo4.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo4.data() << std::endl; SiPixelFPixLorentzAngleMap histo5; histo5.process(connectionString, PI::mk_input(tag, end, end)); - std::cout << histo5.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo5.data() << std::endl; // 2 tags comparisons @@ -60,11 +61,11 @@ int main(int argc, char** argv) { SiPixelLorentzAngleValueComparisonTwoTags histo6; histo6.process(connectionString, PI::mk_input(tag, start, start, tag2, start2, start2)); - std::cout << histo6.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo6.data() << std::endl; SiPixelLorentzAngleByRegionComparisonTwoTags histo7; histo7.process(connectionString, PI::mk_input(tag, start, start, tag2, start2, start2)); - std::cout << histo7.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo7.data() << std::endl; // SiPixelQuality @@ -72,15 +73,15 @@ int main(int argc, char** argv) { start = boost::lexical_cast(1); end = boost::lexical_cast(1); - std::cout << "## Exercising SiPixelQuality plots " << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << "## Exercising SiPixelQuality plots " << std::endl; SiPixelBPixQualityMap histo8; histo8.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo8.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo8.data() << std::endl; SiPixelFPixQualityMap histo9; histo9.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo9.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo9.data() << std::endl; // SiPixelGainCalibrationOffline @@ -88,37 +89,37 @@ int main(int argc, char** argv) { start = boost::lexical_cast(312203); end = boost::lexical_cast(312203); - std::cout << "## Exercising SiPixelGainCalibrationOffline plots " << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << "## Exercising SiPixelGainCalibrationOffline plots " << std::endl; SiPixelGainCalibrationOfflineGainsValues histo10; histo10.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo10.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo10.data() << std::endl; SiPixelGainCalibrationOfflinePedestalsValues histo11; histo11.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo11.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo11.data() << std::endl; SiPixelGainCalibrationOfflineGainsByPart histo12; histo12.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo12.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo12.data() << std::endl; SiPixelGainCalibrationOfflinePedestalsByPart histo13; histo13.process(connectionString, PI::mk_input(tag, start, start)); - std::cout << histo13.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo13.data() << std::endl; end = boost::lexical_cast(326851); SiPixelGainCalibOfflinePedestalComparisonSingleTag histo14; histo14.process(connectionString, PI::mk_input(tag, start, end)); - std::cout << histo14.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo14.data() << std::endl; SiPixelGainCalibOfflineGainByRegionComparisonSingleTag histo15; histo15.process(connectionString, PI::mk_input(tag, start, end)); - std::cout << histo15.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo15.data() << std::endl; SiPixelGainCalibrationOfflineCorrelations histo16; histo16.process(connectionString, PI::mk_input(tag, end, end)); - std::cout << histo16.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo16.data() << std::endl; boost::python::dict inputs; inputs["SetLog"] = "True"; // sets to true, 1,True,Yes will work @@ -126,7 +127,7 @@ int main(int argc, char** argv) { SiPixelGainCalibrationOfflineGainsValuesBarrel histo17; histo17.setInputParamValues(inputs); histo17.process(connectionString, PI::mk_input(tag, end, end)); - std::cout << histo17.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo17.data() << std::endl; // SiPixelTemplates @@ -134,15 +135,15 @@ int main(int argc, char** argv) { start = boost::lexical_cast(326083); end = boost::lexical_cast(326083); - std::cout << "## Exercising SiPixelTemplates plots " << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << "## Exercising SiPixelTemplates plots " << std::endl; SiPixelTemplateIDsBPixMap histo18; histo18.process(connectionString, PI::mk_input(tag, end, end)); - std::cout << histo18.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo18.data() << std::endl; SiPixelTemplateLAFPixMap histo19; histo19.process(connectionString, PI::mk_input(tag, end, end)); - std::cout << histo19.data() << std::endl; + edm::LogPrint("testSiPixelPayloadInspector") << histo19.data() << std::endl; Py_Finalize(); } diff --git a/CondCore/Utilities/plugins/Module_2XML.cc b/CondCore/Utilities/plugins/Module_2XML.cc index e300dec44637a..c85b15f7bd667 100644 --- a/CondCore/Utilities/plugins/Module_2XML.cc +++ b/CondCore/Utilities/plugins/Module_2XML.cc @@ -180,6 +180,7 @@ PAYLOAD_2XML_MODULE(pluginUtilities_payload2xml) { PAYLOAD_2XML_CLASS(L1RPCHwConfig); PAYLOAD_2XML_CLASS(L1TGlobalParameters); PAYLOAD_2XML_CLASS(L1TGlobalPrescalesVetos); + PAYLOAD_2XML_CLASS(L1TGlobalPrescalesVetosFract); PAYLOAD_2XML_CLASS(L1TMuonBarrelParams); PAYLOAD_2XML_CLASS(L1TMuonEndCapForest); PAYLOAD_2XML_CLASS(L1TMuonEndCapParams); diff --git a/CondCore/Utilities/python/o2olib.py b/CondCore/Utilities/python/o2olib.py index 1604913250741..e3bf619dc681e 100644 --- a/CondCore/Utilities/python/o2olib.py +++ b/CondCore/Utilities/python/o2olib.py @@ -14,7 +14,7 @@ import CondCore.Utilities.credentials as auth prod_db_service = ['cms_orcon_prod','cms_orcon_prod/cms_cond_general_w'] -dev_db_service = ['cms_orcoff_prep','cms_orcoff_prep/cms_test_conditions'] +dev_db_service = ['cms_orcoff_prep','cms_orcoff_prep/cms_cond_general_w'] schema_name = 'CMS_CONDITIONS' sqlalchemy_tpl = 'oracle://%s:%s@%s' coral_tpl = 'oracle://%s/%s' diff --git a/CondCore/Utilities/python/popcon2dropbox.py b/CondCore/Utilities/python/popcon2dropbox.py index d4c19bf1370c7..fac71834088db 100644 --- a/CondCore/Utilities/python/popcon2dropbox.py +++ b/CondCore/Utilities/python/popcon2dropbox.py @@ -36,20 +36,24 @@ def checkFile( dbName ): # exit code = 0 => skip # exit code = 1 => import if not os.path.exists( dbFileName ): - logger.error('The file expected as an input %s has not been found.'%dbFileName ) + logger.error('The file generated by PopCon with the data to be imported %s has not been found.'%dbFileName ) return -1 empty = True try: dbcon = sqlite3.connect( dbFileName ) dbcur = dbcon.cursor() + dbcur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='IOV'"); + if dbcur.fetchone() is None: + logger.error('The condition database with the data to be imported has not been found in the file generated by PopCon: %s'%dbFileName ) + return -1 dbcur.execute('SELECT * FROM IOV') rows = dbcur.fetchall() for r in rows: empty = False dbcon.close() if empty: - logger.warning('The file expected as an input %s contains no data. The import will be skipped.'%dbFileName ) + logger.warning('The data set generated by PopCon contains no data to be imported. The import will be skipped.') return 0 return 1 except Exception as e: @@ -174,6 +178,7 @@ def run( args ): command += ' destinationDatabase=%s' %args.destDb command += ' destinationTag=%s' %args.destTag command += ' 2>&1' + logger.info( 'Executing command: %s' %command ) pipe = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) stdout = pipe.communicate()[0] retCode = pipe.returncode @@ -189,5 +194,7 @@ def run( args ): ret = copy( args, dbName ) else: ret = upload( args, dbName ) - os.remove( '%s.db' %dbName ) + if ret >=0: + logger.info('Deleting local file %s.db' %dbName ) + os.remove( '%s.db' %dbName ) return ret diff --git a/CondCore/Utilities/src/CondDBFetch.cc b/CondCore/Utilities/src/CondDBFetch.cc index 4ceb189f8385c..1215f0a0b5124 100644 --- a/CondCore/Utilities/src/CondDBFetch.cc +++ b/CondCore/Utilities/src/CondDBFetch.cc @@ -311,6 +311,7 @@ namespace cond { FETCH_PAYLOAD_CASE(EcalCondObjectContainer) FETCH_PAYLOAD_CASE(MagFieldConfig) FETCH_PAYLOAD_CASE(L1TGlobalPrescalesVetos) + FETCH_PAYLOAD_CASE(L1TGlobalPrescalesVetosFract) // if (payloadTypeName == "PhysicsTools::Calibration::Histogram3D") { diff --git a/CondCore/Utilities/src/CondDBImport.cc b/CondCore/Utilities/src/CondDBImport.cc index 6a0addcdd1930..9dc6465281b1a 100644 --- a/CondCore/Utilities/src/CondDBImport.cc +++ b/CondCore/Utilities/src/CondDBImport.cc @@ -336,6 +336,7 @@ namespace cond { IMPORT_PAYLOAD_CASE(EcalCondObjectContainer) IMPORT_PAYLOAD_CASE(EcalCondObjectContainer) IMPORT_PAYLOAD_CASE(L1TGlobalPrescalesVetos) + IMPORT_PAYLOAD_CASE(L1TGlobalPrescalesVetosFract) if (inputTypeName == "PhysicsTools::Calibration::Histogram3D") { match = true; const PhysicsTools::Calibration::Histogram3D& obj = diff --git a/CondCore/Utilities/src/CondFormats.h b/CondCore/Utilities/src/CondFormats.h index 101d6bc874411..1af80a99b9e97 100644 --- a/CondCore/Utilities/src/CondFormats.h +++ b/CondCore/Utilities/src/CondFormats.h @@ -250,6 +250,7 @@ #include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h" #include "CondFormats/L1TObjects/interface/L1TGlobalParameters.h" #include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetos.h" +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" #include "CondFormats/L1TObjects/interface/L1TriggerKey.h" #include "CondFormats/L1TObjects/interface/L1TriggerKeyList.h" #include "CondFormats/PhysicsToolsObjects/interface/Histogram3D.h" diff --git a/CondCore/Utilities/test/testPngHistograms.cpp b/CondCore/Utilities/test/testPngHistograms.cpp index d0ae63476c7c8..f527f6e4ce27e 100644 --- a/CondCore/Utilities/test/testPngHistograms.cpp +++ b/CondCore/Utilities/test/testPngHistograms.cpp @@ -9,10 +9,6 @@ int main(int argc, char** argv) { Py_Initialize(); - if (argc < 3) { - std::cout << "Not enough arguments given." << std::endl; - return 0; - } edmplugin::PluginManager::Config config; edmplugin::PluginManager::configure(edmplugin::standard::config()); @@ -24,11 +20,10 @@ int main(int argc, char** argv) { edm::ServiceToken servToken(edm::ServiceRegistry::createSet(psets)); edm::ServiceRegistry::Operate operate(servToken); - std::string connectionString("oracle://cms_orcon_adg/CMS_CONDITIONS"); + std::string connectionString("frontier://FrontierProd/CMS_CONDITIONS"); - std::string tag = std::string(argv[1]); - std::string runTimeType = cond::time::timeTypeName(cond::runnumber); - cond::Time_t since = boost::lexical_cast(argv[2]); + std::string tag = std::string("BasicPayload_v10.0"); + cond::Time_t since = boost::lexical_cast("901"); std::cout << "## PNG Histo" << std::endl; diff --git a/CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h b/CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h index 8038b6d20cda1..f30c49afc6a3f 100644 --- a/CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h +++ b/CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h @@ -22,10 +22,11 @@ #include "FWCore/Framework/interface/DependentRecordImplementation.h" #include "CondFormats/DataRecord/interface/BeamSpotOnlineHLTObjectsRcd.h" #include "CondFormats/DataRecord/interface/BeamSpotOnlineLegacyObjectsRcd.h" +#include "CondFormats/DataRecord/interface/BeamSpotObjectsRcd.h" class BeamSpotTransientObjectsRcd : public edm::eventsetup::DependentRecordImplementation< BeamSpotTransientObjectsRcd, - boost::mpl::vector > {}; + boost::mpl::vector > {}; #endif diff --git a/CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h b/CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h new file mode 100644 index 0000000000000..4902776ecf3fd --- /dev/null +++ b/CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h @@ -0,0 +1,18 @@ +// L1TGlobalPrescalesVetosFractRcd +// Description: Record for L1TGlobalPrescalesVetosFract +// +// automatically generate by make_records.pl +// +#ifndef CondFormatsDataRecord_L1TGlobalPrescalesVetosFractO2O_h +#define CondFormatsDataRecord_L1TGlobalPrescalesVetosFractO2O_h + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" +#include "CondFormats/DataRecord/interface/L1TriggerKeyListExtRcd.h" +#include "CondFormats/DataRecord/interface/L1TriggerKeyExtRcd.h" +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h" +class L1TGlobalPrescalesVetosFractO2ORcd + : public edm::eventsetup::DependentRecordImplementation< + L1TGlobalPrescalesVetosFractO2ORcd, + boost::mpl::vector > {}; + +#endif diff --git a/CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h b/CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h new file mode 100644 index 0000000000000..8476cd8030b63 --- /dev/null +++ b/CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h @@ -0,0 +1,20 @@ +// L1TGlobalPrescalesVetosFractRcd +// Description: Record for L1TGlobalPrescalesVetosFract +// +// automatically generate by make_records.pl +// +#ifndef CondFormatsDataRecord_L1TGlobalPrescalesVetosFract_h +#define CondFormatsDataRecord_L1TGlobalPrescalesVetosFract_h + +#include "FWCore/Framework/interface/EventSetupRecordImplementation.h" + +class L1TGlobalPrescalesVetosFractRcd + : public edm::eventsetup::EventSetupRecordImplementation {}; + +// Dependent record implmentation: +//#include "FWCore/Framework/interface/DependentRecordImplementation.h" +//#include "CondFormats/DataRecord/interface/L1TriggerKeyListRcd.h" +//#include "CondFormats/DataRecord/interface/L1TriggerKeyRcd.h" +//class L1TGlobalPrescalesVetosFractRcd : public edm::eventsetup::DependentRecordImplementation > {}; + +#endif diff --git a/CondFormats/DataRecord/src/L1TGlobalPrescalesVetosFractO2ORcd.cc b/CondFormats/DataRecord/src/L1TGlobalPrescalesVetosFractO2ORcd.cc new file mode 100644 index 0000000000000..9e02ff6c11f31 --- /dev/null +++ b/CondFormats/DataRecord/src/L1TGlobalPrescalesVetosFractO2ORcd.cc @@ -0,0 +1,4 @@ +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(L1TGlobalPrescalesVetosFractO2ORcd); diff --git a/CondFormats/DataRecord/src/L1TGlobalPrescalesVetosFractRcd.cc b/CondFormats/DataRecord/src/L1TGlobalPrescalesVetosFractRcd.cc new file mode 100644 index 0000000000000..d033d94134f94 --- /dev/null +++ b/CondFormats/DataRecord/src/L1TGlobalPrescalesVetosFractRcd.cc @@ -0,0 +1,8 @@ +// L1TGlobalPrescalesVetosFractRcd implementation + +// automatically generated by make_records.pl + +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(L1TGlobalPrescalesVetosFractRcd); diff --git a/CondFormats/EcalObjects/interface/EcalXtalGroupId.h b/CondFormats/EcalObjects/interface/EcalXtalGroupId.h index 3331db375dfd1..b21c2b9889d9f 100644 --- a/CondFormats/EcalObjects/interface/EcalXtalGroupId.h +++ b/CondFormats/EcalObjects/interface/EcalXtalGroupId.h @@ -19,7 +19,7 @@ class EcalXtalGroupId { bool operator<(const EcalXtalGroupId& rhs) const { return (id_ < rhs.id()); } bool operator<=(const EcalXtalGroupId& rhs) const { return (id_ <= rhs.id()); } - const unsigned int id() const { return id_; } + unsigned int id() const { return id_; } private: unsigned int id_; diff --git a/CondFormats/JetMETObjects/src/SimpleJetCorrector.cc b/CondFormats/JetMETObjects/src/SimpleJetCorrector.cc index ffbd3a8ef7062..7ca9f82e9b255 100644 --- a/CondFormats/JetMETObjects/src/SimpleJetCorrector.cc +++ b/CondFormats/JetMETObjects/src/SimpleJetCorrector.cc @@ -61,6 +61,11 @@ float SimpleJetCorrector::correction(const std::vector& fX, const std::ve } result = tmp / mParameters.definitions().nBinVar(); } + if (result <= 0) { + edm::LogWarning("SimpleJetCorrector") + << "Null or negative jet energy correction factor evaluated: " << result << ". Truncating to 10e-10."; + result = 10e-10; + } return result; } //------------------------------------------------------------------------ diff --git a/CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h b/CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h new file mode 100644 index 0000000000000..04479dc9819cb --- /dev/null +++ b/CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h @@ -0,0 +1,31 @@ +// L1TGlobalPrescalesVetosFract +// +// Table containing the entire set of prescales and masks for each L1T algorithm bit +// + +#ifndef L1TGlobalPrescalesVetosFract_h +#define L1TGlobalPrescalesVetosFract_h + +#include + +#include "CondFormats/Serialization/interface/Serializable.h" + +class L1TGlobalPrescalesVetosFract { +public: + L1TGlobalPrescalesVetosFract() { + version_ = 0; + bxmask_default_ = 0; + } + + unsigned int version_; + std::vector > prescale_table_; + int bxmask_default_; + std::map > bxmask_map_; + std::vector veto_; + std::vector exp_ints_; + std::vector exp_doubles_; + + COND_SERIALIZABLE; +}; + +#endif diff --git a/CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h b/CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h index ec352f5b94c35..95008abc8c18c 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h +++ b/CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h @@ -7,32 +7,19 @@ * Created: 12 Mar 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmAlgorithm_hh #define tmEventSetup_L1TUtmAlgorithm_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ +#include #include #include #include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ - /** * This class implements data structure for Algorithm */ class L1TUtmAlgorithm { public: - // ctor L1TUtmAlgorithm() : name_(), expression_(), @@ -43,8 +30,7 @@ class L1TUtmAlgorithm { module_index_(), version(0){}; - // dtor - virtual ~L1TUtmAlgorithm(){}; + virtual ~L1TUtmAlgorithm() = default; /** set rpn_vector_ */ void setRpnVector(const std::vector& x) { rpn_vector_ = x; }; @@ -79,8 +65,8 @@ class L1TUtmAlgorithm { unsigned int module_id_; /**< module id */ unsigned int module_index_; /**< index of algorithm in module (local to module id) */ unsigned int version; + COND_SERIALIZABLE; }; #endif // tmEventSetup_L1TUtmAlgorithm_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmBin.h b/CondFormats/L1TObjects/interface/L1TUtmBin.h index 6658f2c1c6f48..d9d0f66dcb37f 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmBin.h +++ b/CondFormats/L1TObjects/interface/L1TUtmBin.h @@ -7,31 +7,17 @@ * Created: 12 Mar 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmBin_hh #define tmEventSetup_L1TUtmBin_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ #include #include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ - /** * This class implements data structure for Bin */ class L1TUtmBin { public: - // ctor L1TUtmBin() : hw_index(std::numeric_limits::max()), minimum(std::numeric_limits::min()), @@ -41,8 +27,7 @@ class L1TUtmBin { L1TUtmBin(const unsigned int id, const double min, const double max) : hw_index(id), minimum(min), maximum(max), version(0){}; - // dtor - virtual ~L1TUtmBin(){}; + virtual ~L1TUtmBin() = default; unsigned int hw_index; /**< HW index of bin */ double minimum; /**< minimum value of bin */ @@ -52,4 +37,3 @@ class L1TUtmBin { }; #endif // tmEventSetup_L1TUtmBin_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmCondition.h b/CondFormats/L1TObjects/interface/L1TUtmCondition.h index 7c6344296b3d4..a1e7b4a905b38 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmCondition.h +++ b/CondFormats/L1TObjects/interface/L1TUtmCondition.h @@ -7,39 +7,24 @@ * Created: 12 Mar 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmCondition_hh #define tmEventSetup_L1TUtmCondition_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ -#include -#include -#include "CondFormats/Serialization/interface/Serializable.h" - #include "CondFormats/L1TObjects/interface/L1TUtmCut.h" #include "CondFormats/L1TObjects/interface/L1TUtmObject.h" +#include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ +#include +#include /** * This class implements data structure for Condition */ class L1TUtmCondition { public: - // ctor L1TUtmCondition() : name_(), type_(-9999), objects_(), cuts_(), version(0){}; - // dtor - virtual ~L1TUtmCondition(){}; + virtual ~L1TUtmCondition() = default; /** set condition name */ void setName(const std::string& x) { name_ = x; }; @@ -69,4 +54,3 @@ class L1TUtmCondition { }; #endif // tmEventSetup_L1TUtmCondition_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmCut.h b/CondFormats/L1TObjects/interface/L1TUtmCut.h index e3a1f7fcf616d..98bb45f158cd5 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmCut.h +++ b/CondFormats/L1TObjects/interface/L1TUtmCut.h @@ -7,37 +7,22 @@ * Created: 8 Nov 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmCut_hh #define tmEventSetup_L1TUtmCut_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ -#include -#include "CondFormats/Serialization/interface/Serializable.h" - #include "CondFormats/L1TObjects/interface/L1TUtmCutValue.h" +#include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ +#include /** * This class implements data structure for Cut */ class L1TUtmCut { public: - // ctor L1TUtmCut() : name_(), object_type_(), cut_type_(), minimum_(), maximum_(), data_(), key_(), version(0){}; - // dtor - virtual ~L1TUtmCut(){}; + virtual ~L1TUtmCut() = default; /** set cut name */ void setName(const std::string& name) { name_ = name; }; @@ -114,11 +99,10 @@ class L1TUtmCut { int cut_type_; /**< type of cut */ L1TUtmCutValue minimum_; /**< minimum value of cut range */ L1TUtmCutValue maximum_; /**< maximum value of cut range */ - std::string data_; /**< data for charge/quality/isolation/charge correlation */ + std::string data_; /**< data for charge/quality/isolation/charge correlation/impact parameter */ std::string key_; /**< key for accessing a scale */ unsigned int version; COND_SERIALIZABLE; }; #endif // tmEventSetup_L1TUtmCut_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmCutValue.h b/CondFormats/L1TObjects/interface/L1TUtmCutValue.h index 4efbf701d9b36..8ae7442d9c4d1 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmCutValue.h +++ b/CondFormats/L1TObjects/interface/L1TUtmCutValue.h @@ -7,33 +7,21 @@ * Created: 12 Mar 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmCutValue_hh #define tmEventSetup_L1TUtmCutValue_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ #include #include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ - /** * This class implements data structure for CutValue */ struct L1TUtmCutValue { - // ctor L1TUtmCutValue() : value(std::numeric_limits::max()), index(std::numeric_limits::max()), version(0){}; + virtual ~L1TUtmCutValue() = default; + double value; /**< cut value */ unsigned int index; /**< HW index for the cut value */ unsigned int version; @@ -41,4 +29,3 @@ struct L1TUtmCutValue { }; #endif // tmEventSetup_L1TUtmCutValue_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmObject.h b/CondFormats/L1TObjects/interface/L1TUtmObject.h index 67f9fdd43946f..0892ccec5f77a 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmObject.h +++ b/CondFormats/L1TObjects/interface/L1TUtmObject.h @@ -7,35 +7,21 @@ * Created: 12 Mar 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmObject_hh #define tmEventSetup_L1TUtmObject_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ -#include -#include -#include -#include "CondFormats/Serialization/interface/Serializable.h" - #include "CondFormats/L1TObjects/interface/L1TUtmCut.h" +#include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ +#include +#include +#include /** * This class implements data structure for Object */ class L1TUtmObject { public: - // ctor L1TUtmObject() : name_(), type_(), @@ -47,8 +33,7 @@ class L1TUtmObject { cuts_(), version(0){}; - // dtor - virtual ~L1TUtmObject(){}; + virtual ~L1TUtmObject() = default; /** set object name */ void setName(const std::string& x) { name_ = x; }; @@ -112,4 +97,3 @@ class L1TUtmObject { }; #endif // tmEventSetup_L1TUtmObject_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmScale.h b/CondFormats/L1TObjects/interface/L1TUtmScale.h index 18972e599c064..8e9a3978c6111 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmScale.h +++ b/CondFormats/L1TObjects/interface/L1TUtmScale.h @@ -7,39 +7,24 @@ * Created: 9 Nov 2015 */ -/** @todo nope */ - #ifndef tmEventSetup_L1TUtmScale_hh #define tmEventSetup_L1TUtmScale_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ +#include "CondFormats/L1TObjects/interface/L1TUtmBin.h" +#include "CondFormats/Serialization/interface/Serializable.h" + #include #include #include -#include "CondFormats/Serialization/interface/Serializable.h" - -#include "CondFormats/L1TObjects/interface/L1TUtmBin.h" - -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ /** * This class implements data structure for Scale */ class L1TUtmScale { public: - // ctor L1TUtmScale() : name_(), object_(), type_(), minimum_(), maximum_(), step_(), n_bits_(), bins_(), version(0){}; - // dtor - virtual ~L1TUtmScale(){}; + virtual ~L1TUtmScale() = default; /** get scale name */ const std::string& getName() const { return name_; }; @@ -79,4 +64,3 @@ class L1TUtmScale { }; #endif // tmEventSetup_L1TUtmScale_hh -/* eof */ diff --git a/CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h b/CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h index a72f3dffb072c..e287010b3e950 100644 --- a/CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h +++ b/CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h @@ -11,31 +11,19 @@ #ifndef tmEventSetup_L1TUtmTriggerMenu_hh #define tmEventSetup_L1TUtmTriggerMenu_hh -/*====================================================================* - * declarations - *====================================================================*/ -/*-----------------------------------------------------------------* - * headers - *-----------------------------------------------------------------*/ -#include -#include -#include "CondFormats/Serialization/interface/Serializable.h" - #include "CondFormats/L1TObjects/interface/L1TUtmScale.h" -#include "CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h" #include "CondFormats/L1TObjects/interface/L1TUtmCondition.h" +#include "CondFormats/L1TObjects/interface/L1TUtmAlgorithm.h" +#include "CondFormats/Serialization/interface/Serializable.h" -/*-----------------------------------------------------------------* - * constants - *-----------------------------------------------------------------*/ -/* nope */ +#include +#include /** * This class implements data structure for TriggerMenu */ class L1TUtmTriggerMenu { public: - // ctor L1TUtmTriggerMenu() : algorithm_map_(), condition_map_(), @@ -51,8 +39,7 @@ class L1TUtmTriggerMenu { n_modules_(), version(0){}; - // dtor - virtual ~L1TUtmTriggerMenu(){}; + virtual ~L1TUtmTriggerMenu() = default; /** get algorithm_map_ * @@ -116,45 +103,45 @@ class L1TUtmTriggerMenu { /** set menu name * - * @param x [in] name of the menu + * @param value [in] name of the menu */ - void setName(const std::string& x) { name_ = x; }; + void setName(const std::string& value) { name_ = value; }; /** set grammar version * - * @param x [in] grammar version + * @param value [in] grammar version */ - void setVersion(const std::string& x) { version_ = x; }; + void setVersion(const std::string& value) { version_ = value; }; /** set comment on the menu * - * @param x [in] comment + * @param value [in] comment */ - void setComment(const std::string& x) { comment_ = x; }; + void setComment(const std::string& value) { comment_ = value; }; /** set datetime of the menu * - * @param x [in] datetime + * @param value [in] datetime */ - void setDatetime(const std::string& x) { datetime_ = x; }; + void setDatetime(const std::string& value) { datetime_ = value; }; /** set UUID of firmware generated by VHDL producer * - * @param x [in] UUID + * @param value [in] UUID */ - void setFirmwareUuid(const std::string& x) { uuid_firmware_ = x; }; + void setFirmwareUuid(const std::string& value) { uuid_firmware_ = value; }; /** set scale set name * - * @param x [in] scale set name + * @param value [in] scale set name */ - void setScaleSetName(const std::string& x) { scale_set_name_ = x; }; + void setScaleSetName(const std::string& value) { scale_set_name_ = value; }; /** set number of uGT boards for the menu * - * @param x [in] number of uGT boards + * @param value [in] number of uGT boards */ - void setNmodules(const unsigned int x) { n_modules_ = x; }; + void setNmodules(const unsigned int value) { n_modules_ = value; }; protected: std::map algorithm_map_; /**< map of algorithm */ @@ -175,4 +162,3 @@ class L1TUtmTriggerMenu { }; #endif // tmEventSetup_L1TUtmTriggerMenu_hh -/* eof */ diff --git a/CondFormats/L1TObjects/src/L1TGlobalPrescalesVetosFract.cc b/CondFormats/L1TObjects/src/L1TGlobalPrescalesVetosFract.cc new file mode 100644 index 0000000000000..801901d65abe9 --- /dev/null +++ b/CondFormats/L1TObjects/src/L1TGlobalPrescalesVetosFract.cc @@ -0,0 +1 @@ +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" diff --git a/CondFormats/L1TObjects/src/T_EventSetup_L1TGlobalPrescalesVetosFract.cc b/CondFormats/L1TObjects/src/T_EventSetup_L1TGlobalPrescalesVetosFract.cc new file mode 100644 index 0000000000000..3c35d9d7ae478 --- /dev/null +++ b/CondFormats/L1TObjects/src/T_EventSetup_L1TGlobalPrescalesVetosFract.cc @@ -0,0 +1,5 @@ + +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" +#include "FWCore/Utilities/interface/typelookup.h" + +TYPELOOKUP_DATA_REG(L1TGlobalPrescalesVetosFract); diff --git a/CondFormats/L1TObjects/src/classes.h b/CondFormats/L1TObjects/src/classes.h index adc45360142c2..5d5412df158ee 100644 --- a/CondFormats/L1TObjects/src/classes.h +++ b/CondFormats/L1TObjects/src/classes.h @@ -67,6 +67,7 @@ #include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h" #include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetos.h" +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" namespace CondFormats_L1TObjects { struct dictionary { @@ -121,6 +122,7 @@ namespace CondFormats_L1TObjects { L1TUtmTriggerMenu dummy21h; L1TGlobalPrescalesVetos dummy22; + L1TGlobalPrescalesVetosFract dummy22a; L1TGlobalParameters dummy23; }; diff --git a/CondFormats/L1TObjects/src/classes_def.xml b/CondFormats/L1TObjects/src/classes_def.xml index b1f68b3b81f32..20f8b53b283c2 100644 --- a/CondFormats/L1TObjects/src/classes_def.xml +++ b/CondFormats/L1TObjects/src/classes_def.xml @@ -358,6 +358,13 @@ + + + + + + + diff --git a/CondTools/L1TriggerExt/interface/L1ConfigOnlineProdBaseExt.h b/CondTools/L1TriggerExt/interface/L1ConfigOnlineProdBaseExt.h index 09dac4608ec3d..d84412ff4a177 100644 --- a/CondTools/L1TriggerExt/interface/L1ConfigOnlineProdBaseExt.h +++ b/CondTools/L1TriggerExt/interface/L1ConfigOnlineProdBaseExt.h @@ -9,7 +9,6 @@ #include "FWCore/Framework/interface/ModuleFactory.h" #include "FWCore/Framework/interface/ESProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "CondFormats/L1TObjects/interface/L1TriggerKeyListExt.h" #include "CondFormats/DataRecord/interface/L1TriggerKeyListExtRcd.h" @@ -41,10 +40,13 @@ class L1ConfigOnlineProdBaseExt : public edm::ESProducer { private: // ----------member data --------------------------- + edm::ESGetToken keyList_token; + edm::ESGetToken key_token; protected: l1t::OMDSReader m_omdsReader; bool m_forceGeneration; + edm::ESConsumesCollectorT wrappedSetWhatProduced(const edm::ParameterSet&); // Called from produce methods. // bool is true if the object data should be made. @@ -65,7 +67,9 @@ L1ConfigOnlineProdBaseExt::L1ConfigOnlineProdBaseExt(const edm::Par m_copyFromCondDB(false) { //the following line is needed to tell the framework what // data is being produced - setWhatProduced(this); + // setWhatProduced(this) + // .setConsumes(keyList_token) + // .setConsumes(key_token); //now do what ever other initialization is needed @@ -85,6 +89,15 @@ L1ConfigOnlineProdBaseExt::L1ConfigOnlineProdBaseExt(const edm::Par } } +template +edm::ESConsumesCollectorT L1ConfigOnlineProdBaseExt::wrappedSetWhatProduced( + const edm::ParameterSet& iConfig) { + auto collector = setWhatProduced(this); + collector.setConsumes(keyList_token); + collector.setConsumes(key_token); + return collector; +} + template L1ConfigOnlineProdBaseExt::~L1ConfigOnlineProdBaseExt() { // do anything here that needs to be done at desctruction time @@ -104,16 +117,15 @@ std::unique_ptr L1ConfigOnlineProdBaseExt::produce(con /// // Get L1TriggerKeyList from EventSetup /// const L1TriggerKeyListRcd& keyListRcd = iRecord.template getRecord(); - edm::ESHandle keyList; /// iRecord.template getRecord< L1TriggerKeyListRcd >() ; /// edm::ESHandle< L1TriggerKeyList > keyList ; - keyListRcd.get(keyList); + auto const& keyList = keyListRcd.get(keyList_token); // Find payload token std::string recordName = edm::typelookup::className(); std::string dataType = edm::typelookup::className(); - std::string payloadToken = keyList->token(recordName, dataType, key); + std::string payloadToken = keyList.token(recordName, dataType, key); edm::LogVerbatim("L1-O2O") << "Copying payload for " << recordName << "@" << dataType << " obj key " << key << " from CondDB."; @@ -156,9 +168,9 @@ bool L1ConfigOnlineProdBaseExt::getObjectKey(const TRcd& record, st // If L1TriggerKeyExt is invalid, then all configuration objects are // already in ORCON. - edm::ESHandle key; + // edm::ESHandle key_token; try { - keyRcd.get(key); + keyRcd.get(key_token); } catch (l1t::DataAlreadyPresentException& ex) { objectKey = std::string(); return false; @@ -168,7 +180,7 @@ bool L1ConfigOnlineProdBaseExt::getObjectKey(const TRcd& record, st std::string recordName = edm::typelookup::className(); std::string dataType = edm::typelookup::className(); - objectKey = key->get(recordName, dataType); + objectKey = keyRcd.get(key_token).get(recordName, dataType); /* edm::LogVerbatim( "L1-O2O" ) */ /* << "L1ConfigOnlineProdBase record " << recordName */ diff --git a/CondTools/L1TriggerExt/interface/L1ObjectKeysOnlineProdBaseExt.h b/CondTools/L1TriggerExt/interface/L1ObjectKeysOnlineProdBaseExt.h index 2d4195c36d533..11cdf531485e8 100644 --- a/CondTools/L1TriggerExt/interface/L1ObjectKeysOnlineProdBaseExt.h +++ b/CondTools/L1TriggerExt/interface/L1ObjectKeysOnlineProdBaseExt.h @@ -7,7 +7,7 @@ // user include files #include "FWCore/Framework/interface/ModuleFactory.h" #include "FWCore/Framework/interface/ESProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ESConsumesCollector.h" #include "CondFormats/L1TObjects/interface/L1TriggerKeyExt.h" #include "CondFormats/DataRecord/interface/L1TriggerKeyExtRcd.h" @@ -29,6 +29,8 @@ class L1ObjectKeysOnlineProdBaseExt : public edm::ESProducer { private: // ----------member data --------------------------- + edm::ESGetToken L1TriggerKeyExt_token; + protected: l1t::OMDSReader m_omdsReader; }; diff --git a/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.cc b/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.cc index 0c5ec3744ff47..1449d7cc80ea1 100644 --- a/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.cc +++ b/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.cc @@ -14,6 +14,7 @@ L1CondDBPayloadWriterExt::L1CondDBPayloadWriterExt(const edm::ParameterSet& iCon m_logTransactions(iConfig.getParameter("logTransactions")), m_newL1TriggerKeyListExt(iConfig.getParameter("newL1TriggerKeyListExt")) { //now do what ever initialization is needed + key_token = esConsumes(); } L1CondDBPayloadWriterExt::~L1CondDBPayloadWriterExt() { @@ -38,18 +39,16 @@ void L1CondDBPayloadWriterExt::analyze(const edm::Event& iEvent, const edm::Even // Write L1TriggerKeyExt to ORCON with no IOV std::string token; - ESHandle key; - + L1TriggerKeyExt key; // Before calling writePayload(), check if TSC key is already in // L1TriggerKeyListExt. writePayload() will not catch this situation in // the case of dummy configurations. bool triggerKeyOK = true; try { // Get L1TriggerKeyExt - iSetup.get().get(key); - + key = iSetup.get().get(key_token); if (!m_overwriteKeys) { - triggerKeyOK = oldKeyList.token(key->tscKey()).empty(); + triggerKeyOK = oldKeyList.token(key.tscKey()).empty(); } } catch (l1t::DataAlreadyPresentException& ex) { triggerKeyOK = false; @@ -57,7 +56,7 @@ void L1CondDBPayloadWriterExt::analyze(const edm::Event& iEvent, const edm::Even } if (triggerKeyOK && m_writeL1TriggerKeyExt) { - edm::LogVerbatim("L1-O2O") << "Object key for L1TriggerKeyExtRcd@L1TriggerKeyExt: " << key->tscKey(); + edm::LogVerbatim("L1-O2O") << "Object key for L1TriggerKeyExtRcd@L1TriggerKeyExt: " << key.tscKey(); token = m_writer.writePayload(iSetup, "L1TriggerKeyExtRcd@L1TriggerKeyExt"); } @@ -68,15 +67,15 @@ void L1CondDBPayloadWriterExt::analyze(const edm::Event& iEvent, const edm::Even // Record token in L1TriggerKeyListExt if (m_writeL1TriggerKeyExt) { keyList = new L1TriggerKeyListExt(oldKeyList); - if (!(keyList->addKey(key->tscKey(), token, m_overwriteKeys))) { - throw cond::Exception("L1CondDBPayloadWriter: TSC key " + key->tscKey() + " already in L1TriggerKeyListExt"); + if (!(keyList->addKey(key.tscKey(), token, m_overwriteKeys))) { + throw cond::Exception("L1CondDBPayloadWriter: TSC key " + key.tscKey() + " already in L1TriggerKeyListExt"); } } if (m_writeConfigData) { // Loop over record@type in L1TriggerKeyExt - L1TriggerKeyExt::RecordToKey::const_iterator it = key->recordToKeyMap().begin(); - L1TriggerKeyExt::RecordToKey::const_iterator end = key->recordToKeyMap().end(); + L1TriggerKeyExt::RecordToKey::const_iterator it = key.recordToKeyMap().begin(); + L1TriggerKeyExt::RecordToKey::const_iterator end = key.recordToKeyMap().end(); for (; it != end; ++it) { // Do nothing if object key is null. diff --git a/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.h b/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.h index 9eed08136a7dd..b8da3c798ecc7 100644 --- a/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.h +++ b/CondTools/L1TriggerExt/plugins/L1CondDBPayloadWriterExt.h @@ -10,8 +10,13 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" + #include "CondTools/L1TriggerExt/interface/DataWriterExt.h" +#include "CondFormats/L1TObjects/interface/L1TriggerKeyExt.h" +#include "CondFormats/DataRecord/interface/L1TriggerKeyExtRcd.h" + class L1CondDBPayloadWriterExt : public edm::EDAnalyzer { public: explicit L1CondDBPayloadWriterExt(const edm::ParameterSet&); @@ -26,6 +31,9 @@ class L1CondDBPayloadWriterExt : public edm::EDAnalyzer { l1t::DataWriterExt m_writer; // std::string m_tag ; // tag is known by PoolDBOutputService + // token to access object key + edm::ESGetToken key_token; + // set to false to write config data without valid TSC key bool m_writeL1TriggerKeyExt; diff --git a/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.cc b/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.cc index dadeaad90908a..0fd860afbd2bb 100644 --- a/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.cc +++ b/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.cc @@ -6,13 +6,18 @@ #include "FWCore/Framework/interface/EventSetup.h" -L1TriggerKeyOnlineProdExt::L1TriggerKeyOnlineProdExt(const edm::ParameterSet& iConfig) - : m_subsystemLabels(iConfig.getParameter >("subsystemLabels")) { +L1TriggerKeyOnlineProdExt::L1TriggerKeyOnlineProdExt(const edm::ParameterSet& iConfig) { //the following line is needed to tell the framework what // data is being produced - setWhatProduced(this); + auto cc = setWhatProduced(this); - //now do what ever other initialization is needed + for (auto const& label : iConfig.getParameter >("subsystemLabels")) { + m_subsystemTokens.emplace_back(cc.consumesFrom(edm::ESInputTag{"", label})); + + //now do what ever other initialization is needed + } + + cc.setConsumes(L1TriggerKeyExt_token, edm::ESInputTag{"", "SubsystemKeysOnly"}); } L1TriggerKeyOnlineProdExt::~L1TriggerKeyOnlineProdExt() { @@ -27,27 +32,18 @@ L1TriggerKeyOnlineProdExt::~L1TriggerKeyOnlineProdExt() { // ------------ method called to produce the data ------------ L1TriggerKeyOnlineProdExt::ReturnType L1TriggerKeyOnlineProdExt::produce(const L1TriggerKeyExtRcd& iRecord) { // Start with "SubsystemKeysOnly" - edm::ESHandle subsystemKeys; + L1TriggerKeyExt subsystemKeys; try { - iRecord.get("SubsystemKeysOnly", subsystemKeys); + subsystemKeys = iRecord.get(L1TriggerKeyExt_token); } catch (l1t::DataAlreadyPresentException& ex) { throw ex; } - auto pL1TriggerKey = std::make_unique(*subsystemKeys); + auto pL1TriggerKey = std::make_unique(subsystemKeys); // Collate object keys - std::vector::const_iterator itr = m_subsystemLabels.begin(); - std::vector::const_iterator end = m_subsystemLabels.end(); - for (; itr != end; ++itr) { - edm::ESHandle objectKeys; - try { - iRecord.get(*itr, objectKeys); - } catch (l1t::DataAlreadyPresentException& ex) { - throw ex; - } - - pL1TriggerKey->add(objectKeys->recordToKeyMap()); + for (auto const& token : m_subsystemTokens) { + pL1TriggerKey->add(iRecord.get(token).recordToKeyMap()); } return pL1TriggerKey; diff --git a/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.h b/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.h index 3d582e01a36a7..94275625ae0eb 100644 --- a/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.h +++ b/CondTools/L1TriggerExt/plugins/L1TriggerKeyOnlineProdExt.h @@ -8,6 +8,7 @@ #include "FWCore/Framework/interface/ModuleFactory.h" #include "FWCore/Framework/interface/ESProducer.h" #include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ESConsumesCollector.h" #include "CondFormats/L1TObjects/interface/L1TriggerKeyExt.h" #include "CondFormats/DataRecord/interface/L1TriggerKeyExtRcd.h" @@ -23,6 +24,8 @@ class L1TriggerKeyOnlineProdExt : public edm::ESProducer { private: // ----------member data --------------------------- + edm::ESGetToken L1TriggerKeyExt_token; + std::vector> m_subsystemTokens; std::vector m_subsystemLabels; }; diff --git a/CondTools/L1TriggerExt/plugins/SealModule.cc b/CondTools/L1TriggerExt/plugins/SealModule.cc index 0d0997517b386..2042439681653 100644 --- a/CondTools/L1TriggerExt/plugins/SealModule.cc +++ b/CondTools/L1TriggerExt/plugins/SealModule.cc @@ -41,6 +41,11 @@ REGISTER_L1_WRITER(L1TUtmTriggerMenuO2ORcd, L1TUtmTriggerMenu); REGISTER_L1_WRITER(L1TGlobalPrescalesVetosO2ORcd, L1TGlobalPrescalesVetos); +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h" + +REGISTER_L1_WRITER(L1TGlobalPrescalesVetosFractO2ORcd, L1TGlobalPrescalesVetosFract); + #include "CondFormats/L1TObjects/interface/L1TMuonBarrelParams.h" #include "CondFormats/DataRecord/interface/L1TMuonBarrelParamsO2ORcd.h" diff --git a/CondTools/L1TriggerExt/python/L1CondEnumExt_cfi.py b/CondTools/L1TriggerExt/python/L1CondEnumExt_cfi.py index dd7e70a783489..caf9a5edfa075 100644 --- a/CondTools/L1TriggerExt/python/L1CondEnumExt_cfi.py +++ b/CondTools/L1TriggerExt/python/L1CondEnumExt_cfi.py @@ -9,7 +9,7 @@ class L1CondEnumExt: L1TMuonEndCapParams=5 L1TMuonGlobalParams=6 L1TCaloParams=7 - L1TGlobalPrescalesVetos=8 + L1TGlobalPrescalesVetosFract=8 L1TMuonEndCapForest=9 NumL1Cond=10 diff --git a/CondTools/L1TriggerExt/python/L1O2OTagsExt_cfi.py b/CondTools/L1TriggerExt/python/L1O2OTagsExt_cfi.py index cd4897b1eabc2..05bd22acd8757 100644 --- a/CondTools/L1TriggerExt/python/L1O2OTagsExt_cfi.py +++ b/CondTools/L1TriggerExt/python/L1O2OTagsExt_cfi.py @@ -9,7 +9,7 @@ def initL1O2OTagsExt(): initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TriggerKeyExt ] = "Stage2v0_hlt" initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TUtmTriggerMenu ] = "Stage2v0_hlt" - initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TGlobalPrescalesVetos ] = "Stage2v0_hlt" + initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TGlobalPrescalesVetosFract ] = "Stage2v0_hlt" initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TMuonBarrelParams ] = "Stage2v1_hlt" initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TMuonOverlapParams ] = "Stage2v0_hlt" initL1O2OTagsExt.tagBaseVec[ L1CondEnumExt.L1TMuonEndCapParams ] = "Stage2v3_hlt" diff --git a/CondTools/L1TriggerExt/python/L1SubsystemParamsExt_cfi.py b/CondTools/L1TriggerExt/python/L1SubsystemParamsExt_cfi.py index f62cc0f1c00a4..e9f8009a17a74 100644 --- a/CondTools/L1TriggerExt/python/L1SubsystemParamsExt_cfi.py +++ b/CondTools/L1TriggerExt/python/L1SubsystemParamsExt_cfi.py @@ -18,9 +18,9 @@ def initL1SubsystemsExt( tagBaseVec = [], key = cms.string(objectKey) ), cms.PSet( - record = cms.string('L1TGlobalPrescalesVetosO2ORcd'), - tag = cms.string('L1TGlobalPrescalesVetos_' + tagBaseVec[ L1CondEnumExt.L1TGlobalPrescalesVetos ]), - type = cms.string('L1TGlobalPrescalesVetos'), + record = cms.string('L1TGlobalPrescalesVetosFractO2ORcd'), + tag = cms.string('L1TGlobalPrescalesVetosFract_' + tagBaseVec[ L1CondEnumExt.L1TGlobalPrescalesVetosFract ]), + type = cms.string('L1TGlobalPrescalesVetosFract'), key = cms.string(objectKey) ), cms.PSet( diff --git a/CondTools/L1TriggerExt/src/L1ObjectKeysOnlineProdBaseExt.cc b/CondTools/L1TriggerExt/src/L1ObjectKeysOnlineProdBaseExt.cc index a90fc80feee0c..8a0ecda433a58 100644 --- a/CondTools/L1TriggerExt/src/L1ObjectKeysOnlineProdBaseExt.cc +++ b/CondTools/L1TriggerExt/src/L1ObjectKeysOnlineProdBaseExt.cc @@ -12,7 +12,8 @@ L1ObjectKeysOnlineProdBaseExt::L1ObjectKeysOnlineProdBaseExt(const edm::Paramete // The subsystemLabel is used by L1TriggerKeyOnlineProdExt to identify the // L1TriggerKeysExt to concatenate. - setWhatProduced(this, iConfig.getParameter("subsystemLabel")); + setWhatProduced(this, iConfig.getParameter("subsystemLabel")) + .setConsumes(L1TriggerKeyExt_token, edm::ESInputTag{"", "SubsystemKeysOnly"}); //now do what ever other initialization is needed } @@ -26,15 +27,15 @@ L1ObjectKeysOnlineProdBaseExt::~L1ObjectKeysOnlineProdBaseExt() { L1ObjectKeysOnlineProdBaseExt::ReturnType L1ObjectKeysOnlineProdBaseExt::produce(const L1TriggerKeyExtRcd& iRecord) { // Get L1TriggerKeyExt with label "SubsystemKeysOnly". Re-throw exception if // not present. - edm::ESHandle subsystemKeys; + L1TriggerKeyExt subsystemKeys; try { - iRecord.get("SubsystemKeysOnly", subsystemKeys); + subsystemKeys = iRecord.get(L1TriggerKeyExt_token); } catch (l1t::DataAlreadyPresentException& ex) { throw ex; } // Copy L1TriggerKeyExt to new object. - auto pL1TriggerKey = std::make_unique(*subsystemKeys); + auto pL1TriggerKey = std::make_unique(subsystemKeys); // Get object keys. fillObjectKeys(pL1TriggerKey.get()); diff --git a/Configuration/AlCa/python/autoCond.py b/Configuration/AlCa/python/autoCond.py index 7e162d350dbcd..0f6f5c9fe3992 100644 --- a/Configuration/AlCa/python/autoCond.py +++ b/Configuration/AlCa/python/autoCond.py @@ -16,23 +16,23 @@ # GlobalTag for MC production with perfectly aligned and calibrated detector for Run2 'run2_design' : '110X_mcRun2_design_v5', #GlobalTag for MC production with optimistic alignment and calibrations for 2016, prior to VFP change - 'run2_mc_pre_vfp' : '110X_mcRun2_asymptotic_preVFP_v4', + 'run2_mc_pre_vfp' : '111X_mcRun2_asymptotic_preVFP_v1', #GlobalTag for MC production with optimistic alignment and calibrations for 2016, after VFP change - 'run2_mc' : '110X_mcRun2_asymptotic_v7', + 'run2_mc' : '111X_mcRun2_asymptotic_v1', # GlobalTag for MC production (cosmics) with starup-like alignment and calibrations for Run2, Strip tracker in peak mode - 'run2_mc_cosmics' : '110X_mcRun2cosmics_startup_deco_v6', + 'run2_mc_cosmics' : '111X_mcRun2cosmics_startup_deco_v1', # GlobalTag for MC production (Heavy Ions collisions) with optimistic alignment and calibrations for Run2 'run2_mc_hi' : '110X_mcRun2_HeavyIon_v2', # GlobalTag for MC production (p-Pb collisions) with realistic alignment and calibrations for Run2 'run2_mc_pa' : '110X_mcRun2_pA_v3', # GlobalTag for Run1 data reprocessing - 'run1_data' : '111X_dataRun2_v3', + 'run1_data' : '111X_dataRun2_v4', # GlobalTag for Run2 data reprocessing - 'run2_data' : '111X_dataRun2_v3', + 'run2_data' : '111X_dataRun2_v4', # GlobalTag for Run2 data 2018B relvals only: HEM-15-16 fail - 'run2_data_HEfail' : '111X_dataRun2_HEfail_v3', + 'run2_data_HEfail' : '111X_dataRun2_HEfail_v4', # GlobalTag for Run2 data relvals: allows customization to run with fixed L1 menu - 'run2_data_relval' : '111X_dataRun2_relval_v3', + 'run2_data_relval' : '111X_dataRun2_relval_v4', # GlobalTag for Run2 HI data 'run2_data_promptlike_hi' : '110X_dataRun2_PromptLike_HI_v10', # GlobalTag for Run1 HLT: it points to the online GT @@ -45,41 +45,41 @@ # GlobalTag for Run2 HLT for HI (not 2018 HI): it points to the online GT 'run2_hlt_hi' : '101X_dataRun2_HLTHI_frozen_v9', # GlobalTag for Run3 data relvals - 'run3_data_promptlike' : '110X_dataRun3_Prompt_v3', + 'run3_data_promptlike' : '111X_dataRun3_Prompt_v4', # GlobalTag for MC production with perfectly aligned and calibrated detector for Phase1 2017 (and 0,0,~0-centred beamspot) - 'phase1_2017_design' : '110X_mc2017_design_v3', + 'phase1_2017_design' : '111X_mc2017_design_v2', # GlobalTag for MC production with realistic conditions for Phase1 2017 detector - 'phase1_2017_realistic' : '110X_mc2017_realistic_v4', + 'phase1_2017_realistic' : '111X_mc2017_realistic_v2', # GlobalTag for MC production (cosmics) with realistic alignment and calibrations for Phase1 2017 detector, Strip tracker in DECO mode - 'phase1_2017_cosmics' : '110X_mc2017cosmics_realistic_deco_v3', + 'phase1_2017_cosmics' : '111X_mc2017cosmics_realistic_deco_v1', # GlobalTag for MC production (cosmics) with realistic alignment and calibrations for Phase1 2017 detector, Strip tracker in PEAK mode - 'phase1_2017_cosmics_peak' : '110X_mc2017cosmics_realistic_peak_v3', + 'phase1_2017_cosmics_peak' : '111X_mc2017cosmics_realistic_peak_v1', # GlobalTag for MC production with perfectly aligned and calibrated detector for full Phase1 2018 (and 0,0,0-centred beamspot) - 'phase1_2018_design' : '110X_upgrade2018_design_v4', + 'phase1_2018_design' : '111X_upgrade2018_design_v2', # GlobalTag for MC production with realistic conditions for full Phase1 2018 detector - 'phase1_2018_realistic' : '110X_upgrade2018_realistic_v9', + 'phase1_2018_realistic' : '111X_upgrade2018_realistic_v2', # GlobalTag for MC production with realistic conditions for full Phase1 2018 detector for Heavy Ion - 'phase1_2018_realistic_hi' : '110X_upgrade2018_realistic_HI_v5', + 'phase1_2018_realistic_hi' : '111X_upgrade2018_realistic_HI_v1', # GlobalTag for MC production with realistic conditions for full Phase1 2018 detector: HEM-15-16 fail - 'phase1_2018_realistic_HEfail' : '110X_upgrade2018_realistic_HEfail_v7', + 'phase1_2018_realistic_HEfail' : '111X_upgrade2018_realistic_HEfail_v2', # GlobalTag for MC production (cosmics) with realistic conditions for full Phase1 2018 detector, Strip tracker in DECO mode - 'phase1_2018_cosmics' : '110X_upgrade2018cosmics_realistic_deco_v6', + 'phase1_2018_cosmics' : '111X_upgrade2018cosmics_realistic_deco_v2', # GlobalTag for MC production (cosmics) with realistic conditions for full Phase1 2018 detector, Strip tracker in PEAK mode - 'phase1_2018_cosmics_peak' : '110X_upgrade2018cosmics_realistic_peak_v7', + 'phase1_2018_cosmics_peak' : '111X_upgrade2018cosmics_realistic_peak_v2', # GlobalTag for MC production with perfectly aligned and calibrated detector for Phase1 2021 - 'phase1_2021_design' : '111X_mcRun3_2021_design_v4', # GT containing design conditions for Phase1 2021 + 'phase1_2021_design' : '111X_mcRun3_2021_design_v7', # GT containing design conditions for Phase1 2021 # GlobalTag for MC production with realistic conditions for Phase1 2021 - 'phase1_2021_realistic' : '111X_mcRun3_2021_realistic_v4', # GT containing realistic conditions for Phase1 2021 + 'phase1_2021_realistic' : '111X_mcRun3_2021_realistic_v7', # GT containing realistic conditions for Phase1 2021 # GlobalTag for MC production (cosmics) with realistic conditions for Phase1 2021, Strip tracker in DECO mode - 'phase1_2021_cosmics' : '111X_mcRun3_2021cosmics_realistic_deco_v4', + 'phase1_2021_cosmics' : '111X_mcRun3_2021cosmics_realistic_deco_v7', # GlobalTag for MC production with realistic conditions for Phase1 2021 detector for Heavy Ion - 'phase1_2021_realistic_hi' : '111X_mcRun3_2021_realistic_HI_v5', + 'phase1_2021_realistic_hi' : '111X_mcRun3_2021_realistic_HI_v9', # GlobalTag for MC production with realistic conditions for Phase1 2023 - 'phase1_2023_realistic' : '111X_mcRun3_2023_realistic_v4', # GT containing realistic conditions for Phase1 2023 + 'phase1_2023_realistic' : '111X_mcRun3_2023_realistic_v6', # GT containing realistic conditions for Phase1 2023 # GlobalTag for MC production with realistic conditions for Phase1 2024 - 'phase1_2024_realistic' : '111X_mcRun3_2024_realistic_v4', # GT containing realistic conditions for Phase1 2024 + 'phase1_2024_realistic' : '111X_mcRun3_2024_realistic_v6', # GT containing realistic conditions for Phase1 2024 # GlobalTag for MC production with realistic conditions for Phase2 - 'phase2_realistic' : '110X_mcRun4_realistic_v3' + 'phase2_realistic' : '111X_mcRun4_realistic_T15_v2' } aliases = { diff --git a/Configuration/Eras/python/Era_Phase2C8_cff.py b/Configuration/Eras/python/Era_Phase2C8_cff.py index 3274c863157ae..39368f36d9682 100644 --- a/Configuration/Eras/python/Era_Phase2C8_cff.py +++ b/Configuration/Eras/python/Era_Phase2C8_cff.py @@ -2,6 +2,7 @@ from Configuration.Eras.Era_Phase2C4_cff import Phase2C4 from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_trackerV14_cff import phase2_trackerV14 -Phase2C8 = cms.ModifierChain(Phase2C4, phase2_hgcalV10) +Phase2C8 = cms.ModifierChain(Phase2C4, phase2_hgcalV10, phase2_trackerV14) diff --git a/Configuration/Eras/python/Modifier_phase2_trackerV14_cff.py b/Configuration/Eras/python/Modifier_phase2_trackerV14_cff.py new file mode 100644 index 0000000000000..04ccae020240f --- /dev/null +++ b/Configuration/Eras/python/Modifier_phase2_trackerV14_cff.py @@ -0,0 +1,4 @@ +import FWCore.ParameterSet.Config as cms + +phase2_trackerV14 = cms.Modifier() + diff --git a/Configuration/Geometry/python/dict2026Geometry.py b/Configuration/Geometry/python/dict2026Geometry.py index 9c5b97e99d8c7..ef3c199c7ca3f 100644 --- a/Configuration/Geometry/python/dict2026Geometry.py +++ b/Configuration/Geometry/python/dict2026Geometry.py @@ -1060,7 +1060,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', @@ -1108,7 +1107,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v3/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v2/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v2/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v3/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v3/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', @@ -1156,7 +1154,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v3/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v2/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v2/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v5/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v3/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Configuration/HLT/python/addOnTestsHLT.py b/Configuration/HLT/python/addOnTestsHLT.py index 8015265124ce4..96469f1014fb0 100644 --- a/Configuration/HLT/python/addOnTestsHLT.py +++ b/Configuration/HLT/python/addOnTestsHLT.py @@ -34,19 +34,19 @@ def addOnTestsHLT(): 'hlt_data_Fake2': ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run2_hlt_Fake2 --relval 9000,50 --datatier "RAW" --eventcontent RAW --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run2_2016 --fileout file:RelVal_Raw_Fake2_DATA.root --filein /store/data/Run2016B/JetHT/RAW/v1/000/272/762/00000/C666CDE2-E013-E611-B15A-02163E011DBE.root', 'HLTrigger/Configuration/test/OnLine_HLT_Fake2.py', 'cmsDriver.py RelVal -s HLT:Fake2,RAW2DIGI,L1Reco,RECO --data --scenario=pp -n 10 --conditions auto:run2_data_Fake2 --relval 9000,50 --datatier "RAW-HLT-RECO" --eventcontent FEVTDEBUGHLT --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --era Run2_2016 --processName=HLTRECO --filein file:RelVal_Raw_Fake2_DATA.root --fileout file:RelVal_Raw_Fake2_DATA_HLT_RECO.root'], - 'hlt_data_2018' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run2_hlt_2018 --relval 9000,50 --datatier "RAW" --eventcontent RAW --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run2_2018 --fileout file:RelVal_Raw_2018_DATA.root --filein /store/data/Run2017A/HLTPhysics4/RAW/v1/000/295/606/00000/36DE5E0A-3645-E711-8FA1-02163E01A43B.root', + 'hlt_data_2018' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run2_hlt_2018 --relval 9000,50 --datatier "RAW" --eventcontent RAW --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run2_2018 --fileout file:RelVal_Raw_2018_DATA.root --filein /store/data/Run2018D/EphemeralHLTPhysics1/RAW/v1/000/323/775/00000/2E066536-5CF2-B340-A73B-209640F29FF6.root', 'HLTrigger/Configuration/test/OnLine_HLT_2018.py', 'cmsDriver.py RelVal -s HLT:2018,RAW2DIGI,L1Reco,RECO --data --scenario=pp -n 10 --conditions auto:run2_data_2018 --relval 9000,50 --datatier "RAW-HLT-RECO" --eventcontent FEVTDEBUGHLT --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --era Run2_2018 --processName=HLTRECO --filein file:RelVal_Raw_2018_DATA.root --fileout file:RelVal_Raw_2018_DATA_HLT_RECO.root'], - 'hlt_data_GRun' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_GRun --relval 9000,50 --datatier "RAW" --eventcontent RAW --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3 --fileout file:RelVal_Raw_GRun_DATA.root --filein /store/data/Run2017A/HLTPhysics4/RAW/v1/000/295/606/00000/36DE5E0A-3645-E711-8FA1-02163E01A43B.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task())\'', + 'hlt_data_GRun' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_GRun --relval 9000,50 --datatier "RAW" --eventcontent RAW --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3 --fileout file:RelVal_Raw_GRun_DATA.root --filein /store/data/Run2018D/EphemeralHLTPhysics1/RAW/v1/000/323/775/00000/2E066536-5CF2-B340-A73B-209640F29FF6.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task())\'', 'HLTrigger/Configuration/test/OnLine_HLT_GRun.py', 'cmsDriver.py RelVal -s HLT:GRun,RAW2DIGI,L1Reco,RECO --data --scenario=pp -n 10 --conditions auto:run3_data_GRun --relval 9000,50 --datatier "RAW-HLT-RECO" --eventcontent FEVTDEBUGHLT --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --era Run3 --processName=HLTRECO --filein file:RelVal_Raw_GRun_DATA.root --fileout file:RelVal_Raw_GRun_DATA_HLT_RECO.root'], 'hlt_data_HIon' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_HIon --relval 9000,50 --datatier "RAW" --eventcontent RAW --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3_pp_on_PbPb --fileout file:RelVal_Raw_HIon_DATA.root --filein /store/data/Run2018D/HIMinimumBias0/RAW/v1/000/325/112/00000/660F62BB-9932-D645-A4A4-0BBBDA3963E8.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task()); from FWCore.ParameterSet.MassReplace import massSearchReplaceAnyInputTag; massSearchReplaceAnyInputTag(process.SimL1Emulator,"rawDataCollector","rawDataRepacker",False,True)\'', 'HLTrigger/Configuration/test/OnLine_HLT_HIon.py', 'cmsDriver.py RelVal -s HLT:HIon,RAW2DIGI,L1Reco,RECO --data --scenario=pp -n 10 --conditions auto:run3_data_HIon --relval 9000,50 --datatier "RAW-HLT-RECO" --eventcontent FEVTDEBUGHLT --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --era Run3_pp_on_PbPb --processName=HLTRECO --filein file:RelVal_Raw_HIon_DATA.root --fileout file:RelVal_Raw_HIon_DATA_HLT_RECO.root'], - 'hlt_data_PIon' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_PIon --relval 9000,50 --datatier "RAW" --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3 --eventcontent RAW --fileout file:RelVal_Raw_PIon_DATA.root --filein /store/data/Run2017A/HLTPhysics4/RAW/v1/000/295/606/00000/36DE5E0A-3645-E711-8FA1-02163E01A43B.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task())\'', + 'hlt_data_PIon' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_PIon --relval 9000,50 --datatier "RAW" --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3 --eventcontent RAW --fileout file:RelVal_Raw_PIon_DATA.root --filein /store/data/Run2018D/EphemeralHLTPhysics1/RAW/v1/000/323/775/00000/2E066536-5CF2-B340-A73B-209640F29FF6.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task())\'', 'HLTrigger/Configuration/test/OnLine_HLT_PIon.py', 'cmsDriver.py RelVal -s HLT:PIon,RAW2DIGI,L1Reco,RECO --data --scenario=pp -n 10 --conditions auto:run3_data_PIon --relval 9000,50 --datatier "RAW-HLT-RECO" --eventcontent FEVTDEBUGHLT --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --era Run3 --processName=HLTRECO --filein file:RelVal_Raw_PIon_DATA.root --fileout file:RelVal_Raw_PIon_DATA_HLT_RECO.root'], - 'hlt_data_PRef' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_PRef --relval 9000,50 --datatier "RAW" --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3 --eventcontent RAW --fileout file:RelVal_Raw_PRef_DATA.root --filein /store/data/Run2017A/HLTPhysics4/RAW/v1/000/295/606/00000/36DE5E0A-3645-E711-8FA1-02163E01A43B.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task())\'', + 'hlt_data_PRef' : ['cmsDriver.py RelVal -s L1REPACK:Full --data --scenario=pp -n 10 --conditions auto:run3_hlt_PRef --relval 9000,50 --datatier "RAW" --customise=HLTrigger/Configuration/CustomConfigs.L1T --era Run3 --eventcontent RAW --fileout file:RelVal_Raw_PRef_DATA.root --filein /store/data/Run2018D/EphemeralHLTPhysics1/RAW/v1/000/323/775/00000/2E066536-5CF2-B340-A73B-209640F29FF6.root --customise_commands=\'if hasattr(process,"simMuonGEMPadTask"): setattr(process,"simMuonGEMPadTask",cms.Task())\'', 'HLTrigger/Configuration/test/OnLine_HLT_PRef.py', 'cmsDriver.py RelVal -s HLT:PRef,RAW2DIGI,L1Reco,RECO --data --scenario=pp -n 10 --conditions auto:run3_data_PRef --relval 9000,50 --datatier "RAW-HLT-RECO" --eventcontent FEVTDEBUGHLT --customise=HLTrigger/Configuration/CustomConfigs.L1THLT --era Run3 --processName=HLTRECO --filein file:RelVal_Raw_PRef_DATA.root --fileout file:RelVal_Raw_PRef_DATA_HLT_RECO.root'], } diff --git a/Configuration/PyReleaseValidation/python/MatrixInjector.py b/Configuration/PyReleaseValidation/python/MatrixInjector.py index 09b85bffeec3c..70adf568aa711 100644 --- a/Configuration/PyReleaseValidation/python/MatrixInjector.py +++ b/Configuration/PyReleaseValidation/python/MatrixInjector.py @@ -167,14 +167,19 @@ def __init__(self,opt,mode='init',options=''): self.chainDicts={} - def prepare(self,mReader, directories, mode='init'): + @staticmethod + def get_wmsplit(): + """ + Return a "wmsplit" dictionary that contain non-default LumisPerJob values + """ + wmsplit = {} try: #from Configuration.PyReleaseValidation.relval_steps import wmsplit wmsplit = {} wmsplit['DIGIHI']=5 wmsplit['RECOHI']=5 wmsplit['HLTD']=5 - wmsplit['RECODreHLT']=2 + wmsplit['RECODreHLT']=2 wmsplit['DIGIPU']=4 wmsplit['DIGIPU1']=4 wmsplit['RECOPU1']=1 @@ -254,8 +259,8 @@ def prepare(self,mReader, directories, mode='init'): wmsplit['HLTDR2_2018']=1 wmsplit['HLTDR2_2018_BadHcalMitig']=1 wmsplit['Hadronizer']=1 - wmsplit['DIGIUP15']=1 - wmsplit['RECOUP15']=1 + wmsplit['DIGIUP15']=1 + wmsplit['RECOUP15']=1 wmsplit['RECOAODUP15']=5 wmsplit['DBLMINIAODMCUP15NODQM']=5 wmsplit['DigiFull']=5 @@ -263,7 +268,7 @@ def prepare(self,mReader, directories, mode='init'): wmsplit['DigiFullPU']=1 wmsplit['RecoFullPU']=1 wmsplit['RECOHID11']=1 - wmsplit['DigiFullTriggerPU_2026D17PU'] = 1 + wmsplit['DigiFullTriggerPU_2026D17PU'] = 1 wmsplit['RecoFullGlobalPU_2026D17PU']=1 wmsplit['DIGIUP17']=1 wmsplit['RECOUP17']=1 @@ -303,19 +308,20 @@ def prepare(self,mReader, directories, mode='init'): wmsplit['RecoFullGlobalPU_2026D50PU']=1 wmsplit['DigiFullTriggerPU_2026D51PU'] = 1 wmsplit['RecoFullGlobalPU_2026D51PU']=1 - wmsplit['DigiFullTriggerPU_2026D52PU'] = 1 - wmsplit['RecoFullGlobalPU_2026D52PU']=1 - wmsplit['DigiFullTriggerPU_2026D57PU'] = 1 - wmsplit['RecoFullGlobalPU_2026D57PU']=1 - wmsplit['DigiFullTriggerPU_2026D58PU'] = 1 - wmsplit['RecoFullGlobalPU_2026D58PU']=1 - - #import pprint - #pprint.pprint(wmsplit) - except: - print("Not set up for step splitting") - wmsplit={} + wmsplit['DigiFullTriggerPU_2026D52PU'] = 1 + wmsplit['RecoFullGlobalPU_2026D52PU']=1 + wmsplit['DigiFullTriggerPU_2026D57PU'] = 1 + wmsplit['RecoFullGlobalPU_2026D57PU']=1 + wmsplit['DigiFullTriggerPU_2026D58PU'] = 1 + wmsplit['RecoFullGlobalPU_2026D58PU']=1 + except Exception as ex: + print('Exception while building a wmsplit dictionary: %s' % (str(ex))) + return {} + + return wmsplit + def prepare(self,mReader, directories, mode='init'): + wmsplit = MatrixInjector.get_wmsplit() acqEra=False for (n,dir) in directories.items(): chainDict=copy.deepcopy(self.defaultChain) diff --git a/Configuration/PyReleaseValidation/python/relval_2017.py b/Configuration/PyReleaseValidation/python/relval_2017.py index 93c92f9963e78..c9c2f27258042 100644 --- a/Configuration/PyReleaseValidation/python/relval_2017.py +++ b/Configuration/PyReleaseValidation/python/relval_2017.py @@ -29,7 +29,7 @@ # (Patatrack ECAL-only: TTbar - on CPU, on GPU, both, auto) # (Patatrack HCAL-only: TTbar - on CPU, on GPU, both, auto) # 2021 (ZMM, TTbar, ZEE, MinBias, TTbar PU, TTbar PU premix, ZEE PU, TTbar design) -# (TTbar trackingMkFit) +# (TTbar trackingOnly, pixelTrackingOnly, trackingMkFit) # (Patatrack pixel-only: ZMM - on CPU, on GPU, both, auto) # (Patatrack pixel-only: TTbar - on CPU, on GPU, both, auto) # (Patatrack ECAL-only: TTbar - on CPU, on GPU, both, auto) @@ -49,13 +49,13 @@ 10842.501,10842.502, # 10842.503,10842.504, 10824.501,10824.502, # 10824.503,10824.504, 10824.511,10824.512, # 10824.513,10824.514, - # 10824.521,10824.522,10824.523,10824.524, + 10824.521,10824.522, # 10824.523,10824.524, 11650.0,11634.0,11646.0,11640.0,11834.0,11834.99,11846.0,12024.0, - 11634.7, + 11634.1,11634.5,11634.7, 11650.501,11650.502, # 11650.503,11650.504, 11634.501,11634.502, # 11634.503,11634.504, 11634.511,11634.512, # 11634.513,11634.514, - # 11634.521,11634.522,11634.523,11634.524, + 11634.521,11634.522, # 11634.523,11634.524, 12434.0,12634.0,12634.99, 12834.0,13034.0,13034.99] for numWF in numWFIB: diff --git a/Configuration/PyReleaseValidation/python/relval_2026.py b/Configuration/PyReleaseValidation/python/relval_2026.py index 00b7596892928..e482c63c546bf 100644 --- a/Configuration/PyReleaseValidation/python/relval_2026.py +++ b/Configuration/PyReleaseValidation/python/relval_2026.py @@ -26,6 +26,8 @@ numWFIB.extend([22434.0]) #2026D47 numWFIB.extend([22834.0]) #2026D48 numWFIB.extend([23234.0,23234.1001,23434.1001]) #2026D49, TestOldDigi, TestOldDigi w/ PU +numWFIB.extend([23234.1002,23434.1002]) #2026D49 TestOldDigiProdLike, TestOldDigiProdLike w/ PU +numWFIB.extend([23234.21,23434.21]) #2026D49 prodlike, prodlike PU numWFIB.extend([23634.0]) #2026D51 numWFIB.extend([24834.0]) #2026D54 numWFIB.extend([26234.0]) #2026D55 diff --git a/Configuration/PyReleaseValidation/python/relval_standard.py b/Configuration/PyReleaseValidation/python/relval_standard.py index e08056a950feb..02d64fb05f48f 100644 --- a/Configuration/PyReleaseValidation/python/relval_standard.py +++ b/Configuration/PyReleaseValidation/python/relval_standard.py @@ -415,6 +415,18 @@ workflows[136.888501] = ['',['RunJetHT2018D','HLTDR2_2018','RECODR2_2018reHLT_Patatrack_PixelOnlyCPU','HARVEST2018_pixelTrackingOnly']] workflows[136.888502] = ['',['RunJetHT2018D','HLTDR2_2018','RECODR2_2018reHLT_Patatrack_PixelOnlyGPU','HARVEST2018_pixelTrackingOnly']] +### run 2018D ECAL-only ### +workflows[136.885511] = ['',['RunHLTPhy2018D','HLTDR2_2018','RECODR2_2018reHLT_ECALOnlyCPU','HARVEST2018_ECALOnly']] +workflows[136.885512] = ['',['RunHLTPhy2018D','HLTDR2_2018','RECODR2_2018reHLT_ECALOnlyGPU','HARVEST2018_ECALOnly']] +workflows[136.888511] = ['',['RunJetHT2018D','HLTDR2_2018','RECODR2_2018reHLT_ECALOnlyCPU','HARVEST2018_ECALOnly']] +workflows[136.888512] = ['',['RunJetHT2018D','HLTDR2_2018','RECODR2_2018reHLT_ECALOnlyGPU','HARVEST2018_ECALOnly']] + +### run 2018D HCAL-only ### +workflows[136.885521] = ['',['RunHLTPhy2018D','HLTDR2_2018','RECODR2_2018reHLT_HCALOnlyCPU','HARVEST2018_HCALOnly']] +workflows[136.885522] = ['',['RunHLTPhy2018D','HLTDR2_2018','RECODR2_2018reHLT_HCALOnlyGPU','HARVEST2018_HCALOnly']] +workflows[136.888521] = ['',['RunJetHT2018D','HLTDR2_2018','RECODR2_2018reHLT_HCALOnlyCPU','HARVEST2018_HCALOnly']] +workflows[136.888522] = ['',['RunJetHT2018D','HLTDR2_2018','RECODR2_2018reHLT_HCALOnlyGPU','HARVEST2018_HCALOnly']] + # multi-run harvesting workflows[137.8] = ['',['RunEGamma2018C','HLTDR2_2018','RECODR2_2018reHLT_skimEGamma_Offline_L1TEgDQM', 'RunEGamma2018D','HLTDR2_2018','RECODR2_2018reHLT_skimEGamma_Prompt_L1TEgDQM','HARVEST2018_L1TEgDQM_MULTIRUN']] diff --git a/Configuration/PyReleaseValidation/python/relval_steps.py b/Configuration/PyReleaseValidation/python/relval_steps.py index 177a00c628ab7..d2e79389d4344 100644 --- a/Configuration/PyReleaseValidation/python/relval_steps.py +++ b/Configuration/PyReleaseValidation/python/relval_steps.py @@ -2316,6 +2316,10 @@ def gen2021HiMix(fragment,howMuch): steps['RECODR2_2018reHLT_Prompt_pixelTrackingOnly']=merge([{'-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly,DQM:@pixelTrackingOnlyDQM'},steps['RECODR2_2018reHLT_Prompt']]) steps['RECODR2_2018reHLT_Patatrack_PixelOnlyCPU']=merge([step3_pixelNtupleFit, steps['RECODR2_2018reHLT_Prompt_pixelTrackingOnly']]) steps['RECODR2_2018reHLT_Patatrack_PixelOnlyGPU']=merge([step3_gpu, steps['RECODR2_2018reHLT_Prompt_pixelTrackingOnly']]) +steps['RECODR2_2018reHLT_ECALOnlyCPU']=merge([{'-s': 'RAW2DIGI:RawToDigi_ecalOnly,RECO:reconstruction_ecalOnly,DQM:@ecalOnly'},steps['RECODR2_2018reHLT_Prompt']]) +steps['RECODR2_2018reHLT_ECALOnlyGPU']=merge([step3_gpu, steps['RECODR2_2018reHLT_ECALOnlyCPU']]) +steps['RECODR2_2018reHLT_HCALOnlyCPU']=merge([{'-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnly,DQM:@hcalOnly+@hcal2Only'},steps['RECODR2_2018reHLT_Prompt']]) +steps['RECODR2_2018reHLT_HCALOnlyGPU']=merge([step3_gpu, steps['RECODR2_2018reHLT_HCALOnlyCPU']]) steps['RECODR2_2018reHLT_Offline']=merge([{'--conditions':'auto:run2_data'},steps['RECODR2_2018reHLT']]) steps['RECODR2_2018reHLT_ZBOffline']=merge([{'--conditions':'auto:run2_data','-s':'RAW2DIGI,L1Reco,RECO,EI,PAT,ALCA:SiStripCalZeroBias+SiStripCalMinBias+TkAlMinBias+EcalESAlign,DQM:@rerecoZeroBias+@ExtraHLT+@miniAODDQM'},steps['RECODR2_2018reHLT']]) steps['RECODR2_2018reHLT_skimEGamma_Prompt_L1TEgDQM']=merge([{'--conditions':'auto:run2_data'},steps['RECODR2_2018reHLT_skimEGamma_L1TEgDQM']]) @@ -2671,6 +2675,8 @@ def gen2021HiMix(fragment,howMuch): steps['HARVEST2018_L1TMuDQM'] = merge([ {'-s':'HARVESTING:@standardDQMFakeHLT+@miniAODDQM+@L1TMuon'}, steps['HARVEST2018'] ]) steps['HARVEST2018_L1TMuDQM_Prompt'] = merge([ {'-s':'HARVESTING:@standardDQMFakeHLT+@miniAODDQM+@L1TMuon'}, steps['HARVEST2018_Prompt'] ]) steps['HARVEST2018_pixelTrackingOnly'] = merge([ {'-s':'HARVESTING:@pixelTrackingOnlyDQM'}, steps['HARVEST2018'] ]) +steps['HARVEST2018_ECALOnly'] = merge([ {'-s':'HARVESTING:@ecal'}, steps['HARVEST2018'] ]) +steps['HARVEST2018_HCALOnly'] = merge([ {'-s':'HARVESTING:@hcalOnly'}, steps['HARVEST2018'] ]) steps['HARVEST2018_hBStar'] = merge([ {'--era' : 'Run2_2018_highBetaStar'}, steps['HARVEST2018'] ]) steps['HARVEST2018_HEfail'] = merge([ {'--conditions':'auto:run2_data_HEfail'}, steps['HARVEST2018'] ]) steps['HARVEST2018_BadHcalMitig'] = merge([ {'--era' : 'Run2_2018,pf_badHcalMitigation','--conditions':'auto:run2_data_HEfail'}, steps['HARVEST2018'] ]) @@ -3259,7 +3265,7 @@ def gen2021HiMix(fragment,howMuch): } # Adding Track trigger step in step2 - upgradeStepDict['DigiFullTrigger'][k] = {'-s':'DIGI:pdigi_valid,L1,L1TrackTrigger,DIGI2RAW,HLT:%s'%(hltversion), + upgradeStepDict['DigiFullTrigger'][k] = {'-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,DIGI2RAW,HLT:%s'%(hltversion), '--conditions':gt, '--datatier':'GEN-SIM-DIGI-RAW', '-n':'10', diff --git a/Configuration/PyReleaseValidation/python/relval_upgrade.py b/Configuration/PyReleaseValidation/python/relval_upgrade.py index 477d05dc9e000..a673422ff61f7 100644 --- a/Configuration/PyReleaseValidation/python/relval_upgrade.py +++ b/Configuration/PyReleaseValidation/python/relval_upgrade.py @@ -60,7 +60,7 @@ def makeStepName(key,frag,step,suffix): elif (specialType is not 'baseline') and ( ('PU' in step and step.replace('PU','') in specialWF.PU) or (step in specialWF.steps) ): stepList[specialType].append(stepMaker(key,frag[:-4],step,specialWF.suffix)) # hack to add an extra step - if specialType == 'ProdLike' and 'RecoFullGlobal' in step: + if (specialType == 'ProdLike' or specialType == 'TestOldDigiProdLike') and 'RecoFullGlobal' in step: stepList[specialType].append(stepMaker(key,frag[:-4],step.replace('RecoFullGlobal','MiniAODFullGlobal'),specialWF.suffix)) elif specialType == 'ProdLike' and 'RecoFull' in step: stepList[specialType].append(stepMaker(key,frag[:-4],step.replace('RecoFull','MiniAODFullGlobal'),specialWF.suffix)) diff --git a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py index c0c6a2cafda65..4e67178336fa1 100644 --- a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py +++ b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py @@ -1,7 +1,7 @@ from copy import deepcopy from collections import OrderedDict import six -from .MatrixUtil import merge +from .MatrixUtil import merge, Kby # DON'T CHANGE THE ORDER, only append new keys. Otherwise the numbering for the runTheMatrix tests will change. @@ -252,7 +252,7 @@ def setup_(self, step, stepName, stepDict, k, properties): if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]]) elif 'HARVEST' in step: stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM'}, stepDict[step][k]]) def condition_(self, fragment, stepList, key, hasHarvest): - return '2017' in key or '2018' in key + return '2017' in key or '2018' in key or '2021' in key upgradeWFs['pixelTrackingOnly'] = UpgradeWorkflow_pixelTrackingOnly( steps = [ 'RecoFull', @@ -420,6 +420,63 @@ def condition_(self, fragment, stepList, key, hasHarvest): '--procModifiers': 'gpu' } +class UpgradeWorkflowPatatrack_HCALOnlyCPU(UpgradeWorkflowPatatrack): + def setup_(self, step, stepName, stepDict, k, properties): + if 'Reco' in step: + stepDict[stepName][k] = merge([self.step3, stepDict[step][k]]) + elif 'HARVEST' in step: + stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@hcalOnlyValidation+@hcalOnly+@hcal2Only'}, stepDict[step][k]]) + + def condition_(self, fragment, stepList, key, hasHarvest): + return '2018' in key or '2021' in key + +upgradeWFs['PatatrackHCALOnlyCPU'] = UpgradeWorkflowPatatrack_HCALOnlyCPU( + steps = [ + 'RecoFull', + 'HARVESTFull', + 'RecoFullGlobal', + 'HARVESTFullGlobal', + ], + PU = [], + suffix = 'Patatrack_HCALOnlyCPU', + offset = 0.521, +) + +upgradeWFs['PatatrackHCALOnlyCPU'].step3 = { + '-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnly,VALIDATION:@hcalOnlyValidation,DQM:@hcalOnly+@hcal2Only', + '--datatier': 'GEN-SIM-RECO,DQMIO', + '--eventcontent': 'RECOSIM,DQM', +} + +class UpgradeWorkflowPatatrack_HCALOnlyGPU(UpgradeWorkflowPatatrack): + def setup_(self, step, stepName, stepDict, k, properties): + if 'Reco' in step: + stepDict[stepName][k] = merge([self.step3, stepDict[step][k]]) + elif 'HARVEST' in step: + stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@hcalOnlyValidation+@hcalOnly+@hcal2Only'}, stepDict[step][k]]) + + def condition_(self, fragment, stepList, key, hasHarvest): + return '2018' in key or '2021' in key + +upgradeWFs['PatatrackHCALOnlyGPU'] = UpgradeWorkflowPatatrack_HCALOnlyGPU( + steps = [ + 'RecoFull', + 'HARVESTFull', + 'RecoFullGlobal', + 'HARVESTFullGlobal', + ], + PU = [], + suffix = 'Patatrack_HCALOnlyGPU', + offset = 0.522, +) + +upgradeWFs['PatatrackHCALOnlyGPU'].step3 = { + '-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnly,VALIDATION:@hcalOnlyValidation,DQM:@hcalOnly+@hcal2Only', + '--datatier': 'GEN-SIM-RECO,DQMIO', + '--eventcontent': 'RECOSIM,DQM', + '--procModifiers': 'gpu' +} + # end of Patatrack workflows class UpgradeWorkflow_ProdLike(UpgradeWorkflow): @@ -611,13 +668,37 @@ class UpgradeWorkflow_TestOldDigi(UpgradeWorkflow): def setup_(self, step, stepName, stepDict, k, properties): if 'Reco' in step: # use existing DIGI-RAW file from old release - stepDict[stepName][k] = merge([{'--filein': 'das:/RelValTTbar_14TeV/CMSSW_11_0_0_pre13-110X_mcRun4_realistic_v2_2026D49noPU-v1/GEN-SIM-DIGI-RAW'}, stepDict[step][k]]) + # re-emulate the full L1 trigger when running on 11_0 DIGI, i.e. replace L1Reco with L1TrackTrigger,L1 + mods = { + '--filein': 'das:/RelValTTbar_14TeV/CMSSW_11_0_0_pre13-110X_mcRun4_realistic_v2_2026D49noPU-v1/GEN-SIM-DIGI-RAW', + '--customise': "L1Trigger/Configuration/customisePhase2TTNoMC.customisePhase2TTNoMC", + } + # for prodlike case + if self.prodlike: + mods['-s'] = 'RAW2DIGI,L1TrackTrigger,L1,RECO,RECOSIM' + mods['--datatier'] = 'AODSIM' + mods['--eventcontent'] = 'AODSIM' + else: + mods['-s'] = stepDict[step][k]['-s'].replace("L1Reco","L1TrackTrigger,L1") + stepDict[stepName][k] = merge([mods, stepDict[step][k]]) # handle separate PU input stepNamePU = step + 'PU' + self.suffix - stepDict[stepNamePU][k] = merge([{'--filein': 'das:/RelValTTbar_14TeV/CMSSW_11_0_0_pre13-PU25ns_110X_mcRun4_realistic_v2_2026D49PU200-v2/GEN-SIM-DIGI-RAW'},stepDict[stepName][k]]) + mods['--filein'] = 'das:/RelValTTbar_14TeV/CMSSW_11_0_0_pre13-PU25ns_110X_mcRun4_realistic_v2_2026D49PU200-v2/GEN-SIM-DIGI-RAW' + stepDict[stepNamePU][k] = merge([mods,stepDict[stepName][k]]) elif 'GenSim' in step or 'Digi' in step: # remove step stepDict[stepName][k] = None + + # other prodlike adjustments + if self.prodlike: + if 'MiniAOD' in step and self.prodlike: + # the separate miniAOD step is used here + stepDict[stepName][k] = deepcopy(stepDict[step][k]) + elif 'ALCA' in step or 'HARVEST' in step: + # remove step + stepDict[stepName][k] = None + elif 'Nano' in step: + stepDict[stepName][k] = merge([{'--filein':'file:step4.root'}, stepDict[step][k]]) def condition(self, fragment, stepList, key, hasHarvest): # limited to HLT TDR production geometry return fragment=="TTbar_14TeV" and '2026D49' in key @@ -637,6 +718,26 @@ def workflow_(self, workflows, num, fragment, stepList): suffix = '_TestOldDigi', offset = 0.1001, ) +upgradeWFs['TestOldDigi'].prodlike = False +upgradeWFs['TestOldDigiProdLike'] = UpgradeWorkflow_TestOldDigi( + steps = [ + 'GenSimHLBeamSpotFull', + 'GenSimHLBeamSpotFull14', + 'DigiFullTrigger', + 'RecoFullGlobal', + 'HARVESTFullGlobal', + 'MiniAODFullGlobal', + ], + PU = [ + 'DigiFullTrigger', + 'RecoFullGlobal', + 'HARVESTFullGlobal', + 'MiniAODFullGlobal', + ], + suffix = '_TestOldDigiProdLike', + offset = 0.1002, +) +upgradeWFs['TestOldDigiProdLike'].prodlike = True # check for duplicate offsets offsets = [specialWF.offset for specialType,specialWF in six.iteritems(upgradeWFs)] @@ -848,7 +949,6 @@ def workflow_(self, workflows, num, fragment, stepList): if 'PU' in key: continue defaultDataSets[key] = '' -from Configuration.PyReleaseValidation.relval_steps import Kby class UpgradeFragment(object): def __init__(self, howMuch, dataset): diff --git a/Configuration/StandardSequences/python/AlCaRecoStreams_cff.py b/Configuration/StandardSequences/python/AlCaRecoStreams_cff.py index 89fbabf913622..b9048810c9a5a 100644 --- a/Configuration/StandardSequences/python/AlCaRecoStreams_cff.py +++ b/Configuration/StandardSequences/python/AlCaRecoStreams_cff.py @@ -231,6 +231,7 @@ pathALCARECOTkAlCosmicsCTF0T = cms.Path(seqALCARECOTkAlCosmicsCTF0T*ALCARECOTkAlCosmicsCTF0TDQM) pathALCARECOTkAlCosmicsCosmicTF0T = cms.Path(seqALCARECOTkAlCosmicsCosmicTF0T*ALCARECOTkAlCosmicsCosmicTF0TDQM) pathALCARECOTkAlCosmicsRegional0T = cms.Path(seqALCARECOTkAlCosmicsRegional0T*ALCARECOTkAlCosmicsRegional0TDQM) +pathALCARECOTkAlCosmicsDuringCollisions0T = cms.Path(seqALCARECOTkAlCosmicsDuringCollisions0T*ALCARECOTkAlCosmicsInCollisions0TDQM) pathALCARECOTkAlCosmicsCTFHLT = cms.Path(seqALCARECOTkAlCosmicsCTFHLT*ALCARECOTkAlCosmicsCTFDQM) pathALCARECOTkAlCosmicsCosmicTFHLT = cms.Path(seqALCARECOTkAlCosmicsCosmicTFHLT*ALCARECOTkAlCosmicsCosmicTFDQM) pathALCARECOTkAlCosmicsRegionalHLT = cms.Path(seqALCARECOTkAlCosmicsRegionalHLT*ALCARECOTkAlCosmicsRegionalDQM) @@ -728,7 +729,7 @@ ALCARECOStreamTkAlCosmics0T = cms.FilteredStream( responsible = 'Andreas Mussgiller', name = 'TkAlCosmics0T', - paths = (pathALCARECOTkAlCosmicsCTF0T,pathALCARECOTkAlCosmicsCosmicTF0T,pathALCARECOTkAlCosmicsRegional0T), + paths = (pathALCARECOTkAlCosmicsCTF0T,pathALCARECOTkAlCosmicsCosmicTF0T,pathALCARECOTkAlCosmicsRegional0T,pathALCARECOTkAlCosmicsDuringCollisions0T), content = OutALCARECOTkAlCosmics0T.outputCommands, selectEvents = OutALCARECOTkAlCosmics0T.SelectEvents, dataTier = cms.untracked.string('ALCARECO') diff --git a/Configuration/StandardSequences/python/L1TrackTrigger_cff.py b/Configuration/StandardSequences/python/L1TrackTrigger_cff.py index 0137b4f3bde89..72d586d6a2e80 100644 --- a/Configuration/StandardSequences/python/L1TrackTrigger_cff.py +++ b/Configuration/StandardSequences/python/L1TrackTrigger_cff.py @@ -2,9 +2,17 @@ from L1Trigger.TrackTrigger.TrackTrigger_cff import * from SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff import * -from L1Trigger.TrackerDTC.Producer_cff import * +from L1Trigger.TrackerDTC.ProducerED_cff import * +from L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff import * -#L1TrackTrigger=cms.Sequence(TrackTriggerClustersStubs*TrackTriggerAssociatorClustersStubs*TrackTriggerTTTracks*TrackTriggerAssociatorTracks) L1TrackTrigger=cms.Sequence(TrackTriggerClustersStubs*TrackTriggerAssociatorClustersStubs*TrackerDTCProducer) -TTStubAlgorithm_official_Phase2TrackerDigi_.zMatchingPS = cms.bool(True) +# Customisation to enable TTTracks in geometry D41 and later (corresponding to phase2_trackerV14 or later). Includes the HGCAL L1 trigger +_tttracks_l1tracktrigger = L1TrackTrigger.copy() +_tttracks_l1tracktrigger = cms.Sequence(_tttracks_l1tracktrigger + L1PromptExtendedHybridTracksWithAssociators) + +from Configuration.Eras.Modifier_phase2_trackerV14_cff import phase2_trackerV14 +from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger +(phase2_trigger & phase2_trackerV14).toReplaceWith( L1TrackTrigger, _tttracks_l1tracktrigger ) + +TTStubAlgorithm_official_Phase2TrackerDigi_.zMatchingPS = True diff --git a/Configuration/StandardSequences/python/RawToDigi_cff.py b/Configuration/StandardSequences/python/RawToDigi_cff.py index cf43133e5d829..d0af52de00a47 100644 --- a/Configuration/StandardSequences/python/RawToDigi_cff.py +++ b/Configuration/StandardSequences/python/RawToDigi_cff.py @@ -69,6 +69,9 @@ RawToDigiTask_ecalOnly = cms.Task(ecalDigisTask, ecalPreshowerDigis, scalersRawToDigi) RawToDigi_ecalOnly = cms.Sequence(RawToDigiTask_ecalOnly) +RawToDigiTask_hcalOnly = cms.Task(hcalDigis) +RawToDigi_hcalOnly = cms.Sequence(RawToDigiTask_hcalOnly) + scalersRawToDigi.scalersInputTag = 'rawDataCollector' siPixelDigis.InputLabel = 'rawDataCollector' ecalDigis.InputLabel = 'rawDataCollector' diff --git a/Configuration/StandardSequences/python/Reconstruction_cff.py b/Configuration/StandardSequences/python/Reconstruction_cff.py index c6098f6cf956c..90d2b05cbb7d1 100644 --- a/Configuration/StandardSequences/python/Reconstruction_cff.py +++ b/Configuration/StandardSequences/python/Reconstruction_cff.py @@ -208,6 +208,9 @@ logErrorHarvester.includeModules = cms.untracked.vstring(set(_modulesInReconstruction)) reconstruction_trackingOnlyTask = cms.Task(localrecoTask,globalreco_trackingTask) +#calo parts removed as long as tracking is not running jetCore in phase2 +trackingPhase2PU140.toReplaceWith(reconstruction_trackingOnlyTask, + reconstruction_trackingOnlyTask.copyAndExclude([hgcalLocalRecoTask,castorreco])) reconstruction_trackingOnly = cms.Sequence(reconstruction_trackingOnlyTask) reconstruction_pixelTrackingOnlyTask = cms.Task( pixeltrackerlocalrecoTask, @@ -227,6 +230,15 @@ ) reconstruction_ecalOnly = cms.Sequence(reconstruction_ecalOnlyTask) +reconstruction_hcalOnlyTask = cms.Task( + bunchSpacingProducer, + offlineBeamSpot, + hcalOnlyLocalRecoTask, + pfClusteringHBHEHFOnlyTask +) + +reconstruction_hcalOnly = cms.Sequence(reconstruction_hcalOnlyTask) + #need a fully expanded sequence copy modulesToRemove = list() # copy does not work well noTrackingAndDependent = list() diff --git a/DQM/BeamMonitor/plugins/BeamMonitor.cc b/DQM/BeamMonitor/plugins/BeamMonitor.cc index 2be6bd823d3be..2fa5e6f077fe8 100644 --- a/DQM/BeamMonitor/plugins/BeamMonitor.cc +++ b/DQM/BeamMonitor/plugins/BeamMonitor.cc @@ -28,6 +28,7 @@ V00-03-25 #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Common/interface/TriggerNames.h" #include "DataFormats/HLTReco/interface/TriggerEvent.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotOnlineObjects.h" #include #include #include @@ -116,6 +117,7 @@ BeamMonitor::BeamMonitor(const ParameterSet& ps) firstAverageFit_(0), countGapLumi_(0) { monitorName_ = ps.getUntrackedParameter("monitorName", "YourSubsystemName"); + recordName_ = ps.getUntrackedParameter("recordName"); bsSrc_ = consumes(ps.getUntrackedParameter("beamSpot")); tracksLabel_ = consumes( ps.getParameter("BeamFitter").getUntrackedParameter("TrackCollection")); @@ -513,6 +515,13 @@ void BeamMonitor::bookHistograms(DQMStore::IBooker& iBooker, edm::Run const& iRu //-------------------------------------------------------- void BeamMonitor::beginLuminosityBlock(const LuminosityBlock& lumiSeg, const EventSetup& context) { + // start DB logger + DBloggerReturn_ = 0; + if (onlineDbService_.isAvailable()) { + onlineDbService_->logger().start(); + onlineDbService_->logger().logInfo() << "BeamMonitor::beginLuminosityBlock"; + } + int nthlumi = lumiSeg.luminosityBlock(); const edm::TimeValue_t fbegintimestamp = lumiSeg.beginTime().value(); const std::time_t ftmptime = fbegintimestamp >> 32; @@ -781,6 +790,12 @@ void BeamMonitor::endLuminosityBlock(const LuminosityBlock& lumiSeg, const Event const edm::TimeValue_t fendtimestamp = lumiSeg.endTime().value(); const std::time_t fendtime = fendtimestamp >> 32; tmpTime = refBStime[1] = refPVtime[1] = fendtime; + + // end DB logger + if (onlineDbService_.isAvailable()) { + onlineDbService_->logger().logInfo() << "BeamMonitor::endLuminosityBlock"; + onlineDbService_->logger().end(DBloggerReturn_); + } } //-------------------------------------------------------- @@ -1324,6 +1339,75 @@ void BeamMonitor::FitAndFill(const LuminosityBlock& lumiSeg, int& lastlumi, int& summaryContent_[2] += 1.; // } + // Create the BeamSpotOnlineObjects object + BeamSpotOnlineObjects* BSOnline = new BeamSpotOnlineObjects(); + BSOnline->SetLastAnalyzedLumi(fitLS.second); + BSOnline->SetLastAnalyzedRun(theBeamFitter->getRunNumber()); + BSOnline->SetLastAnalyzedFill(0); // To be updated with correct LHC Fill number + BSOnline->SetPosition(bs.x0(), bs.y0(), bs.z0()); + BSOnline->SetSigmaZ(bs.sigmaZ()); + BSOnline->SetBeamWidthX(bs.BeamWidthX()); + BSOnline->SetBeamWidthY(bs.BeamWidthY()); + BSOnline->SetBeamWidthXError(bs.BeamWidthXError()); + BSOnline->SetBeamWidthYError(bs.BeamWidthYError()); + BSOnline->Setdxdz(bs.dxdz()); + BSOnline->Setdydz(bs.dydz()); + BSOnline->SetType(bs.type()); + BSOnline->SetEmittanceX(bs.emittanceX()); + BSOnline->SetEmittanceY(bs.emittanceY()); + BSOnline->SetBetaStar(bs.betaStar()); + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + BSOnline->SetCovariance(i, j, bs.covariance(i, j)); + } + } + BSOnline->SetNumTracks(theBeamFitter->getNTracks()); + BSOnline->SetNumPVs(theBeamFitter->getNPVs()); + auto creationTime = + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) + .count(); + BSOnline->SetCreationTime(creationTime); + + edm::LogInfo("BeamMonitor") << "FitAndFill::[PayloadCreation] BeamSpotOnline object created: \n" << std::endl; + edm::LogInfo("BeamMonitor") << *BSOnline << std::endl; + + // Create the payload for BeamSpotOnlineObjects object + if (onlineDbService_.isAvailable()) { + edm::LogInfo("BeamMonitor") << "FitAndFill::[PayloadCreation] onlineDbService available \n" << std::endl; + onlineDbService_->logger().logInfo() << "BeamMonitor::FitAndFill - Lumi of the current fit: " << currentlumi; + onlineDbService_->logger().logInfo() + << "BeamMonitor::FitAndFill - Do PV Fitting for LS = " << beginLumiOfPVFit_ << " to " << endLumiOfPVFit_; + onlineDbService_->logger().logInfo() + << "BeamMonitor::FitAndFill - [BeamFitter] Do BeamSpot Fit for LS = " << fitLS.first << " to " + << fitLS.second; + onlineDbService_->logger().logInfo() + << "BeamMonitor::FitAndFill - [BeamMonitor] Do BeamSpot Fit for LS = " << beginLumiOfBSFit_ << " to " + << endLumiOfBSFit_; + onlineDbService_->logger().logInfo() << "BeamMonitor - RESULTS OF DEFAULT FIT:"; + onlineDbService_->logger().logInfo() << "\n" << bs; + onlineDbService_->logger().logInfo() + << "BeamMonitor::FitAndFill - [PayloadCreation] BeamSpotOnline object created:"; + onlineDbService_->logger().logInfo() << "\n" << *BSOnline; + onlineDbService_->logger().logInfo() << "BeamMonitor::FitAndFill - [PayloadCreation] onlineDbService available"; + onlineDbService_->logger().logInfo() + << "BeamMonitor::FitAndFill - [PayloadCreation] SetCreationTime: " << creationTime + << " [epoch in microseconds]"; + try { + onlineDbService_->writeForNextLumisection(BSOnline, recordName_); + onlineDbService_->logger().logInfo() + << "BeamMonitor::FitAndFill - [PayloadCreation] writeForNextLumisection executed correctly"; + DBloggerReturn_ = 2; + } catch (const std::exception& e) { + onlineDbService_->logger().logError() << "BeamMonitor - Error writing record: " << recordName_ + << " for Run: " << frun << " - Lumi: " << fitLS.second; + onlineDbService_->logger().logError() << "Error is: " << e.what(); + onlineDbService_->logger().logError() << "RESULTS OF DEFAULT FIT WAS:"; + onlineDbService_->logger().logError() << "\n" << bs; + DBloggerReturn_ = -1; + } + } + edm::LogInfo("BeamMonitor") << "FitAndFill::[PayloadCreation] BeamSpotOnline payload created \n" << std::endl; + } //if (theBeamFitter->runPVandTrkFitter()) else { // beam fit fails reco::BeamSpot bs = theBeamFitter->getBeamSpot(); @@ -1331,6 +1415,12 @@ void BeamMonitor::FitAndFill(const LuminosityBlock& lumiSeg, int& lastlumi, int& edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamMonitor] Output beam spot for DIP \n" << endl; edm::LogInfo("BeamMonitor") << bs << endl; + if (onlineDbService_.isAvailable()) { + onlineDbService_->logger().logInfo() << "BeamMonitor::FitAndFill - Beam fit fails!!!"; + onlineDbService_->logger().logInfo() << "BeamMonitor::FitAndFill - Output beam spot for DIP"; + onlineDbService_->logger().logInfo() << "\n" << bs; + } + hs[k_sigmaX0_lumi]->ShiftFillLast(bs.BeamWidthX(), bs.BeamWidthXError(), fitNLumi_); hs[k_sigmaY0_lumi]->ShiftFillLast(bs.BeamWidthY(), bs.BeamWidthYError(), fitNLumi_); hs[k_sigmaZ0_lumi]->ShiftFillLast(bs.sigmaZ(), bs.sigmaZ0Error(), fitNLumi_); @@ -1351,6 +1441,12 @@ void BeamMonitor::FitAndFill(const LuminosityBlock& lumiSeg, int& lastlumi, int& edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamMonitor] Output fake beam spot for DIP \n" << endl; edm::LogInfo("BeamMonitor") << bs << endl; + if (onlineDbService_.isAvailable()) { + onlineDbService_->logger().logInfo() << "BeamMonitor::FitAndFill - No fitting"; + onlineDbService_->logger().logInfo() << "BeamMonitor::FitAndFill - Output fake beam spot for DIP"; + onlineDbService_->logger().logInfo() << "\n" << bs; + } + hs[k_sigmaX0_lumi]->ShiftFillLast(bs.BeamWidthX(), bs.BeamWidthXError(), fitNLumi_); hs[k_sigmaY0_lumi]->ShiftFillLast(bs.BeamWidthY(), bs.BeamWidthYError(), fitNLumi_); hs[k_sigmaZ0_lumi]->ShiftFillLast(bs.sigmaZ(), bs.sigmaZ0Error(), fitNLumi_); diff --git a/DQM/BeamMonitor/plugins/BeamMonitor.h b/DQM/BeamMonitor/plugins/BeamMonitor.h index ced0f134d059d..229ce6fb1c382 100644 --- a/DQM/BeamMonitor/plugins/BeamMonitor.h +++ b/DQM/BeamMonitor/plugins/BeamMonitor.h @@ -24,6 +24,7 @@ #include "DQMServices/Core/interface/DQMOneEDAnalyzer.h" #include "RecoVertex/BeamSpotProducer/interface/BSTrkParameters.h" #include "RecoVertex/BeamSpotProducer/interface/BeamFitter.h" +#include "CondCore/DBOutputService/interface/OnlineDBOutputService.h" #include // @@ -68,10 +69,13 @@ class BeamMonitor : public DQMOneEDAnalyzer { const double dzMin_; const double dzMax_; std::string monitorName_; + std::string recordName_; edm::EDGetTokenT bsSrc_; // beam spot edm::EDGetTokenT tracksLabel_; - edm::EDGetTokenT pvSrc_; // primary vertex - edm::EDGetTokenT hltSrc_; //hlt collection + edm::EDGetTokenT pvSrc_; // primary vertex + edm::EDGetTokenT hltSrc_; //hlt collection + edm::Service onlineDbService_; // DB service + int DBloggerReturn_; // DB logger return value int fitNLumi_; int fitPVNLumi_; diff --git a/DQM/BeamMonitor/plugins/BuildFile.xml b/DQM/BeamMonitor/plugins/BuildFile.xml index d132c1f0a7828..3c22dc071607f 100644 --- a/DQM/BeamMonitor/plugins/BuildFile.xml +++ b/DQM/BeamMonitor/plugins/BuildFile.xml @@ -1,4 +1,5 @@ + @@ -7,6 +8,7 @@ + @@ -19,6 +21,10 @@ + + + + @@ -43,3 +49,7 @@ + + + + diff --git a/DQM/BeamMonitor/plugins/FakeBeamMonitor.cc b/DQM/BeamMonitor/plugins/FakeBeamMonitor.cc new file mode 100644 index 0000000000000..a4819493e3f6d --- /dev/null +++ b/DQM/BeamMonitor/plugins/FakeBeamMonitor.cc @@ -0,0 +1,1609 @@ +/* + * \file FakeBeamMonitor.cc + * \author Geng-yuan Jeng/UC Riverside + * Francisco Yumiceva/FNAL + */ + +/* +The code has been modified for running average +mode, and it gives results for the last NLS which is +configurable. +Sushil S. Chauhan /UCDavis +Evan Friis /UCDavis +The last tag for working versions without this change is +V00-03-25 +*/ + +#include "DQM/BeamMonitor/plugins/FakeBeamMonitor.h" +#include "DQMServices/Core/interface/DQMStore.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "DataFormats/TrackCandidate/interface/TrackCandidate.h" +#include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h" +#include "DataFormats/Common/interface/View.h" +#include "RecoVertex/BeamSpotProducer/interface/BSFitter.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/LuminosityBlock.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Common/interface/TriggerNames.h" +#include "DataFormats/HLTReco/interface/TriggerEvent.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotOnlineObjects.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; + +void FakeBeamMonitor::formatFitTime(char* ts, const time_t& t) { + //constexpr int CET(+1); + constexpr int CEST(+2); + + //tm * ptm; + //ptm = gmtime ( &t ); + //int year = ptm->tm_year; + + //get correct year from ctime + time_t currentTime; + struct tm* localTime; + time(¤tTime); // Get the current time + localTime = localtime(¤tTime); // Convert the current time to the local time + int year = localTime->tm_year + 1900; + + tm* ptm; + ptm = gmtime(&t); + + //check if year is ok + if (year <= 37) + year += 2000; + if (year >= 70 && year <= 137) + year += 1900; + + if (year < 1995) { + edm::LogError("BadTimeStamp") << "year reported is " << year << " !!" << std::endl; + //year = 2015; //overwritten later by BeamFitter.cc for fits but needed here for TH1 + //edm::LogError("BadTimeStamp") << "Resetting to " <tm_mon + 1, + ptm->tm_mday, + (ptm->tm_hour + CEST) % 24, + ptm->tm_min, + ptm->tm_sec); + +#ifdef STRIP_TRAILING_BLANKS_IN_TIMEZONE + unsigned int b = strlen(ts); + while (ts[--b] == ' ') { + ts[b] = 0; + } +#endif +} + +static constexpr int buffTime = 23; + +// +// constructors and destructor +// +FakeBeamMonitor::~FakeBeamMonitor() { delete rndm_; }; + +FakeBeamMonitor::FakeBeamMonitor(const ParameterSet& ps) + : dxBin_(ps.getParameter("dxBin")), + dxMin_(ps.getParameter("dxMin")), + dxMax_(ps.getParameter("dxMax")), + + vxBin_(ps.getParameter("vxBin")), + vxMin_(ps.getParameter("vxMin")), + vxMax_(ps.getParameter("vxMax")), + + phiBin_(ps.getParameter("phiBin")), + phiMin_(ps.getParameter("phiMin")), + phiMax_(ps.getParameter("phiMax")), + + dzBin_(ps.getParameter("dzBin")), + dzMin_(ps.getParameter("dzMin")), + dzMax_(ps.getParameter("dzMax")), + + countEvt_(0), + countLumi_(0), + nthBSTrk_(0), + nFitElements_(3), + resetHistos_(false), + StartAverage_(false), + firstAverageFit_(0), + countGapLumi_(0) { + monitorName_ = ps.getUntrackedParameter("monitorName", "YourSubsystemName"); + recordName_ = ps.getUntrackedParameter("recordName"); + intervalInSec_ = ps.getUntrackedParameter("timeInterval", 920); //40 LS X 23" + fitNLumi_ = ps.getUntrackedParameter("fitEveryNLumi", -1); + resetFitNLumi_ = ps.getUntrackedParameter("resetEveryNLumi", -1); + fitPVNLumi_ = ps.getUntrackedParameter("fitPVEveryNLumi", -1); + resetPVNLumi_ = ps.getUntrackedParameter("resetPVEveryNLumi", -1); + deltaSigCut_ = ps.getUntrackedParameter("deltaSignificanceCut", 15); + debug_ = ps.getUntrackedParameter("Debug"); + onlineMode_ = ps.getUntrackedParameter("OnlineMode"); + min_Ntrks_ = ps.getParameter("BeamFitter").getUntrackedParameter("MinimumInputTracks"); + maxZ_ = ps.getParameter("BeamFitter").getUntrackedParameter("MaximumZ"); + minNrVertices_ = ps.getParameter("PVFitter").getUntrackedParameter("minNrVerticesForFit"); + minVtxNdf_ = ps.getParameter("PVFitter").getUntrackedParameter("minVertexNdf"); + minVtxWgt_ = ps.getParameter("PVFitter").getUntrackedParameter("minVertexMeanWeight"); + + if (!monitorName_.empty()) + monitorName_ = monitorName_ + "/"; + + if (fitNLumi_ <= 0) + fitNLumi_ = 1; + nFits_ = beginLumiOfBSFit_ = endLumiOfBSFit_ = beginLumiOfPVFit_ = endLumiOfPVFit_ = 0; + refBStime[0] = refBStime[1] = refPVtime[0] = refPVtime[1] = 0; + maxZ_ = std::fabs(maxZ_); + lastlumi_ = 0; + nextlumi_ = 0; + processed_ = false; + + rndm_ = new TRandom3(0); +} + +//-------------------------------------------------------- +namespace { + /*The order of the enums is identical to the order in which + MonitorElements are added to hs + */ + enum Hists { + k_x0_lumi, + k_x0_lumi_all, + k_y0_lumi, + k_y0_lumi_all, + k_z0_lumi, + k_z0_lumi_all, + k_sigmaX0_lumi, + k_sigmaX0_lumi_all, + k_sigmaY0_lumi, + k_sigmaY0_lumi_all, + k_sigmaZ0_lumi, + k_sigmaZ0_lumi_all, + k_x0_time, + k_x0_time_all, + k_y0_time, + k_y0_time_all, + k_z0_time, + k_z0_time_all, + k_sigmaX0_time, + k_sigmaX0_time_all, + k_sigmaY0_time, + k_sigmaY0_time_all, + k_sigmaZ0_time, + k_sigmaZ0_time_all, + k_PVx_lumi, + k_PVx_lumi_all, + k_PVy_lumi, + k_PVy_lumi_all, + k_PVz_lumi, + k_PVz_lumi_all, + k_PVx_time, + k_PVx_time_all, + k_PVy_time, + k_PVy_time_all, + k_PVz_time, + k_PVz_time_all, + kNumHists + }; +} // namespace + +void FakeBeamMonitor::bookHistograms(DQMStore::IBooker& iBooker, edm::Run const& iRun, edm::EventSetup const& iSetup) { + frun = iRun.run(); + ftimestamp = iRun.beginTime().value(); + tmpTime = ftimestamp >> 32; + startTime = refTime = tmpTime; + char eventTime[64]; + formatFitTime(eventTime, tmpTime); + edm::LogInfo("FakeBeamMonitor") << "TimeOffset = " << eventTime << std::endl; + TDatime da(eventTime); + if (debug_) { + edm::LogInfo("FakeBeamMonitor") << "TimeOffset = "; + da.Print(); + } + auto daTime = da.Convert(kTRUE); + + // book some histograms here + + // create and cd into new folder + iBooker.setCurrentFolder(monitorName_ + "Fit"); + + h_nTrk_lumi = iBooker.book1D("nTrk_lumi", "Num. of selected tracks vs lumi (Fit)", 20, 0.5, 20.5); + h_nTrk_lumi->setAxisTitle("Lumisection", 1); + h_nTrk_lumi->setAxisTitle("Num of Tracks for Fit", 2); + + //store vtx vs lumi for monitoring why fits fail + h_nVtx_lumi = iBooker.book1D("nVtx_lumi", "Num. of selected Vtx vs lumi (Fit)", 20, 0.5, 20.5); + h_nVtx_lumi->setAxisTitle("Lumisection", 1); + h_nVtx_lumi->setAxisTitle("Num of Vtx for Fit", 2); + + h_nVtx_lumi_all = iBooker.book1D("nVtx_lumi_all", "Num. of selected Vtx vs lumi (Fit) all", 20, 0.5, 20.5); + h_nVtx_lumi_all->getTH1()->SetCanExtend(TH1::kAllAxes); + h_nVtx_lumi_all->setAxisTitle("Lumisection", 1); + h_nVtx_lumi_all->setAxisTitle("Num of Vtx for Fit", 2); + + h_d0_phi0 = iBooker.bookProfile( + "d0_phi0", "d_{0} vs. #phi_{0} (Selected Tracks)", phiBin_, phiMin_, phiMax_, dxBin_, dxMin_, dxMax_, ""); + h_d0_phi0->setAxisTitle("#phi_{0} (rad)", 1); + h_d0_phi0->setAxisTitle("d_{0} (cm)", 2); + + h_vx_vy = iBooker.book2D( + "trk_vx_vy", "Vertex (PCA) position of selected tracks", vxBin_, vxMin_, vxMax_, vxBin_, vxMin_, vxMax_); + h_vx_vy->setOption("COLZ"); + // h_vx_vy->getTH1()->SetCanExtend(TH1::kAllAxes); + h_vx_vy->setAxisTitle("x coordinate of input track at PCA (cm)", 1); + h_vx_vy->setAxisTitle("y coordinate of input track at PCA (cm)", 2); + + { + TDatime* da = new TDatime(); + gStyle->SetTimeOffset(da->Convert(kTRUE)); + } + + const int nvar_ = 6; + string coord[nvar_] = {"x", "y", "z", "sigmaX", "sigmaY", "sigmaZ"}; + string label[nvar_] = { + "x_{0} (cm)", "y_{0} (cm)", "z_{0} (cm)", "#sigma_{X_{0}} (cm)", "#sigma_{Y_{0}} (cm)", "#sigma_{Z_{0}} (cm)"}; + + hs.clear(); + hs.reserve(kNumHists); + for (int i = 0; i < 4; i++) { + iBooker.setCurrentFolder(monitorName_ + "Fit"); + for (int ic = 0; ic < nvar_; ++ic) { + TString histName(coord[ic]); + TString histTitle(coord[ic]); + string ytitle(label[ic]); + string xtitle(""); + string options("E1"); + bool createHisto = true; + switch (i) { + case 1: // BS vs time + histName += "0_time"; + xtitle = "Time [UTC]"; + if (ic < 3) + histTitle += " coordinate of beam spot vs time (Fit)"; + else + histTitle = histTitle.Insert(5, " ") + " of beam spot vs time (Fit)"; + break; + case 2: // PV vs lumi + if (ic < 3) { + iBooker.setCurrentFolder(monitorName_ + "PrimaryVertex"); + histName.Insert(0, "PV"); + histName += "_lumi"; + histTitle.Insert(0, "Avg. "); + histTitle += " position of primary vtx vs lumi"; + xtitle = "Lumisection"; + ytitle.insert(0, "PV"); + ytitle += " #pm #sigma_{PV"; + ytitle += coord[ic]; + ytitle += "} (cm)"; + } else + createHisto = false; + break; + case 3: // PV vs time + if (ic < 3) { + iBooker.setCurrentFolder(monitorName_ + "PrimaryVertex"); + histName.Insert(0, "PV"); + histName += "_time"; + histTitle.Insert(0, "Avg. "); + histTitle += " position of primary vtx vs time"; + xtitle = "Time [UTC]"; + ytitle.insert(0, "PV"); + ytitle += " #pm #sigma_{PV"; + ytitle += coord[ic]; + ytitle += "} (cm)"; + } else + createHisto = false; + break; + default: // BS vs lumi + histName += "0_lumi"; + xtitle = "Lumisection"; + if (ic < 3) + histTitle += " coordinate of beam spot vs lumi (Fit)"; + else + histTitle = histTitle.Insert(5, " ") + " of beam spot vs lumi (Fit)"; + break; + } + if (createHisto) { + edm::LogInfo("FakeBeamMonitor") << "hitsName = " << histName << "; histTitle = " << histTitle << std::endl; + auto tmpHs = iBooker.book1D(histName, histTitle, 40, 0.5, 40.5); + hs.push_back(tmpHs); + tmpHs->setAxisTitle(xtitle, 1); + tmpHs->setAxisTitle(ytitle, 2); + tmpHs->getTH1()->SetOption("E1"); + if (histName.Contains("time")) { + //int nbins = (intervalInSec_/23 > 0 ? intervalInSec_/23 : 40); + tmpHs->getTH1()->SetBins(intervalInSec_, 0.5, intervalInSec_ + 0.5); + tmpHs->setAxisTimeDisplay(1); + tmpHs->setAxisTimeFormat("%H:%M:%S", 1); + tmpHs->getTH1()->GetXaxis()->SetTimeOffset(daTime); + } + histName += "_all"; + histTitle += " all"; + tmpHs = iBooker.book1D(histName, histTitle, 40, 0.5, 40.5); + hs.push_back(tmpHs); + tmpHs->getTH1()->SetCanExtend(TH1::kAllAxes); + tmpHs->setAxisTitle(xtitle, 1); + tmpHs->setAxisTitle(ytitle, 2); + tmpHs->getTH1()->SetOption("E1"); + if (histName.Contains("time")) { + //int nbins = (intervalInSec_/23 > 0 ? intervalInSec_/23 : 40); + tmpHs->getTH1()->SetBins(intervalInSec_, 0.5, intervalInSec_ + 0.5); + tmpHs->setAxisTimeDisplay(1); + tmpHs->setAxisTimeFormat("%H:%M:%S", 1); + tmpHs->getTH1()->GetXaxis()->SetTimeOffset(daTime); + } + } + } + } + assert(hs.size() == kNumHists); + assert(0 == strcmp(hs[k_sigmaY0_time]->getTH1()->GetName(), "sigmaY0_time")); + assert(0 == strcmp(hs[k_PVz_lumi_all]->getTH1()->GetName(), "PVz_lumi_all")); + + iBooker.setCurrentFolder(monitorName_ + "Fit"); + + h_trk_z0 = iBooker.book1D("trk_z0", "z_{0} of selected tracks", dzBin_, dzMin_, dzMax_); + h_trk_z0->setAxisTitle("z_{0} of selected tracks (cm)", 1); + + h_vx_dz = iBooker.bookProfile( + "vx_dz", "v_{x} vs. dz of selected tracks", dzBin_, dzMin_, dzMax_, dxBin_, dxMin_, dxMax_, ""); + h_vx_dz->setAxisTitle("dz (cm)", 1); + h_vx_dz->setAxisTitle("x coordinate of input track at PCA (cm)", 2); + + h_vy_dz = iBooker.bookProfile( + "vy_dz", "v_{y} vs. dz of selected tracks", dzBin_, dzMin_, dzMax_, dxBin_, dxMin_, dxMax_, ""); + h_vy_dz->setAxisTitle("dz (cm)", 1); + h_vy_dz->setAxisTitle("y coordinate of input track at PCA (cm)", 2); + + h_x0 = iBooker.book1D("BeamMonitorFeedBack_x0", "x coordinate of beam spot (Fit)", 100, -0.01, 0.01); + h_x0->setAxisTitle("x_{0} (cm)", 1); + h_x0->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_y0 = iBooker.book1D("BeamMonitorFeedBack_y0", "y coordinate of beam spot (Fit)", 100, -0.01, 0.01); + h_y0->setAxisTitle("y_{0} (cm)", 1); + h_y0->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_z0 = iBooker.book1D("BeamMonitorFeedBack_z0", "z coordinate of beam spot (Fit)", dzBin_, dzMin_, dzMax_); + h_z0->setAxisTitle("z_{0} (cm)", 1); + h_z0->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_sigmaX0 = iBooker.book1D("BeamMonitorFeedBack_sigmaX0", "sigma x0 of beam spot (Fit)", 100, 0, 0.05); + h_sigmaX0->setAxisTitle("#sigma_{X_{0}} (cm)", 1); + h_sigmaX0->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_sigmaY0 = iBooker.book1D("BeamMonitorFeedBack_sigmaY0", "sigma y0 of beam spot (Fit)", 100, 0, 0.05); + h_sigmaY0->setAxisTitle("#sigma_{Y_{0}} (cm)", 1); + h_sigmaY0->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_sigmaZ0 = iBooker.book1D("BeamMonitorFeedBack_sigmaZ0", "sigma z0 of beam spot (Fit)", 100, 0, 10); + h_sigmaZ0->setAxisTitle("#sigma_{Z_{0}} (cm)", 1); + h_sigmaZ0->getTH1()->SetCanExtend(TH1::kAllAxes); + + // Histograms of all reco tracks (without cuts): + h_trkPt = iBooker.book1D("trkPt", "p_{T} of all reco'd tracks (no selection)", 200, 0., 50.); + h_trkPt->setAxisTitle("p_{T} (GeV/c)", 1); + + h_trkVz = iBooker.book1D("trkVz", "Z coordinate of PCA of all reco'd tracks (no selection)", dzBin_, dzMin_, dzMax_); + h_trkVz->setAxisTitle("V_{Z} (cm)", 1); + + cutFlowTable = iBooker.book1D("cutFlowTable", "Cut flow table of track selection", 9, 0, 9); + + // Results of previous good fit: + fitResults = iBooker.book2D("fitResults", "Results of previous good beam fit", 2, 0, 2, 8, 0, 8); + fitResults->setAxisTitle("Fitted Beam Spot (cm)", 1); + fitResults->setBinLabel(8, "x_{0}", 2); + fitResults->setBinLabel(7, "y_{0}", 2); + fitResults->setBinLabel(6, "z_{0}", 2); + fitResults->setBinLabel(5, "#sigma_{Z}", 2); + fitResults->setBinLabel(4, "#frac{dx}{dz} (rad)", 2); + fitResults->setBinLabel(3, "#frac{dy}{dz} (rad)", 2); + fitResults->setBinLabel(2, "#sigma_{X}", 2); + fitResults->setBinLabel(1, "#sigma_{Y}", 2); + fitResults->setBinLabel(1, "Mean", 1); + fitResults->setBinLabel(2, "Stat. Error", 1); + fitResults->getTH1()->SetOption("text"); + + // Histos of PrimaryVertices: + iBooker.setCurrentFolder(monitorName_ + "PrimaryVertex"); + + h_nVtx = iBooker.book1D("vtxNbr", "Reconstructed Vertices(non-fake) in all Event", 60, -0.5, 59.5); + h_nVtx->setAxisTitle("Num. of reco. vertices", 1); + + //For one Trigger only + h_nVtx_st = iBooker.book1D("vtxNbr_SelectedTriggers", "Reconstructed Vertices(non-fake) in Events", 60, -0.5, 59.5); + //h_nVtx_st->setAxisTitle("Num. of reco. vertices for Un-Prescaled Jet Trigger",1); + + // Monitor only the PV with highest sum pt of assoc. trks: + h_PVx[0] = iBooker.book1D("PVX", "x coordinate of Primary Vtx", 50, -0.01, 0.01); + h_PVx[0]->setAxisTitle("PVx (cm)", 1); + h_PVx[0]->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_PVy[0] = iBooker.book1D("PVY", "y coordinate of Primary Vtx", 50, -0.01, 0.01); + h_PVy[0]->setAxisTitle("PVy (cm)", 1); + h_PVy[0]->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_PVz[0] = iBooker.book1D("PVZ", "z coordinate of Primary Vtx", dzBin_, dzMin_, dzMax_); + h_PVz[0]->setAxisTitle("PVz (cm)", 1); + + h_PVx[1] = iBooker.book1D("PVXFit", "x coordinate of Primary Vtx (Last Fit)", 50, -0.01, 0.01); + h_PVx[1]->setAxisTitle("PVx (cm)", 1); + h_PVx[1]->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_PVy[1] = iBooker.book1D("PVYFit", "y coordinate of Primary Vtx (Last Fit)", 50, -0.01, 0.01); + h_PVy[1]->setAxisTitle("PVy (cm)", 1); + h_PVy[1]->getTH1()->SetCanExtend(TH1::kAllAxes); + + h_PVz[1] = iBooker.book1D("PVZFit", "z coordinate of Primary Vtx (Last Fit)", dzBin_, dzMin_, dzMax_); + h_PVz[1]->setAxisTitle("PVz (cm)", 1); + + h_PVxz = iBooker.bookProfile("PVxz", "PVx vs. PVz", dzBin_ / 2, dzMin_, dzMax_, dxBin_ / 2, dxMin_, dxMax_, ""); + h_PVxz->setAxisTitle("PVz (cm)", 1); + h_PVxz->setAxisTitle("PVx (cm)", 2); + + h_PVyz = iBooker.bookProfile("PVyz", "PVy vs. PVz", dzBin_ / 2, dzMin_, dzMax_, dxBin_ / 2, dxMin_, dxMax_, ""); + h_PVyz->setAxisTitle("PVz (cm)", 1); + h_PVyz->setAxisTitle("PVy (cm)", 2); + + // Results of previous good fit: + pvResults = iBooker.book2D("pvResults", "Results of fitting Primary Vertices", 2, 0, 2, 6, 0, 6); + pvResults->setAxisTitle("Fitted Primary Vertex (cm)", 1); + pvResults->setBinLabel(6, "PVx", 2); + pvResults->setBinLabel(5, "PVy", 2); + pvResults->setBinLabel(4, "PVz", 2); + pvResults->setBinLabel(3, "#sigma_{X}", 2); + pvResults->setBinLabel(2, "#sigma_{Y}", 2); + pvResults->setBinLabel(1, "#sigma_{Z}", 2); + pvResults->setBinLabel(1, "Mean", 1); + pvResults->setBinLabel(2, "Stat. Error", 1); + pvResults->getTH1()->SetOption("text"); + + // Summary plots: + iBooker.setCurrentFolder(monitorName_ + "EventInfo"); + + reportSummary = iBooker.bookFloat("reportSummary"); + if (reportSummary) + reportSummary->Fill(std::numeric_limits::quiet_NaN()); + + char histo[20]; + iBooker.setCurrentFolder(monitorName_ + "EventInfo/reportSummaryContents"); + for (int n = 0; n < nFitElements_; n++) { + switch (n) { + case 0: + sprintf(histo, "x0_status"); + break; + case 1: + sprintf(histo, "y0_status"); + break; + case 2: + sprintf(histo, "z0_status"); + break; + } + reportSummaryContents[n] = iBooker.bookFloat(histo); + } + + for (int i = 0; i < nFitElements_; i++) { + summaryContent_[i] = 0.; + reportSummaryContents[i]->Fill(std::numeric_limits::quiet_NaN()); + } + + iBooker.setCurrentFolder(monitorName_ + "EventInfo"); + + reportSummaryMap = iBooker.book2D("reportSummaryMap", "Beam Spot Summary Map", 1, 0, 1, 3, 0, 3); + reportSummaryMap->setAxisTitle("", 1); + reportSummaryMap->setAxisTitle("Fitted Beam Spot", 2); + reportSummaryMap->setBinLabel(1, " ", 1); + reportSummaryMap->setBinLabel(1, "x_{0}", 2); + reportSummaryMap->setBinLabel(2, "y_{0}", 2); + reportSummaryMap->setBinLabel(3, "z_{0}", 2); + for (int i = 0; i < nFitElements_; i++) { + reportSummaryMap->setBinContent(1, i + 1, -1.); + } +} + +//-------------------------------------------------------- +void FakeBeamMonitor::beginLuminosityBlock(const LuminosityBlock& lumiSeg, const EventSetup& context) { + // start DB logger + DBloggerReturn_ = 0; + if (onlineDbService_.isAvailable()) { + onlineDbService_->logger().start(); + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::beginLuminosityBlock"; + } + + int nthlumi = lumiSeg.luminosityBlock(); + const edm::TimeValue_t fbegintimestamp = lumiSeg.beginTime().value(); + const std::time_t ftmptime = fbegintimestamp >> 32; + + if (countLumi_ == 0 && (!processed_)) { + beginLumiOfBSFit_ = beginLumiOfPVFit_ = nthlumi; + refBStime[0] = refPVtime[0] = ftmptime; + mapBeginBSLS[countLumi_] = nthlumi; + mapBeginPVLS[countLumi_] = nthlumi; + mapBeginBSTime[countLumi_] = ftmptime; + mapBeginPVTime[countLumi_] = ftmptime; + } //for the first record + + if (nthlumi > nextlumi_) { + if (processed_) { + countLumi_++; + //store here them will need when we remove the first one of Last N LS + mapBeginBSLS[countLumi_] = nthlumi; + mapBeginPVLS[countLumi_] = nthlumi; + mapBeginBSTime[countLumi_] = ftmptime; + mapBeginPVTime[countLumi_] = ftmptime; + } //processed passed but not the first lumi + if ((!processed_) && countLumi_ != 0) { + mapBeginBSLS[countLumi_] = nthlumi; + mapBeginPVLS[countLumi_] = nthlumi; + mapBeginBSTime[countLumi_] = ftmptime; + mapBeginPVTime[countLumi_] = ftmptime; + } //processed fails for last lumi + } //nthLumi > nextlumi + + if (StartAverage_) { + //Just Make sure it get rest + refBStime[0] = 0; + refPVtime[0] = 0; + beginLumiOfPVFit_ = 0; + beginLumiOfBSFit_ = 0; + + if (debug_) + edm::LogInfo("FakeBeamMonitor") << " beginLuminosityBlock: Size of mapBeginBSLS before = " + << mapBeginBSLS.size() << endl; + if (nthlumi > + nextlumi_) { //this make sure that it does not take into account this lumi for fitting and only look forward for new lumi + //as countLumi also remains the same so map value get overwritten once return to normal running. + //even if few LS are misssing and DQM module do not sees them then it catchs up again + map::iterator itbs = mapBeginBSLS.begin(); + map::iterator itpv = mapBeginPVLS.begin(); + map::iterator itbstime = mapBeginBSTime.begin(); + map::iterator itpvtime = mapBeginPVTime.begin(); + + if (processed_) { // otherwise if false then LS range of fit get messed up because we don't remove trk/pvs but we remove LS begin value . This prevent it as it happened if LS is there but no event are processed for some reason + mapBeginBSLS.erase(itbs); + mapBeginPVLS.erase(itpv); + mapBeginBSTime.erase(itbstime); + mapBeginPVTime.erase(itpvtime); + } + /*//not sure if want this or not ?? + map::iterator itgapb=mapBeginBSLS.begin(); + map::iterator itgape=mapBeginBSLS.end(); itgape--; + countGapLumi_ = ( (itgape->second) - (itgapb->second) ); + //if we see Gap more than then 2*resetNFitLumi !!!!!!! + //for example if 10-15 is fitted and if 16-25 are missing then we next fit will be for range 11-26 but BS can change in between + // so better start as fresh and reset everything like starting in the begining! + if(countGapLumi_ >= 2*resetFitNLumi_){RestartFitting(); mapBeginBSLS[countLumi_] = nthlumi;} + */ + } + + if (debug_) + edm::LogInfo("FakeBeamMonitor") << " beginLuminosityBlock:: Size of mapBeginBSLS After = " << mapBeginBSLS.size() + << endl; + + map::iterator bbs = mapBeginBSLS.begin(); + map::iterator bpv = mapBeginPVLS.begin(); + map::iterator bbst = mapBeginBSTime.begin(); + map::iterator bpvt = mapBeginPVTime.begin(); + + if (beginLumiOfPVFit_ == 0) + beginLumiOfPVFit_ = bpv->second; //new begin time after removing the LS + if (beginLumiOfBSFit_ == 0) + beginLumiOfBSFit_ = bbs->second; + if (refBStime[0] == 0) + refBStime[0] = bbst->second; + if (refPVtime[0] == 0) + refPVtime[0] = bpvt->second; + + } //same logic for average fit as above commented line + + map::iterator nbbst = mapBeginBSTime.begin(); + map::iterator nbpvt = mapBeginPVTime.begin(); + + if (onlineMode_ && (nthlumi < nextlumi_)) + return; + + if (onlineMode_) { + if (nthlumi > nextlumi_) { + if (countLumi_ != 0 && processed_) + FitAndFill(lumiSeg, lastlumi_, nextlumi_, nthlumi); + nextlumi_ = nthlumi; + edm::LogInfo("FakeBeamMonitor") << "beginLuminosityBlock:: Next Lumi to Fit: " << nextlumi_ << endl; + if ((StartAverage_) && refBStime[0] == 0) + refBStime[0] = nbbst->second; + if ((StartAverage_) && refPVtime[0] == 0) + refPVtime[0] = nbpvt->second; + } + } else { + if (processed_) + FitAndFill(lumiSeg, lastlumi_, nextlumi_, nthlumi); + nextlumi_ = nthlumi; + edm::LogInfo("FakeBeamMonitor") << " beginLuminosityBlock:: Next Lumi to Fit: " << nextlumi_ << endl; + if ((StartAverage_) && refBStime[0] == 0) + refBStime[0] = nbbst->second; + if ((StartAverage_) && refPVtime[0] == 0) + refPVtime[0] = nbpvt->second; + } + + //countLumi_++; + if (processed_) + processed_ = false; + edm::LogInfo("FakeBeamMonitor") << " beginLuminosityBlock:: Begin of Lumi: " << nthlumi << endl; +} + +// ---------------------------------------------------------- +void FakeBeamMonitor::analyze(const Event& iEvent, const EventSetup& iSetup) { + const int nthlumi = iEvent.luminosityBlock(); + + if (onlineMode_ && (nthlumi < nextlumi_)) { + edm::LogInfo("FakeBeamMonitor") << "analyze:: Spilt event from previous lumi section!" << std::endl; + return; + } + if (onlineMode_ && (nthlumi > nextlumi_)) { + edm::LogInfo("FakeBeamMonitor") << "analyze:: Spilt event from next lumi section!!!" << std::endl; + return; + } + + countEvt_++; + // theBeamFitter->readEvent( + // iEvent); //Remember when track fitter read the event in the same place the PVFitter read the events !!!!!!!!! + + // Handle recoBeamSpotHandle; + // iEvent.getByToken(bsSrc_, recoBeamSpotHandle); + // refBS = *recoBeamSpotHandle; + + // //------Cut Flow Table filled every event!-------------------------------------- + // { + // // Make a copy of the cut flow table from the beam fitter. + // auto tmphisto = static_cast(theBeamFitter->getCutFlow()); + // cutFlowTable->getTH1()->SetBins( + // tmphisto->GetNbinsX(), tmphisto->GetXaxis()->GetXmin(), tmphisto->GetXaxis()->GetXmax()); + // // Update the bin labels + // if (countEvt_ == 1) // SetLabel just once + // for (int n = 0; n < tmphisto->GetNbinsX(); n++) + // cutFlowTable->setBinLabel(n + 1, tmphisto->GetXaxis()->GetBinLabel(n + 1), 1); + // cutFlowTable->Reset(); + // cutFlowTable->getTH1()->Add(tmphisto); + // } + + //----Reco tracks ------------------------------------- + // Handle TrackCollection; + // iEvent.getByToken(tracksLabel_, TrackCollection); + // const reco::TrackCollection* tracks = TrackCollection.product(); + // for (reco::TrackCollection::const_iterator track = tracks->begin(); track != tracks->end(); ++track) { + // h_trkPt->Fill(track->pt()); //no need to change here for average bs + // h_trkVz->Fill(track->vz()); + // } + + //-------HLT Trigger -------------------------------- + // edm::Handle triggerResults; + // bool JetTrigPass = false; + // if (iEvent.getByToken(hltSrc_, triggerResults)) { + // const edm::TriggerNames& trigNames = iEvent.triggerNames(*triggerResults); + // for (unsigned int i = 0; i < triggerResults->size(); i++) { + // const std::string& trigName = trigNames.triggerName(i); + // + // if (JetTrigPass) + // continue; + // + // for (size_t t = 0; t < jetTrigger_.size(); ++t) { + // if (JetTrigPass) + // continue; + // + // string string_search(jetTrigger_[t]); + // size_t found = trigName.find(string_search); + // + // if (found != string::npos) { + // int thisTrigger_ = trigNames.triggerIndex(trigName); + // if (triggerResults->accept(thisTrigger_)) + // JetTrigPass = true; + // } //if trigger found + // } //for(t=0;..) + // } //for(i=0; ..) + // } //if trigger colleciton exist) + + //------ Primary Vertices------- + // edm::Handle PVCollection; + + // if (iEvent.getByToken(pvSrc_, PVCollection)) { + int nPVcount = 0; + int nPVcount_ST = 0; //For Single Trigger(hence ST) + + // for (reco::VertexCollection::const_iterator pv = PVCollection->begin(); pv != PVCollection->end(); ++pv) { + for (int tmp_idx = 0; tmp_idx < 10; tmp_idx++) { + //--- vertex selection + // if (pv->isFake() || pv->tracksSize() == 0) + // continue; + nPVcount++; // count non fake pv: + + //if (JetTrigPass) + nPVcount_ST++; //non-fake pv with a specific trigger + + // if (pv->ndof() < minVtxNdf_ || (pv->ndof() + 3.) / pv->tracksSize() < 2 * minVtxWgt_) + // continue; + + //Fill this map to store xyx for pv so that later we can remove the first one for run aver + mapPVx[countLumi_].push_back(tmp_idx); + mapPVy[countLumi_].push_back(tmp_idx); + mapPVz[countLumi_].push_back(tmp_idx); + + // if (!StartAverage_) { //for first N LS + // h_PVx[0]->Fill(pv->x()); + // h_PVy[0]->Fill(pv->y()); + // h_PVz[0]->Fill(pv->z()); + // h_PVxz->Fill(pv->z(), pv->x()); + // h_PVyz->Fill(pv->z(), pv->y()); + // } //for first N LiS + // else { + // h_PVxz->Fill(pv->z(), pv->x()); + // h_PVyz->Fill(pv->z(), pv->y()); + // } + + } //loop over pvs + + // h_nVtx->Fill(nPVcount * 1.); //no need to change it for average BS + + mapNPV[countLumi_].push_back((nPVcount_ST)); + + // if (!StartAverage_) { + // h_nVtx_st->Fill(nPVcount_ST * 1.); + // } + + // } //if pv collection is availaable + + if (StartAverage_) { + map >::iterator itpvx = mapPVx.begin(); + map >::iterator itpvy = mapPVy.begin(); + map >::iterator itpvz = mapPVz.begin(); + + map >::iterator itbspvinfo = mapNPV.begin(); + + if ((int)mapPVx.size() > resetFitNLumi_) { //sometimes the events is not there but LS is there! + mapPVx.erase(itpvx); + mapPVy.erase(itpvy); + mapPVz.erase(itpvz); + mapNPV.erase(itbspvinfo); + } //loop over Last N lumi collected + + } //StartAverage==true + + processed_ = true; +} + +//-------------------------------------------------------- +void FakeBeamMonitor::endLuminosityBlock(const LuminosityBlock& lumiSeg, const EventSetup& iSetup) { + int nthlumi = lumiSeg.id().luminosityBlock(); + edm::LogInfo("FakeBeamMonitor") << "endLuminosityBlock:: Lumi of the last event before endLuminosityBlock: " + << nthlumi << endl; + + if (onlineMode_ && nthlumi < nextlumi_) + return; + const edm::TimeValue_t fendtimestamp = lumiSeg.endTime().value(); + const std::time_t fendtime = fendtimestamp >> 32; + tmpTime = refBStime[1] = refPVtime[1] = fendtime; + + // end DB logger + if (onlineDbService_.isAvailable()) { + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::endLuminosityBlock"; + onlineDbService_->logger().end(DBloggerReturn_); + } +} + +//-------------------------------------------------------- +void FakeBeamMonitor::FitAndFill(const LuminosityBlock& lumiSeg, int& lastlumi, int& nextlumi, int& nthlumi) { + if (onlineMode_ && (nthlumi <= nextlumi)) + return; + + //set the correct run number when no event in the LS for fake output + // if ((processed_) && theBeamFitter->getRunNumber() != frun) + // theBeamFitter->setRun(frun); + + int currentlumi = nextlumi; + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: Lumi of the current fit: " << currentlumi << endl; + lastlumi = currentlumi; + endLumiOfBSFit_ = currentlumi; + endLumiOfPVFit_ = currentlumi; + + //---------Fix for Runninv average------------- + mapLSPVStoreSize[countLumi_] = 10; //theBeamFitter->getPVvectorSize(); + + // if (StartAverage_) { + // std::map::iterator rmLSPVi = mapLSPVStoreSize.begin(); + // size_t SizeToRemovePV = rmLSPVi->second; + // for (std::map::iterator rmLSPVe = mapLSPVStoreSize.end(); ++rmLSPVi != rmLSPVe;) + // rmLSPVi->second -= SizeToRemovePV; + // + // theBeamFitter->resizePVvector(SizeToRemovePV); + // + // map::iterator tmpItpv = mapLSPVStoreSize.begin(); + // mapLSPVStoreSize.erase(tmpItpv); + // } + // if (debug_) + // edm::LogInfo("BeamMonitor") << "FitAndFill:: Size of thePVvector After removing the PVs = " + // << theBeamFitter->getPVvectorSize() << endl; + + //lets filt the PV for GUI here: It was in analyzer in preivous versiton but moved here due to absence of event in some lumis, works OK + bool resetHistoFlag_ = false; + if ((int)mapPVx.size() >= resetFitNLumi_ && (StartAverage_)) { + h_PVx[0]->Reset(); + h_PVy[0]->Reset(); + h_PVz[0]->Reset(); + h_nVtx_st->Reset(); + resetHistoFlag_ = true; + } + + int MaxPVs = 0; + int countEvtLastNLS_ = 0; + int countTotPV_ = 0; + + std::map >::iterator mnpv = mapNPV.begin(); + std::map >::iterator mpv2 = mapPVy.begin(); + std::map >::iterator mpv3 = mapPVz.begin(); + + for (std::map >::iterator mpv1 = mapPVx.begin(); mpv1 != mapPVx.end(); + ++mpv1, ++mpv2, ++mpv3, ++mnpv) { + std::vector::iterator mpvs2 = (mpv2->second).begin(); + std::vector::iterator mpvs3 = (mpv3->second).begin(); + for (std::vector::iterator mpvs1 = (mpv1->second).begin(); mpvs1 != (mpv1->second).end(); + ++mpvs1, ++mpvs2, ++mpvs3) { + if (resetHistoFlag_) { + h_PVx[0]->Fill(*mpvs1); //these histogram are reset after StartAverage_ flag is ON + h_PVy[0]->Fill(*mpvs2); + h_PVz[0]->Fill(*mpvs3); + } + } //loop over second + + //Do the same here for nPV distr. + for (std::vector::iterator mnpvs = (mnpv->second).begin(); mnpvs != (mnpv->second).end(); ++mnpvs) { + if ((*mnpvs > 0) && (resetHistoFlag_)) + h_nVtx_st->Fill((*mnpvs) * (1.0)); + countEvtLastNLS_++; + countTotPV_ += (*mnpvs); + if ((*mnpvs) > MaxPVs) + MaxPVs = (*mnpvs); + } //loop over second of mapNPV + + } //loop over last N lumis + + char tmpTitlePV[100]; + sprintf(tmpTitlePV, "%s %i %s %i", "Num. of reco. vertices for LS: ", beginLumiOfPVFit_, " to ", endLumiOfPVFit_); + h_nVtx_st->setAxisTitle(tmpTitlePV, 1); + + // std::vector DipPVInfo_; + // DipPVInfo_.clear(); + // + // if (countTotPV_ != 0) { + // DipPVInfo_.push_back((float)countEvtLastNLS_); + // DipPVInfo_.push_back(h_nVtx_st->getMean()); + // DipPVInfo_.push_back(h_nVtx_st->getMeanError()); + // DipPVInfo_.push_back(h_nVtx_st->getRMS()); + // DipPVInfo_.push_back(h_nVtx_st->getRMSError()); + // DipPVInfo_.push_back((float)MaxPVs); + // DipPVInfo_.push_back((float)countTotPV_); + // MaxPVs = 0; + // } else { + // for (size_t i = 0; i < 7; i++) { + // if (i > 0) { + // DipPVInfo_.push_back(0.); + // } else { + // DipPVInfo_.push_back((float)countEvtLastNLS_); + // } + // } + // } + // theBeamFitter->SetPVInfo(DipPVInfo_); + countEvtLastNLS_ = 0; + + if (onlineMode_) { // filling LS gap + // FIXME: need to add protection for the case if the gap is at the resetting LS! + const int countLS_bs = hs[k_x0_lumi]->getTH1()->GetEntries(); + const int countLS_pv = hs[k_PVx_lumi]->getTH1()->GetEntries(); + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: countLS_bs = " << countLS_bs << " ; countLS_pv = " << countLS_pv + << std::endl; + int LSgap_bs = currentlumi / fitNLumi_ - countLS_bs; + int LSgap_pv = currentlumi / fitPVNLumi_ - countLS_pv; + if (currentlumi % fitNLumi_ == 0) + LSgap_bs--; + if (currentlumi % fitPVNLumi_ == 0) + LSgap_pv--; + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: LSgap_bs = " << LSgap_bs << " ; LSgap_pv = " << LSgap_pv + << std::endl; + // filling previous fits if LS gap ever exists + for (int ig = 0; ig < LSgap_bs; ig++) { + hs[k_x0_lumi]->ShiftFillLast(0., 0., fitNLumi_); //x0 , x0err, fitNLumi_; see DQMCore.... + hs[k_y0_lumi]->ShiftFillLast(0., 0., fitNLumi_); + hs[k_z0_lumi]->ShiftFillLast(0., 0., fitNLumi_); + hs[k_sigmaX0_lumi]->ShiftFillLast(0., 0., fitNLumi_); + hs[k_sigmaY0_lumi]->ShiftFillLast(0., 0., fitNLumi_); + hs[k_sigmaZ0_lumi]->ShiftFillLast(0., 0., fitNLumi_); + h_nVtx_lumi->ShiftFillLast(0., 0., fitNLumi_); + } + for (int ig = 0; ig < LSgap_pv; ig++) { + hs[k_PVx_lumi]->ShiftFillLast(0., 0., fitPVNLumi_); + hs[k_PVy_lumi]->ShiftFillLast(0., 0., fitPVNLumi_); + hs[k_PVz_lumi]->ShiftFillLast(0., 0., fitPVNLumi_); + } + const int previousLS = h_nTrk_lumi->getTH1()->GetEntries(); + for (int i = 1; i < (currentlumi - previousLS); + i++) //if (current-previoius)= 1 then never go inside the for loop!!!!!!!!!!! + h_nTrk_lumi->ShiftFillLast(nthBSTrk_); + } + + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: Time lapsed since last scroll = " << tmpTime - refTime << std::endl; + + if (testScroll(tmpTime, refTime)) { + scrollTH1(hs[k_x0_time]->getTH1(), refTime); + scrollTH1(hs[k_y0_time]->getTH1(), refTime); + scrollTH1(hs[k_z0_time]->getTH1(), refTime); + scrollTH1(hs[k_sigmaX0_time]->getTH1(), refTime); + scrollTH1(hs[k_sigmaY0_time]->getTH1(), refTime); + scrollTH1(hs[k_sigmaZ0_time]->getTH1(), refTime); + scrollTH1(hs[k_PVx_time]->getTH1(), refTime); + scrollTH1(hs[k_PVy_time]->getTH1(), refTime); + scrollTH1(hs[k_PVz_time]->getTH1(), refTime); + } + + // bool doPVFit = false; + // + // if (fitPVNLumi_ > 0) { + // if (onlineMode_) { + // if (currentlumi % fitPVNLumi_ == 0) + // doPVFit = true; + // } else if (countLumi_ % fitPVNLumi_ == 0) + // doPVFit = true; + // } else + // doPVFit = true; + // + // if (doPVFit) { + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: Do PV Fitting for LS = " << beginLumiOfPVFit_ << " to " + << endLumiOfPVFit_ << std::endl; + // Primary Vertex Fit: + if (h_PVx[0]->getTH1()->GetEntries() > minNrVertices_) { + pvResults->Reset(); + char tmpTitle[50]; + sprintf(tmpTitle, "%s %i %s %i", "Fitted Primary Vertex (cm) of LS: ", beginLumiOfPVFit_, " to ", endLumiOfPVFit_); + pvResults->setAxisTitle(tmpTitle, 1); + + std::unique_ptr fgaus{new TF1("fgaus", "gaus")}; + double mean, width, meanErr, widthErr; + fgaus->SetLineColor(4); + h_PVx[0]->getTH1()->Fit(fgaus.get(), "QLM0"); + mean = fgaus->GetParameter(1); + width = fgaus->GetParameter(2); + meanErr = fgaus->GetParError(1); + widthErr = fgaus->GetParError(2); + + hs[k_PVx_lumi]->ShiftFillLast(mean, width, fitPVNLumi_); + hs[k_PVx_lumi_all]->setBinContent(currentlumi, mean); + hs[k_PVx_lumi_all]->setBinError(currentlumi, width); + int nthBin = tmpTime - refTime; + if (nthBin < 0) + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: Event time outside current range of time histograms!" + << std::endl; + if (nthBin > 0) { + hs[k_PVx_time]->setBinContent(nthBin, mean); + hs[k_PVx_time]->setBinError(nthBin, width); + } + int jthBin = tmpTime - startTime; + if (jthBin > 0) { + hs[k_PVx_time_all]->setBinContent(jthBin, mean); + hs[k_PVx_time_all]->setBinError(jthBin, width); + } + pvResults->setBinContent(1, 6, mean); + pvResults->setBinContent(1, 3, width); + pvResults->setBinContent(2, 6, meanErr); + pvResults->setBinContent(2, 3, widthErr); + + { + // snap shot of the fit + auto tmphisto = h_PVx[0]->getTH1F(); + h_PVx[1]->getTH1()->SetBins( + tmphisto->GetNbinsX(), tmphisto->GetXaxis()->GetXmin(), tmphisto->GetXaxis()->GetXmax()); + h_PVx[1]->Reset(); + h_PVx[1]->getTH1()->Add(tmphisto); + h_PVx[1]->getTH1()->Fit(fgaus.get(), "QLM"); + } + + h_PVy[0]->getTH1()->Fit(fgaus.get(), "QLM0"); + mean = fgaus->GetParameter(1); + width = fgaus->GetParameter(2); + meanErr = fgaus->GetParError(1); + widthErr = fgaus->GetParError(2); + hs[k_PVy_lumi]->ShiftFillLast(mean, width, fitPVNLumi_); + hs[k_PVy_lumi_all]->setBinContent(currentlumi, mean); + hs[k_PVy_lumi_all]->setBinError(currentlumi, width); + if (nthBin > 0) { + hs[k_PVy_time]->setBinContent(nthBin, mean); + hs[k_PVy_time]->setBinError(nthBin, width); + } + if (jthBin > 0) { + hs[k_PVy_time_all]->setBinContent(jthBin, mean); + hs[k_PVy_time_all]->setBinError(jthBin, width); + } + pvResults->setBinContent(1, 5, mean); + pvResults->setBinContent(1, 2, width); + pvResults->setBinContent(2, 5, meanErr); + pvResults->setBinContent(2, 2, widthErr); + // snap shot of the fit + { + auto tmphisto = h_PVy[0]->getTH1F(); + h_PVy[1]->getTH1()->SetBins( + tmphisto->GetNbinsX(), tmphisto->GetXaxis()->GetXmin(), tmphisto->GetXaxis()->GetXmax()); + h_PVy[1]->Reset(); + h_PVy[1]->getTH1()->Add(tmphisto); + h_PVy[1]->getTH1()->Fit(fgaus.get(), "QLM"); + } + + h_PVz[0]->getTH1()->Fit(fgaus.get(), "QLM0"); + mean = fgaus->GetParameter(1); + width = fgaus->GetParameter(2); + meanErr = fgaus->GetParError(1); + widthErr = fgaus->GetParError(2); + hs[k_PVz_lumi]->ShiftFillLast(mean, width, fitPVNLumi_); + hs[k_PVz_lumi_all]->setBinContent(currentlumi, mean); + hs[k_PVz_lumi_all]->setBinError(currentlumi, width); + if (nthBin > 0) { + hs[k_PVz_time]->setBinContent(nthBin, mean); + hs[k_PVz_time]->setBinError(nthBin, width); + } + if (jthBin > 0) { + hs[k_PVz_time_all]->setBinContent(jthBin, mean); + hs[k_PVz_time_all]->setBinError(jthBin, width); + } + pvResults->setBinContent(1, 4, mean); + pvResults->setBinContent(1, 1, width); + pvResults->setBinContent(2, 4, meanErr); + pvResults->setBinContent(2, 1, widthErr); + { + // snap shot of the fit + auto tmphisto = h_PVz[0]->getTH1F(); + h_PVz[1]->getTH1()->SetBins( + tmphisto->GetNbinsX(), tmphisto->GetXaxis()->GetXmin(), tmphisto->GetXaxis()->GetXmax()); + h_PVz[1]->Reset(); + h_PVz[1]->getTH1()->Add(tmphisto); + h_PVz[1]->getTH1()->Fit(fgaus.get(), "QLM"); + } + } //check if found min Vertices + // } //do PVfit + + if ((resetPVNLumi_ > 0 && countLumi_ == resetPVNLumi_) || StartAverage_) { + beginLumiOfPVFit_ = 0; + refPVtime[0] = 0; + } + + //---------Readjustment of theBSvector, RefTime, beginLSofFit--------- + // vector theBSvector1 = theBeamFitter->getBSvector(); + // mapLSBSTrkSize[countLumi_] = (theBSvector1.size()); + size_t PreviousRecords = 0; //needed to fill nth record of tracks in GUI + + // if (StartAverage_) { + // size_t SizeToRemove = 0; + // std::map::iterator rmls = mapLSBSTrkSize.begin(); + // SizeToRemove = rmls->second; + // if (debug_) + // edm::LogInfo("BeamMonitor") << " The size to remove is = " << SizeToRemove << endl; + // int changedAfterThis = 0; + // for (std::map::iterator rmLS = mapLSBSTrkSize.begin(); rmLS != mapLSBSTrkSize.end(); + // ++rmLS, ++changedAfterThis) { + // if (changedAfterThis > 0) { + // (rmLS->second) = (rmLS->second) - SizeToRemove; + // if ((mapLSBSTrkSize.size() - (size_t)changedAfterThis) == 2) + // PreviousRecords = (rmLS->second); + // } + // } + // + // theBeamFitter->resizeBSvector(SizeToRemove); + // + // map::iterator tmpIt = mapLSBSTrkSize.begin(); + // mapLSBSTrkSize.erase(tmpIt); + // + // std::pair checkfitLS = theBeamFitter->getFitLSRange(); + // std::pair checkfitTime = theBeamFitter->getRefTime(); + // theBeamFitter->setFitLSRange(beginLumiOfBSFit_, checkfitLS.second); + // theBeamFitter->setRefTime(refBStime[0], checkfitTime.second); + // } + + //Fill the track for this fit + // vector theBSvector = theBeamFitter->getBSvector(); + // h_nTrk_lumi->ShiftFillLast(theBSvector.size()); + // + // if (debug_) + // edm::LogInfo("BeamMonitor") << "FitAndFill:: Size of theBSViector.size() After =" << theBSvector.size() << endl; + + // bool countFitting = false; + // if (theBSvector.size() >= PreviousRecords && theBSvector.size() >= min_Ntrks_) { + // countFitting = true; + // } + + //---Fix for Cut Flow Table for Running average in a same way//the previous code has problem for resetting!!! + // mapLSCF[countLumi_] = *theBeamFitter->getCutFlow(); + // if (StartAverage_ && !mapLSCF.empty()) { + // const TH1F& cutFlowToSubtract = mapLSCF.begin()->second; + // // Subtract the last cut flow from all of the others. + // std::map::iterator cf = mapLSCF.begin(); + // // Start on second entry + // for (; cf != mapLSCF.end(); ++cf) { + // cf->second.Add(&cutFlowToSubtract, -1); + // } + // theBeamFitter->subtractFromCutFlow(&cutFlowToSubtract); + // // Remove the obsolete lumi section + // mapLSCF.erase(mapLSCF.begin()); + // } + + if (resetHistos_) { + h_d0_phi0->Reset(); + h_vx_vy->Reset(); + h_vx_dz->Reset(); + h_vy_dz->Reset(); + h_trk_z0->Reset(); + resetHistos_ = false; + } + + if (StartAverage_) + nthBSTrk_ = PreviousRecords; //after average proccess is ON//for 2-6 LS fit PreviousRecords is size from 2-5 LS + + edm::LogInfo("FakeBeamMonitor") << " The Previous Recored for this fit is =" << nthBSTrk_ << endl; + + // unsigned int itrk = 0; + // for (vector::const_iterator BSTrk = theBSvector.begin(); BSTrk != theBSvector.end(); + // ++BSTrk, ++itrk) { + // if (itrk >= nthBSTrk_) { //fill for this record only !! + // h_d0_phi0->Fill(BSTrk->phi0(), BSTrk->d0()); + // double vx = BSTrk->vx(); + // double vy = BSTrk->vy(); + // double z0 = BSTrk->z0(); + // h_vx_vy->Fill(vx, vy); + // h_vx_dz->Fill(z0, vx); + // h_vy_dz->Fill(z0, vy); + // h_trk_z0->Fill(z0); + // } + // } + + // nthBSTrk_ = theBSvector.size(); // keep track of num of tracks filled so far + + edm::LogInfo("FakeBeamMonitor") << " The Current Recored for this fit is =" << nthBSTrk_ << endl; + + // if (countFitting) + // edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: Num of tracks collected = " << nthBSTrk_ << endl; + + if (fitNLumi_ > 0) { + if (onlineMode_) { + if (currentlumi % fitNLumi_ != 0) { + // for (std::map::iterator itAll = hs.begin(); + // itAll != hs.end(); ++itAll) { + // if ((*itAll).first.Contains("all")) { + // (*itAll).second->setBinContent(currentlumi,0.); + // (*itAll).second->setBinError(currentlumi,0.); + // } + // } + return; + } + } else if (countLumi_ % fitNLumi_ != 0) + return; + } + + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: [DebugTime] refBStime[0] = " << refBStime[0] + << "; address = " << &refBStime[0] << std::endl; + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: [DebugTime] refBStime[1] = " << refBStime[1] + << "; address = " << &refBStime[1] << std::endl; + + //Fill for all LS even if fit fails + // h_nVtx_lumi->ShiftFillLast((theBeamFitter->getPVvectorSize()), 0., fitNLumi_); + // h_nVtx_lumi_all->setBinContent(currentlumi, (theBeamFitter->getPVvectorSize())); + + // if (countFitting) { + nFits_++; + // std::pair fitLS = theBeamFitter->getFitLSRange(); + std::pair fitLS(beginLumiOfBSFit_, endLumiOfBSFit_); + // edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamFitter] Do BeamSpot Fit for LS = " << fitLS.first << " to " + // << fitLS.second << std::endl; + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: [FakeBeamMonitor] Do BeamSpot Fit for LS = " << beginLumiOfBSFit_ + << " to " << endLumiOfBSFit_ << std::endl; + + //Now Run the PV and Track Fitter over the collected tracks and pvs + // if (theBeamFitter->runPVandTrkFitter()) { + // reco::BeamSpot bs = theBeamFitter->getBeamSpot(); + + //Create fake BS here + reco::BeamSpot::CovarianceMatrix matrix; + for (int j = 0; j < 7; ++j) { + for (int k = j; k < 7; ++k) { + matrix(j, k) = 0; + } + } + + // random values for fake BeamSpot + float tmp_BSx = rndm_->Gaus(0.1, 0.1); // [cm] + float tmp_BSy = rndm_->Gaus(0.1, 0.1); // [cm] + float tmp_BSz = rndm_->Gaus(0.1, 0.1); // [cm] + float tmp_BSwidthX = rndm_->Gaus(0.001, 0.0005); // [cm] + float tmp_BSwidthY = rndm_->Gaus(0.001, 0.0005); // [cm] + float tmp_BSwidthZ = rndm_->Gaus(3.5, 0.5); // [cm] + + reco::BeamSpot bs(reco::BeamSpot::Point(tmp_BSx, tmp_BSy, tmp_BSz), + tmp_BSwidthZ, + 0, + 0, + tmp_BSwidthX, + matrix, + reco::BeamSpot::Tracker); + bs.setBeamWidthY(tmp_BSwidthY); + + if (bs.type() > 0) // with good beamwidth fit + preBS = bs; // cache good fit results + + edm::LogInfo("FakeBeamMonitor") << "\n RESULTS OF DEFAULT FIT:" << endl; + edm::LogInfo("FakeBeamMonitor") << bs << endl; + edm::LogInfo("FakeBeamMonitor") << "[BeamFitter] fitting done \n" << endl; + + hs[k_x0_lumi]->ShiftFillLast(bs.x0(), bs.x0Error(), fitNLumi_); + hs[k_y0_lumi]->ShiftFillLast(bs.y0(), bs.y0Error(), fitNLumi_); + hs[k_z0_lumi]->ShiftFillLast(bs.z0(), bs.z0Error(), fitNLumi_); + hs[k_sigmaX0_lumi]->ShiftFillLast(bs.BeamWidthX(), bs.BeamWidthXError(), fitNLumi_); + hs[k_sigmaY0_lumi]->ShiftFillLast(bs.BeamWidthY(), bs.BeamWidthYError(), fitNLumi_); + hs[k_sigmaZ0_lumi]->ShiftFillLast(bs.sigmaZ(), bs.sigmaZ0Error(), fitNLumi_); + hs[k_x0_lumi_all]->setBinContent(currentlumi, bs.x0()); + hs[k_x0_lumi_all]->setBinError(currentlumi, bs.x0Error()); + hs[k_y0_lumi_all]->setBinContent(currentlumi, bs.y0()); + hs[k_y0_lumi_all]->setBinError(currentlumi, bs.y0Error()); + hs[k_z0_lumi_all]->setBinContent(currentlumi, bs.z0()); + hs[k_z0_lumi_all]->setBinError(currentlumi, bs.z0Error()); + hs[k_sigmaX0_lumi_all]->setBinContent(currentlumi, bs.BeamWidthX()); + hs[k_sigmaX0_lumi_all]->setBinError(currentlumi, bs.BeamWidthXError()); + hs[k_sigmaY0_lumi_all]->setBinContent(currentlumi, bs.BeamWidthY()); + hs[k_sigmaY0_lumi_all]->setBinError(currentlumi, bs.BeamWidthYError()); + hs[k_sigmaZ0_lumi_all]->setBinContent(currentlumi, bs.sigmaZ()); + hs[k_sigmaZ0_lumi_all]->setBinError(currentlumi, bs.sigmaZ0Error()); + + int nthBin = tmpTime - refTime; + if (nthBin > 0) { + hs[k_x0_time]->setBinContent(nthBin, bs.x0()); + hs[k_y0_time]->setBinContent(nthBin, bs.y0()); + hs[k_z0_time]->setBinContent(nthBin, bs.z0()); + hs[k_sigmaX0_time]->setBinContent(nthBin, bs.BeamWidthX()); + hs[k_sigmaY0_time]->setBinContent(nthBin, bs.BeamWidthY()); + hs[k_sigmaZ0_time]->setBinContent(nthBin, bs.sigmaZ()); + hs[k_x0_time]->setBinError(nthBin, bs.x0Error()); + hs[k_y0_time]->setBinError(nthBin, bs.y0Error()); + hs[k_z0_time]->setBinError(nthBin, bs.z0Error()); + hs[k_sigmaX0_time]->setBinError(nthBin, bs.BeamWidthXError()); + hs[k_sigmaY0_time]->setBinError(nthBin, bs.BeamWidthYError()); + hs[k_sigmaZ0_time]->setBinError(nthBin, bs.sigmaZ0Error()); + } + + int jthBin = tmpTime - startTime; + if (jthBin > 0) { + hs[k_x0_time_all]->setBinContent(jthBin, bs.x0()); + hs[k_y0_time_all]->setBinContent(jthBin, bs.y0()); + hs[k_z0_time_all]->setBinContent(jthBin, bs.z0()); + hs[k_sigmaX0_time_all]->setBinContent(jthBin, bs.BeamWidthX()); + hs[k_sigmaY0_time_all]->setBinContent(jthBin, bs.BeamWidthY()); + hs[k_sigmaZ0_time_all]->setBinContent(jthBin, bs.sigmaZ()); + hs[k_x0_time_all]->setBinError(jthBin, bs.x0Error()); + hs[k_y0_time_all]->setBinError(jthBin, bs.y0Error()); + hs[k_z0_time_all]->setBinError(jthBin, bs.z0Error()); + hs[k_sigmaX0_time_all]->setBinError(jthBin, bs.BeamWidthXError()); + hs[k_sigmaY0_time_all]->setBinError(jthBin, bs.BeamWidthYError()); + hs[k_sigmaZ0_time_all]->setBinError(jthBin, bs.sigmaZ0Error()); + } + + h_x0->Fill(bs.x0()); + h_y0->Fill(bs.y0()); + h_z0->Fill(bs.z0()); + if (bs.type() > 0) { // with good beamwidth fit + h_sigmaX0->Fill(bs.BeamWidthX()); + h_sigmaY0->Fill(bs.BeamWidthY()); + } + h_sigmaZ0->Fill(bs.sigmaZ()); + + if (nthBSTrk_ >= 2 * min_Ntrks_) { + double amp = std::sqrt(bs.x0() * bs.x0() + bs.y0() * bs.y0()); + double alpha = std::atan2(bs.y0(), bs.x0()); + std::unique_ptr f1{new TF1("f1", "[0]*sin(x-[1])", -3.14, 3.14)}; + f1->SetParameters(amp, alpha); + f1->SetParLimits(0, amp - 0.1, amp + 0.1); + f1->SetParLimits(1, alpha - 0.577, alpha + 0.577); + f1->SetLineColor(4); + h_d0_phi0->getTProfile()->Fit(f1.get(), "QR"); + + double mean = bs.z0(); + double width = bs.sigmaZ(); + std::unique_ptr fgaus{new TF1("fgaus", "gaus")}; + fgaus->SetParameters(mean, width); + fgaus->SetLineColor(4); + h_trk_z0->getTH1()->Fit(fgaus.get(), "QLRM", "", mean - 3 * width, mean + 3 * width); + } + + fitResults->Reset(); + std::pair LSRange(beginLumiOfBSFit_, endLumiOfBSFit_); //= theBeamFitter->getFitLSRange(); + char tmpTitle[50]; + sprintf(tmpTitle, "%s %i %s %i", "Fitted Beam Spot (cm) of LS: ", LSRange.first, " to ", LSRange.second); + fitResults->setAxisTitle(tmpTitle, 1); + fitResults->setBinContent(1, 8, bs.x0()); + fitResults->setBinContent(1, 7, bs.y0()); + fitResults->setBinContent(1, 6, bs.z0()); + fitResults->setBinContent(1, 5, bs.sigmaZ()); + fitResults->setBinContent(1, 4, bs.dxdz()); + fitResults->setBinContent(1, 3, bs.dydz()); + if (bs.type() > 0) { // with good beamwidth fit + fitResults->setBinContent(1, 2, bs.BeamWidthX()); + fitResults->setBinContent(1, 1, bs.BeamWidthY()); + } else { // fill cached widths + fitResults->setBinContent(1, 2, preBS.BeamWidthX()); + fitResults->setBinContent(1, 1, preBS.BeamWidthY()); + } + + fitResults->setBinContent(2, 8, bs.x0Error()); + fitResults->setBinContent(2, 7, bs.y0Error()); + fitResults->setBinContent(2, 6, bs.z0Error()); + fitResults->setBinContent(2, 5, bs.sigmaZ0Error()); + fitResults->setBinContent(2, 4, bs.dxdzError()); + fitResults->setBinContent(2, 3, bs.dydzError()); + if (bs.type() > 0) { // with good beamwidth fit + fitResults->setBinContent(2, 2, bs.BeamWidthXError()); + fitResults->setBinContent(2, 1, bs.BeamWidthYError()); + } else { // fill cached width errors + fitResults->setBinContent(2, 2, preBS.BeamWidthXError()); + fitResults->setBinContent(2, 1, preBS.BeamWidthYError()); + } + + // count good fit + // if (std::fabs(refBS.x0()-bs.x0())/bs.x0Error() < deltaSigCut_) { // disabled temporarily + summaryContent_[0] += 1.; + // } + // if (std::fabs(refBS.y0()-bs.y0())/bs.y0Error() < deltaSigCut_) { // disabled temporarily + summaryContent_[1] += 1.; + // } + // if (std::fabs(refBS.z0()-bs.z0())/bs.z0Error() < deltaSigCut_) { // disabled temporarily + summaryContent_[2] += 1.; + // } + + // Create the BeamSpotOnlineObjects object + BeamSpotOnlineObjects* BSOnline = new BeamSpotOnlineObjects(); + BSOnline->SetLastAnalyzedLumi(fitLS.second); + BSOnline->SetLastAnalyzedRun(frun); + BSOnline->SetLastAnalyzedFill(0); // To be updated with correct LHC Fill number + BSOnline->SetPosition(bs.x0(), bs.y0(), bs.z0()); + BSOnline->SetSigmaZ(bs.sigmaZ()); + BSOnline->SetBeamWidthX(bs.BeamWidthX()); + BSOnline->SetBeamWidthY(bs.BeamWidthY()); + BSOnline->SetBeamWidthXError(bs.BeamWidthXError()); + BSOnline->SetBeamWidthYError(bs.BeamWidthYError()); + BSOnline->Setdxdz(bs.dxdz()); + BSOnline->Setdydz(bs.dydz()); + BSOnline->SetType(bs.type()); + BSOnline->SetEmittanceX(bs.emittanceX()); + BSOnline->SetEmittanceY(bs.emittanceY()); + BSOnline->SetBetaStar(bs.betaStar()); + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + BSOnline->SetCovariance(i, j, bs.covariance(i, j)); + } + } + // BSOnline->SetNumTracks(theBeamFitter->getNTracks()); + // BSOnline->SetNumPVs(theBeamFitter->getNPVs()); + BSOnline->SetNumTracks(50); + BSOnline->SetNumPVs(10); + auto creationTime = + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + BSOnline->SetCreationTime(creationTime); + + edm::LogInfo("FakeBeamMonitor") << "FitAndFill::[PayloadCreation] BeamSpotOnline object created: \n" << std::endl; + edm::LogInfo("FakeBeamMonitor") << *BSOnline << std::endl; + //std::cout << "------------------> fitted BS: " << *BSOnline << std::endl; + + // Create the payload for BeamSpotOnlineObjects object + if (onlineDbService_.isAvailable()) { + edm::LogInfo("FakeBeamMonitor") << "FitAndFill::[PayloadCreation] onlineDbService available \n" << std::endl; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::FitAndFill - Lumi of the current fit: " << currentlumi; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::FitAndFill - Do PV Fitting for LS = " << beginLumiOfPVFit_ + << " to " << endLumiOfPVFit_; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::FitAndFill - [BeamFitter] Do BeamSpot Fit for LS = " + << fitLS.first << " to " << fitLS.second; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::FitAndFill - [FakeBeamMonitor] Do BeamSpot Fit for LS = " + << beginLumiOfBSFit_ << " to " << endLumiOfBSFit_; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor - RESULTS OF DEFAULT FIT:"; + onlineDbService_->logger().logInfo() << "\n" << bs; + onlineDbService_->logger().logInfo() + << "FakeBeamMonitor::FitAndFill - [PayloadCreation] BeamSpotOnline object created:"; + onlineDbService_->logger().logInfo() << "\n" << *BSOnline; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::FitAndFill - [PayloadCreation] onlineDbService available"; + onlineDbService_->logger().logInfo() << "FakeBeamMonitor::FitAndFill - [PayloadCreation] SetCreationTime: " + << creationTime << " [epoch in microseconds]"; + try { + onlineDbService_->writeForNextLumisection(BSOnline, recordName_); + onlineDbService_->logger().logInfo() + << "FakeBeamMonitor::FitAndFill - [PayloadCreation] writeForNextLumisection executed correctly"; + DBloggerReturn_ = 2; + } catch (const std::exception& e) { + onlineDbService_->logger().logError() << "FakeBeamMonitor - Error writing record: " << recordName_ + << " for Run: " << frun << " - Lumi: " << fitLS.second; + onlineDbService_->logger().logError() << "Error is: " << e.what(); + onlineDbService_->logger().logError() << "RESULTS OF DEFAULT FIT WAS:"; + onlineDbService_->logger().logError() << "\n" << bs; + DBloggerReturn_ = -1; + } + } + edm::LogInfo("FakeBeamMonitor") << "FitAndFill::[PayloadCreation] BeamSpotOnline payload created \n" << std::endl; + + // } //if (theBeamFitter->runPVandTrkFitter()) + // else { // beam fit fails + // reco::BeamSpot bs = theBeamFitter->getBeamSpot(); + // edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamMonitor] Beam fit fails!!! \n" << endl; + // edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamMonitor] Output beam spot for DIP \n" << endl; + // edm::LogInfo("BeamMonitor") << bs << endl; + // + // hs[k_sigmaX0_lumi]->ShiftFillLast(bs.BeamWidthX(), bs.BeamWidthXError(), fitNLumi_); + // hs[k_sigmaY0_lumi]->ShiftFillLast(bs.BeamWidthY(), bs.BeamWidthYError(), fitNLumi_); + // hs[k_sigmaZ0_lumi]->ShiftFillLast(bs.sigmaZ(), bs.sigmaZ0Error(), fitNLumi_); + // hs[k_x0_lumi]->ShiftFillLast(bs.x0(), bs.x0Error(), fitNLumi_); + // hs[k_y0_lumi]->ShiftFillLast(bs.y0(), bs.y0Error(), fitNLumi_); + // hs[k_z0_lumi]->ShiftFillLast(bs.z0(), bs.z0Error(), fitNLumi_); + // } // end of beam fit fails + + // } //-------- end of countFitting------------------------------------------ + // else { // no fit + // // Overwrite Fit LS and fit time when no event processed or no track selected + // theBeamFitter->setFitLSRange(beginLumiOfBSFit_, endLumiOfBSFit_); + // theBeamFitter->setRefTime(refBStime[0], refBStime[1]); + // if (theBeamFitter->runPVandTrkFitter()) { + // } // Dump fake beam spot for DIP + // reco::BeamSpot bs = theBeamFitter->getBeamSpot(); + // edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamMonitor] No fitting \n" << endl; + // edm::LogInfo("BeamMonitor") << "FitAndFill:: [BeamMonitor] Output fake beam spot for DIP \n" << endl; + // edm::LogInfo("BeamMonitor") << bs << endl; + // + // hs[k_sigmaX0_lumi]->ShiftFillLast(bs.BeamWidthX(), bs.BeamWidthXError(), fitNLumi_); + // hs[k_sigmaY0_lumi]->ShiftFillLast(bs.BeamWidthY(), bs.BeamWidthYError(), fitNLumi_); + // hs[k_sigmaZ0_lumi]->ShiftFillLast(bs.sigmaZ(), bs.sigmaZ0Error(), fitNLumi_); + // hs[k_x0_lumi]->ShiftFillLast(bs.x0(), bs.x0Error(), fitNLumi_); + // hs[k_y0_lumi]->ShiftFillLast(bs.y0(), bs.y0Error(), fitNLumi_); + // hs[k_z0_lumi]->ShiftFillLast(bs.z0(), bs.z0Error(), fitNLumi_); + // } + + // Fill summary report + // if (countFitting) { + for (int n = 0; n < nFitElements_; n++) { + reportSummaryContents[n]->Fill(summaryContent_[n] / (float)nFits_); + } + + summarySum_ = 0; + for (int ii = 0; ii < nFitElements_; ii++) { + summarySum_ += summaryContent_[ii]; + } + reportSummary_ = summarySum_ / (nFitElements_ * nFits_); + if (reportSummary) + reportSummary->Fill(reportSummary_); + + for (int bi = 0; bi < nFitElements_; bi++) { + reportSummaryMap->setBinContent(1, bi + 1, summaryContent_[bi] / (float)nFits_); + } + // } + + if ((resetFitNLumi_ > 0 && + ((onlineMode_ && + countLumi_ == resetFitNLumi_) || //OR it should be currentLumi_ (if in sequence then does not mattar) + (!onlineMode_ && countLumi_ == resetFitNLumi_))) || + (StartAverage_)) { + edm::LogInfo("FakeBeamMonitor") << "FitAndFill:: The flag is ON for running average Beam Spot fit" << endl; + StartAverage_ = true; + firstAverageFit_++; + resetHistos_ = true; + nthBSTrk_ = 0; + beginLumiOfBSFit_ = 0; + refBStime[0] = 0; + } +} + +//-------------------------------------------------------- +void FakeBeamMonitor::RestartFitting() { + if (debug_) + edm::LogInfo("FakeBeamMonitor") + << " RestartingFitting:: Restart Beami everything to a fresh start !!! because Gap is > 10 LS" << endl; + //track based fit reset here + resetHistos_ = true; + nthBSTrk_ = 0; + // theBeamFitter->resetTrkVector(); + // theBeamFitter->resetLSRange(); + // theBeamFitter->resetRefTime(); + // theBeamFitter->resetPVFitter(); + // theBeamFitter->resetCutFlow(); + beginLumiOfBSFit_ = 0; + refBStime[0] = 0; + //pv based fit iis reset here + h_PVx[0]->Reset(); + h_PVy[0]->Reset(); + h_PVz[0]->Reset(); + beginLumiOfPVFit_ = 0; + refPVtime[0] = 0; + //Clear all the Maps here + mapPVx.clear(); + mapPVy.clear(); + mapPVz.clear(); + mapNPV.clear(); + mapBeginBSLS.clear(); + mapBeginPVLS.clear(); + mapBeginBSTime.clear(); + mapBeginPVTime.clear(); + mapLSBSTrkSize.clear(); + mapLSPVStoreSize.clear(); + mapLSCF.clear(); + countGapLumi_ = 0; + countLumi_ = 0; + StartAverage_ = false; +} + +//------------------------------------------------------- +void FakeBeamMonitor::dqmEndRun(const Run& r, const EventSetup& context) { + if (debug_) + edm::LogInfo("FakeBeamMonitor") << "dqmEndRun:: Clearing all the Maps " << endl; + //Clear all the Maps here + mapPVx.clear(); + mapPVy.clear(); + mapPVz.clear(); + mapNPV.clear(); + mapBeginBSLS.clear(); + mapBeginPVLS.clear(); + mapBeginBSTime.clear(); + mapBeginPVTime.clear(); + mapLSBSTrkSize.clear(); + mapLSPVStoreSize.clear(); + mapLSCF.clear(); +} + +//-------------------------------------------------------- +void FakeBeamMonitor::scrollTH1(TH1* h, time_t ref) { + char offsetTime[64]; + formatFitTime(offsetTime, ref); + TDatime da(offsetTime); + if (lastNZbin > 0) { + double val = h->GetBinContent(lastNZbin); + double valErr = h->GetBinError(lastNZbin); + h->Reset(); + h->GetXaxis()->SetTimeOffset(da.Convert(kTRUE)); + int bin = (lastNZbin > buffTime ? buffTime : 1); + h->SetBinContent(bin, val); + h->SetBinError(bin, valErr); + } else { + h->Reset(); + h->GetXaxis()->SetTimeOffset(da.Convert(kTRUE)); + } +} + +//-------------------------------------------------------- +// Method to check whether to chane histogram time offset (forward only) +bool FakeBeamMonitor::testScroll(time_t& tmpTime_, time_t& refTime_) { + bool scroll_ = false; + if (tmpTime_ - refTime_ >= intervalInSec_) { + scroll_ = true; + edm::LogInfo("FakeBeamMonitor") << "testScroll:: Reset Time Offset" << std::endl; + lastNZbin = intervalInSec_; + for (int bin = intervalInSec_; bin >= 1; bin--) { + if (hs[k_x0_time]->getBinContent(bin) > 0) { + lastNZbin = bin; + break; + } + } + edm::LogInfo("FakeBeamMonitor") << "testScroll:: Last non zero bin = " << lastNZbin << std::endl; + if (tmpTime_ - refTime_ >= intervalInSec_ + lastNZbin) { + edm::LogInfo("FakeBeamMonitor") << "testScroll:: Time difference too large since last readout" << std::endl; + lastNZbin = 0; + refTime_ = tmpTime_ - buffTime; + } else { + edm::LogInfo("FakeBeamMonitor") << "testScroll:: Offset to last record" << std::endl; + int offset = ((lastNZbin > buffTime) ? (lastNZbin - buffTime) : (lastNZbin - 1)); + refTime_ += offset; + } + } + return scroll_; +} + +DEFINE_FWK_MODULE(FakeBeamMonitor); + +// Local Variables: +// show-trailing-whitespace: t +// truncate-lines: t +// End: diff --git a/DQM/BeamMonitor/plugins/FakeBeamMonitor.h b/DQM/BeamMonitor/plugins/FakeBeamMonitor.h new file mode 100644 index 0000000000000..e14337dfbda45 --- /dev/null +++ b/DQM/BeamMonitor/plugins/FakeBeamMonitor.h @@ -0,0 +1,186 @@ +#ifndef FakeBeamMonitor_H +#define FakeBeamMonitor_H + +/** \class FakeBeamMonitor + * * + * \author Francesco Brivio - Milano-Bicocca + * \decription: Same behaviour of BeamMonitor except the + * beamspot is randomly generated and not fitted from tracks/PVs + * + */ +// C++ +#include +#include +// CMS +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/Common/interface/TriggerResults.h" +#include "DQMServices/Core/interface/DQMStore.h" +#include "DQMServices/Core/interface/DQMOneEDAnalyzer.h" +#include "CondCore/DBOutputService/interface/OnlineDBOutputService.h" +#include +#include "TRandom3.h" + +// +// class declaration +// + +class FakeBeamMonitor : public DQMOneEDAnalyzer { +public: + FakeBeamMonitor(const edm::ParameterSet&); + ~FakeBeamMonitor() override; + +protected: + // BeginRun + void bookHistograms(DQMStore::IBooker& i, const edm::Run& r, const edm::EventSetup& c) override; + + void analyze(const edm::Event& e, const edm::EventSetup& c) override; + + void beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& context) override; + + void endLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& c) override; + // EndRun + void dqmEndRun(const edm::Run& r, const edm::EventSetup& c) override; + +private: + void FitAndFill(const edm::LuminosityBlock& lumiSeg, int&, int&, int&); + void RestartFitting(); + void scrollTH1(TH1*, std::time_t); + bool testScroll(std::time_t&, std::time_t&); + void formatFitTime(char*, const std::time_t&); + + const int dxBin_; + const double dxMin_; + const double dxMax_; + + const int vxBin_; + const double vxMin_; + const double vxMax_; + + const int phiBin_; + const double phiMin_; + const double phiMax_; + + const int dzBin_; + const double dzMin_; + const double dzMax_; + std::string monitorName_; + std::string recordName_; // output BeamSpotOnline Record name + edm::Service onlineDbService_; // DB service + int DBloggerReturn_; // DB logger return value + + int fitNLumi_; + int fitPVNLumi_; + int resetFitNLumi_; + int resetPVNLumi_; + int intervalInSec_; + bool debug_; + bool onlineMode_; + + int countEvt_; //counter + int countLumi_; //counter + int beginLumiOfBSFit_; + int endLumiOfBSFit_; + int beginLumiOfPVFit_; + int endLumiOfPVFit_; + int lastlumi_; // previous LS processed + int nextlumi_; // next LS of Fit + std::time_t refBStime[2]; + std::time_t refPVtime[2]; + unsigned int nthBSTrk_; + int nFitElements_; + int nFits_; + double deltaSigCut_; + unsigned int min_Ntrks_; + double maxZ_; + unsigned int minNrVertices_; + double minVtxNdf_; + double minVtxWgt_; + + bool resetHistos_; + bool StartAverage_; + int firstAverageFit_; + int countGapLumi_; + + bool processed_; + + // ----------member data --------------------------- + + // std::vector fBSvector; + reco::BeamSpot refBS; + reco::BeamSpot preBS; + + // MonitorElements: + MonitorElement* h_nTrk_lumi; + MonitorElement* h_nVtx_lumi; + MonitorElement* h_nVtx_lumi_all; + MonitorElement* h_d0_phi0; + MonitorElement* h_trk_z0; + MonitorElement* h_vx_vy; + MonitorElement* h_vx_dz; + MonitorElement* h_vy_dz; + MonitorElement* h_trkPt; + MonitorElement* h_trkVz; + MonitorElement* fitResults; + MonitorElement* h_x0; + MonitorElement* h_y0; + MonitorElement* h_z0; + MonitorElement* h_sigmaX0; + MonitorElement* h_sigmaY0; + MonitorElement* h_sigmaZ0; + MonitorElement* h_nVtx; + MonitorElement* h_nVtx_st; + MonitorElement* h_PVx[2]; + MonitorElement* h_PVy[2]; + MonitorElement* h_PVz[2]; + MonitorElement* h_PVxz; + MonitorElement* h_PVyz; + MonitorElement* pvResults; + std::vector hs; + + // The histo of the primary vertex for DQM gui + std::map > mapPVx, mapPVy, mapPVz; + std::map > mapNPV; + //keep track of beginLuminosity block and time + std::map mapBeginBSLS, mapBeginPVLS; + std::map mapBeginBSTime, mapBeginPVTime; + //these maps are needed to keep track of size of theBSvector and pvStore + std::map mapLSBSTrkSize; + std::map mapLSPVStoreSize; + //to correct the cutFlot Table + std::map mapLSCF; + + // Summary: + Float_t reportSummary_; + Float_t summarySum_; + Float_t summaryContent_[3]; + MonitorElement* reportSummary; + MonitorElement* reportSummaryContents[3]; + MonitorElement* reportSummaryMap; + MonitorElement* cutFlowTable; + // variables for beam fit + + // + std::time_t tmpTime; + std::time_t startTime; + std::time_t refTime; + edm::TimeValue_t ftimestamp; + // Current run + int frun; + int lastNZbin; // last non zero bin of time histos + + TRandom3* rndm_; +}; + +#endif + +// Local Variables: +// show-trailing-whitespace: t +// truncate-lines: t +// End: diff --git a/DQM/BeamMonitor/plugins/OnlineBeamMonitor.cc b/DQM/BeamMonitor/plugins/OnlineBeamMonitor.cc new file mode 100644 index 0000000000000..ead917c43aa92 --- /dev/null +++ b/DQM/BeamMonitor/plugins/OnlineBeamMonitor.cc @@ -0,0 +1,368 @@ +/* + * \file OnlineBeamMonitor.cc + * \author Lorenzo Uplegger/FNAL + * modified by Simone Gennai INFN/Bicocca + */ + +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DQM/BeamMonitor/plugins/OnlineBeamMonitor.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/View.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/LuminosityBlock.h" +#include "FWCore/Framework/interface/Run.h" +#include "RecoVertex/BeamSpotProducer/interface/BeamFitter.h" +#include "RecoVertex/BeamSpotProducer/interface/PVFitter.h" +#include + +#include + +using namespace std; +using namespace edm; +using namespace reco; + +//---------------------------------------------------------------------------------------------------------------------- +OnlineBeamMonitor::OnlineBeamMonitor(const ParameterSet& ps) + : monitorName_(ps.getUntrackedParameter("MonitorName")), + bsTransientToken_( + esConsumes()), + bsHLTToken_( + esConsumes()), + bsLegacyToken_( + esConsumes()), + numberOfValuesToSave_(0) { + if (!monitorName_.empty()) + monitorName_ = monitorName_ + "/"; + + processedLumis_.clear(); + + varNamesV_.push_back("x"); + varNamesV_.push_back("y"); + varNamesV_.push_back("z"); + varNamesV_.push_back("sigmaX"); + varNamesV_.push_back("sigmaY"); + varNamesV_.push_back("sigmaZ"); + + //histoByCategoryNames_.insert(pair("run", "Coordinate")); + //histoByCategoryNames_.insert(pair("run", "PrimaryVertex fit-DataBase")); + //histoByCategoryNames_.insert(pair("run", "PrimaryVertex fit-BeamFit")); + //histoByCategoryNames_.insert(pair("run", "PrimaryVertex fit-Scalers")); + //histoByCategoryNames_.insert(pair("run", "PrimaryVertex-DataBase")); + //histoByCategoryNames_.insert(pair("run", "PrimaryVertex-BeamFit")); + //histoByCategoryNames_.insert(pair("run", "PrimaryVertex-Scalers")); + + histoByCategoryNames_.insert(pair("lumi", "Lumibased BeamSpotHLT")); + histoByCategoryNames_.insert(pair("lumi", "Lumibased BeamSpotLegacy")); + histoByCategoryNames_.insert(pair("lumi", "Lumibased BeamSpotTransient")); + + for (const auto& itV : varNamesV_) { + for (const auto& itM : histoByCategoryNames_) { + histosMap_[itV][itM.first][itM.second] = nullptr; + } + } +} + +void OnlineBeamMonitor::fillDescriptions(edm::ConfigurationDescriptions& iDesc) { + edm::ParameterSetDescription ps; + + ps.addUntracked("MonitorName", "YourSubsystemName"); + iDesc.addDefault(ps); +} + +//---------------------------------------------------------------------------------------------------------------------- +void OnlineBeamMonitor::bookHistograms(DQMStore::IBooker& ibooker, + edm::Run const& iRun, + edm::EventSetup const& iSetup) { + string name; + string title; + int firstLumi = 1; + int lastLumi = 3000; + for (auto& itM : histosMap_) { + //Making histos per Lumi + // x,y,z,sigmaX,sigmaY,sigmaZ + for (auto& itMM : itM.second) { + if (itMM.first != "run") { + for (auto& itMMM : itMM.second) { + name = string("h") + itM.first + itMMM.first; + title = itM.first + "_{0} " + itMMM.first; + if (itMM.first == "lumi") { + ibooker.setCurrentFolder(monitorName_ + "Debug"); + itMMM.second = ibooker.book1D(name, title, lastLumi - firstLumi + 1, firstLumi - 0.5, lastLumi + 0.5); + itMMM.second->setEfficiencyFlag(); + } else { + LogInfo("OnlineBeamMonitorClient") << "Unrecognized category " << itMM.first; + } + if (itMMM.second != nullptr) { + if (itMMM.first.find('-') != string::npos) { + itMMM.second->setAxisTitle(string("#Delta ") + itM.first + "_{0} (cm)", 2); + } else { + itMMM.second->setAxisTitle(itM.first + "_{0} (cm)", 2); + } + itMMM.second->setAxisTitle("Lumisection", 1); + } + } + } + } + } + + // create and cd into new folder + ibooker.setCurrentFolder(monitorName_ + "Validation"); + //Book histograms + bsChoice_ = ibooker.book1D("bsChoice", + "Choice between HLT (+1) and Legacy (-1) BS", + lastLumi - firstLumi + 1, + firstLumi - 0.5, + lastLumi + 0.5); + bsChoice_->setAxisTitle("Lumisection", 1); + bsChoice_->setAxisTitle("Choice", 2); +} + +//---------------------------------------------------------------------------------------------------------------------- +std::shared_ptr OnlineBeamMonitor::globalBeginLuminosityBlock( + const LuminosityBlock& iLumi, const EventSetup& iSetup) const { + // Always create a beamspot group for each lumi weather we have results or not! Each Beamspot will be of unknown type! + + processedLumis_.push_back(iLumi.id().luminosityBlock()); + //Read BeamSpot from DB + ESHandle bsHLTHandle; + ESHandle bsLegacyHandle; + ESHandle bsTransientHandle; + + if (auto bsHLTHandle = iSetup.getHandle(bsHLTToken_)) { + auto const& spotDB = *bsHLTHandle; + + // translate from BeamSpotObjects to reco::BeamSpot + BeamSpot::Point apoint(spotDB.GetX(), spotDB.GetY(), spotDB.GetZ()); + + BeamSpot::CovarianceMatrix matrix; + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + matrix(i, j) = spotDB.GetCovariance(i, j); + } + } + + beamSpotsMap_["HLT"] = + BeamSpot(apoint, spotDB.GetSigmaZ(), spotDB.Getdxdz(), spotDB.Getdydz(), spotDB.GetBeamWidthX(), matrix); + + BeamSpot* aSpot = &(beamSpotsMap_["HLT"]); + + aSpot->setBeamWidthY(spotDB.GetBeamWidthY()); + aSpot->setEmittanceX(spotDB.GetEmittanceX()); + aSpot->setEmittanceY(spotDB.GetEmittanceY()); + aSpot->setbetaStar(spotDB.GetBetaStar()); + + if (spotDB.GetBeamType() == 2) { + aSpot->setType(reco::BeamSpot::Tracker); + } else { + aSpot->setType(reco::BeamSpot::Fake); + } + //LogInfo("OnlineBeamMonitor") + // << *aSpot << std::endl; + } else { + LogInfo("OnlineBeamMonitor") << "Database BeamSpot is not valid at lumi: " << iLumi.id().luminosityBlock(); + } + if (auto bsLegacyHandle = iSetup.getHandle(bsLegacyToken_)) { + auto const& spotDB = *bsLegacyHandle; + // translate from BeamSpotObjects to reco::BeamSpot + BeamSpot::Point apoint(spotDB.GetX(), spotDB.GetY(), spotDB.GetZ()); + + BeamSpot::CovarianceMatrix matrix; + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + matrix(i, j) = spotDB.GetCovariance(i, j); + } + } + + beamSpotsMap_["Legacy"] = + BeamSpot(apoint, spotDB.GetSigmaZ(), spotDB.Getdxdz(), spotDB.Getdydz(), spotDB.GetBeamWidthX(), matrix); + + BeamSpot* aSpot = &(beamSpotsMap_["Legacy"]); + + aSpot->setBeamWidthY(spotDB.GetBeamWidthY()); + aSpot->setEmittanceX(spotDB.GetEmittanceX()); + aSpot->setEmittanceY(spotDB.GetEmittanceY()); + aSpot->setbetaStar(spotDB.GetBetaStar()); + + if (spotDB.GetBeamType() == 2) { + aSpot->setType(reco::BeamSpot::Tracker); + } else { + aSpot->setType(reco::BeamSpot::Fake); + } + //LogInfo("OnlineBeamMonitor") + // << *aSpot << std::endl; + } else { + LogInfo("OnlineBeamMonitor") << "Database BeamSpot is not valid at lumi: " << iLumi.id().luminosityBlock(); + } + if (auto bsTransientHandle = iSetup.getHandle(bsTransientToken_)) { + auto const& spotDB = *bsTransientHandle; + + // translate from BeamSpotObjects to reco::BeamSpot + BeamSpot::Point apoint(spotDB.GetX(), spotDB.GetY(), spotDB.GetZ()); + + BeamSpot::CovarianceMatrix matrix; + for (int i = 0; i < 7; ++i) { + for (int j = 0; j < 7; ++j) { + matrix(i, j) = spotDB.GetCovariance(i, j); + } + } + + beamSpotsMap_["Transient"] = + BeamSpot(apoint, spotDB.GetSigmaZ(), spotDB.Getdxdz(), spotDB.Getdydz(), spotDB.GetBeamWidthX(), matrix); + + BeamSpot* aSpot = &(beamSpotsMap_["Transient"]); + + aSpot->setBeamWidthY(spotDB.GetBeamWidthY()); + aSpot->setEmittanceX(spotDB.GetEmittanceX()); + aSpot->setEmittanceY(spotDB.GetEmittanceY()); + aSpot->setbetaStar(spotDB.GetBetaStar()); + + if (spotDB.GetBeamType() == 2) { + aSpot->setType(reco::BeamSpot::Tracker); + } else { + aSpot->setType(reco::BeamSpot::Fake); + } + //LogInfo("OnlineBeamMonitor") + // << *aSpot << std::endl; + } else { + LogInfo("OnlineBeamMonitor") << "Database BeamSpot is not valid at lumi: " << iLumi.id().luminosityBlock(); + } + return nullptr; +} + +//---------------------------------------------------------------------------------------------------------------------- +void OnlineBeamMonitor::globalEndLuminosityBlock(const LuminosityBlock& iLumi, const EventSetup& iSetup) { + //Setting up the choice + if (beamSpotsMap_.find("Transient") != beamSpotsMap_.end()) { + if (beamSpotsMap_.find("HLT") != beamSpotsMap_.end() && + beamSpotsMap_["Transient"].x0() == beamSpotsMap_["HLT"].x0()) { + bsChoice_->setBinContent(iLumi.id().luminosityBlock(), 1); + bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05); + } else if (beamSpotsMap_.find("Legacy") != beamSpotsMap_.end() && + beamSpotsMap_["Transient"].x0() == beamSpotsMap_["Legacy"].x0()) { + bsChoice_->setBinContent(iLumi.id().luminosityBlock(), -1); + bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05); + } else { + bsChoice_->setBinContent(iLumi.id().luminosityBlock(), -10); + bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05); + } + } else { + bsChoice_->setBinContent(iLumi.id().luminosityBlock(), 0); + bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05); + } + + // "PV,BF..." Value,Error + map > resultsMap; + vector > vertexResults; + MonitorElement* histo = nullptr; + for (const auto& itV : varNamesV_) { + resultsMap.clear(); + for (const auto& itBS : beamSpotsMap_) { + if (itBS.second.type() == BeamSpot::Tracker) { + if (itV == "x") { + resultsMap[itBS.first] = pair(itBS.second.x0(), itBS.second.x0Error()); + } else if (itV == "y") { + resultsMap[itBS.first] = pair(itBS.second.y0(), itBS.second.y0Error()); + } else if (itV == "z") { + resultsMap[itBS.first] = pair(itBS.second.z0(), itBS.second.z0Error()); + } else if (itV == "sigmaX") { + resultsMap[itBS.first] = pair(itBS.second.BeamWidthX(), itBS.second.BeamWidthXError()); + } else if (itV == "sigmaY") { + resultsMap[itBS.first] = pair(itBS.second.BeamWidthY(), itBS.second.BeamWidthYError()); + } else if (itV == "sigmaZ") { + resultsMap[itBS.first] = pair(itBS.second.sigmaZ(), itBS.second.sigmaZ0Error()); + } else { + LogInfo("OnlineBeamMonitor") << "The histosMap_ has been built with the name " << itV + << " that I can't recognize!"; + } + } + } + + for (const auto& itM : histoByCategoryNames_) { + if ((histo = histosMap_[itV][itM.first][itM.second]) == nullptr) + continue; + if (itM.second == "Lumibased BeamSpotHLT") { + if (resultsMap.find("HLT") != resultsMap.end()) { + histo->setBinContent(iLumi.id().luminosityBlock(), resultsMap["HLT"].first); + histo->setBinError(iLumi.id().luminosityBlock(), resultsMap["HLT"].second); + } + } else if (itM.second == "Lumibased BeamSpotLegacy") { + if (resultsMap.find("Legacy") != resultsMap.end()) { + histo->setBinContent(iLumi.id().luminosityBlock(), resultsMap["Legacy"].first); + histo->setBinError(iLumi.id().luminosityBlock(), resultsMap["Legacy"].second); + } + } else if (itM.second == "Lumibased BeamSpotTransient") { + if (resultsMap.find("Transient") != resultsMap.end()) { + histo->setBinContent(iLumi.id().luminosityBlock(), resultsMap["Transient"].first); + histo->setBinError(iLumi.id().luminosityBlock(), resultsMap["Transient"].second); + } + } else { + LogInfo("OnlineBeamMonitor") << "The histosMap_ have a histogram named " << itM.second + << " that I can't recognize in this loop!"; + } + } + } +} + +void OnlineBeamMonitor::dqmEndRun(edm::Run const&, edm::EventSetup const&) { + if (processedLumis_.empty()) { + return; + } + + const double bigNumber = 1000000.; + std::sort(processedLumis_.begin(), processedLumis_.end()); + int firstLumi = *processedLumis_.begin(); + int lastLumi = *(--processedLumis_.end()); + bsChoice_->getTH1()->GetXaxis()->SetRangeUser(firstLumi - 0.5, lastLumi + 0.5); + for (auto& itH : histosMap_) { + for (auto& itHH : itH.second) { + double min = bigNumber; + double max = -bigNumber; + if (itHH.first != "run") { + for (auto& itHHH : itHH.second) { + if (itHHH.second != nullptr) { + for (int bin = 1; bin <= itHHH.second->getTH1()->GetNbinsX(); bin++) { + if (itHHH.second->getTH1()->GetBinError(bin) != 0 || itHHH.second->getTH1()->GetBinContent(bin) != 0) { + if (itHHH.first == "Lumibased BeamSpotHLT" || itHHH.first == "Lumibased BeamSpotLegacy" || + itHHH.first == "Lumibased BeamSpotTransient") { + if (min > itHHH.second->getTH1()->GetBinContent(bin)) { + min = itHHH.second->getTH1()->GetBinContent(bin); + } + if (max < itHHH.second->getTH1()->GetBinContent(bin)) { + max = itHHH.second->getTH1()->GetBinContent(bin); + } + } else { + LogInfo("OnlineBeamMonitorClient") << "The histosMap_ have a histogram named " << itHHH.first + << " that I can't recognize in this loop!"; + } + } + } + } + } + for (auto& itHHH : itHH.second) { + if (itHHH.second != nullptr) { + if (itHHH.first == "Lumibased BeamSpotHLT" || itHHH.first == "Lumibased BeamSpotLegacy" || + itHHH.first == "Lumibased BeamSpotTransient") { + if ((max == -bigNumber && min == bigNumber) || max - min == 0) { + itHHH.second->getTH1()->SetMinimum(itHHH.second->getTH1()->GetMinimum() - 0.01); + itHHH.second->getTH1()->SetMaximum(itHHH.second->getTH1()->GetMaximum() + 0.01); + } else { + itHHH.second->getTH1()->SetMinimum(min - 0.1 * (max - min)); + itHHH.second->getTH1()->SetMaximum(max + 0.1 * (max - min)); + } + } else { + LogInfo("OnlineBeamMonitorClient") + << "The histosMap_ have a histogram named " << itHHH.first << " that I can't recognize in this loop!"; + } + itHHH.second->getTH1()->GetXaxis()->SetRangeUser(firstLumi - 0.5, lastLumi + 0.5); + } + } + } + } + } +} +DEFINE_FWK_MODULE(OnlineBeamMonitor); diff --git a/DQM/BeamMonitor/plugins/OnlineBeamMonitor.h b/DQM/BeamMonitor/plugins/OnlineBeamMonitor.h new file mode 100644 index 0000000000000..ad375d69036b3 --- /dev/null +++ b/DQM/BeamMonitor/plugins/OnlineBeamMonitor.h @@ -0,0 +1,73 @@ +#ifndef DQM_BeamMonitor_OnlineBeamMonitor_h +#define DQM_BeamMonitor_OnlineBeamMonitor_h + +/** \class OnlineBeamMonitor + * * + * \author Simone Gennai INFN/Bicocca + */ +// C++ +#include +#include +#include +// CMS +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "DQMServices/Core/interface/DQMStore.h" +#include "DQMServices/Core/interface/DQMOneEDAnalyzer.h" +#include "DataFormats/Provenance/interface/LuminosityBlockID.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotObjects.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotOnlineObjects.h" +#include "CondFormats/DataRecord/interface/BeamSpotOnlineLegacyObjectsRcd.h" +#include "CondFormats/DataRecord/interface/BeamSpotOnlineHLTObjectsRcd.h" +#include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h" + +namespace onlinebeammonitor { + struct NoCache {}; +} // namespace onlinebeammonitor + +class OnlineBeamMonitor : public DQMOneEDAnalyzer> { +public: + OnlineBeamMonitor(const edm::ParameterSet&); + static void fillDescriptions(edm::ConfigurationDescriptions&); + +protected: + void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override; + std::shared_ptr globalBeginLuminosityBlock(const edm::LuminosityBlock& iLumi, + const edm::EventSetup& iSetup) const override; + void globalEndLuminosityBlock(const edm::LuminosityBlock& iLumi, const edm::EventSetup& iSetup) override; + void dqmEndRun(edm::Run const&, edm::EventSetup const&) override; + +private: + //Typedefs + // BF,BS... + typedef std::map BeamSpotContainer; + // x,y,z,sigmax(y,z)... [run,lumi] Histo name + typedef std::map>> HistosContainer; + // x,y,z,sigmax(y,z)... [run,lumi] Histo name + typedef std::map>> PositionContainer; + + //Parameters + std::string monitorName_; + edm::ESGetToken bsTransientToken_; + edm::ESGetToken bsHLTToken_; + edm::ESGetToken bsLegacyToken_; + + //Service variables + int numberOfValuesToSave_; + mutable int numberOfProcessedLumis_; + mutable std::vector processedLumis_; + // MonitorElements: + MonitorElement* bsChoice_; + + //Containers + mutable BeamSpotContainer beamSpotsMap_; + HistosContainer histosMap_; + PositionContainer positionsMap_; + std::vector varNamesV_; //x,y,z,sigmax(y,z) + std::multimap histoByCategoryNames_; //run, lumi +}; + +#endif diff --git a/DQM/BeamMonitor/python/BeamMonitor_Cosmics_cff.py b/DQM/BeamMonitor/python/BeamMonitor_Cosmics_cff.py index c93ae24968060..59f02f0ea11fa 100644 --- a/DQM/BeamMonitor/python/BeamMonitor_Cosmics_cff.py +++ b/DQM/BeamMonitor/python/BeamMonitor_Cosmics_cff.py @@ -10,6 +10,7 @@ resetEveryNLumi = cms.untracked.int32(20), resetPVEveryNLumi = cms.untracked.int32(2), Debug = cms.untracked.bool(False), + recordName = cms.untracked.string('BeamSpotOnlineHLTObjectsRcd'), BeamFitter = cms.PSet( Debug = cms.untracked.bool(False), TrackCollection = cms.untracked.InputTag('ctfWithMaterialTracksP5'), ## ctfWithMaterialTracksP5 for CRAFT diff --git a/DQM/BeamMonitor/python/BeamMonitor_MC_cff.py b/DQM/BeamMonitor/python/BeamMonitor_MC_cff.py index 363a1e582b9e1..209465897fedc 100644 --- a/DQM/BeamMonitor/python/BeamMonitor_MC_cff.py +++ b/DQM/BeamMonitor/python/BeamMonitor_MC_cff.py @@ -11,6 +11,7 @@ fitPVEveryNLumi = cms.untracked.int32(1), resetPVEveryNLumi = cms.untracked.int32(2), Debug = cms.untracked.bool(False), + recordName = cms.untracked.string('BeamSpotOnlineHLTObjectsRcd'), BeamFitter = cms.PSet( Debug = cms.untracked.bool(False), TrackCollection = cms.untracked.InputTag('generalTracks'), ## ctfWithMaterialTracksP5 for CRAFT diff --git a/DQM/BeamMonitor/python/BeamMonitor_PixelLess_cff.py b/DQM/BeamMonitor/python/BeamMonitor_PixelLess_cff.py index 770df66d9a5a6..87e4a7c8142b4 100644 --- a/DQM/BeamMonitor/python/BeamMonitor_PixelLess_cff.py +++ b/DQM/BeamMonitor/python/BeamMonitor_PixelLess_cff.py @@ -9,6 +9,7 @@ fitPVEveryNLumi = cms.untracked.int32(1), resetPVEveryNLumi = cms.untracked.int32(2), Debug = cms.untracked.bool(False), + recordName = cms.untracked.string('BeamSpotOnlineHLTObjectsRcd'), BeamFitter = cms.PSet( Debug = cms.untracked.bool(False), TrackCollection = cms.untracked.InputTag('ctfPixelLess'), diff --git a/DQM/BeamMonitor/python/BeamMonitor_Pixel_cff.py b/DQM/BeamMonitor/python/BeamMonitor_Pixel_cff.py index b7de937893b96..4365d5850eb4e 100644 --- a/DQM/BeamMonitor/python/BeamMonitor_Pixel_cff.py +++ b/DQM/BeamMonitor/python/BeamMonitor_Pixel_cff.py @@ -12,6 +12,7 @@ resetPVEveryNLumi = cms.untracked.int32(5), Debug = cms.untracked.bool(False), OnlineMode = cms.untracked.bool(True), + recordName = cms.untracked.string('BeamSpotOnlineHLTObjectsRcd'), BeamFitter = cms.PSet( Debug = cms.untracked.bool(False), TrackCollection = cms.untracked.InputTag('pixelTracks'), diff --git a/DQM/BeamMonitor/python/BeamMonitor_cff.py b/DQM/BeamMonitor/python/BeamMonitor_cff.py index 1fef070cacd83..0494a65b047c6 100644 --- a/DQM/BeamMonitor/python/BeamMonitor_cff.py +++ b/DQM/BeamMonitor/python/BeamMonitor_cff.py @@ -12,6 +12,7 @@ resetPVEveryNLumi = cms.untracked.int32(5), Debug = cms.untracked.bool(False), OnlineMode = cms.untracked.bool(True), + recordName = cms.untracked.string('BeamSpotOnlineHLTObjectsRcd'), BeamFitter = cms.PSet( Debug = cms.untracked.bool(False), TrackCollection = cms.untracked.InputTag('generalTracks'), diff --git a/DQM/BeamMonitor/python/FakeBeamMonitor_cff.py b/DQM/BeamMonitor/python/FakeBeamMonitor_cff.py new file mode 100644 index 0000000000000..18305eb868507 --- /dev/null +++ b/DQM/BeamMonitor/python/FakeBeamMonitor_cff.py @@ -0,0 +1,78 @@ +import FWCore.ParameterSet.Config as cms +from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer + +dqmFakeBeamMonitor = DQMEDAnalyzer("FakeBeamMonitor", + monitorName = cms.untracked.string('FakeBeamMonitor'), + timeInterval = cms.untracked.int32(920), + fitEveryNLumi = cms.untracked.int32(1), + resetEveryNLumi = cms.untracked.int32(20), + fitPVEveryNLumi = cms.untracked.int32(1), + resetPVEveryNLumi = cms.untracked.int32(5), + Debug = cms.untracked.bool(False), + OnlineMode = cms.untracked.bool(True), + recordName = cms.untracked.string('BeamSpotOnlineHLTObjectsRcd'), + BeamFitter = cms.PSet( + Debug = cms.untracked.bool(False), + TrackCollection = cms.untracked.InputTag('pixelTracks'), + IsMuonCollection = cms.untracked.bool(False), + WriteAscii = cms.untracked.bool(False), + AsciiFileName = cms.untracked.string('BeamFit.txt'), ## all results + AppendRunToFileName = cms.untracked.bool(True), #runnumber will be inserted to the file name + WriteDIPAscii = cms.untracked.bool(False), + DIPFileName = cms.untracked.string('BeamFitDIP.txt'), + SaveNtuple = cms.untracked.bool(False), + SavePVVertices = cms.untracked.bool(False), + SaveFitResults = cms.untracked.bool(False), + OutputFileName = cms.untracked.string('BeamFit.root'), ## ntuple filename + MinimumPt = cms.untracked.double(1.0), + MaximumEta = cms.untracked.double(2.4), + MaximumImpactParameter = cms.untracked.double(1.0), + MaximumZ = cms.untracked.double(60), + MinimumTotalLayers = cms.untracked.int32(3), + MinimumPixelLayers = cms.untracked.int32(3), + MaximumNormChi2 = cms.untracked.double(30.0), + TrackAlgorithm = cms.untracked.vstring(), ## ctf,rs,cosmics,initialStep,lowPtTripletStep...; for all algos, leave it blank + TrackQuality = cms.untracked.vstring(), ## loose, tight, highPurity...; for all qualities, leave it blank + InputBeamWidth = cms.untracked.double(0.0060), ## beam width used for Trk fitter, used only when result from PV is not available + FractionOfFittedTrks = cms.untracked.double(0.9), + MinimumInputTracks = cms.untracked.int32(150), + deltaSignificanceCut = cms.untracked.double(10) + ), + PVFitter = cms.PSet( + Debug = cms.untracked.bool(False), + Apply3DFit = cms.untracked.bool(True), + VertexCollection = cms.untracked.InputTag('pixelVertices'), + #WriteAscii = cms.untracked.bool(True), + #AsciiFileName = cms.untracked.string('PVFit.txt'), + maxNrStoredVertices = cms.untracked.uint32(1000000), + minNrVerticesForFit = cms.untracked.uint32(50), + minVertexNdf = cms.untracked.double(4.), + #--Not used + maxVertexNormChi2 = cms.untracked.double(30.), + minVertexNTracks = cms.untracked.uint32(0), + minVertexMeanWeight = cms.untracked.double(0.0), + maxVertexR = cms.untracked.double(2.), + maxVertexZ = cms.untracked.double(10.), + #--------------- + errorScale = cms.untracked.double(1.23), + nSigmaCut = cms.untracked.double(50.0), + FitPerBunchCrossing = cms.untracked.bool(False), + useOnlyFirstPV = cms.untracked.bool(False), + minSumPt = cms.untracked.double(0.) + ), + dxBin = cms.int32(200), + dxMin = cms.double(-1.0), + dxMax = cms.double(1.0), + + vxBin = cms.int32(200), + vxMin = cms.double(-0.5), + vxMax = cms.double(0.5), + + dzBin = cms.int32(80), + dzMin = cms.double(-20), + dzMax = cms.double(20), + + phiBin = cms.int32(63), + phiMin = cms.double(-3.15), + phiMax = cms.double(3.15) + ) diff --git a/DQM/BeamMonitor/test/Online_BeamMonitor_file.py b/DQM/BeamMonitor/test/Online_BeamMonitor_file.py new file mode 100644 index 0000000000000..5d8ef1f0c1c2f --- /dev/null +++ b/DQM/BeamMonitor/test/Online_BeamMonitor_file.py @@ -0,0 +1,101 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("DQM") +process.load("FWCore.MessageLogger.MessageLogger_cfi") + + +process.load("CondCore.CondDB.CondDB_cfi") +process.BeamSpotDBSource = cms.ESSource("PoolDBESSource", + process.CondDB, + toGet = cms.VPSet( + cms.PSet( + record = cms.string('BeamSpotOnlineLegacyObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestLegacy"), + refreshTime = cms.uint64(1) + ), + cms.PSet( + record = cms.string('BeamSpotOnlineHLTObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestHLT"), + refreshTime = cms.uint64(1) + + ), + ), + ) +process.BeamSpotDBSource.connect = cms.string('frontier://FrontierProd/CMS_CONDITIONS') +process.BeamSpotESProducer = cms.ESProducer("OnlineBeamSpotESProducer") + + + toGet = cms.VPSet( + cms.PSet( + record = cms.string('BeamSpotOnlineLegacyObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestLegacy"), + refreshTime = cms.uint64(1) + ), + cms.PSet( + record = cms.string('BeamSpotOnlineHLTObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestHLT"), + refreshTime = cms.uint64(1) + ), + ) +) +process.BeamSpotDBSource.connect = cms.string('frontier://FrontierProd/CMS_CONDITIONS') +process.BeamSpotESProducer = cms.ESProducer("OnlineBeamSpotESProducer") + + + + + + +# initialize MessageLogger +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger.categories = ["OnlineBeamMonitor"] +process.MessageLogger.cerr = cms.untracked.PSet(placeholder = cms.untracked.bool(True)) +process.MessageLogger.cout = cms.untracked.PSet( + threshold = cms.untracked.string('INFO'), + default = cms.untracked.PSet( + limit = cms.untracked.int32(0) + ), + OnlineBeamMonitor = cms.untracked.PSet( + reportEvery = cms.untracked.int32(1), # every 1000th only + limit = cms.untracked.int32(0) + ) +) +#process.MessageLogger.statistics.append('cout') +process.source = cms.Source("EmptySource") +process.source.numberEventsInRun=cms.untracked.uint32(20) +process.source.firstRun = cms.untracked.uint32(336055) +process.source.firstLuminosityBlock = cms.untracked.uint32(49) +process.source.numberEventsInLuminosityBlock = cms.untracked.uint32(1) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(100) +) + +#process.load("DQMServices.Core.DQMEDAnalyzer") +process.onlineBeamMonitor = cms.EDProducer("OnlineBeamMonitor", +MonitorName = cms.untracked.string("onlineBeamMonitor")) + + +# DQM Live Environment +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = 'BeamMonitor' +process.dqmSaver.tag = 'BeamMonitor' + +process.dqmEnvPixelLess = process.dqmEnv.clone() +process.dqmEnvPixelLess.subSystemFolder = 'BeamMonitor_PixelLess' + + + +#import RecoVertex.BeamSpotProducer.BeamSpotOnline_cfi +#process.offlineBeamSpotForDQM = RecoVertex.BeamSpotProducer.BeamSpotOnline_cfi.onlineBeamSpotProducer.clone() + +# # summary +process.options = cms.untracked.PSet( + wantSummary = cms.untracked.bool(True), + numberOfThreads = cms.untracked.uint32(4), + numberOfStreams = cms.untracked.uint32 (4), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(2) + + ) + +process.pp = cms.Path(process.onlineBeamMonitor+process.dqmSaver) +process.schedule = cms.Schedule(process.pp) diff --git a/DQM/GEM/plugins/GEMDQMStatusDigi.cc b/DQM/GEM/plugins/GEMDQMStatusDigi.cc index c2321983711c9..350b50954c18b 100644 --- a/DQM/GEM/plugins/GEMDQMStatusDigi.cc +++ b/DQM/GEM/plugins/GEMDQMStatusDigi.cc @@ -29,18 +29,6 @@ using namespace dqm::impl; -typedef struct tagTimeStoreItem { - std::string strName; - std::string strTitle; - std::string strAxisX; - - MonitorElement *h2Histo; - - Int_t nNbinY; - Int_t nNbinMin; - Int_t nNbinMax; -} TimeStoreItem; - class GEMDQMStatusDigi : public DQMEDAnalyzer { public: GEMDQMStatusDigi(const edm::ParameterSet &cfg); @@ -52,11 +40,8 @@ class GEMDQMStatusDigi : public DQMEDAnalyzer { void bookHistogramsChamberPart(DQMStore::IBooker &, GEMDetId &); void bookHistogramsStationPart(DQMStore::IBooker &, GEMDetId &); void bookHistogramsAMCPart(DQMStore::IBooker &); - void bookHistogramsTimeRecordPart(DQMStore::IBooker &); int SetInfoChambers(); - int SetConfigTimeRecord(); - int LoadPrevData(); Int_t seekIdx(std::vector &listLayers, UInt_t unId); void seekIdxSummary(GEMDetId gid, Int_t &nIdxLayer, Int_t &nIdxChamber); @@ -74,6 +59,8 @@ class GEMDQMStatusDigi : public DQMEDAnalyzer { Bool_t FillBits(MonitorElement *monitor, uint64_t unVal, int nNumBits); Bool_t FillBits(MonitorElement *monitor, uint64_t unVal, int nNumBits, int nY); + bool bDebugMode_; + const GEMGeometry *GEMGeometry_; std::shared_ptr GEMROMapping_; std::vector gemChambers_; @@ -83,13 +70,8 @@ class GEMDQMStatusDigi : public DQMEDAnalyzer { int cBit_ = 9; int qVFATBit_ = 5; int fVFATBit_ = 4; - int eBit_ = 16; - int amcStatusBit_ = 6; - - int nNEvtPerSec_; - int nNSecPerBin_; - int nNTimeBinTotal_; - int nNTimeBinPrimitive_; + int eBit_ = 17; + int amcStatusBit_ = 7; int nIdxFirstStrip_; @@ -100,8 +82,6 @@ class GEMDQMStatusDigi : public DQMEDAnalyzer { bool bFlipSummary_; bool bPerSuperchamber_; - std::string strPathPrevDQMRoot_; - edm::EDGetToken tagVFAT_; edm::EDGetToken tagGEB_; edm::EDGetToken tagAMC_; @@ -142,11 +122,6 @@ class GEMDQMStatusDigi : public DQMEDAnalyzer { MonitorElement *h2AMCStatus_; MonitorElement *m_summaryReport_; - - // For more information, see SetConfigTimeRecord() - std::map listTimeStore_; - Int_t nStackedBin_; - Int_t nStackedEvt_; }; const GEMGeometry *GEMDQMStatusDigi::initGeometry(edm::EventSetup const &iSetup) { @@ -177,15 +152,12 @@ GEMDQMStatusDigi::GEMDQMStatusDigi(const edm::ParameterSet &cfg) { bFlipSummary_ = cfg.getParameter("flipSummary"); bPerSuperchamber_ = cfg.getParameter("perSuperchamber"); - strPathPrevDQMRoot_ = cfg.getParameter("pathOfPrevDQMRoot"); - nNEvtPerSec_ = cfg.getParameter("numOfEvtPerSec"); - nNSecPerBin_ = cfg.getParameter("secOfEvtPerBin"); - nNTimeBinPrimitive_ = cfg.getParameter("totalTimeInterval"); - nIdxFirstStrip_ = cfg.getParameter("idxFirstStrip"); nNBxRange_ = cfg.getParameter("bxRange"); nNBxBin_ = cfg.getParameter("bxBin"); + + bDebugMode_ = cfg.getParameter("debugMode"); } void GEMDQMStatusDigi::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { @@ -202,16 +174,13 @@ void GEMDQMStatusDigi::fillDescriptions(edm::ConfigurationDescriptions &descript desc.add("flipSummary", false); desc.add("perSuperchamber", true); - desc.add("pathOfPrevDQMRoot", ""); - desc.add("numOfEvtPerSec", 100); - desc.add("secOfEvtPerBin", 10); - desc.add("totalTimeInterval", 50000); - desc.add("idxFirstStrip", 0); desc.add("bxRange", 10); desc.add("bxBin", 20); + desc.add("debugMode", false); + descriptions.add("GEMDQMStatusDigi", desc); } @@ -231,7 +200,7 @@ int GEMDQMStatusDigi::SetInfoChambers() { int nLayer = sch->nChambers(); for (int l = 0; l < nLayer; l++) { Bool_t bExist = false; - for (auto ch : gemChambers_) + for (const auto &ch : gemChambers_) if (ch.id() == sch->chamber(l + 1)->id()) bExist = true; if (bExist) @@ -248,7 +217,7 @@ int GEMDQMStatusDigi::SetInfoChambers() { m_listLayers.clear(); // Summarizing geometry configurations - for (auto ch : gemChambers_) { + for (const auto &ch : gemChambers_) { GEMDetId gid = ch.id(); GEMDetId layerID(gid.region(), gid.ring(), gid.station(), (bPerSuperchamber_ ? gid.layer() : 0), 0, 0); @@ -301,141 +270,6 @@ int GEMDQMStatusDigi::SetInfoChambers() { return 0; } -// 0: General; for whole AMC slots -int GEMDQMStatusDigi::SetConfigTimeRecord() { - TimeStoreItem newTimeStore; - - newTimeStore.nNbinMin = 0; - newTimeStore.nNbinMax = 0; - - std::string strCommonName = "per_time_"; - - // Very general GEMDetId - newTimeStore.strName = strCommonName + "status_AMCslots"; - newTimeStore.strTitle = "Status of AMC slots per time"; - newTimeStore.strAxisX = "AMC slot"; - newTimeStore.nNbinY = listAMCSlots_.size(); - listTimeStore_[0] = newTimeStore; - - for (auto layerId : m_listLayers) { - std::string strSuffix = - (layerId.region() > 0 ? "p" : "m") + std::to_string(layerId.station()) + "_" + std::to_string(layerId.layer()); - - newTimeStore.strName = strCommonName + "status_GEB_" + suffixLayer(layerId); - newTimeStore.strTitle = ""; - newTimeStore.strAxisX = "Chamber"; - - newTimeStore.nNbinY = nNCh_; - listTimeStore_[layerId] = newTimeStore; - } - - for (auto ch : gemChambers_) { - auto chId = ch.id(); - GEMDetId chIdStatus(chId.region(), chId.ring(), chId.station(), chId.layer(), chId.chamber(), 1); - GEMDetId chIdDigi(chId.region(), chId.ring(), chId.station(), chId.layer(), chId.chamber(), 2); - GEMDetId chIdBx(chId.region(), chId.ring(), chId.station(), chId.layer(), chId.chamber(), 3); - - std::string strSuffix = suffixChamber(chId); - - Int_t nVFAT = 0; - if (chId.station() == 1) - nVFAT = GEMeMap::maxEtaPartition_ * GEMeMap::maxVFatGE11_; - if (chId.station() == 2) - nVFAT = GEMeMap::maxEtaPartition_ * GEMeMap::maxVFatGE21_; - - newTimeStore.strName = strCommonName + "status_chamber_" + strSuffix; - newTimeStore.strTitle = ""; - newTimeStore.strAxisX = "VFAT"; - - newTimeStore.nNbinY = nVFAT; - listTimeStore_[chIdStatus] = newTimeStore; - - newTimeStore.strName = strCommonName + "digi_chamber_" + strSuffix; - newTimeStore.strTitle = ""; - newTimeStore.strAxisX = "VFAT"; - - newTimeStore.nNbinY = nVFAT; - listTimeStore_[chIdDigi] = newTimeStore; - - newTimeStore.strName = strCommonName + "bx_chamber_" + strSuffix; - newTimeStore.strTitle = ""; - newTimeStore.strAxisX = "Bunch crossing"; - - newTimeStore.nNbinY = nNBxBin_; - newTimeStore.nNbinMin = -nNBxRange_; - newTimeStore.nNbinMax = nNBxRange_; - - listTimeStore_[chIdBx] = newTimeStore; - - newTimeStore.nNbinMin = newTimeStore.nNbinMax = 0; - } - - return 0; -} - -int GEMDQMStatusDigi::LoadPrevData() { - TFile *fPrev; - Bool_t bSync = true; - - nStackedBin_ = 0; - nStackedEvt_ = 0; - - if (strPathPrevDQMRoot_.empty()) - return 0; - - std::ifstream fExist(strPathPrevDQMRoot_.c_str()); - if (!fExist.good()) - return 0; - fExist.close(); - - fPrev = new TFile(strPathPrevDQMRoot_.c_str()); - if (fPrev == nullptr) - return 1; - - std::cout << strPathPrevDQMRoot_ << " is being loaded" << std::endl; - std::string strRunnum = ((TDirectoryFile *)fPrev->Get("DQMData"))->GetListOfKeys()->At(0)->GetName(); - - // In this stage, we need to use them to check the consistence of time-histograms - nStackedBin_ = -1; - nStackedEvt_ = -1; - - for (auto &itStore : listTimeStore_) { - std::string strNameStore = "DQMData/" + strRunnum + "/GEM/Run summary/StatusDigi/" + itStore.second.strName; - TH2F *h2Prev = (TH2F *)fPrev->Get(strNameStore.c_str()); - - Int_t nNBinX = h2Prev->GetNbinsX(); - Int_t nNBinY = h2Prev->GetNbinsY(); - - // Including all under/overflow bins (they contain important infos) - nStackedEvt_ = 0; - for (Int_t i = 0; i <= nNBinX + 1; i++) { - if (i > 0) - nStackedEvt_ += h2Prev->GetBinContent(i, 0); - for (Int_t j = 0; j <= nNBinY + 1; j++) { - itStore.second.h2Histo->setBinContent(i, j, h2Prev->GetBinContent(i, j)); - } - } - - Int_t nStackedBinCurr = nStackedEvt_ / (nNSecPerBin_ * nNEvtPerSec_); - Int_t nStackedEvtCurr = nStackedEvt_ % (nNSecPerBin_ * nNEvtPerSec_); - - if (nStackedBin_ < 0) { - nStackedBin_ = nStackedBinCurr; - nStackedEvt_ = nStackedEvtCurr; - } else { - bSync = (nStackedBin_ == nStackedBinCurr && nStackedEvt_ == nStackedEvtCurr); - } - } - - if (!bSync) { // No sync...! - std::cerr << "WARNING: No sync on time histograms" << std::endl; - } - - fPrev->Close(); - - return 0; -} - void GEMDQMStatusDigi::bookHistogramsChamberPart(DQMStore::IBooker &ibooker, GEMDetId &gid) { std::string hName, hTitle; @@ -529,14 +363,17 @@ void GEMDQMStatusDigi::bookHistogramsStationPart(DQMStore::IBooker &ibooker, GEM listGEBZeroSupWordsCnt_[lid] = newbookGEB( ibooker, "geb_zeroSupWordsCnt", "zeroSupWordsCnt", "Zero sup. words count", lid, la, st, re, 10, 0, 10); - listGEBbcOH_[lid] = - newbookGEB(ibooker, "geb_bcOH", "OH bunch crossing", "OH bunch crossing", lid, la, st, re, 3600, 0, 3600); - listGEBecOH_[lid] = - newbookGEB(ibooker, "geb_ecOH", "OH event coounter", "OH event counter", lid, la, st, re, 256, 0, 256); - listGEBOHCRC_[lid] = - newbookGEB(ibooker, "geb_OHCRC", "CRC of OH data", "CRC of OH data", lid, la, st, re, 65536, 0, 65536); + if (bDebugMode_) { + listGEBbcOH_[lid] = + newbookGEB(ibooker, "geb_bcOH", "OH bunch crossing", "OH bunch crossing", lid, la, st, re, 3600, 0, 3600); + listGEBecOH_[lid] = + newbookGEB(ibooker, "geb_ecOH", "OH event coounter", "OH event counter", lid, la, st, re, 256, 0, 256); + listGEBOHCRC_[lid] = + newbookGEB(ibooker, "geb_OHCRC", "CRC of OH data", "CRC of OH data", lid, la, st, re, 65536, 0, 65536); + } unBinPos = 1; + listGEBInputStatus_[lid]->setBinLabel(unBinPos++, "Good", 2); listGEBInputStatus_[lid]->setBinLabel(unBinPos++, "BX mismatch GLIB OH", 2); listGEBInputStatus_[lid]->setBinLabel(unBinPos++, "BX mismatch GLIB VFAT", 2); listGEBInputStatus_[lid]->setBinLabel(unBinPos++, "OOS GLIB OH", 2); @@ -566,6 +403,7 @@ void GEMDQMStatusDigi::bookHistogramsAMCPart(DQMStore::IBooker &ibooker) { amcStatusBit_); uint32_t unBinPos = 1; + h2AMCStatus_->setBinLabel(unBinPos++, "Good", 2); h2AMCStatus_->setBinLabel(unBinPos++, "BC0 not locked", 2); h2AMCStatus_->setBinLabel(unBinPos++, "DAQ not ready", 2); h2AMCStatus_->setBinLabel(unBinPos++, "DAQ clock not locked", 2); @@ -574,37 +412,6 @@ void GEMDQMStatusDigi::bookHistogramsAMCPart(DQMStore::IBooker &ibooker) { h2AMCStatus_->setBinLabel(unBinPos++, "GLIB out-of-sync", 2); } -void GEMDQMStatusDigi::bookHistogramsTimeRecordPart(DQMStore::IBooker &ibooker) { - for (auto &itStore : listTimeStore_) { - auto &infoCurr = itStore.second; - - Float_t fMin = -0.5, fMax = infoCurr.nNbinY - 0.5; - - if (infoCurr.nNbinMin < infoCurr.nNbinMax) { - fMin = infoCurr.nNbinMin; - fMax = infoCurr.nNbinMax; - } - - infoCurr.h2Histo = ibooker.book2D( - infoCurr.strName, - infoCurr.strTitle + ";Per " + std::to_string(nNSecPerBin_ * nNEvtPerSec_) + " events;" + infoCurr.strAxisX, - nNTimeBinPrimitive_, - 0, - nNTimeBinPrimitive_, - infoCurr.nNbinY, - fMin, - fMax); - - if (seekIdx(m_listLayers, itStore.first) >= 0) { - for (Int_t i = 0; i < nNCh_; i++) { - auto &gid = m_listChambers[i]; - Int_t nCh = gid.chamber() + (bPerSuperchamber_ ? 0 : gid.layer() - 1); - infoCurr.h2Histo->setBinLabel(i + 1, std::to_string(nCh), 2); - } - } - } -} - // To make labels like python, with std::(unordered_)map std::string printfWithMap(std::string strFmt, std::unordered_map mapArg) { std::string strRes = strFmt; @@ -663,7 +470,7 @@ void GEMDQMStatusDigi::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const ibooker.cd(); ibooker.setCurrentFolder("GEM/StatusDigi"); - for (auto ch : gemChambers_) { + for (const auto &ch : gemChambers_) { GEMDetId gid = ch.id(); bookHistogramsChamberPart(ibooker, gid); } @@ -674,11 +481,6 @@ void GEMDQMStatusDigi::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const bookHistogramsAMCPart(ibooker); - // Setting the informations for time histograms - SetConfigTimeRecord(); - bookHistogramsTimeRecordPart(ibooker); - LoadPrevData(); - h1_vfat_qualityflag_ = ibooker.book1D("vfat_quality_flag", "quality and flag", 9, 0, 9); h2_vfat_qualityflag_ = ibooker.book2D("vfat_quality_flag_per_geb", "quality and flag", nNCh_, 0, nNCh_, 9, 0, 9); @@ -782,15 +584,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e event.getByToken(tagAMC_, gemAMC); event.getByToken(tagDigi_, gemDigis); - auto fillTimeHisto = [](TimeStoreItem &listCurr, int nStackedBin, int nIdx, bool bFill) -> void { - Int_t nX = nStackedBin + 1; - Int_t nY = nIdx + 1; - - listCurr.h2Histo->setBinContent(nX, 0, listCurr.h2Histo->getBinContent(nX, 0) + 1); - if (bFill) - listCurr.h2Histo->setBinContent(nX, nY, listCurr.h2Histo->getBinContent(nX, nY) + 1); - }; - for (GEMVfatStatusDigiCollection::DigiRangeIterator vfatIt = gemVFAT->begin(); vfatIt != gemVFAT->end(); ++vfatIt) { GEMDetId gemid = (*vfatIt).first; GEMDetId gemchId = gemid.chamberId(); @@ -800,15 +593,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e int nRoll = gemid.roll(); const GEMVfatStatusDigiCollection::Range &range = (*vfatIt).second; - GEMDetId chIdStatus(gemid.region(), gemid.ring(), gemid.station(), gemid.layer(), gemid.chamber(), 1); - if (listTimeStore_.find((UInt_t)chIdStatus) == listTimeStore_.end()) { - edm::LogError("BadGeometry") << "Wrong detId which is not in the current geometry (VFAT status): " << gemchId - << std::endl; - continue; - } - - auto &listCurr = listTimeStore_[chIdStatus]; - for (auto vfatStat = range.first; vfatStat != range.second; ++vfatStat) { bIsNotEmpty = true; @@ -834,8 +618,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e } listVFATEC_[gemchId]->Fill(vfatStat->ec(), nVFAT); - - fillTimeHisto(listCurr, nStackedBin_, nVFAT, (unQFVFAT & ~0x1) != 0); } } @@ -846,19 +628,11 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e Int_t nCh = seekIdx(m_listChambers, chid); - if (listTimeStore_.find((UInt_t)lid) == listTimeStore_.end()) { - edm::LogError("BadGeometry") << "Wrong detId which is not in the current geometry (GEB status): " << lid - << std::endl; - continue; - } - - auto &listCurr = listTimeStore_[lid]; - const GEMGEBdataCollection::Range &range = (*gebIt).second; for (auto GEBStatus = range.first; GEBStatus != range.second; ++GEBStatus) { bIsNotEmpty = true; - uint64_t unBit = 0; + uint64_t unBit = 1; uint64_t unStatus = 0; unStatus |= (GEBStatus->bxmVvV() << unBit++); @@ -882,6 +656,8 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e Int_t nIdxLayer, nIdxChamber; seekIdxSummary(gemid, nIdxLayer, nIdxChamber); h3SummaryStatusPre_->setBinContent(nIdxChamber, nIdxLayer, m_nIdxSummaryErr, 1.0); + } else { + unStatus = 0x01; // Good } bIsNotEmpty = FillBits(listGEBInputStatus_[lid], unStatus, eBit_, nCh); @@ -897,11 +673,11 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e listGEBVFATWordCntT_[lid]->Fill(nCh, GEBStatus->vfatWordCntT() / 3); listGEBZeroSupWordsCnt_[lid]->Fill(nCh, GEBStatus->zeroSupWordsCnt()); - listGEBbcOH_[lid]->Fill(nCh, GEBStatus->bcOH()); - listGEBecOH_[lid]->Fill(nCh, GEBStatus->ecOH()); - listGEBOHCRC_[lid]->Fill(nCh, GEBStatus->crc()); - - fillTimeHisto(listCurr, nStackedBin_, nCh, unStatus != 0); + if (bDebugMode_) { + listGEBbcOH_[lid]->Fill(nCh, GEBStatus->bcOH()); + listGEBecOH_[lid]->Fill(nCh, GEBStatus->ecOH()); + listGEBOHCRC_[lid]->Fill(nCh, GEBStatus->crc()); + } } } @@ -914,10 +690,9 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e for (GEMAMCdataCollection::DigiRangeIterator amcIt = gemAMC->begin(); amcIt != gemAMC->end(); ++amcIt) { const GEMAMCdataCollection::Range &range = (*amcIt).second; - auto &listCurr = listTimeStore_[0]; for (auto amc = range.first; amc != range.second; ++amc) { Int_t nIdAMC = findAMCIdx(amc->amcNum()); - uint64_t unBit = 0; + uint64_t unBit = 1; uint64_t unStatus = 0; unStatus |= (!amc->bc0locked() << unBit++); @@ -927,6 +702,10 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e unStatus |= (amc->backPressure() << unBit++); unStatus |= (amc->oosGlib() << unBit++); + if (unStatus == 0) { + unStatus = 0x01; // Good + } + FillBits(h2AMCStatus_, unStatus, amcStatusBit_, nIdAMC); h1_amc_ttsState_->Fill(amc->ttsState()); @@ -934,8 +713,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e h1_amc_buffState_->Fill(amc->buffState()); h1_amc_oosGlib_->Fill(amc->oosGlib()); h1_amc_chTimeOut_->Fill(amc->linkTo()); - - fillTimeHisto(listCurr, nStackedBin_, nIdAMC, unStatus != 0); } } @@ -955,7 +732,7 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e }; // Checking if there is a fire (data) - for (auto ch : gemChambers_) { + for (const auto &ch : gemChambers_) { GEMDetId cId = ch.id(); Bool_t bIsHit = false; @@ -965,9 +742,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e GEMDetId chIdDigi(cId.region(), cId.ring(), cId.station(), cId.layer(), cId.chamber(), 2); GEMDetId chIdBx(cId.region(), cId.ring(), cId.station(), cId.layer(), cId.chamber(), 3); - auto &listCurrDigi = listTimeStore_[chIdDigi]; - auto &listCurrBx = listTimeStore_[chIdBx]; - for (auto roll : ch.etaPartitions()) { GEMDetId rId = roll->id(); const auto &digis_in_det = gemDigis->get(rId); @@ -978,19 +752,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e bIsHit = true; mapBXVFAT[nVFAT] = d->bx(); - fillTimeHisto(listCurrDigi, nStackedBin_, nVFAT, true); - - Int_t nIdxBx; - - if (d->bx() < listCurrBx.nNbinMin) - nIdxBx = 0; - else if (d->bx() >= listCurrBx.nNbinMax) - nIdxBx = listCurrBx.nNbinY - 1; - else - nIdxBx = (Int_t)(listCurrBx.nNbinY * 1.0 * (d->bx() - listCurrBx.nNbinMin) / - (listCurrBx.nNbinMax - listCurrBx.nNbinMin)); - - fillTimeHisto(listCurrBx, nStackedBin_, nIdxBx, true); } } @@ -1003,13 +764,6 @@ void GEMDQMStatusDigi::analyze(edm::Event const &event, edm::EventSetup const &e h3SummaryStatusPre_->setBinContent(nIdxChamber, nIdxLayer, m_nIdxSummaryFill, 1.0); } } - - // Counting the time tables - nStackedEvt_++; - if (nStackedEvt_ >= nNSecPerBin_ * nNEvtPerSec_) { // Time to jump! - nStackedBin_++; - nStackedEvt_ = 0; - } } DEFINE_FWK_MODULE(GEMDQMStatusDigi); diff --git a/DQM/HcalCommon/src/HashFunctions.cc b/DQM/HcalCommon/src/HashFunctions.cc index 25026978e84a7..20852315fb819 100644 --- a/DQM/HcalCommon/src/HashFunctions.cc +++ b/DQM/HcalCommon/src/HashFunctions.cc @@ -33,7 +33,12 @@ namespace hcaldqm { uint32_t hash_ieta(HcalDetId const &did) { return utilities::hash(HcalDetId(HcalBarrel, did.ieta(), 1, 1)); } - uint32_t hash_depth(HcalDetId const &did) { return utilities::hash(HcalDetId(HcalBarrel, 1, 1, did.depth())); } + uint32_t hash_depth(HcalDetId const &did) { + if (did.subdet() == HcalOuter) + return 9; // key of map, can be any uint32_t valure that is not a raw hcal detid + else + return utilities::hash(HcalDetId(HcalBarrel, 1, 1, did.depth())); + } uint32_t hash_HFPMiphi(HcalDetId const &did) { return utilities::hash(HcalDetId(HcalForward, did.ieta() > 0 ? 1 : -1, did.iphi(), 1)); @@ -169,13 +174,19 @@ namespace hcaldqm { std::string name_depth(HcalDetId const &did) { char name[10]; - sprintf(name, "depth%d", did.depth()); + if (did.subdet() == HcalOuter) + sprintf(name, "depthHO"); + else + sprintf(name, "depth%d", did.depth()); return std::string(name); } uint32_t hash_depth(std::string const &name) { int depth = std::stoi(name.substr(5, name.length() - 5), nullptr); - return HcalDetId(HcalBarrel, 1, 1, depth).rawId(); + if (name.find("HO") != std::string::npos) + return 9; // must match the value in method hash_depth(& digi) + else + return HcalDetId(HcalBarrel, 1, 1, depth).rawId(); } std::string name_HFPMiphi(HcalDetId const &did) { diff --git a/DQM/HcalTasks/python/OfflineSourceSequence_pp.py b/DQM/HcalTasks/python/OfflineSourceSequence_pp.py index 8947a3bbacfa8..0543cf3aae84d 100644 --- a/DQM/HcalTasks/python/OfflineSourceSequence_pp.py +++ b/DQM/HcalTasks/python/OfflineSourceSequence_pp.py @@ -9,13 +9,14 @@ from DQM.HcalTasks.DigiTask import digiTask from DQM.HcalTasks.RawTask import rawTask from DQM.HcalTasks.TPTask import tpTask -from DQM.HcalTasks.RecHitTask import recHitTask +from DQM.HcalTasks.RecHitTask import recHitTask, recHitPreRecoTask # set processing type to Offine digiTask.ptype = cms.untracked.int32(1) tpTask.ptype = cms.untracked.int32(1) recHitTask.ptype = cms.untracked.int32(1) rawTask.ptype = cms.untracked.int32(1) +recHitPreRecoTask.ptype = cms.untracked.int32(1) # set the label for Emulator TP Task tpTask.tagEmul = cms.untracked.InputTag("valHcalTriggerPrimitiveDigis") @@ -26,6 +27,10 @@ +recHitTask +rawTask) +hcalOnlyOfflineSourceSequence = cms.Sequence( + digiTask + +recHitPreRecoTask + +rawTask) from Configuration.Eras.Modifier_phase2_hcal_cff import phase2_hcal _phase2_hcalOfflineSourceSequence = hcalOfflineSourceSequence.copyAndExclude([tpTask,rawTask]) diff --git a/DQM/HcalTasks/python/RecHitTask.py b/DQM/HcalTasks/python/RecHitTask.py index c9133e879fd3b..6663f3905f305 100644 --- a/DQM/HcalTasks/python/RecHitTask.py +++ b/DQM/HcalTasks/python/RecHitTask.py @@ -28,7 +28,9 @@ ) - +recHitPreRecoTask = recHitTask.clone( + tagHBHE = cms.untracked.InputTag("hbheprereco") +) diff --git a/DQM/Integration/python/clients/beam_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/beam_dqm_sourceclient-live_cfg.py index f00578cb86683..8165fdc9b5727 100644 --- a/DQM/Integration/python/clients/beam_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/beam_dqm_sourceclient-live_cfg.py @@ -1,6 +1,10 @@ from __future__ import print_function import FWCore.ParameterSet.Config as cms +# Define here the BeamSpotOnline record name, +# it will be used both in BeamMonitor setup and in payload creation/upload +BSOnlineRecordName = 'BeamSpotOnlineLegacyObjectsRcd' + #from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 #process = cms.Process("BeamMonitor", Run2_2018) FIXME import sys @@ -24,14 +28,23 @@ live=False unitTest=True +# Switch to veto the upload of the BeamSpot conditions to the DB +# when False it performs the upload +noDB = True +if 'noDB=False' in sys.argv: + noDB=False + #--------------- # Input sources if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif live: process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options else: process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options #-------------------------- # HLT Filter @@ -44,6 +57,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'BeamMonitor' process.dqmSaver.tag = 'BeamMonitor' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'BeamMonitor' +process.dqmSaverPB.runNumber = options.runNumber process.dqmEnvPixelLess = process.dqmEnv.clone() process.dqmEnvPixelLess.subSystemFolder = 'BeamMonitor_PixelLess' @@ -215,7 +231,7 @@ # process.dqmcommon = cms.Sequence(process.dqmEnv - * process.dqmSaver) + * process.dqmSaver*process.dqmSaverPB) # process.monitor = cms.Sequence(process.dqmBeamMonitor @@ -281,6 +297,7 @@ process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") process.dqmBeamMonitor.OnlineMode = True +process.dqmBeamMonitor.recordName = BSOnlineRecordName process.dqmBeamMonitor.resetEveryNLumi = 5 # was 10 for HI process.dqmBeamMonitor.resetPVEveryNLumi = 5 # was 10 for HI @@ -333,6 +350,36 @@ process.dqmBeamMonitor.hltResults = cms.InputTag("TriggerResults","","HLT") +#--------- +# Upload BeamSpotOnlineObject (LegacyRcd) to CondDB +process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", + + DBParameters = cms.PSet( + messageLevel = cms.untracked.int32(0), + authenticationPath = cms.untracked.string('') + ), + + # Upload to CondDB + connect = cms.string('oracle://cms_orcoff_prep/CMS_CONDITIONS'), + preLoadConnectionString = cms.untracked.string('frontier://FrontierPrep/CMS_CONDITIONS'), + + runNumber = cms.untracked.uint64(options.runNumber), + lastLumiFile = cms.untracked.string(''), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), + autoCommit = cms.untracked.bool(True), + toPut = cms.VPSet(cms.PSet( + record = cms.string(BSOnlineRecordName), + tag = cms.string('BSOnlineLegacy_tag'), + timetype = cms.untracked.string('Lumi'), + onlyAppendUpdatePolicy = cms.untracked.bool(True) + )) +) + +# If not live or noDB: produce a (local) SQLITE file +if not live or noDB: + process.OnlineDBOutputService.connect = cms.string('sqlite_file:BeamSpotOnlineLegacy.db') + process.OnlineDBOutputService.preLoadConnectionString = cms.untracked.string('sqlite_file:BeamSpotOnlineLegacy.db') + #--------- # Final path if (not process.runType.getRunType() == process.runType.hi_run): diff --git a/DQM/Integration/python/clients/beamfake_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/beamfake_dqm_sourceclient-live_cfg.py new file mode 100644 index 0000000000000..1b43b59417963 --- /dev/null +++ b/DQM/Integration/python/clients/beamfake_dqm_sourceclient-live_cfg.py @@ -0,0 +1,184 @@ +from __future__ import print_function +import FWCore.ParameterSet.Config as cms +import time + +# Define here the BeamSpotOnline record name, +# it will be used both in FakeBeamMonitor setup and in payload creation/upload +BSOnlineRecordName = 'BeamSpotOnlineLegacyObjectsRcd' + +import sys +from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 +process = cms.Process("FakeBeamMonitor", Run2_2018) + +# +process.MessageLogger = cms.Service("MessageLogger", + debugModules = cms.untracked.vstring('*'), + cerr = cms.untracked.PSet( + threshold = cms.untracked.string('WARNING') + ), + destinations = cms.untracked.vstring('cerr') +) + +# switch +live = True # FIXME +unitTest = False + +if 'unitTest=True' in sys.argv: + live=False + unitTest=True +else: + time.sleep(48.) + +#--------------- +# Input sources +if unitTest: + process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options +elif live: + process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options +else: + process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options + +#-------------------------- +# HLT Filter +process.hltTriggerTypeFilter = cms.EDFilter("HLTTriggerTypeFilter", + SelectedTriggerType = cms.int32(1) # physics +) + +#---------------------------- +# DQM Live Environment +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = 'FakeBeamMonitor' +process.dqmSaver.tag = 'FakeBeamMonitor' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'FakeBeamMonitor' +process.dqmSaverPB.runNumber = options.runNumber + + +#--------------- +# Conditions +if (live): + process.load("DQM.Integration.config.FrontierCondition_GT_cfi") +else: + process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + from Configuration.AlCa.GlobalTag import GlobalTag as gtCustomise + process.GlobalTag = gtCustomise(process.GlobalTag, 'auto:run2_data', '') + # you may need to set manually the GT in the line below + process.GlobalTag.globaltag = '100X_upgrade2018_realistic_v10' + +#---------------------------- +# BeamMonitor +process.load("DQM.BeamMonitor.FakeBeamMonitor_cff") + + +#---------------- +# Setup tracking +process.load("Configuration.StandardSequences.GeometryRecoDB_cff") +#process.load('Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff') +#process.load("Configuration.StandardSequences.RawToDigi_Data_cff") +#process.load("RecoLocalTracker.Configuration.RecoLocalTracker_cff") +#process.load("TrackingTools.TransientTrack.TransientTrackBuilder_cfi") + +#----------------- + +process.dqmcommon = cms.Sequence(process.dqmEnv + * process.dqmSaver*process.dqmSaverPB) + +# +process.monitor = cms.Sequence(process.dqmFakeBeamMonitor + ) + +#------------------------ +# Process customizations +from DQM.Integration.config.online_customizations_cfi import * +process = customise(process) + +#------------------------ +# Set rawDataRepacker (HI and live) or rawDataCollector (for all the rest) +if (process.runType.getRunType() == process.runType.hi_run and live): + rawDataInputTag = cms.InputTag("rawDataRepacker") +else: + rawDataInputTag = cms.InputTag("rawDataCollector") + +""" process.castorDigis.InputLabel = rawDataInputTag +process.csctfDigis.producer = rawDataInputTag +process.dttfDigis.DTTF_FED_Source = rawDataInputTag +process.ecalDigis.InputLabel = rawDataInputTag +process.ecalPreshowerDigis.sourceTag = rawDataInputTag +process.gctDigis.inputLabel = rawDataInputTag +process.gtDigis.DaqGtInputTag = rawDataInputTag +process.hcalDigis.InputLabel = rawDataInputTag +process.muonCSCDigis.InputObjects = rawDataInputTag +process.muonDTDigis.inputLabel = rawDataInputTag +process.muonRPCDigis.InputLabel = rawDataInputTag +process.scalersRawToDigi.scalersInputTag = rawDataInputTag +process.siPixelDigis.InputLabel = rawDataInputTag +process.siStripDigis.ProductLabel = rawDataInputTag + """ +process.dqmFakeBeamMonitor.OnlineMode = True +process.dqmFakeBeamMonitor.recordName = BSOnlineRecordName + +process.dqmFakeBeamMonitor.resetEveryNLumi = 5 # was 10 for HI +process.dqmFakeBeamMonitor.resetPVEveryNLumi = 5 # was 10 for HI + + + +#--------- +# Upload BeamSpotOnlineObject (LegacyRcd) to CondDB +if unitTest == False: + process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", + + DBParameters = cms.PSet( + messageLevel = cms.untracked.int32(0), + authenticationPath = cms.untracked.string('.') + ), + + # Upload to CondDB + connect = cms.string('oracle://cms_orcon_prod/CMS_CONDITIONS'), + preLoadConnectionString = cms.untracked.string('frontier://FrontierProd/CMS_CONDITIONS'), + + runNumber = cms.untracked.uint64(options.runNumber), + #lastLumiFile = cms.untracked.string('last_lumi.txt'), + lastLumiUrl = cms.untracked.string('http://ru-c2e14-11-01.cms:11100/urn:xdaq-application:lid=52/getLatestLumiSection'), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), + latency = cms.untracked.uint32(2), + autoCommit = cms.untracked.bool(True), + toPut = cms.VPSet(cms.PSet( + record = cms.string(BSOnlineRecordName), + tag = cms.string('BeamSpotOnlineTestLegacy'), + timetype = cms.untracked.string('Lumi'), + onlyAppendUpdatePolicy = cms.untracked.bool(True) + )) + ) +else: + process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", + + DBParameters = cms.PSet( + messageLevel = cms.untracked.int32(0), + authenticationPath = cms.untracked.string('.') + ), + + # Upload to CondDB + connect = cms.string('sqlite_file:BeamSpotOnlineLegacy.db'), + preLoadConnectionString = cms.untracked.string('sqlite_file:BeamSpotOnlineLegacy.db'), + runNumber = cms.untracked.uint64(options.runNumber), + lastLumiFile = cms.untracked.string('last_lumi.txt'), + #lastLumiUrl = cms.untracked.string('http://ru-c2e14-11-01.cms:11100/urn:xdaq-application:lid=52/getLatestLumiSection'), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), + latency = cms.untracked.uint32(2), + autoCommit = cms.untracked.bool(True), + toPut = cms.VPSet(cms.PSet( + record = cms.string(BSOnlineRecordName), + tag = cms.string('BeamSpotOnlineTestLegacy'), + timetype = cms.untracked.string('Lumi'), + onlyAppendUpdatePolicy = cms.untracked.bool(True) + )) + ) + +#--------- +# Final path +process.p = cms.Path(process.dqmcommon + * process.monitor + ) diff --git a/DQM/Integration/python/clients/beamhlt_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/beamhlt_dqm_sourceclient-live_cfg.py index 23cd31b6a449c..1a2cf04024868 100644 --- a/DQM/Integration/python/clients/beamhlt_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/beamhlt_dqm_sourceclient-live_cfg.py @@ -1,6 +1,10 @@ from __future__ import print_function import FWCore.ParameterSet.Config as cms +# Define once the BeamSpotOnline record name, +# will be used both in BeamMonitor setup and in payload creation/upload +BSOnlineRecordName = 'BeamSpotOnlineHLTObjectsRcd' + #from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 #process = cms.Process("BeamMonitor", Run2_2018) # FIMXE import sys @@ -25,19 +29,28 @@ if 'unitTest=True' in sys.argv: unitTest=True +# Switch to veto the upload of the BeamSpot conditions to the DB +# when False it performs the upload +noDB = True +if 'noDB=False' in sys.argv: + noDB=False + # Common part for PP and H.I Running #----------------------------- if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # new stream label process.source.streamLabel = cms.untracked.string('streamDQMOnlineBeamspot') # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #-------------------------- # HLT Filter @@ -53,6 +66,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'TrackingHLTBeamspotStream' process.dqmSaver.tag = 'TrackingHLTBeamspotStream' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'TrackingHLTBeamspotStream' +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- # BeamMonitor @@ -81,7 +97,7 @@ process.dqmBeamMonitor.BeamFitter.DIPFileName = '/nfshome0/dqmdev/BeamMonitorDQM/BeamFitResults.txt' process.dqmcommon = cms.Sequence(process.dqmEnv - * process.dqmSaver) + * process.dqmSaver*process.dqmSaverPB) process.monitor = cms.Sequence(process.dqmBeamMonitor) @@ -108,6 +124,7 @@ process.dqmBeamMonitor.monitorName = 'TrackingHLTBeamspotStream' process.dqmBeamMonitor.OnlineMode = True + process.dqmBeamMonitor.recordName = BSOnlineRecordName process.dqmBeamMonitor.resetEveryNLumi = 5 process.dqmBeamMonitor.resetPVEveryNLumi = 5 @@ -137,6 +154,36 @@ process.dqmBeamMonitor.hltResults = cms.InputTag("TriggerResults","","HLT") + #--------- + # Upload BeamSpotOnlineObject (HLTRcd) to CondDB + process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", + + DBParameters = cms.PSet( + messageLevel = cms.untracked.int32(0), + authenticationPath = cms.untracked.string('') + ), + + # Upload to CondDB + connect = cms.string('oracle://cms_orcoff_prep/CMS_CONDITIONS'), + preLoadConnectionString = cms.untracked.string('frontier://FrontierPrep/CMS_CONDITIONS'), + + runNumber = cms.untracked.uint64(options.runNumber), + lastLumiFile = cms.untracked.string(''), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), + autoCommit = cms.untracked.bool(True), + toPut = cms.VPSet(cms.PSet( + record = cms.string(BSOnlineRecordName), + tag = cms.string('BSOnlineHLT_tag'), + timetype = cms.untracked.string('Lumi'), + onlyAppendUpdatePolicy = cms.untracked.bool(True) + )) + ) + + # If not live or noDB: produce a (local) SQLITE file + if unitTest or noDB: + process.OnlineDBOutputService.connect = cms.string('sqlite_file:BeamSpotOnlineHLT.db') + process.OnlineDBOutputService.preLoadConnectionString = cms.untracked.string('sqlite_file:BeamSpotOnlineHLT.db') + process.p = cms.Path( process.hltTriggerTypeFilter * process.dqmcommon * process.offlineBeamSpot diff --git a/DQM/Integration/python/clients/beamhltfake_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/beamhltfake_dqm_sourceclient-live_cfg.py new file mode 100644 index 0000000000000..c766db3d63e81 --- /dev/null +++ b/DQM/Integration/python/clients/beamhltfake_dqm_sourceclient-live_cfg.py @@ -0,0 +1,133 @@ +from __future__ import print_function +import FWCore.ParameterSet.Config as cms + +# Define here the BeamSpotOnline record name, +# it will be used both in FakeBeamMonitor setup and in payload creation/upload +BSOnlineRecordName = 'BeamSpotOnlineHLTObjectsRcd' + +import sys +from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 +process = cms.Process("FakeBeamMonitor", Run2_2018) + + +unitTest=False +if 'unitTest=True' in sys.argv: + unitTest=True + + + +# Common part for PP and H.I Running +#----------------------------- +if unitTest: + process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options +else: + # for live online DQM in P5 + process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options + + # new stream label + process.source.streamLabel = cms.untracked.string('streamDQMOnlineBeamspot') + +# for testing in lxplus +#process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options + +#-------------------------- +# HLT Filter +# 0=random, 1=physics, 2=calibration, 3=technical +#-------------------------- +process.hltTriggerTypeFilter = cms.EDFilter("HLTTriggerTypeFilter", + SelectedTriggerType = cms.int32(1) +) + +#----------------------------- +# DQM Live Environment +#----------------------------- +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = 'FakeBeamMonitor' +process.dqmSaver.tag = 'FakeBeamMonitor' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'FakeBeamMonitor' +process.dqmSaverPB.runNumber = options.runNumber + +#----------------------------- +# BeamMonitor +#----------------------------- +process.load("DQM.BeamMonitor.FakeBeamMonitor_cff") +process.dqmBeamMonitor = process.dqmFakeBeamMonitor.clone() + +#--------------- +# Calibration +#--------------- +# Condition for P5 cluster +process.load("DQM.Integration.config.FrontierCondition_GT_cfi") +process.dqmcommon = cms.Sequence(process.dqmEnv + * process.dqmSaver*process.dqmSaverPB) + +process.monitor = cms.Sequence(process.dqmBeamMonitor) + +#----------------------------------------------------------- +# process customizations included here +from DQM.Integration.config.online_customizations_cfi import * +process = customise(process) + +process.dqmBeamMonitor.monitorName = 'TrackingHLTBeamspotStream' +process.dqmBeamMonitor.OnlineMode = True +process.dqmBeamMonitor.recordName = BSOnlineRecordName + +process.dqmBeamMonitor.resetEveryNLumi = 5 +process.dqmBeamMonitor.resetPVEveryNLumi = 5 + +#--------- +# Upload BeamSpotOnlineObject (HLTRcd) to CondDB +if unitTest == False: + process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", + + DBParameters = cms.PSet( + messageLevel = cms.untracked.int32(0), + authenticationPath = cms.untracked.string('') + ), + + # Upload to CondDB + connect = cms.string('oracle://cms_orcon_prod/CMS_CONDITIONS'), + preLoadConnectionString = cms.untracked.string('frontier://FrontierProd/CMS_CONDITIONS'), + runNumber = cms.untracked.uint64(options.runNumber), + #lastLumiFile = cms.untracked.string('last_lumi.txt'), + lastLumiUrl = cms.untracked.string('http://ru-c2e14-11-01.cms:11100/urn:xdaq-application:lid=52/getLatestLumiSection'), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), + autoCommit = cms.untracked.bool(True), + toPut = cms.VPSet(cms.PSet( + record = cms.string(BSOnlineRecordName), + tag = cms.string('BeamSpotOnlineTestHLT'), + timetype = cms.untracked.string('Lumi'), + onlyAppendUpdatePolicy = cms.untracked.bool(True) + )) + ) + +else: + process.OnlineDBOutputService = cms.Service("OnlineDBOutputService", + DBParameters = cms.PSet( + messageLevel = cms.untracked.int32(0), + authenticationPath = cms.untracked.string('') + ), + + # Upload to CondDB + connect = cms.string('sqlite_file:BeamSpotOnlineHLT.db'), + preLoadConnectionString = cms.untracked.string('sqlite_file:BeamSpotOnlineHLT.db'), + + runNumber = cms.untracked.uint64(options.runNumber), + lastLumiFile = cms.untracked.string('last_lumi.txt'), + #lastLumiUrl = cms.untracked.string('http://ru-c2e14-11-01.cms:11100/urn:xdaq-application:lid=52/getLatestLumiSection'), + writeTransactionDelay = cms.untracked.uint32(options.transDelay), + autoCommit = cms.untracked.bool(True), + toPut = cms.VPSet(cms.PSet( + record = cms.string(BSOnlineRecordName), + tag = cms.string('BeamSpotOnlineTestHLT'), + timetype = cms.untracked.string('Lumi'), + onlyAppendUpdatePolicy = cms.untracked.bool(True) + )) +) + +process.p = cms.Path(process.dqmcommon + * process.monitor ) diff --git a/DQM/Integration/python/clients/beampixel_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/beampixel_dqm_sourceclient-live_cfg.py index 21fe8349e17ac..54e2b33584f49 100644 --- a/DQM/Integration/python/clients/beampixel_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/beampixel_dqm_sourceclient-live_cfg.py @@ -15,11 +15,13 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: process.load("DQM.Integration.config.inputsource_cfi") - + from DQM.Integration.config.inputsource_cfi import options # Use this to run locally (for testing purposes) #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- @@ -35,7 +37,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "BeamPixel" process.dqmSaver.tag = "BeamPixel" - +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'BeamPixel' +process.dqmSaverPB.runNumber = options.runNumber #---------------------------- # Conditions @@ -59,7 +63,7 @@ #---------------------------- # Define Sequences #---------------------------- -process.dqmModules = cms.Sequence(process.dqmEnv + process.dqmSaver) +process.dqmModules = cms.Sequence(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.physTrigger = cms.Sequence(process.hltTriggerTypeFilter) diff --git a/DQM/Integration/python/clients/bril_dqm_clientPB-live_cfg.py b/DQM/Integration/python/clients/bril_dqm_clientPB-live_cfg.py index 06791087354c5..2331672926f56 100644 --- a/DQM/Integration/python/clients/bril_dqm_clientPB-live_cfg.py +++ b/DQM/Integration/python/clients/bril_dqm_clientPB-live_cfg.py @@ -9,6 +9,7 @@ #---------------------------- # for live online DQM in P5 process.load("DQM.Integration.config.pbsource_cfi") +from DQM.Integration.config.pbsource_cfi import options process.source.loadFiles = cms.untracked.bool(False) process.source.streamLabel = cms.untracked.string("streamDQMPLT") process.source.nextLumiTimeoutMillis = cms.untracked.int32(500) @@ -20,6 +21,9 @@ process.dqmEnv.subSystemFolder = 'BRIL' process.dqmEnv.eventInfoFolder = 'EventInfo' process.dqmSaver.tag = 'BRIL' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'BRIL' +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- if process.dqmRunConfig.type.value() == "production": @@ -34,6 +38,6 @@ process.BrilClient = DQMEDHarvester("BrilClient") process.bril_path = cms.Path(process.BrilClient) -process.p = cms.EndPath(process.dqmEnv + process.dqmSaver) +process.p = cms.EndPath(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.schedule = cms.Schedule(process.bril_path, process.p) diff --git a/DQM/Integration/python/clients/castor_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/castor_dqm_sourceclient-live_cfg.py index be950c36dfe68..4fe412c28d432 100644 --- a/DQM/Integration/python/clients/castor_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/castor_dqm_sourceclient-live_cfg.py @@ -14,12 +14,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #================================ # DQM Environment @@ -30,6 +33,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "Castor" process.dqmSaver.tag = "Castor" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "Castor" +process.dqmSaverPB.runNumber = options.runNumber process.load("FWCore.MessageLogger.MessageLogger_cfi") @@ -116,9 +122,9 @@ # castorreco -> CastorSimpleReconstructor_cfi # castorMonitor -> CastorMonitorModule_cfi -process.p = cms.Path(process.castorDigis*process.castorreco*process.castorMonitor*process.dqmEnv*process.dqmSaver) -#process.p = cms.Path(process.castorDigis*process.castorMonitor*process.dqmEnv*process.dqmSaver) -#process.p = cms.Path(process.castorMonitor*process.dqmEnv*process.dqmSaver) +process.p = cms.Path(process.castorDigis*process.castorreco*process.castorMonitor*process.dqmEnv*process.dqmSaver*process.dqmSaverPB) +#process.p = cms.Path(process.castorDigis*process.castorMonitor*process.dqmEnv*process.dqmSaver*process.dqmSaverPB) +#process.p = cms.Path(process.castorMonitor*process.dqmEnv*process.dqmSaver*process.dqmSaverPB) process.castorDigis.InputLabel = cms.InputTag("rawDataCollector") diff --git a/DQM/Integration/python/clients/csc_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/csc_dqm_sourceclient-live_cfg.py index 16c974787d571..77b1e6b88b699 100644 --- a/DQM/Integration/python/clients/csc_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/csc_dqm_sourceclient-live_cfg.py @@ -40,12 +40,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Environment @@ -58,6 +61,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "CSC" process.dqmSaver.tag = "CSC" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "CSC" +process.dqmSaverPB.runNumber = options.runNumber #process.DQM.collectorHost = 'pccmsdqm02.cern.ch' @@ -166,8 +172,8 @@ # Sequences #-------------------------- -#process.p = cms.Path(process.dqmCSCClient+process.dqmEnv+process.dqmSaver) -process.p = cms.Path(process.dqmCSCClient * process.muonCSCDigis * process.csc2DRecHits * process.cscSegments * process.cscMonitor + process.dqmEnv + process.dqmSaver) +#process.p = cms.Path(process.dqmCSCClient+process.dqmEnv+process.dqmSaver+process.dqmSaverPB) +process.p = cms.Path(process.dqmCSCClient * process.muonCSCDigis * process.csc2DRecHits * process.cscSegments * process.cscMonitor + process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.castorDigis.InputLabel = cms.InputTag("rawDataCollector") diff --git a/DQM/Integration/python/clients/ctpps_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/ctpps_dqm_sourceclient-live_cfg.py index 23d5aa07d2bee..ca590a35ef5ab 100644 --- a/DQM/Integration/python/clients/ctpps_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/ctpps_dqm_sourceclient-live_cfg.py @@ -13,12 +13,15 @@ # event source if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif not test: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options else: # for testing in lxplus process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options process.source.fileNames = cms.untracked.vstring( #"root://eoscms.cern.ch//eos/cms/store/group/phys_pps/sw_test_input/001D08EE-C4B1-E711-B92D-02163E013864.root" #"/store/express/Run2016H/ExpressPhysics/FEVT/Express-v2/000/283/877/00000/4EE44B0E-2499-E611-A155-02163E011938.root" @@ -33,9 +36,13 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'CTPPS' process.dqmSaver.tag = 'CTPPS' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'CTPPS' +process.dqmSaverPB.runNumber = options.runNumber if test: process.dqmSaver.path = "." + process.dqmSaverPB.path = "./pb" process.load("DQMServices.Components.DQMProvInfo_cfi") @@ -87,7 +94,8 @@ #process.dqmModulesCalibration * process.dqmEnv * - process.dqmSaver + process.dqmSaver * + process.dqmSaverPB ) process.schedule = cms.Schedule(process.path) diff --git a/DQM/Integration/python/clients/dt4ml_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/dt4ml_dqm_sourceclient-live_cfg.py index f4229be2ca04d..79e42e625ceae 100644 --- a/DQM/Integration/python/clients/dt4ml_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/dt4ml_dqm_sourceclient-live_cfg.py @@ -14,12 +14,15 @@ #---------------------------- if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- #### DQM Environment @@ -31,6 +34,9 @@ #---------------------------- process.dqmEnv.subSystemFolder = 'DT' process.dqmSaver.tag = "DT" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "DT" +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- ### CUSTOMIZE FOR ML @@ -47,6 +53,7 @@ if not unitTest: process.dqmSaver.path = filePath + process.dqmSaverPB.path = filePath + "/pb" # disable DQM gui print("old:",process.DQM.collectorHost) @@ -70,7 +77,7 @@ cout = cms.untracked.PSet(threshold = cms.untracked.string('WARNING')) ) -process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver) +process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.dtDQMPathPhys = cms.Path(process.unpackers + process.dqmmodules + process.physicsEventsFilter * process.dtDQMPhysSequence) diff --git a/DQM/Integration/python/clients/dt_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/dt_dqm_sourceclient-live_cfg.py index 7b95a315ff947..694534ef1c879 100644 --- a/DQM/Integration/python/clients/dt_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/dt_dqm_sourceclient-live_cfg.py @@ -13,12 +13,15 @@ #---------------------------- if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- #### DQM Environment @@ -30,6 +33,9 @@ #---------------------------- process.dqmEnv.subSystemFolder = 'DT' process.dqmSaver.tag = "DT" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "DT" +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- #Enable HLT*Mu* filtering to monitor on Muon events @@ -53,7 +59,7 @@ cout = cms.untracked.PSet(threshold = cms.untracked.string('WARNING')) ) -process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver) +process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.dtDQMPathPhys = cms.Path(process.unpackers + process.dqmmodules + process.physicsEventsFilter * process.dtDQMPhysSequence) diff --git a/DQM/Integration/python/clients/ecal_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/ecal_dqm_sourceclient-live_cfg.py index f5f13a9465e38..0c692470fc983 100644 --- a/DQM/Integration/python/clients/ecal_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/ecal_dqm_sourceclient-live_cfg.py @@ -13,8 +13,11 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options + process.load("DQM.Integration.config.environment_cfi") process.load("DQM.Integration.config.FrontierCondition_GT_cfi") #process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") @@ -107,6 +110,9 @@ process.dqmEnv.subSystemFolder = cms.untracked.string('Ecal') process.dqmSaver.tag = cms.untracked.string('Ecal') +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = cms.untracked.string('Ecal') +process.dqmSaverPB.runNumber = options.runNumber process.simEcalTriggerPrimitiveDigis.InstanceEB = "ebDigis" process.simEcalTriggerPrimitiveDigis.InstanceEE = "eeDigis" @@ -137,7 +143,7 @@ process.ecalClientPath = cms.Path(process.preScaler+process.ecalPreRecoSequence+process.ecalPhysicsFilter+process.ecalMonitorClient) process.dqmEndPath = cms.EndPath(process.dqmEnv) -process.dqmOutputPath = cms.EndPath(process.dqmSaver) +process.dqmOutputPath = cms.EndPath(process.dqmSaver + process.dqmSaverPB) ### Schedule ### diff --git a/DQM/Integration/python/clients/ecalcalib_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/ecalcalib_dqm_sourceclient-live_cfg.py index 8b386cad7c9c9..75d1e29330647 100644 --- a/DQM/Integration/python/clients/ecalcalib_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/ecalcalib_dqm_sourceclient-live_cfg.py @@ -23,6 +23,7 @@ process.load("FWCore.Modules.preScaler_cfi") process.load("DQM.Integration.config.FrontierCondition_GT_cfi") process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options ### Individual module setups ### @@ -187,6 +188,9 @@ process.dqmEnv.subSystemFolder = cms.untracked.string('EcalCalibration') process.dqmSaver.tag = cms.untracked.string('EcalCalibration') +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = cms.untracked.string('EcalCalibration') +process.dqmSaverPB.runNumber = options.runNumber ### Sequences ### @@ -201,7 +205,7 @@ process.ecalClientPath = cms.Path(process.ecalCalibMonitorClient) process.dqmEndPath = cms.EndPath(process.dqmEnv) -process.dqmOutputPath = cms.EndPath(process.dqmSaver) +process.dqmOutputPath = cms.EndPath(process.dqmSaver + process.dqmSaverPB) ### Schedule ### diff --git a/DQM/Integration/python/clients/es_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/es_dqm_sourceclient-live_cfg.py index 26699561b7c6d..dc213b817ac26 100644 --- a/DQM/Integration/python/clients/es_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/es_dqm_sourceclient-live_cfg.py @@ -14,12 +14,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options # Condition for P5 cluster process.load("DQM.Integration.config.FrontierCondition_GT_cfi") @@ -51,8 +54,12 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'EcalPreshower' process.dqmSaver.tag = 'EcalPreshower' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'EcalPreshower' +process.dqmSaverPB.runNumber = options.runNumber # for local test #process.dqmSaver.path = '.' +#process.dqmSaverPB.path = './pb' process.load("DQM/EcalPreshowerMonitorModule/EcalPreshowerMonitorTasks_cfi") process.ecalPreshowerIntegrityTask.ESDCCCollections = cms.InputTag("esRawToDigi") @@ -73,7 +80,8 @@ process.ecalPreshowerDefaultTasksSequence* process.dqmEnv* process.ecalPreshowerMonitorClient* - process.dqmSaver) + process.dqmSaver* + process.dqmSaverPB) process.esRawToDigi.sourceTag = cms.InputTag("rawDataCollector") diff --git a/DQM/Integration/python/clients/fed_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/fed_dqm_sourceclient-live_cfg.py index 4178e6ac33974..6feff0263b749 100644 --- a/DQM/Integration/python/clients/fed_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/fed_dqm_sourceclient-live_cfg.py @@ -25,11 +25,16 @@ # Input: if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: process.load('DQM.Integration.config.inputsource_cfi') + from DQM.Integration.config.inputsource_cfi import options # Output: process.dqmEnv.subSystemFolder = 'FED' process.dqmSaver.tag = 'FED' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'FED' +process.dqmSaverPB.runNumber = options.runNumber # Subsystem sequences @@ -142,6 +147,7 @@ process.DQMmodulesPath = cms.Path( process.dqmEnv + process.dqmSaver + + process.dqmSaverPB ) process.schedule = cms.Schedule( diff --git a/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py index 35ab42c368bbf..9c9e3bef8152f 100644 --- a/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/gem_dqm_sourceclient-live_cfg.py @@ -1,7 +1,8 @@ import FWCore.ParameterSet.Config as cms import sys -process = cms.Process('GEMDQM') +from Configuration.StandardSequences.Eras import eras +process = cms.Process('GEMDQM', eras.Run3) unitTest = False if 'unitTest=True' in sys.argv: @@ -10,14 +11,19 @@ process.load('Configuration.StandardSequences.GeometryRecoDB_cff') process.load("DQM.Integration.config.FrontierCondition_GT_cfi") -process.load("DQM.Integration.config.environment_cfi") -process.dqmEnv.subSystemFolder = "GEM" -process.dqmSaver.tag = "GEM" - if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options + +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = "GEM" +process.dqmSaver.tag = "GEM" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "GEM" +process.dqmSaverPB.runNumber = options.runNumber process.load("DQMServices.Components.DQMProvInfo_cfi") @@ -40,7 +46,8 @@ process.end_path = cms.EndPath( process.dqmEnv + - process.dqmSaver + process.dqmSaver + + process.dqmSaverPB ) process.schedule = cms.Schedule( diff --git a/DQM/Integration/python/clients/hcal_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/hcal_dqm_sourceclient-live_cfg.py index aecd025050d13..edaa76e383957 100644 --- a/DQM/Integration/python/clients/hcal_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/hcal_dqm_sourceclient-live_cfg.py @@ -40,10 +40,13 @@ process.load('DQM.Integration.config.FrontierCondition_GT_cfi') if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif useFileInput: process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options else: process.load('DQM.Integration.config.inputsource_cfi') + from DQM.Integration.config.inputsource_cfi import options process.load('DQM.Integration.config.environment_cfi') #------------------------------------- @@ -51,6 +54,9 @@ #------------------------------------- process.dqmEnv.subSystemFolder = subsystem process.dqmSaver.tag = subsystem +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = subsystem +process.dqmSaverPB.runNumber = options.runNumber process = customise(process) process.DQMStore.verbose = 0 if not useFileInput and not unitTest: @@ -224,6 +230,7 @@ process.dqmEnv) process.dqmPath1 = cms.EndPath( process.dqmSaver + *process.dqmSaverPB ) process.qtPath = cms.Path(process.hcalQualityTests) diff --git a/DQM/Integration/python/clients/hcalcalib_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/hcalcalib_dqm_sourceclient-live_cfg.py index a9bb01df7ee0b..4d758939046c5 100644 --- a/DQM/Integration/python/clients/hcalcalib_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/hcalcalib_dqm_sourceclient-live_cfg.py @@ -34,8 +34,10 @@ process.load('DQM.Integration.config.FrontierCondition_GT_cfi') if useFileInput: process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options else: process.load('DQM.Integration.config.inputsource_cfi') + from DQM.Integration.config.inputsource_cfi import options process.load('DQM.Integration.config.environment_cfi') #------------------------------------- @@ -45,6 +47,9 @@ process.source.SelectEvents = cms.untracked.vstring("*HcalCalibration*") process.dqmEnv.subSystemFolder = subsystem process.dqmSaver.tag = subsystem +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = subsystem +process.dqmSaverPB.runNumber = options.runNumber process = customise(process) if not useFileInput: process.source.minEventsPerLumi=100 diff --git a/DQM/Integration/python/clients/hcalreco_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/hcalreco_dqm_sourceclient-live_cfg.py index 36ae2ccf1d931..ade744cd8cff7 100644 --- a/DQM/Integration/python/clients/hcalreco_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/hcalreco_dqm_sourceclient-live_cfg.py @@ -49,10 +49,13 @@ process.load('DQM.Integration.config.FrontierCondition_GT_cfi') if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif useFileInput: process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options else: process.load('DQM.Integration.config.inputsource_cfi') + from DQM.Integration.config.inputsource_cfi import options process.load('DQM.Integration.config.environment_cfi') #------------------------------------- @@ -60,6 +63,9 @@ #------------------------------------- process.dqmEnv.subSystemFolder = subsystem process.dqmSaver.tag = "HcalReco" # to have a file saved as DQM_V..._HcalReco... +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "HcalReco" +process.dqmSaverPB.runNumber = options.runNumber process = customise(process) process.DQMStore.verbose = 0 if not useFileInput and not unitTest: @@ -169,6 +175,7 @@ process.dqmPath = cms.Path( process.dqmEnv *process.dqmSaver + *process.dqmSaverPB ) process.schedule = cms.Schedule( diff --git a/DQM/Integration/python/clients/hlt_dqm_clientPB-live_cfg.py b/DQM/Integration/python/clients/hlt_dqm_clientPB-live_cfg.py index 1e61542caf5c9..f087dacc754cf 100644 --- a/DQM/Integration/python/clients/hlt_dqm_clientPB-live_cfg.py +++ b/DQM/Integration/python/clients/hlt_dqm_clientPB-live_cfg.py @@ -13,9 +13,11 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.pbsource_cfi") + from DQM.Integration.config.pbsource_cfi import options #---------------------------- #### DQM Environment @@ -25,6 +27,9 @@ process.dqmEnv.eventInfoFolder = 'EventInfo' process.dqmSaver.tag = 'HLTpb' #process.dqmSaver.path = './HLT' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'HLTpb' +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- # customise for playback @@ -81,4 +86,4 @@ process.psChecker = process.psMonitorClient.clone() -process.p = cms.EndPath( process.fastTimerServiceClient + process.throughputServiceClient + process.psColumnVsLumi + process.psChecker + process.dqmEnv + process.dqmSaver ) +process.p = cms.EndPath( process.fastTimerServiceClient + process.throughputServiceClient + process.psColumnVsLumi + process.psChecker + process.dqmEnv + process.dqmSaver + process.dqmSaverPB ) diff --git a/DQM/Integration/python/clients/hlt_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/hlt_dqm_sourceclient-live_cfg.py index c20211e74264c..c2203f1eeb50b 100644 --- a/DQM/Integration/python/clients/hlt_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/hlt_dqm_sourceclient-live_cfg.py @@ -10,14 +10,17 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # used in the old input source #process.DQMEventStreamHttpReader.SelectHLTOutput = cms.untracked.string('hltOutputHLTDQM') # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #process.maxEvents = cms.untracked.PSet( # input = cms.untracked.int32(100) @@ -27,6 +30,9 @@ process.dqmEnv.subSystemFolder = 'HLT' process.dqmSaver.tag = 'HLT' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'HLT' +process.dqmSaverPB.runNumber = options.runNumber process.load("Configuration.StandardSequences.GeometryRecoDB_cff") process.load("Configuration.StandardSequences.MagneticField_cff") @@ -123,7 +129,7 @@ #process.p = cms.EndPath(process.hlts+process.hltsClient) -process.pp = cms.Path(process.dqmEnv+process.dqmSaver) +process.pp = cms.Path(process.dqmEnv+process.dqmSaver+process.dqmSaverPB) #process.hltResults.plotAll = True diff --git a/DQM/Integration/python/clients/hltrates_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/hltrates_dqm_sourceclient-live_cfg.py index b0f793f9af4f5..b9c2b39d095f0 100644 --- a/DQM/Integration/python/clients/hltrates_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/hltrates_dqm_sourceclient-live_cfg.py @@ -9,6 +9,7 @@ #### leave the following few lines uncommented for online running process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options process.load("DQM.Integration.config.environment_cfi") #process.DQMEventStreamHttpReader.SelectHLTOutput = cms.untracked.string('hltOutputHLTDQMResults') @@ -34,6 +35,9 @@ # old, not used process.dqmSaver.tag = "HLTRates" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'HLTRates' +process.dqmSaverPB.runNumber = options.runNumber #process.load("Configuration.StandardSequences.GeometryPilot2_cff") #process.load("Configuration.StandardSequences.MagneticField_cff") @@ -100,7 +104,7 @@ process.rateMon = cms.EndPath(process.hltPreTrigResRateMon *process.trRateMon) -process.pp = cms.Path(process.dqmEnv+process.dqmSaver) +process.pp = cms.Path(process.dqmEnv+process.dqmSaver+process.dqmSaverPB) process.dqmEnv.subSystemFolder = 'HLT/TrigResults' #process.hltResults.plotAll = True diff --git a/DQM/Integration/python/clients/hlx_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/hlx_dqm_sourceclient-live_cfg.py index cc9d373042a69..4720023ff4967 100644 --- a/DQM/Integration/python/clients/hlx_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/hlx_dqm_sourceclient-live_cfg.py @@ -7,9 +7,11 @@ ## Input source # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options ## HLX configuration process.load("DQM.HLXMonitor.hlx_dqm_sourceclient_cfi") @@ -24,6 +26,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "HLX" process.dqmSaver.tag= "HLX" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'HLX' +process.dqmSaverPB.runNumber = options.runNumber ## Lumi reference file @@ -38,7 +43,7 @@ qtestOnEndRun = cms.untracked.bool(True) ) -process.p = cms.Path(process.hlxdqmsource*process.hlxQualityTester*process.dqmEnv*process.dqmSaver) +process.p = cms.Path(process.hlxdqmsource*process.hlxQualityTester*process.dqmEnv*process.dqmSaver*process.dqmSaverPB) ### process customizations included here from DQM.Integration.config.online_customizations_cfi import * diff --git a/DQM/Integration/python/clients/info_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/info_dqm_sourceclient-live_cfg.py index b208d59476190..5fc5b9570c487 100644 --- a/DQM/Integration/python/clients/info_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/info_dqm_sourceclient-live_cfg.py @@ -18,12 +18,15 @@ #---------------------------- if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options # Global tag - Condition for P5 cluster process.load("DQM.Integration.config.FrontierCondition_GT_cfi") @@ -34,6 +37,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'Info' process.dqmSaver.tag = 'Info' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'Info' +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- # Digitisation: produce the Scalers digis containing DCS bits @@ -50,7 +56,7 @@ process.load("DQMServices.Components.DQMProvInfo_cfi") # DQM Modules -process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver) +process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.evfDQMmodulesPath = cms.Path( process.scalersRawToDigi* process.tcdsDigis* diff --git a/DQM/Integration/python/clients/l1t_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/l1t_dqm_sourceclient-live_cfg.py index 074efa3a1cddc..301a79f2b2865 100644 --- a/DQM/Integration/python/clients/l1t_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/l1t_dqm_sourceclient-live_cfg.py @@ -16,9 +16,11 @@ # # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options # # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Environment @@ -26,6 +28,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'L1T' process.dqmSaver.tag = 'L1T' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'L1T' +process.dqmSaverPB.runNumber = options.runNumber # # references needed @@ -96,7 +101,8 @@ # process.dqmEndPath = cms.EndPath( process.dqmEnv * - process.dqmSaver + process.dqmSaver * + process.dqmSaverPB ) # diff --git a/DQM/Integration/python/clients/l1temulator_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/l1temulator_dqm_sourceclient-live_cfg.py index c72701b50d495..9701c71d14a3c 100644 --- a/DQM/Integration/python/clients/l1temulator_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/l1temulator_dqm_sourceclient-live_cfg.py @@ -16,9 +16,11 @@ # # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options # # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Environment @@ -30,6 +32,9 @@ # for local test process.dqmEnv.subSystemFolder = 'L1TEMU' process.dqmSaver.tag = 'L1TEMU' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'L1TEMU' +process.dqmSaverPB.runNumber = options.runNumber # # no references needed @@ -88,7 +93,7 @@ process.l1EmulatorMonitorClientPath = cms.Path(process.l1EmulatorMonitorClient) # -process.l1EmulatorMonitorEndPath = cms.EndPath(process.dqmEnv*process.dqmSaver) +process.l1EmulatorMonitorEndPath = cms.EndPath(process.dqmEnv*process.dqmSaver*process.dqmSaverPB) # process.valCscTriggerPrimitiveDigis.gangedME1a = cms.untracked.bool(False) diff --git a/DQM/Integration/python/clients/l1tstage1_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/l1tstage1_dqm_sourceclient-live_cfg.py index 3681313b38b61..b8ae0bcf233b4 100644 --- a/DQM/Integration/python/clients/l1tstage1_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/l1tstage1_dqm_sourceclient-live_cfg.py @@ -16,9 +16,11 @@ # # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options # # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Environment @@ -27,6 +29,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'L1TStage1' process.dqmSaver.tag = 'L1TStage1' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'L1TStage1' +process.dqmSaverPB.runNumber = options.runNumber # # references needed @@ -101,7 +106,8 @@ # process.dqmEndPath = cms.EndPath( process.dqmEnv * - process.dqmSaver + process.dqmSaver * + process.dqmSaverPB ) # diff --git a/DQM/Integration/python/clients/l1tstage1emulator_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/l1tstage1emulator_dqm_sourceclient-live_cfg.py index d06d1da8e4e67..6200618c0fe44 100644 --- a/DQM/Integration/python/clients/l1tstage1emulator_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/l1tstage1emulator_dqm_sourceclient-live_cfg.py @@ -16,9 +16,11 @@ # # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options # # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Environment @@ -28,6 +30,9 @@ # for local test process.dqmEnv.subSystemFolder = 'L1TEMUStage1' process.dqmSaver.tag = 'L1TEMUStage1' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'L1TEMUStage1' +process.dqmSaverPB.runNumber = options.runNumber # # no references needed @@ -88,7 +93,7 @@ process.l1EmulatorMonitorClientPath = cms.Path(process.l1EmulatorMonitorClient) # -process.l1EmulatorMonitorEndPath = cms.EndPath(process.dqmEnv*process.dqmSaver) +process.l1EmulatorMonitorEndPath = cms.EndPath(process.dqmEnv*process.dqmSaver*process.dqmSaverPB) # diff --git a/DQM/Integration/python/clients/l1tstage2_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/l1tstage2_dqm_sourceclient-live_cfg.py index 19e6b4c42c88b..c5788228cac1f 100644 --- a/DQM/Integration/python/clients/l1tstage2_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/l1tstage2_dqm_sourceclient-live_cfg.py @@ -1,8 +1,8 @@ import FWCore.ParameterSet.Config as cms import sys -from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 -process = cms.Process("L1TStage2DQM", Run2_2018) +from Configuration.Eras.Era_Run3_cff import Run3 +process = cms.Process("L1TStage2DQM", Run3) unitTest = False if 'unitTest=True' in sys.argv: @@ -13,12 +13,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # Live Online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # # Testing in lxplus # process.load("DQM.Integration.config.fileinputsource_cfi") +# from DQM.Integration.config.fileinputsource_cfi import options # process.load("FWCore.MessageLogger.MessageLogger_cfi") # process.MessageLogger.cerr.FwkReport.reportEvery = 1 @@ -39,8 +42,11 @@ process.dqmEnv.subSystemFolder = "L1T" process.dqmSaver.tag = "L1T" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "L1T" +process.dqmSaverPB.runNumber = options.runNumber -process.dqmEndPath = cms.EndPath(process.dqmEnv * process.dqmSaver) +process.dqmEndPath = cms.EndPath(process.dqmEnv * process.dqmSaver * process.dqmSaverPB) #-------------------------------------------------- # Standard Unpacking Path diff --git a/DQM/Integration/python/clients/l1tstage2emulator_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/l1tstage2emulator_dqm_sourceclient-live_cfg.py index 5817078450839..91f1f564366d0 100644 --- a/DQM/Integration/python/clients/l1tstage2emulator_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/l1tstage2emulator_dqm_sourceclient-live_cfg.py @@ -1,8 +1,8 @@ import FWCore.ParameterSet.Config as cms import sys -from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 -process = cms.Process("L1TStage2EmulatorDQM", Run2_2018) +from Configuration.Eras.Era_Run3_cff import Run3 +process = cms.Process("L1TStage2EmulatorDQM", Run3) unitTest = False if 'unitTest=True' in sys.argv: @@ -13,12 +13,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # Live Online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # Testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options # Required to load Global Tag process.load("DQM.Integration.config.FrontierCondition_GT_cfi") @@ -35,10 +38,14 @@ process.dqmEnv.subSystemFolder = "L1TEMU" process.dqmSaver.tag = "L1TEMU" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "L1TEMU" +process.dqmSaverPB.runNumber = options.runNumber process.dqmEndPath = cms.EndPath( process.dqmEnv * - process.dqmSaver + process.dqmSaver * + process.dqmSaverPB ) #-------------------------------------------------- diff --git a/DQM/Integration/python/clients/lumi_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/lumi_dqm_sourceclient-live_cfg.py index c38b7dd5fe9c0..47acfcdc471f2 100644 --- a/DQM/Integration/python/clients/lumi_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/lumi_dqm_sourceclient-live_cfg.py @@ -8,6 +8,7 @@ # Event Source #---------------------------- process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options #process.DQMEventStreamHttpReader.consumerName = 'DQM Luminosity Consumer' #process.DQMEventStreamHttpReader.SelectHLTOutput = cms.untracked.string('hltOutputALCALUMIPIXELS') @@ -17,6 +18,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "Info/Lumi" process.dqmSaver.tag = "Lumi" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "Lumi" +process.dqmSaverPB.runNumber = options.runNumber #--------------------------------------------- # Global Tag @@ -63,7 +67,8 @@ process.dqmmodules = cms.Sequence(process.dqmEnv + process.expressLumiProducer + process.dqmLumiMonitor - + process.dqmSaver) + + process.dqmSaver + + process.dqmSaverPB) #---------------------------- # Proton-Proton Running Stuff #---------------------------- diff --git a/DQM/Integration/python/clients/mutracking_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/mutracking_dqm_sourceclient-live_cfg.py index 962ac0528fd13..4e4471e2a0ecb 100644 --- a/DQM/Integration/python/clients/mutracking_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/mutracking_dqm_sourceclient-live_cfg.py @@ -22,13 +22,16 @@ if (unitTest): process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif (live): process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus elif(offlineTesting): process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options print("Running with run type = ", process.runType.getRunType()) @@ -53,9 +56,13 @@ process.dqmSaver.tag = 'Muons' ##?? process.dqmSaver.backupLumiCount = 30 -process.dqmSaver.path = '.' +# process.dqmSaver.path = '.' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'Muons' +# process.dqmSaverPB.path = './pb' +process.dqmSaverPB.runNumber = options.runNumber -process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver) +process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) # Imports diff --git a/DQM/Integration/python/clients/onlinebeammonitor_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/onlinebeammonitor_dqm_sourceclient-live_cfg.py new file mode 100644 index 0000000000000..2ce6747894174 --- /dev/null +++ b/DQM/Integration/python/clients/onlinebeammonitor_dqm_sourceclient-live_cfg.py @@ -0,0 +1,182 @@ +from __future__ import print_function +import FWCore.ParameterSet.Config as cms + +# Define once the BeamSpotOnline record name, +# will be used both in BeamMonitor setup and in payload creation/upload + +#from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 +#process = cms.Process("BeamMonitor", Run2_2018) # FIMXE +import sys +from Configuration.Eras.Era_Run2_2018_cff import Run2_2018 +process = cms.Process("OnlineBeamMonitor", Run2_2018) + +# Message logger +#process.load("FWCore.MessageLogger.MessageLogger_cfi") +#process.MessageLogger = cms.Service("MessageLogger", +# debugModules = cms.untracked.vstring('*'), +# cerr = cms.untracked.PSet( +# FwkReport = cms.untracked.PSet( +# optionalPSet = cms.untracked.bool(True), +# reportEvery = cms.untracked.int32(1000), +# limit = cms.untracked.int32(999999) +# ) +# ), +# destinations = cms.untracked.vstring('cerr'), +#) + + +unitTest=False +if 'unitTest=True' in sys.argv: + unitTest=True +#----------------------------- +if unitTest: + import FWCore.ParameterSet.VarParsing as VarParsing + options = VarParsing.VarParsing("analysis") + + options.register( + "runkey", + "pp_run", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "Run Keys of CMS" + ) + + options.register('runNumber', + 336055, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Run number. This run number has to be present in the dataset configured with the dataset option.") + + options.register('dataset', + '/ExpressCosmics/Commissioning2019-Express-v1/FEVT', + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "Dataset name like '/ExpressCosmics/Commissioning2019-Express-v1/FEVT'") + + options.register('maxLumi', + 2, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Only lumisections up to maxLumi are processed.") + + options.register('minLumi', + 1, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Only lumisections starting from minLumi are processed.") + + options.register('lumiPattern', + '*', + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "Only lumisections with numbers matching lumiPattern are processed.") + + options.register('eventsPerLumi', + 100, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "This number of last events in each lumisection will be processed.") + + options.register('transDelay', + 0, #default value, int limit -3 + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "delay in seconds for the commit of the db transaction") + + # This is used only by the online clients themselves. + # We need to register it here because otherwise an error occurs saying that there is an unidentified option. + options.register('unitTest', + True, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.bool, + "Required to avoid the error.") + + options.register('noDB', + True, # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.bool, + "Don't upload the BeamSpot conditions to the DB") + + options.parseArguments() + + process.source = cms.Source("EmptySource") + process.source.numberEventsInRun=cms.untracked.uint32(100) + process.source.firstRun = cms.untracked.uint32(options.runNumber) + process.source.firstLuminosityBlock = cms.untracked.uint32(49) + process.source.numberEventsInLuminosityBlock = cms.untracked.uint32(2) + process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(100) +) + +else: + process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options + # for live online DQM in P5 + # new stream label + process.source.streamLabel = cms.untracked.string('streamDQMOnlineBeamspot') + +#ESProducer +process.load("CondCore.CondDB.CondDB_cfi") +process.BeamSpotDBSource = cms.ESSource("PoolDBESSource", + process.CondDB, + toGet = cms.VPSet( + cms.PSet( + record = cms.string('BeamSpotOnlineLegacyObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestLegacy"), + refreshTime = cms.uint64(1) + ), + cms.PSet( + record = cms.string('BeamSpotOnlineHLTObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestHLT"), + refreshTime = cms.uint64(1) + + ), + ) + +) +process.BeamSpotESProducer = cms.ESProducer("OnlineBeamSpotESProducer") +if unitTest == True: + process.BeamSpotDBSource.connect = cms.string('frontier://FrontierProd/CMS_CONDITIONS') +else: + process.BeamSpotDBSource.connect = cms.string('oracle://cms_orcon_prod/CMS_CONDITIONS') +#----------------------------- +# DQM Live Environment +#----------------------------- +process.load("DQM.Integration.config.environment_cfi") +process.dqmEnv.subSystemFolder = 'TrackingHLTBeamspotStream' +process.dqmSaver.tag = 'TrackingHLTBeamspotStream' +#process.dqmSaver.runNumber = options.runNumber +#process.dqmSaverPB.tag = 'TrackingHLTBeamspotStream' +#process.dqmSaverPB.runNumber = options.runNumber + +#----------------------------- +# BeamMonitor +#----------------------------- +process.dqmOnlineBeamMonitor = cms.EDProducer("OnlineBeamMonitor", +MonitorName = cms.untracked.string("onlineBeamMonitor") +) + +#--------------- +# Calibration +#--------------- +# Condition for P5 cluster +process.load("DQM.Integration.config.FrontierCondition_GT_cfi") +# Condition for lxplus: change and possibly customise the GT +#from Configuration.AlCa.GlobalTag import GlobalTag as gtCustomise +#process.GlobalTag = gtCustomise(process.GlobalTag, 'auto:run2_data', '') + + +process.dqmcommon = cms.Sequence(process.dqmEnv + * process.dqmSaver) + +process.monitor = cms.Sequence(process.dqmOnlineBeamMonitor) + +#----------------------------------------------------------- +# process customizations included here +from DQM.Integration.config.online_customizations_cfi import * +process = customise(process) + + +process.p = cms.Path( process.dqmcommon + * process.monitor ) + diff --git a/DQM/Integration/python/clients/physics_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/physics_dqm_sourceclient-live_cfg.py index d7a35b425baab..76b6ae553949c 100644 --- a/DQM/Integration/python/clients/physics_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/physics_dqm_sourceclient-live_cfg.py @@ -11,9 +11,11 @@ # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") +from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Environment @@ -22,6 +24,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'Physics' process.dqmSaver.tag = 'Physics' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'Physics' +process.dqmSaverPB.runNumber = options.runNumber # 0=random, 1=physics, 2=calibration, 3=technical process.hltTriggerTypeFilter = cms.EDFilter("HLTTriggerTypeFilter", @@ -47,7 +52,8 @@ # process.dump * process.qcdLowPtDQM * process.dqmEnv * - process.dqmSaver + process.dqmSaver * + process.dqmSaverPB ) process.siPixelDigis.InputLabel = cms.InputTag("rawDataCollector") diff --git a/DQM/Integration/python/clients/pixel_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/pixel_dqm_sourceclient-live_cfg.py index ade0c6d9f35cd..21a9643f998f3 100644 --- a/DQM/Integration/python/clients/pixel_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/pixel_dqm_sourceclient-live_cfg.py @@ -2,8 +2,8 @@ import FWCore.ParameterSet.Config as cms import sys -from Configuration.Eras.Era_Run2_2018_pp_on_AA_cff import Run2_2018_pp_on_AA -process = cms.Process("PIXELDQMLIVE", Run2_2018_pp_on_AA) +from Configuration.Eras.Era_Run3_cff import Run3 +process = cms.Process("PIXELDQMLIVE", Run3) live=True unitTest = False @@ -34,13 +34,16 @@ if (unitTest): process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif (live): process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus elif(offlineTesting): process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options #----------------------------- # DQM Environment @@ -56,6 +59,9 @@ process.dqmEnv.subSystemFolder = TAG process.dqmSaver.tag = TAG +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = TAG +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- @@ -160,7 +166,7 @@ # Scheduling #-------------------------- -process.DQMmodules = cms.Sequence(process.dqmEnv* process.dqmSaver) +process.DQMmodules = cms.Sequence(process.dqmEnv* process.dqmSaver*process.dqmSaverPB) process.RecoForDQM_LocalReco = cms.Sequence(process.siPixelDigis*process.siStripDigis*process.gtDigis*process.trackerlocalreco) diff --git a/DQM/Integration/python/clients/pixellumi_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/pixellumi_dqm_sourceclient-live_cfg.py index 586dfc26fa97f..bd15690ede85a 100644 --- a/DQM/Integration/python/clients/pixellumi_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/pixellumi_dqm_sourceclient-live_cfg.py @@ -21,12 +21,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options ## #---------------------------- @@ -40,6 +43,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "PixelLumi" process.dqmSaver.tag = "PixelLumi" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "PixelLumi" +process.dqmSaverPB.runNumber = options.runNumber if not unitTest: process.source.SelectEvents = cms.untracked.vstring("HLT_ZeroBias*","HLT_L1AlwaysTrue*", "HLT_PAZeroBias*", "HLT_PAL1AlwaysTrue*") @@ -128,7 +134,8 @@ process.Reco = cms.Sequence(process.siPixelDigis*process.siPixelClusters) process.DQMmodules = cms.Sequence(process.dqmEnv* process.pixel_lumi_dqm* - process.dqmSaver) + process.dqmSaver* + process.dqmSaverPB) process.p = cms.Path(process.Reco*process.DQMmodules) diff --git a/DQM/Integration/python/clients/ramdisk_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/ramdisk_dqm_sourceclient-live_cfg.py index 93ed9b30eeb10..b4878faae10cf 100644 --- a/DQM/Integration/python/clients/ramdisk_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/ramdisk_dqm_sourceclient-live_cfg.py @@ -8,11 +8,15 @@ import FWCore.ParameterSet.VarParsing as VarParsing process.load('DQM.Integration.config.inputsource_cfi') +from DQM.Integration.config.inputsource_cfi import options process.load('DQMServices.Components.DQMEnvironment_cfi') process.load('DQM.Integration.config.environment_cfi') process.dqmEnv.subSystemFolder = subsystem process.dqmSaver.tag = subsystem +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = subsystem +process.dqmSaverPB.runNumber = options.runNumber from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer process.analyzer = DQMEDAnalyzer('RamdiskMonitor', diff --git a/DQM/Integration/python/clients/rpc_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/rpc_dqm_sourceclient-live_cfg.py index 33526c28686fe..90bd34dd2ef05 100644 --- a/DQM/Integration/python/clients/rpc_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/rpc_dqm_sourceclient-live_cfg.py @@ -17,12 +17,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options ############### HLT Filter####################### # 0=random, 1=physics, 2=calibration, 3=technical @@ -52,6 +55,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'RPC' process.dqmSaver.tag = 'RPC' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'RPC' +process.dqmSaverPB.runNumber = options.runNumber ############### Scaler Producer ################# @@ -158,7 +164,7 @@ * (process.rpcdigidqm + process.rpcMergerdigidqm) * process.rpcMonitorRaw*process.rpcDcsInfo*process.qTesterRPC ) -process.rpcClient = cms.Sequence(process.rpcdqmclient*process.rpcMergerdqmclient*process.rpcChamberQuality*process.rpcChamberQualityMerger*process.rpcEventSummary*process.rpcEventSummaryMerger*process.dqmEnv*process.dqmSaver) +process.rpcClient = cms.Sequence(process.rpcdqmclient*process.rpcMergerdqmclient*process.rpcChamberQuality*process.rpcChamberQualityMerger*process.rpcEventSummary*process.rpcEventSummaryMerger*process.dqmEnv*process.dqmSaver*process.dqmSaverPB) process.p = cms.Path(process.hltTriggerTypeFilter*process.rpcSource*process.rpcClient) process.rpcunpacker.InputLabel = cms.InputTag("rawDataCollector") diff --git a/DQM/Integration/python/clients/scal_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/scal_dqm_sourceclient-live_cfg.py index 351af026e8aa5..893443f74f1a2 100644 --- a/DQM/Integration/python/clients/scal_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/scal_dqm_sourceclient-live_cfg.py @@ -13,12 +13,15 @@ if unitTest: process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options else: # for live online DQM in P5 process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus #process.load("DQM.Integration.config.fileinputsource_cfi") +#from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- #### DQM Environment @@ -26,6 +29,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = 'Scal' process.dqmSaver.tag = 'Scal' +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = 'Scal' +process.dqmSaverPB.runNumber = options.runNumber #----------------------------- process.load("DQMServices.Components.DQMScalInfo_cfi") @@ -68,7 +74,7 @@ process.dump = cms.EDAnalyzer('EventContentAnalyzer') # DQM Modules -process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver) +process.dqmmodules = cms.Sequence(process.dqmEnv + process.dqmSaver + process.dqmSaverPB) process.evfDQMmodulesPath = cms.Path( process.l1GtUnpack* process.gtDigis* diff --git a/DQM/Integration/python/clients/sistrip_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/sistrip_dqm_sourceclient-live_cfg.py index e56402bab4dc3..9b0dc43b2b5db 100644 --- a/DQM/Integration/python/clients/sistrip_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/sistrip_dqm_sourceclient-live_cfg.py @@ -2,8 +2,8 @@ import FWCore.ParameterSet.Config as cms import sys -from Configuration.Eras.Era_Run2_2018_pp_on_AA_cff import Run2_2018_pp_on_AA -process = cms.Process("SiStrpDQMLive", Run2_2018_pp_on_AA) +from Configuration.Eras.Era_Run3_cff import Run3 +process = cms.Process("SiStrpDQMLive", Run3) process.MessageLogger = cms.Service("MessageLogger", debugModules = cms.untracked.vstring('siStripDigis', @@ -32,11 +32,14 @@ # for live online DQM in P5 if (unitTest): process.load("DQM.Integration.config.unittestinputsource_cfi") + from DQM.Integration.config.unittestinputsource_cfi import options elif (live): process.load("DQM.Integration.config.inputsource_cfi") + from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus elif(offlineTesting): process.load("DQM.Integration.config.fileinputsource_cfi") + from DQM.Integration.config.fileinputsource_cfi import options #---------------------------- # DQM Live Environment @@ -52,6 +55,9 @@ process.dqmEnv.subSystemFolder = "SiStrip" process.dqmSaver.tag = "SiStrip" process.dqmSaver.backupLumiCount = 30 +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "SiStrip" +process.dqmSaverPB.runNumber = options.runNumber from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer process.dqmEnvTr = DQMEDAnalyzer('DQMEventInfo', @@ -208,7 +214,7 @@ # Scheduling #-------------------------- process.SiStripSources_LocalReco = cms.Sequence(process.siStripFEDMonitor*process.SiStripMonitorDigi*process.SiStripMonitorClusterReal) -process.DQMCommon = cms.Sequence(process.stripQTester*process.trackingQTester*process.dqmEnv*process.dqmEnvTr*process.dqmSaver) +process.DQMCommon = cms.Sequence(process.stripQTester*process.trackingQTester*process.dqmEnv*process.dqmEnvTr*process.dqmSaver*process.dqmSaverPB) if (process.runType.getRunType() == process.runType.hi_run): process.RecoForDQM_LocalReco = cms.Sequence(process.siPixelDigis*process.siStripDigis*process.trackerlocalreco) else : @@ -266,6 +272,8 @@ process.trackingQTester.qtestOnEndRun = cms.untracked.bool(True) process.p = cms.Path(process.scalersRawToDigi* + process.tcdsDigis* + process.onlineMetaDataDigis* process.APVPhases* process.consecutiveHEs* process.hltTriggerTypeFilter* @@ -369,6 +377,8 @@ process.p = cms.Path( process.scalersRawToDigi* + process.tcdsDigis* + process.onlineMetaDataDigis* process.APVPhases* process.consecutiveHEs* process.hltTriggerTypeFilter* @@ -463,6 +473,8 @@ process.RecoForDQM_TrkReco = cms.Sequence(process.offlineBeamSpot*process.MeasurementTrackerEvent*process.siPixelClusterShapeCache*process.recopixelvertexing*process.iterTracking_FirstStep) process.p = cms.Path(process.scalersRawToDigi* + process.tcdsDigis* + process.onlineMetaDataDigis* process.APVPhases* process.consecutiveHEs* process.hltTriggerTypeFilter* @@ -617,6 +629,8 @@ process.p = cms.Path( process.scalersRawToDigi* + process.tcdsDigis* + process.onlineMetaDataDigis* process.APVPhases* process.consecutiveHEs* process.hltTriggerTypeFilter* diff --git a/DQM/Integration/python/clients/sistriplas_dqm_sourceclient-live_cfg.py b/DQM/Integration/python/clients/sistriplas_dqm_sourceclient-live_cfg.py index 5fc8452c38295..cf43ad37d5ff8 100644 --- a/DQM/Integration/python/clients/sistriplas_dqm_sourceclient-live_cfg.py +++ b/DQM/Integration/python/clients/sistriplas_dqm_sourceclient-live_cfg.py @@ -11,9 +11,11 @@ #----------------------------- # for live online DQM in P5 #process.load("DQM.Integration.config.inputsource_cfi") +#from DQM.Integration.config.inputsource_cfi import options # for testing in lxplus process.load("DQM.Integration.config.fileinputsource_cfi") +from DQM.Integration.config.fileinputsource_cfi import options process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32( -1 ) @@ -36,6 +38,9 @@ process.load("DQM.Integration.config.environment_cfi") process.dqmEnv.subSystemFolder = "SiStripLAS" process.dqmSaver.tag = "SiStripLAS" +process.dqmSaver.runNumber = options.runNumber +process.dqmSaverPB.tag = "SiStripLAS" +process.dqmSaverPB.runNumber = options.runNumber #---------------------------- # DQM Alignment Software #---------------------------- @@ -51,7 +56,7 @@ process.LaserAlignmentProducerDQM.UpperAdcThreshold = cms.uint32( 280 ) process.seqDigitization = cms.Path( process.siStripDigis ) -process.DQMCommon = cms.Sequence(process.dqmEnv*process.dqmSaver) +process.DQMCommon = cms.Sequence(process.dqmEnv*process.dqmSaver*process.dqmSaverPB) process.seqAnalysis = cms.Path( process.LaserAlignmentProducerDQM*process.DQMCommon) process.siStripDigis.ProductLabel = cms.InputTag("hltTrackerCalibrationRaw") diff --git a/DQM/Integration/python/config/environment_cfi.py b/DQM/Integration/python/config/environment_cfi.py index af11e6dd39245..5b61f72f9c32d 100644 --- a/DQM/Integration/python/config/environment_cfi.py +++ b/DQM/Integration/python/config/environment_cfi.py @@ -76,3 +76,11 @@ def loadDQMRunConfigFromFile(): dqmSaver.tag = "PID%06d" % os.getpid() dqmSaver.producer = 'DQM' dqmSaver.backupLumiCount = 15 + +# Add Protobuf DQM saver +from DQMServices.FileIO.DQMFileSaverPB_cfi import dqmSaver as dqmSaverPB + +dqmSaverPB.path = './upload/pb' +dqmSaverPB.tag = 'PID%06d' % os.getpid() +dqmSaverPB.producer = 'DQM' +dqmSaverPB.fakeFilterUnitMode = True diff --git a/DQM/Integration/python/config/fileinputsource_cfi.py b/DQM/Integration/python/config/fileinputsource_cfi.py index 0d83f7083d335..6852608194b01 100644 --- a/DQM/Integration/python/config/fileinputsource_cfi.py +++ b/DQM/Integration/python/config/fileinputsource_cfi.py @@ -52,6 +52,18 @@ VarParsing.VarParsing.varType.string, "Dataset name like '/ExpressPhysicsPA/PARun2016D-Express-v1/FEVT', or 'auto' to guess it with a DAS query. A dataset_cfi.py that defines 'readFiles' and 'secFiles' (like a DAS Python snippet) will override this, to avoid DAS queries.") +options.register('transDelay', + 0, #default value, int limit -3 + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "delay in seconds for the commit of the db transaction") + +options.register('noDB', + True, # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.bool, + "Don't upload the BeamSpot conditions to the DB") + options.parseArguments() try: diff --git a/DQM/Integration/python/config/inputsource_cfi.py b/DQM/Integration/python/config/inputsource_cfi.py index 53c99bb638660..6dd6c788094b1 100644 --- a/DQM/Integration/python/config/inputsource_cfi.py +++ b/DQM/Integration/python/config/inputsource_cfi.py @@ -33,6 +33,18 @@ VarParsing.VarParsing.varType.bool, "Skip (and ignore the minEventsPerLumi parameter) for the files which have been available at the begining of the processing. ") +options.register('transDelay', + 0, #default value, int limit -3 + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "delay in seconds for the commit of the db transaction") + +options.register('noDB', + True, # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.bool, + "Don't upload the BeamSpot conditions to the DB") + # Parameters for runType options.register ('runkey', diff --git a/DQM/Integration/python/config/unittestinputsource_cfi.py b/DQM/Integration/python/config/unittestinputsource_cfi.py index e5facb9849fd7..3a9fde2dd7f6e 100644 --- a/DQM/Integration/python/config/unittestinputsource_cfi.py +++ b/DQM/Integration/python/config/unittestinputsource_cfi.py @@ -60,6 +60,12 @@ VarParsing.VarParsing.varType.int, "This number of last events in each lumisection will be processed.") +options.register('transDelay', + 0, #default value, int limit -3 + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "delay in seconds for the commit of the db transaction") + # This is used only by the online clients themselves. # We need to register it here because otherwise an error occurs saying that there is an unidentified option. options.register('unitTest', @@ -68,6 +74,12 @@ VarParsing.VarParsing.varType.bool, "Required to avoid the error.") +options.register('noDB', + True, # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.bool, + "Don't upload the BeamSpot conditions to the DB") + options.parseArguments() print("Querying DAS for files...") diff --git a/DQM/Integration/test/BuildFile.xml b/DQM/Integration/test/BuildFile.xml index bf4a20a2b06d0..890e4833e4ab5 100644 --- a/DQM/Integration/test/BuildFile.xml +++ b/DQM/Integration/test/BuildFile.xml @@ -22,6 +22,7 @@ + diff --git a/DQM/L1TMonitor/interface/L1TStage2BMTF.h b/DQM/L1TMonitor/interface/L1TStage2BMTF.h index 61abcbcc01a0f..038d38f11deab 100644 --- a/DQM/L1TMonitor/interface/L1TStage2BMTF.h +++ b/DQM/L1TMonitor/interface/L1TStage2BMTF.h @@ -4,7 +4,7 @@ /* * \file L1TStage2BMTF.h * \Author Esmaeel Eskandari Tadavani - * \December 2015 + * \December 2015 */ // system requirements @@ -95,7 +95,7 @@ class L1TStage2BMTF : public DQMEDAnalyzer { MonitorElement* bmtf_hwQual_bx; MonitorElement* bmtf_hwDXY; - MonitorElement* bmtf_hwPt2; + MonitorElement* bmtf_hwPtUnconstrained; /* MonitorElement* bmtf_twinmuxInput_PhiBX; */ /* MonitorElement* bmtf_twinmuxInput_PhiPhi; */ diff --git a/DQM/L1TMonitor/interface/L1TStage2MuonComp.h b/DQM/L1TMonitor/interface/L1TStage2MuonComp.h index 983a38d38bf74..e1a65024407bb 100644 --- a/DQM/L1TMonitor/interface/L1TStage2MuonComp.h +++ b/DQM/L1TMonitor/interface/L1TStage2MuonComp.h @@ -39,7 +39,9 @@ class L1TStage2MuonComp : public DQMEDAnalyzer { CHARGEVALBAD, QUALBAD, ISOBAD, - IDXBAD + IDXBAD, + PTUNCONSTRBAD, + DXYBAD }; enum ratioVariables { RBXRANGE = 1, @@ -54,9 +56,13 @@ class L1TStage2MuonComp : public DQMEDAnalyzer { RCHARGEVAL, RQUAL, RISO, - RIDX + RIDX, + RPTUNCONSTR, + RDXY }; - bool incBin[RIDX + 1]; + int numErrBins_{ + RIDX}; // In Run-2 we didn't have the last two bins. This is incremented in source file if we configure for Run-3. + bool incBin[RDXY + 1]; edm::EDGetTokenT muonToken1; edm::EDGetTokenT muonToken2; @@ -67,6 +73,7 @@ class L1TStage2MuonComp : public DQMEDAnalyzer { std::vector ignoreBin; bool verbose; bool enable2DComp; // Default value is false. Set to true in the configuration file for enabling 2D eta-phi histograms + bool displacedQuantities_; MonitorElement* summary; MonitorElement* errorSummaryNum; @@ -75,6 +82,8 @@ class L1TStage2MuonComp : public DQMEDAnalyzer { MonitorElement* muColl1BxRange; MonitorElement* muColl1nMu; MonitorElement* muColl1hwPt; + MonitorElement* muColl1hwPtUnconstrained; + MonitorElement* muColl1hwDXY; MonitorElement* muColl1hwEta; MonitorElement* muColl1hwPhi; MonitorElement* muColl1hwEtaAtVtx; @@ -89,6 +98,8 @@ class L1TStage2MuonComp : public DQMEDAnalyzer { MonitorElement* muColl2BxRange; MonitorElement* muColl2nMu; MonitorElement* muColl2hwPt; + MonitorElement* muColl2hwPtUnconstrained; + MonitorElement* muColl2hwDXY; MonitorElement* muColl2hwEta; MonitorElement* muColl2hwPhi; MonitorElement* muColl2hwEtaAtVtx; diff --git a/DQM/L1TMonitor/interface/L1TStage2RegionalMuonCandComp.h b/DQM/L1TMonitor/interface/L1TStage2RegionalMuonCandComp.h index ffbb09b4f10fc..f679c4d30a852 100644 --- a/DQM/L1TMonitor/interface/L1TStage2RegionalMuonCandComp.h +++ b/DQM/L1TMonitor/interface/L1TStage2RegionalMuonCandComp.h @@ -95,7 +95,7 @@ class L1TStage2RegionalMuonCandComp : public DQMEDAnalyzer { MonitorElement* muColl1TrkAddrSize; MonitorElement* muColl1TrkAddr; MonitorElement* muColl1hwDXY; - MonitorElement* muColl1hwPt2; + MonitorElement* muColl1hwPtUnconstrained; MonitorElement* muColl2BxRange; MonitorElement* muColl2nMu; @@ -112,7 +112,7 @@ class L1TStage2RegionalMuonCandComp : public DQMEDAnalyzer { MonitorElement* muColl2TrkAddrSize; MonitorElement* muColl2TrkAddr; MonitorElement* muColl2hwDXY; - MonitorElement* muColl2hwPt2; + MonitorElement* muColl2hwPtUnconstrained; }; #endif diff --git a/DQM/L1TMonitor/interface/L1TStage2uGMT.h b/DQM/L1TMonitor/interface/L1TStage2uGMT.h index 5fd3b2ff43507..0c19f63af5183 100644 --- a/DQM/L1TMonitor/interface/L1TStage2uGMT.h +++ b/DQM/L1TMonitor/interface/L1TStage2uGMT.h @@ -34,6 +34,7 @@ class L1TStage2uGMT : public DQMEDAnalyzer { std::string monitorDir; bool emul; bool verbose; + bool displacedQuantities_; const float etaScale_; const float phiScale_; @@ -41,6 +42,8 @@ class L1TStage2uGMT : public DQMEDAnalyzer { MonitorElement* ugmtBMTFBX; MonitorElement* ugmtBMTFnMuons; MonitorElement* ugmtBMTFhwPt; + MonitorElement* ugmtBMTFhwPtUnconstrained; + MonitorElement* ugmtBMTFhwDXY; MonitorElement* ugmtBMTFhwEta; MonitorElement* ugmtBMTFhwPhi; MonitorElement* ugmtBMTFglbPhi; @@ -112,6 +115,8 @@ class L1TStage2uGMT : public DQMEDAnalyzer { MonitorElement* ugmtnMuons; MonitorElement* ugmtMuonIndex; MonitorElement* ugmtMuonhwPt; + MonitorElement* ugmtMuonhwPtUnconstrained; + MonitorElement* ugmtMuonhwDXY; MonitorElement* ugmtMuonhwEta; MonitorElement* ugmtMuonhwPhi; MonitorElement* ugmtMuonhwEtaAtVtx; @@ -122,6 +127,7 @@ class L1TStage2uGMT : public DQMEDAnalyzer { MonitorElement* ugmtMuonhwIso; MonitorElement* ugmtMuonPt; + MonitorElement* ugmtMuonPtUnconstrained; MonitorElement* ugmtMuonEta; MonitorElement* ugmtMuonPhi; MonitorElement* ugmtMuonEtaAtVtx; diff --git a/DQM/L1TMonitor/interface/L1TStage2uGMTMuon.h b/DQM/L1TMonitor/interface/L1TStage2uGMTMuon.h index f0088862ab17e..6bba81f3edb01 100644 --- a/DQM/L1TMonitor/interface/L1TStage2uGMTMuon.h +++ b/DQM/L1TMonitor/interface/L1TStage2uGMTMuon.h @@ -28,10 +28,13 @@ class L1TStage2uGMTMuon : public DQMEDAnalyzer { std::string titlePrefix; bool verbose; bool makeMuonAtVtxPlots; + bool displacedQuantities_; MonitorElement* ugmtMuonBX; MonitorElement* ugmtnMuons; MonitorElement* ugmtMuonhwPt; + MonitorElement* ugmtMuonhwPtUnconstrained; + MonitorElement* ugmtMuonhwDXY; MonitorElement* ugmtMuonhwEta; MonitorElement* ugmtMuonhwPhi; MonitorElement* ugmtMuonhwEtaAtVtx; @@ -41,6 +44,7 @@ class L1TStage2uGMTMuon : public DQMEDAnalyzer { MonitorElement* ugmtMuonhwQual; MonitorElement* ugmtMuonPt; + MonitorElement* ugmtMuonPtUnconstrained; MonitorElement* ugmtMuonEta; MonitorElement* ugmtMuonPhi; MonitorElement* ugmtMuonEtaAtVtx; diff --git a/DQM/L1TMonitor/python/L1TStage2uGMT_cff.py b/DQM/L1TMonitor/python/L1TStage2uGMT_cff.py index b648e60b9624a..c00390ff7beac 100644 --- a/DQM/L1TMonitor/python/L1TStage2uGMT_cff.py +++ b/DQM/L1TMonitor/python/L1TStage2uGMT_cff.py @@ -11,14 +11,20 @@ monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/intermediate_muons/BMTF"), titlePrefix = cms.untracked.string("uGMT intermediate muon from BMTF "), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) +## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tStage2uGMTIntermediateBMTF, displacedQuantities = cms.untracked.bool(True)) + l1tStage2uGMTIntermediateOMTFNeg = DQMEDAnalyzer( "L1TStage2uGMTMuon", muonProducer = cms.InputTag("gmtStage2Digis", "imdMuonsOMTFNeg"), monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/intermediate_muons/OMTF_neg"), titlePrefix = cms.untracked.string("uGMT intermediate muon from OMTF neg. "), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) l1tStage2uGMTIntermediateOMTFPos = DQMEDAnalyzer( @@ -27,6 +33,7 @@ monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/intermediate_muons/OMTF_pos"), titlePrefix = cms.untracked.string("uGMT intermediate muon from OMTF pos. "), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) l1tStage2uGMTIntermediateEMTFNeg = DQMEDAnalyzer( @@ -35,6 +42,7 @@ monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/intermediate_muons/EMTF_neg"), titlePrefix = cms.untracked.string("uGMT intermediate muon from EMTF neg. "), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) l1tStage2uGMTIntermediateEMTFPos = DQMEDAnalyzer( @@ -43,6 +51,7 @@ monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/intermediate_muons/EMTF_pos"), titlePrefix = cms.untracked.string("uGMT intermediate muon from EMTF pos. "), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) # zero suppression DQM @@ -77,6 +86,22 @@ verbose = cms.untracked.bool(False), ) +## Era: Run3_2021; Changed data format for Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tStage2uGMTZeroSupp, maskCapId2 = cms.untracked.vint32(0x00000000, + 0x00000000, + 0x0007FC00, + 0x00000000, + 0x0007FC00, + 0x00000000), + # mask for validation event outputs (pt==0 defines empty muon) + maskCapId3 = cms.untracked.vint32(0x00000000, + 0x00000000, + 0x0007FC00, + 0x00000000, + 0x0007FC00, + 0x00000000)) + # ZS of validation events (to be used after fat event filter) l1tStage2uGMTZeroSuppFatEvts = l1tStage2uGMTZeroSupp.clone() l1tStage2uGMTZeroSuppFatEvts.monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/zeroSuppression/FatEvts") @@ -102,6 +127,10 @@ verbose = cms.untracked.bool(False), ) +## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tStage2BmtfOutVsuGMTIn, isBmtf = cms.untracked.bool(True)) + # compares the unpacked OMTF output regional muon collection with the unpacked uGMT input regional muon collection from OMTF # only muons that do not match are filled in the histograms l1tStage2OmtfOutVsuGMTIn = DQMEDAnalyzer( @@ -142,8 +171,13 @@ muonCollection2Title = cms.untracked.string("uGMT muons copy 1"), summaryTitle = cms.untracked.string("Summary of comparison between uGMT muons and uGMT muon copy 1"), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) +## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tStage2uGMTMuonVsuGMTMuonCopy1, displacedQuantities = cms.untracked.bool(True)) + l1tStage2uGMTMuonVsuGMTMuonCopy2 = l1tStage2uGMTMuonVsuGMTMuonCopy1.clone() l1tStage2uGMTMuonVsuGMTMuonCopy2.muonCollection2 = cms.InputTag("gmtStage2Digis", "MuonCopy2") l1tStage2uGMTMuonVsuGMTMuonCopy2.monitorDir = cms.untracked.string("L1T/L1TStage2uGMT/uGMTMuonCopies/uGMTMuonCopy2") diff --git a/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py b/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py index 96035f4ece147..b3ad6108691e2 100644 --- a/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py +++ b/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py @@ -11,5 +11,9 @@ monitorDir = cms.untracked.string("L1T/L1TStage2uGMT"), emulator = cms.untracked.bool(False), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False) ) +## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tStage2uGMT, displacedQuantities = cms.untracked.bool(True)) diff --git a/DQM/L1TMonitor/python/L1TdeStage2uGMT_cff.py b/DQM/L1TMonitor/python/L1TdeStage2uGMT_cff.py index 3995b6d4650fb..15114f493df1f 100644 --- a/DQM/L1TMonitor/python/L1TdeStage2uGMT_cff.py +++ b/DQM/L1TMonitor/python/L1TdeStage2uGMT_cff.py @@ -27,8 +27,13 @@ monitorDir = cms.untracked.string(ugmtEmuImdMuDqmDir+"/BMTF"), titlePrefix = cms.untracked.string("uGMT intermediate muon from BMTF "), verbose = cms.untracked.bool(False), + displacedQuantities = cms.untracked.bool(False), ) +## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tStage2uGMTIntermediateBMTFEmul, displacedQuantities = cms.untracked.bool(True)) + l1tStage2uGMTIntermediateOMTFNegEmul = DQMEDAnalyzer( "L1TStage2uGMTMuon", muonProducer = cms.InputTag(emulatorModule, "imdMuonsOMTFNeg"), @@ -72,9 +77,14 @@ muonCollection2Title = cms.untracked.string("uGMT emulator"), summaryTitle = cms.untracked.string("Summary of comparison between uGMT muons and uGMT emulator muons"), verbose = cms.untracked.bool(False), - enable2DComp = cms.untracked.bool(True), # When true eta-phi comparison plots are also produced + enable2DComp = cms.untracked.bool(True), # When true eta-phi comparison plots are also produced + displacedQuantities = cms.untracked.bool(False), ) +## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(l1tdeStage2uGMT, displacedQuantities = cms.untracked.bool(True)) + # compares the unpacked uGMT intermediate muon collection to the emulated uGMT intermediate muon collection # only muons that do not match are filled in the histograms l1tdeStage2uGMTIntermediateBMTF = l1tdeStage2uGMT.clone() @@ -85,6 +95,7 @@ l1tdeStage2uGMTIntermediateBMTF.ignoreBin = cms.untracked.vint32(ignoreBins) l1tdeStage2uGMTIntermediateOMTFNeg = l1tdeStage2uGMTIntermediateBMTF.clone() +l1tdeStage2uGMTIntermediateOMTFNeg.displacedQuantities = cms.untracked.bool(False) l1tdeStage2uGMTIntermediateOMTFNeg.muonCollection1 = cms.InputTag(unpackerModule, "imdMuonsOMTFNeg") l1tdeStage2uGMTIntermediateOMTFNeg.muonCollection2 = cms.InputTag(emulatorModule, "imdMuonsOMTFNeg") l1tdeStage2uGMTIntermediateOMTFNeg.monitorDir = cms.untracked.string(ugmtEmuImdMuDqmDir+"/OMTF_neg/data_vs_emulator_comparison") @@ -92,6 +103,7 @@ l1tdeStage2uGMTIntermediateOMTFNeg.ignoreBin = cms.untracked.vint32(ignoreBins) l1tdeStage2uGMTIntermediateOMTFPos = l1tdeStage2uGMTIntermediateBMTF.clone() +l1tdeStage2uGMTIntermediateOMTFPos.displacedQuantities = cms.untracked.bool(False) l1tdeStage2uGMTIntermediateOMTFPos.muonCollection1 = cms.InputTag(unpackerModule, "imdMuonsOMTFPos") l1tdeStage2uGMTIntermediateOMTFPos.muonCollection2 = cms.InputTag(emulatorModule, "imdMuonsOMTFPos") l1tdeStage2uGMTIntermediateOMTFPos.monitorDir = cms.untracked.string(ugmtEmuImdMuDqmDir+"/OMTF_pos/data_vs_emulator_comparison") @@ -99,6 +111,7 @@ l1tdeStage2uGMTIntermediateOMTFPos.ignoreBin = cms.untracked.vint32(ignoreBins) l1tdeStage2uGMTIntermediateEMTFNeg = l1tdeStage2uGMTIntermediateBMTF.clone() +l1tdeStage2uGMTIntermediateEMTFNeg.displacedQuantities = cms.untracked.bool(False) l1tdeStage2uGMTIntermediateEMTFNeg.muonCollection1 = cms.InputTag(unpackerModule, "imdMuonsEMTFNeg") l1tdeStage2uGMTIntermediateEMTFNeg.muonCollection2 = cms.InputTag(emulatorModule, "imdMuonsEMTFNeg") l1tdeStage2uGMTIntermediateEMTFNeg.monitorDir = cms.untracked.string(ugmtEmuImdMuDqmDir+"/EMTF_neg/data_vs_emulator_comparison") @@ -106,6 +119,7 @@ l1tdeStage2uGMTIntermediateEMTFNeg.ignoreBin = cms.untracked.vint32(ignoreBins) l1tdeStage2uGMTIntermediateEMTFPos = l1tdeStage2uGMTIntermediateBMTF.clone() +l1tdeStage2uGMTIntermediateEMTFPos.displacedQuantities = cms.untracked.bool(False) l1tdeStage2uGMTIntermediateEMTFPos.muonCollection1 = cms.InputTag(unpackerModule, "imdMuonsEMTFPos") l1tdeStage2uGMTIntermediateEMTFPos.muonCollection2 = cms.InputTag(emulatorModule, "imdMuonsEMTFPos") l1tdeStage2uGMTIntermediateEMTFPos.monitorDir = cms.untracked.string(ugmtEmuImdMuDqmDir+"/EMTF_pos/data_vs_emulator_comparison") diff --git a/DQM/L1TMonitor/src/L1TStage2BMTF.cc b/DQM/L1TMonitor/src/L1TStage2BMTF.cc index 1c14e4031c1ec..8af2d0730a9f0 100644 --- a/DQM/L1TMonitor/src/L1TStage2BMTF.cc +++ b/DQM/L1TMonitor/src/L1TStage2BMTF.cc @@ -80,7 +80,8 @@ void L1TStage2BMTF::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run& i bmtf_hwQual_bx->setTitle("; HW Quality; BX"); bmtf_hwDXY = ibooker.book1D(histoPrefix + "_hwDXY", "HW DXY", 4, 0, 4); - bmtf_hwPt2 = ibooker.book1D(histoPrefix + "_hwPt2", "HW p_{T}2", 512, -0.5, 511.5); + bmtf_hwPtUnconstrained = + ibooker.book1D(histoPrefix + "_hwPtUnconstrained", "HW p_{T} unconstrained", 512, -0.5, 511.5); // bmtf_twinmuxInput_PhiBX = ibooker.book1D(histoPrefix+"_twinmuxInput_PhiBX" , "TwinMux Input Phi BX" , 5, -2.5, 2.5); // bmtf_twinmuxInput_PhiPhi = ibooker.book1D(histoPrefix+"_twinmuxInput_PhiPhi" , "TwinMux Input Phi HW Phi" , 201, -100.5, 100.5); @@ -136,7 +137,7 @@ void L1TStage2BMTF::analyze(const edm::Event& eve, const edm::EventSetup& eveSet bmtf_proc->Fill(itMuon->processor()); bmtf_hwDXY->Fill(itMuon->hwDXY()); - bmtf_hwPt2->Fill(itMuon->hwPt2()); + bmtf_hwPtUnconstrained->Fill(itMuon->hwPtUnconstrained()); if (fabs(bmtfMuon->getLastBX() - bmtfMuon->getFirstBX()) > 3) { bmtf_wedge_bx->Fill(itMuon->processor(), itBX); diff --git a/DQM/L1TMonitor/src/L1TStage2MuonComp.cc b/DQM/L1TMonitor/src/L1TStage2MuonComp.cc index db3e57a4f5962..37c62dcd634f0 100644 --- a/DQM/L1TMonitor/src/L1TStage2MuonComp.cc +++ b/DQM/L1TMonitor/src/L1TStage2MuonComp.cc @@ -10,8 +10,8 @@ L1TStage2MuonComp::L1TStage2MuonComp(const edm::ParameterSet& ps) ignoreBin(ps.getUntrackedParameter>("ignoreBin")), verbose(ps.getUntrackedParameter("verbose")), enable2DComp( - ps.getUntrackedParameter("enable2DComp")) // When true eta-phi comparison plots are also produced -{ + ps.getUntrackedParameter("enable2DComp")), // When true eta-phi comparison plots are also produced + displacedQuantities_(ps.getUntrackedParameter("displacedQuantities")) { // First include all bins for (unsigned int i = 1; i <= RIDX; i++) { incBin[i] = true; @@ -40,6 +40,7 @@ void L1TStage2MuonComp::fillDescriptions(edm::ConfigurationDescriptions& descrip desc.addUntracked>("ignoreBin", std::vector())->setComment("List of bins to ignore"); desc.addUntracked("verbose", false); desc.addUntracked("enable2DComp", false); + desc.addUntracked("displacedQuantities", false); descriptions.add("l1tStage2MuonComp", desc); } @@ -47,7 +48,11 @@ void L1TStage2MuonComp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru // Subsystem Monitoring and Muon Output ibooker.setCurrentFolder(monitorDir); - summary = ibooker.book1D("summary", summaryTitle.c_str(), 16, 1, 17); // range to match bin numbering + int numBins{16}; + if (displacedQuantities_) { + numBins += 2; + } + summary = ibooker.book1D("summary", summaryTitle.c_str(), numBins, 1, numBins + 1); // range to match bin numbering summary->setBinLabel(BXRANGEGOOD, "BX range match", 1); summary->setBinLabel(BXRANGEBAD, "BX range mismatch", 1); summary->setBinLabel(NMUONGOOD, "muon collection size match", 1); @@ -64,8 +69,16 @@ void L1TStage2MuonComp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru summary->setBinLabel(QUALBAD, "quality mismatch", 1); summary->setBinLabel(ISOBAD, "iso mismatch", 1); summary->setBinLabel(IDXBAD, "index mismatch", 1); + if (displacedQuantities_) { + summary->setBinLabel(PTUNCONSTRBAD, "p_{T} unconstrained mismatch", 1); + summary->setBinLabel(DXYBAD, "dXY mismatch", 1); + } - errorSummaryNum = ibooker.book1D("errorSummaryNum", summaryTitle.c_str(), 13, 1, 14); // range to match bin numbering + if (displacedQuantities_) { + numErrBins_ += 2; + } + errorSummaryNum = ibooker.book1D( + "errorSummaryNum", summaryTitle.c_str(), numErrBins_, 1, numErrBins_ + 1); // range to match bin numbering errorSummaryNum->setBinLabel(RBXRANGE, "BX range mismatch", 1); errorSummaryNum->setBinLabel(RNMUON, "muon collection size mismatch", 1); errorSummaryNum->setBinLabel(RMUON, "mismatching muons", 1); @@ -79,6 +92,10 @@ void L1TStage2MuonComp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru errorSummaryNum->setBinLabel(RQUAL, "quality mismatch", 1); errorSummaryNum->setBinLabel(RISO, "iso mismatch", 1); errorSummaryNum->setBinLabel(RIDX, "index mismatch", 1); + if (displacedQuantities_) { + errorSummaryNum->setBinLabel(RPTUNCONSTR, "p_{T} unconstrained mismatch", 1); + errorSummaryNum->setBinLabel(RDXY, "dXY mismatch", 1); + } // Change the label for those bins that will be ignored for (unsigned int i = 1; i <= RIDX; i++) { @@ -91,10 +108,11 @@ void L1TStage2MuonComp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru // This needs to come after the calls to setBinLabel. errorSummaryNum->getTH1F()->GetXaxis()->SetCanExtend(false); - errorSummaryDen = ibooker.book1D("errorSummaryDen", "denominators", 13, 1, 14); // range to match bin numbering + errorSummaryDen = ibooker.book1D( + "errorSummaryDen", "denominators", numErrBins_, 1, numErrBins_ + 1); // range to match bin numbering errorSummaryDen->setBinLabel(RBXRANGE, "# events", 1); errorSummaryDen->setBinLabel(RNMUON, "# muon collections", 1); - for (int i = RMUON; i <= RIDX; ++i) { + for (int i = RMUON; i <= numErrBins_; ++i) { errorSummaryDen->setBinLabel(i, "# muons", 1); } // Needed for correct histogram summing in multithreaded running. @@ -131,6 +149,17 @@ void L1TStage2MuonComp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru muColl1Index = ibooker.book1D("muIndexColl1", (muonColl1Title + " mismatching Input muon index").c_str(), 108, -0.5, 107.5); muColl1Index->setAxisTitle("Index", 1); + if (displacedQuantities_) { + muColl1hwPtUnconstrained = ibooker.book1D("muHwPtUnconstrainedColl1", + (muonColl1Title + " mismatching muon p_{T} unconstrained").c_str(), + 512, + -0.5, + 511.5); + muColl1hwPtUnconstrained->setAxisTitle("Hardware p_{T} unconstrained", 1); + muColl1hwDXY = + ibooker.book1D("muHwDXYColl1", (muonColl1Title + " mismatching impact parameter").c_str(), 4, -0.5, 3.5); + muColl1hwDXY->setAxisTitle("Hardware dXY", 1); + } // if enable2DComp variable is True, book also the eta-phi map if (enable2DComp) { @@ -171,6 +200,17 @@ void L1TStage2MuonComp::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru muColl2Index = ibooker.book1D("muIndexColl2", (muonColl2Title + " mismatching Input muon index").c_str(), 108, -0.5, 107.5); muColl2Index->setAxisTitle("Index", 1); + if (displacedQuantities_) { + muColl2hwPtUnconstrained = ibooker.book1D("muHwPtUnconstrainedColl2", + (muonColl2Title + " mismatching muon p_{T} unconstrained").c_str(), + 512, + -0.5, + 511.5); + muColl2hwPtUnconstrained->setAxisTitle("Hardware p_{T} unconstrained", 1); + muColl2hwDXY = + ibooker.book1D("muHwDXYColl2", (muonColl2Title + " mismatching impact parameter").c_str(), 4, -0.5, 3.5); + muColl2hwDXY->setAxisTitle("Hardware dXY", 1); + } // if enable2DdeMu variable is True, book also the eta-phi map if (enable2DComp) { @@ -238,8 +278,13 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { muColl1hwQual->Fill(muonIt1->hwQual()); muColl1hwIso->Fill(muonIt1->hwIso()); muColl1Index->Fill(muonIt1->tfMuonIndex()); - if (enable2DComp) + if (enable2DComp) { muColl1EtaPhimap->Fill(muonIt1->eta(), muonIt1->phi()); + } + if (displacedQuantities_) { + muColl1hwPtUnconstrained->Fill(muonIt1->hwPtUnconstrained()); + muColl1hwDXY->Fill(muonIt1->hwDXY()); + } } } else { muonIt2 = muonBxColl2->begin(iBx) + muonBxColl1->size(iBx); @@ -254,8 +299,13 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { muColl2hwQual->Fill(muonIt2->hwQual()); muColl2hwIso->Fill(muonIt2->hwIso()); muColl2Index->Fill(muonIt2->tfMuonIndex()); - if (enable2DComp) + if (enable2DComp) { muColl2EtaPhimap->Fill(muonIt2->eta(), muonIt2->phi()); + } + if (displacedQuantities_) { + muColl2hwPtUnconstrained->Fill(muonIt2->hwPtUnconstrained()); + muColl2hwDXY->Fill(muonIt2->hwDXY()); + } } } } else { @@ -266,7 +316,7 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { muonIt2 = muonBxColl2->begin(iBx); while (muonIt1 != muonBxColl1->end(iBx) && muonIt2 != muonBxColl2->end(iBx)) { summary->Fill(MUONALL); - for (int i = RMUON; i <= RIDX; ++i) { + for (int i = RMUON; i <= numErrBins_; ++i) { errorSummaryDen->Fill(i); } @@ -280,6 +330,24 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { errorSummaryNum->Fill(RPT); } } + if (displacedQuantities_) { + if (muonIt1->hwPtUnconstrained() != muonIt2->hwPtUnconstrained()) { + muonMismatch = true; + summary->Fill(PTUNCONSTRBAD); + if (incBin[RPTUNCONSTR]) { + muonSelMismatch = true; + errorSummaryNum->Fill(RPTUNCONSTR); + } + } + if (muonIt1->hwDXY() != muonIt2->hwDXY()) { + muonMismatch = true; + summary->Fill(DXYBAD); + if (incBin[RDXY]) { + muonSelMismatch = true; + errorSummaryNum->Fill(RDXY); + } + } + } if (muonIt1->hwEta() != muonIt2->hwEta()) { muonMismatch = true; summary->Fill(ETABAD); @@ -359,6 +427,10 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { if (muonMismatch) { muColl1hwPt->Fill(muonIt1->hwPt()); + if (displacedQuantities_) { + muColl1hwPtUnconstrained->Fill(muonIt1->hwPtUnconstrained()); + muColl1hwDXY->Fill(muonIt1->hwDXY()); + } muColl1hwEta->Fill(muonIt1->hwEta()); muColl1hwPhi->Fill(muonIt1->hwPhi()); muColl1hwEtaAtVtx->Fill(muonIt1->hwEtaAtVtx()); @@ -372,6 +444,10 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { muColl1EtaPhimap->Fill(muonIt1->eta(), muonIt1->phi()); muColl2hwPt->Fill(muonIt2->hwPt()); + if (displacedQuantities_) { + muColl2hwPtUnconstrained->Fill(muonIt2->hwPtUnconstrained()); + muColl2hwDXY->Fill(muonIt2->hwDXY()); + } muColl2hwEta->Fill(muonIt2->hwEta()); muColl2hwPhi->Fill(muonIt2->hwPhi()); muColl2hwEtaAtVtx->Fill(muonIt2->hwEtaAtVtx()); @@ -381,9 +457,9 @@ void L1TStage2MuonComp::analyze(const edm::Event& e, const edm::EventSetup& c) { muColl2hwQual->Fill(muonIt2->hwQual()); muColl2hwIso->Fill(muonIt2->hwIso()); muColl2Index->Fill(muonIt2->tfMuonIndex()); - if (enable2DComp) + if (enable2DComp) { muColl2EtaPhimap->Fill(muonIt2->eta(), muonIt2->phi()); - + } } else { summary->Fill(MUONGOOD); } diff --git a/DQM/L1TMonitor/src/L1TStage2RegionalMuonCandComp.cc b/DQM/L1TMonitor/src/L1TStage2RegionalMuonCandComp.cc index 9fa3271af4b5e..95f05d94d2734 100644 --- a/DQM/L1TMonitor/src/L1TStage2RegionalMuonCandComp.cc +++ b/DQM/L1TMonitor/src/L1TStage2RegionalMuonCandComp.cc @@ -82,7 +82,7 @@ void L1TStage2RegionalMuonCandComp::bookHistograms(DQMStore::IBooker& ibooker, summary->setBinLabel(TRACKADDRBAD, "track address mismatch", 1); if (isBmtf) { summary->setBinLabel(DXYBAD, "DXY mismatch", 1); - summary->setBinLabel(PT2BAD, "P_{T}2 mismatch", 1); + summary->setBinLabel(PT2BAD, "P_{T} unconstrained mismatch", 1); } int nbinsNum = 14; @@ -111,7 +111,7 @@ void L1TStage2RegionalMuonCandComp::bookHistograms(DQMStore::IBooker& ibooker, errorSummaryNum->setBinLabel(RTRACKADDR, "track address mismatch", 1); if (isBmtf) { errorSummaryNum->setBinLabel(RDXY, "DXY mismatch", 1); - errorSummaryNum->setBinLabel(RPT2, "P_{T}2 mismatch", 1); + errorSummaryNum->setBinLabel(RPT2, "P_{T} unconstrained mismatch", 1); } // Change the label for those bins that will be ignored @@ -198,9 +198,12 @@ void L1TStage2RegionalMuonCandComp::bookHistograms(DQMStore::IBooker& ibooker, if (isBmtf) { muColl1hwDXY = ibooker.book1D("muhwDXYColl1", (muonColl1Title + " HW DXY" + trkAddrIgnoreText).c_str(), 4, 0, 4); muColl1hwDXY->setAxisTitle("Hardware DXY", 1); - muColl1hwPt2 = - ibooker.book1D("muhwPt2Coll1", (muonColl1Title + "HW p_{T}2" + trkAddrIgnoreText).c_str(), 512, -0.5, 511.5); - muColl1hwPt2->setAxisTitle("Hardware P_{T}2", 1); + muColl1hwPtUnconstrained = ibooker.book1D("muhwPtUnconstrainedColl1", + (muonColl1Title + "HW p_{T} unconstrained" + trkAddrIgnoreText).c_str(), + 512, + -0.5, + 511.5); + muColl1hwPtUnconstrained->setAxisTitle("Hardware P_{T} unconstrained", 1); } muColl2BxRange = ibooker.book1D("muBxRangeColl2", (muonColl2Title + " mismatching BX range").c_str(), 11, -5.5, 5.5); @@ -266,9 +269,12 @@ void L1TStage2RegionalMuonCandComp::bookHistograms(DQMStore::IBooker& ibooker, if (isBmtf) { muColl2hwDXY = ibooker.book1D("muhwDXYColl2", (muonColl2Title + " HW DXY" + trkAddrIgnoreText).c_str(), 4, 0, 4); muColl2hwDXY->setAxisTitle("Hardware DXY", 1); - muColl2hwPt2 = - ibooker.book1D("muhwPt2Coll2", (muonColl2Title + "HW p_{T}2" + trkAddrIgnoreText).c_str(), 512, -0.5, 511.5); - muColl2hwPt2->setAxisTitle("Hardware P_{T}2", 1); + muColl2hwPtUnconstrained = ibooker.book1D("muhwPtUnconstrainedColl2", + (muonColl2Title + "HW p_{T} unconstrained" + trkAddrIgnoreText).c_str(), + 512, + -0.5, + 511.5); + muColl2hwPtUnconstrained->setAxisTitle("Hardware P_{T} unconstrained", 1); } } @@ -333,7 +339,7 @@ void L1TStage2RegionalMuonCandComp::analyze(const edm::Event& e, const edm::Even muColl1TrkAddrSize->Fill(muon1TrackAddr.size()); if (isBmtf) { muColl1hwDXY->Fill(muonIt1->hwDXY()); - muColl1hwPt2->Fill(muonIt1->hwPt2()); + muColl1hwPtUnconstrained->Fill(muonIt1->hwPtUnconstrained()); } for (std::map::const_iterator trIt1 = muon1TrackAddr.begin(); trIt1 != muon1TrackAddr.end(); ++trIt1) { @@ -357,7 +363,7 @@ void L1TStage2RegionalMuonCandComp::analyze(const edm::Event& e, const edm::Even muColl2TrkAddrSize->Fill(muon2TrackAddr.size()); if (isBmtf) { muColl2hwDXY->Fill(muonIt2->hwDXY()); - muColl2hwPt2->Fill(muonIt2->hwPt2()); + muColl2hwPtUnconstrained->Fill(muonIt2->hwPtUnconstrained()); } for (std::map::const_iterator trIt2 = muon2TrackAddr.begin(); trIt2 != muon2TrackAddr.end(); ++trIt2) { @@ -506,7 +512,7 @@ void L1TStage2RegionalMuonCandComp::analyze(const edm::Event& e, const edm::Even errorSummaryNum->Fill(RDXY); } } - if (muonIt1->hwPt2() != muonIt2->hwPt2()) { + if (muonIt1->hwPtUnconstrained() != muonIt2->hwPtUnconstrained()) { muonMismatch = true; summary->Fill(PT2BAD); if (incBin[RPT2]) { @@ -534,7 +540,7 @@ void L1TStage2RegionalMuonCandComp::analyze(const edm::Event& e, const edm::Even muColl1TrkAddrSize->Fill(muon1TrackAddr.size()); if (isBmtf) { muColl1hwDXY->Fill(muonIt1->hwDXY()); - muColl1hwPt2->Fill(muonIt1->hwPt2()); + muColl1hwPtUnconstrained->Fill(muonIt1->hwPtUnconstrained()); } for (std::map::const_iterator trIt1 = muon1TrackAddr.begin(); trIt1 != muon1TrackAddr.end(); ++trIt1) { @@ -554,7 +560,7 @@ void L1TStage2RegionalMuonCandComp::analyze(const edm::Event& e, const edm::Even muColl2TrkAddrSize->Fill(muon2TrackAddr.size()); if (isBmtf) { muColl2hwDXY->Fill(muonIt2->hwDXY()); - muColl2hwPt2->Fill(muonIt2->hwPt2()); + muColl2hwPtUnconstrained->Fill(muonIt2->hwPtUnconstrained()); } for (std::map::const_iterator trIt2 = muon2TrackAddr.begin(); trIt2 != muon2TrackAddr.end(); ++trIt2) { diff --git a/DQM/L1TMonitor/src/L1TStage2uGMT.cc b/DQM/L1TMonitor/src/L1TStage2uGMT.cc index d2b1dd28ecf99..780cd9598e7d8 100644 --- a/DQM/L1TMonitor/src/L1TStage2uGMT.cc +++ b/DQM/L1TMonitor/src/L1TStage2uGMT.cc @@ -5,6 +5,7 @@ L1TStage2uGMT::L1TStage2uGMT(const edm::ParameterSet& ps) monitorDir(ps.getUntrackedParameter("monitorDir")), emul(ps.getUntrackedParameter("emulator")), verbose(ps.getUntrackedParameter("verbose")), + displacedQuantities_(ps.getUntrackedParameter("displacedQuantities")), etaScale_(0.010875), // eta scale (CMS DN-2015/017) phiScale_(0.010908) // phi scale (2*pi/576 HW values) { @@ -29,6 +30,7 @@ void L1TStage2uGMT::fillDescriptions(edm::ConfigurationDescriptions& description desc.addUntracked("emulator", false) ->setComment("Create histograms for muonProducer input only. xmtfProducer inputs are ignored."); desc.addUntracked("verbose", false); + desc.addUntracked("displacedQuantities", false); descriptions.add("l1tStage2uGMT", desc); } @@ -46,6 +48,15 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtBMTFhwPt = ibooker.book1D("ugmtBMTFhwPt", "uGMT BMTF Input HW p_{T}", 512, -0.5, 511.5); ugmtBMTFhwPt->setAxisTitle("Hardware p_{T}", 1); + if (displacedQuantities_) { + ugmtBMTFhwPtUnconstrained = + ibooker.book1D("ugmtBMTFhwPtUnconstrained", "uGMT BMTF Input HW p_{T} unconstrained", 256, -0.5, 255.5); + ugmtBMTFhwPtUnconstrained->setAxisTitle("Hardware p_{T} unconstrained", 1); + + ugmtBMTFhwDXY = ibooker.book1D("ugmtBMTFhwDXY", "uGMT BMTF Input HW impact parameter", 4, -0.5, 3.5); + ugmtBMTFhwDXY->setAxisTitle("Hardware dXY", 1); + } + ugmtBMTFhwEta = ibooker.book1D("ugmtBMTFhwEta", "uGMT BMTF Input HW #eta", 201, -100.5, 100.5); ugmtBMTFhwEta->setAxisTitle("Hardware #eta", 1); @@ -327,6 +338,15 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtMuonhwPt = ibooker.book1D("ugmtMuonhwPt", "uGMT Muon HW p_{T}", 512, -0.5, 511.5); ugmtMuonhwPt->setAxisTitle("Hardware p_{T}", 1); + if (displacedQuantities_) { + ugmtMuonhwPtUnconstrained = + ibooker.book1D("ugmtMuonhwPtUnconstrained", "uGMT Muon HW p_{T} unconstrained", 256, -0.5, 255.5); + ugmtMuonhwPtUnconstrained->setAxisTitle("Hardware p_{T} unconstrained", 1); + + ugmtMuonhwDXY = ibooker.book1D("ugmtMuonhwDXY", "uGMT Muon HW impact parameter", 4, -0.5, 3.5); + ugmtMuonhwDXY->setAxisTitle("Hardware dXY", 1); + } + ugmtMuonhwEta = ibooker.book1D("ugmtMuonhwEta", "uGMT Muon HW #eta", 461, -230.5, 230.5); ugmtMuonhwEta->setAxisTitle("Hardware Eta", 1); @@ -354,6 +374,12 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtMuonPt = ibooker.book1D("ugmtMuonPt", "uGMT Muon p_{T}", 128, -0.5, 255.5); ugmtMuonPt->setAxisTitle("p_{T} [GeV]", 1); + if (displacedQuantities_) { + ugmtMuonPtUnconstrained = + ibooker.book1D("ugmtMuonPtUnconstrained", "uGMT Muon p_{T} unconstrained", 128, -0.5, 255.5); + ugmtMuonPtUnconstrained->setAxisTitle("p_{T} unconstrained [GeV]", 1); + } + ugmtMuonEta = ibooker.book1D("ugmtMuonEta", "uGMT Muon #eta", 52, -2.6, 2.6); ugmtMuonEta->setAxisTitle("#eta", 1); @@ -660,6 +686,10 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { ++BMTF) { ugmtBMTFBX->Fill(itBX); ugmtBMTFhwPt->Fill(BMTF->hwPt()); + if (displacedQuantities_) { + ugmtBMTFhwPtUnconstrained->Fill(BMTF->hwPtUnconstrained()); + ugmtBMTFhwDXY->Fill(BMTF->hwDXY()); + } ugmtBMTFhwEta->Fill(BMTF->hwEta()); ugmtBMTFhwPhi->Fill(BMTF->hwPhi()); ugmtBMTFhwSign->Fill(BMTF->hwSign()); @@ -891,6 +921,10 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { ugmtMuonBX->Fill(itBX); ugmtMuonIndex->Fill(tfMuonIndex); ugmtMuonhwPt->Fill(Muon->hwPt()); + if (displacedQuantities_) { + ugmtMuonhwPtUnconstrained->Fill(Muon->hwPtUnconstrained()); + ugmtMuonhwDXY->Fill(Muon->hwDXY()); + } ugmtMuonhwEta->Fill(Muon->hwEta()); ugmtMuonhwPhi->Fill(Muon->hwPhi()); ugmtMuonhwEtaAtVtx->Fill(Muon->hwEtaAtVtx()); @@ -901,6 +935,9 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { ugmtMuonhwIso->Fill(Muon->hwIso()); ugmtMuonPt->Fill(Muon->pt()); + if (displacedQuantities_) { + ugmtMuonPtUnconstrained->Fill(Muon->ptUnconstrained()); + } ugmtMuonEta->Fill(Muon->eta()); ugmtMuonPhi->Fill(Muon->phi()); ugmtMuonEtaAtVtx->Fill(Muon->etaAtVtx()); diff --git a/DQM/L1TMonitor/src/L1TStage2uGMTMuon.cc b/DQM/L1TMonitor/src/L1TStage2uGMTMuon.cc index 07b55f9789ca8..d6f4c3675dd5d 100644 --- a/DQM/L1TMonitor/src/L1TStage2uGMTMuon.cc +++ b/DQM/L1TMonitor/src/L1TStage2uGMTMuon.cc @@ -5,7 +5,8 @@ L1TStage2uGMTMuon::L1TStage2uGMTMuon(const edm::ParameterSet& ps) monitorDir(ps.getUntrackedParameter("monitorDir")), titlePrefix(ps.getUntrackedParameter("titlePrefix")), verbose(ps.getUntrackedParameter("verbose")), - makeMuonAtVtxPlots(ps.getUntrackedParameter("makeMuonAtVtxPlots")) {} + makeMuonAtVtxPlots(ps.getUntrackedParameter("makeMuonAtVtxPlots")), + displacedQuantities_(ps.getUntrackedParameter("displacedQuantities")) {} L1TStage2uGMTMuon::~L1TStage2uGMTMuon() {} @@ -17,6 +18,7 @@ void L1TStage2uGMTMuon::fillDescriptions(edm::ConfigurationDescriptions& descrip desc.addUntracked("titlePrefix", "")->setComment("Prefix text for the histogram titles."); desc.addUntracked("verbose", false); desc.addUntracked("makeMuonAtVtxPlots", false); + desc.addUntracked("displacedQuantities", false); descriptions.add("l1tStage2uGMTMuon", desc); } @@ -33,6 +35,15 @@ void L1TStage2uGMTMuon::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru ugmtMuonhwPt = ibooker.book1D("ugmtMuonhwPt", (titlePrefix + "HW p_{T}").c_str(), 512, -0.5, 511.5); ugmtMuonhwPt->setAxisTitle("Hardware p_{T}", 1); + if (displacedQuantities_) { + ugmtMuonhwPtUnconstrained = + ibooker.book1D("ugmtMuonhwPtUnconstrained", (titlePrefix + "HW p_{T} unconstrained").c_str(), 256, -0.5, 255.5); + ugmtMuonhwPtUnconstrained->setAxisTitle("Hardware p_{T} unconstrained", 1); + + ugmtMuonhwDXY = ibooker.book1D("ugmtMuonhwDXY", (titlePrefix + "HW impact parameter").c_str(), 4, -0.5, 3.5); + ugmtMuonhwDXY->setAxisTitle("Hardware dXY", 1); + } + ugmtMuonhwEta = ibooker.book1D("ugmtMuonhwEta", (titlePrefix + "HW #eta").c_str(), 461, -230.5, 230.5); ugmtMuonhwEta->setAxisTitle("Hardware Eta", 1); @@ -51,6 +62,12 @@ void L1TStage2uGMTMuon::bookHistograms(DQMStore::IBooker& ibooker, const edm::Ru ugmtMuonPt = ibooker.book1D("ugmtMuonPt", (titlePrefix + "p_{T}").c_str(), 128, -0.5, 255.5); ugmtMuonPt->setAxisTitle("p_{T} [GeV]", 1); + if (displacedQuantities_) { + ugmtMuonPtUnconstrained = + ibooker.book1D("ugmtMuonPtUnconstrained", (titlePrefix + "p_{T} unconstrained").c_str(), 128, -0.5, 255.5); + ugmtMuonPtUnconstrained->setAxisTitle("p_{T} unconstrained [GeV]", 1); + } + ugmtMuonEta = ibooker.book1D("ugmtMuonEta", (titlePrefix + "#eta").c_str(), 52, -2.6, 2.6); ugmtMuonEta->setAxisTitle("#eta", 1); @@ -162,6 +179,11 @@ void L1TStage2uGMTMuon::analyze(const edm::Event& e, const edm::EventSetup& c) { ++Muon) { ugmtMuonBX->Fill(itBX); ugmtMuonhwPt->Fill(Muon->hwPt()); + if (displacedQuantities_) { + ugmtMuonhwPtUnconstrained->Fill(Muon->hwPtUnconstrained()); + ugmtMuonhwDXY->Fill(Muon->hwDXY()); + ugmtMuonPtUnconstrained->Fill(Muon->ptUnconstrained()); + } ugmtMuonhwEta->Fill(Muon->hwEta()); ugmtMuonhwPhi->Fill(Muon->hwPhi()); ugmtMuonhwCharge->Fill(Muon->hwCharge()); diff --git a/DQM/SiStripMonitorSummary/interface/SiStripClassToMonitorCondData.h b/DQM/SiStripMonitorSummary/interface/SiStripClassToMonitorCondData.h index be4998c021dc2..5eb462de81412 100644 --- a/DQM/SiStripMonitorSummary/interface/SiStripClassToMonitorCondData.h +++ b/DQM/SiStripMonitorSummary/interface/SiStripClassToMonitorCondData.h @@ -74,15 +74,15 @@ class SiStripClassToMonitorCondData { std::string outPutFileName; - SiStripPedestalsDQM *pedestalsDQM_; - SiStripNoisesDQM *noisesDQM_; - SiStripQualityDQM *qualityDQM_; - SiStripApvGainsDQM *apvgainsDQM_; - SiStripLorentzAngleDQM *lorentzangleDQM_; - SiStripBackPlaneCorrectionDQM *bpcorrectionDQM_; - SiStripCablingDQM *cablingDQM_; - SiStripThresholdDQM *lowthresholdDQM_; - SiStripThresholdDQM *highthresholdDQM_; + std::unique_ptr pedestalsDQM_; + std::unique_ptr noisesDQM_; + std::unique_ptr qualityDQM_; + std::unique_ptr apvgainsDQM_; + std::unique_ptr lorentzangleDQM_; + std::unique_ptr bpcorrectionDQM_; + std::unique_ptr cablingDQM_; + std::unique_ptr lowthresholdDQM_; + std::unique_ptr highthresholdDQM_; }; #endif diff --git a/DQM/SiStripMonitorSummary/src/SiStripClassToMonitorCondData.cc b/DQM/SiStripMonitorSummary/src/SiStripClassToMonitorCondData.cc index a8ffd61b95372..ab93af84fde54 100644 --- a/DQM/SiStripMonitorSummary/src/SiStripClassToMonitorCondData.cc +++ b/DQM/SiStripMonitorSummary/src/SiStripClassToMonitorCondData.cc @@ -74,35 +74,7 @@ SiStripClassToMonitorCondData::SiStripClassToMonitorCondData(edm::ParameterSet c // // ----- Destructor // -SiStripClassToMonitorCondData::~SiStripClassToMonitorCondData() { - if (monitorPedestals_) { - delete pedestalsDQM_; - } - if (monitorNoises_) { - delete noisesDQM_; - } - if (monitorQuality_) { - delete qualityDQM_; - } - if (monitorApvGains_) { - delete apvgainsDQM_; - } - if (monitorLorentzAngle_) { - delete lorentzangleDQM_; - } - if (monitorBackPlaneCorrection_) { - delete bpcorrectionDQM_; - } - if (monitorLowThreshold_) { - delete lowthresholdDQM_; - } - if (monitorHighThreshold_) { - delete highthresholdDQM_; - } - if (monitorCabling_) { - delete cablingDQM_; - } -} +SiStripClassToMonitorCondData::~SiStripClassToMonitorCondData() {} // ----- // @@ -110,67 +82,72 @@ SiStripClassToMonitorCondData::~SiStripClassToMonitorCondData() { // void SiStripClassToMonitorCondData::beginRun(edm::RunNumber_t iRun, edm::EventSetup const &eSetup) { if (monitorPedestals_) { - pedestalsDQM_ = new SiStripPedestalsDQM(eSetup, - iRun, - conf_.getParameter("SiStripPedestalsDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + pedestalsDQM_ = + std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripPedestalsDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorNoises_) { - noisesDQM_ = new SiStripNoisesDQM(eSetup, - iRun, - conf_.getParameter("SiStripNoisesDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + noisesDQM_ = std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripNoisesDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorQuality_) { - qualityDQM_ = new SiStripQualityDQM(eSetup, - iRun, - conf_.getParameter("SiStripQualityDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + qualityDQM_ = std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripQualityDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorApvGains_) { - apvgainsDQM_ = new SiStripApvGainsDQM(eSetup, - iRun, - conf_.getParameter("SiStripApvGainsDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + apvgainsDQM_ = + std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripApvGainsDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorLorentzAngle_) { - lorentzangleDQM_ = new SiStripLorentzAngleDQM(eSetup, - iRun, - conf_.getParameter("SiStripLorentzAngleDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + lorentzangleDQM_ = + std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripLorentzAngleDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorBackPlaneCorrection_) { - bpcorrectionDQM_ = - new SiStripBackPlaneCorrectionDQM(eSetup, - iRun, - conf_.getParameter("SiStripBackPlaneCorrectionDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + bpcorrectionDQM_ = std::make_unique( + eSetup, + iRun, + conf_.getParameter("SiStripBackPlaneCorrectionDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorLowThreshold_) { - lowthresholdDQM_ = new SiStripThresholdDQM(eSetup, - iRun, - conf_.getParameter("SiStripLowThresholdDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + lowthresholdDQM_ = + std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripLowThresholdDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorHighThreshold_) { - highthresholdDQM_ = new SiStripThresholdDQM(eSetup, - iRun, - conf_.getParameter("SiStripHighThresholdDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + highthresholdDQM_ = + std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripHighThresholdDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } if (monitorCabling_) { - cablingDQM_ = new SiStripCablingDQM(eSetup, - iRun, - conf_.getParameter("SiStripCablingDQM_PSet"), - conf_.getParameter("FillConditions_PSet")); + cablingDQM_ = std::make_unique(eSetup, + iRun, + conf_.getParameter("SiStripCablingDQM_PSet"), + conf_.getParameter("FillConditions_PSet")); } } // beginRun // ----- diff --git a/DQMOffline/Alignment/python/ALCARECOTkAlDQM_cff.py b/DQMOffline/Alignment/python/ALCARECOTkAlDQM_cff.py index fe49f2b1afb02..e7a1360fa1e42 100644 --- a/DQMOffline/Alignment/python/ALCARECOTkAlDQM_cff.py +++ b/DQMOffline/Alignment/python/ALCARECOTkAlDQM_cff.py @@ -675,6 +675,31 @@ #ALCARECOTkAlCosmicsRegional0TDQM = cms.Sequence( ALCARECOTkAlCosmicsRegional0TTrackingDQM + ALCARECOTkAlCosmicsRegional0TTkAlDQM +ALCARECOTkAlCosmicsRegional0THLTDQM) ALCARECOTkAlCosmicsRegional0TDQM = cms.Sequence( ALCARECOTkAlCosmicsRegional0TTrackingDQM + ALCARECOTkAlCosmicsRegional0TTkAlDQM ) +############################# +### TkAlCosmicsInCollisions0T ### +############################# +__selectionName = 'TkAlCosmicsInCollisions0T' +ALCARECOTkAlCosmicsInCollisions0TTrackingDQM = ALCARECOTkAlCosmicsCTF0TTrackingDQM.clone( +#names and desigantions + TrackProducer = 'ALCARECO'+__selectionName, + AlgoName = 'ALCARECO'+__selectionName, + BSFolderName = "AlCaReco/"+__selectionName+"/BeamSpot", +) +ALCARECOTkAlCosmicsInCollisions0TTkAlDQM = ALCARECOTkAlCosmicsCTF0TTkAlDQM.clone( +#names and desigantions + TrackProducer = 'ALCARECO'+__selectionName, + ReferenceTrackProducer = 'cosmictrackfinderP5', + AlgoName = 'ALCARECO'+__selectionName +) +from Alignment.CommonAlignmentProducer.ALCARECOTkAlCosmics0THLT_cff import ALCARECOTkAlCosmics0THLT +#ALCARECOTkAlCosmicsInCollisions0THLTDQM = hltMonBitSummary.clone( +# directory = "AlCaReco/"+__selectionName+"/HLTSummary", +# histLabel = __selectionName, +# HLTPaths = ["HLT_.*L1.*"], +# eventSetupPathsKey = ALCARECOTkAlCosmics0THLT.eventSetupPathsKey.value() +#) +#ALCARECOTkAlCosmicsInCollisions0TDQM = cms.Sequence( ALCARECOTkAlCosmicsInCollisions0TTrackingDQM + ALCARECOTkAlCosmicsInCollisions0TTkAlDQM +ALCARECOTkAlCosmicsInCollisions0THLTDQM) +ALCARECOTkAlCosmicsInCollisions0TDQM = cms.Sequence( ALCARECOTkAlCosmicsInCollisions0TTrackingDQM + ALCARECOTkAlCosmicsInCollisions0TTkAlDQM ) ########################################################################## ###### DQM modules for cosmic data taking with momentum measurement ###### diff --git a/DQMOffline/Configuration/python/DQMOfflineCosmics_SecondStep_cff.py b/DQMOffline/Configuration/python/DQMOfflineCosmics_SecondStep_cff.py index 69f0186b323d3..e9a5d70975785 100644 --- a/DQMOffline/Configuration/python/DQMOfflineCosmics_SecondStep_cff.py +++ b/DQMOffline/Configuration/python/DQMOfflineCosmics_SecondStep_cff.py @@ -11,6 +11,7 @@ from DQM.DTMonitorClient.dtDQMOfflineClients_Cosmics_cff import * from DQM.RPCMonitorClient.RPCTier0Client_cff import * from DQM.CSCMonitorModule.csc_dqm_offlineclient_cosmics_cff import * +from DQMOffline.Muon.gem_dqm_offline_client_cff import * from DQMServices.Components.DQMFEDIntegrityClient_cff import * DQMNone = cms.Sequence() @@ -27,6 +28,12 @@ DQMOfflineCosmics_SecondStepMuonDPG = cms.Sequence( dtClientsCosmics * rpcTier0Client * cscOfflineCosmicsClients ) + +from Configuration.Eras.Modifier_run3_GEM_cff import run3_GEM +_run3_GEM_DQMOfflineCosmics_SecondStepMuonDPG = DQMOfflineCosmics_SecondStepMuonDPG.copy() +_run3_GEM_DQMOfflineCosmics_SecondStepMuonDPG += gemClients +run3_GEM.toReplaceWith(DQMOfflineCosmics_SecondStepMuonDPG, _run3_GEM_DQMOfflineCosmics_SecondStepMuonDPG) + DQMOfflineCosmics_SecondStepFED = cms.Sequence( dqmFEDIntegrityClient ) DQMOfflineCosmics_SecondStep_PreDPG = cms.Sequence( diff --git a/DQMOffline/Configuration/python/DQMOfflineCosmics_cff.py b/DQMOffline/Configuration/python/DQMOfflineCosmics_cff.py index f897b2f46598f..ab141f80d108d 100644 --- a/DQMOffline/Configuration/python/DQMOfflineCosmics_cff.py +++ b/DQMOffline/Configuration/python/DQMOfflineCosmics_cff.py @@ -11,6 +11,7 @@ from DQM.DTMonitorModule.dtDQMOfflineSources_Cosmics_cff import * from DQM.RPCMonitorClient.RPCTier0Source_cff import * from DQM.CSCMonitorModule.csc_dqm_sourceclient_offline_cff import * +from DQMOffline.Muon.gem_dqm_offline_source_cff import * from DQM.EcalPreshowerMonitorModule.es_dqm_source_offline_cosmic_cff import * from DQM.CastorMonitor.castor_dqm_sourceclient_offline_cff import * @@ -33,6 +34,11 @@ rpcTier0Source * cscSources ) +from Configuration.Eras.Modifier_run3_GEM_cff import run3_GEM +_run3_GEM_DQMOfflineCosmicsMuonDPG = DQMOfflineCosmicsMuonDPG.copy() +_run3_GEM_DQMOfflineCosmicsMuonDPG += gemSources +run3_GEM.toReplaceWith(DQMOfflineCosmicsMuonDPG, _run3_GEM_DQMOfflineCosmicsMuonDPG) + DQMOfflineCosmicsCASTOR = cms.Sequence( castorSources ) DQMOfflineCosmicsPreDPG = cms.Sequence( DQMOfflineCosmicsDCS * diff --git a/DQMOffline/Configuration/python/DQMOfflineHeavyIons_SecondStep_cff.py b/DQMOffline/Configuration/python/DQMOfflineHeavyIons_SecondStep_cff.py index ff609f3beb87f..be01b91bf9392 100644 --- a/DQMOffline/Configuration/python/DQMOfflineHeavyIons_SecondStep_cff.py +++ b/DQMOffline/Configuration/python/DQMOfflineHeavyIons_SecondStep_cff.py @@ -11,6 +11,7 @@ from DQM.DTMonitorClient.dtDQMOfflineClients_cff import * from DQM.RPCMonitorClient.RPCTier0Client_cff import * from DQM.CSCMonitorModule.csc_dqm_offlineclient_collisions_cff import * +from DQMOffline.Muon.gem_dqm_offline_client_cff import * from DQMServices.Components.DQMFEDIntegrityClient_cff import * DQMNone = cms.Sequence() @@ -28,6 +29,11 @@ rpcTier0Client * cscOfflineCollisionsClients ) +from Configuration.Eras.Modifier_run3_GEM_cff import run3_GEM +_run3_GEM_DQMOfflineHeavyIons_SecondStepMuonDPG = DQMOfflineHeavyIons_SecondStepMuonDPG.copy() +_run3_GEM_DQMOfflineHeavyIons_SecondStepMuonDPG += gemClients +run3_GEM.toReplaceWith(DQMOfflineHeavyIons_SecondStepMuonDPG, _run3_GEM_DQMOfflineHeavyIons_SecondStepMuonDPG) + DQMOfflineHeavyIons_SecondStepFED = cms.Sequence( dqmFEDIntegrityClient ) DQMOfflineHeavyIons_SecondStep_PreDPG = cms.Sequence( diff --git a/DQMOffline/Configuration/python/DQMOfflineHeavyIons_cff.py b/DQMOffline/Configuration/python/DQMOfflineHeavyIons_cff.py index 1ef2794f77357..75de40d2cd6f9 100644 --- a/DQMOffline/Configuration/python/DQMOfflineHeavyIons_cff.py +++ b/DQMOffline/Configuration/python/DQMOfflineHeavyIons_cff.py @@ -13,6 +13,7 @@ from DQM.DTMonitorModule.dtDQMOfflineSources_HI_cff import * from DQM.RPCMonitorClient.RPCTier0Source_cff import * from DQM.CSCMonitorModule.csc_dqm_sourceclient_offline_cff import * +from DQMOffline.Muon.gem_dqm_offline_source_cff import * from DQM.BeamMonitor.AlcaBeamMonitorHeavyIons_cff import * DQMNone = cms.Sequence() @@ -37,6 +38,11 @@ rpcTier0Source * cscSources ) +from Configuration.Eras.Modifier_run3_GEM_cff import run3_GEM +_run3_GEM_DQMOfflineHeavyIonsMuonDPG = DQMOfflineHeavyIonsMuonDPG.copy() +_run3_GEM_DQMOfflineHeavyIonsMuonDPG += gemSources +run3_GEM.toReplaceWith(DQMOfflineHeavyIonsMuonDPG, _run3_GEM_DQMOfflineHeavyIonsMuonDPG) + DQMOfflineHeavyIonsPreDPG = cms.Sequence( DQMOfflineHeavyIonsDCS * DQMOfflineHeavyIonsL1T * DQMOfflineHeavyIonsEcal * diff --git a/DQMOffline/Configuration/python/DQMOffline_SecondStep_cff.py b/DQMOffline/Configuration/python/DQMOffline_SecondStep_cff.py index fdfc23ae61a91..870ca95a4a9c6 100644 --- a/DQMOffline/Configuration/python/DQMOffline_SecondStep_cff.py +++ b/DQMOffline/Configuration/python/DQMOffline_SecondStep_cff.py @@ -10,6 +10,7 @@ from DQM.DTMonitorClient.dtDQMOfflineClients_cff import * from DQM.RPCMonitorClient.RPCTier0Client_cff import * from DQM.CSCMonitorModule.csc_dqm_offlineclient_collisions_cff import * +from DQMOffline.Muon.gem_dqm_offline_client_cff import * from DQMOffline.Hcal.HcalDQMOfflinePostProcessor_cff import * from DQM.HcalTasks.OfflineHarvestingSequence_pp import * from DQMServices.Components.DQMFEDIntegrityClient_cff import * @@ -29,6 +30,11 @@ rpcTier0Client * cscOfflineCollisionsClients ) +from Configuration.Eras.Modifier_run3_GEM_cff import run3_GEM +_run3_GEM_DQMOffline_SecondStepMuonDPG = DQMOffline_SecondStepMuonDPG.copy() +_run3_GEM_DQMOffline_SecondStepMuonDPG += gemClients +run3_GEM.toReplaceWith(DQMOffline_SecondStepMuonDPG, _run3_GEM_DQMOffline_SecondStepMuonDPG) + DQMOffline_SecondStepHcal = cms.Sequence( hcalOfflineHarvesting ) DQMOffline_SecondStepHcal2 = cms.Sequence( HcalDQMOfflinePostProcessor ) @@ -189,6 +195,10 @@ muonQualityTests ) +_run3_GEM_DQMHarvestMuon = DQMHarvestMuon.copy() +_run3_GEM_DQMHarvestMuon += gemClients +run3_GEM.toReplaceWith(DQMHarvestMuon, _run3_GEM_DQMHarvestMuon) + DQMHarvestEcal = cms.Sequence( ecal_dqm_client_offline * es_dqm_client_offline ) diff --git a/DQMOffline/Configuration/python/DQMOffline_cff.py b/DQMOffline/Configuration/python/DQMOffline_cff.py index b00a5b93181b7..408e7af59621f 100644 --- a/DQMOffline/Configuration/python/DQMOffline_cff.py +++ b/DQMOffline/Configuration/python/DQMOffline_cff.py @@ -14,6 +14,7 @@ from DQM.DTMonitorModule.dtDQMOfflineSources_cff import * from DQM.RPCMonitorClient.RPCTier0Source_cff import * from DQM.CSCMonitorModule.csc_dqm_sourceclient_offline_cff import * +from DQMOffline.Muon.gem_dqm_offline_source_cff import * from DQM.CastorMonitor.castor_dqm_sourceclient_offline_cff import * from DQM.CTPPS.ctppsDQM_cff import * from DQM.SiTrackerPhase2.Phase2TrackerDQMFirstStep_cff import * @@ -42,10 +43,16 @@ ecal_dqm_source_offline + es_dqm_source_offline ) +#offline version of the online DQM: used in validation/certification DQMOfflineHcal = cms.Sequence( hcalOfflineSourceSequence ) +# offline DQM: used in Release validation DQMOfflineHcal2 = cms.Sequence( HcalDQMOfflineSequence ) +DQMOfflineHcalOnly = cms.Sequence( hcalOnlyOfflineSourceSequence ) + +DQMOfflineHcal2Only = cms.Sequence( RecHitsDQMOffline ) + DQMOfflineTrackerStrip = cms.Sequence( SiStripDQMTier0 ) DQMOfflineTrackerPixel = cms.Sequence( siPixelOfflineDQM_source ) @@ -54,6 +61,11 @@ rpcTier0Source * cscSources ) +from Configuration.Eras.Modifier_run3_GEM_cff import run3_GEM +_run3_GEM_DQMOfflineMuonDPG = DQMOfflineMuonDPG.copy() +_run3_GEM_DQMOfflineMuonDPG += gemSources +run3_GEM.toReplaceWith(DQMOfflineMuonDPG, _run3_GEM_DQMOfflineMuonDPG) + DQMOfflineCASTOR = cms.Sequence( castorSources ) DQMOfflineCTPPS = cms.Sequence( ctppsDQMOfflineSource ) @@ -215,6 +227,10 @@ muonMonitors ) +_run3_GEM_DQMOfflineMuon = DQMOfflineMuon.copy() +_run3_GEM_DQMOfflineMuon += gemSources +run3_GEM.toReplaceWith(DQMOfflineMuon, _run3_GEM_DQMOfflineMuon) + #Taus not created in pp conditions for HI from Configuration.Eras.Modifier_pp_on_AA_2018_cff import pp_on_AA_2018 _DQMOfflineTAU = cms.Sequence() diff --git a/DQMOffline/Configuration/python/autoDQM.py b/DQMOffline/Configuration/python/autoDQM.py index 600e825af3493..11744cb352c13 100644 --- a/DQMOffline/Configuration/python/autoDQM.py +++ b/DQMOffline/Configuration/python/autoDQM.py @@ -101,6 +101,15 @@ 'PostDQMOffline', 'DQMHarvestHcal2'], + 'hcalOnly': ['DQMOfflineHcalOnly', + 'PostDQMOffline', + 'DQMHarvestHcal'], + + 'hcal2Only': ['DQMOfflineHcal2Only', + 'PostDQMOffline', + 'DQMHarvestHcal2'], + + 'jetmet': ['DQMOfflineJetMET', 'PostDQMOffline', 'DQMHarvestJetMET+DQMCertJetMET'], diff --git a/DQMOffline/L1Trigger/src/L1TTauOffline.cc b/DQMOffline/L1Trigger/src/L1TTauOffline.cc index 397c0300b3747..97fcaff38df15 100644 --- a/DQMOffline/L1Trigger/src/L1TTauOffline.cc +++ b/DQMOffline/L1Trigger/src/L1TTauOffline.cc @@ -678,7 +678,7 @@ void L1TTauOffline::getProbeTaus(const edm::Event& iEvent, { const edm::Provenance* prov = antiele.provenance(); const std::vector psetsFromProvenance = - edm::parameterSet(*prov, iEvent.processHistory()).getParameter>("workingsPoints"); + edm::parameterSet(*prov, iEvent.processHistory()).getParameter>("workingPoints"); for (uint i = 0; i < psetsFromProvenance.size(); i++) { if (psetsFromProvenance[i] == AntiEleWP_) AntiEleWPIndex_ = i; diff --git a/DQMOffline/Muon/interface/GEMEfficiencyAnalyzer.h b/DQMOffline/Muon/interface/GEMEfficiencyAnalyzer.h new file mode 100644 index 0000000000000..09c82469535ef --- /dev/null +++ b/DQMOffline/Muon/interface/GEMEfficiencyAnalyzer.h @@ -0,0 +1,63 @@ +#ifndef DQMOffline_Muon_GEMEfficiencyAnalyzer_h +#define DQMOffline_Muon_GEMEfficiencyAnalyzer_h + +#include "DQMOffline/Muon/interface/GEMOfflineDQMBase.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "DataFormats/GEMRecHit/interface/GEMRecHitCollection.h" +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/MuonReco/interface/MuonSelectors.h" +#include "Geometry/GEMGeometry/interface/GEMGeometry.h" +#include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h" + +class GEMEfficiencyAnalyzer : public GEMOfflineDQMBase { +public: + explicit GEMEfficiencyAnalyzer(const edm::ParameterSet &); + ~GEMEfficiencyAnalyzer() override; + +protected: + void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override; + void analyze(const edm::Event &event, const edm::EventSetup &eventSetup) override; + +private: + void bookDetectorOccupancy( + DQMStore::IBooker &, const GEMStation *, const MEMapKey1 &, const TString &, const TString &); + void bookOccupancy(DQMStore::IBooker &, const MEMapKey2 &, const TString &, const TString &); + void bookResolution(DQMStore::IBooker &, const MEMapKey3 &, const TString &, const TString &); + + const GEMRecHit *findMatchedHit(const float, const GEMRecHitCollection::range &); + + edm::EDGetTokenT rechit_token_; + edm::EDGetTokenT > muon_token_; + + MuonServiceProxy *muon_service_; + + bool use_global_muon_; + float residual_x_cut_; + + std::vector pt_binning_; + int eta_nbins_; + double eta_low_; + double eta_up_; + + std::string folder_; + + TString title_; + TString matched_title_; + + MEMap1 me_detector_; + MEMap1 me_detector_matched_; + + MEMap2 me_muon_pt_; + MEMap2 me_muon_eta_; + MEMap2 me_muon_pt_matched_; + MEMap2 me_muon_eta_matched_; + + MEMap3 me_residual_x_; // local + MEMap3 me_residual_y_; // local + MEMap3 me_residual_phi_; // global + MEMap3 me_pull_x_; + MEMap3 me_pull_y_; +}; + +#endif // DQMOffline_Muon_GEMEfficiencyAnalyzer_h diff --git a/DQMOffline/Muon/interface/GEMEfficiencyHarvester.h b/DQMOffline/Muon/interface/GEMEfficiencyHarvester.h new file mode 100644 index 0000000000000..24f3889e9fb11 --- /dev/null +++ b/DQMOffline/Muon/interface/GEMEfficiencyHarvester.h @@ -0,0 +1,32 @@ +#ifndef DQMOffline_Muon_GEMEfficiencyHarvester_h +#define DQMOffline_Muon_GEMEfficiencyHarvester_h + +#include "DQMServices/Core/interface/DQMEDHarvester.h" +#include "DQMServices/Core/interface/DQMStore.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include +#include + +class GEMEfficiencyHarvester : public DQMEDHarvester { +public: + GEMEfficiencyHarvester(const edm::ParameterSet&); + ~GEMEfficiencyHarvester() override; + void dqmEndJob(DQMStore::IBooker&, DQMStore::IGetter&) override; + +private: + TProfile* computeEfficiency(const TH1F*, const TH1F*, const char*, const char*, const double confidence_level = 0.683); + + TH2F* computeEfficiency(const TH2F*, const TH2F*, const char*, const char*); + + std::vector splitString(std::string, const std::string); + std::tuple parseResidualName(std::string, const std::string); + + void doEfficiency(DQMStore::IBooker&, DQMStore::IGetter&); + void doResolution(DQMStore::IBooker&, DQMStore::IGetter&, const std::string); + + std::string folder_; + std::string log_category_; +}; + +#endif // DQMOffline_Muon_GEMEfficiencyHarvester_h diff --git a/DQMOffline/Muon/interface/GEMOfflineDQMBase.h b/DQMOffline/Muon/interface/GEMOfflineDQMBase.h new file mode 100644 index 0000000000000..dbd7a29252243 --- /dev/null +++ b/DQMOffline/Muon/interface/GEMOfflineDQMBase.h @@ -0,0 +1,179 @@ +#ifndef DQMOffline_Muon_GEMOfflineDQMBase_h +#define DQMOffline_Muon_GEMOfflineDQMBase_h + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "DQMServices/Core/interface/DQMEDAnalyzer.h" +#include "DQMServices/Core/interface/DQMStore.h" +#include "CondFormats/GEMObjects/interface/GEMeMap.h" +#include "DataFormats/MuonDetId/interface/GEMDetId.h" +#include "Geometry/GEMGeometry/interface/GEMGeometry.h" + +class GEMOfflineDQMBase : public DQMEDAnalyzer { +public: + explicit GEMOfflineDQMBase(const edm::ParameterSet&); + + typedef std::tuple MEMapKey1; // (region, station) + typedef std::tuple MEMapKey2; // (region, station, is odd superchamber) + typedef std::tuple MEMapKey3; // (region, station, is odd superchamber, ieta) + typedef std::map MEMap1; + typedef std::map MEMap2; + typedef std::map MEMap3; + + inline int getVFATNumber(const int, const int, const int); + inline int getVFATNumberByStrip(const int, const int, const int); + inline int getMaxVFAT(const int); + inline int getDetOccXBin(const int, const int, const int); + + int getDetOccXBin(const GEMDetId&, const edm::ESHandle&); + void setDetLabelsVFAT(MonitorElement*, const GEMStation*); + void setDetLabelsEta(MonitorElement*, const GEMStation*); + // the number of eta partitions per GEMChamber + int getNumEtaPartitions(const GEMStation*); + + template + TString convertKeyToStr(const AnyKey& key); + + template + void fillME(std::map&, const AnyKey&, const float); + + template + void fillME(std::map&, const AnyKey&, const float, const float y); + + template + inline bool checkRefs(const std::vector&); + + std::string log_category_; + + class BookingHelper { + public: + BookingHelper(DQMStore::IBooker& ibooker, const TString& name_suffix, const TString& title_suffix) + : ibooker_(&ibooker), name_suffix_(name_suffix), title_suffix_(title_suffix) {} + + ~BookingHelper() {} + + MonitorElement* book1D(TString name, + TString title, + int nbinsx, + double xlow, + double xup, + TString x_title = "", + TString y_title = "Entries") { + name += name_suffix_; + title += title_suffix_ + ";" + x_title + ";" + y_title; + return ibooker_->book1D(name, title, nbinsx, xlow, xup); + } + + MonitorElement* book1D(TString name, + TString title, + std::vector& x_binning, + TString x_title = "", + TString y_title = "Entries") { + name += name_suffix_; + title += title_suffix_ + ";" + x_title + ";" + y_title; + TH1F* h_obj = new TH1F(name, title, x_binning.size() - 1, &x_binning[0]); + return ibooker_->book1D(name, h_obj); + } + + MonitorElement* book2D(TString name, + TString title, + int nbinsx, + double xlow, + double xup, + int nbinsy, + double ylow, + double yup, + TString x_title = "", + TString y_title = "") { + name += name_suffix_; + title += title_suffix_ + ";" + x_title + ";" + y_title; + return ibooker_->book2D(name, title, nbinsx, xlow, xup, nbinsy, ylow, yup); + } + + private: + DQMStore::IBooker* ibooker_; + const TString name_suffix_; + const TString title_suffix_; + }; // BookingHelper +}; + +inline int GEMOfflineDQMBase::getMaxVFAT(const int station) { + if (station == 1) + return GEMeMap::maxVFatGE11_; + else if (station == 2) + return GEMeMap::maxVFatGE21_; + else + return -1; +} + +inline int GEMOfflineDQMBase::getVFATNumber(const int station, const int ieta, const int vfat_phi) { + const int max_vfat = getMaxVFAT(station); + return max_vfat * (ieta - 1) + vfat_phi; +} + +inline int GEMOfflineDQMBase::getVFATNumberByStrip(const int station, const int ieta, const int strip) { + const int vfat_phi = (strip % GEMeMap::maxChan_) ? strip / GEMeMap::maxChan_ + 1 : strip / GEMeMap::maxChan_; + return getVFATNumber(station, ieta, vfat_phi); +}; + +inline int GEMOfflineDQMBase::getDetOccXBin(const int chamber, const int layer, const int n_chambers) { + return n_chambers * (chamber - 1) + layer; +} + +template +inline bool GEMOfflineDQMBase::checkRefs(const std::vector& refs) { + if (refs.empty()) + return false; + if (refs.front() == nullptr) + return false; + return true; +} + +template +TString GEMOfflineDQMBase::convertKeyToStr(const AnyKey& key) { + if constexpr (std::is_same_v) { + return TString::Format("Region %d, Station %d.", std::get<0>(key), std::get<1>(key)); + + } else if constexpr (std::is_same_v) { + const char* superchamber_type = std::get<2>(key) ? "Odd" : "Even"; + return TString::Format( + "Region %d, Station %d, %s Superchamber", std::get<0>(key), std::get<1>(key), superchamber_type); + + } else if constexpr (std::is_same_v) { + const char* superchamber_type = std::get<2>(key) ? "Odd" : "Even"; + return TString::Format("Region %d, Station %d, %s Superchamber, Roll %d", + std::get<0>(key), + std::get<1>(key), + superchamber_type, + std::get<3>(key)); + + } else { + return TString::Format("unknown key type: %s", typeid(key).name()); + } +} + +template +void GEMOfflineDQMBase::fillME(std::map& me_map, const AnyKey& key, const float x) { + if (me_map.find(key) == me_map.end()) { + const TString&& key_str = convertKeyToStr(key); + edm::LogError(log_category_) << "got invalid key: " << key_str << std::endl; + + } else { + me_map[key]->Fill(x); + } +} + +template +void GEMOfflineDQMBase::fillME(std::map& me_map, + const AnyKey& key, + const float x, + const float y) { + if (me_map.find(key) == me_map.end()) { + const TString&& key_str = convertKeyToStr(key); + edm::LogError(log_category_) << "got invalid key: " << key_str << std::endl; + + } else { + me_map[key]->Fill(x, y); + } +} + +#endif // DQMOffline_Muon_GEMOfflineDQMBase_h diff --git a/DQMOffline/Muon/interface/GEMOfflineMonitor.h b/DQMOffline/Muon/interface/GEMOfflineMonitor.h new file mode 100644 index 0000000000000..19063b5d5f77a --- /dev/null +++ b/DQMOffline/Muon/interface/GEMOfflineMonitor.h @@ -0,0 +1,34 @@ +#ifndef DQMOffline_Muon_GEMOfflineMonitor_h +#define DQMOffline_Muon_GEMOfflineMonitor_h + +#include "DQMOffline/Muon/interface/GEMOfflineDQMBase.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "DataFormats/GEMDigi/interface/GEMDigiCollection.h" +#include "DataFormats/GEMRecHit/interface/GEMRecHitCollection.h" + +class GEMOfflineMonitor : public GEMOfflineDQMBase { +public: + explicit GEMOfflineMonitor(const edm::ParameterSet &); + ~GEMOfflineMonitor() override; + static void fillDescriptions(edm::ConfigurationDescriptions &); + +protected: + void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override; + void analyze(const edm::Event &event, const edm::EventSetup &eventSetup) override; + +private: + void bookDetectorOccupancy( + DQMStore::IBooker &, const GEMStation *, const MEMapKey1 &, const TString &, const TString &); + + edm::EDGetTokenT digi_token_; + edm::EDGetTokenT rechit_token_; + + std::string log_category_; + + MEMap1 me_digi_det_; + MEMap1 me_hit_det_; +}; + +#endif // DQMOffline_Muon_GEMOfflineMonitor_h diff --git a/DQMOffline/Muon/python/gemEfficiencyAnalyzer_cfi.py b/DQMOffline/Muon/python/gemEfficiencyAnalyzer_cfi.py new file mode 100644 index 0000000000000..c284afb7ab195 --- /dev/null +++ b/DQMOffline/Muon/python/gemEfficiencyAnalyzer_cfi.py @@ -0,0 +1,62 @@ +import FWCore.ParameterSet.Config as cms +from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer +from RecoMuon.TrackingTools.MuonServiceProxy_cff import MuonServiceProxy + + +gemOfflineDQMTightGlbMuons = cms.EDFilter("MuonSelector", + src = cms.InputTag('muons'), + cut = cms.string( + '(pt > 20)' + '&& isGlobalMuon' + '&& globalTrack.isNonnull' + '&& passed(\'CutBasedIdTight\')' + ), + filter = cms.bool(False) +) + + +gemOfflineDQMStaMuons = cms.EDFilter("MuonSelector", + src = cms.InputTag('muons'), + cut = cms.string( + '(pt > 20)' + '&& isStandAloneMuon' + '&& outerTrack.isNonnull' + ), + filter = cms.bool(False) +) + + +gemEfficiencyAnalyzerTight = DQMEDAnalyzer('GEMEfficiencyAnalyzer', + MuonServiceProxy, + muonTag = cms.InputTag('gemOfflineDQMTightGlbMuons'), + recHitTag = cms.InputTag('gemRecHits'), + residualXCut = cms.double(5.0), + ptBinning = cms.untracked.vdouble(20. ,30., 40., 50., 60., 70., 80., 90., 100., 120., 140., 200.), + etaNbins = cms.untracked.int32(7), + etaLow = cms.untracked.double(1.5), + etaUp = cms.untracked.double(2.2), + useGlobalMuon = cms.untracked.bool(True), + folder = cms.untracked.string('GEM/GEMEfficiency/TightGlobalMuon'), + logCategory = cms.untracked.string('GEMEfficiencyAnalyzerTight'), +) + + +gemEfficiencyAnalyzerSTA = gemEfficiencyAnalyzerTight.clone() +gemEfficiencyAnalyzerSTA.muonTag = cms.InputTag("gemOfflineDQMStaMuons") +gemEfficiencyAnalyzerSTA.useGlobalMuon = cms.untracked.bool(False) +gemEfficiencyAnalyzerSTA.folder = cms.untracked.string('GEM/GEMEfficiency/StandaloneMuon') +gemEfficiencyAnalyzerSTA.logCategory = cms.untracked.string('GEMEfficiencyAnalyzerSTA') + + +from Configuration.Eras.Modifier_phase2_GEM_cff import phase2_GEM +phase2_GEM.toModify(gemEfficiencyAnalyzerTight, etaNbins=cms.untracked.int32(15), etaHigh=cms.untracked.double(3.0)) +phase2_GEM.toModify(gemEfficiencyAnalyzerSTA, etaNbins=cms.untracked.int32(15), etaHigh=cms.untracked.double(3.0)) + + +gemEfficiencyAnalyzerTightSeq = cms.Sequence( + cms.ignore(gemOfflineDQMTightGlbMuons) * + gemEfficiencyAnalyzerTight) + +gemEfficiencyAnalyzerSTASeq = cms.Sequence( + cms.ignore(gemOfflineDQMStaMuons) * + gemEfficiencyAnalyzerSTA) diff --git a/DQMOffline/Muon/python/gemEfficiencyHarvester_cfi.py b/DQMOffline/Muon/python/gemEfficiencyHarvester_cfi.py new file mode 100644 index 0000000000000..ff49777cec015 --- /dev/null +++ b/DQMOffline/Muon/python/gemEfficiencyHarvester_cfi.py @@ -0,0 +1,13 @@ +import FWCore.ParameterSet.Config as cms + +from DQMServices.Core.DQMEDHarvester import DQMEDHarvester + +gemEfficiencyHarvesterTight = DQMEDHarvester('GEMEfficiencyHarvester', + folder = cms.untracked.string('GEM/GEMEfficiency/TightGlobalMuon'), + logCategory = cms.untracked.string('GEMEfficiencyHarvesterTight') +) + +gemEfficiencyHarvesterSTA = DQMEDHarvester('GEMEfficiencyHarvester', + folder = cms.untracked.string('GEM/GEMEfficiency/StandaloneMuon'), + logCategory = cms.untracked.string('GEMEfficiencyHarvesterSTA') +) diff --git a/DQMOffline/Muon/python/gem_dqm_offline_client_cff.py b/DQMOffline/Muon/python/gem_dqm_offline_client_cff.py new file mode 100644 index 0000000000000..8d89e87148dec --- /dev/null +++ b/DQMOffline/Muon/python/gem_dqm_offline_client_cff.py @@ -0,0 +1,7 @@ +import FWCore.ParameterSet.Config as cms + +from DQMOffline.Muon.gemEfficiencyHarvester_cfi import * + +gemClients = cms.Sequence( + gemEfficiencyHarvesterTight * + gemEfficiencyHarvesterSTA) diff --git a/DQMOffline/Muon/python/gem_dqm_offline_source_cff.py b/DQMOffline/Muon/python/gem_dqm_offline_source_cff.py new file mode 100644 index 0000000000000..0af44227fde1e --- /dev/null +++ b/DQMOffline/Muon/python/gem_dqm_offline_source_cff.py @@ -0,0 +1,9 @@ +import FWCore.ParameterSet.Config as cms + +from DQMOffline.Muon.gemOfflineMonitor_cfi import * +from DQMOffline.Muon.gemEfficiencyAnalyzer_cfi import * + +gemSources = cms.Sequence( + gemOfflineMonitor * + gemEfficiencyAnalyzerTightSeq * + gemEfficiencyAnalyzerSTASeq) diff --git a/DQMOffline/Muon/src/GEMEfficiencyAnalyzer.cc b/DQMOffline/Muon/src/GEMEfficiencyAnalyzer.cc new file mode 100644 index 0000000000000..2cd3e91446cc4 --- /dev/null +++ b/DQMOffline/Muon/src/GEMEfficiencyAnalyzer.cc @@ -0,0 +1,281 @@ +#include "DQMOffline/Muon/interface/GEMEfficiencyAnalyzer.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +GEMEfficiencyAnalyzer::GEMEfficiencyAnalyzer(const edm::ParameterSet& pset) : GEMOfflineDQMBase(pset) { + rechit_token_ = consumes(pset.getParameter("recHitTag")); + muon_token_ = consumes >(pset.getParameter("muonTag")); + + auto muon_service_parameter = pset.getParameter("ServiceParameters"); + muon_service_ = new MuonServiceProxy(muon_service_parameter, consumesCollector()); + + use_global_muon_ = pset.getUntrackedParameter("useGlobalMuon"); + + residual_x_cut_ = static_cast(pset.getParameter("residualXCut")); + + pt_binning_ = pset.getUntrackedParameter >("ptBinning"); + eta_nbins_ = pset.getUntrackedParameter("etaNbins"); + eta_low_ = pset.getUntrackedParameter("etaLow"); + eta_up_ = pset.getUntrackedParameter("etaUp"); + + folder_ = pset.getUntrackedParameter("folder"); + + title_ = (use_global_muon_ ? "Global Muon" : "Standalone Muon"); + matched_title_ = title_ + TString::Format(" (|x_{Muon} - x_{Hit}| < %.1f)", residual_x_cut_); +} + +GEMEfficiencyAnalyzer::~GEMEfficiencyAnalyzer() {} + +void GEMEfficiencyAnalyzer::bookHistograms(DQMStore::IBooker& ibooker, + edm::Run const& run, + edm::EventSetup const& isetup) { + edm::ESHandle gem; + isetup.get().get(gem); + if (not gem.isValid()) { + edm::LogError(log_category_) << "GEMGeometry is invalid" << std::endl; + return; + } + + for (const GEMRegion* region : gem->regions()) { + const int region_number = region->region(); + const char* region_sign = region_number > 0 ? "+" : "-"; + + for (const GEMStation* station : region->stations()) { + const int station_number = station->station(); + + const MEMapKey1 key1{region_number, station_number}; + const auto&& station_name_suffix = TString::Format("_ge%s%d1", region_sign, station_number); + const auto&& station_title_suffix = TString::Format(" : GE %s%d/1", region_sign, station_number); + bookDetectorOccupancy(ibooker, station, key1, station_name_suffix, station_title_suffix); + + const int num_etas = getNumEtaPartitions(station); + + if (station_number == 1) { + for (const bool is_odd : {true, false}) { + std::tuple key2{region_number, station_number, is_odd}; + const TString&& parity_name_suffix = station_name_suffix + (is_odd ? "_odd" : "_even"); + const TString&& parity_title_suffix = + station_title_suffix + (is_odd ? ", Odd Superchamber" : ", Even Superchamber"); + bookOccupancy(ibooker, key2, parity_name_suffix, parity_title_suffix); + + for (int ieta = 1; ieta <= num_etas; ieta++) { + const TString&& ieta_name_suffix = parity_name_suffix + Form("_ieta%d", ieta); + const TString&& ieta_title_suffix = parity_title_suffix + Form(", i#eta = %d", ieta); + const MEMapKey3 key3{region_number, station_number, is_odd, ieta}; + bookResolution(ibooker, key3, ieta_name_suffix, ieta_title_suffix); + } // ieta + } // is_odd + + } else { + std::tuple key2{region_number, station_number, false}; + bookOccupancy(ibooker, key2, station_name_suffix, station_title_suffix); + + for (int ieta = 1; ieta <= num_etas; ieta++) { + const MEMapKey3 key3{region_number, station_number, false, ieta}; + const TString&& ieta_name_suffix = station_name_suffix + Form("_ieta%d", ieta); + const TString&& ieta_title_suffix = station_title_suffix + Form(", i#eta = %d", ieta); + bookResolution(ibooker, key3, ieta_name_suffix, ieta_title_suffix); + } // ieta + } + } // station + } // region +} + +void GEMEfficiencyAnalyzer::bookDetectorOccupancy(DQMStore::IBooker& ibooker, + const GEMStation* station, + const MEMapKey1& key, + const TString& name_suffix, + const TString& title_suffix) { + ibooker.setCurrentFolder(folder_ + "/Efficiency"); + BookingHelper helper(ibooker, name_suffix, title_suffix); + + const auto&& superchambers = station->superChambers(); + if (not checkRefs(superchambers)) { + edm::LogError(log_category_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl; + return; + } + + // the number of GEMChambers per GEMStation + const int num_ch = superchambers.size() * superchambers.front()->nChambers(); + // the number of eta partitions per GEMChamber + const int num_etas = getNumEtaPartitions(station); + + me_detector_[key] = helper.book2D("detector", title_, num_ch, 0.5, num_ch + 0.5, num_etas, 0.5, num_etas + 0.5); + + me_detector_matched_[key] = + helper.book2D("detector_matched", matched_title_, num_ch, 0.5, num_ch + 0.5, num_etas, 0.5, num_etas + 0.5); + + setDetLabelsEta(me_detector_[key], station); + setDetLabelsEta(me_detector_matched_[key], station); +} + +void GEMEfficiencyAnalyzer::bookOccupancy(DQMStore::IBooker& ibooker, + const MEMapKey2& key, + const TString& name_suffix, + const TString& title_suffix) { + ibooker.setCurrentFolder(folder_ + "/Efficiency"); + BookingHelper helper(ibooker, name_suffix, title_suffix); + + me_muon_pt_[key] = helper.book1D("muon_pt", title_, pt_binning_, "Muon p_{T} [GeV]"); + me_muon_eta_[key] = helper.book1D("muon_eta", title_, eta_nbins_, eta_low_, eta_up_, "Muon |#eta|"); + + me_muon_pt_matched_[key] = helper.book1D("muon_pt_matched", matched_title_, pt_binning_, "Muon p_{T} [GeV]"); + me_muon_eta_matched_[key] = + helper.book1D("muon_eta_matched", matched_title_, eta_nbins_, eta_low_, eta_up_, "Muon |#eta|"); +} + +void GEMEfficiencyAnalyzer::bookResolution(DQMStore::IBooker& ibooker, + const MEMapKey3& key, + const TString& name_suffix, + const TString& title_suffix) { + ibooker.setCurrentFolder(folder_ + "/Resolution"); + BookingHelper helper(ibooker, name_suffix, title_suffix); + + // NOTE Residual & Pull + me_residual_x_[key] = helper.book1D("residual_x", title_, 50, -5.0, 5.0, "Residual in Local X [cm]"); + me_residual_y_[key] = helper.book1D("residual_y", title_, 60, -12.0, 12.0, "Residual in Local Y [cm]"); + me_residual_phi_[key] = helper.book1D("residual_phi", title_, 80, -0.008, 0.008, "Residual in Global #phi [rad]"); + + me_pull_x_[key] = helper.book1D("pull_x", title_, 60, -3.0, 3.0, "Pull in Local X"); + me_pull_y_[key] = helper.book1D("pull_y", title_, 60, -3.0, 3.0, "Pull in Local Y"); +} + +void GEMEfficiencyAnalyzer::analyze(const edm::Event& event, const edm::EventSetup& setup) { + edm::Handle rechit_collection; + event.getByToken(rechit_token_, rechit_collection); + if (not rechit_collection.isValid()) { + edm::LogError(log_category_) << "GEMRecHitCollection is invalid" << std::endl; + return; + } + + edm::Handle > muon_view; + event.getByToken(muon_token_, muon_view); + if (not muon_view.isValid()) { + edm::LogError(log_category_) << "View is invalid" << std::endl; + } + + edm::ESHandle gem; + setup.get().get(gem); + if (not gem.isValid()) { + edm::LogError(log_category_) << "GEMGeometry is invalid" << std::endl; + return; + } + + edm::ESHandle transient_track_builder; + setup.get().get("TransientTrackBuilder", transient_track_builder); + if (not transient_track_builder.isValid()) { + edm::LogError(log_category_) << "TransientTrackRecord is invalid" << std::endl; + return; + } + + muon_service_->update(setup); + edm::ESHandle&& propagator = muon_service_->propagator("SteppingHelixPropagatorAny"); + if (not propagator.isValid()) { + edm::LogError(log_category_) << "Propagator is invalid" << std::endl; + return; + } + + for (const reco::Muon& muon : *muon_view) { + const reco::Track* track = nullptr; + + if (use_global_muon_ and muon.globalTrack().isNonnull()) { + track = muon.globalTrack().get(); + + } else if ((not use_global_muon_) and muon.outerTrack().isNonnull()) { + track = muon.outerTrack().get(); + } + + if (track == nullptr) { + edm::LogError(log_category_) << "failed to get muon track" << std::endl; + continue; + } + + const reco::TransientTrack&& transient_track = transient_track_builder->build(track); + if (not transient_track.isValid()) { + edm::LogInfo(log_category_) << "failed to build TransientTrack" << std::endl; + continue; + } + + for (const GEMEtaPartition* eta_partition : gem->etaPartitions()) { + // Skip propagation inn the opposite direction. + if (muon.eta() * eta_partition->id().region() < 0) + continue; + + const BoundPlane& bound_plane = eta_partition->surface(); + + const TrajectoryStateOnSurface&& tsos = + propagator->propagate(transient_track.outermostMeasurementState(), bound_plane); + if (not tsos.isValid()) { + continue; + } + + const LocalPoint&& tsos_local_pos = tsos.localPosition(); + const LocalPoint tsos_local_pos_2d(tsos_local_pos.x(), tsos_local_pos.y(), 0.0f); + if (not bound_plane.bounds().inside(tsos_local_pos_2d)) { + continue; + } + + const GEMDetId&& gem_id = eta_partition->id(); + + bool is_odd = gem_id.station() == 1 ? (gem_id.chamber() % 2 == 1) : false; + const std::tuple key1{gem_id.region(), gem_id.station()}; + const std::tuple key2{gem_id.region(), gem_id.station(), is_odd}; + const std::tuple key3{gem_id.region(), gem_id.station(), is_odd, gem_id.roll()}; + + const int chamber_bin = getDetOccXBin(gem_id, gem); + + fillME(me_detector_, key1, chamber_bin, gem_id.roll()); + fillME(me_muon_pt_, key2, muon.pt()); + fillME(me_muon_eta_, key2, std::fabs(muon.eta())); + + const GEMRecHit* matched_hit = findMatchedHit(tsos_local_pos.x(), rechit_collection->get(gem_id)); + if (matched_hit == nullptr) { + continue; + } + + fillME(me_detector_matched_, key1, chamber_bin, gem_id.roll()); + fillME(me_muon_pt_matched_, key2, muon.pt()); + fillME(me_muon_eta_matched_, key2, std::fabs(muon.eta())); + + const LocalPoint&& hit_local_pos = matched_hit->localPosition(); + const GlobalPoint&& hit_global_pos = eta_partition->toGlobal(hit_local_pos); + const GlobalPoint&& tsos_global_pos = tsos.globalPosition(); + + const float residual_x = tsos_local_pos.x() - hit_local_pos.x(); + const float residual_y = tsos_local_pos.y() - hit_local_pos.y(); + const float residual_phi = reco::deltaPhi(tsos_global_pos.barePhi(), hit_global_pos.barePhi()); + + const LocalError&& tsos_err = tsos.localError().positionError(); + const LocalError&& hit_err = matched_hit->localPositionError(); + + const float pull_x = residual_x / std::sqrt(tsos_err.xx() + hit_err.xx()); + const float pull_y = residual_y / std::sqrt(tsos_err.yy() + hit_err.yy()); + + fillME(me_residual_x_, key3, residual_x); + fillME(me_residual_y_, key3, residual_y); + fillME(me_residual_phi_, key3, residual_phi); + + fillME(me_pull_x_, key3, pull_x); + fillME(me_pull_y_, key3, pull_y); + } // GEMChamber + } // Muon +} + +const GEMRecHit* GEMEfficiencyAnalyzer::findMatchedHit(const float track_local_x, + const GEMRecHitCollection::range& range) { + float min_residual_x{residual_x_cut_}; + const GEMRecHit* closest_hit = nullptr; + + for (auto hit = range.first; hit != range.second; ++hit) { + float residual_x = std::fabs(track_local_x - hit->localPosition().x()); + if (residual_x <= min_residual_x) { + min_residual_x = residual_x; + closest_hit = &(*hit); + } + } + + return closest_hit; +} diff --git a/DQMOffline/Muon/src/GEMEfficiencyHarvester.cc b/DQMOffline/Muon/src/GEMEfficiencyHarvester.cc new file mode 100644 index 0000000000000..b014b207997e3 --- /dev/null +++ b/DQMOffline/Muon/src/GEMEfficiencyHarvester.cc @@ -0,0 +1,333 @@ +#include "DQMOffline/Muon/interface/GEMEfficiencyHarvester.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "TEfficiency.h" + +GEMEfficiencyHarvester::GEMEfficiencyHarvester(const edm::ParameterSet& pset) { + folder_ = pset.getUntrackedParameter("folder"); + log_category_ = pset.getUntrackedParameter("logCategory"); +} + +GEMEfficiencyHarvester::~GEMEfficiencyHarvester() {} + +TProfile* GEMEfficiencyHarvester::computeEfficiency( + const TH1F* passed, const TH1F* total, const char* name, const char* title, const double confidence_level) { + if (not TEfficiency::CheckConsistency(*passed, *total)) { + edm::LogError(log_category_) << "failed to pass TEfficiency::CheckConsistency. " << name << std::endl; + return nullptr; + } + + const TAxis* total_x = total->GetXaxis(); + + TProfile* eff_profile = new TProfile(name, title, total_x->GetNbins(), total_x->GetXmin(), total_x->GetXmax()); + eff_profile->GetXaxis()->SetTitle(total_x->GetTitle()); + eff_profile->GetYaxis()->SetTitle("#epsilon"); + + for (int bin = 1; bin < total->GetNbinsX(); bin++) { + double num_passed = passed->GetBinContent(bin); + double num_total = total->GetBinContent(bin); + + if (num_total < 1) { + eff_profile->SetBinEntries(bin, 0); + continue; + } + + double efficiency = num_passed / num_total; + + double lower_bound = TEfficiency::ClopperPearson(num_total, num_passed, confidence_level, false); + double upper_bound = TEfficiency::ClopperPearson(num_total, num_passed, confidence_level, true); + + double width = std::max(efficiency - lower_bound, upper_bound - efficiency); + double error = std::hypot(efficiency, width); + + eff_profile->SetBinContent(bin, efficiency); + eff_profile->SetBinError(bin, error); + eff_profile->SetBinEntries(bin, 1); + } + + return eff_profile; +} + +TH2F* GEMEfficiencyHarvester::computeEfficiency(const TH2F* passed, + const TH2F* total, + const char* name, + const char* title) { + if (not TEfficiency::CheckConsistency(*passed, *total)) { + edm::LogError(log_category_) << "failed to pass TEfficiency::CheckConsistency. " << name << std::endl; + return nullptr; + } + + TEfficiency eff(*passed, *total); + TH2F* eff_hist = dynamic_cast(eff.CreateHistogram()); + eff_hist->SetName(name); + eff_hist->SetTitle(title); + + const TAxis* total_x = total->GetXaxis(); + TAxis* eff_hist_x = eff_hist->GetXaxis(); + eff_hist_x->SetTitle(total_x->GetTitle()); + for (int bin = 1; bin <= total->GetNbinsX(); bin++) { + const char* label = total_x->GetBinLabel(bin); + eff_hist_x->SetBinLabel(bin, label); + } + + const TAxis* total_y = total->GetYaxis(); + TAxis* eff_hist_y = eff_hist->GetYaxis(); + eff_hist_y->SetTitle(total_y->GetTitle()); + for (int bin = 1; bin <= total->GetNbinsY(); bin++) { + const char* label = total_y->GetBinLabel(bin); + eff_hist_y->SetBinLabel(bin, label); + } + + return eff_hist; +} + +void GEMEfficiencyHarvester::doEfficiency(DQMStore::IBooker& ibooker, DQMStore::IGetter& igetter) { + const std::string efficiency_folder = folder_ + "/Efficiency/"; + ibooker.setCurrentFolder(efficiency_folder); + igetter.setCurrentFolder(efficiency_folder); + + std::map > me_pairs; + + const std::string matched = "_matched"; + + for (const std::string& name : igetter.getMEs()) { + const std::string fullpath = efficiency_folder + name; + const MonitorElement* me = igetter.get(fullpath); + if (me == nullptr) { + edm::LogError(log_category_) << "failed to get " << fullpath << std::endl; + continue; + } + + const bool is_matched = name.find(matched) != std::string::npos; + + std::string key = name; + if (is_matched) + key.erase(key.find(matched), matched.length()); + + if (me_pairs.find(key) == me_pairs.end()) { + me_pairs[key] = {nullptr, nullptr}; + } + + if (is_matched) + me_pairs[key].first = me; + else + me_pairs[key].second = me; + } + + for (auto&& [key, value] : me_pairs) { + const auto& [me_passed, me_total] = value; + if (me_passed == nullptr) { + edm::LogError(log_category_) << "numerator is missing. " << key << std::endl; + } + + if (me_total == nullptr) { + edm::LogError(log_category_) << "denominator is missing. " << key << std::endl; + continue; + } + + if (me_passed->kind() != me_total->kind()) { + edm::LogError(log_category_) << "inconsistency between kinds of passed and total" << key << std::endl; + continue; + } + + const std::string name = "eff_" + me_total->getName(); + const std::string title = me_passed->getTitle(); + + if (me_passed->kind() == MonitorElement::Kind::TH1F) { + TH1F* h_passed = me_passed->getTH1F(); + if (h_passed == nullptr) { + edm::LogError(log_category_) << "failed to get TH1F from passed " << key << std::endl; + continue; + } + h_passed->Sumw2(); + + TH1F* h_total = me_total->getTH1F(); + if (h_total == nullptr) { + edm::LogError(log_category_) << "failed to get TH1F from total" << key << std::endl; + continue; + } + h_total->Sumw2(); + + TProfile* eff = computeEfficiency(h_passed, h_total, name.c_str(), title.c_str()); + if (eff == nullptr) { + edm::LogError(log_category_) << "failed to compute the efficiency " << key << std::endl; + continue; + } + + ibooker.bookProfile(name, eff); + + } else if (me_passed->kind() == MonitorElement::Kind::TH2F) { + TH2F* h_passed = me_passed->getTH2F(); + if (h_passed == nullptr) { + edm::LogError(log_category_) << "failed to get TH1F from passed " << key << std::endl; + continue; + } + h_passed->Sumw2(); + + TH2F* h_total = me_total->getTH2F(); + if (h_total == nullptr) { + edm::LogError(log_category_) << "failed to get TH1F from total" << key << std::endl; + continue; + } + h_total->Sumw2(); + + TH2F* eff = computeEfficiency(h_passed, h_total, name.c_str(), title.c_str()); + if (eff == nullptr) { + edm::LogError(log_category_) << "failed to compute the efficiency " << key << std::endl; + continue; + } + + ibooker.book2D(name, eff); + + } else { + edm::LogError(log_category_) << "not implemented" << std::endl; + continue; + } + } // me_pairs +} + +std::vector GEMEfficiencyHarvester::splitString(std::string name, const std::string delimiter) { + std::vector tokens; + size_t delimiter_pos; + size_t delimiter_len = delimiter.length(); + while ((delimiter_pos = name.find('_')) != std::string::npos) { + tokens.push_back(name.substr(0, delimiter_pos)); + name.erase(0, delimiter_pos + delimiter_len); + } + tokens.push_back(name); + return tokens; +} + +std::tuple GEMEfficiencyHarvester::parseResidualName(const std::string org_name, + const std::string prefix) { + std::string name = org_name; + + // residual_x_ge-11_odd_ieta4 or residdual_x_ge+21_ieta3 + // residual_x: prefix + name.erase(name.find(prefix), prefix.length()); + name.erase(name.find("_ge"), 3); + + const std::vector&& tokens = splitString(name, "_"); + const size_t num_tokens = tokens.size(); + + if ((num_tokens != 2) and (num_tokens != 3)) { + return std::make_tuple("", -1, false, -1); + } + + // station != 1 + std::string region_sign = tokens.front().substr(0, 1); + + TString station_str = tokens.front().substr(1, 1); + TString ieta_str = tokens.back().substr(4, 1); + TString superchamber_str = (num_tokens == 3) ? tokens[1] : ""; + + int station = station_str.IsDigit() ? station_str.Atoi() : -1; + int ieta = ieta_str.IsDigit() ? ieta_str.Atoi() : -1; + + bool is_odd; + if (station == 1) { + if (superchamber_str.EqualTo("odd")) + is_odd = true; + else if (superchamber_str.EqualTo("even")) + is_odd = false; + else + return std::make_tuple("", -1, false, -1); + } else { + is_odd = false; + } + + return std::make_tuple(region_sign, station, is_odd, ieta); +} + +void GEMEfficiencyHarvester::doResolution(DQMStore::IBooker& ibooker, + DQMStore::IGetter& igetter, + const std::string prefix) { + const std::string resolution_folder = folder_ + "/Resolution/"; + + igetter.setCurrentFolder(resolution_folder); + ibooker.setCurrentFolder(resolution_folder); + + std::map, std::vector > > res_data; + + for (const std::string& name : igetter.getMEs()) { + if (name.find(prefix) == std::string::npos) + continue; + + const std::string fullpath = resolution_folder + name; + const MonitorElement* me = igetter.get(fullpath); + if (me == nullptr) { + edm::LogError(log_category_) << "failed to get " << fullpath << std::endl; + continue; + } + + TH1F* hist = me->getTH1F(); + if (hist == nullptr) { + edm::LogError(log_category_) << "failed to get TH1F" << std::endl; + continue; + } + + auto&& [region_sign, station, is_odd, ieta] = parseResidualName(name, prefix); + if (region_sign.empty() or station < 0 or ieta < 0) { + edm::LogError(log_category_) << "failed to parse the name of the residual histogram: " << name << std::endl; + continue; + } + + const std::tuple key{region_sign, station, is_odd}; + + if (res_data.find(key) == res_data.end()) { + res_data.insert({key, std::vector >()}); + } + res_data[key].emplace_back(ieta, hist); + } // MonitorElement + + ////////////////////////////////////////////////////////////////////////////// + // NOTE + ////////////////////////////////////////////////////////////////////////////// + for (auto [key, ieta_data] : res_data) { + if (ieta_data.empty()) { + continue; + } + + TString tmp_title{ieta_data.front().second->GetTitle()}; + const TObjArray* tokens = tmp_title.Tokenize(":"); + TString title = dynamic_cast(tokens->At(0))->GetString(); + + auto&& [region_sign, station, is_odd] = key; + TString&& name = TString::Format("%s_ge%s%d1", prefix.data(), region_sign.c_str(), station); + title += TString::Format("GE %s%d/1", region_sign.c_str(), station); + if (station == 1) { + name += (is_odd ? "_odd" : "_even"); + title += (is_odd ? ", Odd Superchambers" : ", Even Superchambers"); + } + + const int num_etas = ieta_data.size(); + + TH2F* profile = new TH2F(name, title, num_etas, 0.5, num_etas + 0.5, 2, -0.5, 1.5); + auto x_axis = profile->GetXaxis(); + + x_axis->SetTitle("i#eta"); + for (int ieta = 1; ieta <= num_etas; ieta++) { + const std::string&& label = std::to_string(ieta); + x_axis->SetBinLabel(ieta, label.c_str()); + } + + profile->GetYaxis()->SetBinLabel(1, "Mean"); + profile->GetYaxis()->SetBinLabel(2, "Std. Dev."); + + for (auto [ieta, hist] : ieta_data) { + profile->SetBinContent(ieta, 1, hist->GetMean()); + profile->SetBinContent(ieta, 2, hist->GetStdDev()); + + profile->SetBinError(ieta, 1, hist->GetMeanError()); + profile->SetBinError(ieta, 2, hist->GetStdDevError()); + } + + ibooker.book2D(name, profile); + } +} + +void GEMEfficiencyHarvester::dqmEndJob(DQMStore::IBooker& ibooker, DQMStore::IGetter& igetter) { + doEfficiency(ibooker, igetter); + doResolution(ibooker, igetter, "residual_phi"); +} diff --git a/DQMOffline/Muon/src/GEMOfflineDQMBase.cc b/DQMOffline/Muon/src/GEMOfflineDQMBase.cc new file mode 100644 index 0000000000000..c76249848e123 --- /dev/null +++ b/DQMOffline/Muon/src/GEMOfflineDQMBase.cc @@ -0,0 +1,91 @@ +#include "DQMOffline/Muon/interface/GEMOfflineDQMBase.h" + +GEMOfflineDQMBase::GEMOfflineDQMBase(const edm::ParameterSet& pset) { + log_category_ = pset.getUntrackedParameter("logCategory"); +} + +int GEMOfflineDQMBase::getDetOccXBin(const GEMDetId& gem_id, const edm::ESHandle& gem) { + const GEMSuperChamber* superchamber = gem->superChamber(gem_id); + if (superchamber == nullptr) { + return -1; + } + return getDetOccXBin(gem_id.chamber(), gem_id.layer(), superchamber->nChambers()); +} + +void GEMOfflineDQMBase::setDetLabelsVFAT(MonitorElement* me, const GEMStation* station) { + if (me == nullptr) { + edm::LogError(log_category_) << "MonitorElement* is nullptr" << std::endl; + return; + } + + me->setAxisTitle("Superchamber / Chamber", 1); + for (const GEMSuperChamber* superchamber : station->superChambers()) { + const int num_chambers = superchamber->nChambers(); + for (const GEMChamber* chamber : superchamber->chambers()) { + const int sc = chamber->id().chamber(); + const int ch = chamber->id().layer(); + const int xbin = getDetOccXBin(sc, ch, num_chambers); + const char* label = Form("%d/%d", sc, ch); + me->setBinLabel(xbin, label, 1); + } + } + + me->setAxisTitle("VFAT (i#eta)", 2); + const int max_vfat = getMaxVFAT(station->station()); + if (max_vfat < 0) { + edm::LogError(log_category_) << "Wrong max VFAT: " << max_vfat << " at Station " << station->station() << std::endl; + return; + } + + const int num_etas = getNumEtaPartitions(station); + for (int ieta = 1; ieta <= num_etas; ieta++) { + for (int vfat_phi = 1; vfat_phi <= max_vfat; vfat_phi++) { + const int ybin = getVFATNumber(station->station(), ieta, vfat_phi); + const char* label = Form("%d (%d)", ybin, ieta); + me->setBinLabel(ybin, label, 2); + } + } +} + +void GEMOfflineDQMBase::setDetLabelsEta(MonitorElement* me, const GEMStation* station) { + if (me == nullptr) { + edm::LogError(log_category_) << "MonitorElement* is nullptr" << std::endl; + return; + } + + me->setAxisTitle("Superchamber / Chamber", 1); + for (const GEMSuperChamber* superchamber : station->superChambers()) { + const int num_chambers = superchamber->nChambers(); + + for (const GEMChamber* chamber : superchamber->chambers()) { + const int sc = chamber->id().chamber(); + const int ch = chamber->id().layer(); + const int xbin = getDetOccXBin(sc, ch, num_chambers); + const char* label = Form("%d/%d", sc, ch); + me->setBinLabel(xbin, label, 1); + } + } + + const int num_etas = getNumEtaPartitions(station); + me->setAxisTitle("i#eta", 2); + for (int ieta = 1; ieta <= num_etas; ieta++) { + const std::string&& label = std::to_string(ieta); + me->setBinLabel(ieta, label, 2); + } +} + +int GEMOfflineDQMBase::getNumEtaPartitions(const GEMStation* station) { + const auto&& superchambers = station->superChambers(); + if (not checkRefs(superchambers)) { + edm::LogError(log_category_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl; + return 0; + } + + const auto& chambers = superchambers.front()->chambers(); + if (not checkRefs(chambers)) { + edm::LogError(log_category_) << "failed to get a valid vector of GEMChamber ptrs" << std::endl; + return 0; + } + + return chambers.front()->nEtaPartitions(); +} diff --git a/DQMOffline/Muon/src/GEMOfflineMonitor.cc b/DQMOffline/Muon/src/GEMOfflineMonitor.cc new file mode 100644 index 0000000000000..003ec3cd770e2 --- /dev/null +++ b/DQMOffline/Muon/src/GEMOfflineMonitor.cc @@ -0,0 +1,126 @@ +#include "DQMOffline/Muon/interface/GEMOfflineMonitor.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "Geometry/CommonTopologies/interface/StripTopology.h" +#include "Geometry/Records/interface/MuonGeometryRecord.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +GEMOfflineMonitor::GEMOfflineMonitor(const edm::ParameterSet& pset) : GEMOfflineDQMBase(pset) { + digi_token_ = consumes(pset.getParameter("digiTag")); + rechit_token_ = consumes(pset.getParameter("recHitTag")); +} + +GEMOfflineMonitor::~GEMOfflineMonitor() {} + +void GEMOfflineMonitor::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("digiTag", edm::InputTag("muonGEMDigis")); + desc.add("recHitTag", edm::InputTag("gemRecHits")); + desc.addUntracked("logCategory", "GEMOfflineMonitor"); + descriptions.add("gemOfflineMonitor", desc); +} + +void GEMOfflineMonitor::bookHistograms(DQMStore::IBooker& ibooker, edm::Run const& run, edm::EventSetup const& isetup) { + edm::ESHandle gem; + isetup.get().get(gem); + if (not gem.isValid()) { + edm::LogError(log_category_) << "GEMGeometry is invalid" << std::endl; + return; + } + + for (const GEMRegion* region : gem->regions()) { + const int region_number = region->region(); + const char* region_sign = region_number > 0 ? "+" : "-"; + + for (const GEMStation* station : region->stations()) { + const int station_number = station->station(); + + const MEMapKey1 det_key{region_number, station_number}; + const auto&& station_name = TString::Format("_ge%s%d1", region_sign, station_number); + const auto&& station_title = TString::Format(" : GE %s%d/1", region_sign, station_number); + bookDetectorOccupancy(ibooker, station, det_key, station_name, station_title); + } // station + } // region +} + +void GEMOfflineMonitor::bookDetectorOccupancy(DQMStore::IBooker& ibooker, + const GEMStation* station, + const MEMapKey1& key, + const TString& name_suffix, + const TString& title_suffix) { + BookingHelper helper(ibooker, name_suffix, title_suffix); + const auto&& superchambers = station->superChambers(); + if (not checkRefs(superchambers)) { + edm::LogError(log_category_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl; + return; + } + + // per station + const int num_superchambers = superchambers.size(); + const int num_chambers = num_superchambers * superchambers.front()->nChambers(); + // the numer of VFATs per GEMEtaPartition + const int max_vfat = getMaxVFAT(station->station()); + // the number of eta partitions per GEMChamber + const int num_etas = getNumEtaPartitions(station); + // the number of VFATs per GEMChamber + const int num_vfat = num_etas * max_vfat; + + // NOTE Digi + ibooker.setCurrentFolder("GEM/GEMOfflineMonitor/Digi"); + me_digi_det_[key] = + helper.book2D("digi_det", "Digi Occupancy", num_chambers, 0.5, num_chambers + 0.5, num_vfat, 0.5, num_vfat + 0.5); + setDetLabelsVFAT(me_digi_det_[key], station); + + // NOTE RecHit + ibooker.setCurrentFolder("GEM/GEMOfflineMonitor/RecHit"); + me_hit_det_[key] = + helper.book2D("hit_det", "Hit Occupancy", num_chambers, 0.5, num_chambers + 0.5, num_etas, 0.5, num_etas + 0.5); + setDetLabelsEta(me_hit_det_[key], station); +} + +void GEMOfflineMonitor::analyze(const edm::Event& event, const edm::EventSetup& setup) { + edm::Handle digi_collection; + event.getByToken(digi_token_, digi_collection); + if (not digi_collection.isValid()) { + edm::LogError(log_category_) << "GEMDigiCollection is invalid!" << std::endl; + return; + } + + edm::Handle rechit_collection; + event.getByToken(rechit_token_, rechit_collection); + if (not rechit_collection.isValid()) { + edm::LogError(log_category_) << "GEMRecHitCollection is invalid" << std::endl; + return; + } + + edm::ESHandle gem; + setup.get().get(gem); + if (not gem.isValid()) { + edm::LogError(log_category_) << "GEMGeometry is invalid" << std::endl; + return; + } + + // GEMDigi + for (auto range_iter = digi_collection->begin(); range_iter != digi_collection->end(); range_iter++) { + const GEMDetId& gem_id = (*range_iter).first; + const GEMDigiCollection::Range& range = (*range_iter).second; + + const MEMapKey1 det_key{gem_id.region(), gem_id.station()}; + for (auto digi = range.first; digi != range.second; ++digi) { + const int chamber_bin = getDetOccXBin(gem_id, gem); + const int vfat_number = getVFATNumberByStrip(gem_id.station(), gem_id.roll(), digi->strip()); + + fillME(me_digi_det_, det_key, chamber_bin, vfat_number); + } + } + + // GEMRecHit + for (auto hit = rechit_collection->begin(); hit != rechit_collection->end(); hit++) { + const GEMDetId&& gem_id = hit->gemId(); + const MEMapKey1 det_key{gem_id.region(), gem_id.station()}; + + const int chamber_bin = getDetOccXBin(gem_id, gem); + fillME(me_hit_det_, det_key, chamber_bin, gem_id.roll()); + } +} diff --git a/DQMOffline/Muon/src/SealModule.cc b/DQMOffline/Muon/src/SealModule.cc index 1a23411d23b42..53eddf5377dc2 100644 --- a/DQMOffline/Muon/src/SealModule.cc +++ b/DQMOffline/Muon/src/SealModule.cc @@ -21,6 +21,9 @@ #include "DQMOffline/Muon/interface/TriggerMatchMonitor.h" #include "DQMOffline/Muon/interface/TriggerMatchEfficiencyPlotter.h" +#include "DQMOffline/Muon/interface/GEMOfflineMonitor.h" +#include "DQMOffline/Muon/interface/GEMEfficiencyAnalyzer.h" +#include "DQMOffline/Muon/interface/GEMEfficiencyHarvester.h" DEFINE_FWK_MODULE(MuonTrackResidualsTest); DEFINE_FWK_MODULE(MuonRecoTest); @@ -39,3 +42,6 @@ DEFINE_FWK_MODULE(MuonSeedsAnalyzer); DEFINE_FWK_MODULE(MuonMiniAOD); DEFINE_FWK_MODULE(TriggerMatchMonitor); DEFINE_FWK_MODULE(TriggerMatchEfficiencyPlotter); +DEFINE_FWK_MODULE(GEMOfflineMonitor); +DEFINE_FWK_MODULE(GEMEfficiencyAnalyzer); +DEFINE_FWK_MODULE(GEMEfficiencyHarvester); diff --git a/DQMServices/FileIO/plugins/DQMFileSaverBase.cc b/DQMServices/FileIO/plugins/DQMFileSaverBase.cc index ce05a8100ae23..c5e7386e89161 100644 --- a/DQMServices/FileIO/plugins/DQMFileSaverBase.cc +++ b/DQMServices/FileIO/plugins/DQMFileSaverBase.cc @@ -8,6 +8,7 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/MessageLogger/interface/JobReport.h" #include "FWCore/Utilities/interface/TimeOfDay.h" +#include "DataFormats/Histograms/interface/DQMToken.h" #include "DQMFileSaverBase.h" @@ -37,6 +38,12 @@ DQMFileSaverBase::DQMFileSaverBase(const edm::ParameterSet &ps) { std::unique_lock lck(initial_fp_lock_); initial_fp_ = fp; + + runNumber_ = ps.getUntrackedParameter("runNumber", 111); + + // This makes sure a file saver runs in a very end + consumesMany(); + consumesMany(); } DQMFileSaverBase::~DQMFileSaverBase() = default; @@ -65,7 +72,7 @@ void DQMFileSaverBase::globalEndLuminosityBlock(const edm::LuminosityBlock &iLS, lck.unlock(); fp.lumi_ = ilumi; - fp.run_ = irun; + fp.run_ = runNumber_ == 111 ? irun : runNumber_; this->saveLumi(fp); } @@ -75,7 +82,7 @@ void DQMFileSaverBase::globalEndRun(const edm::Run &iRun, const edm::EventSetup FileParameters fp = initial_fp_; lck.unlock(); - fp.run_ = iRun.id().run(); + fp.run_ = runNumber_ == 111 ? iRun.id().run() : runNumber_; // empty this->saveRun(fp); @@ -140,4 +147,7 @@ void DQMFileSaverBase::fillDescription(edm::ParameterSetDescription &desc) { ->setComment("saveReference_, passed to the DQMStore"); desc.addUntracked("path", "./")->setComment("Output path prefix."); + + desc.addUntracked("runNumber", 111) + ->setComment("Run number passed in the configuration. Will appear in output file names."); } diff --git a/DQMServices/FileIO/plugins/DQMFileSaverBase.h b/DQMServices/FileIO/plugins/DQMFileSaverBase.h index 10e0ee3f97bd7..e277e8522c5bb 100644 --- a/DQMServices/FileIO/plugins/DQMFileSaverBase.h +++ b/DQMServices/FileIO/plugins/DQMFileSaverBase.h @@ -69,6 +69,7 @@ namespace dqm { // members mutable std::mutex initial_fp_lock_; FileParameters initial_fp_; + int runNumber_; public: static void fillDescription(edm::ParameterSetDescription &d); diff --git a/DQMServices/FileIO/plugins/DQMFileSaverPB.cc b/DQMServices/FileIO/plugins/DQMFileSaverPB.cc index 0aae3aa55d30a..6ad9c46cec6a6 100644 --- a/DQMServices/FileIO/plugins/DQMFileSaverPB.cc +++ b/DQMServices/FileIO/plugins/DQMFileSaverPB.cc @@ -13,6 +13,7 @@ #include #include #include +#include "zlib.h" #include "TString.h" #include "TSystem.h" #include "TBufferFile.h" @@ -32,9 +33,16 @@ using namespace dqm; DQMFileSaverPB::DQMFileSaverPB(const edm::ParameterSet& ps) : DQMFileSaverBase(ps) { fakeFilterUnitMode_ = ps.getUntrackedParameter("fakeFilterUnitMode", false); streamLabel_ = ps.getUntrackedParameter("streamLabel", "streamDQMHistograms"); + tag_ = ps.getUntrackedParameter("tag", "UNKNOWN"); transferDestination_ = ""; mergeType_ = ""; + + // If tag is set we're running in a DQM Live mode. + // Snapshot files will be saved for every client, then they will be merged and uploaded to the new DQM GUI. + if (tag_ != "UNKNOWN") { + streamLabel_ = "DQMLive"; + } } DQMFileSaverPB::~DQMFileSaverPB() = default; @@ -68,9 +76,17 @@ void DQMFileSaverPB::saveLumi(const FileParameters& fp) const { // create the files names if (fakeFilterUnitMode_) { std::string runDir = str(boost::format("%s/run%06d") % fp.path_ % fp.run_); - std::string baseName = str(boost::format("%s/run%06d_ls%04d_%s") % runDir % fp.run_ % fp.lumi_ % streamLabel_); - + std::string baseName = ""; boost::filesystem::create_directories(runDir); + // If tag is configured, append it to the name of the resulting file. + // This differentiates files saved by different clients. + // If tag is not configured, we don't add it at all to keep the old behaviour unchanged. + if (tag_ == "UNKNOWN") { + baseName = str(boost::format("%s/run%06d_ls%04d_%s") % runDir % fp.run_ % fp.lumi_ % streamLabel_); + } + else { + baseName = str(boost::format("%s/run%06d_%s_%s") % runDir % fp.run_ % tag_ % streamLabel_); + } jsonFilePathName = baseName + ".jsn"; openJsonFilePathName = jsonFilePathName + ".open"; @@ -234,10 +250,49 @@ void DQMFileSaverPB::savePB(DQMStore* store, std::string const& filename, int ru flags |= DQMNet::DQM_PROP_EFFICIENCY_PLOT; histo.set_flags(flags); histo.set_size(buffer.Length()); - histo.set_streamed_histo((void const*)buffer.Buffer(), buffer.Length()); - // Save quality reports if this is not in reference section. - // XXX not supported by protobuf files. + if (tag_ == "UNKNOWN") { + histo.set_streamed_histo((void const*)buffer.Buffer(), buffer.Length()); + } + else { + // Compress ME blob with zlib + int maxOutputSize = this->getMaxCompressedSize(buffer.Length()); + char compression_output[maxOutputSize]; + uLong total_out = this->compressME(buffer, maxOutputSize, compression_output); + histo.set_streamed_histo(compression_output, total_out); + } + + // Save quality reports + for (const auto& qr : me->getQReports()) { + std::string result; + // TODO: 64 is likely too short; memory corruption in the old code? + char buf[64]; + std::snprintf(buf, sizeof(buf), "qr=st:%d:%.*g:", qr->getStatus(), DBL_DIG + 2, qr->getQTresult()); + result = '<' + me->getName() + '.' + qr->getQRName() + '>'; + result += buf; + result += qr->getAlgorithm() + ':' + qr->getMessage(); + result += "getName() + '.' + qr->getQRName() + '>'; + TObjString str(result.c_str()); + + dqmstorepb::ROOTFilePB::Histo& qr_histo = *dqmstore_message.add_histo(); + TBufferFile qr_buffer(TBufferFile::kWrite); + qr_buffer.WriteObject(&str); + qr_histo.set_full_pathname(me->getFullname() + '.' + qr->getQRName()); + qr_histo.set_flags(static_cast(MonitorElement::Kind::STRING)); + qr_histo.set_size(qr_buffer.Length()); + // qr_histo.set_streamed_histo((void const*)qr_buffer.Buffer(), qr_buffer.Length()); + + if (tag_ == "UNKNOWN") { + qr_histo.set_streamed_histo((void const*)qr_buffer.Buffer(), qr_buffer.Length()); + } + else { + // Compress ME blob with zlib + int maxOutputSize = this->getMaxCompressedSize(qr_buffer.Length()); + char compression_output[maxOutputSize]; + uLong total_out = this->compressME(qr_buffer, maxOutputSize, compression_output); + qr_histo.set_streamed_histo(compression_output, total_out); + } + } // Save efficiency tag, if any. // XXX not supported by protobuf files. @@ -252,15 +307,26 @@ void DQMFileSaverPB::savePB(DQMStore* store, std::string const& filename, int ru int filedescriptor = ::open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); FileOutputStream file_stream(filedescriptor); - GzipOutputStream::Options options; - options.format = GzipOutputStream::GZIP; - options.compression_level = 1; - GzipOutputStream gzip_stream(&file_stream, options); - dqmstore_message.SerializeToZeroCopyStream(&gzip_stream); - - // Flush the internal streams before closing the fd. - gzip_stream.Close(); - file_stream.Close(); + if (tag_ == "UNKNOWN") { + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + options.compression_level = 1; + GzipOutputStream gzip_stream(&file_stream, options); + dqmstore_message.SerializeToZeroCopyStream(&gzip_stream); + + // Flush the internal streams + gzip_stream.Close(); + file_stream.Close(); + } + else { + // We zlib compressed individual MEs so no need to compress the entire file again. + dqmstore_message.SerializeToZeroCopyStream(&file_stream); + + // Flush the internal stream + file_stream.Close(); + } + + // Close the file descriptor ::close(filedescriptor); // Maybe make some noise. @@ -268,5 +334,32 @@ void DQMFileSaverPB::savePB(DQMStore* store, std::string const& filename, int ru << "into DQM file '" << filename << "'\n"; } +int DQMFileSaverPB::getMaxCompressedSize(int bufferSize) const { + // When input data is very badly compressable, zlib will add overhead instead of reducing the size. + // There is a minor amount of overhead (6 bytes overall and 5 bytes per 16K block) that is taken + // into consideration here to find out potential absolute maximum size of the output. + int n16kBlocks = (bufferSize + 16383) / 16384; // round up any fraction of a block + int maxOutputSize = bufferSize + 6 + (n16kBlocks * 5); + return maxOutputSize; +} + +ulong DQMFileSaverPB::compressME(const TBufferFile& buffer, int maxOutputSize, char* compression_output) const { + z_stream deflateStream; + deflateStream.zalloc = Z_NULL; + deflateStream.zfree = Z_NULL; + deflateStream.opaque = Z_NULL; + deflateStream.avail_in = (uInt)buffer.Length() + 1; // size of input, string + terminator + deflateStream.next_in = (Bytef *)buffer.Buffer(); // input array + deflateStream.avail_out = (uInt)maxOutputSize; // size of output + deflateStream.next_out = (Bytef *)compression_output; // output array, result will be placed here + + // The actual compression + deflateInit(&deflateStream, Z_BEST_COMPRESSION); + deflate(&deflateStream, Z_FINISH); + deflateEnd(&deflateStream); + + return deflateStream.total_out; +} + #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(DQMFileSaverPB); diff --git a/DQMServices/FileIO/plugins/DQMFileSaverPB.h b/DQMServices/FileIO/plugins/DQMFileSaverPB.h index 46a98e1319f15..062dfa7b6bc7e 100644 --- a/DQMServices/FileIO/plugins/DQMFileSaverPB.h +++ b/DQMServices/FileIO/plugins/DQMFileSaverPB.h @@ -34,11 +34,16 @@ namespace dqm { bool fakeFilterUnitMode_; std::string streamLabel_; + std::string tag_; mutable std::string transferDestination_; mutable std::string mergeType_; public: static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + private: + int getMaxCompressedSize(int bufferSize) const; + ulong compressME(const TBufferFile& buffer, int maxOutputSize, char* compression_output) const; }; } // namespace dqm diff --git a/DQMServices/FileIO/python/DQMFileSaverOnline_cfi.py b/DQMServices/FileIO/python/DQMFileSaverOnline_cfi.py index 7f0182017eba0..113855f560467 100644 --- a/DQMServices/FileIO/python/DQMFileSaverOnline_cfi.py +++ b/DQMServices/FileIO/python/DQMFileSaverOnline_cfi.py @@ -19,5 +19,7 @@ backupLumiCount = cms.untracked.int32(-1), # Set to true to preserve 'lumi backup'. - keepBackupLumi = cms.untracked.bool(False) + keepBackupLumi = cms.untracked.bool(False), + + runNumber = cms.untracked.int32(111), ) diff --git a/DQMServices/FileIO/python/DQMFileSaverPB_cfi.py b/DQMServices/FileIO/python/DQMFileSaverPB_cfi.py index ef1428e96eef3..6104d07aeb75a 100644 --- a/DQMServices/FileIO/python/DQMFileSaverPB_cfi.py +++ b/DQMServices/FileIO/python/DQMFileSaverPB_cfi.py @@ -19,4 +19,6 @@ fakeFilterUnitMode = cms.untracked.bool(False), # Label of the stream streamLabel = cms.untracked.string("streamDQMHistograms"), + + runNumber = cms.untracked.int32(111), ) diff --git a/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc b/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc index bd0b2afddadc8..1662d95621e3b 100644 --- a/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc +++ b/DataFormats/CSCDigi/src/CSCCorrelatedLCTDigi.cc @@ -133,7 +133,8 @@ void CSCCorrelatedLCTDigi::print() const { << " Quality = " << getQuality() << " Key Wire = " << getKeyWG() << " Strip = " << getStrip() << " Pattern = " << getPattern() << " Bend = " << ((getBend() == 0) ? 'L' : 'R') << " BX = " << getBX() - << " MPC Link = " << getMPCLink() << " HMT Bit = " << getHMT(); + << " MPC Link = " << getMPCLink() << " Type (SIM) = " << getType() + << " HMT Bit = " << getHMT(); } else { edm::LogVerbatim("CSCDigi") << "Not a valid correlated LCT."; } @@ -141,9 +142,11 @@ void CSCCorrelatedLCTDigi::print() const { std::ostream& operator<<(std::ostream& o, const CSCCorrelatedLCTDigi& digi) { return o << "CSC LCT #" << digi.getTrknmb() << ": Valid = " << digi.isValid() << " Quality = " << digi.getQuality() - << " MPC Link = " << digi.getMPCLink() << " cscID = " << digi.getCSCID() << "\n" + << " MPC Link = " << digi.getMPCLink() << " cscID = " << digi.getCSCID() + << " syncErr = " << digi.getSyncErr() << " Type (SIM) = " << digi.getType() << " HMT Bit = " << digi.getHMT() + << "\n" << " cathode info: Strip = " << digi.getStrip() << " Pattern = " << digi.getPattern() << " Bend = " << ((digi.getBend() == 0) ? 'L' : 'R') << "\n" - << " anode info: Key wire = " << digi.getKeyWG() << " BX = " << digi.getBX() << " bx0 = " << digi.getBX0() - << " syncErr = " << digi.getSyncErr() << " HMT Bit = " << digi.getHMT() << "\n"; + << " anode info: Key wire = " << digi.getKeyWG() << " BX = " << digi.getBX() + << " bx0 = " << digi.getBX0(); } diff --git a/DataFormats/HGCalReco/interface/Common.h b/DataFormats/HGCalReco/interface/Common.h index cbe7caf87117a..af1ad19f9ccb7 100644 --- a/DataFormats/HGCalReco/interface/Common.h +++ b/DataFormats/HGCalReco/interface/Common.h @@ -14,7 +14,20 @@ namespace ticl { static constexpr int nLayers = 104; static constexpr int iterations = 4; static constexpr int nBins = nEtaBins * nPhiBins; + static constexpr int type = 0; }; + + struct TileConstantsHFNose { + static constexpr float minEta = 3.0f; + static constexpr float maxEta = 4.2f; + static constexpr int nEtaBins = 24; + static constexpr int nPhiBins = 126; + static constexpr int nLayers = 16; // 8x2 + static constexpr int iterations = 4; + static constexpr int nBins = nEtaBins * nPhiBins; + static constexpr int type = 1; + }; + } // namespace ticl namespace ticl { diff --git a/DataFormats/HGCalReco/interface/TICLLayerTile.h b/DataFormats/HGCalReco/interface/TICLLayerTile.h index 01f0b2e3ca7b0..5d9cc8fb51a1c 100644 --- a/DataFormats/HGCalReco/interface/TICLLayerTile.h +++ b/DataFormats/HGCalReco/interface/TICLLayerTile.h @@ -14,6 +14,8 @@ class TICLLayerTileT { tile_[globalBin(eta, phi)].push_back(layerClusterId); } + int typeT() const { return T::type; } + int etaBin(float eta) const { constexpr float etaRange = T::maxEta - T::minEta; static_assert(etaRange >= 0.f); @@ -31,6 +33,14 @@ class TICLLayerTileT { return phiBin; } + std::array searchBoxEtaPhi(float etaMin, float etaMax, float phiMin, float phiMax) const { + int etaBinMin = etaBin(etaMin); + int etaBinMax = etaBin(etaMax); + int phiBinMin = phiBin(phiMin); + int phiBinMax = phiBin(phiMax); + return std::array({{etaBinMin, etaBinMax, phiBinMin, phiBinMax}}); + } + int globalBin(int etaBin, int phiBin) const { return phiBin + etaBin * T::nPhiBins; } int globalBin(double eta, double phi) const { return phiBin(phi) + etaBin(eta) * T::nPhiBins; } @@ -51,6 +61,11 @@ namespace ticl { using TICLLayerTile = TICLLayerTileT; using Tiles = std::array; using TracksterTiles = std::array; + + using TICLLayerTileHFNose = TICLLayerTileT; + using TilesHFNose = std::array; + using TracksterTilesHFNose = std::array; + } // namespace ticl template @@ -68,5 +83,7 @@ class TICLGenericTile { using TICLLayerTiles = TICLGenericTile; using TICLTracksterTiles = TICLGenericTile; +using TICLLayerTilesHFNose = TICLGenericTile; +using TICLTracksterTilesHFNose = TICLGenericTile; #endif diff --git a/DataFormats/HGCalReco/src/classes_def.xml b/DataFormats/HGCalReco/src/classes_def.xml index 1d88912bd9af1..4eb960800b479 100644 --- a/DataFormats/HGCalReco/src/classes_def.xml +++ b/DataFormats/HGCalReco/src/classes_def.xml @@ -25,6 +25,20 @@ + + + + + + + + + + + + + + diff --git a/DataFormats/L1TMuon/interface/RegionalMuonCand.h b/DataFormats/L1TMuon/interface/RegionalMuonCand.h index b9e9831de3693..92c0290dabb40 100644 --- a/DataFormats/L1TMuon/interface/RegionalMuonCand.h +++ b/DataFormats/L1TMuon/interface/RegionalMuonCand.h @@ -45,7 +45,7 @@ namespace l1t { RegionalMuonCand() : m_hwPt(0), - m_hwPt2(0), + m_hwPtUnconstrained(0), m_hwDXY(0), m_hwPhi(0), m_hwEta(0), @@ -59,7 +59,7 @@ namespace l1t { RegionalMuonCand(int pt, int phi, int eta, int sign, int signvalid, int quality, int processor, tftype trackFinder) : m_hwPt(pt), - m_hwPt2(0), + m_hwPtUnconstrained(0), m_hwDXY(0), m_hwPhi(phi), m_hwEta(eta), @@ -107,7 +107,7 @@ namespace l1t { tftype trackFinder, std::map trackAddress) : m_hwPt(pt), - m_hwPt2(0), + m_hwPtUnconstrained(0), m_hwDXY(0), m_hwPhi(phi), m_hwEta(eta), @@ -125,7 +125,7 @@ namespace l1t { /// Set compressed pT as transmitted by hardware LSB = 0.5 (9 bits) void setHwPt(int bits) { m_hwPt = bits; }; /// Set compressed second displaced pT as transmitted by hardware LSB = 1.0 (8 bits) - void setHwPt2(int bits) { m_hwPt2 = bits; }; + void setHwPtUnconstrained(int bits) { m_hwPtUnconstrained = bits; }; /// Set compressed impact parameter with respect to beamspot (4 bits) void setHwDXY(int bits) { m_hwDXY = bits; }; /// Set compressed relative phi as transmitted by hardware LSB = 2*pi/576 (8 bits) @@ -160,7 +160,7 @@ namespace l1t { /// Get compressed pT (returned int * 0.5 = pT (GeV)) const int hwPt() const { return m_hwPt; }; /// Get second compressed pT (returned int * 1.0 = pT (GeV)) - const int hwPt2() const { return m_hwPt2; }; + const int hwPtUnconstrained() const { return m_hwPtUnconstrained; }; /// Get compressed impact parameter (4 bits) const int hwDXY() const { return m_hwDXY; }; /// Get compressed local phi (returned int * 2*pi/576 = local phi in rad) @@ -201,7 +201,7 @@ namespace l1t { private: int m_hwPt; - int m_hwPt2; + int m_hwPtUnconstrained; int m_hwDXY; int m_hwPhi; int m_hwEta; diff --git a/DataFormats/L1TMuon/src/RegionalMuonCand.cc b/DataFormats/L1TMuon/src/RegionalMuonCand.cc index 51e85c3a9613a..861dee51c8725 100644 --- a/DataFormats/L1TMuon/src/RegionalMuonCand.cc +++ b/DataFormats/L1TMuon/src/RegionalMuonCand.cc @@ -25,9 +25,10 @@ namespace l1t { } bool RegionalMuonCand::operator==(const RegionalMuonCand& rhs) const { - return m_hwPt == rhs.hwPt() && m_hwPhi == rhs.hwPhi() && m_hwEta == rhs.hwEta() && m_hwHF == (bool)rhs.hwHF() && - m_hwSign == rhs.hwSign() && m_hwSignValid == rhs.hwSignValid() && m_hwQuality == rhs.hwQual() && - m_link == rhs.link() && m_processor == rhs.processor() && m_trackFinder == rhs.trackFinderType() && + return m_hwPt == rhs.hwPt() && m_hwPtUnconstrained == rhs.hwPtUnconstrained() && m_hwDXY == rhs.hwDXY() && + m_hwPhi == rhs.hwPhi() && m_hwEta == rhs.hwEta() && m_hwHF == (bool)rhs.hwHF() && m_hwSign == rhs.hwSign() && + m_hwSignValid == rhs.hwSignValid() && m_hwQuality == rhs.hwQual() && m_link == rhs.link() && + m_processor == rhs.processor() && m_trackFinder == rhs.trackFinderType() && m_trackAddress == rhs.trackAddress(); } diff --git a/DataFormats/L1TMuon/src/classes_def.xml b/DataFormats/L1TMuon/src/classes_def.xml index 84258a067d589..8acf940fba8a4 100644 --- a/DataFormats/L1TMuon/src/classes_def.xml +++ b/DataFormats/L1TMuon/src/classes_def.xml @@ -1,7 +1,14 @@ - + + + + + + + + @@ -63,7 +70,8 @@ - + + diff --git a/DataFormats/L1TrackTrigger/interface/TTDTC.h b/DataFormats/L1TrackTrigger/interface/TTDTC.h index a8c4a1fc8d54e..586301dd714c4 100644 --- a/DataFormats/L1TrackTrigger/interface/TTDTC.h +++ b/DataFormats/L1TrackTrigger/interface/TTDTC.h @@ -25,23 +25,10 @@ class TTDTC { // collection of optical links typedef std::vector Streams; -private: - // number of ATCA slots per shelf - static constexpr int numSlots_ = 12; - -public: TTDTC() {} TTDTC(int numRegions, int numOverlappingRegions, int numDTCsPerRegion); ~TTDTC() {} - // number of phi slices the outer tracker readout is organized in [default 9] - int numRegions() const { return numRegions_; } - // number of DTC boards used to readout a detector region [default 24] - int numDTCBoards() const { return numDTCsPerRegion_; } - // number of regions a reconstructable particle may cross [default 2] - int numDTCChannel() const { return numOverlappingRegions_; } - // number of DTC boards connected to one TFP [default 48] - int numTFPChannel() const { return numDTCsPerTFP_; } // all regions [default 0..8] const std::vector& tfpRegions() const { return regions_; } // all TFP channel [default 0..47] @@ -58,18 +45,6 @@ class TTDTC { int nStubs() const; // total number of gaps int nGaps() const; - // converts dtc id into tk layout scheme - int tkLayoutId(int dtcId) const; - // converts tk layout id into dtc id - int dtcId(int tkLayoutId) const; - // converts TFP identifier (region[0-8], channel[0-47]) into dtcId [0-215] - int dtcId(int tfpRegion, int tfpChannel) const; - // checks if given dtcId is connected to PS or 2S sensormodules - bool psModlue(int dtcId) const; - // checks if given dtcId is connected to -z (false) or +z (true) - bool side(int dtcId) const; - // ATCA slot number [0-11] of given dtcId - int slot(int dtcId) const; private: // converts DTC identifier (region[0-8], board[0-23], channel[0-1]) into allStreams_ index [0-431] diff --git a/DataFormats/L1TrackTrigger/interface/TTTrack.h b/DataFormats/L1TrackTrigger/interface/TTTrack.h index 7fbf3776246ab..afc30174a2468 100644 --- a/DataFormats/L1TrackTrigger/interface/TTTrack.h +++ b/DataFormats/L1TrackTrigger/interface/TTTrack.h @@ -212,7 +212,7 @@ TTTrack::TTTrack(double aRinv, double thePT = std::abs(MagConstant / aRinv * aBfield / 100.0); // Rinv is in cm-1 theMomentum_ = GlobalVector(GlobalVector::Cylindrical(thePT, aphi0, thePT * aTanlambda)); theRInv_ = aRinv; - thePOCA_ = GlobalPoint(ad0 * cos(aphi0), ad0 * sin(aphi0), az0); + thePOCA_ = GlobalPoint(ad0 * sin(aphi0), -ad0 * cos(aphi0), az0); theD0_ = ad0; theZ0_ = az0; thePhi_ = aphi0; diff --git a/DataFormats/L1TrackTrigger/src/TTDTC.cc b/DataFormats/L1TrackTrigger/src/TTDTC.cc index 29152e8217a07..ddeac7e007ab3 100644 --- a/DataFormats/L1TrackTrigger/src/TTDTC.cc +++ b/DataFormats/L1TrackTrigger/src/TTDTC.cc @@ -12,8 +12,8 @@ TTDTC::TTDTC(int numRegions, int numOverlappingRegions, int numDTCsPerRegion) numDTCsPerRegion_(numDTCsPerRegion), numDTCsPerTFP_(numOverlappingRegions * numDTCsPerRegion), regions_(numRegions_), - channels_(numDTCsPerRegion_ * numOverlappingRegions_), - streams_(numRegions_ * channels_.size()) { + channels_(numDTCsPerTFP_), + streams_(numRegions_ * numDTCsPerTFP_) { iota(regions_.begin(), regions_.end(), 0); iota(channels_.begin(), channels_.end(), 0); } @@ -86,56 +86,6 @@ int TTDTC::nGaps() const { return n; } -// converts dtc id into tk layout scheme -int TTDTC::tkLayoutId(int dtcId) const { - // check argument - if (dtcId < 0 || dtcId >= numDTCsPerRegion_ * numRegions_) { - cms::Exception exception("out_of_range"); - exception.addContext("TTDTC::tkLayoutId"); - exception << "Used DTC Id (" << dtcId << ") is out of range 0 to " << numDTCsPerRegion_ * numRegions_ - 1 << "."; - throw exception; - } - const int slot = dtcId % numSlots_; - const int region = dtcId / numDTCsPerRegion_; - const int side = (dtcId % numDTCsPerRegion_) / numSlots_; - return (side * numRegions_ + region) * numSlots_ + slot + 1; -} - -// converts tk layout id into dtc id -int TTDTC::dtcId(int tkLayoutId) const { - // check argument - if (tkLayoutId <= 0 || tkLayoutId > numDTCsPerRegion_ * numRegions_) { - cms::Exception exception("out_of_range"); - exception.addContext("TTDTC::dtcId"); - exception << "Used TKLayout Id (" << tkLayoutId << ") is out of range 1 to " << numDTCsPerRegion_ * numRegions_ - << "."; - throw exception; - } - const int tkId = tkLayoutId - 1; - const int side = tkId / (numRegions_ * numSlots_); - const int region = (tkId % (numRegions_ * numSlots_)) / numSlots_; - const int slot = tkId % numSlots_; - return region * numDTCsPerRegion_ + side * numSlots_ + slot; -} - -// converts TFP identifier (region[0-8], channel[0-47]) into dtc id -int TTDTC::dtcId(int tfpRegion, int tfpChannel) const { return index(tfpRegion, tfpChannel) / numOverlappingRegions_; } - -// checks if given DTC id is connected to PS or 2S sensormodules -bool TTDTC::psModlue(int dtcId) const { - // from tklayout: first 3 are 10 gbps PS, next 3 are 5 gbps PS and residual 6 are 5 gbps 2S modules - return slot(dtcId) < numSlots_ / 2; -} - -// checks if given dtcId is connected to -z (false) or +z (true) -bool TTDTC::side(int dtcId) const { - const int side = (dtcId % numDTCsPerRegion_) / numSlots_; - // from tkLayout: first 12 +z, next 12 -z - return side == 0; -} -// ATCA slot number [0-11] of given dtcId -int TTDTC::slot(int dtcId) const { return dtcId % numSlots_; } - // converts DTC identifier (region[0-8], board[0-23], channel[0-1]) into streams_ index [0-431] int TTDTC::index(int dtcRegion, int dtcBoard, int dtcChannel) const { return (dtcRegion * numDTCsPerRegion_ + dtcBoard) * numOverlappingRegions_ + dtcChannel; diff --git a/DataFormats/L1Trigger/interface/Muon.h b/DataFormats/L1Trigger/interface/Muon.h index d5a5227539202..3b30133cf8c0e 100644 --- a/DataFormats/L1Trigger/interface/Muon.h +++ b/DataFormats/L1Trigger/interface/Muon.h @@ -40,7 +40,10 @@ namespace l1t { int hwEtaAtVtx = 0, int hwPhiAtVtx = 0, double etaAtVtx = 0., - double phiAtVtx = 0.); + double phiAtVtx = 0., + int hwPtUnconstrained = 0, + double ptUnconstrained = 0., + int dXY = 0); Muon(const PolarLorentzVector& p4, int pt = 0, @@ -60,7 +63,10 @@ namespace l1t { int hwEtaAtVtx = 0, int hwPhiAtVtx = 0, double etaAtVtx = 0., - double phiAtVtx = 0.); + double phiAtVtx = 0., + int hwPtUnconstrained = 0, + double ptUnconstrained = 0., + int dXY = 0); ~Muon() override; @@ -80,6 +86,10 @@ namespace l1t { inline void setHwDEtaExtra(int dEta) { hwDEtaExtra_ = dEta; }; inline void setHwRank(int rank) { hwRank_ = rank; }; + inline void setHwPtUnconstrained(int hwPtUnconstrained) { hwPtUnconstrained_ = hwPtUnconstrained; }; + inline void setPtUnconstrained(double ptUnconstrained) { ptUnconstrained_ = ptUnconstrained; }; + inline void setHwDXY(int hwDXY) { hwDXY_ = hwDXY; }; + inline void setDebug(bool debug) { debug_ = debug; }; // methods to retrieve values @@ -98,6 +108,10 @@ namespace l1t { inline int hwDEtaExtra() const { return hwDEtaExtra_; }; inline int hwRank() const { return hwRank_; }; + inline int hwPtUnconstrained() const { return hwPtUnconstrained_; }; + inline double ptUnconstrained() const { return ptUnconstrained_; }; + inline int hwDXY() const { return hwDXY_; }; + inline bool debug() const { return debug_; }; virtual bool operator==(const l1t::Muon& rhs) const; @@ -122,6 +136,11 @@ namespace l1t { int hwPhiAtVtx_; double etaAtVtx_; double phiAtVtx_; + + // displacement information + int hwPtUnconstrained_; + double ptUnconstrained_; + int hwDXY_; }; } // namespace l1t diff --git a/DataFormats/L1Trigger/src/Muon.cc b/DataFormats/L1Trigger/src/Muon.cc index b7d946aa46495..bdb1905885b2a 100644 --- a/DataFormats/L1Trigger/src/Muon.cc +++ b/DataFormats/L1Trigger/src/Muon.cc @@ -14,7 +14,10 @@ l1t::Muon::Muon() hwEtaAtVtx_(0), hwPhiAtVtx_(0), etaAtVtx_(0.), - phiAtVtx_(0.) {} + phiAtVtx_(0.), + hwPtUnconstrained_(0), + ptUnconstrained_(0.), + hwDXY_(0) {} l1t::Muon::Muon(const LorentzVector& p4, int pt, @@ -34,7 +37,10 @@ l1t::Muon::Muon(const LorentzVector& p4, int hwEtaAtVtx, int hwPhiAtVtx, double etaAtVtx, - double phiAtVtx) + double phiAtVtx, + int hwPtUnconstrained, + double ptUnconstrained, + int dXY) : L1Candidate(p4, pt, eta, phi, qual, iso), hwCharge_(charge), hwChargeValid_(chargeValid), @@ -48,7 +54,10 @@ l1t::Muon::Muon(const LorentzVector& p4, hwEtaAtVtx_(hwEtaAtVtx), hwPhiAtVtx_(hwPhiAtVtx), etaAtVtx_(etaAtVtx), - phiAtVtx_(phiAtVtx) {} + phiAtVtx_(phiAtVtx), + hwPtUnconstrained_(hwPtUnconstrained), + ptUnconstrained_(ptUnconstrained), + hwDXY_(dXY) {} l1t::Muon::Muon(const PolarLorentzVector& p4, int pt, @@ -68,7 +77,10 @@ l1t::Muon::Muon(const PolarLorentzVector& p4, int hwEtaAtVtx, int hwPhiAtVtx, double etaAtVtx, - double phiAtVtx) + double phiAtVtx, + int hwPtUnconstrained, + double ptUnconstrained, + int dXY) : L1Candidate(p4, pt, eta, phi, qual, iso), hwCharge_(charge), hwChargeValid_(chargeValid), @@ -82,12 +94,17 @@ l1t::Muon::Muon(const PolarLorentzVector& p4, hwEtaAtVtx_(hwEtaAtVtx), hwPhiAtVtx_(hwPhiAtVtx), etaAtVtx_(etaAtVtx), - phiAtVtx_(phiAtVtx) {} + phiAtVtx_(phiAtVtx), + hwPtUnconstrained_(hwPtUnconstrained), + ptUnconstrained_(ptUnconstrained), + hwDXY_(dXY) {} l1t::Muon::~Muon() {} bool l1t::Muon::operator==(const l1t::Muon& rhs) const { return l1t::L1Candidate::operator==(static_cast(rhs)) && hwCharge_ == rhs.hwCharge() && hwChargeValid_ == rhs.hwChargeValid() && tfMuonIndex_ == rhs.tfMuonIndex() && - hwEtaAtVtx_ == rhs.hwEtaAtVtx() && hwPhiAtVtx_ == rhs.hwPhiAtVtx(); + hwEtaAtVtx_ == rhs.hwEtaAtVtx() && hwPhiAtVtx_ == rhs.hwPhiAtVtx() && + hwPtUnconstrained_ == rhs.hwPtUnconstrained() && ptUnconstrained_ == rhs.ptUnconstrained() && + hwDXY_ == rhs.hwDXY(); } diff --git a/DataFormats/L1Trigger/src/classes_def.xml b/DataFormats/L1Trigger/src/classes_def.xml index bda2ba8e99937..8fc148869af6f 100644 --- a/DataFormats/L1Trigger/src/classes_def.xml +++ b/DataFormats/L1Trigger/src/classes_def.xml @@ -80,7 +80,8 @@ - + + @@ -90,6 +91,7 @@ + @@ -261,4 +263,5 @@ + diff --git a/DataFormats/StdDictionaries/src/classes_def_others.xml b/DataFormats/StdDictionaries/src/classes_def_others.xml index 11a91fca6231a..4e4d343a68e64 100644 --- a/DataFormats/StdDictionaries/src/classes_def_others.xml +++ b/DataFormats/StdDictionaries/src/classes_def_others.xml @@ -9,6 +9,7 @@ + diff --git a/DetectorDescription/Parser/test/run_testDoc.sh b/DetectorDescription/Parser/test/run_testDoc.sh index 09c6adccff1f1..42ffa53d74860 100755 --- a/DetectorDescription/Parser/test/run_testDoc.sh +++ b/DetectorDescription/Parser/test/run_testDoc.sh @@ -1,13 +1,19 @@ #!/bin/bash + test=testtestDoc function die { echo Failure $1: status $2 ; exit $2 ; } pushd ${LOCAL_TMP_DIR} - export mecpath=${PATH} export PATH=${LOCAL_TOP_DIR}/test/${SCRAM_ARCH}/:${PATH} cd ${LOCAL_TEST_DIR} -# cp ${LOCAL_TOP_DIR}/test/${SCRAM_ARCH}/testDoc . - echo ${test}testDoc ------------------------------------------------------------ - testDoc testConfiguration.xml|| die "testDoc" $? - export PATH=${mecpath} + echo ${test} testDoc ------------------------------------------------------------ + testDocProg=testDoc + for scriptDir in $CMSSW_BASE $CMSSW_RELEASE_BASE $CMSSW_FULL_RELEASE_BASE ; do + if [ -x $scriptDir/test/${SCRAM_ARCH}/testDoc ] ; then + testDocProg=$scriptDir/test/${SCRAM_ARCH}/testDoc + echo Found $testDocProg + break + fi + done + $testDocProg testConfiguration.xml || die "testDoc" $? popd exit 0 diff --git a/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc b/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc index b10b50dd6d098..4a3e76d73200c 100644 --- a/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc +++ b/EventFilter/GEMRawToDigi/plugins/GEMRawToDigiModule.cc @@ -84,6 +84,8 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve amc13Event->setCDFHeader(*word); amc13Event->setAMC13Header(*(++word)); + bool unknownChamber = false, unknownVFat = false, badVfat = false; + // Readout out AMC headers for (uint8_t i = 0; i < amc13Event->nAMC(); ++i) amc13Event->addAMCheader(*(++word)); @@ -104,6 +106,14 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve uint8_t gebId = gebData->inputID(); GEMROMapping::chamEC geb_ec = {fedId, amcNum, gebId}; + + // check if Chamber exists. + if (!gemROMap->isValidChamber(geb_ec)) { + unknownChamber = true; + LogDebug("GEMRawToDigiModule") << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId); + continue; + } + GEMROMapping::chamDC geb_dc = gemROMap->chamberPos(geb_ec); GEMDetId gemChId = geb_dc.detId; @@ -119,19 +129,20 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve // check if ChipID exists. if (!gemROMap->isValidChipID(vfat_ec)) { - edm::LogWarning("GEMRawToDigiModule") - << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId) << " vfatId " << int(vfatId) - << " vfat Pos " << int(vfatData->position()); + unknownVFat = true; + LogDebug("GEMRawToDigiModule") << "InValid: amcNum " << int(amcNum) << " gebId " << int(gebId) << " vfatId " + << int(vfatId) << " vfat Pos " << int(vfatData->position()); continue; } + // check vfat data if (vfatData->quality()) { - edm::LogWarning("GEMRawToDigiModule") + badVfat = true; + LogDebug("GEMRawToDigiModule") << "Quality " << int(vfatData->quality()) << " b1010 " << int(vfatData->b1010()) << " b1100 " << int(vfatData->b1100()) << " b1110 " << int(vfatData->b1110()); if (vfatData->crc() != vfatData->checkCRC()) { - edm::LogWarning("GEMRawToDigiModule") - << "DIFFERENT CRC :" << vfatData->crc() << " " << vfatData->checkCRC(); + LogDebug("GEMRawToDigiModule") << "DIFFERENT CRC :" << vfatData->crc() << " " << vfatData->checkCRC(); } } @@ -200,6 +211,11 @@ void GEMRawToDigiModule::produce(edm::StreamID iID, edm::Event& iEvent, edm::Eve outAMC13Event.get()->insertDigi(amc13Event->bxId(), AMC13Event(*amc13Event)); } + if (unknownChamber || unknownVFat || badVfat) { + edm::LogWarning("GEMRawToDigiModule") << "unpacking error: unknown Chamber " << unknownChamber << " unknown VFat " + << unknownVFat << " bad VFat " << badVfat; + } + } // end of amc13Event iEvent.put(std::move(outGEMDigis)); diff --git a/EventFilter/HcalRawToDigi/plugins/HcalDigiToRawuHTR.cc b/EventFilter/HcalRawToDigi/plugins/HcalDigiToRawuHTR.cc index 6830e224ddd59..f056877c5fd2c 100644 --- a/EventFilter/HcalRawToDigi/plugins/HcalDigiToRawuHTR.cc +++ b/EventFilter/HcalRawToDigi/plugins/HcalDigiToRawuHTR.cc @@ -285,7 +285,7 @@ void HcalDigiToRawuHTR::fillDescriptions(edm::ConfigurationDescriptions& descrip desc.addUntracked("Verbosity", 0); desc.add("tdc1", 4); desc.add("tdc2", 20); - desc.add("packHBTDC", true); + desc.add("packHBTDC", false); desc.add("ElectronicsMap", ""); desc.add("QIE10", edm::InputTag("simHcalDigis", "HFQIE10DigiCollection")); desc.add("QIE11", edm::InputTag("simHcalDigis", "HBHEQIE11DigiCollection")); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.cc index 4379ce88bcbbf..57a180018b244 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.cc @@ -21,7 +21,7 @@ namespace l1t { for (auto imu = muons->begin(); imu != muons->end(); imu++) { if (imu->processor() + 1 == board_id) { uint32_t firstWord(0), lastWord(0); - RegionalMuonRawDigiTranslator::generatePackedDataWords(*imu, firstWord, lastWord); + RegionalMuonRawDigiTranslator::generatePackedDataWords(*imu, firstWord, lastWord, isKalman_); payloadMap_[bmtfBlockID].push_back(firstWord); //imu->link()*2+1 payloadMap_[bmtfBlockID].push_back(lastWord); //imu->link()*2+1 } @@ -51,14 +51,14 @@ namespace l1t { blocks.push_back(block); /* - //debug from here - std::cout << "block id : " << block.header().getID() << std::endl; - - std::cout << "payload created : " << std::endl; - for (auto &word : block.payload()) - std::cout << std::bitset<32>(word).to_string() << std::endl; - //debug up to here - */ + //debug from here + std::cout << "block id : " << block.header().getID() << std::endl; + + std::cout << "payload created : " << std::endl; + for (auto &word : block.payload()) + std::cout << std::bitset<32>(word).to_string() << std::endl; + //debug up to here + */ return blocks; } diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.h index b80c6a944ba18..12396a2616595 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFPackerOutput.h @@ -11,9 +11,12 @@ namespace l1t { class BMTFPackerOutput : public Packer { public: Blocks pack(const edm::Event&, const PackerTokens*) override; + void setKalmanAlgoTrue() { isKalman_ = true; }; private: std::map > payloadMap_; + + bool isKalman_{false}; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFUnpackerOutput.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFUnpackerOutput.cc index aaaa30b1491db..22a4b8116584d 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFUnpackerOutput.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/BMTFUnpackerOutput.cc @@ -65,19 +65,19 @@ namespace l1t { } RegionalMuonCand muCand; - RegionalMuonRawDigiTranslator::fillRegionalMuonCand(muCand, raw_first, raw_secnd, processor, tftype::bmtf); + RegionalMuonRawDigiTranslator::fillRegionalMuonCand( + muCand, raw_first, raw_secnd, processor, tftype::bmtf, isKalman); - if (muCand.hwQual() == 0) + if (muCand.hwPt() == 0) { continue; + } - muCand.setLink(48 + processor); //the link corresponds to the uGMT input if (isKalman) { - muCand.setHwPt2((raw_secnd >> 23) & 0xFF); - muCand.setHwDXY((raw_secnd >> 2) & 0x3); LogDebug("L1T") << "Pt = " << muCand.hwPt() << " eta: " << muCand.hwEta() << " phi: " << muCand.hwPhi() - << " diplacedPt = " << muCand.hwPt2(); - } else + << " diplacedPt = " << muCand.hwPtUnconstrained(); + } else { LogDebug("L1T") << "Pt = " << muCand.hwPt() << " eta: " << muCand.hwEta() << " phi: " << muCand.hwPhi(); + } res->push_back(ibx, muCand); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.cc index 7518a4f5612ee..2e6ce53fdecab 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.cc @@ -4,25 +4,14 @@ namespace l1t { namespace stage2 { - CaloLayer1Collections::CaloLayer1Collections(edm::Event& e) - : UnpackerCollections(e), - ecalDigis_(new EcalTrigPrimDigiCollection()), - hcalDigis_(new HcalTrigPrimDigiCollection()), - caloRegions_(new L1CaloRegionCollection()) { - // Pre-allocate: - // 72 iPhi values - // 28 iEta values in Ecal, 28 + 12 iEta values in Hcal + HF - // 2 hemispheres - ecalDigis_->reserve(72 * 28 * 2); - hcalDigis_->reserve(72 * 40 * 2); - // 7 regions * 18 cards * 2 hemispheres - caloRegions_->reserve(7 * 18 * 2); - } - CaloLayer1Collections::~CaloLayer1Collections() { event_.put(std::move(ecalDigis_)); event_.put(std::move(hcalDigis_)); event_.put(std::move(caloRegions_)); + + for (int i = 0; i < 5; ++i) { + event_.put(std::move(ecalDigisBx_[i]), "EcalDigisBx" + std::to_string(i + 1)); + } } } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.h index 37d6ecf16a368..a0630d46cb881 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Collections.h @@ -5,22 +5,45 @@ #include "DataFormats/HcalDigi/interface/HcalDigiCollections.h" #include "DataFormats/L1CaloTrigger/interface/L1CaloCollections.h" #include "EventFilter/L1TRawToDigi/interface/UnpackerCollections.h" +#include "L1TObjectCollections.h" namespace l1t { namespace stage2 { - class CaloLayer1Collections : public UnpackerCollections { + class CaloLayer1Collections : public L1TObjectCollections { public: - CaloLayer1Collections(edm::Event& e); + CaloLayer1Collections(edm::Event& e) + : L1TObjectCollections(e), + ecalDigis_(new EcalTrigPrimDigiCollection()), + hcalDigis_(new HcalTrigPrimDigiCollection()), + caloRegions_(new L1CaloRegionCollection()) { + // Pre-allocate: + // 72 iPhi values + // 28 iEta values in Ecal, 28 + 12 iEta values in Hcal + HF + // 2 hemispheres + ecalDigis_->reserve(72 * 28 * 2); + hcalDigis_->reserve(72 * 40 * 2); + // 7 regions * 18 cards * 2 hemispheres + caloRegions_->reserve(7 * 18 * 2); + std::generate( + ecalDigisBx_.begin(), ecalDigisBx_.end(), [] { return std::make_unique(); }); + }; + ~CaloLayer1Collections() override; inline EcalTrigPrimDigiCollection* getEcalDigis() { return ecalDigis_.get(); }; inline HcalTrigPrimDigiCollection* getHcalDigis() { return hcalDigis_.get(); }; inline L1CaloRegionCollection* getRegions() { return caloRegions_.get(); }; + inline EcalTrigPrimDigiCollection* getEcalDigisBx(const unsigned int copy) override { + return ecalDigisBx_[copy].get(); + }; + private: std::unique_ptr ecalDigis_; std::unique_ptr hcalDigis_; std::unique_ptr caloRegions_; + + std::array, 5> ecalDigisBx_; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Setup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Setup.cc index 5aaf095e0c231..2a5ec124425fd 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Setup.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Setup.cc @@ -55,6 +55,9 @@ namespace l1t { prod.produces(); prod.produces(); prod.produces(); + for (int i = 0; i < 5; ++i) { + prod.produces("EcalDigisBx" + std::to_string(i + 1)); + } } std::unique_ptr CaloLayer1Setup::getCollections(edm::Event& e) { diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Unpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Unpacker.cc index abcec9cb58d3f..99cdd15a99893 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Unpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CaloLayer1Unpacker.cc @@ -21,11 +21,31 @@ namespace l1t { auto ctp7_phi = block.amc().getBoardID(); const uint32_t* ptr = block.payload().data(); - UCTCTP7RawData ctp7Data(ptr); - makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigis()); - makeHCalTPGs(ctp7_phi, ctp7Data, res->getHcalDigis()); - makeHFTPGs(ctp7_phi, ctp7Data, res->getHcalDigis()); - makeRegions(ctp7_phi, ctp7Data, res->getRegions()); + int N_BX = (block.header().getFlags() >> 16) & 0xf; + // std::cout << " N_BX calculated " << N_BX << std::endl; + + if (N_BX == 1) { + UCTCTP7RawData ctp7Data(ptr); + makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigis()); + makeHCalTPGs(ctp7_phi, ctp7Data, res->getHcalDigis()); + makeHFTPGs(ctp7_phi, ctp7Data, res->getHcalDigis()); + makeRegions(ctp7_phi, ctp7Data, res->getRegions()); + } else if (N_BX == 5) { + const uint32_t* ptr5 = ptr; + UCTCTP7RawData ctp7Data(ptr); + makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigis()); + makeHCalTPGs(ctp7_phi, ctp7Data, res->getHcalDigis()); + makeHFTPGs(ctp7_phi, ctp7Data, res->getHcalDigis()); + makeRegions(ctp7_phi, ctp7Data, res->getRegions()); + for (int i = 0; i < 5; i++) { + UCTCTP7RawData ctp7Data(ptr5); + makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigisBx(i)); + ptr5 += 192; + } + } else { + LogError("CaloLayer1Unpacker") << "Number of BXs to unpack is not 1 or 5, stop here !!! " << N_BX << std::endl; + return false; + } return true; } diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc index 7a747cb8a0aec..86430eee00ec3 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc @@ -1,11 +1,15 @@ +#include "FWCore/Framework/interface/stream/EDProducerBase.h" #include "FWCore/Utilities/interface/InputTag.h" #include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h" #include "EventFilter/L1TRawToDigi/plugins/PackingSetupFactory.h" #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h" -#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h" #include "GMTSetup.h" @@ -37,10 +41,19 @@ namespace l1t { PackerMap GMTSetup::getPackers(int fed, unsigned int fw) { PackerMap res; if (fed == 1402) { + auto gmt_in_packer = static_pointer_cast( + PackerFactory::get()->make("stage2::RegionalMuonGMTPacker")); + if (fw >= 0x6000000) { + gmt_in_packer->setKalmanAlgoTrue(); + } + auto gmt_out_packer = + static_pointer_cast(PackerFactory::get()->make("stage2::GMTMuonPacker")); + gmt_out_packer->setFed(fed); + gmt_out_packer->setFwVersion(fw); // Use amc_no and board id 1 for packing res[{1, 1}] = { - PackerFactory::get()->make("stage2::RegionalMuonGMTPacker"), - PackerFactory::get()->make("stage2::GMTMuonPacker"), + gmt_in_packer, + gmt_out_packer, PackerFactory::get()->make("stage2::IntermediateMuonPacker"), }; } @@ -71,9 +84,15 @@ namespace l1t { // MP7 input link numbers are represented by even numbers starting from 0 (iLink=link*2) // input muons on links 36-71 - auto gmt_in_unp = UnpackerFactory::get()->make("stage2::RegionalMuonGMTUnpacker"); - for (int iLink = 72; iLink < 144; iLink += 2) + auto gmt_in_unp = static_pointer_cast( + UnpackerFactory::get()->make("stage2::RegionalMuonGMTUnpacker")); + if (fw >= 0x6000000) { + gmt_in_unp->setKalmanAlgoTrue(); + } + + for (int iLink = 72; iLink < 144; iLink += 2) { res[iLink] = gmt_in_unp; + } // MP7 output link numbers are represented by odd numbers (oLink=link*2+1) // internal muons on links 24-31 diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc index 7ef5bdadc5d93..11b6aec6befd5 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc @@ -2,6 +2,7 @@ #include "EventFilter/L1TRawToDigi/plugins/PackingSetupFactory.h" #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/EGammaUnpacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/EtSumUnpacker.h" @@ -31,15 +32,17 @@ namespace l1t { if (fed == 1404) { // Use board id 1 for packing - res[{1, 1}] = { - - PackerFactory::get()->make("stage2::GTMuonPacker"), - PackerFactory::get()->make("stage2::GTEGammaPacker"), - PackerFactory::get()->make("stage2::GTEtSumPacker"), - PackerFactory::get()->make("stage2::GTJetPacker"), - PackerFactory::get()->make("stage2::GTTauPacker"), - PackerFactory::get()->make("stage2::GlobalAlgBlkPacker"), - PackerFactory::get()->make("stage2::GlobalExtBlkPacker")}; + auto gt_muon_packer = + static_pointer_cast(PackerFactory::get()->make("stage2::GTMuonPacker")); + gt_muon_packer->setFed(fed); + gt_muon_packer->setFwVersion(fw); + res[{1, 1}] = {gt_muon_packer, + PackerFactory::get()->make("stage2::GTEGammaPacker"), + PackerFactory::get()->make("stage2::GTEtSumPacker"), + PackerFactory::get()->make("stage2::GTJetPacker"), + PackerFactory::get()->make("stage2::GTTauPacker"), + PackerFactory::get()->make("stage2::GlobalAlgBlkPacker"), + PackerFactory::get()->make("stage2::GlobalExtBlkPacker")}; } return res; diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.cc index c93c01ed3a809..f72ea5205db2c 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.cc @@ -120,7 +120,7 @@ namespace l1t { // The intermediate muons of the uGMT (FED number 1402) do not // have coordinates estimated at the vertex in the RAW data. // The corresponding bits are set to zero. - MuonRawDigiTranslator::fillMuon(mu, raw_data_00_31, raw_data_32_63, 1402, getAlgoVersion()); + MuonRawDigiTranslator::fillIntermediateMuon(mu, raw_data_00_31, raw_data_32_63, getAlgoVersion()); LogDebug("L1T") << "Mu" << nWord / 2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT " << mu.hwPt() << " iso " << mu.hwIso() << " qual " << mu.hwQual() << " charge " << mu.hwCharge() diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h index bf63dc34bd481..f543f9ce0ff98 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h @@ -7,6 +7,8 @@ #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/EcalDigi/interface/EcalDigiCollections.h" + #include "EventFilter/L1TRawToDigi/interface/UnpackerCollections.h" namespace l1t { @@ -21,6 +23,8 @@ namespace l1t { virtual EtSumBxCollection* getEtSums(const unsigned int copy) { return nullptr; } virtual JetBxCollection* getJets(const unsigned int copy) { return nullptr; } virtual TauBxCollection* getTaus(const unsigned int copy) { return nullptr; } + + virtual EcalTrigPrimDigiCollection* getEcalDigisBx(const unsigned int copy) { return nullptr; }; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc index 6118fdf7c332d..f2d62ae8f8470 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc @@ -1,7 +1,5 @@ -#include "FWCore/Framework/interface/Event.h" #include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h" -#include "L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h" #include "GMTTokens.h" #include "MuonPacker.h" @@ -13,46 +11,72 @@ namespace l1t { PayloadMap payloadMap; - for (int i = muons->getFirstBX(); i <= muons->getLastBX(); ++i) { - // the first muon in every BX and every block id is 0 - for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) { - payloadMap[blkId].push_back(0); - payloadMap[blkId].push_back(0); - } - - unsigned int blkId = b1_; - int muCtr = 1; - for (auto mu = muons->begin(i); mu != muons->end(i) && muCtr <= 8; ++mu, ++muCtr) { - uint32_t msw = 0; - uint32_t lsw = 0; - - MuonRawDigiTranslator::generatePackedDataWords(*mu, lsw, msw); - - payloadMap[blkId].push_back(lsw); - payloadMap[blkId].push_back(msw); - - // go to next block id after two muons - if (muCtr % 2 == 0) { - blkId += 2; - } - } - - // padding empty muons to reach 3 muons per block id per BX - for (auto& kv : payloadMap) { - while (kv.second.size() % 6 != 0) { - kv.second.push_back(0); - } - } + for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) { + packBx(payloadMap, muons, bx); } Blocks blocks; // push everything in the blocks vector for (auto& kv : payloadMap) { - //cout << kv.first << ": " << kv.second.size() << kv.second[0] << "\n"; blocks.push_back(Block(kv.first, kv.second)); } return blocks; } + + void MuonPacker::packBx(PayloadMap& payloadMap, const edm::Handle& muons, int bx) { + // the first word in every BX and every block id is 0 + for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) { + payloadMap[blkId].push_back(0); + } + + unsigned int blkId = b1_; + auto mu{muons->begin(bx)}; + uint32_t mu1_shared_word{0}; + uint32_t mu2_shared_word{0}; + uint32_t mu1_msw{0}; + uint32_t mu2_msw{0}; + uint32_t mu1_lsw{0}; + uint32_t mu2_lsw{0}; + // Slightly convoluted logic to account for the Run-3 muon readout record: + // To make space for displacement information we moved the raw + // (i.e. non-extrapolated) eta value to the second "spare" word + // in the block which we call "shared word". So the logic below + // needs to be aware if it is operating on the first or second + // muon in the block in order to place the eta value in the right + // place in the shared word. Additionally the logic needs to + // wait for the second muon in the block before filling the + // payload map because the shared word goes in first. + for (int muCtr = 1; muCtr <= 8; ++muCtr) { + if (mu != muons->end(bx)) { + MuonRawDigiTranslator::generatePackedDataWords( + *mu, mu2_shared_word, mu2_lsw, mu2_msw, fedId_, fwId_, 2 - (muCtr % 2)); + ++mu; + } + + // If we're remaining in the current block the muon we just packed is the first one in the block. + // If not we add both muons to the payload map and go to the next block. + if (muCtr % 2 == 1) { + mu1_shared_word = mu2_shared_word; + mu1_lsw = mu2_lsw; + mu1_msw = mu2_msw; + } else { + payloadMap[blkId].push_back(mu1_shared_word | mu2_shared_word); + payloadMap[blkId].push_back(mu1_lsw); + payloadMap[blkId].push_back(mu1_msw); + payloadMap[blkId].push_back(mu2_lsw); + payloadMap[blkId].push_back(mu2_msw); + + blkId += 2; + + mu1_shared_word = 0; + mu1_lsw = 0; + mu1_msw = 0; + } + mu2_shared_word = 0; + mu2_lsw = 0; + mu2_msw = 0; + } + } } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h index 11bd4b96c7457..7cb46c12845bb 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h @@ -2,8 +2,11 @@ #define L1T_PACKER_STAGE2_MUONPACKER_H #include +#include "FWCore/Framework/interface/Event.h" #include "EventFilter/L1TRawToDigi/interface/Packer.h" +#include "L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h" + namespace l1t { namespace stage2 { class MuonPacker : public Packer { @@ -11,9 +14,16 @@ namespace l1t { MuonPacker(unsigned b1) : b1_(b1) {} Blocks pack(const edm::Event&, const PackerTokens*) override; unsigned b1_; + inline void setFwVersion(unsigned fwId) { fwId_ = fwId; }; + inline void setFed(unsigned fedId) { fedId_ = fedId; }; private: typedef std::map> PayloadMap; + + void packBx(PayloadMap& payloadMap, const edm::Handle& muons, int bx); + + unsigned fwId_{0}; + unsigned fedId_{0}; }; class GTMuonPacker : public MuonPacker { diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc index dacd7194f6680..1c1b12021aa07 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc @@ -54,13 +54,15 @@ namespace l1t { } void MuonUnpacker::unpackBx(int bx, const std::vector& payload, unsigned int startIdx) { - unsigned int i = startIdx; + unsigned int i = startIdx + 2; // Only words 2-5 are "standard" muon words. // Check if there are enough words left in the payload - if (i + nWords_ <= payload.size()) { - for (unsigned nWord = 0; nWord < nWords_; nWord += 2) { + if (startIdx + nWords_ <= payload.size()) { + for (unsigned nWord = 2; nWord < nWords_; nWord += 2) { // Only words 2-5 are "standard" muon words. + uint32_t raw_data_spare = payload[startIdx + 1]; uint32_t raw_data_00_31 = payload[i++]; uint32_t raw_data_32_63 = payload[i++]; - LogDebug("L1T") << "raw_data_00_31 = 0x" << hex << raw_data_00_31 << " raw_data_32_63 = 0x" << raw_data_32_63; + LogDebug("L1T") << "raw_data_spare = 0x" << hex << raw_data_spare << " raw_data_00_31 = 0x" << raw_data_00_31 + << " raw_data_32_63 = 0x" << raw_data_32_63; // skip empty muons (hwPt == 0) if (((raw_data_00_31 >> l1t::MuonRawDigiTranslator::ptShift_) & l1t::MuonRawDigiTranslator::ptMask_) == 0) { LogDebug("L1T") << "Muon hwPt zero. Skip."; @@ -69,7 +71,8 @@ namespace l1t { Muon mu; - MuonRawDigiTranslator::fillMuon(mu, raw_data_00_31, raw_data_32_63, fed_, getAlgoVersion()); + MuonRawDigiTranslator::fillMuon( + mu, raw_data_spare, raw_data_00_31, raw_data_32_63, fed_, getAlgoVersion(), nWord / 2); LogDebug("L1T") << "Mu" << nWord / 2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT " << mu.hwPt() << " iso " << mu.hwIso() << " qual " << mu.hwQual() << " charge " << mu.hwCharge() diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc index cc6136ed0bd4c..4ba50c5c03ee7 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc @@ -54,7 +54,7 @@ namespace l1t { uint32_t msw = 0; uint32_t lsw = 0; - RegionalMuonRawDigiTranslator::generatePackedDataWords(*mu, lsw, msw); + RegionalMuonRawDigiTranslator::generatePackedDataWords(*mu, lsw, msw, isKalman_); payloadMap[linkTimes2].push_back(lsw); payloadMap[linkTimes2].push_back(msw); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h index 06a7b7f177367..879a1dd1f5bab 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h @@ -13,10 +13,13 @@ namespace l1t { class RegionalMuonGMTPacker : public Packer { public: Blocks pack(const edm::Event&, const PackerTokens*) override; + void setKalmanAlgoTrue() { isKalman_ = true; }; private: typedef std::map> PayloadMap; void packTF(const edm::Event&, const edm::EDGetTokenT&, Blocks&); + + bool isKalman_{false}; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc index 224b32a4cc744..2a8d556dc0eba 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc @@ -102,11 +102,11 @@ namespace l1t { RegionalMuonCand mu; RegionalMuonRawDigiTranslator::fillRegionalMuonCand( - mu, raw_data_00_31, raw_data_32_63, processor, trackFinder); + mu, raw_data_00_31, raw_data_32_63, processor, trackFinder, isKalman_); LogDebug("L1T") << "Mu" << nWord / 2 << ": eta " << mu.hwEta() << " phi " << mu.hwPhi() << " pT " << mu.hwPt() << " qual " << mu.hwQual() << " sign " << mu.hwSign() << " sign valid " - << mu.hwSignValid(); + << mu.hwSignValid() << " unconstrained pT " << mu.hwPtUnconstrained(); res->push_back(bx, mu); } diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h index 97374feef25f6..97e7683109526 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h @@ -10,10 +10,13 @@ namespace l1t { class RegionalMuonGMTUnpacker : public Unpacker { public: bool unpack(const Block& block, UnpackerCollections* coll) override; + void setKalmanAlgoTrue() { isKalman_ = true; } private: static constexpr unsigned nWords_ = 6; // every link transmits 6 words (3 muons) per bx static constexpr unsigned bxzs_enable_shift_ = 1; + + bool isKalman_{false}; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/python/bmtfStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/bmtfStage2Raw_cfi.py index 56ccb6cce87df..57cf90df06908 100644 --- a/EventFilter/L1TRawToDigi/python/bmtfStage2Raw_cfi.py +++ b/EventFilter/L1TRawToDigi/python/bmtfStage2Raw_cfi.py @@ -10,3 +10,19 @@ FedId = cms.int32(1376), FWId = cms.uint32(1), ) + +## Era: Run2_2016 +from Configuration.Eras.Modifier_stage2L1Trigger_cff import stage2L1Trigger +stage2L1Trigger.toModify(bmtfStage2Raw, InputLabel = cms.InputTag("simBmtfDigis", "BMTF"), FWId = cms.uint32(1)) + +## Era: Run2_2017 +from Configuration.Eras.Modifier_stage2L1Trigger_2017_cff import stage2L1Trigger_2017 +stage2L1Trigger_2017.toModify(bmtfStage2Raw, InputLabel = cms.InputTag("simBmtfDigis", "BMTF"), FWId = cms.uint32(1)) + +### Era: Run2_2018 +from Configuration.Eras.Modifier_stage2L1Trigger_2018_cff import stage2L1Trigger_2018 +stage2L1Trigger_2018.toModify(bmtfStage2Raw, InputLabel = cms.InputTag("simBmtfDigis", "BMTF"), FWId = cms.uint32(1)) + +### Era: Run3_2021 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(bmtfStage2Raw, InputLabel = cms.InputTag("simKBmtfDigis", "BMTF"), FWId = cms.uint32(2499805536)) diff --git a/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py index a949a2394519e..9d322767feb09 100644 --- a/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py +++ b/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py @@ -17,3 +17,20 @@ lenSlinkHeader = cms.untracked.int32(8), lenSlinkTrailer = cms.untracked.int32(8) ) + +## Era: Run2_2016 +from Configuration.Eras.Modifier_stage2L1Trigger_cff import stage2L1Trigger +stage2L1Trigger.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simBmtfDigis", "BMTF"), FWId = cms.uint32(0x3000000)) + +## Era: Run2_2017 +from Configuration.Eras.Modifier_stage2L1Trigger_2017_cff import stage2L1Trigger_2017 +stage2L1Trigger_2017.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simBmtfDigis", "BMTF"), FWId = cms.uint32(0x4010000)) + +### Era: Run2_2018 +from Configuration.Eras.Modifier_stage2L1Trigger_2018_cff import stage2L1Trigger_2018 +stage2L1Trigger_2018.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simBmtfDigis", "BMTF"), FWId = cms.uint32(0x4010000)) + +### Era: Run3_2021 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simKBmtfDigis", "BMTF"), FWId = cms.uint32(0x6000000)) + diff --git a/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py index 7941872c0c3d8..8bfb66b9f7629 100644 --- a/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py +++ b/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py @@ -12,8 +12,24 @@ JetInputTag = cms.InputTag("simCaloStage2Digis"), EtSumInputTag = cms.InputTag("simCaloStage2Digis"), FedId = cms.int32(1404), - ## FWId = cms.uint32(0x10A6), # FW version in GMT with vtx-etrapolation - FWId = cms.uint32(0x10F2), # FW version for packing new HI centrality variables + FWId = cms.uint32(0x1120), # FW w/ displaced muon info. lenSlinkHeader = cms.untracked.int32(8), lenSlinkTrailer = cms.untracked.int32(8) ) + +## Era: Run2_2016 +from Configuration.Eras.Modifier_stage2L1Trigger_cff import stage2L1Trigger +stage2L1Trigger.toModify(gtStage2Raw, FWId = cms.uint32(0x1000)) # FW w/o coordinates at vtx. + +## Era: Run2_2017 +from Configuration.Eras.Modifier_stage2L1Trigger_2017_cff import stage2L1Trigger_2017 +stage2L1Trigger_2017.toModify(gtStage2Raw, FWId = cms.uint32(0x10A6)) # FW w/ vtx extrapolation. + +### Era: Run2_2018 +from Configuration.Eras.Modifier_stage2L1Trigger_2018_cff import stage2L1Trigger_2018 +stage2L1Trigger_2018.toModify(gtStage2Raw, FWId = cms.uint32(0x10F2)) # FW w/ new HI centrality variables & vtx extrapolation. + +### Era: Run3_2021 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(gtStage2Raw, FWId = cms.uint32(0x1120)) # FW w/ displaced muon info. + diff --git a/EventFilter/L1TRawToDigi/src/Block.cc b/EventFilter/L1TRawToDigi/src/Block.cc index 70ce3d234fee6..6ea0ff3ae3de6 100644 --- a/EventFilter/L1TRawToDigi/src/Block.cc +++ b/EventFilter/L1TRawToDigi/src/Block.cc @@ -226,7 +226,7 @@ namespace l1t { // Not sure how to map to generic BlockHeader variables, so just packing // it all in flags variable unsigned blockFlags = ((bx_per_l1a_ & 0xf) << 16) | (calo_bxid_ & 0xfff); - unsigned blockSize = 192; + unsigned blockSize = 192 * (int)bx_per_l1a_; return BlockHeader(blockId, blockSize, capId_, blockFlags, CTP7); } diff --git a/EventFilter/Utilities/interface/AuxiliaryMakers.h b/EventFilter/Utilities/interface/AuxiliaryMakers.h index c060e12302eab..00d15bc0081b1 100644 --- a/EventFilter/Utilities/interface/AuxiliaryMakers.h +++ b/EventFilter/Utilities/interface/AuxiliaryMakers.h @@ -9,6 +9,7 @@ namespace evf { edm::EventAuxiliary makeEventAuxiliary(const tcds::Raw_v1*, unsigned int runNumber, unsigned int lumiSection, + bool isRealData, const edm::EventAuxiliary::ExperimentType&, const std::string& processGUID, bool verifyLumiSection); diff --git a/EventFilter/Utilities/interface/EvFDaqDirector.h b/EventFilter/Utilities/interface/EvFDaqDirector.h index 53e552da7d200..f4f8931884517 100644 --- a/EventFilter/Utilities/interface/EvFDaqDirector.h +++ b/EventFilter/Utilities/interface/EvFDaqDirector.h @@ -108,7 +108,12 @@ namespace evf { void removeFile(unsigned int ls, unsigned int index); void removeFile(std::string); - FileStatus updateFuLock(unsigned int& ls, std::string& nextFile, uint32_t& fsize, uint64_t& lockWaitTime); + FileStatus updateFuLock(unsigned int& ls, + std::string& nextFile, + uint32_t& fsize, + uint16_t& rawHeaderSize, + uint64_t& lockWaitTime, + bool& setExceptionState); void tryInitializeFuLockFile(); unsigned int getRunNumber() const { return run_; } void lockInitLock(); @@ -132,12 +137,14 @@ namespace evf { bool requireHeader, bool retry, bool closeFile); + bool rawFileHasHeader(std::string const& rawSourcePath, uint16_t& rawHeaderSize); int grabNextJsonFromRaw(std::string const& rawSourcePath, int& rawFd, uint16_t& rawHeaderSize, int64_t& fileSizeFromHeader, bool& fileFound, - uint32_t serverLS); + uint32_t serverLS, + bool closeFile); int grabNextJsonFile(std::string const& jsonSourcePath, std::string const& rawSourcePath, int64_t& fileSizeFromJson, @@ -177,7 +184,13 @@ namespace evf { static struct flock make_flock(short type, short whence, off_t start, off_t len, pid_t pid); private: - bool bumpFile(unsigned int& ls, unsigned int& index, std::string& nextFile, uint32_t& fsize, int maxLS); + bool bumpFile(unsigned int& ls, + unsigned int& index, + std::string& nextFile, + uint32_t& fsize, + uint16_t& rawHeaderSize, + int maxLS, + bool& setExceptionState); void openFULockfileStream(bool create); std::string inputFileNameStem(const unsigned int ls, const unsigned int index) const; std::string outputFileNameStem(const unsigned int ls, std::string const& stream) const; diff --git a/EventFilter/Utilities/interface/FedRawDataInputSource.h b/EventFilter/Utilities/interface/FedRawDataInputSource.h index e79b42f1fed23..117898eeed13e 100644 --- a/EventFilter/Utilities/interface/FedRawDataInputSource.h +++ b/EventFilter/Utilities/interface/FedRawDataInputSource.h @@ -20,6 +20,7 @@ #include "FWCore/ServiceRegistry/interface/Service.h" #include "IOPool/Streamer/interface/FRDEventMessage.h" +#include "DataFormats/FEDRawData/interface/FEDNumbering.h" #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h" class FEDRawDataCollection; @@ -92,6 +93,7 @@ class FedRawDataInputSource : public edm::RawInputSource { const bool alwaysStartFromFirstLS_; const bool verifyChecksum_; const bool useL1EventID_; + const std::vector testTCDSFEDRange_; std::vector fileNames_; bool useFileBroker_; //std::vector fileNamesSorted_; @@ -119,6 +121,9 @@ class FedRawDataInputSource : public edm::RawInputSource { unsigned int eventsThisLumi_; unsigned long eventsThisRun_ = 0; + uint16_t MINTCDSuTCAFEDID_ = FEDNumbering::MINTCDSuTCAFEDID; + uint16_t MAXTCDSuTCAFEDID_ = FEDNumbering::MAXTCDSuTCAFEDID; + /* * * Multithreaded file reader @@ -127,7 +132,7 @@ class FedRawDataInputSource : public edm::RawInputSource { typedef std::pair ReaderInfo; - uint32 detectedFRDversion_ = 0; + uint16_t detectedFRDversion_ = 0; std::unique_ptr currentFile_; bool chunkIsFree_ = false; diff --git a/EventFilter/Utilities/plugins/DaqFakeReader.cc b/EventFilter/Utilities/plugins/DaqFakeReader.cc index 51291a9001a52..7bc931d1658a2 100644 --- a/EventFilter/Utilities/plugins/DaqFakeReader.cc +++ b/EventFilter/Utilities/plugins/DaqFakeReader.cc @@ -7,6 +7,7 @@ #include "DataFormats/FEDRawData/interface/FEDHeader.h" #include "DataFormats/FEDRawData/interface/FEDTrailer.h" #include "DataFormats/FEDRawData/interface/FEDNumbering.h" +#include "DataFormats/TCDS/interface/TCDSRaw.h" #include "EventFilter/Utilities/interface/GlobalEventNumber.h" @@ -35,9 +36,13 @@ DaqFakeReader::DaqFakeReader(const edm::ParameterSet& pset) meansize(pset.getUntrackedParameter("meanSize", 1024)), width(pset.getUntrackedParameter("width", 1024)), injected_errors_per_million_events(pset.getUntrackedParameter("injectErrPpm", 0)), + tcdsFEDID_(pset.getUntrackedParameter("tcdsFEDID", 1024)), modulo_error_events(injected_errors_per_million_events ? 1000000 / injected_errors_per_million_events : 0xffffffff) { // mean = pset.getParameter("mean"); + if (tcdsFEDID_ < FEDNumbering::MINTCDSuTCAFEDID) + throw cms::Exception("DaqFakeReader::DaqFakeReader") + << " TCDS FED ID lower than " << FEDNumbering::MINTCDSuTCAFEDID; produces(); } @@ -53,6 +58,7 @@ int DaqFakeReader::fillRawData(Event& e, FEDRawDataCollection*& data) { // a null pointer is passed, need to allocate the fed collection data = new FEDRawDataCollection(); EventID eID = e.id(); + auto ls = e.luminosityBlock(); if (!empty_events) { // Fill the EventID @@ -69,8 +75,7 @@ int DaqFakeReader::fillRawData(Event& e, FEDRawDataCollection*& data) { timeval now; gettimeofday(&now, nullptr); - fillGTPFED(eID, *data, &now); - //TODO: write fake TCDS FED filler + fillTCDSFED(eID, *data, ls, &now); } return 1; } @@ -116,39 +121,43 @@ void DaqFakeReader::fillFEDs( } } -void DaqFakeReader::fillGTPFED(EventID& eID, FEDRawDataCollection& data, timeval* now) { - uint32_t fedId = FEDNumbering::MINTriggerGTPFEDID; +void DaqFakeReader::fillTCDSFED(EventID& eID, FEDRawDataCollection& data, uint32_t ls, timeval* now) { + uint32_t fedId = tcdsFEDID_; FEDRawData& feddata = data.FEDData(fedId); - uint32_t size = evf::evtn::SLINK_WORD_SIZE * 37 - 16; //BST52_3BX + uint32_t size = sizeof(tcds::Raw_v1); feddata.resize(size + 16); + uint64_t orbitnr = 0; + uint16_t bxid = 0; + FEDHeader::set(feddata.data(), 1, // Trigger type eID.event(), // LV1_id (24 bits) - 0, // BX_id + bxid, // BX_id fedId); // source_id - int crc = 0; // FIXME : get CRC + tcds::Raw_v1* tcds = reinterpret_cast(feddata.data() + FEDHeader::length); + tcds::BST_v1* bst = const_cast(&tcds->bst); + tcds::Header_v1* header = const_cast(&tcds->header); + + const_cast(bst->gpstimehigh) = now->tv_sec; + const_cast(bst->gpstimelow) = now->tv_usec; + const_cast(bst->lhcFillHigh) = 0; + const_cast(bst->lhcFillLow) = 0; + + const_cast(header->orbitHigh) = orbitnr & 0xffff00; + const_cast(header->orbitLow) = orbitnr & 0xff; + const_cast(header->bxid) = bxid; + + const_cast(header->eventNumber) = eID.event(); + const_cast(header->lumiSection) = ls; + + int crc = 0; // only full event crc32c checked in HLT, not FED CRC16 FEDTrailer::set(feddata.data() + 8 + size, size / 8 + 2, // in 64 bit words!!! crc, 0, // Evt_stat 0); // TTS bits - - unsigned char* pOffset = feddata.data() + FEDHeader::length; - //fill in event ID - *((uint32_t*)(pOffset + evf::evtn::EVM_BOARDID_OFFSET * evf::evtn::SLINK_WORD_SIZE / 2)) = - evf::evtn::EVM_BOARDID_VALUE << evf::evtn::EVM_BOARDID_SHIFT; - *((uint32_t*)(pOffset + FEDHeader::length + - (9 * 2 + evf::evtn::EVM_TCS_TRIGNR_OFFSET) * evf::evtn::SLINK_WORD_SIZE / 2)) = eID.event(); - //fill in timestamp - *((uint32_t*)(pOffset + evf::evtn::EVM_GTFE_BSTGPS_OFFSET * evf::evtn::SLINK_WORD_SIZE / 2)) = now->tv_sec; - *((uint32_t*)(pOffset + FEDHeader::length + evf::evtn::EVM_GTFE_BSTGPS_OFFSET * evf::evtn::SLINK_WORD_SIZE / 2 + - evf::evtn::SLINK_HALFWORD_SIZE)) = now->tv_usec; - - //*( (uint16_t*) (pOffset + (evtn::EVM_GTFE_BLOCK*2 + evtn::EVM_TCS_LSBLNR_OFFSET)*evtn::SLINK_HALFWORD_SIZE)) = (unsigned short)fakeLs_-1; - - //we could also generate lumiblock, bcr, orbit,... but they are not currently used by the FRD input source } void DaqFakeReader::beginLuminosityBlock(LuminosityBlock const& iL, EventSetup const& iE) { diff --git a/EventFilter/Utilities/plugins/DaqFakeReader.h b/EventFilter/Utilities/plugins/DaqFakeReader.h index 5e76c220f1eb6..94d9d6d79bd4b 100644 --- a/EventFilter/Utilities/plugins/DaqFakeReader.h +++ b/EventFilter/Utilities/plugins/DaqFakeReader.h @@ -38,7 +38,7 @@ class DaqFakeReader : public edm::one::EDProducer<> { // private member functions // void fillFEDs(const int, const int, edm::EventID& eID, FEDRawDataCollection& data, float meansize, float width); - void fillGTPFED(edm::EventID& eID, FEDRawDataCollection& data, timeval* now); + void fillTCDSFED(edm::EventID& eID, FEDRawDataCollection& data, uint32_t ls, timeval* now); virtual void beginLuminosityBlock(edm::LuminosityBlock const& iL, edm::EventSetup const& iE); private: @@ -51,6 +51,7 @@ class DaqFakeReader : public edm::one::EDProducer<> { unsigned int meansize; // in bytes unsigned int width; unsigned int injected_errors_per_million_events; + unsigned int tcdsFEDID_; unsigned int modulo_error_events; unsigned int fakeLs_ = 0; }; diff --git a/EventFilter/Utilities/plugins/FRDStreamSource.cc b/EventFilter/Utilities/plugins/FRDStreamSource.cc index 87a24ee477216..e85024186bb17 100644 --- a/EventFilter/Utilities/plugins/FRDStreamSource.cc +++ b/EventFilter/Utilities/plugins/FRDStreamSource.cc @@ -63,8 +63,9 @@ bool FRDStreamSource::setRunAndEventInfo(edm::EventID& id, } if (detectedFRDversion_ == 0) { - fin_.read((char*)&detectedFRDversion_, sizeof(uint32_t)); - assert(detectedFRDversion_ > 0 && detectedFRDversion_ <= 5); + fin_.read((char*)&detectedFRDversion_, sizeof(uint16_t)); + fin_.read((char*)&flags_, sizeof(uint16_t)); + assert(detectedFRDversion_ > 0 && detectedFRDversion_ <= FRDHeaderMaxVersion); if (buffer_.size() < FRDHeaderVersionSize[detectedFRDversion_]) buffer_.resize(FRDHeaderVersionSize[detectedFRDversion_]); *((uint32_t*)(&buffer_[0])) = detectedFRDversion_; diff --git a/EventFilter/Utilities/plugins/FRDStreamSource.h b/EventFilter/Utilities/plugins/FRDStreamSource.h index 6b7608ce3240e..9763c7652ca3d 100644 --- a/EventFilter/Utilities/plugins/FRDStreamSource.h +++ b/EventFilter/Utilities/plugins/FRDStreamSource.h @@ -41,7 +41,8 @@ class FRDStreamSource : public edm::ProducerSourceFromFiles { const bool verifyAdler32_; const bool verifyChecksum_; const bool useL1EventID_; - unsigned int detectedFRDversion_ = 0; + uint16_t detectedFRDversion_ = 0; + uint16_t flags_ = 0; }; #endif // EventFilter_Utilities_FRDStreamSource_h diff --git a/EventFilter/Utilities/plugins/RawEventOutputModuleForBU.h b/EventFilter/Utilities/plugins/RawEventOutputModuleForBU.h index 3eb1240c66275..de1c591735584 100644 --- a/EventFilter/Utilities/plugins/RawEventOutputModuleForBU.h +++ b/EventFilter/Utilities/plugins/RawEventOutputModuleForBU.h @@ -20,7 +20,6 @@ #include "boost/shared_array.hpp" -class FRDEventMsgView; template class RawEventOutputModuleForBU : public edm::one::OutputModule { typedef unsigned int uint32; @@ -69,7 +68,7 @@ RawEventOutputModuleForBU::RawEventOutputModuleForBU(edm::ParameterSet instance_(ps.getUntrackedParameter("ProductInstance", "")), token_(consumes(edm::InputTag(label_, instance_))), numEventsPerFile_(ps.getUntrackedParameter("numEventsPerFile", 100)), - frdVersion_(ps.getUntrackedParameter("frdVersion", 3)), + frdVersion_(ps.getUntrackedParameter("frdVersion", 6)), totsize(0LL), writtensize(0LL), writtenSizeLast(0LL), @@ -96,6 +95,7 @@ void RawEventOutputModuleForBU::write(edm::EventForOutput const& e) { e.getByToken(token_, fedBuffers); // determine the expected size of the FRDEvent IN BYTES !!!!! + assert(frdVersion_ <= FRDHeaderMaxVersion); int headerSize = FRDHeaderVersionSize[frdVersion_]; int expectedSize = headerSize; int nFeds = frdVersion_ < 3 ? 1024 : FEDNumbering::lastFEDId() + 1; @@ -109,7 +109,16 @@ void RawEventOutputModuleForBU::write(edm::EventForOutput const& e) { // build the FRDEvent into a temporary buffer boost::shared_array workBuffer(new unsigned char[expectedSize + 256]); uint32* bufPtr = (uint32*)workBuffer.get(); - *bufPtr++ = (uint32)frdVersion_; // version number + if (frdVersion_ <= 5) { + *bufPtr++ = (uint32)frdVersion_; // version number only + } else { + uint16 flags = 0; + if (!e.eventAuxiliary().isRealData()) + flags |= FRDEVENT_MASK_ISGENDATA; + *(uint16*)bufPtr = (uint16)(frdVersion_ & 0xffff); + *((uint16*)bufPtr + 1) = flags; + bufPtr++; + } *bufPtr++ = (uint32)e.id().run(); *bufPtr++ = (uint32)e.luminosityBlock(); *bufPtr++ = (uint32)e.id().event(); diff --git a/EventFilter/Utilities/plugins/TcdsRawToDigi.cc b/EventFilter/Utilities/plugins/TcdsRawToDigi.cc index e9b36c20309c4..8cfb5420ccec6 100644 --- a/EventFilter/Utilities/plugins/TcdsRawToDigi.cc +++ b/EventFilter/Utilities/plugins/TcdsRawToDigi.cc @@ -71,9 +71,16 @@ void TcdsRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { TCDSRecord tcdsRecord; if (rawdata.isValid()) { - const FEDRawData& tcdsData = rawdata->FEDData(FEDNumbering::MINTCDSuTCAFEDID); - if (tcdsData.size() > 0) { - tcdsRecord = TCDSRecord(tcdsData.data()); + uint16_t selectedId = 0; + for (uint16_t fedId = FEDNumbering::MINTCDSuTCAFEDID; fedId <= FEDNumbering::MAXTCDSuTCAFEDID; fedId++) { + const FEDRawData& tcdsData = rawdata->FEDData(fedId); + if (tcdsData.size() > 0) { + if (selectedId) + throw cms::Exception("TcdsRawToDigi::produce") + << "Second TCDS FED ID " << fedId << " found. First ID: " << selectedId; + tcdsRecord = TCDSRecord(tcdsData.data()); + selectedId = fedId; + } } } iEvent.put(std::make_unique(tcdsRecord), "tcdsRecord"); diff --git a/EventFilter/Utilities/src/AuxiliaryMakers.cc b/EventFilter/Utilities/src/AuxiliaryMakers.cc index 73446f9a17366..a11ccd229fa09 100644 --- a/EventFilter/Utilities/src/AuxiliaryMakers.cc +++ b/EventFilter/Utilities/src/AuxiliaryMakers.cc @@ -9,6 +9,7 @@ namespace evf { edm::EventAuxiliary makeEventAuxiliary(const tcds::Raw_v1* tcds, unsigned int runNumber, unsigned int lumiSection, + bool isRealData, const edm::EventAuxiliary::ExperimentType& eventType, const std::string& processGUID, bool verifyLumiSection) { @@ -28,17 +29,20 @@ namespace evf { const uint64_t orbitnr = ((uint64_t)tcds->header.orbitHigh << 16) | tcds->header.orbitLow; const uint32_t recordLumiSection = tcds->header.lumiSection; - if (verifyLumiSection && recordLumiSection != lumiSection) - edm::LogWarning("AuxiliaryMakers") - << "Lumisection mismatch, external : " << lumiSection << ", record : " << recordLumiSection; - if ((orbitnr >> 18) + 1 != recordLumiSection) - edm::LogWarning("AuxiliaryMakers") << "Lumisection and orbit number mismatch, LS : " << lumiSection - << ", LS from orbit: " << ((orbitnr >> 18) + 1) << ", orbit:" << orbitnr; + if (isRealData) { + //warnings are disabled for generated data + if (verifyLumiSection && recordLumiSection != lumiSection) + edm::LogWarning("AuxiliaryMakers") + << "Lumisection mismatch, external : " << lumiSection << ", record : " << recordLumiSection; + if ((orbitnr >> 18) + 1 != recordLumiSection) + edm::LogWarning("AuxiliaryMakers") << "Lumisection and orbit number mismatch, LS : " << lumiSection + << ", LS from orbit: " << ((orbitnr >> 18) + 1) << ", orbit:" << orbitnr; + } return edm::EventAuxiliary(eventId, processGUID, edm::Timestamp(time), - true, + isRealData, eventType, (int)tcds->header.bxid, ((uint32_t)(tcds->bst.lhcFillHigh) << 16) | tcds->bst.lhcFillLow, diff --git a/EventFilter/Utilities/src/EvFDaqDirector.cc b/EventFilter/Utilities/src/EvFDaqDirector.cc index e8d99627897d3..02526304af2b5 100644 --- a/EventFilter/Utilities/src/EvFDaqDirector.cc +++ b/EventFilter/Utilities/src/EvFDaqDirector.cc @@ -497,8 +497,11 @@ namespace evf { EvFDaqDirector::FileStatus EvFDaqDirector::updateFuLock(unsigned int& ls, std::string& nextFile, uint32_t& fsize, - uint64_t& lockWaitTime) { + uint16_t& rawHeaderSize, + uint64_t& lockWaitTime, + bool& setExceptionState) { EvFDaqDirector::FileStatus fileStatus = noFile; + rawHeaderSize = 0; int retval = -1; int lock_attempts = 0; @@ -607,7 +610,7 @@ namespace evf { ls++; else { // try to bump (look for new index or EoLS file) - bumpedOk = bumpFile(readLs, readIndex, nextFile, fsize, stopFileLS); + bumpedOk = bumpFile(readLs, readIndex, nextFile, fsize, rawHeaderSize, stopFileLS, setExceptionState); //avoid 2 lumisections jump if (ls && readLs > currentLs && currentLs > ls) { ls++; @@ -641,8 +644,10 @@ namespace evf { fileStatus = newFile; LogDebug("EvFDaqDirector") << "Written to file -: " << readLs << ":" << readIndex + 1; } else { - throw cms::Exception("EvFDaqDirector") + edm::LogError("EvFDaqDirector") << "seek on fu read/write lock for updating failed with error " << strerror(errno); + setExceptionState = true; + return noFile; } } else if (currentLs < readLs) { //there is no new file in next LS (yet), but lock file can be updated to the next LS @@ -655,8 +660,10 @@ namespace evf { fsync(fu_readwritelock_fd2); LogDebug("EvFDaqDirector") << "Written to file -: " << readLs << ":" << readIndex; } else { - throw cms::Exception("EvFDaqDirector") + edm::LogError("EvFDaqDirector") << "seek on fu read/write lock for updating failed with error " << strerror(errno); + setExceptionState = true; + return noFile; } } } else { @@ -763,8 +770,13 @@ namespace evf { return boost::lexical_cast(data); } - bool EvFDaqDirector::bumpFile( - unsigned int& ls, unsigned int& index, std::string& nextFile, uint32_t& fsize, int maxLS) { + bool EvFDaqDirector::bumpFile(unsigned int& ls, + unsigned int& index, + std::string& nextFile, + uint32_t& fsize, + uint16_t& rawHeaderSize, + int maxLS, + bool& setExceptionState) { if (previousFileSize_ != 0) { if (!fms_) { fms_ = (FastMonitoringService*)(edm::Service().operator->()); @@ -773,6 +785,7 @@ namespace evf { fms_->accumulateFileSize(ls, previousFileSize_); previousFileSize_ = 0; } + nextFile = ""; //reached limit if (maxLS >= 0 && ls > (unsigned int)maxLS) @@ -784,21 +797,34 @@ namespace evf { nextIndex++; // 1. Check suggested file - nextFile = getInputJsonFilePath(ls, index); - if (stat(nextFile.c_str(), &buf) == 0) { - previousFileSize_ = buf.st_size; - fsize = buf.st_size; + std::string nextFileJson = getInputJsonFilePath(ls, index); + if (stat(nextFileJson.c_str(), &buf) == 0) { + fsize = previousFileSize_ = buf.st_size; + nextFile = nextFileJson; return true; } // 2. No file -> lumi ended? (and how many?) else { + // 3. No file -> check for standalone raw file + std::string nextFileRaw = getRawFilePath(ls, index); + if (stat(nextFileRaw.c_str(), &buf) == 0 && rawFileHasHeader(nextFileRaw, rawHeaderSize)) { + fsize = previousFileSize_ = buf.st_size; + nextFile = nextFileRaw; + return true; + } + std::string BUEoLSFile = getEoLSFilePathOnBU(ls); - bool eolFound = (stat(BUEoLSFile.c_str(), &buf) == 0); - while (eolFound) { + + if (stat(BUEoLSFile.c_str(), &buf) == 0) { // recheck that no raw file appeared in the meantime - if (stat(nextFile.c_str(), &buf) == 0) { - previousFileSize_ = buf.st_size; - fsize = buf.st_size; + if (stat(nextFileJson.c_str(), &buf) == 0) { + fsize = previousFileSize_ = buf.st_size; + nextFile = nextFileJson; + return true; + } + if (stat(nextFileRaw.c_str(), &buf) == 0 && rawFileHasHeader(nextFileRaw, rawHeaderSize)) { + fsize = previousFileSize_ = buf.st_size; + nextFile = nextFileRaw; return true; } @@ -813,6 +839,7 @@ namespace evf { edm::LogError("EvFDaqDirector") << "Potential miss of index file in LS -: " << ls << ". Missing " << nextFile << " because " << indexFilesInLS - 1 << " is the highest index expected. Will not update fu.lock file"; + setExceptionState = true; return false; } } @@ -824,18 +851,20 @@ namespace evf { if (maxLS >= 0 && ls > (unsigned int)maxLS) return false; - nextFile = getInputJsonFilePath(ls, 0); - if (stat(nextFile.c_str(), &buf) == 0) { + nextFileJson = getInputJsonFilePath(ls, 0); + nextFileRaw = getRawFilePath(ls, 0); + if (stat(nextFileJson.c_str(), &buf) == 0) { // a new file was found at new lumisection, index 0 - previousFileSize_ = buf.st_size; - fsize = buf.st_size; + fsize = previousFileSize_ = buf.st_size; + nextFile = nextFileJson; + return true; + } + if (stat(nextFileRaw.c_str(), &buf) == 0 && rawFileHasHeader(nextFileRaw, rawHeaderSize)) { + fsize = previousFileSize_ = buf.st_size; + nextFile = nextFileRaw; return true; - } else { - //change of policy: we need to cycle through each LS - return false; } - BUEoLSFile = getEoLSFilePathOnBU(ls); - eolFound = (stat(BUEoLSFile.c_str(), &buf) == 0); + return false; } } // no new file found @@ -1019,12 +1048,52 @@ namespace evf { return 0; //OK } + bool EvFDaqDirector::rawFileHasHeader(std::string const& rawSourcePath, uint16_t& rawHeaderSize) { + int infile; + if ((infile = ::open(rawSourcePath.c_str(), O_RDONLY)) < 0) { + edm::LogWarning("EvFDaqDirector") << "rawFileHasHeader - failed to open input file -: " << rawSourcePath << " : " + << strerror(errno); + return false; + } + constexpr std::size_t buf_sz = sizeof(FRDFileHeader_v1); //try to read v1 FRD header size + FRDFileHeader_v1 fileHead; + + ssize_t sz_read = ::read(infile, (char*)&fileHead, buf_sz); + + if (sz_read < 0) { + edm::LogError("EvFDaqDirector") << "rawFileHasHeader - unable to read " << rawSourcePath << " : " + << strerror(errno); + if (infile != -1) + close(infile); + return false; + } + if ((size_t)sz_read < buf_sz) { + edm::LogError("EvFDaqDirector") << "rawFileHasHeader - file smaller than header: " << rawSourcePath; + if (infile != -1) + close(infile); + return false; + } + + uint16_t frd_version = getFRDFileHeaderVersion(fileHead.id_, fileHead.version_); + + close(infile); + + if (frd_version > 0) { + rawHeaderSize = fileHead.headerSize_; + return true; + } + + rawHeaderSize = 0; + return false; + } + int EvFDaqDirector::grabNextJsonFromRaw(std::string const& rawSourcePath, int& rawFd, uint16_t& rawHeaderSize, int64_t& fileSizeFromHeader, bool& fileFound, - uint32_t serverLS) { + uint32_t serverLS, + bool closeFile) { fileFound = true; //take only first three tokens delimited by "_" in the renamed raw file name @@ -1047,7 +1116,7 @@ namespace evf { int32_t nbEventsWrittenRaw; int64_t fileSizeFromRaw; auto ret = parseFRDFileHeader( - rawSourcePath, rawFd, rawHeaderSize, lsFromRaw, nbEventsWrittenRaw, fileSizeFromRaw, true, true, false); + rawSourcePath, rawFd, rawHeaderSize, lsFromRaw, nbEventsWrittenRaw, fileSizeFromRaw, true, true, closeFile); if (ret != 0) { if (ret == 1) fileFound = false; @@ -1719,7 +1788,7 @@ namespace evf { if (fileStatus == newFile) { if (rawHeader > 0) serverEventsInNewFile = - grabNextJsonFromRaw(nextFileRaw, rawFd, rawHeaderSize, fileSizeFromMetadata, fileFound, serverLS); + grabNextJsonFromRaw(nextFileRaw, rawFd, rawHeaderSize, fileSizeFromMetadata, fileFound, serverLS, false); else serverEventsInNewFile = grabNextJsonFile(nextFileJson, nextFileRaw, fileSizeFromMetadata, fileFound); } diff --git a/EventFilter/Utilities/src/EvFOutputModule.cc b/EventFilter/Utilities/src/EvFOutputModule.cc index e7be8123f4686..25e103bbbf0d2 100644 --- a/EventFilter/Utilities/src/EvFOutputModule.cc +++ b/EventFilter/Utilities/src/EvFOutputModule.cc @@ -140,7 +140,7 @@ namespace evf { edm::ParameterSetDescription desc; edm::StreamerOutputModuleCommon::fillDescription(desc); EvFOutputModuleType::fillDescription(desc); - desc.addUntracked("psetMap", {"psetMap"}) + desc.addUntracked("psetMap", {"hltPSetMap"}) ->setComment("Optionally allow the map of ParameterSets to be calculated externally."); descriptions.addDefault(desc); } diff --git a/EventFilter/Utilities/src/FedRawDataInputSource.cc b/EventFilter/Utilities/src/FedRawDataInputSource.cc index f763fd28a37e3..1706dc5709278 100644 --- a/EventFilter/Utilities/src/FedRawDataInputSource.cc +++ b/EventFilter/Utilities/src/FedRawDataInputSource.cc @@ -16,7 +16,6 @@ #include #include -#include "DataFormats/FEDRawData/interface/FEDNumbering.h" #include "DataFormats/FEDRawData/interface/FEDHeader.h" #include "DataFormats/FEDRawData/interface/FEDTrailer.h" #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h" @@ -61,6 +60,8 @@ FedRawDataInputSource::FedRawDataInputSource(edm::ParameterSet const& pset, edm: alwaysStartFromFirstLS_(pset.getUntrackedParameter("alwaysStartFromFirstLS", false)), verifyChecksum_(pset.getUntrackedParameter("verifyChecksum", true)), useL1EventID_(pset.getUntrackedParameter("useL1EventID", false)), + testTCDSFEDRange_( + pset.getUntrackedParameter>("testTCDSFEDRange", std::vector())), fileNames_(pset.getUntrackedParameter>("fileNames", std::vector())), fileListMode_(pset.getUntrackedParameter("fileListMode", false)), fileListLoopMode_(pset.getUntrackedParameter("fileListLoopMode", false)), @@ -76,6 +77,15 @@ FedRawDataInputSource::FedRawDataInputSource(edm::ParameterSet const& pset, edm: edm::LogInfo("FedRawDataInputSource") << "Construction. read-ahead chunk size -: " << std::endl << (eventChunkSize_ / 1048576) << " MB on host " << thishost; + if (!testTCDSFEDRange_.empty()) { + if (testTCDSFEDRange_.size() != 2) { + throw cms::Exception("FedRawDataInputSource::fillFEDRawDataCollection") + << "Invalid TCDS Test FED range parameter"; + } + MINTCDSuTCAFEDID_ = testTCDSFEDRange_[0]; + MAXTCDSuTCAFEDID_ = testTCDSFEDRange_[1]; + } + long autoRunNumber = -1; if (fileListMode_) { autoRunNumber = initFileList(); @@ -165,10 +175,9 @@ FedRawDataInputSource::~FedRawDataInputSource() { quit_threads_ = true; //delete any remaining open files - for (auto it = filesToDelete_.begin(); it != filesToDelete_.end(); it++) { - std::string fileToDelete = it->second->fileName_; - it->second.release(); - } + for (auto it = filesToDelete_.begin(); it != filesToDelete_.end(); it++) + it->second.reset(); + if (startedSupervisorThread_) { readSupervisorThread_->join(); } else { @@ -208,6 +217,8 @@ void FedRawDataInputSource::fillDescriptions(edm::ConfigurationDescriptions& des ->setComment("Verify event CRC-32C checksum of FRDv5 and higher or Adler32 with v3 and v4"); desc.addUntracked("useL1EventID", false) ->setComment("Use L1 event ID from FED header if true or from TCDS FED if false"); + desc.addUntracked>("testTCDSFEDRange", std::vector()) + ->setComment("[min, max] range to search for TCDS FED ID in test setup"); desc.addUntracked("fileListMode", false) ->setComment("Use fileNames parameter to directly specify raw files to open"); desc.addUntracked>("fileNames", std::vector()) @@ -355,7 +366,7 @@ inline evf::EvFDaqDirector::FileStatus FedRawDataInputSource::getNextEvent() { if (status == evf::EvFDaqDirector::runEnded) { if (fms_) fms_->setInState(evf::FastMonitoringThread::inRunEnd); - currentFile_.release(); + currentFile_.reset(); return status; } else if (status == evf::EvFDaqDirector::runAbort) { throw cms::Exception("FedRawDataInputSource::getNextEvent") @@ -372,8 +383,7 @@ inline evf::EvFDaqDirector::FileStatus FedRawDataInputSource::getNextEvent() { } else { //let this be picked up from next event status = evf::EvFDaqDirector::noFile; } - - currentFile_.release(); + currentFile_.reset(); return status; } else if (status == evf::EvFDaqDirector::newFile) { currentFileIndex_++; @@ -395,8 +405,7 @@ inline evf::EvFDaqDirector::FileStatus FedRawDataInputSource::getNextEvent() { maybeOpenNewLumiSection(currentFile_->lumi_); } //immediately delete empty file - std::string currentName = currentFile_->fileName_; - currentFile_.release(); + currentFile_.reset(); return evf::EvFDaqDirector::noFile; } @@ -422,8 +431,7 @@ inline evf::EvFDaqDirector::FileStatus FedRawDataInputSource::getNextEvent() { filesToDelete_.push_back(std::pair>(currentFileIndex_, std::move(currentFile_))); } else { //in single-thread and stream jobs, events are already processed - std::string currentName = currentFile_->fileName_; - currentFile_.release(); + currentFile_.reset(); } return evf::EvFDaqDirector::noFile; } @@ -475,8 +483,8 @@ inline evf::EvFDaqDirector::FileStatus FedRawDataInputSource::getNextEvent() { readNextChunkIntoBuffer(currentFile_.get()); if (detectedFRDversion_ == 0) { - detectedFRDversion_ = *((uint32*)dataPosition); - if (detectedFRDversion_ > 5) + detectedFRDversion_ = *((uint16_t*)dataPosition); + if (detectedFRDversion_ > FRDHeaderMaxVersion) throw cms::Exception("FedRawDataInputSource::getNextEvent") << "Unknown FRD version -: " << detectedFRDversion_; assert(detectedFRDversion_ >= 1); @@ -614,13 +622,16 @@ void FedRawDataInputSource::read(edm::EventPrincipal& eventPrincipal) { if (useL1EventID_) { eventID_ = edm::EventID(eventRunNumber_, currentLumiSection_, L1EventID_); - edm::EventAuxiliary aux(eventID_, processGUID(), tstamp, true, edm::EventAuxiliary::PhysicsTrigger); + edm::EventAuxiliary aux(eventID_, processGUID(), tstamp, event_->isRealData(), edm::EventAuxiliary::PhysicsTrigger); aux.setProcessHistoryID(processHistoryID_); makeEvent(eventPrincipal, aux); } else if (tcds_pointer_ == nullptr) { - assert(GTPEventID_); + if (!GTPEventID_) { + throw cms::Exception("FedRawDataInputSource::read") + << "No TCDS or GTP FED in event with FEDHeader EID -: " << L1EventID_; + } eventID_ = edm::EventID(eventRunNumber_, currentLumiSection_, GTPEventID_); - edm::EventAuxiliary aux(eventID_, processGUID(), tstamp, true, edm::EventAuxiliary::PhysicsTrigger); + edm::EventAuxiliary aux(eventID_, processGUID(), tstamp, event_->isRealData(), edm::EventAuxiliary::PhysicsTrigger); aux.setProcessHistoryID(processHistoryID_); makeEvent(eventPrincipal, aux); } else { @@ -630,6 +641,7 @@ void FedRawDataInputSource::read(edm::EventPrincipal& eventPrincipal) { evf::evtn::makeEventAuxiliary(tcds, eventRunNumber_, currentLumiSection_, + event_->isRealData(), static_cast(fedHeader.triggerType()), processGUID(), !fileListLoopMode_); @@ -666,7 +678,6 @@ void FedRawDataInputSource::read(edm::EventPrincipal& eventPrincipal) { } if (!fileIsBeingProcessed) { std::string fileToDelete = it->second->fileName_; - //it->second.release(); it = filesToDelete_.erase(it); } else it++; @@ -692,6 +703,7 @@ edm::Timestamp FedRawDataInputSource::fillFEDRawDataCollection(FEDRawDataCollect unsigned char* event = (unsigned char*)event_->payload(); GTPEventID_ = 0; tcds_pointer_ = nullptr; + uint16_t selectedTCDSFed = 0; while (eventSize > 0) { assert(eventSize >= FEDTrailer::length); eventSize -= FEDTrailer::length; @@ -703,9 +715,13 @@ edm::Timestamp FedRawDataInputSource::fillFEDRawDataCollection(FEDRawDataCollect const uint16_t fedId = fedHeader.sourceID(); if (fedId > FEDNumbering::MAXFEDID) { throw cms::Exception("FedRawDataInputSource::fillFEDRawDataCollection") << "Out of range FED ID : " << fedId; - } - if (fedId == FEDNumbering::MINTCDSuTCAFEDID) { - tcds_pointer_ = event + eventSize; + } else if (fedId >= MINTCDSuTCAFEDID_ && fedId <= MAXTCDSuTCAFEDID_) { + if (!selectedTCDSFed) { + selectedTCDSFed = fedId; + tcds_pointer_ = event + eventSize; + } else + throw cms::Exception("FedRawDataInputSource::fillFEDRawDataCollection") + << "Second TCDS FED ID " << fedId << " found. First ID: " << selectedTCDSFed; } if (fedId == FEDNumbering::MINTriggerGTPFEDID) { if (evf::evtn::evm_board_sense(event + eventSize, fedSize)) @@ -843,7 +859,8 @@ void FedRawDataInputSource::readSupervisor() { ls = lsFromRaw; } } else if (!useFileBroker_) - status = daqDirector_->updateFuLock(ls, nextFile, fileSizeIndex, thisLockWaitTimeUs); + status = daqDirector_->updateFuLock( + ls, nextFile, fileSizeIndex, rawHeaderSize, thisLockWaitTimeUs, setExceptionState_); else { status = daqDirector_->getNextFromFileBroker(currentLumiSection, ls, @@ -881,7 +898,8 @@ void FedRawDataInputSource::readSupervisor() { fms_->setInStateSup(evf::FastMonitoringThread::inRunEnd); usleep(100000); //now all files should have appeared in ramdisk, check again if any raw files were left behind - status = daqDirector_->updateFuLock(ls, nextFile, fileSizeIndex, thisLockWaitTimeUs); + status = daqDirector_->updateFuLock( + ls, nextFile, fileSizeIndex, rawHeaderSize, thisLockWaitTimeUs, setExceptionState_); if (currentLumiSection != ls && status == evf::EvFDaqDirector::runEnded) status = evf::EvFDaqDirector::noFile; } @@ -977,7 +995,7 @@ void FedRawDataInputSource::readSupervisor() { std::string rawFile; //file service will report raw extension - if (useFileBroker_) + if (useFileBroker_ || rawHeaderSize) rawFile = nextFile; else { boost::filesystem::path rawFilePath(nextFile); @@ -1006,9 +1024,18 @@ void FedRawDataInputSource::readSupervisor() { eventsInNewFile = -1; } else { std::string empty; - if (!useFileBroker_) - eventsInNewFile = daqDirector_->grabNextJsonFileAndUnlock(nextFile); - else + if (!useFileBroker_) { + if (rawHeaderSize) { + int rawFdEmpty = -1; + uint16_t rawHeaderCheck; + bool fileFound; + eventsInNewFile = daqDirector_->grabNextJsonFromRaw( + nextFile, rawFdEmpty, rawHeaderCheck, fileSizeFromMetadata, fileFound, 0, true); + assert(fileFound && rawHeaderCheck == rawHeaderSize); + daqDirector_->unlockFULocal(); + } else + eventsInNewFile = daqDirector_->grabNextJsonFileAndUnlock(nextFile); + } else eventsInNewFile = serverEventsInNewFile; assert(eventsInNewFile >= 0); assert((eventsInNewFile > 0) == @@ -1212,7 +1239,7 @@ void FedRawDataInputSource::readWorker(unsigned int tid) { chunk = workerJob_[tid].second; //skip reading initial header size in first chunk if inheriting file descriptor (already set at appropriate position) - unsigned int bufferLeft = (chunk->offset_ == 0 && file->rawFd_ != 0) ? file->rawHeaderSize_ : 0; + unsigned int bufferLeft = (chunk->offset_ == 0 && file->rawFd_ != -1) ? file->rawHeaderSize_ : 0; //if only one worker thread exists, use single fd for all operations //if more worker threads exist, use rawFd_ for only the first read operation and then close file @@ -1312,9 +1339,9 @@ void FedRawDataInputSource::readWorker(unsigned int tid) { //detect FRD event version. Skip file Header if it exists if (detectedFRDversion_ == 0 && chunk->offset_ == 0) { - detectedFRDversion_ = *((uint32*)(chunk->buf_ + file->rawHeaderSize_)); + detectedFRDversion_ = *((uint16_t*)(chunk->buf_ + file->rawHeaderSize_)); } - assert(detectedFRDversion_ <= 5); + assert(detectedFRDversion_ <= FRDHeaderMaxVersion); chunk->readComplete_ = true; //this is atomic to secure the sequential buffer fill before becoming available for processing) file->chunks_[chunk->fileIndex_] = chunk; //put the completed chunk in the file chunk vector at predetermined index @@ -1403,15 +1430,17 @@ void FedRawDataInputSource::readNextChunkIntoBuffer(InputFile* file) { if (fileDescriptor_ < 0) { bufferInputRead_ = 0; - if (file->rawFd_ == -1) + if (file->rawFd_ == -1) { fileDescriptor_ = open(file->fileName_.c_str(), O_RDONLY); - else { + if (file->rawHeaderSize_) + lseek(fileDescriptor_, file->rawHeaderSize_, SEEK_SET); + } else fileDescriptor_ = file->rawFd_; - //skip header size in destination buffer (chunk position was already adjusted) - bufferInputRead_ += file->rawHeaderSize_; - existingSize += file->rawHeaderSize_; - } - //off_t pos = lseek(fileDescriptor,0,SEEK_SET); + + //skip header size in destination buffer (chunk position was already adjusted) + bufferInputRead_ += file->rawHeaderSize_; + existingSize += file->rawHeaderSize_; + if (fileDescriptor_ >= 0) LogDebug("FedRawDataInputSource") << "opened file -: " << std::endl << file->fileName_; else { @@ -1419,32 +1448,44 @@ void FedRawDataInputSource::readNextChunkIntoBuffer(InputFile* file) { << "failed to open file " << std::endl << file->fileName_ << " fd:" << fileDescriptor_; } - } - - if (file->chunkPosition_ == 0) { //in the rare case the last byte barely fit + //fill chunk (skipping file header if present) for (unsigned int i = 0; i < readBlocks_; i++) { - const ssize_t last = ::read(fileDescriptor_, (void*)(file->chunks_[0]->buf_ + existingSize), eventChunkBlock_); + const ssize_t last = ::read(fileDescriptor_, + (void*)(file->chunks_[0]->buf_ + existingSize), + eventChunkBlock_ - (i == readBlocks_ - 1 ? existingSize : 0)); bufferInputRead_ += last; existingSize += last; } + } else { - const uint32_t chunksize = file->chunkPosition_; - const uint32_t blockcount = chunksize / eventChunkBlock_; - const uint32_t leftsize = chunksize % eventChunkBlock_; - uint32_t existingSizeLeft = eventChunkSize_ - file->chunkPosition_; - memmove((void*)file->chunks_[0]->buf_, file->chunks_[0]->buf_ + file->chunkPosition_, existingSizeLeft); - - for (uint32_t i = 0; i < blockcount; i++) { - const ssize_t last = - ::read(fileDescriptor_, (void*)(file->chunks_[0]->buf_ + existingSizeLeft), eventChunkBlock_); - bufferInputRead_ += last; - existingSizeLeft += last; - } - if (leftsize) { - const ssize_t last = ::read(fileDescriptor_, (void*)(file->chunks_[0]->buf_ + existingSizeLeft), leftsize); - bufferInputRead_ += last; + //continue reading + if (file->chunkPosition_ == 0) { //in the rare case the last byte barely fit + for (unsigned int i = 0; i < readBlocks_; i++) { + const ssize_t last = ::read(fileDescriptor_, (void*)(file->chunks_[0]->buf_ + existingSize), eventChunkBlock_); + bufferInputRead_ += last; + existingSize += last; + } + } else { + //event didn't fit in last chunk, so leftover must be moved to the beginning and completed + uint32_t existingSizeLeft = eventChunkSize_ - file->chunkPosition_; + memmove((void*)file->chunks_[0]->buf_, file->chunks_[0]->buf_ + file->chunkPosition_, existingSizeLeft); + + //calculate amount of data that can be added + const uint32_t blockcount = file->chunkPosition_ / eventChunkBlock_; + const uint32_t leftsize = file->chunkPosition_ % eventChunkBlock_; + + for (uint32_t i = 0; i < blockcount; i++) { + const ssize_t last = + ::read(fileDescriptor_, (void*)(file->chunks_[0]->buf_ + existingSizeLeft), eventChunkBlock_); + bufferInputRead_ += last; + existingSizeLeft += last; + } + if (leftsize) { + const ssize_t last = ::read(fileDescriptor_, (void*)(file->chunks_[0]->buf_ + existingSizeLeft), leftsize); + bufferInputRead_ += last; + } + file->chunkPosition_ = 0; //data was moved to beginning of the chunk } - file->chunkPosition_ = 0; //data was moved to beginning of the chunk } if (bufferInputRead_ == file->fileSize_) { // no more data in this file if (fileDescriptor_ != -1) { @@ -1489,7 +1530,12 @@ long FedRawDataInputSource::initFileList() { //get run number from first file in the vector boost::filesystem::path fileName = fileNames_[0]; std::string fileStem = fileName.stem().string(); - auto end = fileStem.find("_"); + if (fileStem.find("file://") == 0) + fileStem = fileStem.substr(7); + else if (fileStem.find("file:") == 0) + fileStem = fileStem.substr(5); + auto end = fileStem.find('_'); + if (fileStem.find("run") == 0) { std::string runStr = fileStem.substr(3, end - 3); try { diff --git a/EventFilter/Utilities/src/json_reader.cpp b/EventFilter/Utilities/src/json_reader.cpp index 14bdb45b6663d..efc9802860836 100644 --- a/EventFilter/Utilities/src/json_reader.cpp +++ b/EventFilter/Utilities/src/json_reader.cpp @@ -430,7 +430,7 @@ namespace Json { while (token.type_ == tokenComment && ok) { ok = readToken(token); } - bool badTokenType = (token.type_ == tokenArraySeparator || token.type_ == tokenArrayEnd); + bool badTokenType = (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { return addErrorAndRecover("Missing ',' or ']' in array declaration", token, tokenArrayEnd); } diff --git a/EventFilter/Utilities/test/startBU.py b/EventFilter/Utilities/test/startBU.py index 7b60c83f1a960..a42e287a1ee21 100644 --- a/EventFilter/Utilities/test/startBU.py +++ b/EventFilter/Utilities/test/startBU.py @@ -123,6 +123,7 @@ process.s = cms.EDProducer("DaqFakeReader", meanSize = cms.untracked.uint32(options.fedMeanSize), width = cms.untracked.uint32(int(math.ceil(options.fedMeanSize/2.))), + tcdsFEDID = cms.untracked.uint32(1024), injectErrPpm = cms.untracked.uint32(0) ) @@ -130,7 +131,7 @@ ProductLabel = cms.untracked.string("s"), numEventsPerFile= cms.untracked.uint32(options.eventsPerFile), frdFileVersion=cms.untracked.uint32(options.frdFileVersion), - frdVersion=cms.untracked.uint32(5) + frdVersion=cms.untracked.uint32(6), ) process.p = cms.Path(process.s+process.a) diff --git a/EventFilter/Utilities/test/startFU.py b/EventFilter/Utilities/test/startFU.py index 8d3394a4ecfb7..86d09e09b615a 100644 --- a/EventFilter/Utilities/test/startFU.py +++ b/EventFilter/Utilities/test/startFU.py @@ -84,7 +84,7 @@ process.source = cms.Source("FedRawDataInputSource", getLSFromFilename = cms.untracked.bool(True), verifyChecksum = cms.untracked.bool(True), - useL1EventID = cms.untracked.bool(True), + useL1EventID = cms.untracked.bool(False), eventChunkSize = cms.untracked.uint32(8), eventChunkBlock = cms.untracked.uint32(8), numBuffers = cms.untracked.uint32(2), @@ -120,7 +120,12 @@ defaultAction = cms.untracked.int32(0), defaultQualifier = cms.untracked.int32(5)) -process.p1 = cms.Path(process.a*process.filter1) + +process.tcdsRawToDigi = cms.EDProducer("TcdsRawToDigi", + InputLabel = cms.InputTag("rawDataCollector") +) + +process.p1 = cms.Path(process.a*process.tcdsRawToDigi*process.filter1) process.p2 = cms.Path(process.b*process.filter2) process.streamA = cms.OutputModule("EvFOutputModule", diff --git a/EventFilter/Utilities/test/unittest_FU.py b/EventFilter/Utilities/test/unittest_FU.py index ae0d4c2e63f0f..e5e8e54c16f2a 100644 --- a/EventFilter/Utilities/test/unittest_FU.py +++ b/EventFilter/Utilities/test/unittest_FU.py @@ -86,7 +86,7 @@ process.source = cms.Source("FedRawDataInputSource", getLSFromFilename = cms.untracked.bool(True), verifyChecksum = cms.untracked.bool(True), - useL1EventID = cms.untracked.bool(True), + useL1EventID = cms.untracked.bool(False), eventChunkSize = cms.untracked.uint32(8), eventChunkBlock = cms.untracked.uint32(8), numBuffers = cms.untracked.uint32(2), @@ -130,7 +130,11 @@ defaultAction = cms.untracked.int32(0), defaultQualifier = cms.untracked.int32(5)) -process.p1 = cms.Path(process.a*process.filter1) +process.tcdsRawToDigi = cms.EDProducer("TcdsRawToDigi", + InputLabel = cms.InputTag("rawDataCollector") +) + +process.p1 = cms.Path(process.a*process.tcdsRawToDigi*process.filter1) process.p2 = cms.Path(process.b*process.filter2) process.streamA = cms.OutputModule("EvFOutputModule", diff --git a/FWCore/Integration/test/TestInterProcessProd.cc b/FWCore/Integration/test/TestInterProcessProd.cc index 26d256aabbcd8..382b824887fd5 100644 --- a/FWCore/Integration/test/TestInterProcessProd.cc +++ b/FWCore/Integration/test/TestInterProcessProd.cc @@ -19,7 +19,7 @@ namespace testinter { struct StreamCache { StreamCache(const std::string& iConfig, int id) : id_{id}, - channel_("testProd", id_), + channel_("testProd", id_, 60), readBuffer_{channel_.sharedMemoryName(), channel_.fromWorkerBufferInfo()}, deserializer_{readBuffer_}, br_deserializer_{readBuffer_}, diff --git a/FWCore/Integration/test/TestInterProcessRandomProd.cc b/FWCore/Integration/test/TestInterProcessRandomProd.cc index 95c42023b8484..8cd9164f3c9b2 100644 --- a/FWCore/Integration/test/TestInterProcessRandomProd.cc +++ b/FWCore/Integration/test/TestInterProcessRandomProd.cc @@ -31,7 +31,7 @@ namespace testinter { struct StreamCache { StreamCache(const std::string& iConfig, int id) : id_{id}, - channel_("testProd", id_), + channel_("testProd", id_, 60), readBuffer_{channel_.sharedMemoryName(), channel_.fromWorkerBufferInfo()}, writeBuffer_{std::string("Rand") + channel_.sharedMemoryName(), channel_.toWorkerBufferInfo()}, deserializer_{readBuffer_}, diff --git a/FWCore/SharedMemory/interface/ControllerChannel.h b/FWCore/SharedMemory/interface/ControllerChannel.h index 8c189ae1e814d..1646b1652821d 100644 --- a/FWCore/SharedMemory/interface/ControllerChannel.h +++ b/FWCore/SharedMemory/interface/ControllerChannel.h @@ -39,7 +39,7 @@ namespace edm::shared_memory { /** iName is used as the base for the shared memory name. The full name uses iID as well as getpid() to create the value sharedMemoryName(). iID allows multiple ControllChannels to use the same base name iName. */ - ControllerChannel(std::string const& iName, int iID); + ControllerChannel(std::string const& iName, int iID, unsigned int iMaxWaitInSeconds); ~ControllerChannel(); ControllerChannel(const ControllerChannel&) = delete; const ControllerChannel& operator=(const ControllerChannel&) = delete; @@ -60,7 +60,7 @@ namespace edm::shared_memory { using namespace boost::posix_time; //std::cout << id_ << " waiting for external process" << std::endl; - if (not cndToMain_.timed_wait(lock, microsec_clock::universal_time() + seconds(60))) { + if (not cndToMain_.timed_wait(lock, microsec_clock::universal_time() + seconds(maxWaitInSeconds_))) { //std::cout << id_ << " FAILED waiting for external process" << std::endl; throw cms::Exception("ExternalFailed"); } else { @@ -115,6 +115,7 @@ namespace edm::shared_memory { // ---------- member data -------------------------------- int id_; + unsigned int maxWaitInSeconds_; std::string smName_; boost::interprocess::managed_shared_memory managed_sm_; BufferInfo* toWorkerBufferInfo_; diff --git a/FWCore/SharedMemory/src/ControllerChannel.cc b/FWCore/SharedMemory/src/ControllerChannel.cc index 184796737e20b..5190d326cd96d 100644 --- a/FWCore/SharedMemory/src/ControllerChannel.cc +++ b/FWCore/SharedMemory/src/ControllerChannel.cc @@ -31,8 +31,9 @@ using namespace boost::interprocess; // constructors and destructor // -ControllerChannel::ControllerChannel(std::string const& iName, int id) +ControllerChannel::ControllerChannel(std::string const& iName, int id, unsigned int iMaxWaitInSeconds) : id_{id}, + maxWaitInSeconds_{iMaxWaitInSeconds}, smName_{uniqueName(iName)}, managed_sm_{open_or_create, smName_.c_str(), 1024}, toWorkerBufferInfo_{bufferInfo(channel_names::kToWorkerBufferInfo, managed_sm_)}, @@ -89,7 +90,7 @@ bool ControllerChannel::wait(scoped_lock& lock, edm::Transition iTr //std::cout << id_ << " waiting" << std::endl; using namespace boost::posix_time; - if (not cndToMain_.timed_wait(lock, microsec_clock::universal_time() + seconds(60))) { + if (not cndToMain_.timed_wait(lock, microsec_clock::universal_time() + seconds(maxWaitInSeconds_))) { //std::cout << id_ << " waiting FAILED" << std::endl; return false; } diff --git a/FWCore/SharedMemory/test/test_channels.cc b/FWCore/SharedMemory/test/test_channels.cc index 82ec63221102d..d38930ff42eff 100644 --- a/FWCore/SharedMemory/test/test_channels.cc +++ b/FWCore/SharedMemory/test/test_channels.cc @@ -10,7 +10,7 @@ namespace { int controller(int argc, char** argv) { using namespace edm::shared_memory; - ControllerChannel channel("TestChannel", 0); + ControllerChannel channel("TestChannel", 0, 60); //Pipe has to close AFTER we tell the worker to stop auto closePipe = [](FILE* iFile) { pclose(iFile); }; diff --git a/GeneratorInterface/Core/plugins/ExternalGeneratorFilter.cc b/GeneratorInterface/Core/plugins/ExternalGeneratorFilter.cc index 91eb2c1dac81c..63c1ddf069322 100644 --- a/GeneratorInterface/Core/plugins/ExternalGeneratorFilter.cc +++ b/GeneratorInterface/Core/plugins/ExternalGeneratorFilter.cc @@ -30,9 +30,9 @@ using namespace edm::shared_memory; namespace externalgen { struct StreamCache { - StreamCache(const std::string& iConfig, int id, bool verbose) + StreamCache(const std::string& iConfig, int id, bool verbose, unsigned int waitTime) : id_{id}, - channel_("extGen", id_), + channel_("extGen", id_, waitTime), readBuffer_{channel_.sharedMemoryName(), channel_.fromWorkerBufferInfo()}, writeBuffer_{std::string("Rand") + channel_.sharedMemoryName(), channel_.toWorkerBufferInfo()}, deserializer_{readBuffer_}, @@ -204,6 +204,7 @@ class ExternalGeneratorFilter : public edm::global::EDFilter()}, lumiInfoToken_{produces()}, config_{iPSet.getUntrackedParameter("@python_config")}, - verbose_{iPSet.getUntrackedParameter("_external_process_verbose_")} {} + verbose_{iPSet.getUntrackedParameter("_external_process_verbose_")}, + waitTime_{iPSet.getUntrackedParameter("_external_process_waitTime_")} {} std::unique_ptr ExternalGeneratorFilter::beginStream(edm::StreamID iID) const { auto const label = moduleDescription().moduleLabel(); @@ -239,7 +241,7 @@ process = TestProcess() process.add_(cms.Service("InitRootHandlers", UnloadRootSigHandler=cms.untracked.bool(True))) )_"; - auto cache = std::make_unique(config, iID.value(), verbose_); + auto cache = std::make_unique(config, iID.value(), verbose_, waitTime_); if (iID.value() == 0) { stream0Cache_ = cache.get(); diff --git a/GeneratorInterface/Core/python/ExternalGeneratorFilter.py b/GeneratorInterface/Core/python/ExternalGeneratorFilter.py index b7f2da8f41214..166b8f2831b71 100644 --- a/GeneratorInterface/Core/python/ExternalGeneratorFilter.py +++ b/GeneratorInterface/Core/python/ExternalGeneratorFilter.py @@ -1,8 +1,9 @@ import FWCore.ParameterSet.Config as cms class ExternalGeneratorFilter(cms.EDFilter): - def __init__(self, prod, _external_process_verbose_ = cms.untracked.bool(False)): + def __init__(self, prod, _external_process_waitTime_ = cms.untracked.uint32(60), _external_process_verbose_ = cms.untracked.bool(False)): self.__dict__['_external_process_verbose_']=_external_process_verbose_ + self.__dict__['_external_process_waitTime_']=_external_process_waitTime_ self.__dict__['_prod'] = prod super(cms.EDFilter,self).__init__('ExternalGeneratorFilter') def __setattr__(self, name, value): @@ -15,6 +16,8 @@ def __getattr__(self, name): if name == '_external_process_verbose_': return self.__dict__['_external_process_verbose_'] return getattr(self._prod, name) + def __getstate__(self): return self.__dict__ + def __setstate__(self, d): self.__dict__.update(d) def clone(self, **params): returnValue = ExternalGeneratorFilter.__new__(type(self)) returnValue.__init__(self._prod.clone()) @@ -27,6 +30,7 @@ def insertInto(self, parameterSet, myname): newpset.addString(True, "@external_type", self._prod.type_()) newpset.addString(False,"@python_config", self._prod.dumpPython()) newpset.addBool(False,"_external_process_verbose_", self._external_process_verbose_.value()) + newpset.addUInt32(False,"_external_process_waitTime_", self._external_process_waitTime_.value()) self._prod.insertContentsInto(newpset) parameterSet.addPSet(True, self.nameInProcessDesc_(myname), newpset) def dumpPython(self, options=cms.PrintOptions()): diff --git a/GeneratorInterface/LHEInterface/scripts/cmsLHEtoEOSManager.py b/GeneratorInterface/LHEInterface/scripts/cmsLHEtoEOSManager.py index 51359809593d2..43d6fcf142e1c 100755 --- a/GeneratorInterface/LHEInterface/scripts/cmsLHEtoEOSManager.py +++ b/GeneratorInterface/LHEInterface/scripts/cmsLHEtoEOSManager.py @@ -11,16 +11,16 @@ import re defaultEOSRootPath = '/eos/cms/store/lhe' -defaultEOSLoadPath = 'root://eoscms/' -defaultEOSlistCommand = 'xrd eoscms dirlist ' -defaultEOSmkdirCommand = 'xrd eoscms mkdir ' -defaultEOSfeCommand = 'xrd eoscms existfile ' +defaultEOSLoadPath = 'root://eoscms.cern.ch/' +defaultEOSlistCommand = 'xrdfs '+defaultEOSLoadPath+' ls ' +defaultEOSmkdirCommand = 'xrdfs '+defaultEOSLoadPath+' mkdir ' +defaultEOSfeCommand = 'xrdfs '+defaultEOSLoadPath+' stat -q IsReadable ' defaultEOScpCommand = 'xrdcp -np ' def findXrdDir(theDirRecord): elements = theDirRecord.split(' ') - if len(elements) > 1: + if len(elements): return elements[-1].rstrip('\n').split('/')[-1] else: return None @@ -65,7 +65,7 @@ def fileUpload(uploadPath,lheList, checkSumList, reallyDoIt): theCommand = defaultEOSfeCommand+' '+newFileName exeFullList = subprocess.Popen(["/bin/sh","-c",theCommand], stdout=subprocess.PIPE) result = exeFullList.stdout.readlines() - if result[0].rstrip('\n') == 'The file exists.': + if result[-1].rstrip('\n') == 'Query: IsReadable': addFile = False print('File '+newFileName+' already exists: do you want to overwrite? [y/n]') reply = raw_input() diff --git a/Geometry/CMSCommonData/data/beampipe/2021/v1/beampipe.xml b/Geometry/CMSCommonData/data/beampipe/2021/v1/beampipe.xml index 2cb249237a617..27517206a0658 100644 --- a/Geometry/CMSCommonData/data/beampipe/2021/v1/beampipe.xml +++ b/Geometry/CMSCommonData/data/beampipe/2021/v1/beampipe.xml @@ -31,7 +31,7 @@ - + diff --git a/Geometry/CMSCommonData/data/cms/2021/v3/cms.xml b/Geometry/CMSCommonData/data/cms/2021/v3/cms.xml index e646067a3e262..1279899cbc593 100644 --- a/Geometry/CMSCommonData/data/cms/2021/v3/cms.xml +++ b/Geometry/CMSCommonData/data/cms/2021/v3/cms.xml @@ -87,7 +87,7 @@ - + diff --git a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D49.xml b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D49.xml index 36841cfe944bb..a9becb802f78b 100644 --- a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D49.xml +++ b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D49.xml @@ -72,7 +72,6 @@ - diff --git a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D50.xml b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D50.xml index 8d3311865262b..6dfacc83d9f41 100644 --- a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D50.xml +++ b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D50.xml @@ -72,7 +72,6 @@ - diff --git a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D51.xml b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D51.xml index 7f2c63befe4be..6cff0317dd4a3 100644 --- a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D51.xml +++ b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D51.xml @@ -72,7 +72,6 @@ - diff --git a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D52.xml b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D52.xml index f32ad3d4ced4b..4c0c66664b556 100644 --- a/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D52.xml +++ b/Geometry/CMSCommonData/data/dd4hep/cmsExtendedGeometry2026D52.xml @@ -72,7 +72,6 @@ - diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D49XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D49XML_cfi.py index 6c06a33c59fa8..160972563d711 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D49XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D49XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D50XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D50XML_cfi.py index ad2330a134bc8..2021fe17eb8ab 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D50XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D50XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D51XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D51XML_cfi.py index d6960998cbdf5..6245138f23c91 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D51XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D51XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D53XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D53XML_cfi.py index 88b23477045c7..3098b4d25ebae 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D53XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D53XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D54XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D54XML_cfi.py index d2dddf9637195..a4b0ea468ba0a 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D54XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D54XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D55XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D55XML_cfi.py index 4ee1a3832088e..349ba4f9e2930 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D55XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D55XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v3/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v2/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v2/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v3/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v3/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D56XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D56XML_cfi.py index 3d9ad0a41d112..97346279507b9 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D56XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D56XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v2/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v1/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v1/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v2/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v2/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D57XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D57XML_cfi.py index a1f7670332f68..aef061ac2ca99 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D57XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D57XML_cfi.py @@ -73,7 +73,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v3/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v2/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v2/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v5/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v3/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D58XML_cfi.py b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D58XML_cfi.py index ccda6e6234ede..6a56aa694bff5 100644 --- a/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D58XML_cfi.py +++ b/Geometry/CMSCommonData/python/cmsExtendedGeometry2026D58XML_cfi.py @@ -78,7 +78,6 @@ 'Geometry/MuonCommonData/data/mb4Shield/2021/v1/mb4Shield.xml', 'Geometry/MuonCommonData/data/muonYoke/2021/v3/muonYoke.xml', 'Geometry/MuonCommonData/data/csc/2021/v2/csc.xml', - 'Geometry/MuonCommonData/data/mfshield/2017/v2/mfshield.xml', 'Geometry/MuonCommonData/data/mf/2026/v5/mf.xml', 'Geometry/MuonCommonData/data/rpcf/2026/v3/rpcf.xml', 'Geometry/MuonCommonData/data/gemf/TDR_BaseLine/gemf.xml', diff --git a/Geometry/CaloTopology/interface/HGCalTopology.h b/Geometry/CaloTopology/interface/HGCalTopology.h index 6cda2a63c7a73..44881c34301d9 100644 --- a/Geometry/CaloTopology/interface/HGCalTopology.h +++ b/Geometry/CaloTopology/interface/HGCalTopology.h @@ -85,7 +85,9 @@ class HGCalTopology : public CaloSubdetectorTopology { ///Is this a valid cell id bool valid(const DetId& id) const override; + bool valid(const DetId& id, int cornerMin) const; bool validHashIndex(uint32_t ix) const { return (ix < kSizeForDenseIndexing); } + bool validModule(const DetId& id, int cornerMin) const; unsigned int totalModules() const { return kSizeForDenseIndexing; } unsigned int totalGeomModules() const { return (unsigned int)(2 * kHGeomHalf_); } diff --git a/Geometry/CaloTopology/src/HGCalTopology.cc b/Geometry/CaloTopology/src/HGCalTopology.cc index 762a1a152d2c6..f702195520ecc 100644 --- a/Geometry/CaloTopology/src/HGCalTopology.cc +++ b/Geometry/CaloTopology/src/HGCalTopology.cc @@ -3,6 +3,7 @@ #include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" #include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" #include "Geometry/CaloTopology/interface/HGCalTopology.h" #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" @@ -57,14 +58,14 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { std::vector ids; HGCalTopology::DecodedDetId id = decode(idin); if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { - HGCalDDDConstants::CellType celltype = hdcons_.cellType(id.iType, id.iCell1, id.iCell2); + HGCalTypes::CellType celltype = hdcons_.cellType(id.iType, id.iCell1, id.iCell2); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Type:WaferU:WaferV " << id.iType << ":" << id.iCell1 << ":" << id.iCell2 << " CellType " - << static_cast::type>(celltype); + << static_cast::type>(celltype); #endif switch (celltype) { - case (HGCalDDDConstants::CellType::CentralType): { + case (HGCalTypes::CellType::CentralType): { // cell within the wafer #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Cell Type 0"; @@ -77,7 +78,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::BottomLeftEdge): { + case (HGCalTypes::CellType::BottomLeftEdge): { // bottom left edge int wu1(id.iSec1), wv1(id.iSec2 - 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -95,7 +96,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::LeftEdge): { + case (HGCalTypes::CellType::LeftEdge): { // left edege int wu1(id.iSec1 + 1), wv1(id.iSec2); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -113,7 +114,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::TopLeftEdge): { + case (HGCalTypes::CellType::TopLeftEdge): { // top left edge int wu1(id.iSec1 + 1), wv1(id.iSec2 + 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -131,7 +132,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::TopRightEdge): { + case (HGCalTypes::CellType::TopRightEdge): { // top right edge int wu1(id.iSec1), wv1(id.iSec2 + 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -149,7 +150,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, t1, id.iLay, wu1, wv1, 0, v1 - N1 + 1); break; } - case (HGCalDDDConstants::CellType::RightEdge): { + case (HGCalTypes::CellType::RightEdge): { // right edge int wu1(id.iSec1 - 1), wv1(id.iSec2); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -167,7 +168,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, t1, id.iLay, wu1, wv1, u1 - N1 + 1, 0); break; } - case (HGCalDDDConstants::CellType::BottomRightEdge): { + case (HGCalTypes::CellType::BottomRightEdge): { // bottom right edge int wu1(id.iSec1 - 1), wv1(id.iSec2 - 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -185,7 +186,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::BottomCorner): { + case (HGCalTypes::CellType::BottomCorner): { // bottom corner int wu1(id.iSec1), wv1(id.iSec2 - 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -208,7 +209,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::BottomLeftCorner): { + case (HGCalTypes::CellType::BottomLeftCorner): { // bottom left corner int wu1(id.iSec1 + 1), wv1(id.iSec2); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -231,7 +232,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::TopLeftCorner): { + case (HGCalTypes::CellType::TopLeftCorner): { // top left corner int wu1(id.iSec1 + 1), wv1(id.iSec2 + 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -254,7 +255,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, id.iType, id.iLay, id.iSec1, id.iSec2, id.iCell1 + 1, id.iCell2 + 1); break; } - case (HGCalDDDConstants::CellType::TopCorner): { + case (HGCalTypes::CellType::TopCorner): { // top corner int wu1(id.iSec1 + 1), wv1(id.iSec2 + 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -277,7 +278,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, t2, id.iLay, wu2, wv2, 0, v2 - N2 + 1); break; } - case (HGCalDDDConstants::CellType::TopRightCorner): { + case (HGCalTypes::CellType::TopRightCorner): { // top right corner int wu1(id.iSec1), wv1(id.iSec2 + 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -300,7 +301,7 @@ std::vector HGCalTopology::neighbors(const DetId& idin) const { addHGCSiliconId(ids, id.det, id.zSide, t2, id.iLay, wu2, wv2, u2 - N2 + 1, 0); break; } - case (HGCalDDDConstants::CellType::BottomRightCorner): { + case (HGCalTypes::CellType::BottomRightCorner): { // bottom right corner int wu1(id.iSec1 - 1), wv1(id.iSec2 - 1); int t1 = hdcons_.getTypeHex(id.iLay, wu1, wv1); @@ -476,6 +477,30 @@ bool HGCalTopology::valid(const DetId& idin) const { return flag; } +bool HGCalTopology::valid(const DetId& idin, int cornerMin) const { + if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { + HGCalTopology::DecodedDetId id = decode(idin); + bool mask = (cornerMin < HGCalTypes::WaferCornerMin) ? false : hdcons_.maskCell(idin, cornerMin); + bool flag = ((idin.det() == det_) && + hdcons_.isValidHex8( + id.iLay, id.iSec1, id.iSec2, id.iCell1, id.iCell2, (cornerMin >= HGCalTypes::WaferCornerMin))); + return (flag && (!mask)); + } else { + return valid(idin); + } +} + +bool HGCalTopology::validModule(const DetId& idin, int cornerMin) const { + if (idin.det() != det_) { + return false; + } else if ((idin.det() == DetId::HGCalEE) || (idin.det() == DetId::HGCalHSi)) { + HGCalTopology::DecodedDetId id = decode(idin); + return hdcons_.isValidHex8(id.iLay, id.iSec1, id.iSec2, (cornerMin >= HGCalTypes::WaferCornerMin)); + } else { + return valid(idin); + } +} + DetId HGCalTopology::offsetBy(const DetId startId, int nrStepsX, int nrStepsY) const { if (startId.det() == DetId::Forward && startId.subdetId() == (int)(subdet_)) { DetId id = changeXY(startId, nrStepsX, nrStepsY); diff --git a/Geometry/HGCalCommonData/data/hgcalCons/v10/hgcalCons.xml b/Geometry/HGCalCommonData/data/hgcalCons/v10/hgcalCons.xml index f90ea46f618b5..dd4d0a55023a4 100644 --- a/Geometry/HGCalCommonData/data/hgcalCons/v10/hgcalCons.xml +++ b/Geometry/HGCalCommonData/data/hgcalCons/v10/hgcalCons.xml @@ -1,5 +1,5 @@ - + @@ -137,6 +137,7 @@ + diff --git a/Geometry/HGCalCommonData/data/hgcalCons/v11/hgcalCons.xml b/Geometry/HGCalCommonData/data/hgcalCons/v11/hgcalCons.xml index d0b101321d342..a35bcfb2a10b9 100644 --- a/Geometry/HGCalCommonData/data/hgcalCons/v11/hgcalCons.xml +++ b/Geometry/HGCalCommonData/data/hgcalCons/v11/hgcalCons.xml @@ -1,5 +1,5 @@ - + @@ -137,6 +137,7 @@ + diff --git a/Geometry/HGCalCommonData/data/hgcalCons/v11m/hgcalCons.xml b/Geometry/HGCalCommonData/data/hgcalCons/v11m/hgcalCons.xml index b11e8c2fcaa52..9024454b5ff6c 100644 --- a/Geometry/HGCalCommonData/data/hgcalCons/v11m/hgcalCons.xml +++ b/Geometry/HGCalCommonData/data/hgcalCons/v11m/hgcalCons.xml @@ -1,5 +1,5 @@ - + @@ -86,7 +86,7 @@ - + @@ -137,6 +137,7 @@ + diff --git a/Geometry/HGCalCommonData/data/hgcalCons/v12/hgcalCons.xml b/Geometry/HGCalCommonData/data/hgcalCons/v12/hgcalCons.xml index b11e8c2fcaa52..9024454b5ff6c 100644 --- a/Geometry/HGCalCommonData/data/hgcalCons/v12/hgcalCons.xml +++ b/Geometry/HGCalCommonData/data/hgcalCons/v12/hgcalCons.xml @@ -1,5 +1,5 @@ - + @@ -86,7 +86,7 @@ - + @@ -137,6 +137,7 @@ + diff --git a/Geometry/HGCalCommonData/data/hgcalCons/v9/hgcalCons.xml b/Geometry/HGCalCommonData/data/hgcalCons/v9/hgcalCons.xml index 9afe60a7bf08c..9e027afcee3ca 100644 --- a/Geometry/HGCalCommonData/data/hgcalCons/v9/hgcalCons.xml +++ b/Geometry/HGCalCommonData/data/hgcalCons/v9/hgcalCons.xml @@ -1,5 +1,5 @@ - + @@ -125,6 +125,7 @@ + diff --git a/Geometry/HGCalCommonData/interface/HGCalDDDConstants.h b/Geometry/HGCalCommonData/interface/HGCalDDDConstants.h index 27625b0870ba0..a3dc4f0552dba 100644 --- a/Geometry/HGCalCommonData/interface/HGCalDDDConstants.h +++ b/Geometry/HGCalCommonData/interface/HGCalDDDConstants.h @@ -14,9 +14,11 @@ #include #include #include "DataFormats/DetId/interface/DetId.h" -#include "DetectorDescription/Core/interface/DDsvalues.h" +#include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h" #include "Geometry/HGCalCommonData/interface/HGCalGeometryMode.h" +#include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" #include "Geometry/HGCalCommonData/interface/HGCalParameters.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" #include @@ -25,23 +27,6 @@ class HGCalDDDConstants { HGCalDDDConstants(const HGCalParameters* hp, const std::string& name); ~HGCalDDDConstants(); - enum class CellType { - UndefinedType = -1, - CentralType = 0, - BottomLeftEdge = 1, - LeftEdge = 2, - TopLeftEdge = 3, - TopRightEdge = 4, - RightEdge = 5, - BottomRightEdge = 6, - BottomCorner = 11, - BottomLeftCorner = 12, - TopLeftCorner = 13, - TopCorner = 14, - TopRightCorner = 15, - BottomRightCorner = 16 - }; - std::pair assignCell(float x, float y, int lay, int subSec, bool reco) const; std::array assignCellHex(float x, float y, int lay, bool reco) const; std::array assignCellTrap(float x, float y, float z, int lay, bool reco) const; @@ -52,7 +37,7 @@ class HGCalDDDConstants { return std::make_pair(hgpar_->radiusLayer_[type][irad - 1], hgpar_->radiusLayer_[type][irad]); } double cellThickness(int layer, int waferU, int waferV) const; - CellType cellType(int type, int waferU, int waferV) const; + HGCalTypes::CellType cellType(int type, int waferU, int waferV) const; double distFromEdgeHex(double x, double y, double z) const; double distFromEdgeTrap(double x, double y, double z) const; void etaPhiFromPosition(const double x, @@ -66,6 +51,7 @@ class HGCalDDDConstants { int firstLayer() const { return hgpar_->firstLayer_; } HGCalGeometryMode::GeometryMode geomMode() const { return mode_; } int getLayer(double z, bool reco) const; + int getLayerOffset() const { return hgpar_->layerOffset_; } HGCalParameters::hgtrap getModule(unsigned int k, bool hexType, bool reco) const; std::vector getModules() const; const HGCalParameters* getParameter() const { return hgpar_; } @@ -83,7 +69,8 @@ class HGCalDDDConstants { int getUVMax(int type) const { return ((type == 0) ? hgpar_->nCellsFine_ : hgpar_->nCellsCoarse_); } bool isHalfCell(int waferType, int cell) const; bool isValidHex(int lay, int mod, int cell, bool reco) const; - bool isValidHex8(int lay, int modU, int modV, int cellU, int cellV) const; + bool isValidHex8(int lay, int waferU, int waferV, bool fullAndPart = false) const; + bool isValidHex8(int lay, int modU, int modV, int cellU, int cellV, bool fullAndPart = false) const; bool isValidTrap(int lay, int ieta, int iphi) const; int lastLayer(bool reco) const; int layerIndex(int lay, bool reco) const; @@ -92,6 +79,7 @@ class HGCalDDDConstants { std::pair locateCell(int cell, int lay, int type, bool reco) const; std::pair locateCell( int lay, int waferU, int waferV, int cellU, int cellV, bool reco, bool all, bool debug = false) const; + std::pair locateCell(const HGCSiliconDetId&, bool debug = false) const; std::pair locateCellHex(int cell, int wafer, bool reco) const; std::pair locateCellTrap(int lay, int ieta, int iphi, bool reco) const; int levelTop(int ind = 0) const { return hgpar_->levelT_[ind]; } @@ -114,6 +102,7 @@ class HGCalDDDConstants { int numberCellsHexagon(int wafer) const; int numberCellsHexagon(int lay, int waferU, int waferV, bool flag) const; std::pair rangeR(double z, bool reco) const; + std::pair rangeRLayer(int lay, bool reco) const; std::pair rangeZ(bool reco) const; std::pair rowColumnWafer(const int wafer) const; int sectors() const { return hgpar_->nSectors_; } @@ -136,8 +125,34 @@ class HGCalDDDConstants { int waferCount(const int type) const { return ((type == 0) ? waferMax_[2] : waferMax_[3]); } int waferMax() const { return waferMax_[1]; } int waferMin() const { return waferMax_[0]; } + std::pair waferParameters(bool reco) const; std::pair waferPosition(int wafer, bool reco) const; std::pair waferPosition(int lay, int waferU, int waferV, bool reco, bool debug = false) const; + unsigned int waferFileSize() const { return hgpar_->waferInfoMap_.size(); } + int waferFileIndex(unsigned int kk) const { + if (kk < hgpar_->waferInfoMap_.size()) { + auto itr = hgpar_->waferInfoMap_.begin(); + std::advance(itr, kk); + return itr->first; + } else + return 0; + } + std::tuple waferFileInfo(unsigned int kk) const { + if (kk < hgpar_->waferInfoMap_.size()) { + auto itr = hgpar_->waferInfoMap_.begin(); + std::advance(itr, kk); + return std::make_tuple(itr->second.type, itr->second.part, itr->second.orient); + } else + return std::make_tuple(0, 0, 0); + } + std::tuple waferFileInfoFromIndex(int kk) const { + auto itr = hgpar_->waferInfoMap_.find(kk); + if (itr != hgpar_->waferInfoMap_.end()) { + return std::make_tuple(itr->second.type, itr->second.part, itr->second.orient); + } else + return std::make_tuple(0, 0, 0); + } + bool waferFileInfoExist(int kk) const { return (hgpar_->waferInfoMap_.find(kk) != hgpar_->waferInfoMap_.end()); } double waferSepar(bool reco) const { return (reco ? hgpar_->sensorSeparation_ : HGCalParameters::k_ScaleToDDD * hgpar_->sensorSeparation_); } @@ -158,8 +173,11 @@ class HGCalDDDConstants { int waferTypeL(int wafer) const { return ((wafer >= 0) && (wafer < (int)(hgpar_->waferTypeL_.size()))) ? hgpar_->waferTypeL_[wafer] : 0; } - int waferType(DetId const& id) const; - int waferType(int layer, int waferU, int waferV) const; + int waferType(DetId const& id, bool fromFile = false) const; + int waferType(int layer, int waferU, int waferV, bool fromFile = false) const; + std::tuple waferType(HGCSiliconDetId const& id, bool fromFile = false) const; + std::pair waferTypeRotation( + int layer, int waferU, int waferV, bool fromFile = false, bool debug = false) const; int waferUVMax() const { return hgpar_->waferUVMax_; } bool waferVirtual(int layer, int waferU, int waferV) const; double waferZ(int layer, bool reco) const; @@ -177,6 +195,7 @@ class HGCalDDDConstants { bool waferInLayerTest(int wafer, int lay, bool full) const; std::pair waferPosition(int waferU, int waferV, bool reco) const; + HGCalGeomTools geomTools_; const double k_horizontalShift = 1.0; const float dPhiMin = 0.02; typedef std::array, 2> Simrecovecs; diff --git a/Geometry/HGCalCommonData/interface/HGCalGeomParameters.h b/Geometry/HGCalCommonData/interface/HGCalGeomParameters.h index 9ac190d8fda6b..1afb29bd09adc 100644 --- a/Geometry/HGCalCommonData/interface/HGCalGeomParameters.h +++ b/Geometry/HGCalCommonData/interface/HGCalGeomParameters.h @@ -106,8 +106,8 @@ class HGCalGeomParameters { const int& firstLayer, HGCalParameters& php); void loadSpecParsHexagon(const HGCalParameters& php); - void loadSpecParsHexagon8(const HGCalParameters& php); - void loadSpecParsTrapezoid(const HGCalParameters& php); + void loadSpecParsHexagon8(HGCalParameters& php); + void loadSpecParsTrapezoid(HGCalParameters& php); std::vector getDDDArray(const std::string& str, const DDsvalues_type& sv, const int nmin); std::pair cellPosition(const std::vector& wafers, std::vector::const_iterator& itrf, @@ -117,9 +117,18 @@ class HGCalGeomParameters { void rescale(std::vector&, const double s); void resetZero(std::vector&); + constexpr static double tan30deg_ = 0.5773502693; + constexpr static int siliconFileEE = 2; + constexpr static int siliconFileHE = 3; + constexpr static int scintillatorFile = 4; HGCalGeomTools geomTools_; const double sqrt3_; double waferSize_; + std::vector waferIndex_, waferTypes_, waferParts_, waferOrien_; + std::vector tileIndx_, tileType_, tileSiPM_; + std::vector tileHEX1_, tileHEX2_, tileHEX3_, tileHEX4_; + std::vector tileRMin_, tileRMax_; + std::vector tileRingMin_, tileRingMax_; }; #endif diff --git a/Geometry/HGCalCommonData/interface/HGCalGeomTools.h b/Geometry/HGCalCommonData/interface/HGCalGeomTools.h index d62e810641852..c42ffde8538c5 100644 --- a/Geometry/HGCalCommonData/interface/HGCalGeomTools.h +++ b/Geometry/HGCalCommonData/interface/HGCalGeomTools.h @@ -10,36 +10,6 @@ class HGCalGeomTools { HGCalGeomTools(); ~HGCalGeomTools() {} - enum WaferCorner { - WaferCorner0 = 0, - WaferCorner1 = 1, - WaferCorner2 = 2, - WaferCorner3 = 3, - WaferCorner4 = 4, - WaferCorner5 = 5 - }; - - enum WaferPosition { - UnknownPosition = -1, - WaferCenter = 0, - CornerCenterYp = 1, - CornerCenterYm = 2, - CornerCenterXp = 3, - CornerCenterXm = 4 - }; - - enum WaferType { - WaferFull = 0, - WaferFive = 1, - WaferChopTwo = 2, - WaferChopTwoM = 3, - WaferHalf = 4, - WaferSemi = 5, - WaferSemi2 = 6, - WaferThree = 7, - WaferOut = 99 - }; - static const int k_allCorners = 6; static const int k_fiveCorners = 5; static const int k_fourCorners = 4; @@ -63,7 +33,7 @@ class HGCalGeomTools { std::vector const& slope); static double radius( double z, int layer0, int layerf, std::vector const& zFront, std::vector const& rFront); - std::pair shiftXY(int waferPosition, double waferSize); + std::pair shiftXY(int waferPosition, double waferSize) const; static double slope(double z, std::vector const& zFront, std::vector const& slope); static std::pair zradius(double z1, double z2, diff --git a/Geometry/HGCalCommonData/interface/HGCalParameters.h b/Geometry/HGCalCommonData/interface/HGCalParameters.h index ab52aba3caec8..62de72f0b098d 100644 --- a/Geometry/HGCalCommonData/interface/HGCalParameters.h +++ b/Geometry/HGCalCommonData/interface/HGCalParameters.h @@ -12,9 +12,20 @@ class HGCalParameters { public: + struct waferInfo { + int32_t type, part, orient; + waferInfo(int32_t t = 0, int32_t p = 0, int32_t o = 0) : type(t), part(p), orient(o){}; + }; + struct tileInfo { + int32_t type, sipm, hex1, hex2, hex3, hex4; + tileInfo(int32_t t = 0, int32_t s = 0, int32_t h1 = 0, int32_t h2 = 0, int32_t h3 = 0, int32_t h4 = 0) + : type(t), sipm(s), hex1(h1), hex2(h2), hex3(h3), hex4(h4){}; + }; typedef std::vector > layer_map; typedef std::unordered_map wafer_map; typedef std::unordered_map > waferT_map; + typedef std::unordered_map waferInfo_map; + typedef std::unordered_map tileInfo_map; static constexpr double k_ScaleFromDDD = 0.1; static constexpr double k_ScaleToDDD = 10.0; @@ -160,6 +171,10 @@ class HGCalParameters { wafer_map typesInLayers_; waferT_map waferTypes_; int waferMaskMode_; + waferInfo_map waferInfoMap_; + tileInfo_map tileInfoMap_; + std::vector > tileRingR_; + std::vector > tileRingRange_; COND_SERIALIZABLE; diff --git a/Geometry/HGCalCommonData/interface/HGCalParametersFromDD.h b/Geometry/HGCalCommonData/interface/HGCalParametersFromDD.h index 4b192259879a6..600aabed3330d 100644 --- a/Geometry/HGCalCommonData/interface/HGCalParametersFromDD.h +++ b/Geometry/HGCalCommonData/interface/HGCalParametersFromDD.h @@ -32,6 +32,7 @@ class HGCalParametersFromDD { void getCellPosition(HGCalParameters& php, int type); double getDDDValue(const char* s, const DDsvalues_type& sv); std::vector getDDDArray(const char* s, const DDsvalues_type& sv); + constexpr static double tan30deg_ = 0.5773502693; }; #endif diff --git a/Geometry/HGCalCommonData/interface/HGCalTileIndex.h b/Geometry/HGCalCommonData/interface/HGCalTileIndex.h new file mode 100644 index 0000000000000..4201bd277590a --- /dev/null +++ b/Geometry/HGCalCommonData/interface/HGCalTileIndex.h @@ -0,0 +1,25 @@ +#ifndef Geometry_HGCalCommonData_HGCalTileIndex_h +#define Geometry_HGCalCommonData_HGCalTileIndex_h + +#include +#include + +class HGCalTileIndex { +public: + HGCalTileIndex() {} + ~HGCalTileIndex() {} + static int32_t tileIndex(int32_t layer, int32_t ring, int32_t phi); + static int32_t tileLayer(int32_t index); + static int32_t tileRing(int32_t index); + static int32_t tilePhi(int32_t index); + +private: + static constexpr int32_t kHGCalLayerOffset = 18; + static constexpr int32_t kHGCalLayerMask = 0x1F; + static constexpr int32_t kHGCalPhiOffset = 0; + static constexpr int32_t kHGCalPhiMask = 0x1FF; + static constexpr int32_t kHGCalRingOffset = 9; + static constexpr int32_t kHGCalRingMask = 0x1FF; +}; + +#endif diff --git a/Geometry/HGCalCommonData/interface/HGCalTypes.h b/Geometry/HGCalCommonData/interface/HGCalTypes.h new file mode 100644 index 0000000000000..4f235eb1fff5d --- /dev/null +++ b/Geometry/HGCalCommonData/interface/HGCalTypes.h @@ -0,0 +1,68 @@ +#ifndef Geometry_HGCalCommonData_HGCalTypes_h +#define Geometry_HGCalCommonData_HGCalTypes_h + +#include +#include +#include + +class HGCalTypes { +public: + HGCalTypes() {} + + enum class CellType { + UndefinedType = -1, + CentralType = 0, + BottomLeftEdge = 1, + LeftEdge = 2, + TopLeftEdge = 3, + TopRightEdge = 4, + RightEdge = 5, + BottomRightEdge = 6, + BottomCorner = 11, + BottomLeftCorner = 12, + TopLeftCorner = 13, + TopCorner = 14, + TopRightCorner = 15, + BottomRightCorner = 16 + }; + + enum WaferCorner { + WaferCorner0 = 0, + WaferCorner1 = 1, + WaferCorner2 = 2, + WaferCorner3 = 3, + WaferCorner4 = 4, + WaferCorner5 = 5 + }; + + enum WaferPosition { + UnknownPosition = -1, + WaferCenter = 0, + CornerCenterYp = 1, + CornerCenterYm = 2, + CornerCenterXp = 3, + CornerCenterXm = 4 + }; + + enum WaferType { WaferFineThin = 0, WaferCoarseThin = 1, WaferCoarseThick = 2, WaferFineThick = 3 }; + + enum WaferSizeType { + WaferFull = 0, + WaferFive = 1, + WaferChopTwo = 2, + WaferChopTwoM = 3, + WaferHalf = 4, + WaferSemi = 5, + WaferSemi2 = 6, + WaferThree = 7, + WaferOut = 99 + }; + + static constexpr int32_t WaferCornerMin = 3; + + enum TileType { TileFine = 0, TileCoarseCast = 1, TileCoarseMould = 2 }; + + enum TileSiPMType { SiPMUnknown = 0, SiPMSmall = 2, SiPMLarge = 4 }; +}; + +#endif diff --git a/Geometry/HGCalCommonData/interface/HGCalWaferMask.h b/Geometry/HGCalCommonData/interface/HGCalWaferMask.h index c5628d13cba60..8b4ac51473ff6 100644 --- a/Geometry/HGCalCommonData/interface/HGCalWaferMask.h +++ b/Geometry/HGCalCommonData/interface/HGCalWaferMask.h @@ -25,8 +25,9 @@ class HGCalWaferMask { const double& delY, const double& rin, const double& rout, - const int& nw, - const int& mode); + const int& waferType, + const int& mode, + bool deug = false); static const int k_OffsetRotation = 10; }; diff --git a/Geometry/HGCalCommonData/plugins/HGCalNumberingInitialization.cc b/Geometry/HGCalCommonData/plugins/HGCalNumberingInitialization.cc index 5649917d528e9..eba8976d41969 100644 --- a/Geometry/HGCalCommonData/plugins/HGCalNumberingInitialization.cc +++ b/Geometry/HGCalCommonData/plugins/HGCalNumberingInitialization.cc @@ -55,7 +55,7 @@ HGCalNumberingInitialization::~HGCalNumberingInitialization() {} // ------------ method called to produce the data ------------ HGCalNumberingInitialization::ReturnType HGCalNumberingInitialization::produce(const IdealGeometryRecord& iRecord) { - edm::LogVerbatim("HGCalGeom") << "in HGCalNumberingInitialization::produce"; + edm::LogVerbatim("HGCalGeom") << "in HGCalNumberingInitialization::produce for " << name_; const auto& pHGpar = iRecord.get(hgParToken_); return std::make_unique(&pHGpar, name_); } diff --git a/Geometry/HGCalCommonData/python/testHGCalV11XML_cfi.py b/Geometry/HGCalCommonData/python/testHGCalV11XML_cfi.py index 89c554d0f0336..8d966ef5f005e 100644 --- a/Geometry/HGCalCommonData/python/testHGCalV11XML_cfi.py +++ b/Geometry/HGCalCommonData/python/testHGCalV11XML_cfi.py @@ -31,7 +31,6 @@ 'Geometry/HcalCommonData/data/hcal/v2/hcalalgo.xml', 'Geometry/HcalCommonData/data/hcalbarrelalgo.xml', 'Geometry/HcalCommonData/data/hcalcablealgo/v2/hcalcablealgo.xml', - 'Geometry/HcalCommonData/data/hcalcablealgo/v2/hcalcablealgo.xml', 'Geometry/HcalCommonData/data/hcalouteralgo.xml', 'Geometry/HcalCommonData/data/hcalforwardalgo.xml', 'Geometry/HcalCommonData/data/hcalSimNumbering/NoHE/hcalSimNumbering.xml', diff --git a/Geometry/HGCalCommonData/python/testHGCalV12XML_cfi.py b/Geometry/HGCalCommonData/python/testHGCalV12XML_cfi.py index 93dda7c054b6b..e2569dacae092 100644 --- a/Geometry/HGCalCommonData/python/testHGCalV12XML_cfi.py +++ b/Geometry/HGCalCommonData/python/testHGCalV12XML_cfi.py @@ -31,7 +31,6 @@ 'Geometry/HcalCommonData/data/hcal/v2/hcalalgo.xml', 'Geometry/HcalCommonData/data/hcalbarrelalgo.xml', 'Geometry/HcalCommonData/data/hcalcablealgo/v2/hcalcablealgo.xml', - 'Geometry/HcalCommonData/data/hcalcablealgo/v2/hcalcablealgo.xml', 'Geometry/HcalCommonData/data/hcalouteralgo.xml', 'Geometry/HcalCommonData/data/hcalforwardalgo.xml', 'Geometry/HcalCommonData/data/hcalSimNumbering/NoHE/hcalSimNumbering.xml', diff --git a/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc b/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc index cf901199489ea..4885c699d55ff 100644 --- a/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc +++ b/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc @@ -23,6 +23,9 @@ using namespace geant_units::operators; HGCalDDDConstants::HGCalDDDConstants(const HGCalParameters* hp, const std::string& name) : hgpar_(hp), sqrt3_(std::sqrt(3.0)) { mode_ = hgpar_->mode_; +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "Mode " << mode_; +#endif if ((mode_ == HGCalGeometryMode::Hexagon) || (mode_ == HGCalGeometryMode::HexagonFull) || (mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { rmax_ = (HGCalParameters::k_ScaleFromDDD * (hgpar_->waferR_) * std::cos(30._deg)); @@ -46,10 +49,16 @@ HGCalDDDConstants::HGCalDDDConstants(const HGCalParameters* hp, const std::strin maxWafersPerLayer_ = std::max(maxWafersPerLayer_, max_modules_layer_[simreco][layer]); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Layer " << layer << " with " << max_modules_layer_[simreco][layer] << ":" - << modHalf_ << " modules"; + << modHalf_ << " modules in RECO"; + } else { + edm::LogVerbatim("HGCalGeom") << "Layer " << layer << " with " << max_modules_layer_[simreco][layer] + << " modules in SIM"; #endif } } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "SimReco " << simreco << " with " << tot_layers_[simreco] << " Layers"; +#endif } tot_wafers_ = wafers(); @@ -212,7 +221,7 @@ bool HGCalDDDConstants::cellInLayer(int waferU, int waferV, int cellU, int cellV double HGCalDDDConstants::cellThickness(int layer, int waferU, int waferV) const { double thick(-1); - int type = waferType(layer, waferU, waferV); + int type = waferType(layer, waferU, waferV, false); if (type >= 0) { if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { thick = 10000.0 * hgpar_->cellThickness_[type]; // cm to micron @@ -233,43 +242,43 @@ double HGCalDDDConstants::cellSizeHex(int type) const { return cell; } -HGCalDDDConstants::CellType HGCalDDDConstants::cellType(int type, int cellU, int cellV) const { +HGCalTypes::CellType HGCalDDDConstants::cellType(int type, int cellU, int cellV) const { // type=0: in the middle; 1..6: the edges clocwise from bottom left; // =11..16: the corners clockwise from bottom int N = (type == 0) ? hgpar_->nCellsFine_ : hgpar_->nCellsCoarse_; if (cellU == 0) { if (cellV == 0) - return HGCalDDDConstants::CellType::BottomLeftCorner; + return HGCalTypes::CellType::BottomLeftCorner; else if (cellV - cellU == N - 1) - return HGCalDDDConstants::CellType::BottomCorner; + return HGCalTypes::CellType::BottomCorner; else - return HGCalDDDConstants::CellType::BottomLeftEdge; + return HGCalTypes::CellType::BottomLeftEdge; } else if (cellV == 0) { if (cellU - cellV == N) - return HGCalDDDConstants::CellType::TopLeftCorner; + return HGCalTypes::CellType::TopLeftCorner; else - return HGCalDDDConstants::CellType::LeftEdge; + return HGCalTypes::CellType::LeftEdge; } else if (cellU - cellV == N) { if (cellU == 2 * N - 1) - return HGCalDDDConstants::CellType::TopCorner; + return HGCalTypes::CellType::TopCorner; else - return HGCalDDDConstants::CellType::TopLeftEdge; + return HGCalTypes::CellType::TopLeftEdge; } else if (cellU == 2 * N - 1) { if (cellV == 2 * N - 1) - return HGCalDDDConstants::CellType::TopRightCorner; + return HGCalTypes::CellType::TopRightCorner; else - return HGCalDDDConstants::CellType::TopRightEdge; + return HGCalTypes::CellType::TopRightEdge; } else if (cellV == 2 * N - 1) { if (cellV - cellU == N - 1) - return HGCalDDDConstants::CellType::BottomRightCorner; + return HGCalTypes::CellType::BottomRightCorner; else - return HGCalDDDConstants::CellType::RightEdge; + return HGCalTypes::CellType::RightEdge; } else if (cellV - cellU == N - 1) { - return HGCalDDDConstants::CellType::BottomRightEdge; + return HGCalTypes::CellType::BottomRightEdge; } else if ((cellU > 2 * N - 1) || (cellV > 2 * N - 1) || (cellV >= (cellU + N)) || (cellU > (cellV + N))) { - return HGCalDDDConstants::CellType::UndefinedType; + return HGCalTypes::CellType::UndefinedType; } else { - return HGCalDDDConstants::CellType::CentralType; + return HGCalTypes::CellType::CentralType; } } @@ -482,7 +491,7 @@ bool HGCalDDDConstants::isValidHex(int lay, int mod, int cell, bool reco) const return result; } -bool HGCalDDDConstants::isValidHex8(int layer, int modU, int modV, int cellU, int cellV) const { +bool HGCalDDDConstants::isValidHex8(int layer, int modU, int modV, bool fullAndPart) const { // Check validity for a layer|wafer|cell of post-TDR version int indx = HGCalWaferIndex::waferIndex(layer, modU, modV); auto itr = hgpar_->typesInLayers_.find(indx); @@ -499,6 +508,28 @@ bool HGCalDDDConstants::isValidHex8(int layer, int modU, int modV, int cellU, in if (!(jtr->second)) return false; + if (fullAndPart) { + auto ktr = hgpar_->waferTypes_.find(indx); + if (ktr != hgpar_->waferTypes_.end()) { + if (hgpar_->waferMaskMode_ > 0) { + if (ktr->second.first == HGCalTypes::WaferOut) + return false; + } else { + if (ktr->second.first < HGCalTypes::WaferCornerMin) + return false; + } + } + } + return true; +} + +bool HGCalDDDConstants::isValidHex8(int layer, int modU, int modV, int cellU, int cellV, bool fullAndPart) const { + // First check validity for a layer|wafer| of post TDR version + if (!isValidHex8(layer, modU, modV, fullAndPart)) + return false; + int indx = HGCalWaferIndex::waferIndex(layer, modU, modV); + auto itr = hgpar_->typesInLayers_.find(indx); + int type = hgpar_->waferTypeL_[itr->second]; int N = ((hgpar_->waferTypeL_[itr->second] == 0) ? hgpar_->nCellsFine_ : hgpar_->nCellsCoarse_); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "HGCalDDDConstants::isValidHex8:Cell " << cellU << ":" << cellV << ":" << N @@ -510,12 +541,6 @@ bool HGCalDDDConstants::isValidHex8(int layer, int modU, int modV, int cellU, in if (((cellV - cellU) >= N) || ((cellU - cellV) > N)) return false; - auto ktr = hgpar_->waferTypes_.find(indx); - if (ktr != hgpar_->waferTypes_.end()) - return false; - - // edm::LogVerbatim("HGCalGeom") << "Corners " << (ktr->second).first << ":" << waferVirtual(layer,modU,modV); - int type = ((itr == hgpar_->typesInLayers_.end()) ? 2 : hgpar_->waferTypeL_[itr->second]); return isValidCell8(layer, modU, modV, cellU, cellV, type); } @@ -631,6 +656,34 @@ std::pair HGCalDDDConstants::locateCell( return std::make_pair(x, y); } +std::pair HGCalDDDConstants::locateCell(const HGCSiliconDetId& id, bool debug) const { + int lay(id.layer()); + double r = 0.5 * (hgpar_->waferSize_ + hgpar_->sensorSeparation_); + double R = 2.0 * r / sqrt3_; + int ncells = (id.type() == 0) ? hgpar_->nCellsFine_ : hgpar_->nCellsCoarse_; + int n2 = ncells / 2; + auto xyoff = geomTools_.shiftXY(hgpar_->layerCenter_[lay - 1], (2.0 * r)); + double xpos = xyoff.first + ((-2 * id.waferU() + id.waferV()) * r); + double ypos = xyoff.second + (1.5 * id.waferV() * R); +#ifdef EDM_ML_DEBUG + if (debug) + edm::LogVerbatim("HGCalGeom") << "LocateCell " << id << " Lay " << lay << " r:R " << r << ":" << R << " N " + << ncells << ":" << n2 << " Off " << xyoff.first << ":" << xyoff.second << " Pos " + << xpos << ":" << ypos; +#endif + double R1 = hgpar_->waferSize_ / (3.0 * ncells); + double r1 = 0.5 * R1 * sqrt3_; + xpos += ((1.5 * (id.cellV() - ncells) + 1.0) * R1); + ypos += ((id.cellU() - 0.5 * id.cellV() - n2) * 2 * r1); +#ifdef EDM_ML_DEBUG + if (debug) + edm::LogVerbatim("HGCalGeom") << "LocateCell r1:R1 " << r1 << ":" << R1 << " dx:dy " + << ((1.5 * (id.cellV() - ncells) + 1.0) * R1) << ":" + << ((id.cellU() - 0.5 * id.cellV() - n2) * 2 * r1) << " Pos " << xpos << ":" << ypos; +#endif + return std::make_pair(xpos * id.zside(), ypos); +} + std::pair HGCalDDDConstants::locateCellHex(int cell, int wafer, bool reco) const { float x(0), y(0); if (hgpar_->waferTypeT_[wafer] - 1 == HGCSiliconDetId::HGCalFine) { @@ -905,6 +958,24 @@ std::pair HGCalDDDConstants::rangeR(double z, bool reco) const { return std::make_pair(rmin, rmax); } +std::pair HGCalDDDConstants::rangeRLayer(int lay, bool reco) const { + double rmin(0), rmax(0); + const auto& index = getIndex(lay, reco); + if (index.first >= 0 && index.first < static_cast(hgpar_->rMinLayHex_.size())) { + rmin = hgpar_->rMinLayHex_[index.first]; + rmax = hgpar_->rMaxLayHex_[index.first]; + } + if (!reco) { + rmin *= HGCalParameters::k_ScaleToDDD; + rmax *= HGCalParameters::k_ScaleToDDD; + } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "HGCalDDDConstants:rangeR: " << lay << ":" << index.first << " R " << rmin << ":" + << rmax; +#endif + return std::make_pair(rmin, rmax); +} + std::pair HGCalDDDConstants::rangeZ(bool reco) const { double zmin = (hgpar_->zLayerHex_[0] - hgpar_->waferThick_); double zmax = (hgpar_->zLayerHex_[hgpar_->zLayerHex_.size() - 1] + hgpar_->waferThick_); @@ -1109,6 +1180,13 @@ bool HGCalDDDConstants::waferFullInLayer(int wafer, int lay, bool reco) const { return waferInLayerTest(wafer, indx.first, false); } +std::pair HGCalDDDConstants::waferParameters(bool reco) const { + if (reco) + return std::make_pair(rmax_, hexside_); + else + return std::make_pair(HGCalParameters::k_ScaleToDDD * rmax_, HGCalParameters::k_ScaleToDDD * hexside_); +} + std::pair HGCalDDDConstants::waferPosition(int wafer, bool reco) const { double xx(0), yy(0); if (wafer >= 0 && wafer < (int)(hgpar_->waferPosX_.size())) { @@ -1127,9 +1205,11 @@ std::pair HGCalDDDConstants::waferPosition( int ll = lay - hgpar_->firstLayer_; double x = hgpar_->xLayerHex_[ll]; double y = hgpar_->yLayerHex_[ll]; +#ifdef EDM_ML_DEBUG if (debug) edm::LogVerbatim("HGCalGeom") << "Layer " << lay << ":" << ll << " Shift " << hgpar_->xLayerHex_[ll] << ":" << hgpar_->yLayerHex_[ll]; +#endif if (!reco) { x *= HGCalParameters::k_ScaleToDDD; y *= HGCalParameters::k_ScaleToDDD; @@ -1138,27 +1218,53 @@ std::pair HGCalDDDConstants::waferPosition( const auto& xy = waferPosition(waferU, waferV, reco); x += xy.first; y += xy.second; +#ifdef EDM_ML_DEBUG if (debug) edm::LogVerbatim("HGCalGeom") << "With wafer " << x << ":" << y << ":" << xy.first << ":" << xy.second; +#endif return std::make_pair(x, y); } -int HGCalDDDConstants::waferType(DetId const& id) const { +int HGCalDDDConstants::waferType(DetId const& id, bool fromFile) const { int type(1); if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { - type = ((id.det() != DetId::Forward) ? HGCSiliconDetId(id).type() : HFNoseDetId(id).type()); + if (fromFile && (waferFileSize() > 0)) { + int layer(0), waferU(0), waferV(0); + if (id.det() != DetId::Forward) { + HGCSiliconDetId hid(id); + layer = hid.layer(); + waferU = hid.waferU(); + waferV = hid.waferV(); + } else { + HFNoseDetId hid(id); + layer = hid.layer(); + waferU = hid.waferU(); + waferV = hid.waferV(); + } + auto itr = hgpar_->waferInfoMap_.find(HGCalWaferIndex::waferIndex(layer, waferU, waferV)); + if (itr != hgpar_->waferInfoMap_.end()) + type = (itr->second).type; + } else { + type = ((id.det() != DetId::Forward) ? HGCSiliconDetId(id).type() : HFNoseDetId(id).type()); + } } else if ((mode_ == HGCalGeometryMode::Hexagon) || (mode_ == HGCalGeometryMode::HexagonFull)) { type = waferTypeL(HGCalDetId(id).wafer()) - 1; } return type; } -int HGCalDDDConstants::waferType(int layer, int waferU, int waferV) const { +int HGCalDDDConstants::waferType(int layer, int waferU, int waferV, bool fromFile) const { int type(HGCSiliconDetId::HGCalCoarseThick); if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { - auto itr = hgpar_->typesInLayers_.find(HGCalWaferIndex::waferIndex(layer, waferU, waferV)); - if (itr != hgpar_->typesInLayers_.end()) - type = hgpar_->waferTypeL_[itr->second]; + if (fromFile && (waferFileSize() > 0)) { + auto itr = hgpar_->waferInfoMap_.find(HGCalWaferIndex::waferIndex(layer, waferU, waferV)); + if (itr != hgpar_->waferInfoMap_.end()) + type = (itr->second).type; + } else { + auto itr = hgpar_->typesInLayers_.find(HGCalWaferIndex::waferIndex(layer, waferU, waferV)); + if (itr != hgpar_->typesInLayers_.end()) + type = hgpar_->waferTypeL_[itr->second]; + } } else if ((mode_ == HGCalGeometryMode::Hexagon) || (mode_ == HGCalGeometryMode::HexagonFull)) { if ((waferU >= 0) && (waferU < (int)(hgpar_->waferTypeL_.size()))) type = (hgpar_->waferTypeL_[waferU] - 1); @@ -1166,6 +1272,86 @@ int HGCalDDDConstants::waferType(int layer, int waferU, int waferV) const { return type; } +std::tuple HGCalDDDConstants::waferType(HGCSiliconDetId const& id, bool fromFile) const { + const auto& index = HGCalWaferIndex::waferIndex(id.layer(), id.waferU(), id.waferV()); + int type(-1), part(-1), orient(-1); + if (fromFile && (waferFileSize() > 0)) { + auto itr = hgpar_->waferInfoMap_.find(index); + if (itr != hgpar_->waferInfoMap_.end()) { + type = (itr->second).type; + part = (itr->second).part; + orient = (itr->second).orient; + } + } else { + auto ktr = hgpar_->typesInLayers_.find(index); + if (ktr != hgpar_->typesInLayers_.end()) + type = hgpar_->waferTypeL_[ktr->second]; + auto itr = hgpar_->waferTypes_.find(index); + if (itr != hgpar_->waferTypes_.end()) { + if ((itr->second).second < HGCalWaferMask::k_OffsetRotation) { + orient = (itr->second).second; + if ((itr->second).first == HGCalGeomTools::k_allCorners) { + part = HGCalTypes::WaferFull; + } else if ((itr->second).first == HGCalGeomTools::k_fiveCorners) { + part = HGCalTypes::WaferFive; + } else if ((itr->second).first == HGCalGeomTools::k_fourCorners) { + part = HGCalTypes::WaferHalf; + } else if ((itr->second).first == HGCalGeomTools::k_threeCorners) { + part = HGCalTypes::WaferThree; + } + } else { + part = (itr->second).first; + orient = ((itr->second).second - HGCalWaferMask::k_OffsetRotation); + } + } else { + part = HGCalTypes::WaferFull; + orient = 0; + } + } + return std::make_tuple(type, part, orient); +} + +std::pair HGCalDDDConstants::waferTypeRotation( + int layer, int waferU, int waferV, bool fromFile, bool debug) const { + int type(HGCalTypes::WaferOut), rotn(0); + int wl = HGCalWaferIndex::waferIndex(layer, waferU, waferV); + if (fromFile && (waferFileSize() > 0)) { + auto itr = hgpar_->waferInfoMap_.find(wl); + if (itr != hgpar_->waferInfoMap_.end()) { + type = (itr->second).part; + rotn = (itr->second).orient; + } + } else { + auto itr = hgpar_->waferTypes_.find(wl); + if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { + if (itr != hgpar_->waferTypes_.end()) { + if ((itr->second).second < HGCalWaferMask::k_OffsetRotation) { + rotn = (itr->second).second; + if ((itr->second).first == HGCalGeomTools::k_allCorners) { + type = HGCalTypes::WaferFull; + } else if ((itr->second).first == HGCalGeomTools::k_fiveCorners) { + type = HGCalTypes::WaferFive; + } else if ((itr->second).first == HGCalGeomTools::k_fourCorners) { + type = HGCalTypes::WaferHalf; + } else if ((itr->second).first == HGCalGeomTools::k_threeCorners) { + type = HGCalTypes::WaferThree; + } + } else { + type = (itr->second).first; + rotn = ((itr->second).second - HGCalWaferMask::k_OffsetRotation); + } + } + } + } +#ifdef EDM_ML_DEBUG + if (debug) + edm::LogVerbatim("HGCalGeom") << "waferTypeRotation: Layer " << layer << " Wafer " << waferU << ":" << waferV + << " Index " << std::hex << wl << std::dec << ":" + << (itr != hgpar_->waferTypes_.end()) << " Type " << type << " Rotation " << rotn; +#endif + return std::make_pair(type, rotn); +} + bool HGCalDDDConstants::waferVirtual(int layer, int waferU, int waferV) const { bool type(false); if ((mode_ == HGCalGeometryMode::Hexagon8) || (mode_ == HGCalGeometryMode::Hexagon8Full)) { @@ -1245,9 +1431,11 @@ void HGCalDDDConstants::cellHex(double xloc, double yloc, int cellType, int& cel cv0 = std::max(0, std::min(cv0, 2 * N - 1)); if (cv0 - cu0 >= N) cv0 = cu0 + N - 1; +#ifdef EDM_ML_DEBUG if (debug) edm::LogVerbatim("HGCalGeom") << "cellHex: input " << xloc << ":" << yloc << ":" << cellType << " parameter " << rc << ":" << Rc << " u0 " << u0 << ":" << cu0 << " v0 " << v0 << ":" << cv0; +#endif bool found(false); static const int shift[3] = {0, 1, -1}; for (int i1 = 0; i1 < 3; ++i1) { @@ -1260,11 +1448,13 @@ void HGCalDDDConstants::cellHex(double xloc, double yloc, int cellType, int& cel double yc = (2 * cellU - cellV - N) * rc; if ((std::abs(yloc - yc) <= rc) && (std::abs(xloc - xc) <= Rc) && ((std::abs(xloc - xc) <= 0.5 * Rc) || (std::abs(yloc - yc) <= sqrt3_ * (Rc - std::abs(xloc - xc))))) { +#ifdef EDM_ML_DEBUG if (debug) edm::LogVerbatim("HGCalGeom") << "cellHex: local " << xc << ":" << yc << " difference " << std::abs(xloc - xc) << ":" << std::abs(yloc - yc) << ":" << sqrt3_ * (Rc - std::abs(yloc - yc)) << " comparator " << rc << ":" << Rc << " (u,v) = (" << cellU << "," << cellV << ")"; +#endif found = true; break; } diff --git a/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc b/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc index f4831237b007d..793f4271707ca 100644 --- a/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc +++ b/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc @@ -170,7 +170,7 @@ void HGCalGeomParameters::loadGeometryHexagon(const DDFilteredView& _fv, zv = polygon.zVec(); rv = polygon.xVec(); } - php.waferR_ = HGCalParameters::k_ScaleFromDDDToG4 * rv[0] / std::cos(30._deg); + php.waferR_ = 2.0 * HGCalParameters::k_ScaleFromDDDToG4 * rv[0] * tan30deg_; php.waferSize_ = HGCalParameters::k_ScaleFromDDD * rv[0]; double dz = 0.5 * HGCalParameters::k_ScaleFromDDDToG4 * (zv[1] - zv[0]); #ifdef EDM_ML_DEBUG @@ -394,7 +394,7 @@ void HGCalGeomParameters::loadGeometryHexagon(const cms::DDCompactView* cpv, zv[1] = pars[9]; rv = pars[4]; } - php.waferR_ = HGCalParameters::k_ScaleFromDD4HepToG4 * rv / std::cos(30._deg); + php.waferR_ = 2.0 * HGCalParameters::k_ScaleFromDD4HepToG4 * rv * tan30deg_; php.waferSize_ = HGCalParameters::k_ScaleFromDD4Hep * rv; double dz = 0.5 * HGCalParameters::k_ScaleFromDD4HepToG4 * (zv[1] - zv[0]); #ifdef EDM_ML_DEBUG @@ -1008,6 +1008,19 @@ void HGCalGeomParameters::loadSpecParsHexagon8(const DDFilteredView& fv, HGCalPa php.layerOffset_ = dummy2[0]; php.layerCenter_ = dbl_to_int(DDVectorGetter::get("LayerCenter")); + // Read in parameters from Philip's file + if (php.waferMaskMode_ == siliconFileEE) { + waferIndex_ = dbl_to_int(DDVectorGetter::get("WaferIndexEE")); + waferTypes_ = dbl_to_int(DDVectorGetter::get("WaferTypesEE")); + waferParts_ = dbl_to_int(DDVectorGetter::get("WaferPartialEE")); + waferOrien_ = dbl_to_int(DDVectorGetter::get("WaferOrientEE")); + } else if (php.waferMaskMode_ == siliconFileHE) { + waferIndex_ = dbl_to_int(DDVectorGetter::get("WaferIndexHE")); + waferTypes_ = dbl_to_int(DDVectorGetter::get("WaferTypesHE")); + waferParts_ = dbl_to_int(DDVectorGetter::get("WaferPartialHE")); + waferOrien_ = dbl_to_int(DDVectorGetter::get("WaferOrientHE")); + } + loadSpecParsHexagon8(php); } @@ -1066,10 +1079,45 @@ void HGCalGeomParameters::loadSpecParsHexagon8(const cms::DDFilteredView& fv, } } + // Read in parameters from Philip's file + if (php.waferMaskMode_ == siliconFileEE) { + for (auto const& it : vmap) { + if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferIndexEE")) { + for (const auto& i : it.second) + waferIndex_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferTypesEE")) { + for (const auto& i : it.second) + waferTypes_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferPartialEE")) { + for (const auto& i : it.second) + waferParts_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferOrientEE")) { + for (const auto& i : it.second) + waferOrien_.emplace_back(std::round(i)); + } + } + } else if (php.waferMaskMode_ == siliconFileHE) { + for (auto const& it : vmap) { + if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferIndexHE")) { + for (const auto& i : it.second) + waferIndex_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferTypesHE")) { + for (const auto& i : it.second) + waferTypes_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferPartialHE")) { + for (const auto& i : it.second) + waferParts_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "WaferOrientHE")) { + for (const auto& i : it.second) + waferOrien_.emplace_back(std::round(i)); + } + } + } + loadSpecParsHexagon8(php); } -void HGCalGeomParameters::loadSpecParsHexagon8(const HGCalParameters& php) { +void HGCalGeomParameters::loadSpecParsHexagon8(HGCalParameters& php) { #ifdef EDM_ML_DEBUG for (unsigned int k = 0; k < php.cellThickness_.size(); ++k) edm::LogVerbatim("HGCalGeom") << "HGCalGeomParameters: cell[" << k << "] Thickness " << php.cellThickness_[k]; @@ -1101,6 +1149,22 @@ void HGCalGeomParameters::loadSpecParsHexagon8(const HGCalParameters& php) { for (unsigned int k = 0; k < php.layerCenter_.size(); ++k) edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << php.layerCenter_[k]; #endif + + // Store parameters from Philip's file + if (php.waferMaskMode_ > 1) { + for (unsigned int k = 0; k < waferIndex_.size(); ++k) { + php.waferInfoMap_[waferIndex_[k]] = HGCalParameters::waferInfo(waferTypes_[k], waferParts_[k], waferOrien_[k]); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "[" << k << ":" << waferIndex_[k] << "] " + << " Type " << waferTypes_[k] << " Partial type " << waferParts_[k] + << " Orientation " << waferOrien_[k]; +#endif + } + waferIndex_.clear(); + waferTypes_.clear(); + waferParts_.clear(); + waferOrien_.clear(); + } } void HGCalGeomParameters::loadSpecParsTrapezoid(const DDFilteredView& fv, HGCalParameters& php) { @@ -1137,6 +1201,23 @@ void HGCalGeomParameters::loadSpecParsTrapezoid(const DDFilteredView& fv, HGCalP php.layerOffset_ = dummy2[0]; php.layerCenter_ = dbl_to_int(DDVectorGetter::get("LayerCenter")); + // tile parameters from Katja's file + if (php.waferMaskMode_ == scintillatorFile) { + tileIndx_ = dbl_to_int(DDVectorGetter::get("TileIndex")); + tileType_ = dbl_to_int(DDVectorGetter::get("TileType")); + tileSiPM_ = dbl_to_int(DDVectorGetter::get("TileSiPM")); + tileHEX1_ = dbl_to_int(DDVectorGetter::get("TileHEX1")); + tileHEX2_ = dbl_to_int(DDVectorGetter::get("TileHEX2")); + tileHEX3_ = dbl_to_int(DDVectorGetter::get("TileHEX3")); + tileHEX4_ = dbl_to_int(DDVectorGetter::get("TileHEX4")); + tileRMin_ = DDVectorGetter::get("TileRMin"); + tileRMax_ = DDVectorGetter::get("TileRMax"); + rescale(tileRMin_, HGCalParameters::k_ScaleFromDDD); + rescale(tileRMax_, HGCalParameters::k_ScaleFromDDD); + tileRingMin_ = dbl_to_int(DDVectorGetter::get("TileRingMin")); + tileRingMax_ = dbl_to_int(DDVectorGetter::get("TileRingMax")); + } + loadSpecParsTrapezoid(php); } @@ -1184,10 +1265,50 @@ void HGCalGeomParameters::loadSpecParsTrapezoid(const cms::DDFilteredView& fv, const auto& dummy2 = fv.get >(sdTag1, "LayerOffset"); php.layerOffset_ = dummy2[0]; + // tile parameters from Katja's file + if (php.waferMaskMode_ == scintillatorFile) { + for (auto const& it : vmap) { + if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileIndex")) { + for (const auto& i : it.second) + tileIndx_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileType")) { + for (const auto& i : it.second) + tileType_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileSiPM")) { + for (const auto& i : it.second) + tileSiPM_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileHEX1")) { + for (const auto& i : it.second) + tileHEX1_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileHEX2")) { + for (const auto& i : it.second) + tileHEX2_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileHEX3")) { + for (const auto& i : it.second) + tileHEX3_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileHEX4")) { + for (const auto& i : it.second) + tileHEX4_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileRMin")) { + for (const auto& i : it.second) + tileRMin_.emplace_back(HGCalParameters::k_ScaleFromDD4Hep * i); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileRMax")) { + for (const auto& i : it.second) + tileRMax_.emplace_back(HGCalParameters::k_ScaleFromDD4Hep * i); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileRingMin")) { + for (const auto& i : it.second) + tileRingMin_.emplace_back(std::round(i)); + } else if (cms::dd::compareEqual(cms::dd::noNamespace(it.first), "TileRingMax")) { + for (const auto& i : it.second) + tileRingMax_.emplace_back(std::round(i)); + } + } + } + loadSpecParsTrapezoid(php); } -void HGCalGeomParameters::loadSpecParsTrapezoid(const HGCalParameters& php) { +void HGCalGeomParameters::loadSpecParsTrapezoid(HGCalParameters& php) { #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "HGCalGeomParameters:nCells " << php.nCellsFine_ << ":" << php.nCellsCoarse_ << " cellSize: " << php.cellSize_[0] << ":" << php.cellSize_[1]; @@ -1216,6 +1337,42 @@ void HGCalGeomParameters::loadSpecParsTrapezoid(const HGCalParameters& php) { for (unsigned int k = 0; k < php.layerCenter_.size(); ++k) edm::LogVerbatim("HGCalGeom") << "[" << k << "] " << php.layerCenter_[k]; #endif + + // tile parameters from Katja's file + if (php.waferMaskMode_ == scintillatorFile) { + for (unsigned int k = 0; k < tileIndx_.size(); ++k) { + php.tileInfoMap_[tileIndx_[k]] = + HGCalParameters::tileInfo(tileType_[k], tileSiPM_[k], tileHEX1_[k], tileHEX2_[k], tileHEX3_[k], tileHEX4_[k]); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "Tile[" << k << ":" << tileIndx_[k] << "] " + << " Type " << tileType_[k] << " SiPM " << tileSiPM_[k] << " HEX " << tileHEX1_[k] + << ":" << tileHEX2_[k] << ":" << tileHEX3_[k] << ":" << tileHEX4_[k]; +#endif + } + tileIndx_.clear(); + tileType_.clear(); + tileSiPM_.clear(); + tileHEX1_.clear(); + tileHEX2_.clear(); + tileHEX3_.clear(); + tileHEX4_.clear(); + for (unsigned int k = 0; k < tileRMin_.size(); ++k) { + php.tileRingR_.emplace_back(tileRMin_[k], tileRMax_[k]); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "TileRingR[" << k << "] " << tileRMin_[k] << ":" << tileRMax_[k]; + #endif + } + tileRMin_.clear(); + tileRMax_.clear(); + for (unsigned k = 0; k < tileRingMin_.size(); ++k) { + php.tileRingRange_.emplace_back(tileRingMin_[k], tileRingMax_[k]); +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "TileRingRange[" << k << "] " << tileRingMin_[k] << ":" << tileRingMax_[k]; +#endif + } + tileRingMin_.clear(); + tileRingMax_.clear(); + } } void HGCalGeomParameters::loadWaferHexagon(HGCalParameters& php) { @@ -1343,11 +1500,14 @@ void HGCalGeomParameters::loadWaferHexagon8(HGCalParameters& php) { double r = 0.5 * (waferW + waferS); double R = 2.0 * r / sqrt3_; double dy = 0.75 * R; + double r1 = 0.5 * waferW; + double R1 = 2.0 * r1 / sqrt3_; int N = (r == 0) ? 3 : ((int)(0.5 * rout / r) + 3); int ns1 = (2 * N + 1) * (2 * N + 1); int ns2 = ns1 * php.zLayerHex_.size(); #ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeom") << "r " << r << " dy " << dy << " N " << N << " sizes " << ns1 << ":" << ns2; + edm::LogVerbatim("HGCalGeom") << "wafer " << waferW << ":" << waferS << " r " << r << " dy " << dy << " N " << N + << " sizes " << ns1 << ":" << ns2; std::vector indtypes(ns1 + 1); indtypes.clear(); #endif @@ -1368,7 +1528,7 @@ void HGCalGeomParameters::loadWaferHexagon8(HGCalParameters& php) { php.waferPosY_.emplace_back(ypos); wafersInLayers[indx] = ipos; ++ipos; - std::pair corner = HGCalGeomTools::waferCorner(xpos, ypos, r, R, 0, rout, false); + std::pair corner = HGCalGeomTools::waferCorner(xpos, ypos, r1, R1, 0, rout, false); if ((corner.first == (int)(HGCalParameters::k_CornerSize)) || ((corner.first > 0) && php.defineFull_)) { uvmax = std::max(uvmax, std::max(std::abs(u), std::abs(v))); } @@ -1376,9 +1536,11 @@ void HGCalGeomParameters::loadWaferHexagon8(HGCalParameters& php) { int copy = i + php.layerOffset_; std::pair xyoff = geomTools_.shiftXY(php.layerCenter_[copy], (waferW + waferS)); int lay = php.layer_[php.layerIndex_[i]]; + double xpos0 = xpos + xyoff.first; + double ypos0 = ypos + xyoff.second; double zpos = php.zLayerHex_[i]; - int type = wType->getType(HGCalParameters::k_ScaleToDDD * (xpos + xyoff.first), - HGCalParameters::k_ScaleToDDD * (ypos + xyoff.second), + int type = wType->getType(HGCalParameters::k_ScaleToDDD * xpos0, + HGCalParameters::k_ScaleToDDD * ypos0, HGCalParameters::k_ScaleToDDD * zpos); php.waferTypeL_.emplace_back(type); int kndx = HGCalWaferIndex::waferIndex(lay, u, v); @@ -1388,7 +1550,7 @@ void HGCalGeomParameters::loadWaferHexagon8(HGCalParameters& php) { indtypes.emplace_back(kndx); #endif std::pair corner = - HGCalGeomTools::waferCorner(xpos, ypos, r, R, php.rMinLayHex_[i], php.rMaxLayHex_[i], false); + HGCalGeomTools::waferCorner(xpos0, ypos0, r1, R1, php.rMinLayHex_[i], php.rMaxLayHex_[i], false); #ifdef EDM_ML_DEBUG if (((corner.first == 0) && std::abs(u) < 5 && std::abs(v) < 5) || (std::abs(u) < 2 && std::abs(v) < 2)) { edm::LogVerbatim("HGCalGeom") << "Layer " << lay << " R " << php.rMinLayHex_[i] << ":" << php.rMaxLayHex_[i] @@ -1406,12 +1568,14 @@ void HGCalGeomParameters::loadWaferHexagon8(HGCalParameters& php) { int wl = HGCalWaferIndex::waferIndex(lay, u, v); if (php.waferMaskMode_ > 0) { std::pair corner0 = HGCalWaferMask::getTypeMode( - xpos, ypos, r, R, php.rMinLayHex_[i], php.rMaxLayHex_[i], N, php.waferMaskMode_); + xpos0, ypos0, r1, R1, php.rMinLayHex_[i], php.rMaxLayHex_[i], type, php.waferMaskMode_); waferTypes[wl] = corner0; #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") - << "Layer " << lay << " u|v " << u << ":" << v << " with corner " << corner.first << ":" - << corner.second << " croner0 " << corner0.first << ":" << corner0.second; + << "Layer " << lay << " u|v " << u << ":" << v << " Index " << std::hex << wl << std::dec << " pos " + << xpos0 << ":" << ypos0 << " R " << r1 << ":" << R1 << " Range " << php.rMinLayHex_[i] << ":" + << php.rMaxLayHex_[i] << type << ":" << php.waferMaskMode_ << " corner " << corner.first << ":" + << corner.second << " croner0 " << corner0.first << ":" << corner0.second; #endif } else { waferTypes[wl] = corner; diff --git a/Geometry/HGCalCommonData/src/HGCalGeomTools.cc b/Geometry/HGCalCommonData/src/HGCalGeomTools.cc index 96623558b0259..327f9ed64b4b8 100644 --- a/Geometry/HGCalCommonData/src/HGCalGeomTools.cc +++ b/Geometry/HGCalCommonData/src/HGCalGeomTools.cc @@ -1,4 +1,5 @@ #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "Geometry/HGCalCommonData/interface/HGCalParameters.h" @@ -162,22 +163,22 @@ double HGCalGeomTools::radius( return r; } -std::pair HGCalGeomTools::shiftXY(int waferPosition, double waferSize) { +std::pair HGCalGeomTools::shiftXY(int waferPosition, double waferSize) const { double dx(0), dy(0); switch (waferPosition) { - case (CornerCenterYp): { + case (HGCalTypes::CornerCenterYp): { dy = factor_ * waferSize; break; } - case (CornerCenterYm): { + case (HGCalTypes::CornerCenterYm): { dy = -factor_ * waferSize; break; } - case (CornerCenterXp): { + case (HGCalTypes::CornerCenterXp): { dx = factor_ * waferSize; break; } - case (CornerCenterXm): { + case (HGCalTypes::CornerCenterXm): { dx = -factor_ * waferSize; break; } diff --git a/Geometry/HGCalCommonData/src/HGCalParametersFromDD.cc b/Geometry/HGCalCommonData/src/HGCalParametersFromDD.cc index 30d4ab16e993c..93403ed7d3e2e 100644 --- a/Geometry/HGCalCommonData/src/HGCalParametersFromDD.cc +++ b/Geometry/HGCalCommonData/src/HGCalParametersFromDD.cc @@ -103,6 +103,7 @@ bool HGCalParametersFromDD::build(const DDCompactView* cpv, #endif } php.minTileSize_ = 0; + php.waferMaskMode_ = 0; } if ((php.mode_ == HGCalGeometryMode::Hexagon8) || (php.mode_ == HGCalGeometryMode::Hexagon8Full)) { php.levelT_ = dbl_to_int(getDDDArray("LevelTop", sv)); @@ -134,7 +135,7 @@ bool HGCalParametersFromDD::build(const DDCompactView* cpv, php.waferThick_ = HGCalParameters::k_ScaleFromDDD * getDDDValue("WaferThickness", sv2); php.sensorSeparation_ = HGCalParameters::k_ScaleFromDDD * getDDDValue("SensorSeparation", sv2); php.mouseBite_ = HGCalParameters::k_ScaleFromDDD * getDDDValue("MouseBite", sv2); - php.waferR_ = 0.5 * HGCalParameters::k_ScaleToDDD * php.waferSize_ / std::cos(30._deg); + php.waferR_ = HGCalParameters::k_ScaleToDDD * php.waferSize_ * tan30deg_; php.cellSize_.emplace_back(HGCalParameters::k_ScaleToDDD * php.waferSize_ / php.nCellsFine_); php.cellSize_.emplace_back(HGCalParameters::k_ScaleToDDD * php.waferSize_ / php.nCellsCoarse_); #ifdef EDM_ML_DEBUG @@ -199,10 +200,13 @@ bool HGCalParametersFromDD::build(const DDCompactView* cpv, php.minTileSize_ = HGCalParameters::k_ScaleFromDDD * getDDDValue("MinimumTileSize", sv); php.waferSize_ = php.waferR_ = 0; php.sensorSeparation_ = php.mouseBite_ = 0; + php.waferMaskMode_ = static_cast(getDDDValue("WaferMaskMode", sv)); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Top levels " << php.levelT_[0] << ":" << php.levelT_[1] << " first layers " << php.firstLayer_ << ":" << php.firstMixedLayer_ << " Det Type " - << php.detectorType_ << " thickenss " << php.waferThick_; + << php.detectorType_ << " thickenss " << php.waferThick_ << " Tile Mask Mode " + << php.waferMaskMode_; + ; #endif // Load the SpecPars geom->loadSpecParsTrapezoid(fv, php); @@ -271,6 +275,7 @@ bool HGCalParametersFromDD::build(const cms::DDCompactView* cpv, << HGCalGeometryMode::ExtrudedPolygon; #endif php.minTileSize_ = 0; + php.waferMaskMode_ = 0; } if ((php.mode_ == HGCalGeometryMode::Hexagon8) || (php.mode_ == HGCalGeometryMode::Hexagon8Full)) { php.levelT_ = dbl_to_int(fv.get >(name, "LevelTop")); @@ -283,10 +288,14 @@ bool HGCalParametersFromDD::build(const cms::DDCompactView* cpv, tempD = fv.get >(name, "DetectorType"); php.detectorType_ = static_cast(tempD[0]); php.minTileSize_ = 0; + tempD = fv.get >(name, "WaferMaskMode"); + php.waferMaskMode_ = static_cast(tempD[0]); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Top levels " << php.levelT_[0] << ":" << php.levelT_[1] << " ZSide Level " << php.levelZSide_ << " first layers " << php.firstLayer_ << ":" - << php.firstMixedLayer_ << " Det Type " << php.detectorType_; + << php.firstMixedLayer_ << " Det Type " << php.detectorType_ << " Wafer Mask Mode " + << php.waferMaskMode_; + ; #endif tempS = fv.get >(namet, "WaferMode"); @@ -304,7 +313,7 @@ bool HGCalParametersFromDD::build(const cms::DDCompactView* cpv, php.sensorSeparation_ = HGCalParameters::k_ScaleFromDD4Hep * tempD[0]; tempD = fv.get >(namet, "MouseBite"); php.mouseBite_ = HGCalParameters::k_ScaleFromDD4Hep * tempD[0]; - php.waferR_ = 0.5 * HGCalParameters::k_ScaleToDDD * php.waferSize_ / std::cos(30._deg); + php.waferR_ = HGCalParameters::k_ScaleToDDD * php.waferSize_ * tan30deg_; php.cellSize_.emplace_back(HGCalParameters::k_ScaleToDDD * php.waferSize_ / php.nCellsFine_); php.cellSize_.emplace_back(HGCalParameters::k_ScaleToDDD * php.waferSize_ / php.nCellsCoarse_); #ifdef EDM_ML_DEBUG @@ -376,11 +385,14 @@ bool HGCalParametersFromDD::build(const cms::DDCompactView* cpv, php.minTileSize_ = HGCalParameters::k_ScaleFromDD4Hep * tempD[0]; php.waferSize_ = php.waferR_ = 0; php.sensorSeparation_ = php.mouseBite_ = 0; + tempD = fv.get >(name, "WaferMaskMode"); + php.waferMaskMode_ = static_cast(tempD[0]); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Top levels " << php.levelT_[0] << ":" << php.levelT_[1] << " first layers " << php.firstLayer_ << ":" << php.firstMixedLayer_ << " Det Type " << php.detectorType_ << " thickenss " << php.waferThick_ << " min tile size " - << php.minTileSize_; + << php.minTileSize_ << " Tile Mask Mode " << php.waferMaskMode_; + ; #endif // Load the SpecPars geom->loadSpecParsTrapezoid(fv, vmap, php, name); diff --git a/Geometry/HGCalCommonData/src/HGCalTileIndex.cc b/Geometry/HGCalCommonData/src/HGCalTileIndex.cc new file mode 100644 index 0000000000000..a1374ac447036 --- /dev/null +++ b/Geometry/HGCalCommonData/src/HGCalTileIndex.cc @@ -0,0 +1,14 @@ +#include "Geometry/HGCalCommonData/interface/HGCalTileIndex.h" + +int32_t HGCalTileIndex::tileIndex(int32_t layer, int32_t ring, int32_t phi) { + int32_t id(0); + id |= (((phi & kHGCalPhiMask) << kHGCalPhiOffset) | ((ring & kHGCalRingMask) << kHGCalRingOffset) | + ((layer & kHGCalLayerMask) << kHGCalLayerOffset)); + return id; +} + +int32_t HGCalTileIndex::tileLayer(int32_t id) { return ((id >> kHGCalLayerOffset) & kHGCalLayerMask); } + +int32_t HGCalTileIndex::tileRing(int32_t id) { return ((id >> kHGCalRingOffset) & kHGCalRingMask); } + +int32_t HGCalTileIndex::tilePhi(int32_t id) { return ((id >> kHGCalPhiOffset) & kHGCalPhiMask); } diff --git a/Geometry/HGCalCommonData/src/HGCalWaferMask.cc b/Geometry/HGCalCommonData/src/HGCalWaferMask.cc index 96fb2b3772f9f..8791bf6cfe965 100644 --- a/Geometry/HGCalCommonData/src/HGCalWaferMask.cc +++ b/Geometry/HGCalCommonData/src/HGCalWaferMask.cc @@ -1,4 +1,5 @@ #include "Geometry/HGCalCommonData/interface/HGCalWaferMask.h" +#include "Geometry/HGCalCommonData/interface/HGCalTypes.h" #include "Geometry/HGCalCommonData/interface/HGCalGeomTools.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -106,217 +107,219 @@ The argument 'corners' controls the types of wafers the user wants: for instance bool HGCalWaferMask::goodCell(int u, int v, int n, int type, int rotn) { bool good(false); int n2 = n / 2; + int n3 = (n + 1) / 3; + int n4 = n / 4; switch (type) { - case (HGCalGeomTools::WaferFull): { //WaferFull + case (HGCalTypes::WaferFull): { //WaferFull good = true; break; } - case (HGCalGeomTools::WaferFive): { //WaferFive + case (HGCalTypes::WaferFive): { //WaferFive switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { - int u2 = (u + 1) / 2; + case (HGCalTypes::WaferCorner0): { + int u2 = u / 2; good = ((v - u2) < n); break; } - case (HGCalGeomTools::WaferCorner1): { - good = ((v + u) < (3 * n)); + case (HGCalTypes::WaferCorner1): { + good = ((v + u) < (3 * n - 1)); break; } - case (HGCalGeomTools::WaferCorner2): { - good = ((2 * u - v) <= (2 * n)); + case (HGCalTypes::WaferCorner2): { + int v2 = (v + 1) / 2; + good = ((u - v2) < n); break; } - case (HGCalGeomTools::WaferCorner3): { - int u2 = u / 2; - good = (v >= u2); + case (HGCalTypes::WaferCorner3): { + int u2 = (u + 1) / 2; + good = (u2 <= v); break; } - case (HGCalGeomTools::WaferCorner4): { - good = ((v + u) <= (n - 1)); + case (HGCalTypes::WaferCorner4): { + good = ((v + u) >= n); break; } default: { - good = (v <= (2 * u)); + int v2 = v / 2; + good = (u > v2); break; } } break; } - case (HGCalGeomTools::WaferChopTwo): { //WaferChopTwo + case (HGCalTypes::WaferChopTwo): { //WaferChopTwo switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { - good = (v <= (3 * n2)); + case (HGCalTypes::WaferCorner0): { + good = (v < (3 * n2)); break; } - case (HGCalGeomTools::WaferCorner1): { - good = (u <= (3 * n2)); + case (HGCalTypes::WaferCorner1): { + good = (u < (3 * n2)); break; } - case (HGCalGeomTools::WaferCorner2): { - good = ((u - v) <= (n2 + 1)); + case (HGCalTypes::WaferCorner2): { + good = ((u - v) <= n2); break; } - case (HGCalGeomTools::WaferCorner3): { - good = (v >= (n2 - 1)); + case (HGCalTypes::WaferCorner3): { + good = (v >= n2); break; } - case (HGCalGeomTools::WaferCorner4): { - good = (u >= (n2 - 1)); + case (HGCalTypes::WaferCorner4): { + good = (u >= n2); break; } default: { - good = ((v - u) <= n2); + good = ((v - u) < n2); break; } } break; } - case (HGCalGeomTools::WaferChopTwoM): { //WaferChopTwoM + case (HGCalTypes::WaferChopTwoM): { //WaferChopTwoM switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { - good = (v < (3 * n2)); + case (HGCalTypes::WaferCorner0): { + good = (v < (5 * n4)); break; } - case (HGCalGeomTools::WaferCorner1): { - good = (u < (3 * n2)); + case (HGCalTypes::WaferCorner1): { + good = (u < (5 * n4)); break; } - case (HGCalGeomTools::WaferCorner2): { - good = ((u - v) <= n2); + case (HGCalTypes::WaferCorner2): { + good = ((u - v) <= n4); break; } - case (HGCalGeomTools::WaferCorner3): { - good = (v >= n2); + case (HGCalTypes::WaferCorner3): { + good = (v >= (3 * n4)); break; } - case (HGCalGeomTools::WaferCorner4): { - good = (u >= n2); + case (HGCalTypes::WaferCorner4): { + good = (u >= (3 * n4)); break; } default: { - good = ((v - u) < n2); + good = ((v - u) < n4); break; } } break; } - case (HGCalGeomTools::WaferHalf): { //WaferHalf + case (HGCalTypes::WaferHalf): { //WaferHalf switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { + case (HGCalTypes::WaferCorner0): { good = (v < n); break; } - case (HGCalGeomTools::WaferCorner1): { - good = (u <= n); + case (HGCalTypes::WaferCorner1): { + good = (u < n); break; } - case (HGCalGeomTools::WaferCorner2): { + case (HGCalTypes::WaferCorner2): { good = (v >= u); break; } - case (HGCalGeomTools::WaferCorner3): { - good = (v >= (n - 1)); + case (HGCalTypes::WaferCorner3): { + good = (v >= n); break; } - case (HGCalGeomTools::WaferCorner4): { + case (HGCalTypes::WaferCorner4): { good = (u >= n); break; } default: { - good = (u >= v); + good = (u > v); break; } } break; } - case (HGCalGeomTools::WaferSemi): { //WaferSemi + case (HGCalTypes::WaferSemi): { //WaferSemi switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { - good = ((u + v) <= (2 * n - 1)); + case (HGCalTypes::WaferCorner0): { + good = ((u + v) < (2 * n)); break; } - case (HGCalGeomTools::WaferCorner1): { - good = ((2 * u - v) >= n); + case (HGCalTypes::WaferCorner1): { + good = ((2 * u - v) < n); break; } - case (HGCalGeomTools::WaferCorner2): { - int u2 = ((u + 1) / 2); - good = ((v - u2) >= (n2 - 1)); + case (HGCalTypes::WaferCorner2): { + good = ((2 * v - u) >= n); break; } - case (HGCalGeomTools::WaferCorner3): { - good = ((u + v) >= (2 * n - 1)); + case (HGCalTypes::WaferCorner3): { + good = ((u + v) >= (2 * n)); break; } - case (HGCalGeomTools::WaferCorner4): { - good = ((2 * u - v) <= n); + case (HGCalTypes::WaferCorner4): { + good = ((2 * u - v) > n); break; } default: { - int u2 = ((u + 1) / 2); - good = ((v - u2) <= (n2 - 1)); + good = ((2 * v - u) < n); break; } } break; } - case (HGCalGeomTools::WaferThree): { //WaferThree + case (HGCalTypes::WaferThree): { //WaferThree switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { + case (HGCalTypes::WaferCorner0): { good = ((v + u) < n); break; } - case (HGCalGeomTools::WaferCorner1): { - good = (v >= (2 * u)); + case (HGCalTypes::WaferCorner1): { + int v2 = v / 2; + good = (u <= v2); break; } - case (HGCalGeomTools::WaferCorner2): { + case (HGCalTypes::WaferCorner2): { int u2 = (u / 2); good = ((v - u2) >= n); break; } - case (HGCalGeomTools::WaferCorner3): { + case (HGCalTypes::WaferCorner3): { good = ((v + u) >= (3 * n - 1)); break; } - case (HGCalGeomTools::WaferCorner4): { - good = ((2 * u - v) >= (2 * n)); + case (HGCalTypes::WaferCorner4): { + int v2 = v / 2; + good = ((u - v2) >= n); break; } default: { - int u2 = (u / 2); - good = (v <= u2); + int u2 = ((u + 1) / 2); + good = (v < u2); break; } } break; } - case (HGCalGeomTools::WaferSemi2): { //WaferSemi2 + case (HGCalTypes::WaferSemi2): { //WaferSemi2 switch (rotn) { - case (HGCalGeomTools::WaferCorner0): { - good = ((u + v) < (2 * n - 1)); + case (HGCalTypes::WaferCorner0): { + good = ((u + v) < (4 * n3)); break; } - case (HGCalGeomTools::WaferCorner1): { - good = ((2 * u - v) > n); + case (HGCalTypes::WaferCorner1): { + good = ((2 * u - v) <= n2); break; } - case (HGCalGeomTools::WaferCorner2): { - int u2 = ((u + 1) / 2); - good = ((v - u2) > (n2 - 1)); + case (HGCalTypes::WaferCorner2): { + good = ((2 * v - u) > (3 * n2)); break; } - case (HGCalGeomTools::WaferCorner3): { - good = ((u + v) > (2 * n - 1)); + case (HGCalTypes::WaferCorner3): { + good = ((u + v) >= (5 * n2 - 1)); break; } - case (HGCalGeomTools::WaferCorner4): { - good = ((2 * u - v) < n); + case (HGCalTypes::WaferCorner4): { + good = ((2 * u - v) < (3 * n2)); break; } default: { - int u2 = ((u + 1) / 2); - good = ((v - u2) < (n2 - 1)); + good = ((2 * v - u) <= n3); break; } } @@ -336,30 +339,20 @@ std::pair HGCalWaferMask::getTypeMode(const double& xpos, const double& delY, const double& rin, const double& rout, - const int& nw, - const int& mode) { - int ncor(0), fcor(0), iok(0); - int type(HGCalGeomTools::WaferFull), rotn(HGCalGeomTools::WaferCorner0); - static const double sqrt3 = std::sqrt(3.0); - double dxw = delX / (nw * sqrt3); - double dyw = 0.5 * delX / nw; + const int& wType, + const int& mode, + bool debug) { + int ncor(0), iok(0); + int type(HGCalTypes::WaferFull), rotn(HGCalTypes::WaferCorner0); static const int corners = 6; static const int base = 10; + double dx0[corners] = {0.0, delX, delX, 0.0, -delX, -delX}; + double dy0[corners] = {-delY, -0.5 * delY, 0.5 * delY, delY, 0.5 * delY, -0.5 * delY}; double xc[corners], yc[corners]; - xc[0] = xpos; - yc[0] = ypos + delY; - xc[1] = xpos - delX; - yc[1] = ypos + 0.5 * delY; - xc[2] = xpos - delX; - yc[2] = ypos - 0.5 * delY; - xc[3] = xpos; - yc[3] = ypos - delY; - xc[4] = xpos + delX; - yc[4] = ypos - 0.5 * delY; - xc[5] = xpos + delX; - yc[5] = ypos + 0.5 * delY; for (int k = 0; k < corners; ++k) { + xc[k] = xpos + dx0[k]; + yc[k] = ypos + dy0[k]; double rpos = sqrt(xc[k] * xc[k] + yc[k] * yc[k]); if (rpos <= rout && rpos >= rin) { ++ncor; @@ -368,65 +361,81 @@ std::pair HGCalWaferMask::getTypeMode(const double& xpos, iok *= base; } } - static const int ipat5[corners] = {111110, 11111, 101111, 110111, 111011, 111101}; - static const int ipat4[corners] = {111100, 11110, 1111, 100111, 110011, 111001}; - static const int ipat3[corners] = {111000, 11100, 1110, 111, 100011, 110001}; - double dx1[corners] = {(0.5 * delX + dxw), -0.5 * delX, -delX, -0.5 * delX, (0.5 * delX - dxw), delX}; - double dy1[corners] = {(0.75 * delY - dyw), 0.75 * delY, dyw, -0.75 * delY, -(0.75 * delY + dyw), 0.0}; - double dx2[corners] = {(0.5 * delX + dxw), delX, (0.5 * delX - dxw), -0.5 * delX, -delX, -0.5 * delX}; - double dy2[corners] = {-(0.75 * delY - dyw), 0.0, (0.75 * delY + dyw), 0.75 * delY, -dyw, -0.75 * delY}; - double dx3[corners] = {(0.5 * delX - dxw), -0.5 * delX, -delX, -0.5 * delX, (0.5 * delX + dxw), delX}; - double dy3[corners] = {(0.75 * delY + dyw), 0.75 * delY, -dyw, -0.75 * delY, -(0.75 * delY - dyw), 0.0}; - double dx4[corners] = {(0.5 * delX - dxw), delX, (0.5 * delX + dxw), 0.5 * delX, -delX, -0.5 * delX}; - double dy4[corners] = {-(0.75 * delY + dyw), 0.0, (0.75 * delY - dyw), 0.75 * delY, dyw, -0.75 * delY}; - double dx5[corners] = {0.5 * delX, -0.5 * delX, -delX, -0.5 * delX, 0.5 * delX, delX}; - double dy5[corners] = {0.75 * delY, 0.75 * delY, 0.0, -0.75 * delY, -0.75 * delY, 0.0}; - double dx6[corners] = {-0.5 * delX, 0.5 * delX, delX, 0.5 * delX, -0.5 * delX, -delX}; - double dy6[corners] = {-0.75 * delY, -0.75 * delY, 0.0, 0.75 * delY, 0.75 * delY, 0.0}; + if (debug) + edm::LogVerbatim("HGCalGeom") << "I/p " << xpos << ":" << ypos << ":" << delX << ":" << delY << ":" << rin << ":" + << rout << ":" << wType << ":" << mode << " Corners " << ncor << " iok " << iok; + + static const int ipat5[corners] = {101111, 110111, 111011, 111101, 111110, 11111}; + static const int ipat4[corners] = {100111, 110011, 111001, 111100, 11110, 1111}; + static const int ipat3[corners] = {100011, 110001, 111000, 11100, 1110, 111}; + double dx1[corners] = {0.5 * delX, delX, 0.5 * delX, -0.5 * delX, -delX, -0.5 * delX}; + double dy1[corners] = {-0.75 * delY, 0.0, 0.75 * delY, 0.75 * delY, 0.0, -0.75 * delY}; + double dx2[corners] = {0.5 * delX, -0.5 * delX, -delX, -0.5 * delX, 0.5 * delX, delX}; + double dy2[corners] = {0.75 * delY, 0.75 * delY, 0.0, -0.75 * delY, -0.75 * delY, 0.0}; + double dx3[corners] = {0.25 * delX, delX, 0.75 * delX, -0.25 * delX, -delX, -0.75 * delX}; + double dy3[corners] = {-0.875 * delY, -0.25 * delY, 0.625 * delY, 0.875 * delY, 0.25 * delY, -0.625 * delY}; + double dx4[corners] = {0.25 * delX, -0.75 * delX, -delX, -0.25 * delX, 0.75 * delX, delX}; + double dy4[corners] = {0.875 * delY, 0.625 * delY, -0.25 * delY, -0.875 * delY, -0.625 * delY, 0.25 * delY}; + double dx5[corners] = {-0.5 * delX, -delX, -0.5 * delX, 0.5 * delX, delX, 0.5 * delX}; + double dy5[corners] = {0.75 * delY, 0.0, -0.75 * delY, -0.75 * delY, 0.0, 0.75 * delY}; + double dx6[corners] = {-0.75 * delX, -delX, -0.25 * delX, 0.75 * delX, delX, 0.25 * delX}; + double dy6[corners] = {0.625 * delY, -0.25 * delY, -0.875 * delY, -0.625 * delY, 0.25 * delY, 0.875 * delY}; if (ncor == HGCalGeomTools::k_allCorners) { } else if (ncor == HGCalGeomTools::k_fiveCorners) { - fcor = static_cast(std::find(ipat5, ipat5 + 6, iok) - ipat5); - type = HGCalGeomTools::WaferFive; - rotn = fcor + 1; - if (rotn > 5) - rotn = 0; + rotn = static_cast(std::find(ipat5, ipat5 + 6, iok) - ipat5); + type = HGCalTypes::WaferFive; } else if (ncor == HGCalGeomTools::k_fourCorners) { - fcor = static_cast(std::find(ipat4, ipat4 + 6, iok) - ipat4); - type = HGCalGeomTools::WaferHalf; - rotn = fcor; - double rpos = sqrt((xpos + dx1[fcor]) * (xpos + dx1[fcor]) + (ypos + dy1[fcor]) * (ypos + dy1[fcor])); - if (rpos <= rout && rpos >= rin) { - rpos = sqrt((xpos + dx2[fcor]) * (xpos + dx2[fcor]) + (ypos + dy2[fcor]) * (ypos + dy2[fcor])); - if (rpos <= rout && rpos >= rin) - type = HGCalGeomTools::WaferChopTwo; + rotn = static_cast(std::find(ipat4, ipat4 + 6, iok) - ipat4); + type = HGCalTypes::WaferHalf; + double rpos1 = sqrt((xpos + dx1[rotn]) * (xpos + dx1[rotn]) + (ypos + dy1[rotn]) * (ypos + dy1[rotn])); + double rpos2(0); + if (rpos1 <= rout && rpos1 >= rin) { + rpos2 = sqrt((xpos + dx2[rotn]) * (xpos + dx2[rotn]) + (ypos + dy2[rotn]) * (ypos + dy2[rotn])); + if (rpos2 <= rout && rpos2 >= rin) + type = HGCalTypes::WaferChopTwo; } - if (type == HGCalGeomTools::WaferHalf) { - rpos = sqrt((xpos + dx3[fcor]) * (xpos + dx3[fcor]) + (ypos + dy3[fcor]) * (ypos + dy3[fcor])); - if (rpos <= rout && rpos >= rin) { - rpos = sqrt((xpos + dx4[fcor]) * (xpos + dx4[fcor]) + (ypos + dy4[fcor]) * (ypos + dy4[fcor])); - if (rpos <= rout && rpos >= rin) - type = HGCalGeomTools::WaferChopTwoM; + if (debug) + edm::LogVerbatim("HGCalGeom") << "Test for Chop2 " << rpos1 << ":" << rpos2 << " Type " << type; + if ((type == HGCalTypes::WaferHalf) && (wType == 0)) { + rpos1 = sqrt((xpos + dx3[rotn]) * (xpos + dx3[rotn]) + (ypos + dy3[rotn]) * (ypos + dy3[rotn])); + if (rpos1 <= rout && rpos1 >= rin) { + rpos2 = sqrt((xpos + dx4[rotn]) * (xpos + dx4[rotn]) + (ypos + dy4[rotn]) * (ypos + dy4[rotn])); + if (rpos2 <= rout && rpos2 >= rin) + type = HGCalTypes::WaferChopTwoM; } + if (debug) + edm::LogVerbatim("HGCalGeom") << "Test for Chop2M " << rpos1 << ":" << rpos2 << " Type " << type; } } else if (ncor == HGCalGeomTools::k_threeCorners) { - fcor = static_cast(std::find(ipat3, ipat3 + 6, iok) - ipat3); - type = HGCalGeomTools::WaferThree; - rotn = fcor - 1; - if (rotn < 0) - rotn = HGCalGeomTools::WaferCorner5; - double rpos = sqrt((xpos + dx5[fcor]) * (xpos + dx5[fcor]) + (ypos + dy5[fcor]) * (ypos + dy5[fcor])); - if (rpos <= rout && rpos >= rin) { - rpos = sqrt((xpos + dx6[fcor]) * (xpos + dx6[fcor]) + (ypos + dy6[fcor]) * (ypos + dy6[fcor])); - if (rpos <= rout && rpos >= rin) - type = HGCalGeomTools::WaferSemi; + rotn = static_cast(std::find(ipat3, ipat3 + 6, iok) - ipat3); + type = HGCalTypes::WaferThree; + double rpos1 = sqrt((xpos + dx1[rotn]) * (xpos + dx1[rotn]) + (ypos + dy1[rotn]) * (ypos + dy1[rotn])); + double rpos2(0); + if (rpos1 <= rout && rpos1 >= rin) { + rpos2 = sqrt((xpos + dx5[rotn]) * (xpos + dx5[rotn]) + (ypos + dy5[rotn]) * (ypos + dy5[rotn])); + if (rpos2 <= rout && rpos2 >= rin) + type = HGCalTypes::WaferSemi; + } + if (debug) + edm::LogVerbatim("HGCalGeom") << "Test for Semi " << rpos1 << ":" << rpos2 << " Type " << type; + if ((type == HGCalTypes::WaferThree) && (wType == 0)) { + rpos1 = sqrt((xpos + dx3[rotn]) * (xpos + dx3[rotn]) + (ypos + dy3[rotn]) * (ypos + dy3[rotn])); + if (rpos1 <= rout && rpos1 >= rin) { + rpos2 = sqrt((xpos + dx6[rotn]) * (xpos + dx6[rotn]) + (ypos + dy6[rotn]) * (ypos + dy6[rotn])); + if (rpos2 <= rout && rpos2 >= rin) + type = HGCalTypes::WaferSemi2; + } + if (debug) + edm::LogVerbatim("HGCalGeom") << "Test for SemiM " << rpos1 << ":" << rpos2 << " Type " << type; } } else { - type = HGCalGeomTools::WaferOut; + type = HGCalTypes::WaferOut; } -#ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeom") << "Corners " << ncor << ":" << fcor << " Type " << type << ":" << rotn; -#endif - return ((mode == 0) ? std::make_pair(ncor, fcor) : std::make_pair(type, k_OffsetRotation + rotn)); + if (debug) + edm::LogVerbatim("HGCalGeom") << "I/p " << xpos << ":" << ypos << ":" << delX << ":" << delY << ":" << rin << ":" + << rout << ":" << wType << ":" << mode << " o/p " << iok << ":" << ncor << ":" << type + << ":" << rotn; + return ((mode == 0) ? std::make_pair(ncor, rotn) : std::make_pair(type, (rotn + HGCalWaferMask::k_OffsetRotation))); } diff --git a/Geometry/HGCalCommonData/src/HGCalWaferType.cc b/Geometry/HGCalCommonData/src/HGCalWaferType.cc index 6c029ff72b9b6..402b119db2a2f 100644 --- a/Geometry/HGCalCommonData/src/HGCalWaferType.cc +++ b/Geometry/HGCalCommonData/src/HGCalWaferType.cc @@ -47,7 +47,7 @@ int HGCalWaferType::getType(double xpos, double ypos, double zpos) { yc[4] = ypos - R_; xc[5] = xpos + r_; yc[5] = ypos - 0.5 * R_; - std::pair rv = rLimits(zpos); + const auto& rv = rLimits(zpos); std::vector fine, coarse; for (unsigned int k = 0; k < HGCalParameters::k_CornerSize; ++k) { double rpos = std::sqrt(xc[k] * xc[k] + yc[k] * yc[k]); @@ -86,7 +86,7 @@ int HGCalWaferType::getType(double xpos, double ypos, double zpos) { ycn.emplace_back(yc[k1]); if (!ok) { double rr = (type == -1) ? rv.first : rv.second; - std::pair xy = intersection(k1, k2, xc, yc, xpos, ypos, rr); + const auto& xy = intersection(k1, k2, xc, yc, xpos, ypos, rr); xcn.emplace_back(xy.first); ycn.emplace_back(xy.second); } @@ -116,12 +116,17 @@ std::pair HGCalWaferType::rLimits(double zpos) { rcoarse *= zz; rcoarse += rad200_[i]; } - return std::pair(rfine * HGCalParameters::k_ScaleToDDD, rcoarse * HGCalParameters::k_ScaleToDDD); + rfine *= HGCalParameters::k_ScaleToDDD; + rcoarse *= HGCalParameters::k_ScaleToDDD; +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "HGCalWaferType: Z " << zpos << ":" << zz << " R " << rfine << ":" << rcoarse; +#endif + return std::make_pair(rfine, rcoarse); } double HGCalWaferType::areaPolygon(std::vector const& x, std::vector const& y) { double area = 0.0; - int n = x.size(); + int n = static_cast(x.size()); int j = n - 1; for (int i = 0; i < n; ++i) { area += ((x[j] + x[i]) * (y[i] - y[j])); @@ -142,8 +147,12 @@ std::pair HGCalWaferType::intersection( xx[i] = (slope * yy[i] + interc); dist[i] = ((xx[i] - xpos) * (xx[i] - xpos)) + ((yy[i] - ypos) * (yy[i] - ypos)); } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "HGCalWaferType: InterSection " << dist[0] << ":" << xx[0] << ":" << yy[0] << " vs " + << dist[1] << ":" << xx[1] << ":" << yy[1]; +#endif if (dist[0] > dist[1]) - return std::pair(xx[1], yy[1]); + return std::make_pair(xx[1], yy[1]); else - return std::pair(xx[0], yy[0]); + return std::make_pair(xx[0], yy[0]); } diff --git a/Geometry/HGCalCommonData/test/HGCalNumberingTester.cc b/Geometry/HGCalCommonData/test/HGCalNumberingTester.cc index 8b5d68fa1b5d9..87e0f6702a2db 100644 --- a/Geometry/HGCalCommonData/test/HGCalNumberingTester.cc +++ b/Geometry/HGCalCommonData/test/HGCalNumberingTester.cc @@ -42,7 +42,6 @@ class HGCalNumberingTester : public edm::one::EDAnalyzer<> { public: explicit HGCalNumberingTester(const edm::ParameterSet&); - ~HGCalNumberingTester() override; void beginJob() override {} void analyze(edm::Event const& iEvent, edm::EventSetup const&) override; @@ -89,8 +88,6 @@ HGCalNumberingTester::HGCalNumberingTester(const edm::ParameterSet& iC) { << std::endl; } -HGCalNumberingTester::~HGCalNumberingTester() {} - // ------------ method called to produce the data ------------ void HGCalNumberingTester::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { const HGCalDDDConstants& hgdc = iSetup.getData(dddToken_); @@ -99,9 +96,13 @@ void HGCalNumberingTester::analyze(const edm::Event& iEvent, const edm::EventSet if (detType_ != 0) { std::cout << "Minimum Wafer # " << hgdc.waferMin() << " Mamximum Wafer # " << hgdc.waferMax() << " Wafer counts " << hgdc.waferCount(0) << ":" << hgdc.waferCount(1) << std::endl; - for (unsigned int i = 0; i < hgdc.layers(true); ++i) - std::cout << "Layer " << i + 1 << " Wafers " << hgdc.wafers(i + 1, 0) << ":" << hgdc.wafers(i + 1, 1) << ":" - << hgdc.wafers(i + 1, 2) << std::endl; + for (unsigned int i = 0; i < hgdc.layers(true); ++i) { + int lay = i + 1; + double z = hgdc.waferZ(lay, reco_); + std::cout << "Layer " << lay << " Wafers " << hgdc.wafers(lay, 0) << ":" << hgdc.wafers(lay, 1) << ":" + << hgdc.wafers(lay, 2) << " Z " << z << " R " << hgdc.rangeR(z, reco_).first << ":" + << hgdc.rangeR(z, reco_).second << std::endl; + } } std::cout << std::endl << std::endl; std::pair xy; diff --git a/Geometry/HGCalCommonData/test/HGCalParameterTester.cc b/Geometry/HGCalCommonData/test/HGCalParameterTester.cc index eda67010aec7d..e039712fe93e6 100644 --- a/Geometry/HGCalCommonData/test/HGCalParameterTester.cc +++ b/Geometry/HGCalCommonData/test/HGCalParameterTester.cc @@ -22,6 +22,8 @@ class HGCalParameterTester : public edm::one::EDAnalyzer<> { private: template void myPrint(std::string const& s, std::vector const& obj, int n) const; + template + void myPrint(std::string const& s, std::vector > const& obj, int n) const; void myPrint(std::string const& s, std::vector const& obj1, std::vector const& obj2, int n) const; void myPrint(std::string const& s, HGCalParameters::wafer_map const& obj, int n) const; void printTrform(HGCalParameters const*) const; @@ -46,6 +48,7 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet std::cout << phgp->name_ << "\n"; if (mode_ == 0) { + // Wafers of 6-inch format std::cout << "DetectorType: " << phgp->detectorType_ << "\n"; std::cout << "WaferR_: " << phgp->waferR_ << "\n"; std::cout << "nCells_: " << phgp->nCells_ << "\n"; @@ -72,7 +75,7 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet myPrint("moduleDzR", phgp->moduleDzR_, 10); myPrint("moduleAlphaR", phgp->moduleAlphaR_, 10); myPrint("moduleCellR", phgp->moduleCellR_, 10); - myPrint("trformTranX", phgp->trformTranY_, 10); + myPrint("trformTranX", phgp->trformTranX_, 10); myPrint("trformTranY", phgp->trformTranY_, 10); myPrint("trformTranZ", phgp->trformTranZ_, 10); myPrint("trformRotXX", phgp->trformRotXX_, 10); @@ -112,6 +115,7 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet printWaferType(phgp); } else if (mode_ == 1) { + // Wafers of 8-inch format std::cout << "DetectorType: " << phgp->detectorType_ << "\n"; std::cout << "Wafer Parameters: " << phgp->waferSize_ << ":" << phgp->waferR_ << ":" << phgp->waferThick_ << ":" << phgp->sensorSeparation_ << ":" << phgp->mouseBite_ << "\n"; @@ -151,9 +155,9 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet myPrint("moduleDzR", phgp->moduleDzR_, 10); myPrint("moduleAlphaR", phgp->moduleAlphaR_, 10); myPrint("moduleCellR", phgp->moduleCellR_, 10); - myPrint("trformTranX", phgp->trformTranY_, 10); - myPrint("trformTranY", phgp->trformTranY_, 10); - myPrint("trformTranZ", phgp->trformTranZ_, 10); + myPrint("trformTranX", phgp->trformTranX_, 8); + myPrint("trformTranY", phgp->trformTranY_, 8); + myPrint("trformTranZ", phgp->trformTranZ_, 8); myPrint("trformRotXX", phgp->trformRotXX_, 10); myPrint("trformRotYX", phgp->trformRotYX_, 10); myPrint("trformRotZX", phgp->trformRotZX_, 10); @@ -163,15 +167,15 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet myPrint("trformRotXZ", phgp->trformRotXZ_, 10); myPrint("trformRotYZ", phgp->trformRotYZ_, 10); myPrint("trformRotZZ", phgp->trformRotZZ_, 10); - myPrint("xLayerHex", phgp->xLayerHex_, 10); - myPrint("yLayerHex", phgp->yLayerHex_, 10); - myPrint("zLayerHex", phgp->zLayerHex_, 10); - myPrint("rMinLayHex", phgp->rMinLayHex_, 10); - myPrint("rMaxLayHex", phgp->rMaxLayHex_, 10); + myPrint("xLayerHex", phgp->xLayerHex_, 8); + myPrint("yLayerHex", phgp->yLayerHex_, 8); + myPrint("zLayerHex", phgp->zLayerHex_, 8); + myPrint("rMinLayHex", phgp->rMinLayHex_, 8); + myPrint("rMaxLayHex", phgp->rMaxLayHex_, 8); myPrint("waferPos", phgp->waferPosX_, phgp->waferPosY_, 4); - myPrint("cellFineIndex", phgp->cellFineIndex_, 10); + myPrint("cellFineIndex", phgp->cellFineIndex_, 8); myPrint("cellFine", phgp->cellFineX_, phgp->cellFineY_, 4); - myPrint("cellCoarseIndex", phgp->cellCoarseIndex_, 10); + myPrint("cellCoarseIndex", phgp->cellCoarseIndex_, 8); myPrint("cellCoarse", phgp->cellCoarseX_, phgp->cellCoarseY_, 4); myPrint("layer", phgp->layer_, 18); myPrint("layerIndex", phgp->layerIndex_, 18); @@ -184,7 +188,17 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet myPrint("levelTop", phgp->levelT_, 10); printWaferType(phgp); + std::cout << "MaskMode: " << phgp->waferMaskMode_ << "\n"; + if (phgp->waferMaskMode_ > 1) { + std::cout << "WaferInfo with " << phgp->waferInfoMap_.size(); + unsigned int kk(0); + std::unordered_map::const_iterator itr = phgp->waferInfoMap_.begin(); + for (; itr != phgp->waferInfoMap_.end(); ++itr, ++kk) + std::cout << "[" << kk << "] " << itr->first << " (" << (itr->second).type << ", " << (itr->second).part << ", " + << (itr->second).orient << ")" << std::endl; + } } else { + // Tpaezoid (scintillator) type std::cout << "DetectorType: " << phgp->detectorType_ << "\n"; std::cout << "nCells_: " << phgp->nCellsFine_ << ":" << phgp->nCellsCoarse_ << "\n"; std::cout << "MinTileZize: " << phgp->minTileSize_ << "\n"; @@ -226,10 +240,10 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet myPrint("moduleHR", phgp->moduleHR_, 10); myPrint("moduleDzR", phgp->moduleDzR_, 10); myPrint("moduleAlphaR", phgp->moduleAlphaR_, 10); - myPrint("moduleCellR", phgp->moduleCellR_, 10); - myPrint("trformTranX", phgp->trformTranY_, 10); - myPrint("trformTranY", phgp->trformTranY_, 10); - myPrint("trformTranZ", phgp->trformTranZ_, 10); + myPrint("moduleCellR", phgp->moduleCellR_, 9); + myPrint("trformTranX", phgp->trformTranY_, 9); + myPrint("trformTranY", phgp->trformTranY_, 9); + myPrint("trformTranZ", phgp->trformTranZ_, 9); myPrint("trformRotXX", phgp->trformRotXX_, 10); myPrint("trformRotYX", phgp->trformRotYX_, 10); myPrint("trformRotZX", phgp->trformRotZX_, 10); @@ -242,8 +256,8 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet myPrint("xLayerHex", phgp->xLayerHex_, 10); myPrint("yLayerHex", phgp->yLayerHex_, 10); myPrint("zLayerHex", phgp->zLayerHex_, 10); - myPrint("rMinLayHex", phgp->rMinLayHex_, 10); - myPrint("rMaxLayHex", phgp->rMaxLayHex_, 10); + myPrint("rMinLayHex", phgp->rMinLayHex_, 9); + myPrint("rMaxLayHex", phgp->rMaxLayHex_, 9); myPrint("layer", phgp->layer_, 18); myPrint("layerIndex", phgp->layerIndex_, 18); myPrint("depth", phgp->depth_, 18); @@ -252,6 +266,19 @@ void HGCalParameterTester::analyze(const edm::Event& iEvent, const edm::EventSet printTrform(phgp); myPrint("levelTop", phgp->levelT_, 10); printWaferType(phgp); + + std::cout << "MaskMode: " << phgp->waferMaskMode_ << "\n"; + if (phgp->waferMaskMode_ > 1) { + myPrint("tileRingR", phgp->tileRingR_, 4); + myPrint("tileRingRange", phgp->tileRingRange_, 8); + std::cout << "TileInfo with " << phgp->tileInfoMap_.size(); + unsigned int kk(0); + std::unordered_map::const_iterator itr = phgp->tileInfoMap_.begin(); + for (; itr != phgp->tileInfoMap_.end(); ++itr, ++kk) + std::cout << "[" << kk << "] " << itr->first << " (" << (itr->second).type << ", " << (itr->second).sipm + << std::hex << ", " << (itr->second).hex1 << ", " << (itr->second).hex2 << ", " << (itr->second).hex3 + << ", " << (itr->second).hex4 << ")" << std::dec << std::endl; + } } auto finish = std::chrono::high_resolution_clock::now(); @@ -275,6 +302,22 @@ void HGCalParameterTester::myPrint(std::string const& s, std::vector const& o std::cout << "\n"; } +template +void HGCalParameterTester::myPrint(std::string const& s, std::vector > const& obj, int n) const { + int k(0); + std::cout << s << " with " << obj.size() << " elements\n"; + for (auto const& it : obj) { + std::cout << "(" << it.first << ", " << it.second << ") "; + ++k; + if (k == n) { + std::cout << "\n"; + k = 0; + } + } + if (k > 0) + std::cout << "\n"; +} + void HGCalParameterTester::myPrint(std::string const& s, std::vector const& obj1, std::vector const& obj2, @@ -315,7 +358,7 @@ void HGCalParameterTester::printTrform(HGCalParameters const* phgp) const { std::array id = phgp->getID(i); std::cout << id[0] << ":" << id[1] << ":" << id[2] << ":" << id[3] << ", "; ++k; - if (k == 10) { + if (k == 7) { std::cout << "\n"; k = 0; } diff --git a/Geometry/HGCalGeometry/interface/HGCalGeometry.h b/Geometry/HGCalGeometry/interface/HGCalGeometry.h index 5c1e8f89b5bdf..d8e2674d07f7c 100644 --- a/Geometry/HGCalGeometry/interface/HGCalGeometry.h +++ b/Geometry/HGCalGeometry/interface/HGCalGeometry.h @@ -72,6 +72,7 @@ class HGCalGeometry final : public CaloSubdetectorGeometry { CaloSubdetectorGeometry::IVec& dinsVector) const override; GlobalPoint getPosition(const DetId& id) const; + GlobalPoint getWaferPosition(const DetId& id) const; /// Returns area of a cell double getArea(const DetId& detid) const; diff --git a/Geometry/HGCalGeometry/plugins/HGCalGeometryESProducer.cc b/Geometry/HGCalGeometry/plugins/HGCalGeometryESProducer.cc index 98e8676a59e19..f82ce79c1c682 100644 --- a/Geometry/HGCalGeometry/plugins/HGCalGeometryESProducer.cc +++ b/Geometry/HGCalGeometry/plugins/HGCalGeometryESProducer.cc @@ -46,15 +46,16 @@ class HGCalGeometryESProducer : public edm::ESProducer { private: // ----------member data --------------------------- edm::ESGetToken topologyToken_; + std::string name_; }; HGCalGeometryESProducer::HGCalGeometryESProducer(const edm::ParameterSet& iConfig) { - auto name = iConfig.getUntrackedParameter("Name"); + name_ = iConfig.getUntrackedParameter("Name"); #ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeom") << "Constructing HGCalGeometry for " << name; + edm::LogVerbatim("HGCalGeom") << "Constructing HGCalGeometry for " << name_; #endif - auto cc = setWhatProduced(this, name); - topologyToken_ = cc.consumes(edm::ESInputTag{"", name}); + auto cc = setWhatProduced(this, name_); + topologyToken_ = cc.consumes(edm::ESInputTag{"", name_}); } HGCalGeometryESProducer::~HGCalGeometryESProducer() {} @@ -66,9 +67,7 @@ HGCalGeometryESProducer::~HGCalGeometryESProducer() {} // ------------ method called to produce the data ------------ HGCalGeometryESProducer::ReturnType HGCalGeometryESProducer::produce(const IdealGeometryRecord& iRecord) { const auto& topo = iRecord.get(topologyToken_); -#ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeom") << "Create HGCalGeometry (*topo)"; -#endif + edm::LogVerbatim("HGCalGeom") << "Create HGCalGeometry (*topo) for " << name_; HGCalGeometryLoader builder; return ReturnType(builder.build(topo)); diff --git a/Geometry/HGCalGeometry/src/HGCalGeometry.cc b/Geometry/HGCalGeometry/src/HGCalGeometry.cc index ecb4fc4be7089..3f13158e034a4 100644 --- a/Geometry/HGCalGeometry/src/HGCalGeometry.cc +++ b/Geometry/HGCalGeometry/src/HGCalGeometry.cc @@ -226,6 +226,25 @@ GlobalPoint HGCalGeometry::getPosition(const DetId& detid) const { return glob; } +GlobalPoint HGCalGeometry::getWaferPosition(const DetId& detid) const { + unsigned int cellIndex = indexFor(detid); + GlobalPoint glob; + unsigned int maxSize = ((mode_ == HGCalGeometryMode::Trapezoid) ? m_cellVec2.size() : m_cellVec.size()); + if (cellIndex < maxSize) { + const HepGeom::Point3D lcoord(0, 0, 0); + if (mode_ == HGCalGeometryMode::Trapezoid) { + glob = m_cellVec2[cellIndex].getPosition(lcoord); + } else { + glob = m_cellVec[cellIndex].getPosition(lcoord); + } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("HGCalGeom") << "getPositionTrap:: ID " << std::hex << detid.rawId() << std::dec << " index " + << cellIndex << " Global " << glob; +#endif + } + return glob; +} + double HGCalGeometry::getArea(const DetId& detid) const { HGCalGeometry::CornersVec corners = getNewCorners(detid); double area(0); diff --git a/HLTrigger/Configuration/python/HLTPhase2TDR_EventContent_cff.py b/HLTrigger/Configuration/python/HLTPhase2TDR_EventContent_cff.py new file mode 100644 index 0000000000000..6361e26bea27f --- /dev/null +++ b/HLTrigger/Configuration/python/HLTPhase2TDR_EventContent_cff.py @@ -0,0 +1,84 @@ +import FWCore.ParameterSet.Config as cms + +HLTPhase2TDR = cms.PSet( + outputCommands = cms.vstring( *( + 'keep *_TTTrackAssociatorFromPixelDigis_*_*', + 'keep *_TTStubAssociatorFromPixelDigis_*_*', + 'drop *_TTStubsFromPhase2TrackerDigis_*_HLT', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusteredmNewDetSetVector_TTClustersFromPhase2TrackerDigis_ClusterInclusive_*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusterAssociationMap_TTClusterAssociatorFromPixelDigis_ClusterInclusive_*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusterAssociationMap_TTClusterAssociatorFromPixelDigis_ClusterAccepted_*', + 'drop recoPFClusters_particleFlowClusterHGCal__*', + 'drop l1tHGCalTriggerCellBXVector_hgcalVFEProducer_HGCalVFEProcessorSums_*', + 'drop recoHGCalMultiClusters_ticlMultiClustersFromTrackstersMerge__*', + 'drop recoHGCalMultiClusters_ticlMultiClustersFromTrackstersTrk__*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusteredmNewDetSetVector_TTClustersFromPhase2TrackerDigis_ClusterInclusive_HLT', + 'drop recoHGCalMultiClusters_ticlMultiClustersFromTrackstersMIP__*', + 'drop recoPFClusters_particleFlowClusterHGCalFromMultiCl__*', + 'drop l1tHGCalClusterBXVector_hgcalBackEndLayer1Producer_HGCalBackendLayer1Processor2DClustering_*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusterAssociationMap_TTClusterAssociatorFromPixelDigis_ClusterInclusive_HLT', + 'drop l1tHGCalTowerMapBXVector_hgcalTowerMapProducer_HGCalTowerMapProcessor_*', + 'drop recoGsfTrackExtras_electronGsfTracks__*', + 'drop recoCaloClusters_particleFlowSuperClusterHGCal__*', + 'drop l1tHGCalTriggerCellBXVector_hgcalConcentratorProducer_HGCalConcentratorProcessorSelection_*', + 'drop recoSuperClusters_particleFlowSuperClusterHGCal__*', + 'drop recoGsfTrackExtras_electronGsfTracksFromMultiCl__*', + 'drop recoHGCalMultiClusters_hgcalMultiClusters__*', + 'drop recoGsfTrackExtras_electronGsfTracks__*', + 'drop recoCaloClusters_particleFlowSuperClusterHGCalFromMultiCl__*', + 'drop recoSuperClusters_particleFlowSuperClusterHGCalFromMultiCl__*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusteredmNewDetSetVector_TTStubsFromPhase2TrackerDigis_ClusterAccepted_HLT', + 'drop recoElectronSeeds_electronMergedSeedsFromMultiCl__*', + 'drop recoTrackExtras_electronGsfTracks__*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTClusterAssociationMap_TTClusterAssociatorFromPixelDigis_ClusterAccepted_HLT', + 'drop recoHGCalMultiClusters_ticlMultiClustersFromTrackstersHAD__*', + 'drop recoTrackExtras_electronGsfTracksFromMultiCl__*', + 'drop Phase2TrackerDigiedmDetSetVectorPhase2TrackerDigiPhase2TrackerDigiedmrefhelperFindForDetSetVectoredmRefTTStubAssociationMap_TTStubAssociatorFromPixelDigis_StubAccepted_HLT', + 'drop CaloTowersSorted_towerMaker__*', + 'drop l1tHGCalTowerBXVector_hgcalTowerProducer_HGCalTowerProcessor_*', + 'drop TrackingRecHitsOwned_electronGsfTracks__*', + 'drop recoHGCalMultiClusters_ticlMultiClustersFromTrackstersEM__*', + 'drop *_hltGtStage2Digis_*_HLT', + 'drop *_simBmtfDigis_*_HLT', + 'drop *_simCaloStage2Digis_*_HLT', + 'drop *_simCaloStage2Layer1Digis_*_HLT', + 'drop *_simEmtfDigis_*_HLT', + 'drop *_simGmtStage2Digis_*_HLT', + 'drop *_simGtStage2Digis_*_HLT', + 'drop *_simOmtfDigis_*_HLT', + 'keep *_TTClusterAssociatorFromPixelDigis_ClusterAccepted_*', + 'drop *_TTClusterAssociatorFromPixelDigis_*_HLT', + 'keep *_particleFlowTmpBarrel_*_*', + 'keep *_muons_muons1stStep2muonsMap_*', + 'drop recoElectronSeeds_electronMergedSeeds__*', + #low pt GsfElectrons which are pointless for HLT TDR + 'drop recoCaloClusters_lowPtGsfElectronSuperClusters__*', + 'drop recoGsfElectrons_lowPtGsfElectrons__*', + 'drop recoGsfTracks_lowPtGsfEleGsfTracks__*', + 'drop recoSuperClusters_lowPtGsfElectronSuperClusters__*', + 'drop recoGsfElectronCores_lowPtGsfElectronCores__*', + 'drop floatedmValueMap_lowPtGsfElectronSeedValueMaps_unbiased_*', + 'drop floatedmValueMap_lowPtGsfElectronSeedValueMaps_ptbiased_*', + 'drop recoTracksedmAssociation_lowPtGsfToTrackLinks__*', + 'drop floatedmValueMap_lowPtGsfElectronID__*', + 'drop *_gsfTracksOpenConversions_*_*', + #e/gamma for ecal debugging, out of scope for tdr + 'drop recoGsfElectrons_uncleanedOnlyGsfElectrons__*', + 'drop recoGsfElectronCores_uncleanedOnlyGsfElectronCores__*', + #tracking debugging not needed + 'drop TrackingRecHitsOwned_electronGsfTracksFromMultiCl__*', + ) ) +) + +def extendInputEvtContentForHLTTDR(source): + if not hasattr(source,"inputCommands"): + source.inputCommands = cms.untracked.vstring("keep *") + source.inputCommands.extend(HLTPhase2TDR.outputCommands) + source.dropDescendantsOfDroppedBranches = cms.untracked.bool(False) + +def extendOutputEvtContentForHLTTDR(output): + if not hasattr(output,"outputCommands"): + output.outputCommands = cms.untracked.vstring("keep *") + output.outputCommands.extend(HLTPhase2TDR.outputCommands) + + diff --git a/HLTrigger/Configuration/python/HLT_2018_cff.py b/HLTrigger/Configuration/python/HLT_2018_cff.py index 1d28d1dcc7a7a..489455b5f12f4 100644 --- a/HLTrigger/Configuration/python/HLT_2018_cff.py +++ b/HLTrigger/Configuration/python/HLT_2018_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /frozen/2018/111X/HLT --type 2018 -# /frozen/2018/111X/HLT/V11 (CMSSW_11_1_0_pre7) +# /frozen/2018/111X/HLT/V16 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/frozen/2018/111X/HLT/V11') + tableName = cms.string('/frozen/2018/111X/HLT/V16') ) fragment.transferSystem = cms.PSet( @@ -6280,11 +6280,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -6739,6 +6740,7 @@ fragment.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +fragment.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) fragment.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -33340,6 +33342,7 @@ minMeff = cms.vdouble( 0.0 ) ) fragment.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -33369,6 +33372,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -48708,10 +48712,13 @@ minMht = cms.vdouble( 100.0 ) ) fragment.hltPFMETProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlow" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "hltPFMet" ), - src = cms.InputTag( "hltParticleFlow" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMET100 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -50313,6 +50320,7 @@ newQuality = cms.string( "confirmed" ) ) fragment.hltVerticesL3 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -50342,6 +50350,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltMergedTracksForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -50662,10 +50671,13 @@ cut = cms.string( "particleId!=3" ) ) fragment.hltPFMETNoMuProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMetNoMu" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMETNoMu120 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -53496,13 +53508,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtag" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtag" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -66693,10 +66705,13 @@ MaxMass = cms.double( -1.0 ) ) fragment.hltPFMETVBFProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMet" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMETVBF110 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -86783,13 +86798,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -87006,13 +87021,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForDBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForDBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -89010,7 +89025,7 @@ fragment.HLTBeginSequenceParking = cms.Sequence( fragment.hltTriggerType + fragment.hltEnableParking + fragment.HLTL1UnpackerSequence + fragment.HLTBeamSpot ) fragment.HLTPFScoutingPackingSequence = cms.Sequence( fragment.hltScoutingPFPacker + fragment.hltScoutingMuonPacker + fragment.hltScoutingEgammaPacker ) -fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltBoolFalse ) +fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltPSetMap + fragment.hltBoolFalse ) fragment.HLT_AK8PFJet360_TrimMass30_v18 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet360TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet260 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets260 + fragment.hltAK8SinglePFJet360 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) fragment.HLT_AK8PFJet380_TrimMass30_v11 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet380TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet280 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets280 + fragment.hltAK8SinglePFJet380 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) fragment.HLT_AK8PFJet400_TrimMass30_v12 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet400TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet300 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets300 + fragment.hltAK8SinglePFJet400 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) diff --git a/HLTrigger/Configuration/python/HLT_FULL_cff.py b/HLTrigger/Configuration/python/HLT_FULL_cff.py index 17b9538eb2956..af3073780d96a 100644 --- a/HLTrigger/Configuration/python/HLT_FULL_cff.py +++ b/HLTrigger/Configuration/python/HLT_FULL_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/HLT --type FULL -# /dev/CMSSW_11_1_0/HLT/V17 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/HLT/V21 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/HLT/V17') + tableName = cms.string('/dev/CMSSW_11_1_0/HLT/V21') ) fragment.transferSystem = cms.PSet( @@ -7585,11 +7585,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -8044,6 +8045,7 @@ fragment.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +fragment.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) fragment.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -9424,16 +9426,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -34569,6 +34571,7 @@ minMeff = cms.vdouble( 0.0 ) ) fragment.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -34598,6 +34601,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -36267,16 +36271,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersRegL1TauSeededCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -41960,16 +41964,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersRegForTauCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -50010,10 +50014,13 @@ minMht = cms.vdouble( 100.0 ) ) fragment.hltPFMETProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlow" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "hltPFMet" ), - src = cms.InputTag( "hltParticleFlow" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMET100 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -50395,16 +50402,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersRegForBTagCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -51543,6 +51550,7 @@ newQuality = cms.string( "confirmed" ) ) fragment.hltVerticesL3 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -51572,6 +51580,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltMergedTracksForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -51892,10 +51901,13 @@ cut = cms.string( "particleId!=3" ) ) fragment.hltPFMETNoMuProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMetNoMu" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMETNoMu120 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -54672,13 +54684,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtag" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtag" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -68293,10 +68305,13 @@ MaxMass = cms.double( -1.0 ) ) fragment.hltPFMETVBFProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMet" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMETVBF110 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -82280,16 +82295,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCacheAfterSplitting = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -82481,6 +82496,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltPAIter0PrimaryVertices = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -82503,6 +82519,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPAIter0CtfWithMaterialTracks" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -85022,6 +85039,7 @@ etMin = cms.double( 60.0 ) ) fragment.hltVerticesL3PFBjets = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -85051,6 +85069,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -94926,13 +94945,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -95149,13 +95168,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForDBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForDBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -96513,16 +96532,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCacheForHighBeta = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -97955,16 +97974,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCachePPOnAA = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -100304,6 +100323,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPreSplittingPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -100326,6 +100346,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -100636,6 +100657,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -100658,6 +100680,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -102150,6 +102173,7 @@ correctors = cms.VInputTag( 'hltCsAK4PFCorrectorPPOnAA' ) ) fragment.hltVerticesPFPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -102179,6 +102203,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMergingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -107394,6 +107419,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -107416,6 +107442,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -107600,6 +107627,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -107622,6 +107650,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -109843,6 +109872,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -109872,6 +109902,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -110182,6 +110213,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForDmesonNoIter10 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -110211,6 +110243,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmesonNoIter10" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -113310,16 +113343,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltHISiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -113620,16 +113653,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCachePPOnAAForLowPt = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -113795,6 +113828,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -113817,6 +113851,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -113999,6 +114034,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -114021,6 +114057,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -116097,6 +116134,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -116126,6 +116164,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -118989,6 +119028,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -119011,6 +119051,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -119995,6 +120036,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -120024,6 +120066,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -121958,7 +122001,7 @@ fragment.HLTHISinglePixelTrackNpix = cms.Sequence( fragment.HLTHIDoLocalPixelSequence + ~fragment.hltHIPixelCountFilterNpix + fragment.HLTHIRecoPixelTracksSequenceForTrackTrigger + fragment.hltHIPixelCandsForTrackTrigger + fragment.hltHIPixelFilter1 ) fragment.HLTPFScoutingPackingSequence = cms.Sequence( fragment.hltScoutingPFPacker + fragment.hltScoutingMuonPacker + fragment.hltScoutingEgammaPacker ) -fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltBoolFalse ) +fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltPSetMap + fragment.hltBoolFalse ) fragment.HLT_AK8PFJet360_TrimMass30_v18 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet360TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet260 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets260 + fragment.hltAK8SinglePFJet360 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) fragment.HLT_AK8PFJet380_TrimMass30_v11 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet380TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet280 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets280 + fragment.hltAK8SinglePFJet380 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) fragment.HLT_AK8PFJet400_TrimMass30_v12 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet400TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet300 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets300 + fragment.hltAK8SinglePFJet400 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) diff --git a/HLTrigger/Configuration/python/HLT_Fake1_cff.py b/HLTrigger/Configuration/python/HLT_Fake1_cff.py index 02e47840bd1b3..bb43582ec8c25 100644 --- a/HLTrigger/Configuration/python/HLT_Fake1_cff.py +++ b/HLTrigger/Configuration/python/HLT_Fake1_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/Fake1 --type Fake1 -# /dev/CMSSW_11_1_0/Fake1/V6 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/Fake1/V9 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/Fake1/V6') + tableName = cms.string('/dev/CMSSW_11_1_0/Fake1/V9') ) fragment.streams = cms.PSet( A = cms.vstring( 'InitialPD' ) ) diff --git a/HLTrigger/Configuration/python/HLT_Fake2_cff.py b/HLTrigger/Configuration/python/HLT_Fake2_cff.py index 9e4e53f867e04..232de253f5907 100644 --- a/HLTrigger/Configuration/python/HLT_Fake2_cff.py +++ b/HLTrigger/Configuration/python/HLT_Fake2_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/Fake2 --type Fake2 -# /dev/CMSSW_11_1_0/Fake2/V6 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/Fake2/V9 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/Fake2/V6') + tableName = cms.string('/dev/CMSSW_11_1_0/Fake2/V9') ) fragment.streams = cms.PSet( A = cms.vstring( 'InitialPD' ) ) diff --git a/HLTrigger/Configuration/python/HLT_Fake_cff.py b/HLTrigger/Configuration/python/HLT_Fake_cff.py index 6c96f1cfb8e1c..57b0a615e61ad 100644 --- a/HLTrigger/Configuration/python/HLT_Fake_cff.py +++ b/HLTrigger/Configuration/python/HLT_Fake_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/Fake --type Fake -# /dev/CMSSW_11_1_0/Fake/V6 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/Fake/V9 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/Fake/V6') + tableName = cms.string('/dev/CMSSW_11_1_0/Fake/V9') ) fragment.streams = cms.PSet( A = cms.vstring( 'InitialPD' ) ) diff --git a/HLTrigger/Configuration/python/HLT_GRun_cff.py b/HLTrigger/Configuration/python/HLT_GRun_cff.py index 5404fdd120892..30c3632abce26 100644 --- a/HLTrigger/Configuration/python/HLT_GRun_cff.py +++ b/HLTrigger/Configuration/python/HLT_GRun_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/GRun --type GRun -# /dev/CMSSW_11_1_0/GRun/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/GRun/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/GRun/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/GRun/V11') ) fragment.transferSystem = cms.PSet( @@ -6268,11 +6268,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -6727,6 +6728,7 @@ fragment.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +fragment.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) fragment.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -8107,16 +8109,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -33204,6 +33206,7 @@ minMeff = cms.vdouble( 0.0 ) ) fragment.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -33233,6 +33236,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -34878,16 +34882,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersRegL1TauSeededCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -40571,16 +40575,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersRegForTauCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -48237,10 +48241,13 @@ minMht = cms.vdouble( 100.0 ) ) fragment.hltPFMETProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlow" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "hltPFMet" ), - src = cms.InputTag( "hltParticleFlow" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMET100 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -48622,16 +48629,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersRegForBTagCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -49770,6 +49777,7 @@ newQuality = cms.string( "confirmed" ) ) fragment.hltVerticesL3 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -49799,6 +49807,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltMergedTracksForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -50119,10 +50128,13 @@ cut = cms.string( "particleId!=3" ) ) fragment.hltPFMETNoMuProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMetNoMu" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMETNoMu120 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -52899,13 +52911,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtag" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtag" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -66017,10 +66029,13 @@ MaxMass = cms.double( -1.0 ) ) fragment.hltPFMETVBFProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMet" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) fragment.hltPFMETVBF110 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -85615,13 +85630,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -85838,13 +85853,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForDBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForDBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -87829,7 +87844,7 @@ fragment.HLTBeginSequenceParking = cms.Sequence( fragment.hltTriggerType + fragment.hltEnableParking + fragment.HLTL1UnpackerSequence + fragment.HLTBeamSpot ) fragment.HLTPFScoutingPackingSequence = cms.Sequence( fragment.hltScoutingPFPacker + fragment.hltScoutingMuonPacker + fragment.hltScoutingEgammaPacker ) -fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltBoolFalse ) +fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltPSetMap + fragment.hltBoolFalse ) fragment.HLT_AK8PFJet360_TrimMass30_v18 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet360TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet260 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets260 + fragment.hltAK8SinglePFJet360 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) fragment.HLT_AK8PFJet380_TrimMass30_v11 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet380TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet280 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets280 + fragment.hltAK8SinglePFJet380 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) fragment.HLT_AK8PFJet400_TrimMass30_v12 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sSingleJet180 + fragment.hltPreAK8PFJet400TrimMass30 + fragment.HLTAK8CaloJetsSequence + fragment.hltAK8SingleCaloJet300 + fragment.HLTAK8PFJetsSequence + fragment.hltAK8PFJetsCorrectedMatchedToCaloJets300 + fragment.hltAK8SinglePFJet400 + fragment.hltAK8TrimModJets + fragment.hltAK8SinglePFJetTrimModMass30 + fragment.HLTEndSequence ) diff --git a/HLTrigger/Configuration/python/HLT_HIon_cff.py b/HLTrigger/Configuration/python/HLT_HIon_cff.py index 1a3225295d92b..2a8db575a0dfc 100644 --- a/HLTrigger/Configuration/python/HLT_HIon_cff.py +++ b/HLTrigger/Configuration/python/HLT_HIon_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/HIon --type HIon -# /dev/CMSSW_11_1_0/HIon/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/HIon/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/HIon/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/HIon/V11') ) fragment.transferSystem = cms.PSet( @@ -5393,11 +5393,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -5852,6 +5853,7 @@ fragment.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +fragment.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) fragment.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -7819,16 +7821,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCachePPOnAA = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -10182,6 +10184,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPreSplittingPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -10204,6 +10207,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -10525,6 +10529,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -10547,6 +10552,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -12558,6 +12564,7 @@ correctors = cms.VInputTag( 'hltCsAK4PFCorrectorPPOnAA' ) ) fragment.hltVerticesPFPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -12587,6 +12594,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMergingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -17874,6 +17882,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -17896,6 +17905,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -18080,6 +18090,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -18102,6 +18113,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -20323,6 +20335,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -20352,6 +20365,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -20662,6 +20676,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForDmesonNoIter10 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -20691,6 +20706,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmesonNoIter10" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -23801,16 +23817,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltHISiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -24111,16 +24127,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCachePPOnAAForLowPt = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -24286,6 +24302,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -24308,6 +24325,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -24490,6 +24508,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -24512,6 +24531,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -26588,6 +26608,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -26617,6 +26638,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -29502,6 +29524,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) fragment.hltFullIter0PrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -29524,6 +29547,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -30508,6 +30532,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) fragment.hltFullOnlinePrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -30537,6 +30562,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -31703,7 +31729,7 @@ fragment.HLTBtagCSVv2SequenceL3ForHIBJet100 = cms.Sequence( fragment.HLTTrackReconstructionForBTagForHI + fragment.hltFullOnlinePrimaryVerticesPPOnAAForBTag + fragment.hltFastPixelBLifetimeL3AssociatorHIBJet100 + fragment.hltImpactParameterTagInfosHIBJet100 + fragment.hltInclusiveVertexFinderPPOnAA + fragment.hltInclusiveSecondaryVerticesPPOnAA + fragment.hltTrackVertexArbitratorPPOnAA + fragment.hltInclusiveMergedVerticesPPOnAA + fragment.hltInclusiveSecondaryVertexFinderTagInfosHIBJet100 + fragment.hltCombinedSecondaryVertexV2BJetTagsCaloBJet100 ) fragment.HLTHISinglePixelTrackNpix = cms.Sequence( fragment.HLTHIDoLocalPixelSequence + ~fragment.hltHIPixelCountFilterNpix + fragment.HLTHIRecoPixelTracksSequenceForTrackTrigger + fragment.hltHIPixelCandsForTrackTrigger + fragment.hltHIPixelFilter1 ) -fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltBoolFalse ) +fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltPSetMap + fragment.hltBoolFalse ) fragment.DST_Physics_v7 = cms.Path( fragment.HLTBeginSequence + fragment.hltPreDSTPhysics + fragment.HLTEndSequence ) fragment.HLT_EcalCalibration_v4 = cms.Path( fragment.HLTBeginSequenceCalibration + fragment.hltPreEcalCalibration + fragment.hltEcalCalibrationRaw + fragment.HLTEndSequence ) fragment.HLT_HcalCalibration_v5 = cms.Path( fragment.HLTBeginSequenceCalibration + fragment.hltPreHcalCalibration + fragment.hltHcalCalibTypeFilter + fragment.hltHcalCalibrationRaw + fragment.HLTEndSequence ) diff --git a/HLTrigger/Configuration/python/HLT_PIon_cff.py b/HLTrigger/Configuration/python/HLT_PIon_cff.py index f0959325797bc..7ce481fdcebc8 100644 --- a/HLTrigger/Configuration/python/HLT_PIon_cff.py +++ b/HLTrigger/Configuration/python/HLT_PIon_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/PIon --type PIon -# /dev/CMSSW_11_1_0/PIon/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/PIon/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/PIon/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/PIon/V11') ) fragment.transferSystem = cms.PSet( @@ -4864,11 +4864,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -5323,6 +5324,7 @@ fragment.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +fragment.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) fragment.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -5463,7 +5465,7 @@ fragment.HLTBeginSequenceRandom = cms.Sequence( fragment.hltRandomEventsFilter + fragment.hltGtStage2Digis ) fragment.HLTBeginSequence = cms.Sequence( fragment.hltTriggerType + fragment.HLTL1UnpackerSequence + fragment.HLTBeamSpot ) -fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltBoolFalse ) +fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltPSetMap + fragment.hltBoolFalse ) fragment.HLT_Physics_v7 = cms.Path( fragment.HLTBeginSequenceL1Fat + fragment.hltPrePhysics + fragment.HLTEndSequence ) fragment.HLT_Random_v3 = cms.Path( fragment.HLTBeginSequenceRandom + fragment.hltPreRandom + fragment.HLTEndSequence ) fragment.HLT_ZeroBias_v6 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sZeroBias + fragment.hltPreZeroBias + fragment.HLTEndSequence ) diff --git a/HLTrigger/Configuration/python/HLT_PRef_cff.py b/HLTrigger/Configuration/python/HLT_PRef_cff.py index f25b39fe4e09b..de117cc0dbb98 100644 --- a/HLTrigger/Configuration/python/HLT_PRef_cff.py +++ b/HLTrigger/Configuration/python/HLT_PRef_cff.py @@ -1,13 +1,13 @@ # hltGetConfiguration --cff --data /dev/CMSSW_11_1_0/PRef --type PRef -# /dev/CMSSW_11_1_0/PRef/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/PRef/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms fragment = cms.ProcessFragment( "HLT" ) fragment.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/PRef/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/PRef/V11') ) fragment.transferSystem = cms.PSet( @@ -4942,11 +4942,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -5401,6 +5402,7 @@ fragment.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +fragment.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) fragment.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -6548,16 +6550,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) fragment.hltSiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -9832,6 +9834,7 @@ newQuality = cms.string( "confirmed" ) ) fragment.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -9861,6 +9864,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -10846,7 +10850,7 @@ fragment.HLTDoFullUnpackingEgammaEcalSequence = cms.Sequence( fragment.hltEcalDigis + fragment.hltEcalPreshowerDigis + fragment.hltEcalUncalibRecHit + fragment.hltEcalDetIdToBeRecovered + fragment.hltEcalRecHit + fragment.hltEcalPreshowerRecHit ) fragment.HLTBeginSequenceCalibration = cms.Sequence( fragment.hltCalibrationEventsFilter + fragment.hltGtStage2Digis ) -fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltBoolFalse ) +fragment.HLTriggerFirstPath = cms.Path( fragment.hltGetConditions + fragment.hltGetRaw + fragment.hltPSetMap + fragment.hltBoolFalse ) fragment.HLT_ZeroBias_Beamspot_v4 = cms.Path( fragment.HLTBeginSequence + fragment.hltL1sZeroBias + fragment.hltPreZeroBiasBeamspot + fragment.HLTTrackingForBeamSpot + fragment.hltVerticesPF + fragment.hltVerticesPFSelector + fragment.hltVerticesPFFilter + fragment.HLTEndSequence ) fragment.HLT_Physics_v7 = cms.Path( fragment.HLTBeginSequenceL1Fat + fragment.hltPrePhysics + fragment.HLTEndSequence ) fragment.DST_Physics_v7 = cms.Path( fragment.HLTBeginSequence + fragment.hltPreDSTPhysics + fragment.HLTEndSequence ) diff --git a/HLTrigger/Configuration/python/customizeHLTforCMSSW.py b/HLTrigger/Configuration/python/customizeHLTforCMSSW.py index 81f6bad8e77cf..179ea9a5a8760 100644 --- a/HLTrigger/Configuration/python/customizeHLTforCMSSW.py +++ b/HLTrigger/Configuration/python/customizeHLTforCMSSW.py @@ -170,6 +170,36 @@ def customiseFor2017DtUnpacking(process): return process +def customisePixelGainForRun2Input(process): + """Customise the HLT to run on Run 2 data/MC using the old definition of the pixel calibrations + Up to 11.0.x, the pixel calibarations were fully specified in the configuration: + VCaltoElectronGain = 47 + VCaltoElectronGain_L1 = 50 + VCaltoElectronOffset = -60 + VCaltoElectronOffset_L1 = -670 + Starting with 11.1.x, the calibrations for Run 3 were moved to the conditions, leaving in the configuration only: + VCaltoElectronGain = 1 + VCaltoElectronGain_L1 = 1 + VCaltoElectronOffset = 0 + VCaltoElectronOffset_L1 = 0 + Since the conditions for Run 2 have not been updated to the new scheme, the HLT configuration needs to be reverted. + """ + # revert the Pixel parameters to be compatible with the Run 2 conditions + for producer in producers_by_type(process, "SiPixelClusterProducer"): + producer.VCaltoElectronGain = 47 + producer.VCaltoElectronGain_L1 = 50 + producer.VCaltoElectronOffset = -60 + producer.VCaltoElectronOffset_L1 = -670 + + return process + + +def customiseFor2018Input(process): + """Customise the HLT to run on Run 2 data/MC""" + process = customisePixelGainForRun2Input(process) + process = synchronizeHCALHLTofflineRun3on2018data(process) + + # CMSSW version specific customizations def customizeHLTforCMSSW(process, menuType="GRun"): diff --git a/HLTrigger/Configuration/test/OnLine_HLT_2018.py b/HLTrigger/Configuration/test/OnLine_HLT_2018.py index 9214a4a6dbe50..e25f3198efee0 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_2018.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_2018.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /frozen/2018/111X/HLT --type 2018 --unprescale --process HLT2018 --globaltag auto:run2_hlt_2018 --input file:RelVal_Raw_2018_DATA.root -# /frozen/2018/111X/HLT/V11 (CMSSW_11_1_0_pre7) +# /frozen/2018/111X/HLT/V16 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLT2018" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/frozen/2018/111X/HLT/V11') + tableName = cms.string('/frozen/2018/111X/HLT/V16') ) process.transferSystem = cms.PSet( @@ -6441,11 +6441,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -7042,6 +7043,7 @@ process.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +process.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) process.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -33643,6 +33645,7 @@ minMeff = cms.vdouble( 0.0 ) ) process.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -33672,6 +33675,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -49011,10 +49015,13 @@ minMht = cms.vdouble( 100.0 ) ) process.hltPFMETProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlow" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "hltPFMet" ), - src = cms.InputTag( "hltParticleFlow" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMET100 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -50616,6 +50623,7 @@ newQuality = cms.string( "confirmed" ) ) process.hltVerticesL3 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -50645,6 +50653,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltMergedTracksForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -50965,10 +50974,13 @@ cut = cms.string( "particleId!=3" ) ) process.hltPFMETNoMuProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMetNoMu" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMETNoMu120 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -53799,13 +53811,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtag" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtag" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -66996,10 +67008,13 @@ MaxMass = cms.double( -1.0 ) ) process.hltPFMETVBFProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMet" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMETVBF110 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -87086,13 +87101,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -87309,13 +87324,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForDBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForDBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -92059,7 +92074,7 @@ process.HLTBeginSequenceParking = cms.Sequence( process.hltTriggerType + process.hltEnableParking + process.HLTL1UnpackerSequence + process.HLTBeamSpot ) process.HLTPFScoutingPackingSequence = cms.Sequence( process.hltScoutingPFPacker + process.hltScoutingMuonPacker + process.hltScoutingEgammaPacker ) -process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltBoolFalse ) +process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltPSetMap + process.hltBoolFalse ) process.HLT_AK8PFJet360_TrimMass30_v18 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet360TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet260 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets260 + process.hltAK8SinglePFJet360 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) process.HLT_AK8PFJet380_TrimMass30_v11 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet380TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet280 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets280 + process.hltAK8SinglePFJet380 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) process.HLT_AK8PFJet400_TrimMass30_v12 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet400TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet300 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets300 + process.hltAK8SinglePFJet400 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) @@ -92815,7 +92830,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_FULL.py b/HLTrigger/Configuration/test/OnLine_HLT_FULL.py index ec6afc593acbc..c8e2ba9c1560f 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_FULL.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_FULL.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/HLT --type FULL --unprescale --process HLTFULL --globaltag auto:run3_hlt_FULL --input file:RelVal_Raw_FULL_DATA.root -# /dev/CMSSW_11_1_0/HLT/V17 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/HLT/V21 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTFULL" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/HLT/V17') + tableName = cms.string('/dev/CMSSW_11_1_0/HLT/V21') ) process.transferSystem = cms.PSet( @@ -7746,11 +7746,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -8347,6 +8348,7 @@ process.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +process.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) process.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -9727,16 +9729,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -34872,6 +34874,7 @@ minMeff = cms.vdouble( 0.0 ) ) process.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -34901,6 +34904,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -36570,16 +36574,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersRegL1TauSeededCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -42263,16 +42267,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersRegForTauCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -50313,10 +50317,13 @@ minMht = cms.vdouble( 100.0 ) ) process.hltPFMETProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlow" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "hltPFMet" ), - src = cms.InputTag( "hltParticleFlow" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMET100 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -50698,16 +50705,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersRegForBTagCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -51846,6 +51853,7 @@ newQuality = cms.string( "confirmed" ) ) process.hltVerticesL3 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -51875,6 +51883,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltMergedTracksForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -52195,10 +52204,13 @@ cut = cms.string( "particleId!=3" ) ) process.hltPFMETNoMuProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMetNoMu" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMETNoMu120 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -54975,13 +54987,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtag" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtag" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -68596,10 +68608,13 @@ MaxMass = cms.double( -1.0 ) ) process.hltPFMETVBFProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMet" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMETVBF110 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -82583,16 +82598,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCacheAfterSplitting = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -82784,6 +82799,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltPAIter0PrimaryVertices = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -82806,6 +82822,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPAIter0CtfWithMaterialTracks" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -85325,6 +85342,7 @@ etMin = cms.double( 60.0 ) ) process.hltVerticesL3PFBjets = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -85354,6 +85372,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -95229,13 +95248,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -95452,13 +95471,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForDBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForDBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -96816,16 +96835,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCacheForHighBeta = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -98258,16 +98277,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCachePPOnAA = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -100607,6 +100626,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPreSplittingPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -100629,6 +100649,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -100939,6 +100960,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -100961,6 +100983,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -102453,6 +102476,7 @@ correctors = cms.VInputTag( 'hltCsAK4PFCorrectorPPOnAA' ) ) process.hltVerticesPFPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -102482,6 +102506,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMergingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -107697,6 +107722,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -107719,6 +107745,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -107903,6 +107930,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -107925,6 +107953,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -110146,6 +110175,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -110175,6 +110205,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -110485,6 +110516,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForDmesonNoIter10 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -110514,6 +110546,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmesonNoIter10" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -113613,16 +113646,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltHISiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -113923,16 +113956,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCachePPOnAAForLowPt = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -114098,6 +114131,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -114120,6 +114154,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -114302,6 +114337,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -114324,6 +114360,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -116400,6 +116437,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -116429,6 +116467,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -119292,6 +119331,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -119314,6 +119354,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -120298,6 +120339,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -120327,6 +120369,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -128683,7 +128726,7 @@ process.HLTHISinglePixelTrackNpix = cms.Sequence( process.HLTHIDoLocalPixelSequence + ~process.hltHIPixelCountFilterNpix + process.HLTHIRecoPixelTracksSequenceForTrackTrigger + process.hltHIPixelCandsForTrackTrigger + process.hltHIPixelFilter1 ) process.HLTPFScoutingPackingSequence = cms.Sequence( process.hltScoutingPFPacker + process.hltScoutingMuonPacker + process.hltScoutingEgammaPacker ) -process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltBoolFalse ) +process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltPSetMap + process.hltBoolFalse ) process.HLT_AK8PFJet360_TrimMass30_v18 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet360TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet260 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets260 + process.hltAK8SinglePFJet360 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) process.HLT_AK8PFJet380_TrimMass30_v11 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet380TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet280 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets280 + process.hltAK8SinglePFJet380 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) process.HLT_AK8PFJet400_TrimMass30_v12 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet400TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet300 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets300 + process.hltAK8SinglePFJet400 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) @@ -130229,7 +130272,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_Fake.py b/HLTrigger/Configuration/test/OnLine_HLT_Fake.py index eb656841f0c76..a707304852f77 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_Fake.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_Fake.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/Fake --type Fake --unprescale --process HLTFake --globaltag auto:run1_hlt_Fake --input file:RelVal_Raw_Fake_DATA.root -# /dev/CMSSW_11_1_0/Fake/V6 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/Fake/V9 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTFake" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/Fake/V6') + tableName = cms.string('/dev/CMSSW_11_1_0/Fake/V9') ) process.streams = cms.PSet( A = cms.vstring( 'InitialPD' ) ) @@ -371,7 +371,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_Fake1.py b/HLTrigger/Configuration/test/OnLine_HLT_Fake1.py index 16ac8aa66b165..28a001af852b2 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_Fake1.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_Fake1.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/Fake1 --type Fake1 --unprescale --process HLTFake1 --globaltag auto:run2_hlt_Fake1 --input file:RelVal_Raw_Fake1_DATA.root -# /dev/CMSSW_11_1_0/Fake1/V6 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/Fake1/V9 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTFake1" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/Fake1/V6') + tableName = cms.string('/dev/CMSSW_11_1_0/Fake1/V9') ) process.streams = cms.PSet( A = cms.vstring( 'InitialPD' ) ) @@ -388,7 +388,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_Fake2.py b/HLTrigger/Configuration/test/OnLine_HLT_Fake2.py index de525b4c25b84..6c9d0f2a0f992 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_Fake2.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_Fake2.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/Fake2 --type Fake2 --unprescale --process HLTFake2 --globaltag auto:run2_hlt_Fake2 --input file:RelVal_Raw_Fake2_DATA.root -# /dev/CMSSW_11_1_0/Fake2/V6 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/Fake2/V9 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTFake2" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/Fake2/V6') + tableName = cms.string('/dev/CMSSW_11_1_0/Fake2/V9') ) process.streams = cms.PSet( A = cms.vstring( 'InitialPD' ) ) @@ -395,7 +395,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_GRun.py b/HLTrigger/Configuration/test/OnLine_HLT_GRun.py index bbf4d97579bfe..216935add8491 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_GRun.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_GRun.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/GRun --type GRun --unprescale --process HLTGRun --globaltag auto:run3_hlt_GRun --input file:RelVal_Raw_GRun_DATA.root -# /dev/CMSSW_11_1_0/GRun/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/GRun/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTGRun" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/GRun/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/GRun/V11') ) process.transferSystem = cms.PSet( @@ -6429,11 +6429,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -7030,6 +7031,7 @@ process.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +process.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) process.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -8410,16 +8412,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -33507,6 +33509,7 @@ minMeff = cms.vdouble( 0.0 ) ) process.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -33536,6 +33539,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -35181,16 +35185,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersRegL1TauSeededCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -40874,16 +40878,16 @@ maxNumberOfClusters = cms.int32( 20000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersRegForTauCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -48540,10 +48544,13 @@ minMht = cms.vdouble( 100.0 ) ) process.hltPFMETProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlow" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "hltPFMet" ), - src = cms.InputTag( "hltParticleFlow" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMET100 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -48925,16 +48932,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersRegForBTagCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -50073,6 +50080,7 @@ newQuality = cms.string( "confirmed" ) ) process.hltVerticesL3 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -50102,6 +50110,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltMergedTracksForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -50422,10 +50431,13 @@ cut = cms.string( "particleId!=3" ) ) process.hltPFMETNoMuProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMetNoMu" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMETNoMu120 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -53202,13 +53214,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtag" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtag" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -66320,10 +66332,13 @@ MaxMass = cms.double( -1.0 ) ) process.hltPFMETVBFProducer = cms.EDProducer( "PFMETProducer", - globalThreshold = cms.double( 0.0 ), + src = cms.InputTag( "hltParticleFlowNoMu" ), + parameters = cms.PSet( ), + applyWeight = cms.bool( False ), calculateSignificance = cms.bool( False ), alias = cms.string( "pfMet" ), - src = cms.InputTag( "hltParticleFlowNoMu" ) + srcWeights = cms.InputTag( "" ), + globalThreshold = cms.double( 0.0 ) ) process.hltPFMETVBF110 = cms.EDFilter( "HLT1PFMET", saveTags = cms.bool( True ), @@ -85918,13 +85933,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -86141,13 +86156,13 @@ minimumTransverseMomentum = cms.double( 1.0 ), primaryVertex = cms.InputTag( "hltVerticesPFFilter" ), maximumLongitudinalImpactParameter = cms.double( 17.0 ), - computeGhostTrack = cms.bool( True ), + jets = cms.InputTag( "hltPFJetForDBtagAK8" ), maxDeltaR = cms.double( 0.4 ), candidates = cms.InputTag( "hltParticleFlow" ), jetDirectionUsingGhostTrack = cms.bool( False ), minimumNumberOfPixelHits = cms.int32( 2 ), jetDirectionUsingTracks = cms.bool( False ), - jets = cms.InputTag( "hltPFJetForDBtagAK8" ), + computeGhostTrack = cms.bool( True ), useTrackQuality = cms.bool( False ), ghostTrackPriorDeltaR = cms.double( 0.03 ), maximumChiSquared = cms.double( 5.0 ), @@ -90860,7 +90875,7 @@ process.HLTBeginSequenceParking = cms.Sequence( process.hltTriggerType + process.hltEnableParking + process.HLTL1UnpackerSequence + process.HLTBeamSpot ) process.HLTPFScoutingPackingSequence = cms.Sequence( process.hltScoutingPFPacker + process.hltScoutingMuonPacker + process.hltScoutingEgammaPacker ) -process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltBoolFalse ) +process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltPSetMap + process.hltBoolFalse ) process.HLT_AK8PFJet360_TrimMass30_v18 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet360TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet260 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets260 + process.hltAK8SinglePFJet360 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) process.HLT_AK8PFJet380_TrimMass30_v11 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet380TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet280 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets280 + process.hltAK8SinglePFJet380 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) process.HLT_AK8PFJet400_TrimMass30_v12 = cms.Path( process.HLTBeginSequence + process.hltL1sSingleJet180 + process.hltPreAK8PFJet400TrimMass30 + process.HLTAK8CaloJetsSequence + process.hltAK8SingleCaloJet300 + process.HLTAK8PFJetsSequence + process.hltAK8PFJetsCorrectedMatchedToCaloJets300 + process.hltAK8SinglePFJet400 + process.hltAK8TrimModJets + process.hltAK8SinglePFJetTrimModMass30 + process.HLTEndSequence ) @@ -91610,7 +91625,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_HIon.py b/HLTrigger/Configuration/test/OnLine_HLT_HIon.py index 3f48f55eadcaf..ad02d1f574a6c 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_HIon.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_HIon.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/HIon --type HIon --unprescale --process HLTHIon --globaltag auto:run3_hlt_HIon --input file:RelVal_Raw_HIon_DATA.root -# /dev/CMSSW_11_1_0/HIon/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/HIon/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTHIon" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/HIon/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/HIon/V11') ) process.transferSystem = cms.PSet( @@ -5554,11 +5554,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -6155,6 +6156,7 @@ process.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataRepacker" ) ) +process.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) process.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -8122,16 +8124,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCachePPOnAA = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -10485,6 +10487,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPreSplittingPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -10507,6 +10510,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -10828,6 +10832,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -10850,6 +10855,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -12861,6 +12867,7 @@ correctors = cms.VInputTag( 'hltCsAK4PFCorrectorPPOnAA' ) ) process.hltVerticesPFPPOnAA = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -12890,6 +12897,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMergingPPOnAA" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -18177,6 +18185,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -18199,6 +18208,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -18383,6 +18393,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -18405,6 +18416,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -20626,6 +20638,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForDmeson = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -20655,6 +20668,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmeson" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -20965,6 +20979,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForDmesonNoIter10 = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -20994,6 +21009,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForDmesonNoIter10" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -24104,16 +24120,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltHISiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -24414,16 +24430,16 @@ maxNumberOfClusters = cms.int32( -1 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "Offline" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCachePPOnAAForLowPt = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -24589,6 +24605,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPreSplittingPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -24611,6 +24628,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPreSplittingPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -24793,6 +24811,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -24815,6 +24834,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -26891,6 +26911,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForLowPt = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -26920,6 +26941,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForLowPt" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -29805,6 +29827,7 @@ Propagator = cms.string( "hltESPRungeKuttaTrackerPropagator" ) ) process.hltFullIter0PrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -29827,6 +29850,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIter0CtfWithMaterialTracksPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -30811,6 +30835,7 @@ trackAlgoPriorityOrder = cms.string( "hltESPTrackAlgoPriorityOrder" ) ) process.hltFullOnlinePrimaryVerticesPPOnAAForBTag = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 2.5 ), label = cms.string( "" ), @@ -30840,6 +30865,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltFullIterativeTrackingMergedPPOnAAForBTag" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( algorithm = cms.string( "gap" ), TkGapClusParameters = cms.PSet( zSeparation = cms.double( 1.0 ) ) @@ -33594,7 +33620,7 @@ process.HLTBtagCSVv2SequenceL3ForHIBJet100 = cms.Sequence( process.HLTTrackReconstructionForBTagForHI + process.hltFullOnlinePrimaryVerticesPPOnAAForBTag + process.hltFastPixelBLifetimeL3AssociatorHIBJet100 + process.hltImpactParameterTagInfosHIBJet100 + process.hltInclusiveVertexFinderPPOnAA + process.hltInclusiveSecondaryVerticesPPOnAA + process.hltTrackVertexArbitratorPPOnAA + process.hltInclusiveMergedVerticesPPOnAA + process.hltInclusiveSecondaryVertexFinderTagInfosHIBJet100 + process.hltCombinedSecondaryVertexV2BJetTagsCaloBJet100 ) process.HLTHISinglePixelTrackNpix = cms.Sequence( process.HLTHIDoLocalPixelSequence + ~process.hltHIPixelCountFilterNpix + process.HLTHIRecoPixelTracksSequenceForTrackTrigger + process.hltHIPixelCandsForTrackTrigger + process.hltHIPixelFilter1 ) -process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltBoolFalse ) +process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltPSetMap + process.hltBoolFalse ) process.DST_Physics_v7 = cms.Path( process.HLTBeginSequence + process.hltPreDSTPhysics + process.HLTEndSequence ) process.HLT_EcalCalibration_v4 = cms.Path( process.HLTBeginSequenceCalibration + process.hltPreEcalCalibration + process.hltEcalCalibrationRaw + process.HLTEndSequence ) process.HLT_HcalCalibration_v5 = cms.Path( process.HLTBeginSequenceCalibration + process.hltPreHcalCalibration + process.hltHcalCalibTypeFilter + process.hltHcalCalibrationRaw + process.HLTEndSequence ) @@ -34120,7 +34146,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_PIon.py b/HLTrigger/Configuration/test/OnLine_HLT_PIon.py index 70f8154110ff3..0b89f072818d1 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_PIon.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_PIon.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/PIon --type PIon --unprescale --process HLTPIon --globaltag auto:run3_hlt_PIon --input file:RelVal_Raw_PIon_DATA.root -# /dev/CMSSW_11_1_0/PIon/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/PIon/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTPIon" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/PIon/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/PIon/V11') ) process.transferSystem = cms.PSet( @@ -5025,11 +5025,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -5626,6 +5627,7 @@ process.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +process.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) process.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -5843,7 +5845,7 @@ process.HLTBeginSequenceRandom = cms.Sequence( process.hltRandomEventsFilter + process.hltGtStage2Digis ) process.HLTBeginSequence = cms.Sequence( process.hltTriggerType + process.HLTL1UnpackerSequence + process.HLTBeamSpot ) -process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltBoolFalse ) +process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltPSetMap + process.hltBoolFalse ) process.HLT_Physics_v7 = cms.Path( process.HLTBeginSequenceL1Fat + process.hltPrePhysics + process.HLTEndSequence ) process.HLT_Random_v3 = cms.Path( process.HLTBeginSequenceRandom + process.hltPreRandom + process.HLTEndSequence ) process.HLT_ZeroBias_v6 = cms.Path( process.HLTBeginSequence + process.hltL1sZeroBias + process.hltPreZeroBias + process.HLTEndSequence ) @@ -5853,7 +5855,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/OnLine_HLT_PRef.py b/HLTrigger/Configuration/test/OnLine_HLT_PRef.py index a364435b9e4f5..052e86752898f 100644 --- a/HLTrigger/Configuration/test/OnLine_HLT_PRef.py +++ b/HLTrigger/Configuration/test/OnLine_HLT_PRef.py @@ -1,13 +1,13 @@ # hltGetConfiguration --full --data /dev/CMSSW_11_1_0/PRef --type PRef --unprescale --process HLTPRef --globaltag auto:run3_hlt_PRef --input file:RelVal_Raw_PRef_DATA.root -# /dev/CMSSW_11_1_0/PRef/V8 (CMSSW_11_1_0_pre7) +# /dev/CMSSW_11_1_0/PRef/V11 (CMSSW_11_1_0) import FWCore.ParameterSet.Config as cms process = cms.Process( "HLTPRef" ) process.HLTConfigVersion = cms.PSet( - tableName = cms.string('/dev/CMSSW_11_1_0/PRef/V8') + tableName = cms.string('/dev/CMSSW_11_1_0/PRef/V11') ) process.transferSystem = cms.PSet( @@ -5103,11 +5103,12 @@ ClusterProbComputationFlag = cms.int32( 0 ), Alpha2Order = cms.bool( True ), appendToDataLabel = cms.string( "" ), - EdgeClusterErrorY = cms.double( 85.0 ), + lAWidthFPix = cms.double( 0.0 ), SmallPitch = cms.bool( False ), LoadTemplatesFromDB = cms.bool( True ), + NoTemplateErrorsWhenNoTrkAngles = cms.bool( False ), EdgeClusterErrorX = cms.double( 50.0 ), - lAWidthFPix = cms.double( 0.0 ), + EdgeClusterErrorY = cms.double( 85.0 ), lAOffset = cms.double( 0.0 ), ComponentName = cms.string( "hltESPPixelCPEGeneric" ), MagneticFieldRecord = cms.ESInputTag( "" ), @@ -5704,6 +5705,7 @@ process.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw", RawDataCollection = cms.InputTag( "rawDataCollector" ) ) +process.hltPSetMap = cms.EDProducer( "ParameterSetBlobProducer" ) process.hltBoolFalse = cms.EDFilter( "HLTBool", result = cms.bool( False ) ) @@ -6851,16 +6853,16 @@ maxNumberOfClusters = cms.int32( 40000 ), ClusterThreshold_L1 = cms.int32( 2000 ), MissCalibrate = cms.bool( True ), - VCaltoElectronGain = cms.int32( 47 ), - VCaltoElectronGain_L1 = cms.int32( 50 ), - VCaltoElectronOffset = cms.int32( -60 ), + VCaltoElectronGain = cms.int32( 1 ), + VCaltoElectronGain_L1 = cms.int32( 1 ), + VCaltoElectronOffset = cms.int32( 0 ), SplitClusters = cms.bool( False ), payloadType = cms.string( "HLT" ), Phase2Calibration = cms.bool( False ), Phase2KinkADC = cms.int32( 8 ), ClusterMode = cms.string( "PixelThresholdClusterizer" ), SeedThreshold = cms.int32( 1000 ), - VCaltoElectronOffset_L1 = cms.int32( -670 ), + VCaltoElectronOffset_L1 = cms.int32( 0 ), ClusterThreshold = cms.int32( 4000 ) ) process.hltSiPixelClustersCache = cms.EDProducer( "SiPixelClusterShapeCacheProducer", @@ -10135,6 +10137,7 @@ newQuality = cms.string( "confirmed" ) ) process.hltVerticesPF = cms.EDProducer( "PrimaryVertexProducer", + TrackTimesLabel = cms.InputTag( "dummy_default" ), vertexCollections = cms.VPSet( cms.PSet( chi2cutoff = cms.double( 3.0 ), label = cms.string( "" ), @@ -10164,6 +10167,7 @@ ), beamSpotLabel = cms.InputTag( "hltOnlineBeamSpot" ), TrackLabel = cms.InputTag( "hltPFMuonMerging" ), + TrackTimeResosLabel = cms.InputTag( "dummy_default" ), TkClusParameters = cms.PSet( TkDAClusParameters = cms.PSet( zmerge = cms.double( 0.01 ), @@ -11697,7 +11701,7 @@ process.HLTDoFullUnpackingEgammaEcalSequence = cms.Sequence( process.hltEcalDigis + process.hltEcalPreshowerDigis + process.hltEcalUncalibRecHit + process.hltEcalDetIdToBeRecovered + process.hltEcalRecHit + process.hltEcalPreshowerRecHit ) process.HLTBeginSequenceCalibration = cms.Sequence( process.hltCalibrationEventsFilter + process.hltGtStage2Digis ) -process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltBoolFalse ) +process.HLTriggerFirstPath = cms.Path( process.hltGetConditions + process.hltGetRaw + process.hltPSetMap + process.hltBoolFalse ) process.HLT_ZeroBias_Beamspot_v4 = cms.Path( process.HLTBeginSequence + process.hltL1sZeroBias + process.hltPreZeroBiasBeamspot + process.HLTTrackingForBeamSpot + process.hltVerticesPF + process.hltVerticesPFSelector + process.hltVerticesPFFilter + process.HLTEndSequence ) process.HLT_Physics_v7 = cms.Path( process.HLTBeginSequenceL1Fat + process.hltPrePhysics + process.HLTEndSequence ) process.DST_Physics_v7 = cms.Path( process.HLTBeginSequence + process.hltPreDSTPhysics + process.HLTEndSequence ) @@ -11742,7 +11746,6 @@ # load the DQMStore and DQMRootOutputModule process.load( "DQMServices.Core.DQMStore_cfi" ) -process.DQMStore.enableMultiThread = True process.dqmOutput = cms.OutputModule("DQMRootOutputModule", fileName = cms.untracked.string("DQMIO.root") diff --git a/HLTrigger/Configuration/test/cmsDriver.csh b/HLTrigger/Configuration/test/cmsDriver.csh index 51e51e8259c92..5f2db58a20ec2 100755 --- a/HLTrigger/Configuration/test/cmsDriver.csh +++ b/HLTrigger/Configuration/test/cmsDriver.csh @@ -33,7 +33,7 @@ set InputGenSimPRef3 = $InputGenSimGRun3 set InputLHCRawGRun0 = root://eoscms.cern.ch//eos/cms/store/data/Run2012A/MuEG/RAW/v1/000/191/718/14932935-E289-E111-830C-5404A6388697.root set InputLHCRawGRun1 = root://eoscms.cern.ch//eos/cms/store/data/Run2015D/MuonEG/RAW/v1/000/256/677/00000/80950A90-745D-E511-92FD-02163E011C5D.root set InputLHCRawGRun2 = root://eoscms.cern.ch//eos/cms/store/data/Run2016B/JetHT/RAW/v1/000/272/762/00000/C666CDE2-E013-E611-B15A-02163E011DBE.root -set InputLHCRawGRun3 = root://eoscms.cern.ch//eos/cms/store/data/Run2017A/HLTPhysics4/RAW/v1/000/295/606/00000/36DE5E0A-3645-E711-8FA1-02163E01A43B.root +set InputLHCRawGRun3 = root://eoscms.cern.ch//eos/cms/store/data/Run2018D/EphemeralHLTPhysics1/RAW/v1/000/323/775/00000/2E066536-5CF2-B340-A73B-209640F29FF6.root set InputLHCRawHIon1 = root://eoscms.cern.ch//eos/cms/store/hidata/HIRun2015/HIHardProbes/RAW-RECO/HighPtJet-PromptReco-v1/000/263/689/00000/1802CD9A-DDB8-E511-9CF9-02163E0138CA.root #et InputLHCRawHIon3 = root://eoscms.cern.ch//eos/cms/store/hidata/HIRun2018A/HIHardProbes/RAW/v1/000/326/479/00000/853DBE29-53BA-9A44-9FDD-58E4E9064EB1.root set InputLHCRawHIon3 = root://eoscms.cern.ch//eos/cms/store/data/Run2018D/HIMinimumBias0/RAW/v1/000/325/112/00000/660F62BB-9932-D645-A4A4-0BBBDA3963E8.root diff --git a/HLTrigger/Timer/BuildFile.xml b/HLTrigger/Timer/BuildFile.xml index d3f2053126285..7d28a7ac17025 100644 --- a/HLTrigger/Timer/BuildFile.xml +++ b/HLTrigger/Timer/BuildFile.xml @@ -1,12 +1,11 @@ - + + + - - - diff --git a/HLTrigger/Timer/plugins/memory_usage.h b/HLTrigger/Timer/interface/memory_usage.h similarity index 80% rename from HLTrigger/Timer/plugins/memory_usage.h rename to HLTrigger/Timer/interface/memory_usage.h index d53a68d28aca4..0d854d6704430 100644 --- a/HLTrigger/Timer/plugins/memory_usage.h +++ b/HLTrigger/Timer/interface/memory_usage.h @@ -8,6 +8,8 @@ class memory_usage { static bool is_available(); static uint64_t allocated(); static uint64_t deallocated(); + static uint64_t peak(); + static void reset_peak(); }; #endif // memory_usage_h diff --git a/HLTrigger/Timer/plugins/processor_model.h b/HLTrigger/Timer/interface/processor_model.h similarity index 100% rename from HLTrigger/Timer/plugins/processor_model.h rename to HLTrigger/Timer/interface/processor_model.h diff --git a/HLTrigger/Timer/plugins/FastTimerService.cc b/HLTrigger/Timer/plugins/FastTimerService.cc index c4fcb33a9517b..224fcb4b69443 100644 --- a/HLTrigger/Timer/plugins/FastTimerService.cc +++ b/HLTrigger/Timer/plugins/FastTimerService.cc @@ -33,12 +33,10 @@ using json = nlohmann::json; #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "FWCore/Utilities/interface/StreamID.h" +#include "HLTrigger/Timer/interface/memory_usage.h" +#include "HLTrigger/Timer/interface/processor_model.h" #include "FastTimerService.h" -// local headers -#include "memory_usage.h" -#include "processor_model.h" - using namespace std::literals; /////////////////////////////////////////////////////////////////////////////// diff --git a/HLTrigger/Timer/plugins/ThroughputService.cc b/HLTrigger/Timer/plugins/ThroughputService.cc index 5510cc81afd23..ec5071c0f662f 100644 --- a/HLTrigger/Timer/plugins/ThroughputService.cc +++ b/HLTrigger/Timer/plugins/ThroughputService.cc @@ -7,14 +7,12 @@ #include // CMSSW headers +#include "DQMServices/Core/interface/DQMStore.h" #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h" #include "FWCore/Utilities/interface/TimeOfDay.h" -#include "DQMServices/Core/interface/DQMStore.h" +#include "HLTrigger/Timer/interface/processor_model.h" #include "ThroughputService.h" -// local headers -#include "processor_model.h" - // describe the module's configuration void ThroughputService::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; diff --git a/HLTrigger/Timer/plugins/memory_usage.cc b/HLTrigger/Timer/plugins/memory_usage.cc deleted file mode 100644 index a55a4ede31e39..0000000000000 --- a/HLTrigger/Timer/plugins/memory_usage.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include - -#include "memory_usage.h" - -// see -extern "C" { -typedef int (*mallctl_t)(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen); -} - -namespace { - bool initialise(); - const uint64_t *initialise_thread_allocated_p(); - const uint64_t *initialise_thread_deallocated_p(); - - const uint64_t zero = 0UL; - thread_local const uint64_t *thread_allocated_p = initialise_thread_allocated_p(); - thread_local const uint64_t *thread_deallocated_p = initialise_thread_deallocated_p(); - - mallctl_t mallctl = nullptr; - const bool have_jemalloc_and_stats = initialise(); - - bool initialise() { - // check if mallctl is available, if we are using jemalloc - mallctl = (mallctl_t)::dlsym(RTLD_DEFAULT, "mallctl"); - if (mallctl == nullptr) - return false; - - // check if the statistics are available, if --enable-stats was specified at build time - bool enable_stats = false; - size_t bool_s = sizeof(bool); - mallctl("config.stats", &enable_stats, &bool_s, nullptr, 0); - return enable_stats; - } - - const uint64_t *initialise_thread_allocated_p() { - const uint64_t *stats = &zero; - size_t ptr_s = sizeof(uint64_t *); - - if (have_jemalloc_and_stats) - // get pointers to the thread-specific allocation statistics - mallctl("thread.allocatedp", &stats, &ptr_s, nullptr, 0); - - return stats; - } - - const uint64_t *initialise_thread_deallocated_p() { - const uint64_t *stats = &zero; - size_t ptr_s = sizeof(uint64_t *); - - if (have_jemalloc_and_stats) - // get pointers to the thread-specific allocation statistics - mallctl("thread.deallocatedp", &stats, &ptr_s, nullptr, 0); - - return stats; - } - -} // namespace - -bool memory_usage::is_available() { return have_jemalloc_and_stats; } - -uint64_t memory_usage::allocated() { return *thread_allocated_p; } - -uint64_t memory_usage::deallocated() { return *thread_deallocated_p; } diff --git a/HLTrigger/Timer/src/memory_usage.cc b/HLTrigger/Timer/src/memory_usage.cc new file mode 100644 index 0000000000000..0b49c4fd5369b --- /dev/null +++ b/HLTrigger/Timer/src/memory_usage.cc @@ -0,0 +1,101 @@ +#include +#include + +#include "HLTrigger/Timer/interface/memory_usage.h" + +// see +extern "C" { +typedef int (*mallctl_t)(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen); +typedef int (*mallctlnametomib_t)(const char *name, size_t *mibp, size_t *miblenp); +typedef int (*mallctlbymib_t)(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); +} + +namespace { + bool initialise(); + bool initialise_peak(); + const uint64_t *initialise_thread_allocated_p(); + const uint64_t *initialise_thread_deallocated_p(); + + const uint64_t zero = 0UL; + size_t mib_peak_read[3]; // management information base for "thread.peak.read" + size_t mib_peak_reset[3]; // management information base for "thread.peak.reset" + thread_local const uint64_t *thread_allocated_p = initialise_thread_allocated_p(); + thread_local const uint64_t *thread_deallocated_p = initialise_thread_deallocated_p(); + + mallctl_t mallctl = nullptr; + mallctlnametomib_t mallctlnametomib = nullptr; + mallctlbymib_t mallctlbymib = nullptr; + const bool have_jemalloc_and_stats = initialise(); + const bool have_jemalloc_and_peak = have_jemalloc_and_stats and initialise_peak(); + + bool initialise() { + // check if mallctl and friends are available, if we are using jemalloc + mallctl = (mallctl_t)::dlsym(RTLD_DEFAULT, "mallctl"); + if (mallctl == nullptr) + return false; + mallctlnametomib = (mallctlnametomib_t)::dlsym(RTLD_DEFAULT, "mallctlnametomib"); + if (mallctlnametomib == nullptr) + return false; + mallctlbymib = (mallctlbymib_t)::dlsym(RTLD_DEFAULT, "mallctlbymib"); + if (mallctlbymib == nullptr) + return false; + + // check if the statistics are available, if --enable-stats was specified at build time + bool enable_stats = false; + size_t bool_s = sizeof(bool); + mallctl("config.stats", &enable_stats, &bool_s, nullptr, 0); + return enable_stats; + } + + bool initialise_peak() { + // check if thread.peak.read and thread.peak.reset are available + size_t miblen = 3; + if (mallctlnametomib("thread.peak.read", mib_peak_read, &miblen) != 0) + return false; + if (mallctlnametomib("thread.peak.reset", mib_peak_reset, &miblen) != 0) + return false; + return true; + } + + const uint64_t *initialise_thread_allocated_p() { + const uint64_t *stats = &zero; + size_t ptr_s = sizeof(uint64_t *); + + if (have_jemalloc_and_stats) + // get a pointer to the thread-specific allocation statistics + mallctl("thread.allocatedp", &stats, &ptr_s, nullptr, 0); + + return stats; + } + + const uint64_t *initialise_thread_deallocated_p() { + const uint64_t *stats = &zero; + size_t ptr_s = sizeof(uint64_t *); + + if (have_jemalloc_and_stats) + // get a pointer to the thread-specific allocation statistics + mallctl("thread.deallocatedp", &stats, &ptr_s, nullptr, 0); + + return stats; + } + +} // namespace + +bool memory_usage::is_available() { return have_jemalloc_and_stats; } + +uint64_t memory_usage::allocated() { return *thread_allocated_p; } + +uint64_t memory_usage::deallocated() { return *thread_deallocated_p; } + +uint64_t memory_usage::peak() { + uint64_t peak = 0; + size_t size = sizeof(uint64_t); + if (have_jemalloc_and_peak) + mallctlbymib(mib_peak_read, 3, &peak, &size, nullptr, 0); + return peak; +} + +void memory_usage::reset_peak() { + if (have_jemalloc_and_peak) + mallctlbymib(mib_peak_reset, 3, nullptr, nullptr, nullptr, 0); +} diff --git a/HLTrigger/Timer/plugins/processor_model.cc b/HLTrigger/Timer/src/processor_model.cc similarity index 95% rename from HLTrigger/Timer/plugins/processor_model.cc rename to HLTrigger/Timer/src/processor_model.cc index 9206b1c53efee..f1d97922a96fb 100644 --- a/HLTrigger/Timer/plugins/processor_model.cc +++ b/HLTrigger/Timer/src/processor_model.cc @@ -13,7 +13,7 @@ #include #endif // BOOST_OS_BSD || BOOST_OS_MACOS -#include "processor_model.h" +#include "HLTrigger/Timer/interface/processor_model.h" std::string read_processor_model() { #if BOOST_OS_LINUX diff --git a/HLTrigger/Timer/test/BuildFile.xml b/HLTrigger/Timer/test/BuildFile.xml index 1372082167f81..5cbadfe21e7aa 100644 --- a/HLTrigger/Timer/test/BuildFile.xml +++ b/HLTrigger/Timer/test/BuildFile.xml @@ -5,3 +5,16 @@ + + + + + + + + + + + + + diff --git a/HLTrigger/Timer/test/memory_usage_t.cc b/HLTrigger/Timer/test/memory_usage_t.cc new file mode 100644 index 0000000000000..9b9e33dd0f39a --- /dev/null +++ b/HLTrigger/Timer/test/memory_usage_t.cc @@ -0,0 +1,48 @@ +#include +#include +#include + +#include "HLTrigger/Timer/interface/memory_usage.h" + +void print_thread_header() { + std::cout << "+allocated / -deallocated / < peak memory for the current thread:" << std::endl; +} + +void print_thread_stat() { + std::cout << "\t+" << (memory_usage::allocated() / 1024) << " kB / " // allocated memory, in kB + << "-" << (memory_usage::deallocated() / 1024) << " kB / " // deallocated memory, in kB + << "< " << (memory_usage::peak() / 1024) << " kB" // peak used memory, in kB + << std::endl; +} + +int main(void) { + constexpr int size = 10; + std::array, size> buffers; + + print_thread_header(); + print_thread_stat(); + + for (auto& buffer : buffers) { + buffer = std::make_unique(16 * 1024); + print_thread_stat(); + } + + for (auto& buffer : buffers) { + buffer.reset(); + print_thread_stat(); + } + + std::cout << std::endl; + memory_usage::reset_peak(); + print_thread_header(); + print_thread_stat(); + + for (auto& buffer : buffers) { + buffer = std::make_unique(16 * 1024); + print_thread_stat(); + buffer.reset(); + print_thread_stat(); + } + + return 0; +} diff --git a/HLTrigger/Timer/test/processor_model_t.cc b/HLTrigger/Timer/test/processor_model_t.cc new file mode 100644 index 0000000000000..22326f4859107 --- /dev/null +++ b/HLTrigger/Timer/test/processor_model_t.cc @@ -0,0 +1,28 @@ +#include +#include + +#include "HLTrigger/Timer/interface/processor_model.h" + +const char* article(char letter) { + switch (tolower(letter)) { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + case 'y': + return "an"; + default: + return "a"; + } +} + +const char* article(const char* word) { return word == nullptr ? nullptr : article(word[0]); } + +const char* article(const std::string& word) { return word.empty() ? nullptr : article(word[0]); } + +int main() { + std::cout << "Running on " << article(processor_model) << " " << processor_model << std::endl; + + return processor_model.empty(); +} diff --git a/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.cc b/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.cc index d3c7d8aaca86a..0530724aaeab6 100644 --- a/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.cc +++ b/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.cc @@ -37,6 +37,7 @@ HLTDisplacedmumuVtxProducer::HLTDisplacedmumuVtxProducer(const edm::ParameterSet srcToken_(consumes(srcTag_)), previousCandTag_(iConfig.getParameter("PreviousCandTag")), previousCandToken_(consumes(previousCandTag_)), + matchToPrevious_(iConfig.getParameter("matchToPrevious")), maxEta_(iConfig.getParameter("MaxEta")), minPt_(iConfig.getParameter("MinPt")), minPtPair_(iConfig.getParameter("MinPtPair")), @@ -52,6 +53,7 @@ void HLTDisplacedmumuVtxProducer::fillDescriptions(edm::ConfigurationDescription edm::ParameterSetDescription desc; desc.add("Src", edm::InputTag("hltL3MuonCandidates")); desc.add("PreviousCandTag", edm::InputTag("")); + desc.add("matchToPrevious", true); desc.add("MaxEta", 2.5); desc.add("MinPt", 0.0); desc.add("MinPtPair", 0.0); @@ -85,10 +87,12 @@ void HLTDisplacedmumuVtxProducer::produce(edm::StreamID, edm::Event& iEvent, con // get the objects passing the previous filter Handle previousCands; - iEvent.getByToken(previousCandToken_, previousCands); + if (matchToPrevious_) + iEvent.getByToken(previousCandToken_, previousCands); vector vPrevCands; - previousCands->getObjects(TriggerMuon, vPrevCands); + if (matchToPrevious_) + previousCands->getObjects(TriggerMuon, vPrevCands); for (cand1 = mucands->begin(); cand1 != mucands->end(); cand1++) { TrackRef tk1 = cand1->get(); @@ -96,7 +100,7 @@ void HLTDisplacedmumuVtxProducer::produce(edm::StreamID, edm::Event& iEvent, con << ", eta= " << cand1->eta() << ", hits= " << tk1->numberOfValidHits(); //first check if this muon passed the previous filter - if (!checkPreviousCand(tk1, vPrevCands)) + if (matchToPrevious_ && !checkPreviousCand(tk1, vPrevCands)) continue; // cuts @@ -115,7 +119,7 @@ void HLTDisplacedmumuVtxProducer::produce(edm::StreamID, edm::Event& iEvent, con << " 2nd muon in loop: q*pt= " << cand2->charge() * cand2->pt() << ", eta= " << cand2->eta() << ", hits= " << tk2->numberOfValidHits() << ", d0= " << tk2->d0(); //first check if this muon passed the previous filter - if (!checkPreviousCand(tk2, vPrevCands)) + if (matchToPrevious_ && !checkPreviousCand(tk2, vPrevCands)) continue; // cuts diff --git a/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.h b/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.h index d8f82a0330057..6ff338cd99df6 100644 --- a/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.h +++ b/HLTrigger/btau/plugins/HLTDisplacedmumuVtxProducer.h @@ -41,6 +41,7 @@ class HLTDisplacedmumuVtxProducer : public edm::global::EDProducer<> { const edm::EDGetTokenT srcToken_; const edm::InputTag previousCandTag_; const edm::EDGetTokenT previousCandToken_; + const bool matchToPrevious_; const double maxEta_; const double minPt_; const double minPtPair_; diff --git a/IOPool/Streamer/interface/FRDEventMessage.h b/IOPool/Streamer/interface/FRDEventMessage.h index 611e41389fa89..8087389c42c61 100644 --- a/IOPool/Streamer/interface/FRDEventMessage.h +++ b/IOPool/Streamer/interface/FRDEventMessage.h @@ -15,6 +15,18 @@ * 14-Nov-2013 - RKM - Added event size, adler32 and padding size (version #3) * 15-Oct-2014 - WDD - Event number from 32 bits to 64 bits (version #4) * 01-Apr-2015 - SM - replaced adler32 with crc32c which is accelerated in SSE 4.2 (version #5) + * 22-Sep-2020 - SM - reused high version 16-bits for event info via flags (version #6) + * + * + * Version 6 Format: + * uint16 - format version number + * uint16 - event flags + * uint32 - run number + * uint32 - lumi number + * uint32 - event number + * uint32 - event size + * uint32 - crc32c checksum of FED data (excluding event header) + * variable size - FED data * * Version 5 Format: * uint32 - format version number @@ -57,14 +69,24 @@ #include "IOPool/Streamer/interface/MsgTools.h" +#include + +struct FRDEventHeader_V6 { + uint16 version_; + uint16 flags_; + uint32 run_; + uint32 lumi_; + uint32 event_; + uint32 eventSize_; + uint32 crc32c_; +}; + struct FRDEventHeader_V5 { uint32 version_; uint32 run_; uint32 lumi_; - uint32 eventLow_; - uint32 eventHigh_; + uint32 event_; uint32 eventSize_; - uint32 paddingSize_; uint32 crc32c_; }; @@ -101,8 +123,16 @@ struct FRDEventHeader_V1 { uint32 event_; }; -const uint32 FRDHeaderVersionSize[6] = { - 0, 2 * sizeof(uint32), (4 + 1024) * sizeof(uint32), 7 * sizeof(uint32), 8 * sizeof(uint32), 6 * sizeof(uint32)}; +const uint16 FRDEVENT_MASK_ISGENDATA = 1; + +constexpr size_t FRDHeaderMaxVersion = 6; +constexpr std::array FRDHeaderVersionSize{{0, + 2 * sizeof(uint32), + (4 + 1024) * sizeof(uint32), + 7 * sizeof(uint32), + 8 * sizeof(uint32), + 6 * sizeof(uint32), + 6 * sizeof(uint32)}}; class FRDEventMsgView { public: @@ -112,7 +142,8 @@ class FRDEventMsgView { void* payload() const { return payload_; } uint32 size() const { return size_; } - uint32 version() const { return version_; } + uint16 version() const { return version_; } + uint16 flags() const { return flags_; } uint32 run() const { return run_; } uint32 lumi() const { return lumi_; } uint64 event() const { return event_; } @@ -121,11 +152,14 @@ class FRDEventMsgView { uint32 adler32() const { return adler32_; } uint32 crc32c() const { return crc32c_; } + bool isRealData() const { return !(flags_ & FRDEVENT_MASK_ISGENDATA); } + private: uint8* buf_; void* payload_; uint32 size_; - uint32 version_; + uint16 version_; + uint16 flags_; uint32 run_; uint32 lumi_; uint64 event_; diff --git a/IOPool/Streamer/plugins/ParameterSetBlobProducer.cc b/IOPool/Streamer/plugins/ParameterSetBlobProducer.cc index 796cc0e643cf1..46c555ada1f2b 100644 --- a/IOPool/Streamer/plugins/ParameterSetBlobProducer.cc +++ b/IOPool/Streamer/plugins/ParameterSetBlobProducer.cc @@ -15,7 +15,10 @@ class ParameterSetBlobProducer : public edm::global::EDProducer> const token_; diff --git a/IOPool/Streamer/src/FRDEventMessage.cc b/IOPool/Streamer/src/FRDEventMessage.cc index 2ffdcb5bf0134..0811b3e59fbbf 100644 --- a/IOPool/Streamer/src/FRDEventMessage.cc +++ b/IOPool/Streamer/src/FRDEventMessage.cc @@ -10,6 +10,7 @@ */ #include "IOPool/Streamer/interface/FRDEventMessage.h" +#include "FWCore/Utilities/interface/Exception.h" /** * Constructor for the FRD event message viewer. @@ -19,6 +20,7 @@ FRDEventMsgView::FRDEventMsgView(void* buf) payload_(nullptr), size_(0), version_(0), + flags_(0), run_(0), lumi_(0), event_(0), @@ -27,22 +29,27 @@ FRDEventMsgView::FRDEventMsgView(void* buf) adler32_(0), crc32c_(0) { uint32* bufPtr = static_cast(buf); - version_ = *bufPtr; - // if the version number is rather large, then we assume that the true - // version number is one. (In version one of the format, there was - // no version number in the data, and the run number appeared first.) - if (version_ >= 32) { - version_ = 1; + + // In version one of the format, there was no version number in the data, + // and the run number (32-bit) appeared first. + // This format is no longer supported + version_ = *(uint16*)bufPtr; + + if (version_ < 2 || version_ > 6) { + throw cms::Exception("FRDEventMsgView") << "FRD version " << version_ << " is not supported"; } - size_ = 0; + // Version 6 repurposes unused high 16-bits of 32-bit version + // assuming we no longer need version 1 support + flags_ = *((uint16*)bufPtr + 1); - // version number - if (version_ >= 2) { - size_ += sizeof(uint32); - ++bufPtr; + if (version_ < 6 && flags_) { + throw cms::Exception("FRDEventMsgView") << "FRD flags can not be used in version " << version_; } + size_ = sizeof(uint32); + ++bufPtr; + // run number run_ = *bufPtr; size_ += sizeof(uint32); diff --git a/IOPool/Streamer/src/StreamerOutputModuleBase.cc b/IOPool/Streamer/src/StreamerOutputModuleBase.cc index 52234aebd25d4..dee1806980504 100644 --- a/IOPool/Streamer/src/StreamerOutputModuleBase.cc +++ b/IOPool/Streamer/src/StreamerOutputModuleBase.cc @@ -68,7 +68,7 @@ namespace edm { void StreamerOutputModuleBase::fillDescription(ParameterSetDescription& desc) { StreamerOutputModuleCommon::fillDescription(desc); OutputModule::fillDescription(desc); - desc.addUntracked("psetMap", {"psetMap"}) + desc.addUntracked("psetMap", {"hltPSetMap"}) ->setComment("Optionally allow the map of ParameterSets to be calculated externally."); } } // namespace edm diff --git a/L1Trigger/CSCCommonTrigger/interface/CSCConstants.h b/L1Trigger/CSCCommonTrigger/interface/CSCConstants.h index 4b6ceb50c2efe..4e5d44024f965 100644 --- a/L1Trigger/CSCCommonTrigger/interface/CSCConstants.h +++ b/L1Trigger/CSCCommonTrigger/interface/CSCConstants.h @@ -64,10 +64,10 @@ class CSCConstants { // Maximum allowed matching window size MAX_MATCH_WINDOW_SIZE = 15, // Each CLCT processor can send up to 2 CLCTs to TMB per BX - MAX_CLCTS_PER_PROCESSOR = 50, + MAX_CLCTS_PER_PROCESSOR = 2, MAX_CLCTS_READOUT = 2, // Each ALCT processor can send up to 2 ALCTs to TMB per BX - MAX_ALCTS_PER_PROCESSOR = 50, + MAX_ALCTS_PER_PROCESSOR = 2, MAX_ALCTS_READOUT = 2, // Each CSC can send up to 2 LCTs to the MPC per BX MAX_LCTS_PER_CSC = 2, diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h index b7429a588b47d..724efaad0a15b 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h @@ -75,7 +75,7 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { std::vector readoutALCTs(int nMaxALCTs = CSCConstants::MAX_ALCTS_READOUT) const; /** Returns vector of all found ALCTs, if any. */ - std::vector getALCTs(int nMaxALCTs = CSCConstants::MAX_ALCTS_READOUT) const; + std::vector getALCTs(unsigned nMaxALCTs = CSCConstants::MAX_ALCTS_READOUT) const; /** read out pre-ALCTs */ std::vector preTriggerDigis() const { return thePreTriggerDigis; } @@ -99,7 +99,7 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { CSCALCTDigi secondALCT[CSCConstants::MAX_ALCT_TBINS]; /** LCTs in this chamber, as found by the processor. */ - CSCALCTDigi ALCTContainer_[CSCConstants::MAX_ALCT_TBINS][CSCConstants::MAX_ALCTS_PER_PROCESSOR]; + std::vector > ALCTContainer_; /** Access routines to wire digis. */ bool getDigis(const CSCWireDigiCollection* wiredc); @@ -231,6 +231,10 @@ class CSCAnodeLCTProcessor : public CSCBaseboard { /** Dump digis on wire groups. */ void dumpDigis(const std::vector wire[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_WIRES]) const; + // Check if the ALCT is valid + void checkValidReadout(const CSCALCTDigi& alct) const; + void checkValid(const CSCALCTDigi& alct, unsigned max_stubs = CSCConstants::MAX_ALCTS_PER_PROCESSOR) const; + void showPatterns(const int key_wire); }; diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h index 765efc4be0a6f..2fa6b04827b36 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCBaseboard.h @@ -50,6 +50,7 @@ class CSCBaseboard { // is this an ME11 chamber? bool isME11_; + bool isME21_; // CSCDetId for this chamber CSCDetId cscId_; diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h index 0dba5cd5b0ee5..6271de540ad41 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h @@ -70,7 +70,7 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { std::vector readoutCLCTsME1b(int nMaxCLCTs = CSCConstants::MAX_CLCTS_READOUT) const; /** Returns vector of all found CLCTs, if any. */ - std::vector getCLCTs() const; + std::vector getCLCTs(unsigned nMaxCLCTs = CSCConstants::MAX_CLCTS_PER_PROCESSOR) const; /** get best/second best CLCT * Note: CLCT has BX shifted */ @@ -85,8 +85,11 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { std::vector preTriggerDigisME1b() const; protected: - /** LCTs in this chamber, as found by the processor. */ - CSCCLCTDigi CLCTContainer_[CSCConstants::MAX_CLCT_TBINS][CSCConstants::MAX_CLCTS_PER_PROCESSOR]; + /** Best LCT in this chamber, as found by the processor. */ + CSCCLCTDigi bestCLCT[CSCConstants::MAX_CLCT_TBINS]; + + /** Second best LCT in this chamber, as found by the processor. */ + CSCCLCTDigi secondCLCT[CSCConstants::MAX_CLCT_TBINS]; /** Access routines to comparator digis. */ bool getDigis(const CSCComparatorDigiCollection* compdc); @@ -138,6 +141,9 @@ class CSCCathodeLCTProcessor : public CSCBaseboard { void dumpDigis(const std::vector strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips) const; + // Check if the CLCT is valid + void checkValid(const CSCCLCTDigi& lct, unsigned max_stubs = CSCConstants::MAX_CLCTS_PER_PROCESSOR) const; + //--------------------------- Member variables ----------------------------- /* best pattern Id for a given half-strip */ diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMotherboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMotherboard.h index 3da30e9482edd..ddb6766caa07a 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMotherboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMotherboard.h @@ -200,6 +200,8 @@ class CSCGEMMotherboard : public CSCUpgradeMotherboard { /** Chamber id (trigger-type labels). */ unsigned gemId; + int maxPads() const; + int maxRolls() const; const GEMGeometry* gem_g; bool gemGeometryAvailable; diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h new file mode 100644 index 0000000000000..8fc124d846aef --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h @@ -0,0 +1,30 @@ +#ifndef L1Trigger_CSCTriggerPrimitives_CSCLCTTools_h +#define L1Trigger_CSCTriggerPrimitives_CSCLCTTools_h + +#include "L1Trigger/CSCCommonTrigger/interface/CSCConstants.h" + +#include +#include + +namespace csctp { + + // CSC max strip & max wire + unsigned get_csc_max_wire(int station, int ring); + unsigned get_csc_max_halfstrip(int station, int ring); + unsigned get_csc_max_quartstrip(int station, int ring); + unsigned get_csc_max_eightstrip(int station, int ring); + + // CLCT min, max CFEB numbers + std::pair get_csc_min_max_cfeb(int station, int ring); + + // CSC min, max pattern + std::pair get_csc_min_max_pattern(bool isRun3); + + // CSC max quality + unsigned get_csc_alct_max_quality(int station, int ring, bool isRun3); + unsigned get_csc_clct_max_quality(); + unsigned get_csc_lct_max_quality(); + +} // namespace csctp + +#endif diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h index 0c8011ff2774e..d7bfd271b95f9 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h @@ -118,6 +118,9 @@ class CSCMotherboard : public CSCBaseboard { unsigned int highMultiplicityBits_; bool useHighMultiplicityBits_; + // Use the new patterns according to the comparator code format + bool use_run3_patterns_; + /** Default values of configuration parameters. */ static const unsigned int def_mpc_block_me1a; static const unsigned int def_alct_trig_enable, def_clct_trig_enable; @@ -165,6 +168,9 @@ class CSCMotherboard : public CSCBaseboard { /** Dump TMB/MPC configuration parameters. */ void dumpConfigParams() const; + // Check if the LCT is valid + void checkValid(const CSCCorrelatedLCTDigi& lct) const; + /* encode high multiplicity bits for Run-3 exotic triggers */ void encodeHighMultiplicityBits(unsigned alctBits); }; diff --git a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc index 457dfe60514ba..62ac0e058a000 100644 --- a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc +++ b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc @@ -81,23 +81,24 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS produces("MPCSORTED"); if (runME11ILT_ or runME21ILT_) produces(); + + // temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member + builder_ = std::make_unique(config_); } CSCTriggerPrimitivesProducer::~CSCTriggerPrimitivesProducer() {} -void CSCTriggerPrimitivesProducer::produce(edm::StreamID iID, edm::Event& ev, const edm::EventSetup& setup) const { - // Remark: access builder using "streamCache(iID)" - +void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup& setup) { // get the csc geometry edm::ESHandle h; setup.get().get(h); - streamCache(iID)->setCSCGeometry(&*h); + builder_->setCSCGeometry(&*h); // get the gem geometry if it's there edm::ESHandle h_gem; setup.get().get(h_gem); if (h_gem.isValid()) { - streamCache(iID)->setGEMGeometry(&*h_gem); + builder_->setGEMGeometry(&*h_gem); } else { edm::LogInfo("CSCTriggerPrimitivesProducer|NoGEMGeometry") << "+++ Info: GEM geometry is unavailable. Running CSC-only trigger algorithm. +++\n"; @@ -119,7 +120,7 @@ void CSCTriggerPrimitivesProducer::produce(edm::StreamID iID, edm::Event& ev, co << "+++ Cannot continue emulation without these parameters +++\n"; return; } - streamCache(iID)->setConfigParameters(conf.product()); + builder_->setConfigParameters(conf.product()); } // Get the collections of comparator & wire digis from event. @@ -172,21 +173,21 @@ void CSCTriggerPrimitivesProducer::produce(edm::StreamID iID, edm::Event& ev, co // Fill output collections if valid input collections are available. if (wireDigis.isValid() && compDigis.isValid()) { const CSCBadChambers* temp = checkBadChambers_ ? pBadChambers.product() : new CSCBadChambers; - streamCache(iID)->build(temp, - wireDigis.product(), - compDigis.product(), - gemPads, - gemPadClusters, - *oc_alct, - *oc_alct_all, - *oc_clct, - *oc_clct_all, - *oc_alctpretrigger, - *oc_clctpretrigger, - *oc_pretrig, - *oc_lct, - *oc_sorted_lct, - *oc_gemcopad); + builder_->build(temp, + wireDigis.product(), + compDigis.product(), + gemPads, + gemPadClusters, + *oc_alct, + *oc_alct_all, + *oc_clct, + *oc_clct_all, + *oc_alctpretrigger, + *oc_clctpretrigger, + *oc_pretrig, + *oc_lct, + *oc_sorted_lct, + *oc_gemcopad); if (!checkBadChambers_) delete temp; } diff --git a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h index 494caeedc6641..0bb6da5fce883 100644 --- a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h +++ b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h @@ -30,7 +30,7 @@ #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/one/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/InputTag.h" @@ -41,20 +41,20 @@ #include "DataFormats/GEMDigi/interface/GEMPadDigiClusterCollection.h" #include "L1Trigger/CSCTriggerPrimitives/interface/CSCTriggerPrimitivesBuilder.h" -class CSCTriggerPrimitivesProducer : public edm::global::EDProducer> { +// temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member +class CSCTriggerPrimitivesProducer : public edm::one::EDProducer<> { public: explicit CSCTriggerPrimitivesProducer(const edm::ParameterSet&); ~CSCTriggerPrimitivesProducer() override; - void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + void produce(edm::Event&, const edm::EventSetup&) override; private: // master configuration edm::ParameterSet config_; - std::unique_ptr beginStream(edm::StreamID) const override { - return std::unique_ptr(new CSCTriggerPrimitivesBuilder(config_)); - } + // temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member + std::unique_ptr builder_; // input tags for input collections edm::InputTag compDigiProducer_; diff --git a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py index 3b421cb0b0da0..27850b7af7ca8 100644 --- a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py +++ b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigis_cfi.py @@ -506,7 +506,7 @@ alctSLHCME21 = cscTriggerPrimitiveDigis.alctSLHC.clone(alctNplanesHitPattern = 3), clctSLHCME21 = cscTriggerPrimitiveDigis.clctSLHC.clone(clctNplanesHitPattern = 3), me21tmbSLHCGEM = me21tmbSLHCGEM, - alctSLHCME3141 = cscTriggerPrimitiveDigis.alctSLHC.clone(alctNplanesHitPattern = 4), + alctSLHCME3141 = cscTriggerPrimitiveDigis.alctParam07.clone(alctNplanesHitPattern = 4), clctSLHCME3141 = cscTriggerPrimitiveDigis.clctSLHC.clone(clctNplanesHitPattern = 4), meX1tmbSLHC = meX1tmbSLHC, copadParamGE11 = copadParamGE11, diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc index e5eacc99e2281..f9646b101828d 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCAnodeLCTProcessor.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" #include // Default values of configuration parameters. @@ -195,9 +196,6 @@ void CSCAnodeLCTProcessor::clear() { for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { bestALCT[bx].clear(); secondALCT[bx].clear(); - for (int iALCT = 0; iALCT < CSCConstants::MAX_ALCTS_PER_PROCESSOR; iALCT++) { - ALCTContainer_[bx][iALCT].clear(); - } } lct_list.clear(); } @@ -222,35 +220,32 @@ std::vector CSCAnodeLCTProcessor::run(const CSCWireDigiCollection* // Get the number of wire groups for the given chamber. Do it only once // per chamber. - if (numWireGroups == 0) { + if (numWireGroups <= 0 or numWireGroups > CSCConstants::MAX_NUM_WIRES) { if (cscChamber_) { numWireGroups = cscChamber_->layer(1)->geometry()->numberOfWireGroups(); if (numWireGroups > CSCConstants::MAX_NUM_WIRES) { - if (infoV >= 0) - edm::LogError("CSCAnodeLCTProcessor|SetupError") - << "+++ Number of wire groups, " << numWireGroups << " found in " << theCSCName_ << " (sector " - << theSector << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << " exceeds max expected, " << CSCConstants::MAX_NUM_WIRES << " +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCAnodeLCTProcessor|SetupError") + << "+++ Number of wire groups, " << numWireGroups << " found in " << theCSCName_ << " (sector " << theSector + << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" + << " exceeds max expected, " << CSCConstants::MAX_NUM_WIRES << " +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numWireGroups = -1; } } else { - if (infoV >= 0) - edm::LogError("CSCAnodeLCTProcessor|SetupError") - << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " - << theTrigChamber << ")" - << " is not defined in current geometry! +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCAnodeLCTProcessor|SetupError") + << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << ")" + << " is not defined in current geometry! +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numWireGroups = -1; } } - if (numWireGroups < 0) { - if (infoV >= 0) - edm::LogError("CSCAnodeLCTProcessor|SetupError") - << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " - << theTrigChamber << "):" - << " numWireGroups = " << numWireGroups << "; ALCT emulation skipped! +++"; + if (numWireGroups <= 0 or (unsigned) numWireGroups > csctp::get_csc_max_wire(theStation, theRing)) { + edm::LogError("CSCAnodeLCTProcessor|SetupError") + << "+++ " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << "):" + << " numWireGroups = " << numWireGroups << "; ALCT emulation skipped! +++"; std::vector emptyV; return emptyV; } @@ -294,15 +289,17 @@ void CSCAnodeLCTProcessor::run(const std::vector wire[CSCConstants::NUM_LAY // Check if there are any in-time hits and do the pulse extension. bool chamber_empty = pulseExtension(wire); - // Take the best MAX_CLCTS_PER_PROCESSOR candidates per bx. - int ALCTIndex_[CSCConstants::MAX_ALCT_TBINS] = {}; - // Only do the rest of the processing if chamber is not empty. // Stop drift_delay bx's short of fifo_tbins since at later bx's we will // not have a full set of hits to start pattern search anyway. unsigned int stop_bx = fifo_tbins - drift_delay; if (!chamber_empty) { for (int i_wire = 0; i_wire < numWireGroups; i_wire++) { + // extra check to make sure only valid wires are processed + const unsigned max_wire = csctp::get_csc_max_wire(theStation, theRing); + if (unsigned(i_wire) >= max_wire) + continue; + unsigned int start_bx = 0; // Allow for more than one pass over the hits in the time window. while (start_bx < stop_bx) { @@ -322,10 +319,9 @@ void CSCAnodeLCTProcessor::run(const std::vector wire[CSCConstants::NUM_LAY //acceleration mode if (quality[i_wire][0] > 0 and bx < CSCConstants::MAX_ALCT_TBINS) { int valid = (ghost_cleared[0] == 0) ? 1 : 0; //cancelled, valid=0, otherwise it is 1 - const auto& newALCT(CSCALCTDigi(valid, quality[i_wire][0], 1, 0, i_wire, bx)); - lct_list.push_back(newALCT); - ALCTContainer_[bx][ALCTIndex_[bx]] = newALCT; - ALCTIndex_[bx]++; + CSCALCTDigi newALCT(valid, quality[i_wire][0], 1, 0, i_wire, bx); + + lct_list.emplace_back(newALCT); if (infoV > 1) LogTrace("CSCAnodeLCTProcessor") << "Add one ALCT to list " << lct_list.back(); } @@ -333,10 +329,10 @@ void CSCAnodeLCTProcessor::run(const std::vector wire[CSCConstants::NUM_LAY //collision mode if (quality[i_wire][1] > 0 and bx < CSCConstants::MAX_ALCT_TBINS) { int valid = (ghost_cleared[1] == 0) ? 1 : 0; //cancelled, valid=0, otherwise it is 1 - const auto& newALCT(CSCALCTDigi(valid, quality[i_wire][1], 0, quality[i_wire][2], i_wire, bx)); - lct_list.push_back(newALCT); - ALCTContainer_[bx][ALCTIndex_[bx]] = newALCT; - ALCTIndex_[bx]++; + + CSCALCTDigi newALCT(valid, quality[i_wire][1], 0, quality[i_wire][2], i_wire, bx); + + lct_list.emplace_back(newALCT); if (infoV > 1) LogTrace("CSCAnodeLCTProcessor") << "Add one ALCT to list " << lct_list.back(); } @@ -905,6 +901,10 @@ void CSCAnodeLCTProcessor::lctSearch() { for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { if (bestALCT[bx].isValid()) { bestALCT[bx].setTrknmb(1); + + // check if the best ALCT is valid + checkValidReadout(bestALCT[bx]); + if (infoV > 0) { LogDebug("CSCAnodeLCTProcessor") << bestALCT[bx] << " fullBX = " << bestALCT[bx].getFullBX() << " found in " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector @@ -913,6 +913,10 @@ void CSCAnodeLCTProcessor::lctSearch() { } if (secondALCT[bx].isValid()) { secondALCT[bx].setTrknmb(2); + + // check if the second best ALCT is valid + checkValidReadout(secondALCT[bx]); + if (infoV > 0) { LogDebug("CSCAnodeLCTProcessor") << secondALCT[bx] << " fullBX = " << secondALCT[bx].getFullBX() << " found in " << theCSCName_ @@ -922,21 +926,6 @@ void CSCAnodeLCTProcessor::lctSearch() { } } } - - // set track number for the other ALCTs - for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { - for (int iALCT = 0; iALCT < CSCConstants::MAX_ALCTS_PER_PROCESSOR; iALCT++) { - if (ALCTContainer_[bx][iALCT].isValid()) { - ALCTContainer_[bx][iALCT].setTrknmb(iALCT + 1); - if (infoV > 0) { - LogDebug("CSCAnodeLCTProcessor") - << ALCTContainer_[bx][iALCT] << " found in " << theCSCName_ << " (sector " << theSector << " subsector " - << theSubsector << " trig id. " << theTrigChamber << ")" - << "\n"; - } - } - } - } } std::vector CSCAnodeLCTProcessor::bestTrackSelector(const std::vector& all_alcts) { @@ -1217,6 +1206,65 @@ void CSCAnodeLCTProcessor::dumpDigis( LogTrace("CSCAnodeLCTProcessor") << strstrm.str(); } +// Check if the ALCT is valid +void CSCAnodeLCTProcessor::checkValidReadout(const CSCALCTDigi& alct) const { + checkValid(alct, CSCConstants::MAX_ALCTS_READOUT); +} + +// Check if the ALCT is valid +void CSCAnodeLCTProcessor::checkValid(const CSCALCTDigi& alct, unsigned max_stubs) const { + const unsigned max_wire = csctp::get_csc_max_wire(theStation, theRing); + const unsigned max_quality = csctp::get_csc_alct_max_quality(theStation, theRing, runME21ILT_); + + unsigned errors = 0; + + // stub must be valid + if (!alct.isValid()) { + edm::LogError("CSCAnodeLCTProcessor") << "CSCALCTDigi with invalid bit set: " << alct.isValid(); + errors++; + } + + // ALCT number is 1 or 2 + if (alct.getTrknmb() < 1 or alct.getTrknmb() > max_stubs) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid track number: " << alct.getTrknmb() << "; allowed [1," << max_stubs << "]"; + errors++; + } + + // ALCT quality must be valid + // number of layers - 3 + if (alct.getQuality() <= 0 or alct.getQuality() > max_quality) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid quality: " << alct.getQuality() << "; allowed [0," << max_quality << "]"; + errors++; + } + + // ALCT key wire-group must be within bounds + if (alct.getKeyWG() > max_wire) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid wire-group: " << alct.getKeyWG() << "; allowed [0, " << max_wire << "]"; + errors++; + } + + // ALCT with out-of-time BX + if (alct.getBX() > CSCConstants::MAX_ALCT_TBINS - 1) { + edm::LogError("CSCAnodeLCTProcessor") << "CSCALCTDigi with invalid BX: " << alct.getBX() << "; allowed [0, " + << CSCConstants::MAX_LCT_TBINS - 1 << "]"; + errors++; + } + + // ALCT is neither accelerator or collision + if (alct.getCollisionB() > 1) { + edm::LogError("CSCAnodeLCTProcessor") + << "CSCALCTDigi with invalid accel/coll bit: " << alct.getCollisionB() << "; allowed [0,1]"; + errors++; + } + + if (errors > 0) { + edm::LogError("CSCAnodeLCTProcessor") << "Faulty ALCT: " << cscId_ << " " << alct << "\n errors " << errors; + } +} + // Returns vector of read-out ALCTs, if any. Starts with the vector of // all found ALCTs and selects the ones in the read-out time window. std::vector CSCAnodeLCTProcessor::readoutALCTs(int nMaxALCTs) const { @@ -1283,25 +1331,23 @@ std::vector CSCAnodeLCTProcessor::readoutALCTs(int nMaxALCTs) const for (auto& p : tmpV) { p.setBX(p.getBX() - (CSCConstants::LCT_CENTRAL_BX - l1a_window_width / 2)); } + + // do a final check on the ALCTs in readout + for (const auto& alct : tmpV) { + checkValid(alct, nMaxALCTs); + } + return tmpV; } // Returns vector of all found ALCTs, if any. Used in ALCT-CLCT matching. -std::vector CSCAnodeLCTProcessor::getALCTs(int nMaxALCTs) const { +std::vector CSCAnodeLCTProcessor::getALCTs(unsigned nMaxALCTs) const { std::vector tmpV; for (int bx = 0; bx < CSCConstants::MAX_ALCT_TBINS; bx++) { - if (nMaxALCTs == CSCConstants::MAX_ALCTS_READOUT) { - if (bestALCT[bx].isValid()) - tmpV.push_back(bestALCT[bx]); - if (secondALCT[bx].isValid()) - tmpV.push_back(secondALCT[bx]); - } else { - for (int iALCT = 0; iALCT < CSCConstants::MAX_ALCTS_PER_PROCESSOR; iALCT++) { - if (ALCTContainer_[bx][iALCT].isValid()) { - tmpV.push_back(ALCTContainer_[bx][iALCT]); - } - } - } + if (bestALCT[bx].isValid()) + tmpV.push_back(bestALCT[bx]); + if (secondALCT[bx].isValid()) + tmpV.push_back(secondALCT[bx]); } return tmpV; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc index 0f64cb196b99f..91cecae52176a 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCBaseboard.cc @@ -13,6 +13,7 @@ CSCBaseboard::CSCBaseboard(unsigned endcap, theChamber = CSCTriggerNumbering::chamberFromTriggerLabels(theSector, theSubsector, theStation, theTrigChamber); isME11_ = (theStation == 1 && theRing == 1); + isME21_ = (theStation == 2 && theRing == 1); cscId_ = CSCDetId(theEndcap, theStation, theRing, theChamber, 0); @@ -91,11 +92,10 @@ void CSCBaseboard::checkConfigParameters(unsigned int& var, const std::string& var_str) { // Make sure that the parameter values are within the allowed range. if (var >= var_max) { - if (infoV >= 0) - edm::LogError("CSCConfigError") << "+++ Value of " + var_str + ", " << var << ", exceeds max allowed, " << var - 1 - << " +++\n" - << "+++ Try to proceed with the default value, " + var_str + "=" << var_def - << " +++\n"; + edm::LogError("CSCConfigError") << "+++ Value of " + var_str + ", " << var << ", exceeds max allowed, " << var - 1 + << " +++\n" + << "+++ Try to proceed with the default value, " + var_str + "=" << var_def + << " +++\n"; var = var_def; } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc index 5f9d69859199a..61621c88df25f 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" #include #include @@ -186,9 +187,8 @@ void CSCCathodeLCTProcessor::clear() { thePreTriggerDigis.clear(); thePreTriggerBXs.clear(); for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { - for (int iCLCT = 0; iCLCT < CSCConstants::MAX_CLCTS_PER_PROCESSOR; iCLCT++) { - CLCTContainer_[bx][iCLCT].clear(); - } + bestCLCT[bx].clear(); + secondCLCT[bx].clear(); } } @@ -205,7 +205,7 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl // Get the number of strips and stagger of layers for the given chamber. // Do it only once per chamber. - if (numStrips == 0) { + if (numStrips <= 0 or numStrips > CSCConstants::MAX_NUM_STRIPS_7CFEBS) { if (cscChamber_) { numStrips = cscChamber_->layer(1)->geometry()->numberOfStrips(); // ME1/a is known to the readout hardware as strips 65-80 of ME1/1. @@ -216,12 +216,10 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl // For SLHC ME1/1 is set to have 4 CFEBs in ME1/b and 3 CFEBs in ME1/a if (isME11_) { if (theRing == 4) { - if (infoV >= 0) { - edm::LogError("L1CSCTPEmulatorSetupError") - << "+++ Invalid ring number for this processor " << theRing << " was set in the config." - << " +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; - } + edm::LogError("CSCCathodeLCTProcessor|SetupError") + << "+++ Invalid ring number for this processor " << theRing << " was set in the config." + << " +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; } if (!disableME1a_ && theRing == 1 && !gangedME1a_) numStrips = CSCConstants::MAX_NUM_STRIPS_7CFEBS; @@ -232,13 +230,11 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl } if (numStrips > CSCConstants::MAX_NUM_STRIPS_7CFEBS) { - if (infoV >= 0) - edm::LogError("L1CSCTPEmulatorSetupError") - << "+++ Number of strips, " << numStrips << " found in " - << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << " exceeds max expected, " << CSCConstants::MAX_NUM_STRIPS_7CFEBS << " +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCCathodeLCTProcessor|SetupError") + << "+++ Number of strips, " << numStrips << " found in " << theCSCName_ << " (sector " << theSector + << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" + << " exceeds max expected, " << CSCConstants::MAX_NUM_STRIPS_7CFEBS << " +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numStrips = -1; } // The strips for a given layer may be offset from the adjacent layers. @@ -258,22 +254,20 @@ std::vector CSCCathodeLCTProcessor::run(const CSCComparatorDigiColl stagger[i_layer] = (cscChamber_->layer(i_layer + 1)->geometry()->stagger() + 1) / 2; } } else { - if (infoV >= 0) - edm::LogError("L1CSCTPEmulatorConfigError") - << " " << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << " is not defined in current geometry! +++\n" - << "+++ CSC geometry looks garbled; no emulation possible +++\n"; + edm::LogError("CSCCathodeLCTProcessor|ConfigError") + << " " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << ")" + << " is not defined in current geometry! +++\n" + << "+++ CSC geometry looks garbled; no emulation possible +++\n"; numStrips = -1; } } - if (numStrips < 0) { - if (infoV >= 0) - edm::LogError("L1CSCTPEmulatorConfigError") - << " " << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << "):" - << " numStrips = " << numStrips << "; CLCT emulation skipped! +++"; + if (numStrips <= 0 or 2 * (unsigned)numStrips > csctp::get_csc_max_halfstrip(theStation, theRing)) { + edm::LogError("CSCCathodeLCTProcessor|ConfigError") + << " " << theCSCName_ << " (sector " << theSector << " subsector " << theSubsector << " trig id. " + << theTrigChamber << "):" + << " numStrips = " << numStrips << "; CLCT emulation skipped! +++"; std::vector emptyV; return emptyV; } @@ -338,9 +332,6 @@ void CSCCathodeLCTProcessor::run( if (CLCTlist.size() > 1) sort(CLCTlist.begin(), CLCTlist.end(), std::greater()); - // Take the best MAX_CLCTS_PER_PROCESSOR candidates per bx. - int CLCTIndex_[CSCConstants::MAX_CLCT_TBINS] = {}; - for (const auto& p : CLCTlist) { const int bx = p.getBX(); if (bx >= CSCConstants::MAX_CLCT_TBINS) { @@ -351,22 +342,37 @@ void CSCCathodeLCTProcessor::run( continue; } - CLCTContainer_[bx][CLCTIndex_[bx]] = p; - CLCTIndex_[bx]++; + if (!bestCLCT[bx].isValid()) { + bestCLCT[bx] = p; + } else if (!secondCLCT[bx].isValid()) { + secondCLCT[bx] = p; + } } for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { - for (int iCLCT = 0; iCLCT < CSCConstants::MAX_CLCTS_PER_PROCESSOR; iCLCT++) { - if (CLCTContainer_[bx][iCLCT].isValid()) { - CLCTContainer_[bx][iCLCT].setTrknmb(iCLCT + 1); - if (infoV > 0) { - LogDebug("CSCCathodeLCTProcessor") - << CLCTContainer_[bx][iCLCT] << " found in " - << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) << " (sector " << theSector - << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" - << "\n"; - } - } + if (bestCLCT[bx].isValid()) { + bestCLCT[bx].setTrknmb(1); + + // check if the LCT is valid + checkValid(bestCLCT[bx]); + + if (infoV > 0) + LogDebug("CSCCathodeLCTProcessor") + << bestCLCT[bx] << " found in " << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) + << " (sector " << theSector << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" + << "\n"; + } + if (secondCLCT[bx].isValid()) { + secondCLCT[bx].setTrknmb(2); + + // check if the LCT is valid + checkValid(secondCLCT[bx]); + + if (infoV > 0) + LogDebug("CSCCathodeLCTProcessor") + << secondCLCT[bx] << " found in " << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) + << " (sector " << theSector << " subsector " << theSubsector << " trig id. " << theTrigChamber << ")" + << "\n"; } } // Now that we have our best CLCTs, they get correlated with the best @@ -614,24 +620,23 @@ std::vector CSCCathodeLCTProcessor::findLCTs( } } - // If 1st best CLCT is found, look for other CLCTs! + // If 1st best CLCT is found, look for the 2nd best. if (best_halfstrip[0] >= 0) { - for (int ilct = 1; ilct < CSCConstants::MAX_CLCTS_PER_PROCESSOR; ilct++) { - // Mark keys near best CLCT as busy by setting their quality to zero, and repeat the search. - markBusyKeys(best_halfstrip[ilct - 1], best_pid[best_halfstrip[ilct - 1]], quality); + // Mark keys near best CLCT as busy by setting their quality to + // zero, and repeat the search. + markBusyKeys(best_halfstrip[0], best_pid[best_halfstrip[0]], quality); - for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) { - if (quality[hstrip] > best_quality[ilct]) { - best_halfstrip[ilct] = hstrip; - best_quality[ilct] = quality[hstrip]; - } - if (infoV > 1 && quality[hstrip] > 0) { - LogTrace("CSCCathodeLCTProcessor") - << "CLCT " << ilct + 1 << ": halfstrip = " << std::setw(3) << hstrip << " quality = " << std::setw(3) - << quality[hstrip] << " nhits = " << std::setw(3) << nhits[hstrip] << " pid = " << std::setw(3) - << best_pid[hstrip] << " best halfstrip = " << std::setw(3) << best_halfstrip[1] - << " best quality = " << std::setw(3) << best_quality[1]; - } + for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) { + if (quality[hstrip] > best_quality[1]) { + best_halfstrip[1] = hstrip; + best_quality[1] = quality[hstrip]; + } + if (infoV > 1 && quality[hstrip] > 0) { + LogTrace("CSCCathodeLCTProcessor") + << " 2nd CLCT: halfstrip = " << std::setw(3) << hstrip << " quality = " << std::setw(3) + << quality[hstrip] << " nhits = " << std::setw(3) << nhits[hstrip] << " pid = " << std::setw(3) + << best_pid[hstrip] << " best halfstrip = " << std::setw(3) << best_halfstrip[1] + << " best quality = " << std::setw(3) << best_quality[1]; } } @@ -648,8 +653,14 @@ std::vector CSCCathodeLCTProcessor::findLCTs( keystrip_data[ilct][CLCT_STRIP_TYPE] = 1; // obsolete keystrip_data[ilct][CLCT_QUALITY] = nhits[best_hs]; keystrip_data[ilct][CLCT_CFEB] = keystrip_data[ilct][CLCT_STRIP] / CSCConstants::NUM_HALF_STRIPS_PER_CFEB; - const uint16_t halfstrip_in_cfeb = keystrip_data[ilct][CLCT_STRIP] - - CSCConstants::NUM_HALF_STRIPS_PER_CFEB * keystrip_data[ilct][CLCT_CFEB]; + int halfstrip_in_cfeb = keystrip_data[ilct][CLCT_STRIP] - + CSCConstants::NUM_HALF_STRIPS_PER_CFEB * keystrip_data[ilct][CLCT_CFEB]; + + if (infoV > 1) + LogTrace("CSCCathodeLCTProcessor") + << " Final selection: ilct " << ilct << " key halfstrip " << keystrip_data[ilct][CLCT_STRIP] + << " quality " << keystrip_data[ilct][CLCT_QUALITY] << " pattern " + << keystrip_data[ilct][CLCT_PATTERN] << " bx " << keystrip_data[ilct][CLCT_BX]; CSCCLCTDigi thisLCT(1, keystrip_data[ilct][CLCT_QUALITY], @@ -905,7 +916,7 @@ bool CSCCathodeLCTProcessor::patternFinding( hit_layer[this_layer] = true; layers_hit++; // determines number of layers hit // add this strip in this layer to the pattern we are currently considering - hits_single_pattern[this_layer][strip_num] = this_strip; + hits_single_pattern[this_layer][strip_num] = this_strip - stagger[this_layer]; } // find at what bx did pulse on this halsfstrip & layer have started @@ -1023,8 +1034,7 @@ void CSCCathodeLCTProcessor::dumpConfigParams() const { void CSCCathodeLCTProcessor::dumpDigis( const std::vector strip[CSCConstants::NUM_LAYERS][CSCConstants::NUM_HALF_STRIPS_7CFEBS], const int nStrips) const { - LogDebug("CSCCathodeLCTProcessor") << CSCDetId::chamberName(theEndcap, theStation, theRing, theChamber) - << " strip type: half-strip, nStrips " << nStrips; + LogDebug("CSCCathodeLCTProcessor") << theCSCName_ << " strip type: half-strip, nStrips " << nStrips; std::ostringstream strstrm; for (int i_strip = 0; i_strip < nStrips; i_strip++) { @@ -1061,6 +1071,111 @@ void CSCCathodeLCTProcessor::dumpDigis( LogTrace("CSCCathodeLCTProcessor") << strstrm.str(); } +// Check if the CLCT is valid +void CSCCathodeLCTProcessor::checkValid(const CSCCLCTDigi& clct, unsigned max_stubs) const { + const unsigned max_strip = csctp::get_csc_max_halfstrip(theStation, theRing); + const auto& [min_pattern, max_pattern] = csctp::get_csc_min_max_pattern(use_run3_patterns_); + const auto& [min_cfeb, max_cfeb] = csctp::get_csc_min_max_cfeb(theStation, theRing); + const unsigned max_quality = csctp::get_csc_clct_max_quality(); + unsigned errors = 0; + + // CLCT must be valid + if (!clct.isValid()) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid bit set: " << clct.isValid(); + errors++; + } + + // CLCT number is 1 or max + if (clct.getTrknmb() < 1 or clct.getTrknmb() > max_stubs) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid track number: " << clct.getTrknmb() << "; allowed [1," << max_stubs << "]"; + errors++; + } + + // CLCT quality must be valid + // CLCTs require at least 4 layers hit + // Run-3: ME1/1 CLCTs require only 3 layers + // Run-4: ME2/1 CLCTs require only 3 layers + if (clct.getQuality() < nplanes_hit_pattern or clct.getQuality() > max_quality) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid quality: " << clct.getQuality() << "; allowed [0," << max_quality << "]"; + ; + errors++; + } + + // CLCT half-strip must be within bounds + if (clct.getStrip() >= CSCConstants::NUM_HALF_STRIPS_PER_CFEB) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid half-strip: " << clct.getStrip() + << "; allowed [0, " << CSCConstants::NUM_HALF_STRIPS_PER_CFEB - 1 << "]"; + errors++; + } + + // CLCT key half-strip must be within bounds + if (clct.getKeyStrip() >= max_strip) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid key half-strip: " << clct.getKeyStrip() << "; allowed [0, " << max_strip - 1 << "]"; + errors++; + } + + // CLCT with out-of-time BX + if (clct.getBX() >= CSCConstants::MAX_CLCT_TBINS) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid BX: " << clct.getBX() << "; allowed [0, " + << CSCConstants::MAX_CLCT_TBINS - 1 << "]"; + errors++; + } + + // CLCT with neither left nor right bending + if (clct.getBend() > 1) { + edm::LogError("CSCCathodeLCTProcessor") + << "CSCLCTDigi with invalid bending: " << clct.getBend() << "; allowed [0,1]"; + errors++; + } + + // CLCT with an invalid pattern ID + if (clct.getPattern() < min_pattern or clct.getPattern() > max_pattern) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid pattern ID: " << clct.getPattern() + << "; allowed [" << min_pattern << ", " << max_pattern << "]"; + errors++; + } + + // CLCT with an invalid CFEB ID + if (clct.getCFEB() < min_cfeb or clct.getCFEB() > max_cfeb) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid CFEB ID: " << clct.getCFEB() << "; allowed [" + << min_cfeb << ", " << max_cfeb << "]"; + errors++; + } + + if (use_run3_patterns_) { + // CLCT comparator code is invalid + if (clct.getCompCode() < 0 or clct.getCompCode() >= std::pow(2, 12)) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid comparator code: " << clct.getCompCode() + << "; allowed [0, " << std::pow(2, 12) - 1 << "]"; + errors++; + } + + unsigned max_quartstrip = csctp::get_csc_max_quartstrip(theStation, theRing); + unsigned max_eightstrip = csctp::get_csc_max_eightstrip(theStation, theRing); + + // CLCT key half-strip must be within bounds + if (clct.getKeyStrip(4) >= max_quartstrip) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid key quart-strip: " << clct.getKeyStrip(4) + << "; allowed [0, " << max_quartstrip - 1 << "]"; + errors++; + } + + // CLCT key half-strip must be within bounds + if (clct.getKeyStrip(8) >= max_eightstrip) { + edm::LogError("CSCCathodeLCTProcessor") << "CSCLCTDigi with invalid key eight-strip: " << clct.getKeyStrip(8) + << "; allowed [0, " << max_eightstrip - 1 << "]"; + errors++; + } + } + + if (errors > 0) { + edm::LogError("CSCCathodeLCTProcessor") << "Faulty CLCT: " << cscId_ << " " << clct << "\n errors " << errors; + } +} + // Returns vector of read-out CLCTs, if any. Starts with the vector // of all found CLCTs and selects the ones in the read-out time window. std::vector CSCCathodeLCTProcessor::readoutCLCTs(int nMaxCLCTs) const { @@ -1103,7 +1218,7 @@ std::vector CSCCathodeLCTProcessor::readoutCLCTs(int nMaxCLCTs) con // Start from the vector of all found CLCTs and select those within // the CLCT*L1A coincidence window. int bx_readout = -1; - const std::vector& all_lcts = getCLCTs(); + const std::vector& all_lcts = getCLCTs(nMaxCLCTs); for (const auto& p : all_lcts) { // only consider valid CLCTs if (!p.isValid()) @@ -1141,9 +1256,9 @@ std::vector CSCCathodeLCTProcessor::readoutCLCTs(int nMaxCLCTs) con tmpV.push_back(p); } - // remove the CLCTs with an index larger than nMaxCLCTs - if (tmpV.size() > unsigned(nMaxCLCTs)) { - tmpV.erase(tmpV.begin() + nMaxCLCTs, tmpV.end()); + // do a final check on the CLCTs in readout + for (const auto& clct : tmpV) { + checkValid(clct, nMaxCLCTs); } return tmpV; @@ -1198,14 +1313,13 @@ std::vector CSCCathodeLCTProcessor::preTriggerDigisME1b() } // Returns vector of all found CLCTs, if any. Used for ALCT-CLCT matching. -std::vector CSCCathodeLCTProcessor::getCLCTs() const { +std::vector CSCCathodeLCTProcessor::getCLCTs(unsigned nMaxCLCTs) const { std::vector tmpV; for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) { - for (int iCLCT = 0; iCLCT < CSCConstants::MAX_CLCTS_PER_PROCESSOR; iCLCT++) { - if (CLCTContainer_[bx][iCLCT].isValid()) { - tmpV.push_back(CLCTContainer_[bx][iCLCT]); - } - } + if (bestCLCT[bx].isValid()) + tmpV.push_back(bestCLCT[bx]); + if (secondCLCT[bx].isValid()) + tmpV.push_back(secondCLCT[bx]); } return tmpV; } @@ -1216,13 +1330,13 @@ std::vector CSCCathodeLCTProcessor::getCLCTs() const { // to make a proper comparison with ALCTs we need // CLCT and ALCT to have the central BX in the same bin CSCCLCTDigi CSCCathodeLCTProcessor::getBestCLCT(int bx) const { - CSCCLCTDigi lct = CLCTContainer_[bx][0]; + CSCCLCTDigi lct = bestCLCT[bx]; lct.setBX(lct.getBX() + alctClctOffset_); return lct; } CSCCLCTDigi CSCCathodeLCTProcessor::getSecondCLCT(int bx) const { - CSCCLCTDigi lct = CLCTContainer_[bx][1]; + CSCCLCTDigi lct = secondCLCT[bx]; lct.setBX(lct.getBX() + alctClctOffset_); return lct; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc index ea5c3cea83def..a4286c9cf3bd1 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMotherboard.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" CSCGEMMotherboard::CSCGEMMotherboard(unsigned endcap, unsigned station, @@ -44,6 +45,10 @@ void CSCGEMMotherboard::retrieveGEMPads(const GEMPadDigiCollection* gemPads, uns GEMDetId roll_id(roll->id()); auto pads_in_det = gemPads->get(roll_id); for (auto pad = pads_in_det.first; pad != pads_in_det.second; ++pad) { + // ignore invalid pads + if (!pad->isValid()) + continue; + const int bx_shifted(CSCConstants::LCT_CENTRAL_BX + pad->bx()); // consider matches with BX difference +1/0/-1 for (int bx = bx_shifted - maxDeltaBXPad_; bx <= bx_shifted + maxDeltaBXPad_; ++bx) { @@ -98,8 +103,8 @@ CSCCorrelatedLCTDigi CSCGEMMotherboard::constructLCTsGEM(const CSCALCTDigi& alct // make a new LCT CSCCorrelatedLCTDigi thisLCT; - if (not alct.isValid() and not clct.isValid()) { - LogTrace("CSCGEMCMotherboard") << "Warning!!! either ALCT or CLCT not valid, return invalid LCT \n"; + if (!alct.isValid() and !clct.isValid()) { + edm::LogError("CSCGEMCMotherboard") << "Warning!!! neither ALCT nor CLCT valid, return invalid LCT"; return thisLCT; } @@ -144,20 +149,28 @@ CSCCorrelatedLCTDigi CSCGEMMotherboard::constructLCTsGEM(const CSCALCTDigi& alct p = CSCPart::ME1A; } + // min pad number is always 0 + // max pad number is 191 or 383, depending on the station + assert(gem2.pad(1) >= 0); + assert(gem2.pad(2) >= 0); + assert(gem2.pad(1) < maxPads()); + assert(gem2.pad(2) < maxPads()); + const auto& mymap1 = getLUT()->get_gem_pad_to_csc_hs(theParity, p); // GEM pad number is counting from 1 // keyStrip from mymap: for ME1b 0-127 and for ME1a 0-95 // keyStrip for CLCT: for ME1b 0-127 and for ME1a 128-223 - keyStrip = mymap1[gem2.pad(2) - 1]; - if (p == CSCPart::ME1A and keyStrip <= CSCConstants::MAX_HALF_STRIP_ME1B) + keyStrip = mymap1.at(gem2.pad(2)); + if (p == CSCPart::ME1A and keyStrip <= CSCConstants::MAX_HALF_STRIP_ME1B) { keyStrip += CSCConstants::MAX_HALF_STRIP_ME1B + 1; + } keyWG = alct.getKeyWG(); if ((not doesWiregroupCrossStrip(keyWG, keyStrip)) and p == CSCPart::ME1B and keyWG <= 15) { //try ME1A as strip and WG do not cross p = CSCPart::ME1A; const auto& mymap2 = getLUT()->get_gem_pad_to_csc_hs(theParity, p); - keyStrip = mymap2[gem2.pad(2) - 1] + CSCConstants::MAX_HALF_STRIP_ME1B + 1; + keyStrip = mymap2.at(gem2.pad(2)) + CSCConstants::MAX_HALF_STRIP_ME1B + 1; } pattern = promoteALCTGEMpattern_ ? 10 : 0; @@ -169,13 +182,18 @@ CSCCorrelatedLCTDigi CSCGEMMotherboard::constructLCTsGEM(const CSCALCTDigi& alct thisLCT.setType(CSCCorrelatedLCTDigi::ALCT2GEM); valid = true; } else if (clct.isValid() and gem2.isValid() and not alct.isValid()) { + // min roll number is always 1 + // max roll number is 8 or 16, depending on the station + assert(gem2.roll() >= GEMDetId::minRollId); + assert(gem2.roll() <= maxRolls()); + const auto& mymap2 = getLUT()->get_gem_roll_to_csc_wg(theParity); pattern = encodePattern(clct.getPattern()); quality = promoteCLCTGEMquality_ ? 15 : 11; bx = gem2.bx(1) + CSCConstants::LCT_CENTRAL_BX; keyStrip = clct.getKeyStrip(); // choose the corresponding wire-group in the middle of the partition - keyWG = mymap2[gem2.roll() - 1]; + keyWG = mymap2.at(gem2.roll() - 1); bend = clct.getBend(); thisLCT.setCLCT(clct); thisLCT.setGEM1(gem2.first()); @@ -221,7 +239,7 @@ bool CSCGEMMotherboard::isPadInOverlap(int roll) const { // overlap region are WGs 10-15 if ((i < 10) or (i > 15)) continue; - if ((mymap[i].first <= roll) and (roll <= mymap[i].second)) + if ((mymap.at(i).first <= roll) and (roll <= mymap.at(i).second)) return true; } return false; @@ -240,8 +258,8 @@ int CSCGEMMotherboard::getRoll(const GEMPadDigiId& p) const { return GEMDetId(p. int CSCGEMMotherboard::getRoll(const GEMCoPadDigiId& p) const { return p.second.roll(); } std::pair CSCGEMMotherboard::getRolls(const CSCALCTDigi& alct) const { - return std::make_pair((getLUT()->get_csc_wg_to_gem_roll(theParity))[alct.getKeyWG()].first, - (getLUT()->get_csc_wg_to_gem_roll(theParity))[alct.getKeyWG()].second); + const auto& mymap(getLUT()->get_csc_wg_to_gem_roll(theParity)); + return std::make_pair(mymap.at(alct.getKeyWG()).first, mymap.at(alct.getKeyWG()).second); } float CSCGEMMotherboard::getPad(const GEMPadDigi& p) const { return p.pad(); } @@ -257,7 +275,7 @@ float CSCGEMMotherboard::getPad(const CSCCLCTDigi& clct, enum CSCPart part) cons //ME1A part, convert halfstrip from 128-223 to 0-95 if (part == CSCPart::ME1A and keyStrip > CSCConstants::MAX_HALF_STRIP_ME1B) keyStrip = keyStrip - CSCConstants::MAX_HALF_STRIP_ME1B - 1; - return 0.5 * (mymap[keyStrip].first + mymap[keyStrip].second); + return 0.5 * (mymap.at(keyStrip).first + mymap.at(keyStrip).second); } void CSCGEMMotherboard::setupGeometry() { @@ -265,6 +283,10 @@ void CSCGEMMotherboard::setupGeometry() { generator_->setGEMGeometry(gem_g); } +int CSCGEMMotherboard::maxPads() const { return gem_g->superChamber(gemId)->chamber(1)->etaPartition(1)->npads(); } + +int CSCGEMMotherboard::maxRolls() const { return gem_g->superChamber(gemId)->chamber(1)->nEtaPartitions(); } + void CSCGEMMotherboard::printGEMTriggerPads(int bx_start, int bx_stop, enum CSCPart part) { LogTrace("CSCGEMMotherboard") << "------------------------------------------------------------------------" << std::endl; diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc index 76bdaa12e04a0..539509a06999d 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME11.cc @@ -19,9 +19,13 @@ CSCGEMMotherboardME11::CSCGEMMotherboardME11(unsigned endcap, buildLCTfromCLCTandGEM_ME1b_(tmbParams_.getParameter("buildLCTfromCLCTandGEM_ME1b")), promoteCLCTGEMquality_ME1a_(tmbParams_.getParameter("promoteCLCTGEMquality_ME1a")), promoteCLCTGEMquality_ME1b_(tmbParams_.getParameter("promoteCLCTGEMquality_ME1b")) { - if (!isSLHC_) - edm::LogError("CSCGEMMotherboardME11|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME11 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME11ILT_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while runME11ILT_ is not set! +++\n"; + }; // set LUTs tmbLUT_.reset(new CSCGEMMotherboardLUTME11()); @@ -30,9 +34,13 @@ CSCGEMMotherboardME11::CSCGEMMotherboardME11(unsigned endcap, CSCGEMMotherboardME11::CSCGEMMotherboardME11() : CSCGEMMotherboard() { // Constructor used only for testing. - if (!isSLHC_) - edm::LogError("CSCGEMMotherboardME11|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME11 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME11ILT_) { + edm::LogError("CSCGEMMotherboardME11|SetupError") << "+++ TMB constructed while runME11ILT_ is not set! +++\n"; + } } CSCGEMMotherboardME11::~CSCGEMMotherboardME11() {} @@ -71,17 +79,15 @@ void CSCGEMMotherboardME11::run(const CSCWireDigiCollection* wiredc, // check for GEM geometry if (not gemGeometryAvailable) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME11|SetupError") - << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; + edm::LogError("CSCGEMMotherboardME11|SetupError") + << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; return; } gemCoPadV = coPadProcessor->run(gemPads); // run copad processor in GE1/1 - if (!(alctProc and clctProc and isSLHC_)) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME11|SetupError") - << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + if (!(alctProc and clctProc)) { + edm::LogError("CSCGEMMotherboardME11|SetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -478,6 +484,12 @@ std::vector CSCGEMMotherboardME11::readoutLCTsME11(enum CS } else tmpV.push_back(lct); } + + // do a final check on the LCTs in readout + for (const auto& lct : tmpV) { + checkValid(lct); + } + return tmpV; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc index 45752d32f2f0f..be1572ef4260c 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboardME21.cc @@ -11,18 +11,26 @@ CSCGEMMotherboardME21::CSCGEMMotherboardME21(unsigned endcap, dropLowQualityALCTsNoGEMs_(tmbParams_.getParameter("dropLowQualityALCTsNoGEMs")), buildLCTfromALCTandGEM_(tmbParams_.getParameter("buildLCTfromALCTandGEM")), buildLCTfromCLCTandGEM_(tmbParams_.getParameter("buildLCTfromCLCTandGEM")) { - if (!isSLHC_ or !runME21ILT_) - edm::LogError("CSCGEMMotherboardME21|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME21 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME21ILT_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while runME21ILT_ is not set! +++\n"; + } // set LUTs tmbLUT_.reset(new CSCGEMMotherboardLUTME21()); } CSCGEMMotherboardME21::CSCGEMMotherboardME21() : CSCGEMMotherboard() { - if (!isSLHC_ or !runME21ILT_) - edm::LogError("CSCGEMMotherboardME21|ConfigError") - << "+++ Upgrade CSCGEMMotherboardME21 constructed while isSLHC is not set! +++\n"; + if (!isSLHC_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while isSLHC is not set! +++\n"; + } + + if (!runME21ILT_) { + edm::LogError("CSCGEMMotherboardME21|SetupError") << "+++ TMB constructed while runME21ILT_ is not set! +++\n"; + } } CSCGEMMotherboardME21::~CSCGEMMotherboardME21() {} @@ -54,17 +62,15 @@ void CSCGEMMotherboardME21::run(const CSCWireDigiCollection* wiredc, // check for GEM geometry if (not gemGeometryAvailable) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME21|SetupError") - << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; + edm::LogError("CSCGEMMotherboardME21|SetupError") + << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; return; } gemCoPadV = coPadProcessor->run(gemPads); // run copad processor in GE1/1 if (!(alctProc and clctProc)) { - if (infoV >= 0) - edm::LogError("CSCGEMMotherboardME21|SetupError") - << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + edm::LogError("CSCGEMMotherboardME21|SetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -107,6 +113,8 @@ void CSCGEMMotherboardME21::run(const CSCWireDigiCollection* wiredc, const int bx_copad_start(bx_alct - maxDeltaBXCoPad_); const int bx_copad_stop(bx_alct + maxDeltaBXCoPad_); + const int quality(alctProc->getBestALCT(bx_alct).getQuality()); + if (debug_matching) { LogTrace("CSCGEMMotherboardME21") << "========================================================================" << std::endl @@ -214,7 +222,8 @@ void CSCGEMMotherboardME21::run(const CSCWireDigiCollection* wiredc, // ALCT-to-GEM matching int nGoodGEMMatches = 0; - if (nGoodMatches == 0 and buildLCTfromALCTandGEM_) { + // only use high-quality stubs + if (nGoodMatches == 0 and buildLCTfromALCTandGEM_ and quality >=1) { if (debug_matching) LogTrace("CSCGEMMotherboardME21") << "++No valid ALCT-CLCT matches in ME21" << std::endl; for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) { @@ -436,6 +445,12 @@ std::vector CSCGEMMotherboardME21::readoutLCTs() const { CSCUpgradeMotherboard::sortLCTs(result, CSCUpgradeMotherboard::sortLCTsByQuality); if (tmb_cross_bx_algo == 3) CSCUpgradeMotherboard::sortLCTs(result, CSCUpgradeMotherboard::sortLCTsByGEMDphi); + + // do a final check on the LCTs in readout + for (const auto& lct : result) { + checkValid(lct); + } + return result; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCLCTTools.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCLCTTools.cc new file mode 100644 index 0000000000000..5eb13047a5e4e --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCLCTTools.cc @@ -0,0 +1,109 @@ +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" + +namespace csctp { + + // Number of halfstrips and wiregroups + // +----------------------------+------------+------------+ + // | Chamber type | Num of | Num of | + // | | halfstrips | wiregroups | + // +----------------------------+------------+------------+ + // | ME1/1a | 96 | 48 | + // | ME1/1b | 128 | 48 | + // | ME1/2 | 160 | 64 | + // | ME1/3 | 128 | 32 | + // | ME2/1 | 160 | 112 | + // | ME3/1, ME4/1 | 160 | 96 | + // | ME2/2, ME3/2, ME4/2 | 160 | 64 | + // +----------------------------+------------+------------+ + + unsigned get_csc_max_wire(int station, int ring) { + unsigned max_wire = 0; // wiregroup + if (station == 1 && ring == 4) { // ME1/1a + max_wire = 48; + } else if (station == 1 && ring == 1) { // ME1/1b + max_wire = 48; + } else if (station == 1 && ring == 2) { // ME1/2 + max_wire = 64; + } else if (station == 1 && ring == 3) { // ME1/3 + max_wire = 32; + } else if (station == 2 && ring == 1) { // ME2/1 + max_wire = 112; + } else if (station >= 3 && ring == 1) { // ME3/1, ME4/1 + max_wire = 96; + } else if (station >= 2 && ring == 2) { // ME2/2, ME3/2, ME4/2 + max_wire = 64; + } + return max_wire; + } + + unsigned get_csc_max_halfstrip(int station, int ring) { + int max_strip = 0; // halfstrip + if (station == 1 && ring == 4) { // ME1/1a + max_strip = 96; + } else if (station == 1 && ring == 1) { // ME1/1b + // In the CSC local trigger + // ME1/a is taken together with ME1/b + max_strip = 128 + 96; + } else if (station == 1 && ring == 2) { // ME1/2 + max_strip = 160; + } else if (station == 1 && ring == 3) { // ME1/3 + max_strip = 128; + } else if (station == 2 && ring == 1) { // ME2/1 + max_strip = 160; + } else if (station >= 3 && ring == 1) { // ME3/1, ME4/1 + max_strip = 160; + } else if (station >= 2 && ring == 2) { // ME2/2, ME3/2, ME4/2 + max_strip = 160; + } + return max_strip; + } + + unsigned get_csc_max_quartstrip(int station, int ring) { return get_csc_max_halfstrip(station, ring) * 2; } + + unsigned get_csc_max_eightstrip(int station, int ring) { return get_csc_max_halfstrip(station, ring) * 4; } + + std::pair get_csc_min_max_cfeb(int station, int ring) { + // 5 CFEBs [0,4] for non-ME1/1 chambers + int min_cfeb = 0; + int max_cfeb = CSCConstants::MAX_CFEBS - 1; // 4 + // 7 CFEBs [0,6] for ME1/1 chambers + if (station == 1 and ring == 1) { + max_cfeb = 6; + } + return std::make_pair(min_cfeb, max_cfeb); + } + + std::pair get_csc_min_max_pattern(bool isRun3) { + int min_pattern, max_pattern; + // Run-1 or Run-2 case + if (!isRun3) { + min_pattern = 2; + max_pattern = 10; + // Run-3 case + } else { + min_pattern = 0; + max_pattern = 4; + } + return std::make_pair(min_pattern, max_pattern); + } + + unsigned get_csc_alct_max_quality(int station, int ring, bool runGEMCSC) { + int max_quality = 3; + // GE2/1-ME2/1 ALCTs are allowed 3-layer ALCTs + if (runGEMCSC and station == 2 and ring == 1) { + max_quality = 4; + } + return max_quality; + } + + unsigned get_csc_clct_max_quality() { + int max_quality = 6; + return max_quality; + } + + unsigned get_csc_lct_max_quality() { + int max_quality = 15; + return max_quality; + } + +} // namespace csctp diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc index 0cf847a627286..4ad3b6ee90fef 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc @@ -1,4 +1,5 @@ #include "L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h" +#include "L1Trigger/CSCTriggerPrimitives/interface/CSCLCTTools.h" #include // Default values of configuration parameters. @@ -37,6 +38,8 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, clct_to_alct = tmbParams_.getParameter("clctToAlct"); + use_run3_patterns_ = clctParams_.getParameter("useRun3Patterns"); + // special tmb bits useHighMultiplicityBits_ = tmbParams_.getParameter("useHighMultiplicityBits"); highMultiplicityBits_ = 0; @@ -130,8 +133,7 @@ void CSCMotherboard::run(const CSCWireDigiCollection* wiredc, const CSCComparato // Check for existing processors if (!(alctProc && clctProc)) { - if (infoV >= 0) - edm::LogError("CSCMotherboard|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + edm::LogError("CSCMotherboard|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -399,6 +401,12 @@ std::vector CSCMotherboard::readoutLCTs() const { else tmpV.push_back(*plct); } + + // do a final check on the LCTs in readout + for (const auto& lct : tmpV) { + checkValid(lct); + } + return tmpV; } @@ -409,10 +417,10 @@ std::vector CSCMotherboard::getLCTs() const { // Do not report LCTs found in ME1/A if mpc_block_me1/a is set. for (int bx = 0; bx < CSCConstants::MAX_LCT_TBINS; bx++) { if (firstLCT[bx].isValid()) - if (!mpc_block_me1a || (!isME11_ || firstLCT[bx].getStrip() <= 127)) + if (!mpc_block_me1a || (!isME11_ || firstLCT[bx].getStrip() <= CSCConstants::MAX_HALF_STRIP_ME1B)) tmpV.push_back(firstLCT[bx]); if (secondLCT[bx].isValid()) - if (!mpc_block_me1a || (!isME11_ || secondLCT[bx].getStrip() <= 127)) + if (!mpc_block_me1a || (!isME11_ || secondLCT[bx].getStrip() <= CSCConstants::MAX_HALF_STRIP_ME1B)) tmpV.push_back(secondLCT[bx]); } return tmpV; @@ -635,3 +643,123 @@ void CSCMotherboard::encodeHighMultiplicityBits(unsigned alctBits) { // this depends on memory constraints in the TMB FPGA highMultiplicityBits_ = alctBits; } + +void CSCMotherboard::checkValid(const CSCCorrelatedLCTDigi& lct) const { + const unsigned max_strip = csctp::get_csc_max_halfstrip(theStation, theRing); + const unsigned max_quartstrip = csctp::get_csc_max_quartstrip(theStation, theRing); + const unsigned max_eightstrip = csctp::get_csc_max_eightstrip(theStation, theRing); + const unsigned max_wire = csctp::get_csc_max_wire(theStation, theRing); + const auto& [min_pattern, max_pattern] = csctp::get_csc_min_max_pattern(use_run3_patterns_); + const unsigned max_quality = csctp::get_csc_lct_max_quality(); + + unsigned errors = 0; + + // LCT must be valid + if (!lct.isValid()) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid bit set: " << lct.isValid(); + errors++; + } + + // LCT number is 1 or 2 + if (lct.getTrknmb() < 1 or lct.getTrknmb() > 2) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid track number: " << lct.getTrknmb() + << "; allowed [1,2]"; + errors++; + } + + // LCT quality must be valid + if (lct.getQuality() > max_quality) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid quality: " << lct.getQuality() + << "; allowed [0,15]"; + errors++; + } + + // LCT key half-strip must be within bounds + if (lct.getStrip() > max_strip) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid half-strip: " << lct.getStrip() + << "; allowed [0, " << max_strip << "]"; + errors++; + } + + // LCT key half-strip must be within bounds + if (lct.getStrip(4) >= max_quartstrip) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid key quart-strip: " << lct.getStrip(4) + << "; allowed [0, " << max_quartstrip - 1 << "]"; + errors++; + } + + // LCT key half-strip must be within bounds + if (lct.getStrip(8) >= max_eightstrip) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid key eight-strip: " << lct.getStrip(8) + << "; allowed [0, " << max_eightstrip - 1 << "]"; + errors++; + } + + // LCT key wire-group must be within bounds + if (lct.getKeyWG() > max_wire) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid wire-group: " << lct.getKeyWG() + << "; allowed [0, " << max_wire << "]"; + errors++; + } + + // LCT with out-of-time BX + if (lct.getBX() > CSCConstants::MAX_LCT_TBINS - 1) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid BX: " << lct.getBX() << "; allowed [0, " + << CSCConstants::MAX_LCT_TBINS - 1 << "]"; + errors++; + } + + // LCT with neither left nor right bending + if (lct.getBend() > 1) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid bending: " << lct.getBend() + << "; allowed [0,1"; + errors++; + } + + // LCT with invalid CSCID + if (lct.getCSCID() < CSCTriggerNumbering::minTriggerCscId() or + lct.getCSCID() > CSCTriggerNumbering::maxTriggerCscId()) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid CSCID: " << lct.getBend() << "; allowed [" + << CSCTriggerNumbering::minTriggerCscId() << ", " + << CSCTriggerNumbering::maxTriggerCscId() << "]"; + errors++; + } + + // LCT with an invalid pattern ID + if (lct.getPattern() < min_pattern or lct.getPattern() > max_pattern) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid pattern ID: " << lct.getPattern() + << "; allowed [" << min_pattern << ", " << max_pattern << "]"; + errors++; + } + + // simulated LCT type must be valid + if (lct.getType() == CSCCorrelatedLCTDigi::CLCTALCT or lct.getType() == CSCCorrelatedLCTDigi::CLCTONLY or + lct.getType() == CSCCorrelatedLCTDigi::ALCTONLY) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid type (SIM): " << lct.getType() + << "; allowed [" << CSCCorrelatedLCTDigi::ALCTCLCT << ", " + << CSCCorrelatedLCTDigi::CLCT2GEM << "]"; + errors++; + } + + // non-GEM-CSC stations ALWAYS send out ALCTCLCT type LCTs + if (!(theRing == 1 and (theStation == 1 or theStation == 2))) { + if (lct.getType() != CSCCorrelatedLCTDigi::ALCTCLCT) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid type (SIM) in this station: " + << lct.getType() << "; allowed [" << CSCCorrelatedLCTDigi::ALCTCLCT << "]"; + errors++; + } + } + + // GEM-CSC stations can send out GEM-type LCTs ONLY when the ILT is turned on! + if (theRing == 1 and lct.getType() != CSCCorrelatedLCTDigi::ALCTCLCT) { + if ((theStation == 1 and !runME11ILT_) or (theStation == 2 and !runME21ILT_)) { + edm::LogError("CSCMotherboard") << "CSCCorrelatedLCTDigi with invalid type (SIM) with GEM-CSC trigger not on: " + << lct.getType() << "; allowed [" << CSCCorrelatedLCTDigi::ALCTCLCT << "]"; + errors++; + } + } + + if (errors > 0) { + edm::LogError("CSCMotherboard") << "Faulty LCT: " << cscId_ << " " << lct << "\n errors " << errors; + } +} diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc index 657de7f9ba544..4bca564f06900 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc @@ -20,8 +20,10 @@ CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, const edm::ParameterSet& conf) : CSCUpgradeMotherboard(endcap, station, sector, subsector, chamber, conf) { if (!isSLHC_) - edm::LogError("CSCMotherboardME11|ConfigError") - << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (!runME11Up_) + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; cscTmbLUT_.reset(new CSCMotherboardLUTME11()); @@ -31,8 +33,10 @@ CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, CSCMotherboardME11::CSCMotherboardME11() : CSCUpgradeMotherboard() { if (!isSLHC_) - edm::LogError("CSCMotherboardME11|ConfigError") - << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (!runME11Up_) + edm::LogError("CSCMotherboardME11|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; } CSCMotherboardME11::~CSCMotherboardME11() {} @@ -50,9 +54,8 @@ void CSCMotherboardME11::run(const CSCWireDigiCollection* wiredc, const CSCCompa clear(); // Check for existing processors - if (!(alctProc && clctProc && isSLHC_)) { - if (infoV >= 0) - edm::LogError("CSCMotherboardME11|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + if (!(alctProc && clctProc)) { + edm::LogError("CSCMotherboardME11|SetupError") << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -273,6 +276,12 @@ std::vector CSCMotherboardME11::readoutLCTs(int me1ab) con } else tmpV.push_back(*plct); } + + // do a final check on the LCTs in readout + for (const auto& lct : tmpV) { + checkValid(lct); + } + return tmpV; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc index 33140c4577946..80197156e0490 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc @@ -59,23 +59,22 @@ CSCTriggerPrimitivesBuilder::CSCTriggerPrimitivesBuilder(const edm::ParameterSet // go through all possible cases if (isSLHC_ and ring == 1 and stat == 1 and runME11Up_ and !runME11ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCMotherboardME11(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); else if (isSLHC_ and ring == 1 and stat == 1 and runME11Up_ and runME11ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCGEMMotherboardME11(endc, stat, sect, subs, cham, conf)); - else if (isSLHC_ and ring == 1 and stat == 2 and runME21Up_ and !runME21ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCUpgradeMotherboard(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); else if (isSLHC_ and ring == 1 and stat == 2 and runME21Up_ and runME21ILT_) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCGEMMotherboardME21(endc, stat, sect, subs, cham, conf)); - else if (isSLHC_ and ring == 1 and ((stat == 3 and runME31Up_) || (stat == 4 and runME41Up_))) - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCUpgradeMotherboard(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); + else if (isSLHC_ and ring == 1 and + ((stat == 2 and runME21Up_ and !runME21ILT_) || (stat == 3 and runME31Up_) || + (stat == 4 and runME41Up_))) + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); else - tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1].reset( - new CSCMotherboard(endc, stat, sect, subs, cham, conf)); + tmb_[endc - 1][stat - 1][sect - 1][subs - 1][cham - 1] = + std::make_unique(endc, stat, sect, subs, cham, conf); } } } @@ -335,7 +334,9 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, put(alctpretriggerV, oc_alctpretrigger, detid, " ME21 ALCT pre-trigger digi"); } // running upgraded ME2/1-ME3/1-ME4/1 TMBs (without GEMs or RPCs) - else if ((stat == 2 or stat == 3 or stat == 4) && ring == 1 && isSLHC_) { + else if (isSLHC_ and ring == 1 and + ((stat == 2 and runME21Up_ and !runME21ILT_) || (stat == 3 and runME31Up_) || + (stat == 4 and runME41Up_))) { // run the TMB CSCUpgradeMotherboard* utmb = static_cast(tmb); utmb->setCSCGeometry(csc_g); diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc index 699b7aac27cc2..dfabdd5eccf00 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeAnodeLCTProcessor.cc @@ -36,7 +36,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogic() { // Non-empty wire group. int qual_this = quality[key_wire][i_pattern]; if (qual_this > 0) { - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_ and isME21_) qual_this = (qual_this & 0x03); // Previous wire. int dt = -1; @@ -47,7 +47,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogic() { else dt = first_bx[key_wire] - first_bx[key_wire - 1]; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_ and isME21_) qual_prev = (qual_prev & 0x03); // Cancel this wire @@ -84,7 +84,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogic() { else dt = first_bx[key_wire] - first_bx[key_wire + 1]; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_ and isME21_) qual_next = (qual_next & 0x03); // Same cancellation logic as for the previous wire. if (dt == 0) { @@ -127,7 +127,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogicOneWire(const int key_wi // Non-empty wire group. int qual_this = quality[key_wire][i_pattern]; if (qual_this > 0) { - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_ and isME21_) qual_this = (qual_this & 0x03); // Previous wire. int dt = -1; @@ -150,7 +150,7 @@ void CSCUpgradeAnodeLCTProcessor::ghostCancellationLogicOneWire(const int key_wi else dt = first_bx[key_wire] - first_bx_prev; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (isSLHC_ and runME21ILT_ and isME21_) qual_prev = (qual_prev & 0x03); // Cancel this wire @@ -195,7 +195,7 @@ int CSCUpgradeAnodeLCTProcessor::getTempALCTQuality(int temp_quality) const { // on pattern_thresh. int Q; // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT - if (temp_quality == 3 and isSLHC_ and (runME21ILT_ or runME31Up_ or runME41Up_)) + if (temp_quality == 3 and isSLHC_ and runME21ILT_ and isME21_) Q = 4; else if (temp_quality > 3) Q = temp_quality - 3; diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeCathodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeCathodeLCTProcessor.cc index 4a8a7af457973..baf71dfe79c21 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeCathodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeCathodeLCTProcessor.cc @@ -272,21 +272,20 @@ std::vector CSCUpgradeCathodeLCTProcessor::findLCTs( // If 1st best CLCT is found, look for the 2nd best. if (best_halfstrip[0] >= 0) { - for (int ilct = 1; ilct < CSCConstants::MAX_CLCTS_PER_PROCESSOR; ilct++) { - // Mark keys near best CLCT as busy by setting their quality to zero, and repeat the search. - markBusyKeys(best_halfstrip[ilct - 1], best_pid[best_halfstrip[ilct - 1]], quality); + // Mark keys near best CLCT as busy by setting their quality to zero, and repeat the search. + markBusyKeys(best_halfstrip[0], best_pid[best_halfstrip[0]], quality); - for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) { - if (quality[hstrip] > best_quality[ilct] && pretrig_zone[hstrip] && !busyMap[hstrip][first_bx]) { - best_halfstrip[ilct] = hstrip; - best_quality[ilct] = quality[hstrip]; - if (infoV > 1) { - LogTrace("CSCCathodeLCTProcessor") - << "CLCT " << ilct + 1 << ": halfstrip = " << std::setw(3) << hstrip - << " quality = " << std::setw(3) << quality[hstrip] << " nhits = " << std::setw(3) << nhits[hstrip] - << " pid = " << std::setw(3) << best_pid[hstrip] << " best halfstrip = " << std::setw(3) - << best_halfstrip[ilct] << " best quality = " << std::setw(3) << best_quality[ilct]; - } + for (int hstrip = stagger[CSCConstants::KEY_CLCT_LAYER - 1]; hstrip < maxHalfStrips; hstrip++) { + if (quality[hstrip] > best_quality[1] && pretrig_zone[hstrip] && !busyMap[hstrip][first_bx]) + //!busyMap[hstrip][latch_bx] ) + { + best_halfstrip[1] = hstrip; + best_quality[1] = quality[hstrip]; + if (infoV > 1) { + LogTrace("CSCUpgradeCathodeLCTProcessor") + << " 2nd CLCT: halfstrip = " << std::setw(3) << hstrip << " quality = " << std::setw(3) + << quality[hstrip] << " best halfstrip = " << std::setw(3) << best_halfstrip[1] + << " best quality = " << std::setw(3) << best_quality[1]; } } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc index a02c2af86e59e..ca316127e8c7e 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCUpgradeMotherboard.cc @@ -10,8 +10,18 @@ CSCUpgradeMotherboard::CSCUpgradeMotherboard(unsigned endcap, CSCMotherboard(endcap, station, sector, subsector, chamber, conf), allLCTs(match_trig_window_size) { if (!isSLHC_) - edm::LogError("CSCUpgradeMotherboard|ConfigError") - << "+++ Upgrade CSCUpgradeMotherboard constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (theRing == 1) { + if (theStation == 1 and !runME11Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; + if (theStation == 2 and !runME21Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME21Up_ is not set! +++\n"; + if (theStation == 3 and !runME31Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME31Up_ is not set! +++\n"; + if (theStation == 4 and !runME41Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME41Up_ is not set! +++\n"; + } theParity = theChamber % 2 == 0 ? Parity::Even : Parity::Odd; @@ -40,8 +50,18 @@ CSCUpgradeMotherboard::CSCUpgradeMotherboard(unsigned endcap, CSCUpgradeMotherboard::CSCUpgradeMotherboard() : CSCMotherboard(), allLCTs(match_trig_window_size) { if (!isSLHC_) - edm::LogError("CSCUpgradeMotherboard|ConfigError") - << "+++ Upgrade CSCUpgradeMotherboard constructed while isSLHC_ is not set! +++\n"; + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while isSLHC_ is not set! +++\n"; + + if (theRing == 1) { + if (theStation == 1 and !runME11Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME11Up_ is not set! +++\n"; + if (theStation == 2 and !runME21Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME21Up_ is not set! +++\n"; + if (theStation == 3 and !runME31Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME31Up_ is not set! +++\n"; + if (theStation == 4 and !runME41Up_) + edm::LogError("CSCUpgradeMotherboard|SetupError") << "+++ TMB constructed while runME41Up_ is not set! +++\n"; + } setPrefIndex(); } @@ -50,9 +70,8 @@ void CSCUpgradeMotherboard::run(const CSCWireDigiCollection* wiredc, const CSCCo clear(); if (!(alctProc and clctProc)) { - if (infoV >= 0) - edm::LogError("CSCUpgradeMotherboard|SetupError") - << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + edm::LogError("CSCUpgradeMotherboard|SetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; return; } @@ -243,6 +262,12 @@ std::vector CSCUpgradeMotherboard::readoutLCTs() const { allLCTs.getMatched(result); if (tmb_cross_bx_algo == 2) CSCUpgradeMotherboard::sortLCTs(result, CSCUpgradeMotherboard::sortLCTsByQuality); + + // do a final check on the LCTs in readout + for (const auto& lct : result) { + checkValid(lct); + } + return result; } diff --git a/L1Trigger/CSCTriggerPrimitives/src/GEMCoPadProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/GEMCoPadProcessor.cc index c82badf8808f9..218c9c4f098d5 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/GEMCoPadProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/GEMCoPadProcessor.cc @@ -27,6 +27,8 @@ GEMCoPadProcessor::GEMCoPadProcessor() : theRegion(1), theStation(1), theChamber void GEMCoPadProcessor::clear() { gemCoPadV.clear(); } std::vector GEMCoPadProcessor::run(const GEMPadDigiCollection* in_pads) { + clear(); + // Build coincidences for (auto det_range = in_pads->begin(); det_range != in_pads->end(); ++det_range) { const GEMDetId& id = (*det_range).first; diff --git a/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py b/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py index c2fc684b6b99f..436822e8ab8e9 100644 --- a/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py +++ b/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py @@ -73,6 +73,7 @@ 'keep *_simCaloStage2Digis_*_*', 'keep *_simGmtDigis_*_*', "keep *_simBmtfDigis_*_*", + "keep *_simKBmtfDigis_*_*", "keep *_simOmtfDigis_*_*", "keep *_simEmtfDigis_*_*", "keep *_simGmtStage2Digis_*_*", @@ -153,3 +154,55 @@ def _appendME0Digis(obj): from Configuration.Eras.Modifier_phase2_muon_cff import phase2_muon phase2_muon.toModify(L1TriggerFEVTDEBUG, func=_appendME0Digis) + +# adding phase2 trigger +def _appendPhase2Digis(obj): + l1Phase2Digis = [ + "keep *_simKBmtfDigis_*_*", + 'keep *_hgcalVFEProducerhgcalConcentratorProducer_*_*', + 'keep *_hgcalBackEndLayer1Producer_*_*', + 'keep *_hgcalBackEndLayer2Producer_*_*', + 'keep *_hgcalTowerMapProducer_*_*', + 'keep *_hgcalTowerProducer_*_*', + 'keep *_L1EGammaClusterEmuProducer_*_*', + 'keep *_l1EGammaEEProducer_*_*', + 'keep *_L1TkPrimaryVertex_*_*', + 'keep *_L1TkElectronsCrystal_*_*', + 'keep *_L1TkElectronsLooseCrystal_*_*', + 'keep *_L1TkElectronsEllipticMatchCrystal_*_*', + 'keep *_L1TkIsoElectronsCrystal_*_*', + 'keep *_L1TkPhotonsCrystal_*_*', + 'keep *_L1TkElectronsHGC_*_*', + 'keep *_L1TkElectronsEllipticMatchHGC_*_*', + 'keep *_L1TkIsoElectronsHGC_*_*', + 'keep *_L1TkPhotonsHGC_*_*', + 'keep *_L1TkMuons_*_*', + 'keep *_pfClustersFromL1EGClusters_*_*', + 'keep *_pfClustersFromCombinedCaloHCal_*_*', + 'keep *_pfClustersFromCombinedCaloHF_*_*', + 'keep *_pfClustersFromHGC3DClusters_*_*', + 'keep *_pfTracksFromL1TracksBarrel_*_*', + 'keep *_l1pfProducerBarrel_*_*', + 'keep *_pfTracksFromL1TracksHGCal_*_*', + 'keep *_l1pfProducerHGCal_*_*', + 'keep *_l1pfProducerHGCalNoTK_*_*', + 'keep *_l1pfProducerHF_*_*', + 'keep *_l1pfCandidates_*_*', + 'keep *_ak4PFL1Calo_*_*', + 'keep *_ak4PFL1PF_*_*', + 'keep *_ak4PFL1Puppi_*_*', + 'keep *_ak4PFL1CaloCorrected_*_*', + 'keep *_ak4PFL1PFCorrected_*_*', + 'keep *_ak4PFL1PuppiCorrected_*_*', + 'keep *_l1PFMetCalo_*_*', + 'keep *_l1PFMetPF_*_*', + 'keep *_l1PFMetPuppi_*_*', + 'keep *_TTStubsFromPhase2TrackerDigis_*_*', + 'keep *_TTClustersFromPhase2TrackerDigis_*_*', + 'keep *_TTTracksFromExtendedTrackletEmulation_*_*', + 'keep *_TTTracksFromTrackletEmulation_*_*', + ] + obj.outputCommands += l1Phase2Digis + +from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger +phase2_muon.toModify(L1TriggerFEVTDEBUG, func=_appendPhase2Digis) diff --git a/L1Trigger/Configuration/python/SimL1Emulator_cff.py b/L1Trigger/Configuration/python/SimL1Emulator_cff.py index 19b37622c0e6e..817ed38a3ca4e 100644 --- a/L1Trigger/Configuration/python/SimL1Emulator_cff.py +++ b/L1Trigger/Configuration/python/SimL1Emulator_cff.py @@ -58,10 +58,109 @@ # soon to be removed when availble in GTs from L1Trigger.L1TTwinMux.fakeTwinMuxParams_cff import * -# Customisation for the phase2_hgcal era. Includes the HGCAL L1 trigger -from L1Trigger.L1THGCal.hgcalTriggerPrimitives_cff import * _phase2_siml1emulator = SimL1EmulatorTask.copy() + +# ######################################################################## +# ######################################################################## +# +# Phase-2 +# +# ######################################################################## +# ######################################################################## + +# ######################################################################## +# Phase-2 Trigger Primitives +# ######################################################################## + +# HGCAL TP +# ######################################################################## +from L1Trigger.L1THGCal.hgcalTriggerPrimitives_cff import * _phase2_siml1emulator.add(hgcalTriggerPrimitivesTask) + +# ######################################################################## +# Phase 2 L1T +# ######################################################################## + +# Barrel and EndCap EGamma +# ######################################################################## + +from L1Trigger.L1CaloTrigger.L1EGammaCrystalsEmulatorProducer_cfi import * +_phase2_siml1emulator.add(L1EGammaClusterEmuProducer) + +from L1Trigger.L1CaloTrigger.l1EGammaEEProducer_cfi import * +_phase2_siml1emulator.add(l1EGammaEEProducer) + +# ######################################################################## +# Phase-2 L1T - TrackTrigger dependent modules +# ######################################################################## + +# Tk + StandaloneObj, including L1TkPrimaryVertex +# ######################################################################## +from L1Trigger.L1TTrackMatch.L1TkObjectProducers_cff import * + +_phase2_siml1emulator.add(L1TkPrimaryVertex) + +_phase2_siml1emulator.add(L1TkElectronsCrystal) +_phase2_siml1emulator.add(L1TkElectronsLooseCrystal) +_phase2_siml1emulator.add(L1TkElectronsEllipticMatchCrystal) +_phase2_siml1emulator.add(L1TkIsoElectronsCrystal) +_phase2_siml1emulator.add(L1TkPhotonsCrystal) + +_phase2_siml1emulator.add(L1TkElectronsHGC) +_phase2_siml1emulator.add(L1TkElectronsEllipticMatchHGC) +_phase2_siml1emulator.add(L1TkIsoElectronsHGC) +_phase2_siml1emulator.add(L1TkPhotonsHGC) + +_phase2_siml1emulator.add( L1TkMuons ) + +# PF Candidates +# ######################################################################## +from L1Trigger.Phase2L1ParticleFlow.l1ParticleFlow_cff import * +_phase2_siml1emulator.add(l1ParticleFlowTask) + +# PF JetMET +# ######################################################################## +from L1Trigger.Phase2L1ParticleFlow.l1pfJetMet_cff import * +# Describe here l1PFJets Task +# ############################### +l1PFJetsTask = cms.Task( + ak4PFL1Calo , ak4PFL1PF , ak4PFL1Puppi , + ak4PFL1CaloCorrected , ak4PFL1PFCorrected , ak4PFL1PuppiCorrected) +_phase2_siml1emulator.add(l1PFJetsTask) +# Describe here l1PFMets Task +# ############################### +l1PFMetsTask = cms.Task(l1PFMetCalo , l1PFMetPF , l1PFMetPuppi) +_phase2_siml1emulator.add(l1PFMetsTask) + +# --> add modules +#%% # Barrel EGamma +#%% # ######################################################################## +from L1Trigger.L1CaloTrigger.L1EGammaCrystalsEmulatorProducer_cfi import * +_phase2_siml1emulator.add(L1EGammaClusterEmuProducer) + +from L1Trigger.L1CaloTrigger.l1EGammaEEProducer_cfi import * +_phase2_siml1emulator.add(l1EGammaEEProducer) + +# Tk + StandaloneObj, including L1TkPrimaryVertex +# ######################################################################## +from L1Trigger.L1TTrackMatch.L1TkObjectProducers_cff import * + +_phase2_siml1emulator.add(L1TkPrimaryVertex) + +_phase2_siml1emulator.add(L1TkElectronsCrystal) +_phase2_siml1emulator.add(L1TkElectronsLooseCrystal) +_phase2_siml1emulator.add(L1TkElectronsEllipticMatchCrystal) +_phase2_siml1emulator.add(L1TkIsoElectronsCrystal) +_phase2_siml1emulator.add(L1TkPhotonsCrystal) + +_phase2_siml1emulator.add(L1TkElectronsHGC) +_phase2_siml1emulator.add(L1TkElectronsEllipticMatchHGC) +_phase2_siml1emulator.add(L1TkIsoElectronsHGC) +_phase2_siml1emulator.add(L1TkPhotonsHGC) + +_phase2_siml1emulator.add( L1TkMuons ) + -from Configuration.Eras.Modifier_phase2_hgcal_cff import phase2_hgcal -phase2_hgcal.toReplaceWith( SimL1EmulatorTask , _phase2_siml1emulator ) +from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger +from Configuration.Eras.Modifier_phase2_trackerV14_cff import phase2_trackerV14 +(phase2_trigger & phase2_trackerV14).toReplaceWith( SimL1EmulatorTask , _phase2_siml1emulator) diff --git a/L1Trigger/Configuration/python/customisePhase2TTNoMC.py b/L1Trigger/Configuration/python/customisePhase2TTNoMC.py new file mode 100644 index 0000000000000..66e84b7921e3d --- /dev/null +++ b/L1Trigger/Configuration/python/customisePhase2TTNoMC.py @@ -0,0 +1,8 @@ +import FWCore.ParameterSet.Config as cms + +def customisePhase2TTNoMC(process): + process.L1TrackTrigger.replace(process.L1PromptExtendedHybridTracksWithAssociators, process.L1PromptExtendedHybridTracks) + process.L1TrackTrigger.remove(process.TrackTriggerAssociatorClustersStubs) + process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') + + return process diff --git a/L1Trigger/Configuration/python/customisePhase2TTOn110.py b/L1Trigger/Configuration/python/customisePhase2TTOn110.py new file mode 100644 index 0000000000000..58ee2163d29e9 --- /dev/null +++ b/L1Trigger/Configuration/python/customisePhase2TTOn110.py @@ -0,0 +1,10 @@ +import FWCore.ParameterSet.Config as cms + +def customisePhase2TTOn110(process): + process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') + #when running directly, the ttclusterassoc uses the "mix" product name + #however its ediased to simSiPixelDigis so its output with that name + #so we have to adjust the input tag + process.TTClusterAssociatorFromPixelDigis.digiSimLinks = cms.InputTag('simSiPixelDigis','Tracker') + + return process diff --git a/L1Trigger/Configuration/python/customiseReEmul.py b/L1Trigger/Configuration/python/customiseReEmul.py index eb3eca67a4970..082ee58efd537 100644 --- a/L1Trigger/Configuration/python/customiseReEmul.py +++ b/L1Trigger/Configuration/python/customiseReEmul.py @@ -75,8 +75,12 @@ def L1TReEmulFromRAW2015(process): srcCSC = "csctfDigis" ) stage2L1Trigger.toModify(process.simBmtfDigis, - DTDigi_Source = "simTwinMuxDigis", - DTDigi_Theta_Source = "dttfDigis" + DTDigi_Source = "simTwinMuxDigis", + DTDigi_Theta_Source = "dttfDigis" + ) + stage2L1Trigger.toModify(process.simKBmtfStubs, + srcPhi = "simTwinMuxDigis", + srcTheta = "dttfDigis" ) stage2L1Trigger.toModify(process.simEmtfDigis, CSCInput = "csctfDigis", @@ -141,8 +145,13 @@ def L1TReEmulFromRAW2016(process): ) # BMTF stage2L1Trigger.toModify(process.simBmtfDigis, - DTDigi_Source = 'simTwinMuxDigis', - DTDigi_Theta_Source = 'bmtfDigis' + DTDigi_Source = "simTwinMuxDigis", + DTDigi_Theta_Source = "bmtfDigis" + ) + # KBMTF + stage2L1Trigger.toModify(process.simKBmtfStubs, + srcPhi = 'simTwinMuxDigis', + srcTheta = 'bmtfDigis' ) # OMTF stage2L1Trigger.toModify(process.simOmtfDigis, @@ -291,6 +300,11 @@ def L1TReEmulFromRAWsimTP(process): DTDigi_Source = 'simTwinMuxDigis', DTDigi_Theta_Source = 'simDtTriggerPrimitiveDigis' ) + # KBMTF + stage2L1Trigger.toModify(process.simKBmtfStubs, + srcPhi = "simTwinMuxDigis", + srcTheta = "simDtTriggerPrimitiveDigis" + ) # OMTF stage2L1Trigger.toModify(process.simOmtfDigis, srcRPC = 'muonRPCDigis', diff --git a/L1Trigger/DTTriggerPhase2/BuildFile.xml b/L1Trigger/DTTriggerPhase2/BuildFile.xml new file mode 100644 index 0000000000000..61b5fb6050528 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/BuildFile.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/doc/qualities.txt b/L1Trigger/DTTriggerPhase2/doc/qualities.txt new file mode 100644 index 0000000000000..a28603daa7045 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/doc/qualities.txt @@ -0,0 +1,20 @@ +Just to keep track of the fast evolving quality definition +######################################################### +DT quality code +--------------- +1, 2: 3-hit in a single SL +3, 4: 4-hit in a single SL (3 means that there are other TP in this SL, 4 that it is the only one) +5: 3-hit in a single SL + 1 or 2 hits in the other SL +6: 3-hit in both SL +7: 4-hit in a single SL + 1 or 2 hits in the other SL +8: 4-hit in a SL + 3-hit in the other SL +9: 4-hit in both SL + +RPC Flag (tells how RPC was used) #FIXME being implemented, not everything available yet +--------------------------------- +0: segment that could not be matched to any RPC cluster (or 'useRPC' option is set to false) +1: RPC used to overwrite TP timing info (both t0 and BX) +2: RPC only segment +3: RPC single hit not associated to any DT segment +4: RPC used to confirm the presence of the TP, but not used to recompute any of its quantities +5: RPC single hit associated with a DT segment (only kept if 'storeAllRPCHits' is set to True, which not the default) diff --git a/L1Trigger/DTTriggerPhase2/interface/CandidateGroup.h b/L1Trigger/DTTriggerPhase2/interface/CandidateGroup.h new file mode 100644 index 0000000000000..6195bb32b20b6 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/CandidateGroup.h @@ -0,0 +1,62 @@ +#ifndef L1Trigger_DTTriggerPhase2_CandidateGroup_h +#define L1Trigger_DTTriggerPhase2_CandidateGroup_h + +#include +#include +#include +#include +#include + +#include "L1Trigger/DTTriggerPhase2/interface/DTprimitive.h" +#include "L1Trigger/DTTriggerPhase2/interface/DTPattern.h" + +namespace dtbayesam { + + typedef std::bitset<8> qualitybits; + + class CandidateGroup { + public: + //Constructors and destructors + CandidateGroup(); + CandidateGroup(DTPattern* p); + ~CandidateGroup(); + + //Hit operation procedures + void addHit(DTPrimitive dthit, int lay, bool isGood); + void removeHit(DTPrimitive dthit); + + //Get Methods + int candId() const { return candId_; }; + int nhits() const { return nhits_; }; + int nisGood() const { return nisGood_; }; + int nLayerhits() const { return nLayerhits_; }; + int nLayerUp() const { return nLayerUp_; }; + int nLayerDown() const { return nLayerDown_; }; + DTPrimitivePtrs candHits() const { return candHits_; }; + qualitybits quality() const { return quality_; }; + const DTPattern* pattern() const { return pattern_; }; + + //Set Methods + void setCandId(int cId) { candId_ = cId; }; + + //Pattern rankers + bool operator>(const CandidateGroup& cOther) const; + bool operator==(const CandidateGroup& cOther) const; + + private: + DTPrimitivePtrs candHits_; + qualitybits quality_; + int nhits_; + int nLayerhits_; + int nLayerUp_; + int nLayerDown_; + int nisGood_; + DTPattern* pattern_; + int candId_; + }; + + typedef std::shared_ptr CandidateGroupPtr; + typedef std::vector CandidateGroupPtrs; +}; // namespace dtbayesam + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/DTPattern.h b/L1Trigger/DTTriggerPhase2/interface/DTPattern.h new file mode 100644 index 0000000000000..5841070e42775 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/DTPattern.h @@ -0,0 +1,63 @@ +#ifndef L1Trigger_DTTriggerPhase2_DTPattern_h +#define L1Trigger_DTTriggerPhase2_DTPattern_h + +#include +#include +#include + +// Typedef for refHits organized as [SL, Cell, Laterality]. Using integers is an +// overkill for something that only needs 3, 7 and 2 bits. +typedef std::tuple RefDTPatternHit; +// Another overkill typing for the pattern identifier +// [SLUp, SLDown, ChambedUp-ChamberDown], only need 3, 3 and 5 bits +typedef std::tuple DTPatternIdentifier; + +class DTPattern { + // A pattern is a seed plus a set of hits. Translational simmetry is used to + // translate it across all posible recoHits in the lower (upper layer) and + // check for pattern hit matches of recohits. +public: + //Constructors and destructors + DTPattern(); + DTPattern(RefDTPatternHit seedUp, RefDTPatternHit seedDown); + DTPattern(int SL1, int SL2, int diff); + virtual ~DTPattern(); + + //Adding hits to the pattern + void addHit(RefDTPatternHit hit); + // Given the up and down seeding hits check if a given hit is in the pattern. + // Returns -1 for left laterality, +1 for right laterality, 0 if undecided + // and -999 if not in the pattern + int latHitIn(int slId, int chId, int allowedVariance) const; + + // When comparing with a given set of hits we need to set up at least one of + // those two to compute the translation + void setHitUp(int chIdUp) { recoseedUp_ = chIdUp; } + void setHitDown(int chIdDown) { recoseedDown_ = chIdDown; } + + //Get methods + DTPatternIdentifier id() const { return id_; } + int sl1() const { return std::get<0>(id_); } + int sl2() const { return std::get<1>(id_); } + int diff() const { return std::get<2>(id_); } + const std::vector &genHits() const { return genHits_; } + + //Printing + friend std::ostream &operator<<(std::ostream &out, DTPattern &p); + +private: + //Generated seeds + RefDTPatternHit seedUp_; + RefDTPatternHit seedDown_; + // Generated hits + std::vector genHits_; + // Pattern is classified in terms of SL + chamber differences to profit from + // translational invariance + DTPatternIdentifier id_; + //Generated seeds + hits translated to a given seed pair + int recoseedUp_; + int recoseedDown_; + bool debug_ = false; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/DTprimitive.h b/L1Trigger/DTTriggerPhase2/interface/DTprimitive.h new file mode 100644 index 0000000000000..cec71913409f8 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/DTprimitive.h @@ -0,0 +1,57 @@ +#ifndef L1Trigger_DTTriggerPhase2_DTprimitive_h +#define L1Trigger_DTTriggerPhase2_DTprimitive_h + +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include +#include +#include + +class DTPrimitive { +public: + DTPrimitive(); + DTPrimitive(std::shared_ptr& ptr); + DTPrimitive(DTPrimitive* ptr); + virtual ~DTPrimitive(); + + bool isValidTime(); + float wireHorizPos(); + + void setTimeCorrection(int time) { timeCorrection_ = time; }; + void setTDCTimeStamp(int tstamp) { tdcTimeStamp_ = tstamp; }; + void setOrbit(int orb) { orbit_ = orb; } + void setPayload(double hitTag, int idx) { this->payLoad_[idx] = hitTag; }; + void setChannelId(int channel) { channelId_ = channel; }; + void setLayerId(int layer) { layerId_ = layer; }; + void setCameraId(int camera) { cameraId_ = camera; }; + void setSuperLayerId(int lay) { superLayerId_ = lay; }; + void setLaterality(cmsdt::LATERAL_CASES lat) { laterality_ = lat; }; + + const int timeCorrection() const { return timeCorrection_; }; + const int tdcTimeStamp() const { return tdcTimeStamp_; }; + const int orbit() const { return orbit_; }; + const int tdcTimeStampNoOffset() const { return tdcTimeStamp_ - timeCorrection_; }; + const double payLoad(int idx) const { return payLoad_[idx]; }; + const int channelId() const { return channelId_; }; + const int layerId() const { return layerId_; }; + const int cameraId() const { return cameraId_; }; + const int superLayerId() const { return superLayerId_; }; + const cmsdt::LATERAL_CASES laterality() const { return laterality_; }; + +private: + int cameraId_; // Chamber ID + int superLayerId_; // SL ID + int layerId_; // Layer ID + int channelId_; // Wire number + cmsdt::LATERAL_CASES laterality_; // LEFT, RIGHT, NONE + + int timeCorrection_; + int tdcTimeStamp_; + int orbit_; + double payLoad_[cmsdt::PAYLOAD_ENTRIES]; +}; + +typedef std::vector DTPrimitives; +typedef std::shared_ptr DTPrimitivePtr; +typedef std::vector DTPrimitivePtrs; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/HoughGrouping.h b/L1Trigger/DTTriggerPhase2/interface/HoughGrouping.h new file mode 100644 index 0000000000000..61d498d0d39ac --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/HoughGrouping.h @@ -0,0 +1,106 @@ +#ifndef L1Trigger_DTTriggerPhase2_HoughGrouping_h +#define L1Trigger_DTTriggerPhase2_HoughGrouping_h + +// System / std headers +#include +#include +#include +#include +#include + +// Other headers +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/DTprimitive.h" +#include "L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h" + +// =============================================================================== +// Class declarations +// =============================================================================== +struct ProtoCand { + unsigned short int nLayersWithHits_; // 0: # of layers with hits. + std::vector isThereHitInLayer_; // 1: # of hits of high quality (the expected line crosses the cell). + std::vector + isThereNeighBourHitInLayer_; // 2: # of hits of low quality (the expected line is in a neighbouring cell). + unsigned short int nHitsDiff_; // 3: absolute diff. between the number of hits in SL1 and SL3. + std::vector xDistToPattern_; // 4: absolute distance to all hits of the segment. + DTPrimitives dtHits_; // 5: DTPrimitive of the candidate. +}; + +typedef std::pair PointInPlane; +typedef std::vector PointsInPlane; +typedef std::tuple PointTuple; +typedef std::vector PointTuples; +typedef std::map PointMap; + +class HoughGrouping : public MotherGrouping { +public: + // Constructors and destructor + HoughGrouping(const edm::ParameterSet& pset, edm::ConsumesCollector& iC); + ~HoughGrouping() override; + + // Main methods + void initialise(const edm::EventSetup& iEventSetup) override; + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& outMpath) override; + void finish() override; + + // Other public methods + // Public attributes + +private: + // Private methods + void resetAttributes(); + void resetPosElementsOfLinespace(); + + void obtainGeometricalBorders(const DTLayer* lay); + + void doHoughTransform(); + + PointsInPlane getMaximaVector(); + PointsInPlane findTheMaxima(PointTuples& inputvec); + + PointInPlane getTwoDelta(const PointTuple& pair1, const PointTuple& pair2); + PointInPlane getAveragePoint(const PointTuples& inputvec, + unsigned short int firstindex, + const std::vector& indexlist); + PointInPlane transformPair(const PointInPlane& inputpair); + + ProtoCand associateHits(const DTChamber* thechamb, double m, double n); + + void orderAndFilter(std::vector& invector, MuonPathPtrs& outMuonPath); + + void setDifferenceBetweenSL(ProtoCand& tupl); + bool areThereEnoughHits(const ProtoCand& tupl); + + // Private attributes + bool debug_, allowUncorrelatedPatterns_; + unsigned short int minNLayerHits_, minSingleSLHitsMax_, minSingleSLHitsMin_, minUncorrelatedHits_, upperNumber_, + lowerNumber_; + double angletan_, anglebinwidth_, posbinwidth_, maxdeltaAngDeg_, maxdeltaPos_, maxDistanceToWire_; + + DTGeometry const* dtGeo_; + edm::ESGetToken dtGeomH; + DTChamberId TheChambId; + + double maxrads_, minangle_, oneanglebin_; + double xlowlim_, xhighlim_, zlowlim_, zhighlim_; + double maxdeltaAng_; + + unsigned short int anglebins_, halfanglebins_, spacebins_; + unsigned short int idigi_, nhits_; + unsigned short int thestation_, thesector_; + short int thewheel_; + + std::vector> linespace_; + + PointMap anglemap_; + PointMap posmap_; + std::map digimap_[8]; + + PointsInPlane maxima_; + PointsInPlane hitvec_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/InitialGrouping.h b/L1Trigger/DTTriggerPhase2/interface/InitialGrouping.h new file mode 100644 index 0000000000000..1a8bb034b83bb --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/InitialGrouping.h @@ -0,0 +1,98 @@ +#ifndef Phase2L1Trigger_DTTrigger_InitialGrouping_h +#define Phase2L1Trigger_DTTrigger_InitialGrouping_h + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/DTSuperLayerId.h" +#include "DataFormats/MuonDetId/interface/DTLayerId.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" +#include "DataFormats/DTDigi/interface/DTDigiCollection.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +/* + Channels are labeled following next schema: + --------------------------------- + | 6 | 7 | 8 | 9 | + --------------------------------- + | 3 | 4 | 5 | + ------------------------- + | 1 | 2 | + ----------------- + | 0 | + --------- +*/ + +namespace dtamgrouping { + /* Cell's combination, following previous labeling, to obtain every possible muon's path. + Others cells combinations imply non straight paths */ + constexpr int CHANNELS_PATH_ARRANGEMENTS[8][4] = { + {0, 1, 3, 6}, {0, 1, 3, 7}, {0, 1, 4, 7}, {0, 1, 4, 8}, {0, 2, 4, 7}, {0, 2, 4, 8}, {0, 2, 5, 8}, {0, 2, 5, 9}}; + + /* For each of the previous cell's combinations, this array stores the associated cell's + displacement, relative to lower layer cell, measured in semi-cell length units */ + + constexpr int CELL_HORIZONTAL_LAYOUTS[8][4] = {{0, -1, -2, -3}, + {0, -1, -2, -1}, + {0, -1, 0, -1}, + {0, -1, 0, 1}, + {0, 1, 0, -1}, + {0, 1, 0, 1}, + {0, 1, 2, 1}, + {0, 1, 2, 3}}; +} // namespace dtamgrouping + +// =============================================================================== +// Class declarations +// =============================================================================== + +class InitialGrouping : public MotherGrouping { +public: + // Constructors and destructor + InitialGrouping(const edm::ParameterSet& pset, edm::ConsumesCollector& iC); + ~InitialGrouping() override; + + // Main methods + void initialise(const edm::EventSetup& iEventSetup) override; + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& outMpath) override; + void finish() override; + + // Other public methods + + // Public attributes + +private: + // Private methods + void setInChannels(const DTDigiCollection* digi, int sl); + void selectInChannels(int baseCh); + void resetPrvTDCTStamp(void); + void mixChannels(int sl, int pathId, MuonPathPtrs& outMpath); + bool notEnoughDataInChannels(void); + bool isEqualComb2Previous(DTPrimitives& ptr); + + // Private attributes + bool debug_; + + DTPrimitives muxInChannels_[cmsdt::NUM_CELLS_PER_BLOCK]; + DTPrimitives channelIn_[cmsdt::NUM_LAYERS][cmsdt::NUM_CH_PER_LAYER]; + DTPrimitives chInDummy_; + int prevTDCTimeStamps_[4]; + int currentBaseChannel_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MPFilter.h b/L1Trigger/DTTriggerPhase2/interface/MPFilter.h new file mode 100644 index 0000000000000..95df42c84c4f5 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MPFilter.h @@ -0,0 +1,55 @@ +#ifndef Phase2L1Trigger_DTTrigger_MPFilter_h +#define Phase2L1Trigger_DTTrigger_MPFilter_h + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" +#include "Geometry/Records/interface/MuonGeometryRecord.h" + +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/DTGeometry/interface/DTLayer.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MPFilter { +public: + // Constructors and destructor + MPFilter(const edm::ParameterSet& pset); + virtual ~MPFilter(); + + // Main methods + virtual void initialise(const edm::EventSetup& iEventSetup) = 0; + virtual void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + std::vector& inMPath, + std::vector& outMPath) = 0; + virtual void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + MuonPathPtrs& inMPath, + MuonPathPtrs& outMPath) = 0; + + virtual void finish() = 0; + + // Other public methods + +private: + // Private attributes + bool debug_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h b/L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h new file mode 100644 index 0000000000000..11b5624769b93 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h @@ -0,0 +1,55 @@ +#ifndef Phase2L1Trigger_DTTrigger_MPQualityEnhancerFilter_h +#define Phase2L1Trigger_DTTrigger_MPQualityEnhancerFilter_h + +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MPQualityEnhancerFilter : public MPFilter { +public: + // Constructors and destructor + MPQualityEnhancerFilter(const edm::ParameterSet &pset); + ~MPQualityEnhancerFilter() override; + + // Main methods + void initialise(const edm::EventSetup &iEventSetup) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + std::vector &inMPath, + std::vector &outMPath) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMPath, + MuonPathPtrs &outMPath) override{}; + + void finish() override; + + // Other public methods + + // Public attributes + int areCousins(cmsdt::metaPrimitive mp1, cmsdt::metaPrimitive mp2); + int rango(cmsdt::metaPrimitive mp); + void printmP(cmsdt::metaPrimitive mP); + +private: + // Private methods + void filterCousins(std::vector &inMPath, std::vector &outMPath); + void refilteringCousins(std::vector &inMPath, std::vector &outMPath); + void filterTanPhi(std::vector &inMPath, std::vector &outMPath); + void filterUnique(std::vector &inMPath, std::vector &outMPath); + + // Private attributes + bool debug_; + bool filter_cousins_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h b/L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h new file mode 100644 index 0000000000000..4ba9d7eab92e4 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h @@ -0,0 +1,48 @@ +#ifndef Phase2L1Trigger_DTTrigger_MPRedundantFilter_h +#define Phase2L1Trigger_DTTrigger_MPRedundantFilter_h + +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" + +#include +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MPRedundantFilter : public MPFilter { +public: + // Constructors and destructor + MPRedundantFilter(const edm::ParameterSet& pset); + ~MPRedundantFilter() override; + + // Main methods + void initialise(const edm::EventSetup& iEventSetup) override; + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + std::vector& inMPath, + std::vector& outMPath) override{}; + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + MuonPathPtrs& inMPath, + MuonPathPtrs& outMPath) override; + void finish() override { buffer_.clear(); }; + + // Other public methods + +private: + void filter(MuonPathPtr& mpath, MuonPathPtrs& outMPaths); + bool isInBuffer(MuonPathPtr& mpath); + + // Private attributes + bool debug_; + unsigned int maxBufferSize_; + std::deque buffer_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h b/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h new file mode 100644 index 0000000000000..fbab714a359c5 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h @@ -0,0 +1,54 @@ +#ifndef Phase2L1Trigger_DTTrigger_MotherGrouping_h +#define Phase2L1Trigger_DTTrigger_MotherGrouping_h + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" + +#include "DataFormats/DTDigi/interface/DTDigiCollection.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +#include "Geometry/Records/interface/MuonGeometryRecord.h" +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/DTGeometry/interface/DTLayer.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MotherGrouping { +public: + // Constructors and destructor + MotherGrouping(const edm::ParameterSet& pset, edm::ConsumesCollector& iC); + virtual ~MotherGrouping(); + + // Main methods + virtual void initialise(const edm::EventSetup& iEventSetup); + virtual void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& outMpath); + virtual void finish(); + + // Other public methods + + // Public attributes + +private: + // Private methods + + // Private attributes + bool debug_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPath.h b/L1Trigger/DTTriggerPhase2/interface/MuonPath.h new file mode 100644 index 0000000000000..cb5a268355628 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPath.h @@ -0,0 +1,124 @@ +#ifndef L1Trigger_DTTriggerPhase2_MuonPath_h +#define L1Trigger_DTTriggerPhase2_MuonPath_h +#include +#include + +#include "L1Trigger/DTTriggerPhase2/interface/DTprimitive.h" + +class MuonPath { +public: + MuonPath(); + MuonPath(DTPrimitivePtrs &ptrPrimitive, int prup = 0, int prdw = 0); + MuonPath(DTPrimitives &ptrPrimitive, int prup = 0, int prdw = 0); + MuonPath(std::shared_ptr &ptr); + virtual ~MuonPath() {} + + // setter methods + void setPrimitive(DTPrimitivePtr &ptr, int layer); + void setNPrimitives(short nprim) { nprimitives_ = nprim; } + void setNPrimitivesUp(short nprim) { nprimitivesUp_ = nprim; } + void setNPrimitivesDown(short nprim) { nprimitivesDown_ = nprim; } + void setCellHorizontalLayout(int layout[4]); + void setCellHorizontalLayout(const int *layout); + void setBaseChannelId(int bch) { baseChannelId_ = bch; } + void setQuality(cmsdt::MP_QUALITY qty) { quality_ = qty; } + void setBxTimeValue(int time); + void setLateralComb(cmsdt::LATERAL_CASES latComb[4]); + void setLateralComb(const cmsdt::LATERAL_CASES *latComb); + void setLateralCombFromPrimitives(void); + + void setHorizPos(float pos) { horizPos_ = pos; } + void setTanPhi(float tanPhi) { tanPhi_ = tanPhi; } + void setChiSquare(float chi) { chiSquare_ = chi; } + void setPhi(float phi) { phi_ = phi; } + void setPhiB(float phib) { phiB_ = phib; } + void setXCoorCell(float x, int cell) { xCoorCell_[cell] = x; } + void setDriftDistance(float dx, int cell) { xDriftDistance_[cell] = dx; } + void setXWirePos(float x, int cell) { xWirePos_[cell] = x; } + void setZWirePos(float z, int cell) { zWirePos_[cell] = z; } + void setTWireTDC(float t, int cell) { tWireTDC_[cell] = t; } + void setRawId(uint32_t id) { rawId_ = id; } + + // getter methods + DTPrimitivePtr primitive(int layer) const { return prim_[layer]; } + short nprimitives() const { return nprimitives_; } + short nprimitivesDown() const { return nprimitivesDown_; } + short nprimitivesUp() const { return nprimitivesUp_; } + const int *cellLayout() const { return cellLayout_; } + int baseChannelId() const { return baseChannelId_; } + cmsdt::MP_QUALITY quality() const { return quality_; } + int bxTimeValue() const { return bxTimeValue_; } + int bxNumId() const { return bxNumId_; } + float tanPhi() const { return tanPhi_; } + const cmsdt::LATERAL_CASES *lateralComb() const { return (lateralComb_); } + float horizPos() const { return horizPos_; } + float chiSquare() const { return chiSquare_; } + float phi() const { return phi_; } + float phiB() const { return phiB_; } + float xCoorCell(int cell) const { return xCoorCell_[cell]; } + float xDriftDistance(int cell) const { return xDriftDistance_[cell]; } + float xWirePos(int cell) const { return xWirePos_[cell]; } + float zWirePos(int cell) const { return zWirePos_[cell]; } + float tWireTDC(int cell) const { return tWireTDC_[cell]; } + uint32_t rawId() const { return rawId_; } + + // Other methods + bool isEqualTo(MuonPath *ptr); + bool isAnalyzable(); + bool completeMP(); + +private: + //------------------------------------------------------------------ + //--- MuonPath's data + //------------------------------------------------------------------ + /* + Primitives that make up the path. The 0th position holds the channel ID of + the lower layer. The order is critical. + */ + DTPrimitivePtrs prim_; //ENSURE that there are no more than 4-8 prims + short nprimitives_; + short nprimitivesUp_; + short nprimitivesDown_; + + /* Horizontal position of each cell (one per layer), in half-cell units, + with respect of the lower layer (layer 0). + */ + int cellLayout_[cmsdt::NUM_LAYERS]; + int baseChannelId_; + + //------------------------------------------------------------------ + //--- Fit results: + //------------------------------------------------------------------ + /* path quality */ + cmsdt::MP_QUALITY quality_; + + /* Lateral combination */ + cmsdt::LATERAL_CASES lateralComb_[cmsdt::NUM_LAYERS]; + + /* BX time value with respect to BX0 of the orbit */ + int bxTimeValue_; + + /* BX number in the orbit */ + int bxNumId_; + + /* Cell parameters */ + float xCoorCell_[cmsdt::NUM_LAYERS_2SL]; // Horizontal position of the hit in each cell + float xDriftDistance_[cmsdt::NUM_LAYERS_2SL]; // Drift distance on the cell (absolute value) + float xWirePos_[cmsdt::NUM_LAYERS_2SL]; + float zWirePos_[cmsdt::NUM_LAYERS_2SL]; + float tWireTDC_[cmsdt::NUM_LAYERS_2SL]; + + float tanPhi_; + float horizPos_; + float chiSquare_; + float phi_; + float phiB_; + + uint32_t rawId_; +}; + +typedef std::vector MuonPaths; +typedef std::shared_ptr MuonPathPtr; +typedef std::vector MuonPathPtrs; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h new file mode 100644 index 0000000000000..159a6289273e0 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h @@ -0,0 +1,67 @@ +#ifndef Phase2L1Trigger_DTTrigger_MuonPathAnalyzer_h +#define Phase2L1Trigger_DTTrigger_MuonPathAnalyzer_h + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/FrameworkfwdMostUsed.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/DTSuperLayerId.h" +#include "DataFormats/MuonDetId/interface/DTLayerId.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +#include "Geometry/Records/interface/MuonGeometryRecord.h" +#include "Geometry/DTGeometry/interface/DTGeometry.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MuonPathAnalyzer { +public: + // Constructors and destructor + MuonPathAnalyzer(const edm::ParameterSet& pset, edm::ConsumesCollector& iC); + virtual ~MuonPathAnalyzer(); + + // Main methods + virtual void initialise(const edm::EventSetup& iEventSetup); + virtual void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + MuonPathPtrs& inMpath, + std::vector& metaPrimitives) = 0; + virtual void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + MuonPathPtrs& inMpath, + MuonPathPtrs& outMPath) = 0; + + virtual void finish(); + + // Other public methods + + // Public attributes + +private: + // Private methods + + // Private attributes + bool debug_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h new file mode 100644 index 0000000000000..3baf7556d7309 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h @@ -0,0 +1,83 @@ +#ifndef L1Trigger_DTTriggerPhase2_MuonPathAnalyzerInChamber_h +#define L1Trigger_DTTriggerPhase2_MuonPathAnalyzerInChamber_h + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== +namespace { + constexpr int NLayers = 8; + typedef std::array TLateralities; +} // namespace +// =============================================================================== +// Class declarations +// =============================================================================== + +class MuonPathAnalyzerInChamber : public MuonPathAnalyzer { +public: + // Constructors and destructor + MuonPathAnalyzerInChamber(const edm::ParameterSet &pset, edm::ConsumesCollector &iC); + ~MuonPathAnalyzerInChamber() override; + + // Main methods + void initialise(const edm::EventSetup &iEventSetup) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMpath, + std::vector &metaPrimitives) override {} + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMpath, + MuonPathPtrs &outMPath) override; + + void finish() override; + + // Other public methods + void setBxTolerance(int t) { bxTolerance_ = t; }; + void setMinHits4Fit(int h) { minHits4Fit_ = h; }; + void setChiSquareThreshold(float ch2Thr) { chiSquareThreshold_ = ch2Thr; }; + void setMinimumQuality(cmsdt::MP_QUALITY q) { + if (minQuality_ >= cmsdt::LOWQGHOST) + minQuality_ = q; + }; + + int bxTolerance(void) { return bxTolerance_; }; + int minHits4Fit(void) { return minHits4Fit_; }; + cmsdt::MP_QUALITY minQuality(void) { return minQuality_; }; + + bool hasPosRF(int wh, int sec) { return wh > 0 || (wh == 0 && sec % 4 > 1); }; + + // Public attributes + DTGeometry const *dtGeo_; + edm::ESGetToken dtGeomH; + + //shift + std::map shiftinfo_; + +private: + // Private methods + void analyze(MuonPathPtr &inMPath, MuonPathPtrs &outMPaths); + + void setCellLayout(MuonPathPtr &mpath); + void buildLateralities(MuonPathPtr &mpath); + void setLateralitiesInMP(MuonPathPtr &mpath, TLateralities lat); + void setWirePosAndTimeInMP(MuonPathPtr &mpath); + void calculateFitParameters(MuonPathPtr &mpath, TLateralities lat, int present_layer[NLayers]); + + void evaluateQuality(MuonPathPtr &mPath); + int totalNumValLateralities_; + std::vector lateralities_; + std::vector latQuality_; + + bool debug_; + double chi2Th_; + edm::FileInPath shift_filename_; + int bxTolerance_; + cmsdt::MP_QUALITY minQuality_; + float chiSquareThreshold_; + short minHits4Fit_; + int cellLayout_[NLayers]; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h new file mode 100644 index 0000000000000..7352ea9677bdd --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h @@ -0,0 +1,103 @@ +#ifndef L1Trigger_DTTriggerPhase2_MuonPathAnalyzerPerSL_h +#define L1Trigger_DTTriggerPhase2_MuonPathAnalyzerPerSL_h + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MuonPathAnalyzerPerSL : public MuonPathAnalyzer { +public: + // Constructors and destructor + MuonPathAnalyzerPerSL(const edm::ParameterSet &pset, edm::ConsumesCollector &iC); + ~MuonPathAnalyzerPerSL() override; + + // Main methods + void initialise(const edm::EventSetup &iEventSetup) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMpath, + std::vector &metaPrimitives) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMpath, + MuonPathPtrs &outMPath) override{}; + + void finish() override; + + // Other public methods + void setBXTolerance(int t) { bxTolerance_ = t; }; + int bxTolerance(void) { return bxTolerance_; }; + + void setChiSquareThreshold(float ch2Thr) { chiSquareThreshold_ = ch2Thr; }; + + void setMinQuality(cmsdt::MP_QUALITY q) { + if (minQuality_ >= cmsdt::LOWQGHOST) + minQuality_ = q; + }; + cmsdt::MP_QUALITY minQuality(void) { return minQuality_; }; + + bool hasPosRF(int wh, int sec) { return wh > 0 || (wh == 0 && sec % 4 > 1); }; + + // Public attributes + DTGeometry const *dtGeo_; + edm::ESGetToken dtGeomH; + + //shift + edm::FileInPath shift_filename_; + std::map shiftinfo_; + + int chosen_sl_; + +private: + // Private methods + void analyze(MuonPathPtr &inMPath, std::vector &metaPrimitives); + + void setCellLayout(const int layout[cmsdt::NUM_LAYERS]); + void buildLateralities(void); + bool isStraightPath(cmsdt::LATERAL_CASES sideComb[cmsdt::NUM_LAYERS]); + + void evaluatePathQuality(MuonPathPtr &mPath); + void evaluateLateralQuality(int latIdx, MuonPathPtr &mPath, cmsdt::LATQ_TYPE *latQuality); + void validate(cmsdt::LATERAL_CASES sideComb[3], int layerIndex[3], MuonPathPtr &mPath, cmsdt::PARTIAL_LATQ_TYPE *latq); + + int eqMainBXTerm(cmsdt::LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath); + + int eqMainTerm(cmsdt::LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath, int bxValue); + + void lateralCoeficients(cmsdt::LATERAL_CASES sideComb[2], int *coefs); + bool sameBXValue(cmsdt::PARTIAL_LATQ_TYPE *latq); + + void calculatePathParameters(MuonPathPtr &mPath); + void calcTanPhiXPosChamber(MuonPathPtr &mPath); + void calcCellDriftAndXcoor(MuonPathPtr &mPath); + void calcChiSquare(MuonPathPtr &mPath); + + void calcTanPhiXPosChamber3Hits(MuonPathPtr &mPath); + void calcTanPhiXPosChamber4Hits(MuonPathPtr &mPath); + + int omittedHit(int idx); + + // Private attributes + + static const int LAYER_ARRANGEMENTS_[cmsdt::NUM_LAYERS][cmsdt::NUM_CELL_COMB]; + cmsdt::LATERAL_CASES lateralities_[cmsdt::NUM_LATERALITIES][cmsdt::NUM_LAYERS]; + cmsdt::LATQ_TYPE latQuality_[cmsdt::NUM_LATERALITIES]; + + int totalNumValLateralities_; + + int bxTolerance_; + cmsdt::MP_QUALITY minQuality_; + float chiSquareThreshold_; + bool debug_; + double chi2Th_; + double chi2corTh_; + double tanPhiTh_; + int cellLayout_[cmsdt::NUM_LAYERS]; + bool use_LSB_; + double tanPsi_precision_; + double x_precision_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h new file mode 100644 index 0000000000000..8586f54f3b96b --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h @@ -0,0 +1,92 @@ +#ifndef Phase2L1Trigger_DTTrigger_MuonPathAssociator_h +#define Phase2L1Trigger_DTTrigger_MuonPathAssociator_h + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/FrameworkfwdMostUsed.h" + +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/DTSuperLayerId.h" +#include "DataFormats/MuonDetId/interface/DTLayerId.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" +#include "DataFormats/DTDigi/interface/DTDigiCollection.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +#include "Geometry/Records/interface/MuonGeometryRecord.h" +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/DTGeometry/interface/DTLayer.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MuonPathAssociator { +public: + // Constructors and destructor + MuonPathAssociator(const edm::ParameterSet &pset, edm::ConsumesCollector &iC); + ~MuonPathAssociator(); + + // Main methods + void initialise(const edm::EventSetup &iEventSetup); + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + edm::Handle digis, + std::vector &inMPaths, + std::vector &outMPaths); + + void finish(); + + // Other public methods + + bool shareFit(cmsdt::metaPrimitive first, cmsdt::metaPrimitive second); + bool isNotAPrimo(cmsdt::metaPrimitive first, cmsdt::metaPrimitive second); + void removeSharingFits(std::vector &chamberMPaths, + std::vector &allMPaths); + void removeSharingHits(std::vector &firstMPaths, + std::vector &secondMPaths, + std::vector &allMPaths); + void printmPC(cmsdt::metaPrimitive mP); + + // Public attributes + DTGeometry const *dtGeo_; + edm::ESGetToken dtGeomH_; + +private: + // Private methods + void correlateMPaths(edm::Handle digis, + std::vector &inMPaths, + std::vector &outMPaths); + + bool hasPosRF(int wh, int sec) { return wh > 0 || (wh == 0 && sec % 4 > 1); } + + // Private attributes + bool debug_; + bool clean_chi2_correlation_; + bool useBX_correlation_; + bool allow_confirmation_; + double dT0_correlate_TP_; + double dBX_correlate_TP_; + double dTanPsi_correlate_TP_; + double minx_match_2digis_; + double chi2corTh_; + bool use_LSB_; + double tanPsi_precision_; + double x_precision_; + + //shift + edm::FileInPath shift_filename_; + std::map shiftinfo_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/PseudoBayesGrouping.h b/L1Trigger/DTTriggerPhase2/interface/PseudoBayesGrouping.h new file mode 100644 index 0000000000000..82210d2af0acc --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/PseudoBayesGrouping.h @@ -0,0 +1,118 @@ +#ifndef Phase2L1Trigger_DTTrigger_PseudoBayesGrouping_h +#define Phase2L1Trigger_DTTrigger_PseudoBayesGrouping_h + +#include "L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h" +#include "L1Trigger/DTTriggerPhase2/interface/DTPattern.h" +#include "L1Trigger/DTTriggerPhase2/interface/CandidateGroup.h" + +// =============================================================================== +// Class declarations +// =============================================================================== +class PseudoBayesGrouping : public MotherGrouping { +public: + // Constructors and destructor + PseudoBayesGrouping(const edm::ParameterSet& pset, edm::ConsumesCollector& iC); + ~PseudoBayesGrouping() override; + + // Main methods + void initialise(const edm::EventSetup& iEventSetup) override; + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& outMpath) override; + void finish() override; + + // Other public methods + + // Public attributes + +private: + // Private methods + void LoadPattern(std::vector>>::iterator itPattern); + void FillDigisByLayer(const DTDigiCollection* digis); + void CleanDigisByLayer(); + void RecognisePatternsByLayerPairs(); + void RecognisePatterns(std::vector digisinLDown, + std::vector digisinLUp, + std::vector patterns); + void ReCleanPatternsAndDigis(); + void FillMuonPaths(MuonPathPtrs& mpaths); + + //Comparator for pointer mode + struct CandPointGreat { + bool operator()(dtbayesam::CandidateGroupPtr c1, dtbayesam::CandidateGroupPtr c2) { return *c1 > *c2; } + }; + + // Private attributes + // Config variables + bool debug_; + std::string pattern_filename_; + int pidx_; + int minNLayerHits_; + int allowedVariance_; + bool allowDuplicates_; + bool allowUncorrelatedPatterns_; + bool setLateralities_; + bool saveOnPlace_; + int minSingleSLHitsMax_; + int minSingleSLHitsMin_; + int minUncorrelatedHits_; + + //Classified digis + std::vector alldigis_; + + std::vector digisinL0_; + std::vector digisinL1_; + std::vector digisinL2_; + std::vector digisinL3_; + std::vector digisinL4_; + std::vector digisinL5_; + std::vector digisinL6_; + std::vector digisinL7_; + + //Preliminary matches, those can grow quite big so better not to rely on the stack + std::unique_ptr prelimMatches_; + std::unique_ptr allMatches_; + std::unique_ptr finalMatches_; + + //Pattern related info + int nPatterns_; + std::vector allPatterns_; + + std::vector L0L7Patterns_; + std::vector L1L7Patterns_; + std::vector L2L7Patterns_; + std::vector L3L7Patterns_; + std::vector L4L7Patterns_; + std::vector L5L7Patterns_; + std::vector L6L7Patterns_; + + std::vector L0L6Patterns_; + std::vector L1L6Patterns_; + std::vector L2L6Patterns_; + std::vector L3L6Patterns_; + std::vector L4L6Patterns_; + std::vector L5L6Patterns_; + + std::vector L0L5Patterns_; + std::vector L1L5Patterns_; + std::vector L2L5Patterns_; + std::vector L3L5Patterns_; + std::vector L4L5Patterns_; + + std::vector L0L4Patterns_; + std::vector L1L4Patterns_; + std::vector L2L4Patterns_; + std::vector L3L4Patterns_; + + std::vector L0L3Patterns_; + std::vector L1L3Patterns_; + std::vector L2L3Patterns_; + + std::vector L0L2Patterns_; + std::vector L1L2Patterns_; + + std::vector L0L1Patterns_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h b/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h new file mode 100644 index 0000000000000..0e7b1ba0e9dc3 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h @@ -0,0 +1,103 @@ +#ifndef Phase2L1Trigger_DTTrigger_RPCIntegrator_h +#define Phase2L1Trigger_DTTrigger_RPCIntegrator_h + +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" + +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/DTSuperLayerId.h" +#include "DataFormats/MuonDetId/interface/DTLayerId.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" +#include "DataFormats/DTDigi/interface/DTDigiCollection.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhDigi.h" + +#include "DataFormats/RPCRecHit/interface/RPCRecHitCollection.h" +#include +#include "Geometry/RPCGeometry/interface/RPCGeometry.h" + +//DT geometry +#include +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/DTGeometry/interface/DTLayer.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" +#include "DQM/DTMonitorModule/interface/DTTrigGeomUtils.h" + +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +struct RPCMetaprimitive { + RPCDetId rpc_id; + const RPCRecHit* rpc_cluster; + GlobalPoint global_position; + int rpcFlag; + int rpc_bx; + double rpc_t0; + RPCMetaprimitive(RPCDetId rpc_id_construct, + const RPCRecHit* rpc_cluster_construct, + GlobalPoint global_position_construct, + int rpcFlag_construct, + int rpc_bx_construct, + double rpc_t0_construct) + : rpc_id(rpc_id_construct), + rpc_cluster(rpc_cluster_construct), + global_position(global_position_construct), + rpcFlag(rpcFlag_construct), + rpc_bx(rpc_bx_construct), + rpc_t0(rpc_t0_construct) {} +}; + +class RPCIntegrator { +public: + RPCIntegrator(const edm::ParameterSet& pset, edm::ConsumesCollector& iC); + ~RPCIntegrator(); + + void initialise(const edm::EventSetup& iEventSetup, double shift_back_fromDT); + void finish(); + + void prepareMetaPrimitives(edm::Handle rpcRecHits); + void matchWithDTAndUseRPCTime(std::vector& dt_metaprimitives); + void makeRPCOnlySegments(); + void storeRPCSingleHits(); + void removeRPCHitsUsed(); + + RPCMetaprimitive* matchDTwithRPC(cmsdt::metaPrimitive* dt_metaprimitive); + L1Phase2MuDTPhDigi createL1Phase2MuDTPhDigi( + RPCDetId rpcDetId, int rpc_bx, double rpc_time, double rpc_global_phi, double phiB, int rpc_flag); + + double phiBending(RPCMetaprimitive* rpc_hit_1, RPCMetaprimitive* rpc_hit_2); + int phiInDTTPFormat(double rpc_global_phi, int rpcSector); + GlobalPoint RPCGlobalPosition(RPCDetId rpcId, const RPCRecHit& rpcIt) const; + double phi_DT_MP_conv(double rpc_global_phi, int rpcSector); + bool hasPosRF_rpc(int wh, int sec) const; + + std::vector rpcRecHits_translated_; + std::vector RPCMetaprimitives_; + +private: + //RPCRecHitCollection m_rpcRecHits; + bool m_debug_; + int m_max_quality_to_overwrite_t0_; + int m_bx_window_; + double m_phi_window_; + bool m_storeAllRPCHits_; + + DTGeometry const* dtGeo_; + RPCGeometry const* rpcGeo_; + edm::ESGetToken dtGeomH_; + edm::ESGetToken rpcGeomH_; + + static constexpr double m_dt_phi_granularity_ = (65536. / 0.8); // 65536 different values per 0.8 radian + static constexpr double m_dt_phiB_granularity_ = (2048. / 1.4); // 2048. different values per 1.4 radian + // Constant geometry values + //R[stat][layer] - radius of rpc station/layer from center of CMS + static constexpr double R_[2][2] = {{410.0, 444.8}, {492.7, 527.3}}; + static constexpr double distance_between_two_rpc_layers_ = 35; // in cm + + double shift_back_; +}; +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/constants.h b/L1Trigger/DTTriggerPhase2/interface/constants.h new file mode 100644 index 0000000000000..3c7e1b7756f78 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/constants.h @@ -0,0 +1,254 @@ +/** + * Project: + * File name: constants.h + * Language: C++ + * + * ********************************************************************* + * Description: + * + * + * To Do: + * + * Author: Jose Manuel Cela + * + * ********************************************************************* + * Copyright (c) 2015-08-07 Jose Manuel Cela + * + * For internal use, all rights reserved. + * ********************************************************************* + */ +#ifndef L1Trigger_DTTriggerPhase2_constants_h +#define L1Trigger_DTTriggerPhase2_constants_h +#include + +// Compiler option to select program mode: PRUEBA_MEZCLADOR, PRUEBA_ANALIZADOR, +// or NONE + +/* Quality of the trayectories: + NOPATH => Not valid trayectory + LOWQGHOST => 3h (multiple lateralities) + LOWQ => 3h + HIGHQGHOST => 4h (multiple lateralities) + HIGHQ => 4h + CLOWQ => 3h + 2h/1h + LOWLOWQ => 3h + 3h + CHIGHQ => 4h + 2h/1h + HIGHLOWQ => 4h + 3h + HIGHHIGHQ => 4h + 4h +*/ +namespace cmsdt { + + enum MP_QUALITY { NOPATH = 0, LOWQGHOST, LOWQ, HIGHQGHOST, HIGHQ, CLOWQ, LOWLOWQ, CHIGHQ, HIGHLOWQ, HIGHHIGHQ }; + + // Tipos de lateralidad de traza de partícula al pasar por una celda + enum LATERAL_CASES { LEFT = 0, RIGHT, NONE }; + + enum RPC_QUALITY { NORPC = 0, RPC_TIME, RPC_ONLY, RPC_HIT, RPC_CONFIRM, RPC_ASSOCIATE }; + + struct metaPrimitive { + metaPrimitive(uint32_t id, + double t, + double pos, + double tan, + double ph, + double phb, + double chi, + int q, + int w1, + int t1, + int l1, + int w2, + int t2, + int l2, + int w3, + int t3, + int l3, + int w4, + int t4, + int l4, + int w5 = 0, + int t5 = -1, + int l5 = 0, + int w6 = 0, + int t6 = -1, + int l6 = 0, + int w7 = 0, + int t7 = -1, + int l7 = 0, + int w8 = 0, + int t8 = -1, + int l8 = 0, + int idx = 0, + int rpc = 0) + : rawId(id), + t0(t), + x(pos), + tanPhi(tan), + phi(ph), + phiB(phb), + chi2(chi), + quality(q), + wi1(w1), + tdc1(t1), + lat1(l1), + wi2(w2), + tdc2(t2), + lat2(l2), + wi3(w3), + tdc3(t3), + lat3(l3), + wi4(w4), + tdc4(t4), + lat4(l4), + wi5(w5), + tdc5(t5), + lat5(l5), + wi6(w6), + tdc6(t6), + lat6(l6), + wi7(w7), + tdc7(t7), + lat7(l7), + wi8(w8), + tdc8(t8), + lat8(l8), + index(idx), + rpcFlag(rpc) {} + + uint32_t rawId; + double t0; + double x; + double tanPhi; + double phi; + double phiB; + double chi2; + int quality; + int wi1; + int tdc1; + int lat1; + int wi2; + int tdc2; + int lat2; + int wi3; + int tdc3; + int lat3; + int wi4; + int tdc4; + int lat4; + int wi5; + int tdc5; + int lat5; + int wi6; + int tdc6; + int lat6; + int wi7; + int tdc7; + int lat7; + int wi8; + int tdc8; + int lat8; + int index; + int rpcFlag = 0; + }; + struct PARTIAL_LATQ_TYPE { + bool latQValid; + int bxValue; + }; + struct LATQ_TYPE { + bool valid; + int bxValue; + int invalidateHitIdx; + MP_QUALITY quality; + }; + + enum algo { Standard = 0, PseudoBayes = 1, HoughTrans = 2 }; + + enum scenario { MC = 0, DATA = 1, SLICE_TEST = 2 }; + + /* En nanosegundos */ + constexpr int LHC_CLK_FREQ = 25; + + /* Adimensional */ + constexpr int MAX_BX_IDX = 3564; + + // En nanosegundos (tiempo de deriva en la celda) + constexpr float MAXDRIFT = 386.75; + // En milímetros (dimensiones de la celda) + constexpr int CELL_HEIGHT = 13; + constexpr float CELL_SEMIHEIGHT = 6.5; + constexpr int CELL_LENGTH = 42; + constexpr int CELL_SEMILENGTH = 21; + // En milímetros / nanosegundo (velocidad de deriva) + constexpr float DRIFT_SPEED = 0.0542; + /* + This is the maximum value than internal time can take. This is because + internal time is cyclical due to the limited size of the time counters and + the limited value of the bunch crossing index. + It should be, approximately, the LHC's clock frequency multiplied by the + maximum BX index, plus an arbitrary amount for taking into account the + muon traveling time and muon's signal drift time. + */ + constexpr int MAX_VALUE_OF_TIME = (LHC_CLK_FREQ * MAX_BX_IDX + 5000); + + /* + * Total BTI number and total channel number must be coordinated. One BTI + * works over 10 channels, but 2 consecutive BTI's overlap many of their + * channels. + */ + constexpr int TOTAL_BTI = 100; // Should be the same value as NUM_CH_PER_LAYER + constexpr int NUM_CH_PER_LAYER = 100; // Should be the same value as TOTAL_BTI + constexpr int NUM_LAYERS = 4; + constexpr int NUM_LATERALITIES = 16; + constexpr int NUM_CELL_COMB = 3; + constexpr int TOTAL_CHANNELS = (NUM_LAYERS * NUM_CH_PER_LAYER); + constexpr int NUM_SUPERLAYERS = 3; + constexpr float PHIRES_CONV = 65536. / 0.8; + constexpr float PHIBRES_CONV = 2048. / 1.4; + constexpr int CHI2RES_CONV = 1000000; + + constexpr int DIVISION_HELPER1 = 43691; + constexpr int DIVISION_HELPER2 = 65536; + constexpr int DIVISION_HELPER3 = 131072; + constexpr int DENOM_TYPE1 = 6; + constexpr int DENOM_TYPE2 = 4; + constexpr int DENOM_TYPE3 = 2; + constexpr int NBITS = 18; + /* + * Size of pre-mixer buffers for DTPrimitives + * + * As first approach, this value should be evaluated in order to allow storing + * enough elements to avoid saturating its size. It will be dependent on the + * noise level, the number of good data injected in the system, as well as on + * the processing speed of the final analyzer. + */ + constexpr int SIZE_SEEKT_BUFFER = 32; + + // Number of cells for a analysis block (BTI) + constexpr int NUM_CELLS_PER_BLOCK = 10; + + /* + * Number of entries for the payload inside DTPrimitive. + * This value is also used in other code places to manage reading and writing + * from/to files + */ + constexpr int PAYLOAD_ENTRIES = 9; + + /* + * Size of muon primitive + */ + constexpr int NUM_LAYERS_2SL = 8; + constexpr double PHI_CONV = 0.5235988; + + constexpr int BX_SHIFT = 20; + constexpr float Z_SHIFT_MB4 = -1.8; + constexpr float Z_POS_SL = 11.75; + constexpr double X_POS_L3 = 0.65; + constexpr double X_POS_L4 = 1.95; + + constexpr int MEANTIME_2LAT = 16384; + constexpr int MEANTIME_3LAT = 10923; + constexpr int MEANTIME_4LAT = 8192; + +} // namespace cmsdt + +#endif diff --git a/L1Trigger/DTTriggerPhase2/plugins/BuildFile.xml b/L1Trigger/DTTriggerPhase2/plugins/BuildFile.xml new file mode 100644 index 0000000000000..202f0d6fa28d7 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/plugins/BuildFile.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc b/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc new file mode 100644 index 0000000000000..b27cfaf6edf69 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// Package: UserCode/CalibratedDigis +// Class: CalibratedDigis +// +/**\class CalibratedDigis CalibratedDigis.cc UserCode/CalibratedDigis/plugins/CalibratedDigis.cc + + Description: [one line class summary] + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Luigi Guiducci +// Created: Fri, 11 Jan 2019 12:49:12 GMT +// +// + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "CalibMuon/DTDigiSync/interface/DTTTrigBaseSync.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "DataFormats/Common/interface/Handle.h" +#include "FWCore/Framework/interface/ESHandle.h" + +#include "CalibMuon/DTDigiSync/interface/DTTTrigSyncFactory.h" + +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "DataFormats/DTDigi/interface/DTDigiCollection.h" +#include "DataFormats/MuonDetId/interface/DTLayerId.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" +#include "Geometry/Records/interface/MuonGeometryRecord.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +namespace edm { + class ParameterSet; + class EventSetup; +} // namespace edm + +using namespace std; +using namespace edm; +using namespace cmsdt; +// +// class declaration +// + +class CalibratedDigis : public edm::stream::EDProducer<> { +public: + explicit CalibratedDigis(const edm::ParameterSet&); + ~CalibratedDigis() override; + +private: + int timeOffset_; + int flat_calib_; + int scenario; + + void produce(edm::Event&, const edm::EventSetup&) override; + + std::unique_ptr theSync; + + // ----------member data --------------------------- + edm::EDGetTokenT dtDigisToken; + edm::Handle DTDigiHandle; + edm::InputTag dtDigiTag; + + static constexpr float bxspacing = 25.0; + static constexpr float timeshift = 400.0; + static constexpr float flatcalib = 325.0; +}; + +// +// constructors and destructor +// +CalibratedDigis::CalibratedDigis(const edm::ParameterSet& iConfig) { + //register your products + dtDigiTag = iConfig.getParameter("dtDigiTag"); + dtDigisToken = consumes(dtDigiTag); + + theSync = DTTTrigSyncFactory::get()->create(iConfig.getParameter("tTrigMode"), + iConfig.getParameter("tTrigModeConfig")); + + flat_calib_ = iConfig.getParameter("flat_calib"); + timeOffset_ = iConfig.getParameter("timeOffset"); + + scenario = iConfig.getUntrackedParameter("scenario"); + + produces(); + //now do what ever other initialization is needed +} + +CalibratedDigis::~CalibratedDigis() { + // do anything here that needs to be done at destruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void CalibratedDigis::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + theSync->setES(iSetup); + iEvent.getByToken(dtDigisToken, DTDigiHandle); + DTDigiCollection mydigis; + + for (const auto& dtLayerIt : *DTDigiHandle) { + const DTLayerId& layerId = dtLayerIt.first; + for (DTDigiCollection::const_iterator digiIt = dtLayerIt.second.first; digiIt != dtLayerIt.second.second; + ++digiIt) { + DTWireId wireId(layerId, (*digiIt).wire()); + float digiTime = (*digiIt).time(); + int wire = (*digiIt).wire(); + int number = (*digiIt).number(); + float newTime = 0; + if (flat_calib_ != 0) + newTime = digiTime - flatcalib + bxspacing * iEvent.eventAuxiliary().bunchCrossing() + float(timeOffset_); + else { + if (scenario == MC) //FIX MC + newTime = digiTime + bxspacing * timeshift; + else if (scenario == SLICE_TEST) //FIX SliceTest + newTime = digiTime; + else + newTime = digiTime - theSync->offset(wireId) + bxspacing * iEvent.eventAuxiliary().bunchCrossing() + + float(timeOffset_); + } + DTDigi newDigi(wire, newTime, number); + mydigis.insertDigi(layerId, newDigi); + } + } + auto CorrectedDTDigiCollection = std::make_unique(mydigis); + iEvent.put(std::move(CorrectedDTDigiCollection)); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(CalibratedDigis); diff --git a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc new file mode 100644 index 0000000000000..4dcedadba8e37 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc @@ -0,0 +1,711 @@ +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Framework/interface/ModuleFactory.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ESProducts.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "Geometry/Records/interface/MuonGeometryRecord.h" +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/DTGeometry/interface/DTLayer.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" + +#include "L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h" +#include "L1Trigger/DTTriggerPhase2/interface/InitialGrouping.h" +#include "L1Trigger/DTTriggerPhase2/interface/HoughGrouping.h" +#include "L1Trigger/DTTriggerPhase2/interface/PseudoBayesGrouping.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h" +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" +#include "L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h" +#include "L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h" + +#include "DataFormats/MuonDetId/interface/DTChamberId.h" +#include "DataFormats/MuonDetId/interface/DTSuperLayerId.h" +#include "DataFormats/MuonDetId/interface/DTLayerId.h" +#include "DataFormats/MuonDetId/interface/DTWireId.h" +#include "DataFormats/DTDigi/interface/DTDigiCollection.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhDigi.h" + +// DT trigger GeomUtils +#include "DQM/DTMonitorModule/interface/DTTrigGeomUtils.h" + +//RPC TP +#include "DataFormats/RPCRecHit/interface/RPCRecHitCollection.h" +#include +#include "Geometry/RPCGeometry/interface/RPCGeometry.h" +#include "L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h" + +#include +#include +#include +#include + +using namespace edm; +using namespace std; +using namespace cmsdt; + +class DTTrigPhase2Prod : public edm::stream::EDProducer<> { + typedef std::map> DTDigiMap; + typedef DTDigiMap::iterator DTDigiMap_iterator; + typedef DTDigiMap::const_iterator DTDigiMap_const_iterator; + +public: + //! Constructor + DTTrigPhase2Prod(const edm::ParameterSet& pset); + + //! Destructor + ~DTTrigPhase2Prod() override; + + //! Create Trigger Units before starting event processing + void beginRun(edm::Run const& iRun, const edm::EventSetup& iEventSetup) override; + + //! Producer: process every event and generates trigger data + void produce(edm::Event& iEvent, const edm::EventSetup& iEventSetup) override; + + //! endRun: finish things + void endRun(edm::Run const& iRun, const edm::EventSetup& iEventSetup) override; + + // Methods + int rango(const metaPrimitive& mp) const; + bool outer(const metaPrimitive& mp) const; + bool inner(const metaPrimitive& mp) const; + void printmP(const std::string& ss, const metaPrimitive& mP) const; + void printmPC(const std::string& ss, const metaPrimitive& mP) const; + bool hasPosRF(int wh, int sec) const; + + // Getter-methods + MP_QUALITY getMinimumQuality(void); + + // Setter-methods + void setChiSquareThreshold(float ch2Thr); + void setMinimumQuality(MP_QUALITY q); + + // data-members + DTGeometry const* dtGeo_; + edm::ESGetToken dtGeomH; + std::vector> primitives_; + +private: + // Trigger Configuration Manager CCB validity flag + bool my_CCBValid_; + + // BX offset used to correct DTTPG output + int my_BXoffset_; + + // Debug Flag + bool debug_; + bool dump_; + double dT0_correlate_TP_; + bool do_correlation_; + int scenario_; + + // shift + edm::FileInPath shift_filename_; + std::map shiftinfo_; + + // ParameterSet + edm::EDGetTokenT dtDigisToken_; + edm::EDGetTokenT rpcRecHitsLabel_; + + // Grouping attributes and methods + int algo_; // Grouping code + std::unique_ptr grouping_obj_; + std::unique_ptr mpathanalyzer_; + std::unique_ptr mpathqualityenhancer_; + std::unique_ptr mpathredundantfilter_; + std::unique_ptr mpathassociator_; + + // Buffering + bool activateBuffer_; + int superCellhalfspacewidth_; + float superCelltimewidth_; + std::vector distribDigis(std::queue>& inQ); + void processDigi(std::queue>& inQ, + std::vector>*>& vec); + + // RPC + std::unique_ptr rpc_integrator_; + bool useRPC_; + + void assignIndex(std::vector& inMPaths); + void assignIndexPerBX(std::vector& inMPaths); + int assignQualityOrder(const metaPrimitive& mP) const; + + const std::unordered_map qmap_; +}; + +namespace { + struct { + bool operator()(std::pair a, std::pair b) const { + return (a.second.time() < b.second.time()); + } + } DigiTimeOrdering; +} // namespace + +DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) + : qmap_({{9, 9}, {8, 8}, {7, 6}, {6, 7}, {5, 3}, {4, 5}, {3, 4}, {2, 2}, {1, 1}}) { + produces(); + + debug_ = pset.getUntrackedParameter("debug"); + dump_ = pset.getUntrackedParameter("dump"); + + do_correlation_ = pset.getParameter("do_correlation"); + scenario_ = pset.getParameter("scenario"); + + dtDigisToken_ = consumes(pset.getParameter("digiTag")); + + rpcRecHitsLabel_ = consumes(pset.getParameter("rpcRecHits")); + useRPC_ = pset.getParameter("useRPC"); + + // Choosing grouping scheme: + algo_ = pset.getParameter("algo"); + + edm::ConsumesCollector consumesColl(consumesCollector()); + + if (algo_ == PseudoBayes) { + grouping_obj_ = + std::make_unique(pset.getParameter("PseudoBayesPattern"), consumesColl); + } else if (algo_ == HoughTrans) { + grouping_obj_ = + std::make_unique(pset.getParameter("HoughGrouping"), consumesColl); + } else { + grouping_obj_ = std::make_unique(pset, consumesColl); + } + + if (algo_ == Standard) { + if (debug_) + LogDebug("DTTrigPhase2Prod") << "DTp2:constructor: JM analyzer"; + mpathanalyzer_ = std::make_unique(pset, consumesColl); + } else { + if (debug_) + LogDebug("DTTrigPhase2Prod") << "DTp2:constructor: Full chamber analyzer"; + mpathanalyzer_ = std::make_unique(pset, consumesColl); + } + + // Getting buffer option + activateBuffer_ = pset.getParameter("activateBuffer"); + superCellhalfspacewidth_ = pset.getParameter("superCellspacewidth") / 2; + superCelltimewidth_ = pset.getParameter("superCelltimewidth"); + + mpathqualityenhancer_ = std::make_unique(pset); + mpathredundantfilter_ = std::make_unique(pset); + mpathassociator_ = std::make_unique(pset, consumesColl); + rpc_integrator_ = std::make_unique(pset, consumesColl); + + dtGeomH = esConsumes(); +} + +DTTrigPhase2Prod::~DTTrigPhase2Prod() { + if (debug_) + LogDebug("DTTrigPhase2Prod") << "DTp2: calling destructor" << std::endl; +} + +void DTTrigPhase2Prod::beginRun(edm::Run const& iRun, const edm::EventSetup& iEventSetup) { + if (debug_) + LogDebug("DTTrigPhase2Prod") << "beginRun " << iRun.id().run(); + if (debug_) + LogDebug("DTTrigPhase2Prod") << "beginRun: getting DT geometry"; + + grouping_obj_->initialise(iEventSetup); // Grouping object initialisation + mpathanalyzer_->initialise(iEventSetup); // Analyzer object initialisation + mpathqualityenhancer_->initialise(iEventSetup); // Filter object initialisation + mpathredundantfilter_->initialise(iEventSetup); // Filter object initialisation + mpathassociator_->initialise(iEventSetup); // Associator object initialisation + + const MuonGeometryRecord& geom = iEventSetup.get(); + dtGeo_ = &geom.get(dtGeomH); +} + +void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { + if (debug_) + LogDebug("DTTrigPhase2Prod") << "produce"; + edm::Handle dtdigis; + iEvent.getByToken(dtDigisToken_, dtdigis); + + if (debug_) + LogDebug("DTTrigPhase2Prod") << "\t Getting the RPC RecHits" << std::endl; + edm::Handle rpcRecHits; + iEvent.getByToken(rpcRecHitsLabel_, rpcRecHits); + + //////////////////////////////// + // GROUPING CODE: + //////////////////////////////// + DTDigiMap digiMap; + DTDigiCollection::DigiRangeIterator detUnitIt; + for (const auto& detUnitIt : *dtdigis) { + const DTLayerId& layId = detUnitIt.first; + const DTChamberId chambId = layId.superlayerId().chamberId(); + const DTDigiCollection::Range& range = detUnitIt.second; + digiMap[chambId].put(range, layId); + } + + // generate a list muon paths for each event!!! + if (debug_ && activateBuffer_) + LogDebug("DTTrigPhase2Prod") << "produce - Getting and grouping digis per chamber using a buffer and super cells."; + else if (debug_) + LogDebug("DTTrigPhase2Prod") << "produce - Getting and grouping digis per chamber."; + + MuonPathPtrs muonpaths; + for (const auto& ich : dtGeo_->chambers()) { + // The code inside this for loop would ideally later fit inside a trigger unit (in principle, a DT station) of the future Phase 2 DT Trigger. + const DTChamber* chamb = ich; + DTChamberId chid = chamb->id(); + DTDigiMap_iterator dmit = digiMap.find(chid); + + if (dmit == digiMap.end()) + continue; + + if (activateBuffer_) { // Use buffering (per chamber) or not + // Import digis from the station + std::vector> tmpvec; + tmpvec.clear(); + + for (const auto& dtLayerIdIt : (*dmit).second) { + for (DTDigiCollection::const_iterator digiIt = (dtLayerIdIt.second).first; + digiIt != (dtLayerIdIt.second).second; + digiIt++) { + tmpvec.emplace_back(dtLayerIdIt.first, *digiIt); + } + } + + // Check to enhance CPU time usage + if (tmpvec.empty()) + continue; + + // Order digis depending on TDC time and insert them into a queue (FIFO buffer). TODO: adapt for MC simulations. + std::sort(tmpvec.begin(), tmpvec.end(), DigiTimeOrdering); + std::queue> timequeue; + + for (const auto& elem : tmpvec) + timequeue.emplace(std::move(elem)); + tmpvec.clear(); + + // Distribute the digis from the queue into 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); + superCells.pop_back(); + } + } else { + grouping_obj_->run(iEvent, iEventSetup, (*dmit).second, muonpaths); + } + } + digiMap.clear(); + + if (dump_) { + for (unsigned int i = 0; i < muonpaths.size(); i++) { + stringstream ss; + ss << iEvent.id().event() << " mpath " << i << ": "; + for (int lay = 0; lay < muonpaths.at(i)->nprimitives(); lay++) + ss << muonpaths.at(i)->primitive(lay)->channelId() << " "; + for (int lay = 0; lay < muonpaths.at(i)->nprimitives(); lay++) + ss << muonpaths.at(i)->primitive(lay)->tdcTimeStamp() << " "; + for (int lay = 0; lay < muonpaths.at(i)->nprimitives(); lay++) + ss << muonpaths.at(i)->primitive(lay)->laterality() << " "; + LogInfo("DTTrigPhase2Prod") << ss.str(); + } + } + + // FILTER GROUPING + MuonPathPtrs filteredmuonpaths; + if (algo_ == Standard) { + mpathredundantfilter_->run(iEvent, iEventSetup, muonpaths, filteredmuonpaths); + } + + if (dump_) { + for (unsigned int i = 0; i < filteredmuonpaths.size(); i++) { + stringstream ss; + ss << iEvent.id().event() << " filt. mpath " << i << ": "; + for (int lay = 0; lay < filteredmuonpaths.at(i)->nprimitives(); lay++) + ss << filteredmuonpaths.at(i)->primitive(lay)->channelId() << " "; + for (int lay = 0; lay < filteredmuonpaths.at(i)->nprimitives(); lay++) + ss << filteredmuonpaths.at(i)->primitive(lay)->tdcTimeStamp() << " "; + LogInfo("DTTrigPhase2Prod") << ss.str(); + } + } + + /////////////////////////////////////////// + /// FITTING SECTION; + /////////////////////////////////////////// + if (debug_) + LogDebug("DTTrigPhase2Prod") << "MUON PATHS found: " << muonpaths.size() << " (" << filteredmuonpaths.size() + << ") in event " << iEvent.id().event(); + if (debug_) + LogDebug("DTTrigPhase2Prod") << "filling NmetaPrimtives" << std::endl; + std::vector metaPrimitives; + MuonPathPtrs outmpaths; + if (algo_ == Standard) { + if (debug_) + LogDebug("DTTrigPhase2Prod") << "Fitting 1SL "; + mpathanalyzer_->run(iEvent, iEventSetup, filteredmuonpaths, metaPrimitives); + } else { + // implementation for advanced (2SL) grouping, no filter required.. + if (debug_) + LogDebug("DTTrigPhase2Prod") << "Fitting 2SL at once "; + mpathanalyzer_->run(iEvent, iEventSetup, muonpaths, outmpaths); + } + + if (dump_) { + for (unsigned int i = 0; i < outmpaths.size(); i++) { + LogInfo("DTTrigPhase2Prod") << iEvent.id().event() << " mp " << i << ": " << outmpaths.at(i)->bxTimeValue() << " " + << outmpaths.at(i)->horizPos() << " " << outmpaths.at(i)->tanPhi() << " " + << outmpaths.at(i)->phi() << " " << outmpaths.at(i)->phiB() << " " + << outmpaths.at(i)->quality() << " " << outmpaths.at(i)->chiSquare(); + } + for (unsigned int i = 0; i < metaPrimitives.size(); i++) { + stringstream ss; + ss << iEvent.id().event() << " mp " << i << ": "; + printmP(ss.str(), metaPrimitives.at(i)); + } + } + + muonpaths.clear(); + filteredmuonpaths.clear(); + + ///////////////////////////////////// + // FILTER SECTIONS: + //////////////////////////////////// + if (debug_) + LogDebug("DTTrigPhase2Prod") << "declaring new vector for filtered" << std::endl; + + std::vector filteredMetaPrimitives; + if (algo_ == Standard) + mpathqualityenhancer_->run(iEvent, iEventSetup, metaPrimitives, filteredMetaPrimitives); + + if (dump_) { + for (unsigned int i = 0; i < filteredMetaPrimitives.size(); i++) { + stringstream ss; + ss << iEvent.id().event() << " filtered mp " << i << ": "; + printmP(ss.str(), filteredMetaPrimitives.at(i)); + } + } + + metaPrimitives.clear(); + metaPrimitives.erase(metaPrimitives.begin(), metaPrimitives.end()); + + if (debug_) + LogDebug("DTTrigPhase2Prod") << "DTp2 in event:" << iEvent.id().event() << " we found " + << filteredMetaPrimitives.size() << " filteredMetaPrimitives (superlayer)" + << std::endl; + if (debug_) + LogDebug("DTTrigPhase2Prod") << "filteredMetaPrimitives: starting correlations" << std::endl; + + ///////////////////////////////////// + //// CORRELATION: + ///////////////////////////////////// + std::vector correlatedMetaPrimitives; + if (algo_ == Standard) + mpathassociator_->run(iEvent, iEventSetup, dtdigis, filteredMetaPrimitives, correlatedMetaPrimitives); + else { + for (const auto& muonpath : outmpaths) { + correlatedMetaPrimitives.emplace_back(muonpath->rawId(), + (double)muonpath->bxTimeValue(), + muonpath->horizPos(), + muonpath->tanPhi(), + muonpath->phi(), + muonpath->phiB(), + muonpath->chiSquare(), + (int)muonpath->quality(), + muonpath->primitive(0)->channelId(), + muonpath->primitive(0)->tdcTimeStamp(), + muonpath->primitive(0)->laterality(), + muonpath->primitive(1)->channelId(), + muonpath->primitive(1)->tdcTimeStamp(), + muonpath->primitive(1)->laterality(), + muonpath->primitive(2)->channelId(), + muonpath->primitive(2)->tdcTimeStamp(), + muonpath->primitive(2)->laterality(), + muonpath->primitive(3)->channelId(), + muonpath->primitive(3)->tdcTimeStamp(), + muonpath->primitive(3)->laterality(), + muonpath->primitive(4)->channelId(), + muonpath->primitive(4)->tdcTimeStamp(), + muonpath->primitive(4)->laterality(), + muonpath->primitive(5)->channelId(), + muonpath->primitive(5)->tdcTimeStamp(), + muonpath->primitive(5)->laterality(), + muonpath->primitive(6)->channelId(), + muonpath->primitive(6)->tdcTimeStamp(), + muonpath->primitive(6)->laterality(), + muonpath->primitive(7)->channelId(), + muonpath->primitive(7)->tdcTimeStamp(), + muonpath->primitive(7)->laterality()); + } + } + filteredMetaPrimitives.clear(); + + if (debug_) + LogDebug("DTTrigPhase2Prod") << "DTp2 in event:" << iEvent.id().event() << " we found " + << correlatedMetaPrimitives.size() << " correlatedMetPrimitives (chamber)"; + + if (dump_) { + LogInfo("DTTrigPhase2Prod") << "DTp2 in event:" << iEvent.id().event() << " we found " + << correlatedMetaPrimitives.size() << " correlatedMetPrimitives (chamber)"; + + for (unsigned int i = 0; i < correlatedMetaPrimitives.size(); i++) { + stringstream ss; + ss << iEvent.id().event() << " correlated mp " << i << ": "; + printmPC(ss.str(), correlatedMetaPrimitives.at(i)); + } + } + + double shift_back = 0; + if (scenario_ == MC) //scope for MC + shift_back = 400; + else if (scenario_ == DATA) //scope for data + shift_back = 0; + else if (scenario_ == SLICE_TEST) //scope for slice test + shift_back = 0; + + // RPC integration + if (useRPC_) { + rpc_integrator_->initialise(iEventSetup, shift_back); + rpc_integrator_->prepareMetaPrimitives(rpcRecHits); + rpc_integrator_->matchWithDTAndUseRPCTime(correlatedMetaPrimitives); + rpc_integrator_->makeRPCOnlySegments(); + rpc_integrator_->storeRPCSingleHits(); + rpc_integrator_->removeRPCHitsUsed(); + } + + /// STORING RESULTs + vector outP2Ph; + + // Assigning index value + assignIndex(correlatedMetaPrimitives); + for (const auto& metaPrimitiveIt : correlatedMetaPrimitives) { + DTChamberId chId(metaPrimitiveIt.rawId); + if (debug_) + LogDebug("DTTrigPhase2Prod") << "looping in final vector: SuperLayerId" << chId << " x=" << metaPrimitiveIt.x + << " quality=" << metaPrimitiveIt.quality + << " BX=" << round(metaPrimitiveIt.t0 / 25.) << " index=" << metaPrimitiveIt.index; + + int sectorTP = chId.sector(); + //sectors 13 and 14 exist only for the outermost stations for sectors 4 and 10 respectively + //due to the larger MB4 that are divided into two. + if (sectorTP == 13) + sectorTP = 4; + if (sectorTP == 14) + sectorTP = 10; + sectorTP = sectorTP - 1; + int sl = 0; + if (metaPrimitiveIt.quality < LOWLOWQ || metaPrimitiveIt.quality == CHIGHQ) { + if (inner(metaPrimitiveIt)) + sl = 1; + else + sl = 3; + } + + if (debug_) + LogDebug("DTTrigPhase2Prod") << "pushing back phase-2 dataformat carlo-federica dataformat"; + outP2Ph.push_back(L1Phase2MuDTPhDigi( + (int)round(metaPrimitiveIt.t0 / (float)LHC_CLK_FREQ) - shift_back, + chId.wheel(), // uwh (m_wheel) + sectorTP, // usc (m_sector) + chId.station(), // ust (m_station) + sl, // ust (m_station) + (int)round(metaPrimitiveIt.phi * PHIRES_CONV), // uphi (_phiAngle) + (int)round(metaPrimitiveIt.phiB * PHIBRES_CONV), // uphib (m_phiBending) + metaPrimitiveIt.quality, // uqua (m_qualityCode) + metaPrimitiveIt.index, // uind (m_segmentIndex) + (int)round(metaPrimitiveIt.t0) - shift_back * LHC_CLK_FREQ, // ut0 (m_t0Segment) + (int)round(metaPrimitiveIt.chi2 * CHI2RES_CONV), // uchi2 (m_chi2Segment) + metaPrimitiveIt.rpcFlag // urpc (m_rpcFlag) + )); + } + + // Storing RPC hits that were not used elsewhere + if (useRPC_) { + for (auto rpc_dt_digi = rpc_integrator_->rpcRecHits_translated_.begin(); + rpc_dt_digi != rpc_integrator_->rpcRecHits_translated_.end(); + rpc_dt_digi++) { + outP2Ph.push_back(*rpc_dt_digi); + } + } + + auto resultP2Ph = std::make_unique(); + resultP2Ph->setContainer(outP2Ph); + iEvent.put(std::move(resultP2Ph)); + outP2Ph.clear(); + outP2Ph.erase(outP2Ph.begin(), outP2Ph.end()); +} + +void DTTrigPhase2Prod::endRun(edm::Run const& iRun, const edm::EventSetup& iEventSetup) { + grouping_obj_->finish(); + mpathanalyzer_->finish(); + mpathqualityenhancer_->finish(); + mpathredundantfilter_->finish(); + mpathassociator_->finish(); + rpc_integrator_->finish(); +}; + +bool DTTrigPhase2Prod::outer(const metaPrimitive& mp) const { + int counter = (mp.wi5 != -1) + (mp.wi6 != -1) + (mp.wi7 != -1) + (mp.wi8 != -1); + return (counter > 2); +} + +bool DTTrigPhase2Prod::inner(const metaPrimitive& mp) const { + int counter = (mp.wi1 != -1) + (mp.wi2 != -1) + (mp.wi3 != -1) + (mp.wi4 != -1); + return (counter > 2); +} + +bool DTTrigPhase2Prod::hasPosRF(int wh, int sec) const { return wh > 0 || (wh == 0 && sec % 4 > 1); } + +void DTTrigPhase2Prod::printmP(const string& ss, const metaPrimitive& mP) const { + DTSuperLayerId slId(mP.rawId); + LogInfo("DTTrigPhase2Prod") << ss << (int)slId << "\t " << setw(2) << left << mP.wi1 << " " << setw(2) << left + << mP.wi2 << " " << setw(2) << left << mP.wi3 << " " << setw(2) << left << mP.wi4 << " " + << setw(5) << left << mP.tdc1 << " " << setw(5) << left << mP.tdc2 << " " << setw(5) + << left << mP.tdc3 << " " << setw(5) << left << mP.tdc4 << " " << setw(10) << right + << mP.x << " " << setw(9) << left << mP.tanPhi << " " << setw(5) << left << mP.t0 << " " + << setw(13) << left << mP.chi2 << " r:" << rango(mP); +} + +void DTTrigPhase2Prod::printmPC(const string& ss, const metaPrimitive& mP) const { + DTChamberId ChId(mP.rawId); + LogInfo("DTTrigPhase2Prod") << ss << (int)ChId << "\t " << setw(2) << left << mP.wi1 << " " << setw(2) << left + << mP.wi2 << " " << setw(2) << left << mP.wi3 << " " << setw(2) << left << mP.wi4 << " " + << setw(2) << left << mP.wi5 << " " << setw(2) << left << mP.wi6 << " " << setw(2) << left + << mP.wi7 << " " << setw(2) << left << mP.wi8 << " " << setw(5) << left << mP.tdc1 << " " + << setw(5) << left << mP.tdc2 << " " << setw(5) << left << mP.tdc3 << " " << setw(5) + << left << mP.tdc4 << " " << setw(5) << left << mP.tdc5 << " " << setw(5) << left + << mP.tdc6 << " " << setw(5) << left << mP.tdc7 << " " << setw(5) << left << mP.tdc8 + << " " << setw(2) << left << mP.lat1 << " " << setw(2) << left << mP.lat2 << " " + << setw(2) << left << mP.lat3 << " " << setw(2) << left << mP.lat4 << " " << setw(2) + << left << mP.lat5 << " " << setw(2) << left << mP.lat6 << " " << setw(2) << left + << mP.lat7 << " " << setw(2) << left << mP.lat8 << " " << setw(10) << right << mP.x << " " + << setw(9) << left << mP.tanPhi << " " << setw(5) << left << mP.t0 << " " << setw(13) + << left << mP.chi2 << " r:" << rango(mP); +} + +int DTTrigPhase2Prod::rango(const metaPrimitive& mp) const { + if (mp.quality == 1 or mp.quality == 2) + return 3; + if (mp.quality == 3 or mp.quality == 4) + return 4; + return mp.quality; +} + +void DTTrigPhase2Prod::assignIndex(std::vector& inMPaths) { + std::map> primsPerBX; + for (const auto& metaPrimitive : inMPaths) { + int BX = round(metaPrimitive.t0 / 25.); + primsPerBX[BX].push_back(metaPrimitive); + } + inMPaths.clear(); + for (auto& prims : primsPerBX) { + assignIndexPerBX(prims.second); + for (const auto& primitive : prims.second) + inMPaths.push_back(primitive); + } +} + +void DTTrigPhase2Prod::assignIndexPerBX(std::vector& inMPaths) { + // First we asociate a new index to the metaprimitive depending on quality or phiB; + uint32_t rawId = -1; + int numP = -1; + for (auto& metaPrimitiveIt : inMPaths) { + numP++; + rawId = metaPrimitiveIt.rawId; + int iOrder = assignQualityOrder(metaPrimitiveIt); + int inf = 0; + int numP2 = -1; + for (auto& metaPrimitiveItN : inMPaths) { + int nOrder = assignQualityOrder(metaPrimitiveItN); + numP2++; + if (rawId != metaPrimitiveItN.rawId) + continue; + if (numP2 == numP) { + metaPrimitiveIt.index = inf; + break; + } else if (iOrder < nOrder) { + inf++; + } else if (iOrder > nOrder) { + metaPrimitiveItN.index++; + } else if (iOrder == nOrder) { + if (std::abs(metaPrimitiveIt.phiB) >= std::abs(metaPrimitiveItN.phiB)) { + inf++; + } else if (std::abs(metaPrimitiveIt.phiB) < std::abs(metaPrimitiveItN.phiB)) { + metaPrimitiveItN.index++; + } + } + } // ending second for + } // ending first for +} + +int DTTrigPhase2Prod::assignQualityOrder(const metaPrimitive& mP) const { + if (mP.quality > 9 || mP.quality < 1) + return -1; + + return qmap_.find(mP.quality)->second; +} + +std::vector DTTrigPhase2Prod::distribDigis(std::queue>& inQ) { + std::vector>*> tmpVector; + tmpVector.clear(); + 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(); + } + collVector.push_back(&tmpColl); + } + return collVector; +} + +void DTTrigPhase2Prod::processDigi(std::queue>& inQ, + 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()) { + // Time requirement + if (TMath::Abs(sC->front().second.wire() - inQ.front().second.wire()) <= superCellhalfspacewidth_) { + // Spatial requirement + sC->push(std::move(inQ.front())); + classified = true; + } + } + } + } + if (classified) { + inQ.pop(); + return; + } + + std::queue> newQueue; + + std::pair tmpPair; + tmpPair = std::move(inQ.front()); + newQueue.push(tmpPair); + inQ.pop(); + + vec.push_back(&newQueue); +} + +DEFINE_FWK_MODULE(DTTrigPhase2Prod); diff --git a/L1Trigger/DTTriggerPhase2/python/CalibratedDigis_cfi.py b/L1Trigger/DTTriggerPhase2/python/CalibratedDigis_cfi.py new file mode 100644 index 0000000000000..8fd4400f161b5 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/python/CalibratedDigis_cfi.py @@ -0,0 +1,30 @@ +import FWCore.ParameterSet.Config as cms + +# The reconstruction algo and its parameter set +# constant vdrift from DB (and ttrig from DB) + +CalibratedDigis = cms.EDProducer("CalibratedDigis", + tTrigModeConfig = cms.PSet( + # The velocity of signal propagation along the wire (cm/ns) + vPropWire = cms.double(24.4), + # Switch on/off the TOF correction for particles + doTOFCorrection = cms.bool(True), + tofCorrType = cms.int32(0), + wirePropCorrType = cms.int32(0), + # Switch on/off the correction for the signal propagation along the wire + doWirePropCorrection = cms.bool(True), + # Switch on/off the TOF correction from pulses + doT0Correction = cms.bool(True), + debug = cms.untracked.bool(False), + tTrigLabel = cms.string(''), + ), + tTrigMode = cms.string('DTTTrigSyncFromDB'), + timeOffset = cms.int32(0), + flat_calib = cms.int32(0), + scenario = cms.untracked.int32(0), + dtDigiTag = cms.InputTag("muonDTDigis") + ) + + + + diff --git a/L1Trigger/DTTriggerPhase2/python/CalibratedDigishlt_cfi.py b/L1Trigger/DTTriggerPhase2/python/CalibratedDigishlt_cfi.py new file mode 100644 index 0000000000000..85592d4af6f85 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/python/CalibratedDigishlt_cfi.py @@ -0,0 +1,29 @@ +import FWCore.ParameterSet.Config as cms + +# The reconstruction algo and its parameter set +# constant vdrift from DB (and ttrig from DB) + +CalibratedDigis = cms.EDProducer("CalibratedDigis", + tTrigModeConfig = cms.PSet( + # The velocity of signal propagation along the wire (cm/ns) + vPropWire = cms.double(24.4), + # Switch on/off the TOF correction for particles + doTOFCorrection = cms.bool(True), + tofCorrType = cms.int32(0), + wirePropCorrType = cms.int32(0), + # Switch on/off the correction for the signal propagation along the wire + doWirePropCorrection = cms.bool(True), + # Switch on/off the TOF correction from pulses + doT0Correction = cms.bool(True), + debug = cms.untracked.bool(False), + tTrigLabel = cms.string(''), + ), + tTrigMode = cms.string('DTTTrigSyncFromDB'), + timeOffset = cms.int32(0), + flat_calib = cms.int32(0), + dtDigiTag = cms.InputTag("hltMuonDTDigis") + ) + + + + diff --git a/L1Trigger/DTTriggerPhase2/python/HoughGrouping_cfi.py b/L1Trigger/DTTriggerPhase2/python/HoughGrouping_cfi.py new file mode 100644 index 0000000000000..727deda514b87 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/python/HoughGrouping_cfi.py @@ -0,0 +1,42 @@ +import FWCore.ParameterSet.Config as cms + +HoughGrouping = cms.PSet(debug = cms.untracked.bool(False), + # HOUGH TRANSFORM CONFIGURATION + # Tangent of the angle that puts a limit to the maximum inclination of a + # muon. Then, the maximum number of radians of inclination of the muon + # is derived as pi/2 - arctan(angletan). + angletan = cms.untracked.double(0.3), + # Width (in sexageseimal degrees) of the angle bins of the line space. + anglebinwidth = cms.untracked.double(1.0), + # Width (in centimetres) of the position bins of the line space. + posbinwidth = cms.untracked.double(2.1), + + # MAXIMA SEARCH CONFIGURATION + # Maximum distance (in sexageseimal degrees) used to derive maxima. + maxdeltaAngDeg = cms.untracked.double(10), + # Maximum distance (in centimetres) used to derive maxima. + maxdeltaPos = cms.untracked.double(10), + # Upper number of entries of a line space bin that are needed to be + # considered for maxima search. + UpperNumber = cms.untracked.int32(6), + # Lower number of entries of a line space bin that are needed to be + # considered for maxima search. + LowerNumber = cms.untracked.int32(4), + + # HITS ASSOCIATION CONFIGURATION + # Distance to the wire (in centimetres) from a candidate line below + # which no laterality is assumed. + MaxDistanceToWire = cms.untracked.double(0.03), + + # CANDIDATE QUALITY CONFIGURATION + # Minimum number of layers on which the candidate has a hit (maximum 8). + minNLayerHits = cms.untracked.int32(6), + # Minimum number of hits in the superlayer with more hits. + minSingleSLHitsMax = cms.untracked.int32(3), + # Minimum number of hits in the superlayer with less hits. + minSingleSLHitsMin = cms.untracked.int32(3), + # Allow the algorithm to give you back uncorrelated candidates. + allowUncorrelatedPatterns = cms.untracked.bool(True), + # Minimum number of hits that uncorrelated candidates can have. + minUncorrelatedHits = cms.untracked.int32(3), + ) diff --git a/L1Trigger/DTTriggerPhase2/python/PseudoBayesGrouping_cfi.py b/L1Trigger/DTTriggerPhase2/python/PseudoBayesGrouping_cfi.py new file mode 100644 index 0000000000000..bbe30f1ed6be0 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/python/PseudoBayesGrouping_cfi.py @@ -0,0 +1,23 @@ +import FWCore.ParameterSet.Config as cms + +PseudoBayesPattern = cms.PSet(pattern_filename = cms.untracked.FileInPath("L1Trigger/DTTriggerPhase2/data/PseudoBayesPatterns_uncorrelated_v0.root"), + debug = cms.untracked.bool(False), + #Minimum number of layers hit (total). Together with the two parameters under this it means 4+4, 4+3 or 3+3 + minNLayerHits = cms.untracked.int32(4), + #Minimum number of hits in the most hit superlayer + minSingleSLHitsMax = cms.untracked.int32(2), + #Minimum number of hits in the less hit superlayer + minSingleSLHitsMin = cms.untracked.int32(2), + #By default pattern width is 1, 0 can be considered (harder fits but, lower efficiency of high quality), 2 is the absolute limit unless we have extremely bent muons somehow + allowedVariance = cms.untracked.int32(0), + #If true, it will provide all candidate sets with the same hits of the same quality (with lateralities defined). If false only the leading one (with its lateralities). + allowDuplicates = cms.untracked.bool(False), + #Also provide best estimates for the lateralities + setLateralities = cms.untracked.bool(True), + #Allow for uncorrelated patterns searching + allowUncorrelatedPatterns = cms.untracked.bool(True), + #If uncorrelated, minimum hits + minUncorrelatedHits = cms.untracked.int32(3), + #DTPrimitives are saved in the appropriate element of the muonPath array + saveOnPlace = cms.untracked.bool(True), + ) diff --git a/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py b/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py new file mode 100644 index 0000000000000..f1c65d71868e2 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py @@ -0,0 +1,51 @@ +import FWCore.ParameterSet.Config as cms + +from L1TriggerConfig.DTTPGConfigProducers.L1DTTPGConfigFromDB_cff import * +from L1Trigger.DTTriggerPhase2.HoughGrouping_cfi import HoughGrouping +from L1Trigger.DTTriggerPhase2.PseudoBayesGrouping_cfi import PseudoBayesPattern + +dtTriggerPhase2PrimitiveDigis = cms.EDProducer("DTTrigPhase2Prod", + digiTag = cms.InputTag("CalibratedDigis"), + trigger_with_sl = cms.untracked.int32(4), + tanPhiTh = cms.untracked.double(1.), + chi2Th = cms.untracked.double(0.01), #in cm^2 + chi2corTh = cms.untracked.double(0.1), #in cm^2 + do_correlation = cms.bool(True), + useBX_correlation = cms.untracked.bool(False), + dT0_correlate_TP = cms.untracked.double(25.), + dBX_correlate_TP = cms.untracked.int32(0), + dTanPsi_correlate_TP = cms.untracked.double(99999.), + clean_chi2_correlation = cms.untracked.bool(True), + allow_confirmation = cms.untracked.bool(True), + use_LSB = cms.untracked.bool(True), + tanPsi_precision = cms.untracked.double(1./4096.), + x_precision = cms.untracked.double(1./160.), + minx_match_2digis = cms.untracked.double(1.), + scenario = cms.int32(0), #0 for mc, 1 for data, 2 for slice test + filter_cousins = cms.untracked.bool(True), + + ttrig_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_ttrig.txt'), + z_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_z.txt'), + shift_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_x.txt'), + algo = cms.int32(0), # 0 = STD gr., 2 = Hough transform, 1 = PseudoBayes Approach + + minHits4Fit = cms.untracked.int32(4), + + #debugging + debug = cms.untracked.bool(False), + dump = cms.untracked.bool(False), + + #RPC + rpcRecHits = cms.InputTag("rpcRecHits"), + useRPC = cms.bool(False), + bx_window = cms.untracked.int32(1), # will look for RPC cluster within a bunch crossing window of 'dt.BX +- bx_window' + phi_window = cms.untracked.double(50.), # will look for RPC cluster within a phi window of +- phi_window in arbitrary coordinates (plot the value we cut on in RPCIntergator to fine tune it) + max_quality_to_overwrite_t0 = cms.untracked.int32(9), # will use RPC to set 't0' for TP with quality < 'max_quality_to_overwrite_t0' + storeAllRPCHits = cms.untracked.bool(False), + activateBuffer = cms.bool(False), + superCelltimewidth = cms.double(400), # in nanoseconds + superCellspacewidth = cms.int32(20), # in number of cells: IT MUST BE AN EVEN NUMBER + ) + +dtTriggerPhase2PrimitiveDigis.HoughGrouping = HoughGrouping +dtTriggerPhase2PrimitiveDigis.PseudoBayesPattern = PseudoBayesPattern diff --git a/L1Trigger/DTTriggerPhase2/src/CandidateGroup.cc b/L1Trigger/DTTriggerPhase2/src/CandidateGroup.cc new file mode 100644 index 0000000000000..2875ae71b10f5 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/CandidateGroup.cc @@ -0,0 +1,118 @@ +#include "L1Trigger/DTTriggerPhase2/interface/CandidateGroup.h" + +#include +#include + +using namespace dtbayesam; + +//------------------------------------------------------------------ +//--- Constructores y destructores +//------------------------------------------------------------------ +CandidateGroup::CandidateGroup(DTPattern* p) { + nhits_ = 0; + nLayerhits_ = 0; + nisGood_ = 0; + nLayerDown_ = 0; + nLayerUp_ = 0; + pattern_ = p; +} + +CandidateGroup::CandidateGroup() {} + +CandidateGroup::~CandidateGroup() {} + +void CandidateGroup::addHit(DTPrimitive dthit, int lay, bool isGood) { + //Add a hit, check if the hits layer was fired and if it wasn't add it to the fired layers + candHits_.push_back(std::make_shared(dthit)); + if (quality_ != (quality_ | qualitybits(std::pow(2, lay)))) + nLayerhits_++; + if (isGood) + nisGood_++; + quality_ = quality_ | qualitybits(std::pow(2, lay)); + nhits_++; + if (lay <= 3) + nLayerDown_++; + if (lay >= 4) + nLayerUp_++; +} + +void CandidateGroup::removeHit(DTPrimitive dthit) { + //Add a hit, check if the hits layer was fired and if it wasn't add it to the fired layers + DTPrimitivePtrs tempHits; + nhits_ = 0; + nLayerDown_ = 0; + nLayerUp_ = 0; + nLayerhits_ = 0; + nisGood_ = 0; + quality_ = qualitybits("00000000"); + for (auto dt_it = candHits_.begin(); dt_it != candHits_.end(); dt_it++) { + if (dthit.layerId() == (*dt_it)->layerId() && dthit.channelId() == (*dt_it)->channelId()) { + } else { + if (pattern_->latHitIn((*dt_it)->layerId(), (*dt_it)->channelId(), 0) > -5) + nisGood_++; + if (quality_ != (quality_ | qualitybits(std::pow(2, (*dt_it)->layerId())))) + nLayerhits_++; + quality_ = quality_ | qualitybits(std::pow(2, (*dt_it)->layerId())); + nhits_++; + if ((*dt_it)->layerId() <= 3) + nLayerDown_++; + else if ((*dt_it)->layerId() >= 4) + nLayerUp_++; + tempHits.push_back(*dt_it); + } + } + candHits_ = tempHits; +} + +bool CandidateGroup::operator>(const CandidateGroup& cOther) const { + //First number of good (in pattern) matched hits + if (nisGood_ > cOther.nisGood()) + return true; + else if (nisGood_ < cOther.nisGood()) + return false; + //Tehn quality_ is number of layers fired + else if (nLayerhits_ > cOther.nLayerhits()) + return true; + else if (nLayerhits_ < cOther.nLayerhits()) + return false; + //Then number of matched hits (if multiple hits in a layer is better) + else if (nhits_ > cOther.nhits()) + return true; + else if (nhits_ < cOther.nhits()) + return false; + //Balanced quality_, prefer 3+2 over 4+1 for example + else if ((nLayerUp_ - nLayerDown_) > (cOther.nLayerUp() - cOther.nLayerDown())) + return true; + else if ((nLayerUp_ - nLayerDown_) < (cOther.nLayerUp() - cOther.nLayerDown())) + return false; + //Last, patterns with less gen hits are better matched + else if (pattern_->genHits().size() < (cOther.pattern()->genHits().size())) + return true; + else if (pattern_->genHits().size() > (cOther.pattern()->genHits().size())) + return false; + //For a total order relation we need this additional dummy + else if (candId_ < cOther.candId()) + return true; + else if (candId_ > cOther.candId()) + return false; + + //If we are here, they are basically equal so it doesn't matter who goes first + return true; +} + +bool CandidateGroup::operator==(const CandidateGroup& cOther) const { + //First number of good hits + if (nisGood_ != cOther.nisGood()) + return false; + //First quality_ is number of layers fired + else if (nLayerhits_ != cOther.nLayerhits()) + return false; + //Then number of matched hits (if multiple hits in a layer is better) + else if (nhits_ != cOther.nhits()) + return false; + //Balanced quality_, prefer 3+2 over 4+1 for example + else if ((nLayerUp_ - nLayerDown_) != (cOther.nLayerUp() - cOther.nLayerDown())) + return false; + //Last, patterns with less gen hits are better matched + return true; +} diff --git a/L1Trigger/DTTriggerPhase2/src/DTPattern.cc b/L1Trigger/DTTriggerPhase2/src/DTPattern.cc new file mode 100644 index 0000000000000..9902df6e41dc2 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/DTPattern.cc @@ -0,0 +1,69 @@ +#include "L1Trigger/DTTriggerPhase2/interface/DTPattern.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include + +//------------------------------------------------------------------ +//--- Constructores y destructores +//------------------------------------------------------------------ +DTPattern::DTPattern() {} + +DTPattern::DTPattern(RefDTPatternHit seedUp, RefDTPatternHit seedDown) : seedUp_(seedUp), seedDown_(seedDown) { + //On creation, pattern is based on seeds, with no hits. Due to traslational simmetry we only need the superlayer indexes as well as the cell index difference + id_ = std::make_tuple(std::get<0>(seedUp), std::get<0>(seedDown), std::get<1>(seedUp) - std::get<1>(seedDown)); + if (debug_) + LogDebug("DTPattern") << "Pattern id: " << std::get<0>(id_) << " , " << std::get<1>(id_) << " , " + << std::get<2>(id_); +} + +DTPattern::DTPattern(int SL1, int SL2, int diff) { + //On creation, pattern is based on seeds, with no hits. Due to traslational simmetry we only need the superlayer indexes as well as the cell index difference + seedUp_ = std::make_tuple(SL1, 0, 0); + seedDown_ = std::make_tuple(SL2, diff, 0); + id_ = std::make_tuple(SL1, SL2, diff); + if (debug_) + LogDebug("DTPattern") << "Pattern id: " << std::get<0>(id_) << " , " << std::get<1>(id_) << " , " + << std::get<2>(id_); +} + +void DTPattern::addHit(RefDTPatternHit hit) { + //Add additional gen level hits in the gen pattern coordinates (untranslated) + genHits_.push_back(hit); + if (debug_) + LogDebug("DTPattern") << "Added gen hit: " << std::get<0>(hit) << " , " << std::get<1>(hit) << " , " + << std::get<2>(hit); +} + +int DTPattern::latHitIn(int slId, int chId, int allowedVariance) const { + //Check if a hit is inside of the pattern for a given pattern width + int temp = -999; + for (auto it = this->genHits_.begin(); it != this->genHits_.end(); ++it) { + if (slId == (std::get<0>(*it) - 1)) { + if (chId == (std::get<1>(*it) + recoseedDown_)) { + return std::get<2>(*it); + } + //This is equivalent to an allowed discrete width of the pattern (configured) + else if ((chId <= (std::get<1>(*it) + recoseedDown_ + allowedVariance)) && + (chId >= (std::get<1>(*it) + recoseedDown_ - allowedVariance))) { + temp = -10; + } + } + } + return temp; +} + +std::ostream &operator<<(std::ostream &out, DTPattern &p) { + //Friend for printing pattern information trough iostream + out << "Pattern id: " << std::get<0>(p.id()) << " , " << std::get<1>(p.id()) << " , " << std::get<2>(p.id()) + << std::endl; + std::vector thegenHits = p.genHits(); + out << "Pattern hits: " << std::endl; + + for (std::vector::iterator itHit = thegenHits.begin(); itHit != thegenHits.end(); itHit++) { + out << "[" << std::get<0>(*itHit) << " , " << std::get<1>(*itHit) << " , " << std::get<2>(*itHit) << "]"; + } + return out; +} + +DTPattern::~DTPattern() {} diff --git a/L1Trigger/DTTriggerPhase2/src/DTprimitive.cc b/L1Trigger/DTTriggerPhase2/src/DTprimitive.cc new file mode 100644 index 0000000000000..173f692562461 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/DTprimitive.cc @@ -0,0 +1,66 @@ +#include "L1Trigger/DTTriggerPhase2/interface/DTprimitive.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include +#include + +using namespace cmsdt; +//------------------------------------------------------------------ +//--- Constructores y destructores +//------------------------------------------------------------------ +DTPrimitive::DTPrimitive() { + cameraId_ = -1; + superLayerId_ = -1; + layerId_ = -1; + channelId_ = -1; + tdcTimeStamp_ = -1; + orbit_ = -1; + timeCorrection_ = 0; + laterality_ = NONE; + + for (int i = 0; i < PAYLOAD_ENTRIES; i++) + setPayload(0.0, i); +} + +DTPrimitive::DTPrimitive(DTPrimitivePtr& ptr) { + setTimeCorrection(ptr->timeCorrection()); + setTDCTimeStamp(ptr->tdcTimeStamp()); + setOrbit(ptr->orbit()); + setChannelId(ptr->channelId()); + setLayerId(ptr->layerId()); + setCameraId(ptr->cameraId()); + setSuperLayerId(ptr->superLayerId()); + setLaterality(ptr->laterality()); + + for (int i = 0; i < PAYLOAD_ENTRIES; i++) + setPayload(ptr->payLoad(i), i); +} + +DTPrimitive::DTPrimitive(DTPrimitive* ptr) { + setTimeCorrection(ptr->timeCorrection()); + setTDCTimeStamp(ptr->tdcTimeStamp()); + setOrbit(ptr->orbit()); + setChannelId(ptr->channelId()); + setLayerId(ptr->layerId()); + setCameraId(ptr->cameraId()); + setSuperLayerId(ptr->superLayerId()); + setLaterality(ptr->laterality()); + + for (int i = 0; i < PAYLOAD_ENTRIES; i++) + setPayload(ptr->payLoad(i), i); +} + +DTPrimitive::~DTPrimitive() {} + +//------------------------------------------------------------------ +//--- Public Methods +//------------------------------------------------------------------ +bool DTPrimitive::isValidTime(void) { return (tdcTimeStamp_ >= 0 ? true : false); } + +float DTPrimitive::wireHorizPos(void) { + // For layers with odd-number + float wireHorizPos = CELL_LENGTH * channelId(); + // If layer is even, you must correct by half a cell + if (layerId() == 0 || layerId() == 2) + wireHorizPos += CELL_SEMILENGTH; + return wireHorizPos; +} diff --git a/L1Trigger/DTTriggerPhase2/src/HoughGrouping.cc b/L1Trigger/DTTriggerPhase2/src/HoughGrouping.cc new file mode 100644 index 0000000000000..d4cdccb1ad514 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/HoughGrouping.cc @@ -0,0 +1,905 @@ +#include "L1Trigger/DTTriggerPhase2/interface/HoughGrouping.h" + +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/Math/interface/CMSUnits.h" + +#include +#include + +#include "TMath.h" + +using namespace std; +using namespace edm; +using namespace cmsdt; +using namespace cms_units::operators; + +namespace { + struct { + bool operator()(ProtoCand a, ProtoCand b) const { + unsigned short int sumhqa = 0; + unsigned short int sumhqb = 0; + unsigned short int sumlqa = 0; + unsigned short int sumlqb = 0; + double sumdista = 0; + double sumdistb = 0; + + for (unsigned short int lay = 0; lay < 8; lay++) { + sumhqa += (unsigned short int)a.isThereHitInLayer_[lay]; + sumhqb += (unsigned short int)b.isThereHitInLayer_[lay]; + sumlqa += (unsigned short int)a.isThereNeighBourHitInLayer_[lay]; + sumlqb += (unsigned short int)b.isThereNeighBourHitInLayer_[lay]; + sumdista += a.xDistToPattern_[lay]; + sumdistb += b.xDistToPattern_[lay]; + } + + if (a.nLayersWithHits_ != b.nLayersWithHits_) + return (a.nLayersWithHits_ > b.nLayersWithHits_); // number of layers with hits + else if (sumhqa != sumhqb) + return (sumhqa > sumhqb); // number of hq hits + else if (sumlqa != sumlqb) + return (sumlqa > sumlqb); // number of lq hits + else if (a.nHitsDiff_ != b.nHitsDiff_) + return (a.nHitsDiff_ < b.nHitsDiff_); // abs. diff. between SL1 & SL3 hits + else + return (sumdista < sumdistb); // abs. dist. to digis + } + } HoughOrdering; +} // namespace +// ============================================================================ +// Constructors and destructor +// ============================================================================ +HoughGrouping::HoughGrouping(const ParameterSet& pset, edm::ConsumesCollector& iC) : MotherGrouping(pset, iC) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); + if (debug_) + LogDebug("HoughGrouping") << "HoughGrouping: constructor"; + + // HOUGH TRANSFORM CONFIGURATION + angletan_ = pset.getUntrackedParameter("angletan"); + anglebinwidth_ = pset.getUntrackedParameter("anglebinwidth"); + posbinwidth_ = pset.getUntrackedParameter("posbinwidth"); + + // MAXIMA SEARCH CONFIGURATION + maxdeltaAngDeg_ = pset.getUntrackedParameter("maxdeltaAngDeg"); + maxdeltaPos_ = pset.getUntrackedParameter("maxdeltaPos"); + upperNumber_ = (unsigned short int)pset.getUntrackedParameter("UpperNumber"); + lowerNumber_ = (unsigned short int)pset.getUntrackedParameter("LowerNumber"); + + // HITS ASSOCIATION CONFIGURATION + maxDistanceToWire_ = pset.getUntrackedParameter("MaxDistanceToWire"); + + // CANDIDATE QUALITY CONFIGURATION + minNLayerHits_ = (unsigned short int)pset.getUntrackedParameter("minNLayerHits"); + minSingleSLHitsMax_ = (unsigned short int)pset.getUntrackedParameter("minSingleSLHitsMax"); + minSingleSLHitsMin_ = (unsigned short int)pset.getUntrackedParameter("minSingleSLHitsMin"); + allowUncorrelatedPatterns_ = pset.getUntrackedParameter("allowUncorrelatedPatterns"); + minUncorrelatedHits_ = (unsigned short int)pset.getUntrackedParameter("minUncorrelatedHits"); + + dtGeomH = iC.esConsumes(); +} + +HoughGrouping::~HoughGrouping() { + if (debug_) + LogDebug("HoughGrouping") << "HoughGrouping: destructor" << endl; +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void HoughGrouping::initialise(const edm::EventSetup& iEventSetup) { + if (debug_) + LogDebug("HoughGrouping") << "initialise"; + + resetAttributes(); + + maxrads_ = 0.5 * M_PI - atan(angletan_); + minangle_ = (double)convertDegToRad(anglebinwidth_); + halfanglebins_ = round(maxrads_ / minangle_ + 1); + anglebins_ = (unsigned short int)2 * halfanglebins_; + oneanglebin_ = maxrads_ / halfanglebins_; + + maxdeltaAng_ = maxdeltaAngDeg_ * 2 * M_PI / 360; + + // Initialisation of anglemap. Posmap depends on the size of the chamber. + double phi = 0; + anglemap_ = {}; + for (unsigned short int ab = 0; ab < halfanglebins_; ab++) { + anglemap_[ab] = phi; + phi += oneanglebin_; + } + + phi = (M_PI - maxrads_); + for (unsigned short int ab = halfanglebins_; ab < anglebins_; ab++) { + anglemap_[ab] = phi; + phi += oneanglebin_; + } + + if (debug_) { + LogDebug("HoughGrouping") + << "\nHoughGrouping::ResetAttributes - Information from the initialisation of HoughGrouping:"; + LogDebug("HoughGrouping") << "ResetAttributes - maxrads: " << maxrads_; + LogDebug("HoughGrouping") << "ResetAttributes - anglebinwidth: " << anglebinwidth_; + LogDebug("HoughGrouping") << "ResetAttributes - minangle: " << minangle_; + LogDebug("HoughGrouping") << "ResetAttributes - halfanglebins: " << halfanglebins_; + LogDebug("HoughGrouping") << "ResetAttributes - anglebins: " << anglebins_; + LogDebug("HoughGrouping") << "ResetAttributes - oneanglebin: " << oneanglebin_; + LogDebug("HoughGrouping") << "ResetAttributes - posbinwidth: " << posbinwidth_; + } + + const MuonGeometryRecord& geom = iEventSetup.get(); + dtGeo_ = &geom.get(dtGeomH); +} + +void HoughGrouping::run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& outMpath) { + if (debug_) + LogDebug("HoughGrouping") << "\nHoughGrouping::run"; + + resetAttributes(); + + if (debug_) + LogDebug("HoughGrouping") << "run - Beginning digis' loop..."; + LocalPoint wirePosInLay, wirePosInChamber; + GlobalPoint wirePosGlob; + for (DTDigiCollection::DigiRangeIterator dtLayerIdIt = digis.begin(); dtLayerIdIt != digis.end(); dtLayerIdIt++) { + const DTLayer* lay = dtGeo_->layer((*dtLayerIdIt).first); + for (DTDigiCollection::const_iterator digiIt = ((*dtLayerIdIt).second).first; + digiIt != ((*dtLayerIdIt).second).second; + digiIt++) { + if (debug_) { + LogDebug("HoughGrouping") << "\nHoughGrouping::run - Digi number " << idigi_; + LogDebug("HoughGrouping") << "run - Wheel: " << (*dtLayerIdIt).first.wheel(); + LogDebug("HoughGrouping") << "run - Chamber: " << (*dtLayerIdIt).first.station(); + LogDebug("HoughGrouping") << "run - Sector: " << (*dtLayerIdIt).first.sector(); + LogDebug("HoughGrouping") << "run - Superlayer: " << (*dtLayerIdIt).first.superLayer(); + LogDebug("HoughGrouping") << "run - Layer: " << (*dtLayerIdIt).first.layer(); + LogDebug("HoughGrouping") << "run - Wire: " << (*digiIt).wire(); + LogDebug("HoughGrouping") << "run - First wire: " << lay->specificTopology().firstChannel(); + LogDebug("HoughGrouping") << "run - Last wire: " << lay->specificTopology().lastChannel(); + LogDebug("HoughGrouping") << "run - First wire x: " + << lay->specificTopology().wirePosition(lay->specificTopology().firstChannel()); + LogDebug("HoughGrouping") << "run - Last wire x: " + << lay->specificTopology().wirePosition(lay->specificTopology().lastChannel()); + LogDebug("HoughGrouping") << "run - Cell width: " << lay->specificTopology().cellWidth(); + LogDebug("HoughGrouping") << "run - Cell height: " << lay->specificTopology().cellHeight(); + } + if ((*dtLayerIdIt).first.superLayer() == 2) + continue; + + wirePosInLay = LocalPoint(lay->specificTopology().wirePosition((*digiIt).wire()), 0, 0); + wirePosGlob = lay->toGlobal(wirePosInLay); + wirePosInChamber = lay->chamber()->toLocal(wirePosGlob); + + if ((*dtLayerIdIt).first.superLayer() == 3) { + digimap_[(*dtLayerIdIt).first.layer() + 3][(*digiIt).wire()] = DTPrimitive(); + digimap_[(*dtLayerIdIt).first.layer() + 3][(*digiIt).wire()].setTDCTimeStamp((*digiIt).time()); + digimap_[(*dtLayerIdIt).first.layer() + 3][(*digiIt).wire()].setChannelId((*digiIt).wire()); + digimap_[(*dtLayerIdIt).first.layer() + 3][(*digiIt).wire()].setLayerId((*dtLayerIdIt).first.layer()); + digimap_[(*dtLayerIdIt).first.layer() + 3][(*digiIt).wire()].setSuperLayerId((*dtLayerIdIt).first.superLayer()); + digimap_[(*dtLayerIdIt).first.layer() + 3][(*digiIt).wire()].setCameraId((*dtLayerIdIt).first.rawId()); + } else { + digimap_[(*dtLayerIdIt).first.layer() - 1][(*digiIt).wire()] = DTPrimitive(); + digimap_[(*dtLayerIdIt).first.layer() - 1][(*digiIt).wire()].setTDCTimeStamp((*digiIt).time()); + digimap_[(*dtLayerIdIt).first.layer() - 1][(*digiIt).wire()].setChannelId((*digiIt).wire()); + digimap_[(*dtLayerIdIt).first.layer() - 1][(*digiIt).wire()].setLayerId((*dtLayerIdIt).first.layer()); + digimap_[(*dtLayerIdIt).first.layer() - 1][(*digiIt).wire()].setSuperLayerId((*dtLayerIdIt).first.superLayer()); + digimap_[(*dtLayerIdIt).first.layer() - 1][(*digiIt).wire()].setCameraId((*dtLayerIdIt).first.rawId()); + } + + // Obtaining geometrical info of the chosen chamber + if (xlowlim_ == 0 && xhighlim_ == 0 && zlowlim_ == 0 && zhighlim_ == 0) { + thewheel_ = (*dtLayerIdIt).first.wheel(); + thestation_ = (*dtLayerIdIt).first.station(); + thesector_ = (*dtLayerIdIt).first.sector(); + obtainGeometricalBorders(lay); + } + + if (debug_) { + LogDebug("HoughGrouping") << "run - X position of the cell (chamber frame of reference): " + << wirePosInChamber.x(); + LogDebug("HoughGrouping") << "run - Y position of the cell (chamber frame of reference): " + << wirePosInChamber.y(); + LogDebug("HoughGrouping") << "run - Z position of the cell (chamber frame of reference): " + << wirePosInChamber.z(); + } + + hitvec_.push_back({wirePosInChamber.x() - 1.05, wirePosInChamber.z()}); + hitvec_.push_back({wirePosInChamber.x() + 1.05, wirePosInChamber.z()}); + nhits_ += 2; + + idigi_++; + } + } + + if (debug_) { + LogDebug("HoughGrouping") << "\nHoughGrouping::run - nhits: " << nhits_; + LogDebug("HoughGrouping") << "run - idigi: " << idigi_; + } + + if (hitvec_.empty()) { + if (debug_) + LogDebug("HoughGrouping") << "run - No digis present in this chamber."; + return; + } + + // Perform the Hough transform of the inputs. + doHoughTransform(); + + // Obtain the maxima + maxima_ = getMaximaVector(); + resetPosElementsOfLinespace(); + + if (maxima_.empty()) { + if (debug_) + LogDebug("HoughGrouping") << "run - No good maxima found in this event."; + return; + } + + DTChamberId TheChambId(thewheel_, thestation_, thesector_); + const DTChamber* TheChamb = dtGeo_->chamber(TheChambId); + std::vector cands; + + for (unsigned short int ican = 0; ican < maxima_.size(); ican++) { + if (debug_) + LogDebug("HoughGrouping") << "\nHoughGrouping::run - Candidate number: " << ican; + cands.push_back(associateHits(TheChamb, maxima_.at(ican).first, maxima_.at(ican).second)); + } + + // Now we filter them: + orderAndFilter(cands, outMpath); + if (debug_) + LogDebug("HoughGrouping") << "run - now we have our muonpaths! It has " << outMpath.size() << " elements"; + + cands.clear(); + return; +} + +void HoughGrouping::finish() { + if (debug_) + LogDebug("HoughGrouping") << "finish"; + return; +} + +// ============================================================================ +// Other methods +// ============================================================================ +void HoughGrouping::resetAttributes() { + if (debug_) + LogDebug("HoughGrouping") << "ResetAttributes"; + // std::vector's: + maxima_.clear(); + hitvec_.clear(); + + // Integer-type variables: + spacebins_ = 0; + idigi_ = 0; + nhits_ = 0; + xlowlim_ = 0; + xhighlim_ = 0; + zlowlim_ = 0; + zhighlim_ = 0; + thestation_ = 0; + thesector_ = 0; + thewheel_ = 0; + + // Arrays: + // NOTE: linespace array is treated and reset separately + + // Maps (dictionaries): + posmap_.clear(); + for (unsigned short int abslay = 0; abslay < 8; abslay++) + digimap_[abslay].clear(); +} + +void HoughGrouping::resetPosElementsOfLinespace() { + if (debug_) + LogDebug("HoughGrouping") << "ResetPosElementsOfLinespace"; + for (unsigned short int ab = 0; ab < anglebins_; ab++) { + linespace_[ab].clear(); + } + linespace_.clear(); +} + +void HoughGrouping::obtainGeometricalBorders(const DTLayer* lay) { + if (debug_) + LogDebug("HoughGrouping") << "ObtainGeometricalBorders"; + LocalPoint FirstWireLocal(lay->chamber()->superLayer(1)->layer(1)->specificTopology().wirePosition( + lay->chamber()->superLayer(1)->layer(1)->specificTopology().firstChannel()), + 0, + 0); // TAKING INFO FROM L1 OF SL1 OF THE CHOSEN CHAMBER + GlobalPoint FirstWireGlobal = lay->chamber()->superLayer(1)->layer(1)->toGlobal(FirstWireLocal); + LocalPoint FirstWireLocalCh = lay->chamber()->toLocal(FirstWireGlobal); + + LocalPoint LastWireLocal(lay->chamber()->superLayer(1)->layer(1)->specificTopology().wirePosition( + lay->chamber()->superLayer(1)->layer(1)->specificTopology().lastChannel()), + 0, + 0); + GlobalPoint LastWireGlobal = lay->chamber()->superLayer(1)->layer(1)->toGlobal(LastWireLocal); + LocalPoint LastWireLocalCh = lay->chamber()->toLocal(LastWireGlobal); + + // unsigned short int upsl = thestation == 4 ? 2 : 3; + unsigned short int upsl = thestation_ == 4 ? 3 : 3; + if (debug_) + LogDebug("HoughGrouping") << "ObtainGeometricalBorders - uppersuperlayer: " << upsl; + + LocalPoint FirstWireLocalUp(lay->chamber()->superLayer(upsl)->layer(4)->specificTopology().wirePosition( + lay->chamber()->superLayer(upsl)->layer(4)->specificTopology().firstChannel()), + 0, + 0); // TAKING INFO FROM L1 OF SL1 OF THE CHOSEN CHAMBER + GlobalPoint FirstWireGlobalUp = lay->chamber()->superLayer(upsl)->layer(4)->toGlobal(FirstWireLocalUp); + LocalPoint FirstWireLocalChUp = lay->chamber()->toLocal(FirstWireGlobalUp); + + xlowlim_ = FirstWireLocalCh.x() - lay->chamber()->superLayer(1)->layer(1)->specificTopology().cellWidth() / 2; + xhighlim_ = LastWireLocalCh.x() + lay->chamber()->superLayer(1)->layer(1)->specificTopology().cellWidth() / 2; + zlowlim_ = FirstWireLocalChUp.z() - lay->chamber()->superLayer(upsl)->layer(4)->specificTopology().cellHeight() / 2; + zhighlim_ = LastWireLocalCh.z() + lay->chamber()->superLayer(1)->layer(1)->specificTopology().cellHeight() / 2; + + spacebins_ = round(std::abs(xhighlim_ - xlowlim_) / posbinwidth_); +} + +void HoughGrouping::doHoughTransform() { + if (debug_) + LogDebug("HoughGrouping") << "DoHoughTransform"; + // First we want to obtain the number of bins in angle that we want. To do so, we will consider at first a maximum angle of + // (in rad.) pi/2 - arctan(0.3) (i.e. ~73º) and a resolution (width of bin angle) of 2º. + + if (debug_) { + LogDebug("HoughGrouping") << "DoHoughTransform - maxrads: " << maxrads_; + LogDebug("HoughGrouping") << "DoHoughTransform - minangle: " << minangle_; + LogDebug("HoughGrouping") << "DoHoughTransform - halfanglebins: " << halfanglebins_; + LogDebug("HoughGrouping") << "DoHoughTransform - anglebins: " << anglebins_; + LogDebug("HoughGrouping") << "DoHoughTransform - oneanglebin: " << oneanglebin_; + LogDebug("HoughGrouping") << "DoHoughTransform - spacebins: " << spacebins_; + } + + double rho = 0, phi = 0, sbx = 0; + double lowinitsb = xlowlim_ + posbinwidth_ / 2; + + // Initialisation + linespace_.resize(anglebins_, std::vector(spacebins_)); + for (unsigned short int ab = 0; ab < anglebins_; ab++) { + sbx = lowinitsb; + for (unsigned short int sb = 0; sb < spacebins_; sb++) { + posmap_[sb] = sbx; + linespace_[ab][sb] = 0; + sbx += posbinwidth_; + } + } + + // Filling of the double array and actually doing the transform + for (unsigned short int i = 0; i < hitvec_.size(); i++) { + for (unsigned short int ab = 0; ab < anglebins_; ab++) { + phi = anglemap_[ab]; + rho = hitvec_.at(i).first * cos(phi) + hitvec_.at(i).second * sin(phi); + sbx = lowinitsb - posbinwidth_ / 2; + for (unsigned short int sb = 0; sb < spacebins_; sb++) { + if (rho < sbx) { + linespace_[ab][sb]++; + break; + } + sbx += posbinwidth_; + } + } + } +} + +PointsInPlane HoughGrouping::getMaximaVector() { + if (debug_) + LogDebug("HoughGrouping") << "getMaximaVector"; + PointTuples tmpvec; + + bool flagsearched = false; + unsigned short int numbertolookat = upperNumber_; + + while (!flagsearched) { + for (unsigned short int ab = 0; ab < anglebins_; ab++) { + for (unsigned short int sb = 0; sb < spacebins_; sb++) { + if (linespace_[ab][sb] >= numbertolookat) + tmpvec.push_back({anglemap_[ab], posmap_[sb], linespace_[ab][sb]}); + } + } + if (((numbertolookat - 1) < lowerNumber_) || (!tmpvec.empty())) + flagsearched = true; + else + numbertolookat--; + } + + if (tmpvec.empty()) { + if (debug_) + LogDebug("HoughGrouping") << "GetMaximaVector - No maxima could be found"; + PointsInPlane finalvec; + return finalvec; + } else { + PointsInPlane finalvec = findTheMaxima(tmpvec); + + // And now obtain the values of m and n of the lines. + for (unsigned short int i = 0; i < finalvec.size(); i++) + finalvec.at(i) = transformPair(finalvec.at(i)); + return finalvec; + } +} + +PointInPlane HoughGrouping::transformPair(const PointInPlane& inputpair) { + if (debug_) + LogDebug("HoughGrouping") << "transformPair"; + // input: (ang, pos); output: (m, n) + if (inputpair.first == 0) + return {1000, -1000 * inputpair.second}; + else + return {-1. / tan(inputpair.first), inputpair.second / sin(inputpair.first)}; +} + +PointsInPlane HoughGrouping::findTheMaxima(PointTuples& inputvec) { + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima"; + bool fullyreduced = false; + unsigned short int ind = 0; + + std::vector chosenvec; + PointsInPlane resultvec; + PointInPlane finalpair = {}; + + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - prewhile"; + while (!fullyreduced) { + if (debug_) { + LogDebug("HoughGrouping") << "\nHoughGrouping::findTheMaxima - New iteration"; + LogDebug("HoughGrouping") << "findTheMaxima - inputvec size: " << inputvec.size(); + LogDebug("HoughGrouping") << "findTheMaxima - ind: " << ind; + LogDebug("HoughGrouping") << "findTheMaxima - maximum deltaang: " << maxdeltaAng_ + << " and maximum deltapos: " << maxdeltaPos_; + } + chosenvec.clear(); + //calculate distances and check out the ones that are near + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - Ours have " << get<2>(inputvec.at(ind)) + << " entries, ang.: " << get<0>(inputvec.at(ind)) + << " and pos.: " << get<1>(inputvec.at(ind)); + + for (unsigned short int j = ind + 1; j < inputvec.size(); j++) { + if (getTwoDelta(inputvec.at(ind), inputvec.at(j)).first <= maxdeltaAng_ && + getTwoDelta(inputvec.at(ind), inputvec.at(j)).second <= maxdeltaPos_) { + chosenvec.push_back(j); + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - - Adding num. " << j + << " with deltaang: " << getTwoDelta(inputvec.at(ind), inputvec.at(j)).first + << ", and deltapos: " << getTwoDelta(inputvec.at(ind), inputvec.at(j)).second + << " and with " << get<2>(inputvec.at(j)) + << " entries, ang.: " << get<0>(inputvec.at(j)) + << " and pos.: " << get<1>(inputvec.at(j)); + } else if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - - Ignoring num. " << j + << " with deltaang: " << getTwoDelta(inputvec.at(ind), inputvec.at(j)).first + << ", and deltapos: " << getTwoDelta(inputvec.at(ind), inputvec.at(j)).second + << " and with " << get<2>(inputvec.at(j)) << " entries."; + } + + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - chosenvecsize: " << chosenvec.size(); + + if (chosenvec.empty()) { + if (ind + 1 >= (unsigned short int)inputvec.size()) + fullyreduced = true; + if ((get<0>(inputvec.at(ind)) <= maxrads_) || (get<0>(inputvec.at(ind)) >= M_PI - maxrads_)) + resultvec.push_back({get<0>(inputvec.at(ind)), get<1>(inputvec.at(ind))}); + else if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - - Candidate dropped due to an excess in angle"; + ind++; + continue; + } + + // Now average them + finalpair = getAveragePoint(inputvec, ind, chosenvec); + + // Erase the ones you used + inputvec.erase(inputvec.begin() + ind); + for (short int j = chosenvec.size() - 1; j > -1; j--) { + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - erasing index: " << chosenvec.at(j) - 1; + inputvec.erase(inputvec.begin() + chosenvec.at(j) - 1); + } + + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - inputvec size: " << inputvec.size(); + + // And add the one you calculated: + if ((finalpair.first <= maxrads_) || (finalpair.first >= M_PI - maxrads_)) + resultvec.push_back(finalpair); + else if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - - Candidate dropped due to an excess in angle"; + + if (ind + 1 >= (unsigned short int)inputvec.size()) + fullyreduced = true; + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - iteration ends"; + ind++; + } + if (debug_) + LogDebug("HoughGrouping") << "findTheMaxima - postwhile"; + return resultvec; +} + +PointInPlane HoughGrouping::getTwoDelta(const PointTuple& pair1, const PointTuple& pair2) { + if (debug_) + LogDebug("HoughGrouping") << "getTwoDelta"; + return {abs(get<0>(pair1) - get<0>(pair2)), abs(get<1>(pair1) - get<1>(pair2))}; +} + +PointInPlane HoughGrouping::getAveragePoint(const PointTuples& inputvec, + unsigned short int firstindex, + const std::vector& indexlist) { + if (debug_) + LogDebug("HoughGrouping") << "getAveragePoint"; + std::vector xs; + std::vector ys; + std::vector ws; + xs.push_back(get<0>(inputvec.at(firstindex))); + ys.push_back(get<1>(inputvec.at(firstindex))); + ws.push_back(exp(get<2>(inputvec.at(firstindex)))); + for (unsigned short int i = 0; i < indexlist.size(); i++) { + xs.push_back(get<0>(inputvec.at(indexlist.at(i)))); + ys.push_back(get<1>(inputvec.at(indexlist.at(i)))); + ws.push_back(exp(get<2>(inputvec.at(indexlist.at(i))))); + } + return {TMath::Mean(xs.begin(), xs.end(), ws.begin()), TMath::Mean(ys.begin(), ys.end(), ws.begin())}; +} + +ProtoCand HoughGrouping::associateHits(const DTChamber* thechamb, double m, double n) { + if (debug_) + LogDebug("HoughGrouping") << "associateHits"; + LocalPoint tmpLocal, AWireLocal, AWireLocalCh, tmpLocalCh, thepoint; + GlobalPoint tmpGlobal, AWireGlobal; + double tmpx = 0; + double distleft = 0; + double distright = 0; + unsigned short int tmpwire = 0; + unsigned short int abslay = 0; + LATERAL_CASES lat = NONE; + bool isleft = false; + bool isright = false; + + ProtoCand returnPC; + for (auto l = 0; l < NUM_LAYERS_2SL; l++) { + returnPC.isThereHitInLayer_.push_back(false); + returnPC.isThereNeighBourHitInLayer_.push_back(false); + returnPC.xDistToPattern_.push_back(0); + returnPC.dtHits_.push_back(DTPrimitive()); + } + + if (debug_) + LogDebug("HoughGrouping") << "associateHits - Beginning SL loop"; + for (unsigned short int sl = 1; sl < 3 + 1; sl++) { + if (sl == 2) + continue; + if (debug_) + LogDebug("HoughGrouping") << "associateHits - SL: " << sl; + + for (unsigned short int l = 1; l < 4 + 1; l++) { + if (debug_) + LogDebug("HoughGrouping") << "associateHits - L: " << l; + isleft = false; + isright = false; + lat = NONE; + distleft = 0; + distright = 0; + if (sl == 1) + abslay = l - 1; + else + abslay = l + 3; + AWireLocal = LocalPoint(thechamb->superLayer(sl)->layer(l)->specificTopology().wirePosition( + thechamb->superLayer(sl)->layer(l)->specificTopology().firstChannel()), + 0, + 0); + AWireGlobal = thechamb->superLayer(sl)->layer(l)->toGlobal(AWireLocal); + AWireLocalCh = thechamb->toLocal(AWireGlobal); + tmpx = (AWireLocalCh.z() - n) / m; + + if ((tmpx <= xlowlim_) || (tmpx >= xhighlim_)) { + returnPC.dtHits_[abslay] = DTPrimitive(); // empty primitive + continue; + } + + thepoint = LocalPoint(tmpx, 0, AWireLocalCh.z()); + tmpwire = thechamb->superLayer(sl)->layer(l)->specificTopology().channel(thepoint); + if (debug_) + LogDebug("HoughGrouping") << "associateHits - Wire number: " << tmpwire; + if (debug_) + LogDebug("HoughGrouping") << "associateHits - First channel in layer: " + << thechamb->superLayer(sl)->layer(l)->specificTopology().firstChannel(); + if ((digimap_[abslay]).count(tmpwire)) { + // OK, we have a digi, let's choose the laterality, if we can: + tmpLocal = LocalPoint(thechamb->superLayer(sl)->layer(l)->specificTopology().wirePosition(tmpwire), 0, 0); + tmpGlobal = thechamb->superLayer(sl)->layer(l)->toGlobal(tmpLocal); + tmpLocalCh = thechamb->toLocal(tmpGlobal); + + if (abs(tmpLocalCh.x() - thepoint.x()) >= maxDistanceToWire_) { + // The distance where lateralities are not put is 0.03 cm, which is a conservative threshold for the resolution of the cells. + if ((tmpLocalCh.x() - thepoint.x()) > 0) + lat = LEFT; + else + lat = RIGHT; + } + + // Filling info + returnPC.nLayersWithHits_++; + returnPC.isThereHitInLayer_[abslay] = true; + returnPC.isThereNeighBourHitInLayer_[abslay] = true; + if (lat == LEFT) + returnPC.xDistToPattern_[abslay] = abs(tmpx - (tmpLocalCh.x() - 1.05)); + else if (lat == RIGHT) + returnPC.xDistToPattern_[abslay] = abs(tmpx - (tmpLocalCh.x() + 1.05)); + else + returnPC.xDistToPattern_[abslay] = abs(tmpx - tmpLocalCh.x()); + returnPC.dtHits_[abslay] = DTPrimitive(digimap_[abslay][tmpwire]); + returnPC.dtHits_[abslay].setLaterality(lat); + } else { + if (debug_) + LogDebug("HoughGrouping") << "associateHits - No hit in the crossing cell"; + if ((digimap_[abslay]).count(tmpwire - 1)) + isleft = true; + if ((digimap_[abslay]).count(tmpwire + 1)) + isright = true; + if (debug_) + LogDebug("HoughGrouping") << "associateHits - There is in the left: " << (int)isleft; + if (debug_) + LogDebug("HoughGrouping") << "associateHits - There is in the right: " << (int)isright; + + if ((isleft) && (!isright)) { + tmpLocal = LocalPoint(thechamb->superLayer(sl)->layer(l)->specificTopology().wirePosition(tmpwire - 1), 0, 0); + tmpGlobal = thechamb->superLayer(sl)->layer(l)->toGlobal(tmpLocal); + tmpLocalCh = thechamb->toLocal(tmpGlobal); + + // Filling info + returnPC.nLayersWithHits_++; + returnPC.isThereNeighBourHitInLayer_[abslay] = true; + returnPC.xDistToPattern_[abslay] = abs(tmpx - (tmpLocalCh.x() + 1.05)); + returnPC.dtHits_[abslay] = DTPrimitive(digimap_[abslay][tmpwire - 1]); + returnPC.dtHits_[abslay].setLaterality(RIGHT); + + } else if ((!isleft) && (isright)) { + tmpLocal = LocalPoint(thechamb->superLayer(sl)->layer(l)->specificTopology().wirePosition(tmpwire + 1), 0, 0); + tmpGlobal = thechamb->superLayer(sl)->layer(l)->toGlobal(tmpLocal); + tmpLocalCh = thechamb->toLocal(tmpGlobal); + + // Filling info + returnPC.nLayersWithHits_++; + returnPC.isThereNeighBourHitInLayer_[abslay] = true; + returnPC.xDistToPattern_[abslay] = abs(tmpx - (tmpLocalCh.x() - 1.05)); + returnPC.dtHits_[abslay] = DTPrimitive(digimap_[abslay][tmpwire + 1]); + returnPC.dtHits_[abslay].setLaterality(LEFT); + } else if ((isleft) && (isright)) { + LocalPoint tmpLocal_l = + LocalPoint(thechamb->superLayer(sl)->layer(l)->specificTopology().wirePosition(tmpwire - 1), 0, 0); + GlobalPoint tmpGlobal_l = thechamb->superLayer(sl)->layer(l)->toGlobal(tmpLocal_l); + LocalPoint tmpLocalCh_l = thechamb->toLocal(tmpGlobal_l); + + LocalPoint tmpLocal_r = + LocalPoint(thechamb->superLayer(sl)->layer(l)->specificTopology().wirePosition(tmpwire + 1), 0, 0); + GlobalPoint tmpGlobal_r = thechamb->superLayer(sl)->layer(l)->toGlobal(tmpLocal_r); + LocalPoint tmpLocalCh_r = thechamb->toLocal(tmpGlobal_r); + + distleft = std::abs(thepoint.x() - tmpLocalCh_l.x()); + distright = std::abs(thepoint.x() - tmpLocalCh_r.x()); + + // Filling info + returnPC.nLayersWithHits_++; + returnPC.isThereNeighBourHitInLayer_[abslay] = true; + + returnPC.xDistToPattern_[abslay] = abs(tmpx - (tmpLocalCh.x() - 1.05)); + returnPC.dtHits_[abslay] = DTPrimitive(digimap_[abslay][tmpwire + 1]); + returnPC.dtHits_[abslay].setLaterality(LEFT); + + if (distleft < distright) { + returnPC.xDistToPattern_[abslay] = std::abs(tmpx - (tmpLocalCh.x() + 1.05)); + returnPC.dtHits_[abslay] = DTPrimitive(digimap_[abslay][tmpwire - 1]); + returnPC.dtHits_[abslay].setLaterality(RIGHT); + } else { + returnPC.xDistToPattern_[abslay] = std::abs(tmpx - (tmpLocalCh.x() - 1.05)); + returnPC.dtHits_[abslay] = DTPrimitive(digimap_[abslay][tmpwire + 1]); + returnPC.dtHits_[abslay].setLaterality(LEFT); + } + } else { // case where there are no digis + returnPC.dtHits_[abslay] = DTPrimitive(); // empty primitive + } + } + } + } + + setDifferenceBetweenSL(returnPC); + if (debug_) { + LogDebug("HoughGrouping") << "associateHits - Finishing with the candidate. We have found the following of it:"; + LogDebug("HoughGrouping") << "associateHits - # of layers with hits: " << returnPC.nLayersWithHits_; + for (unsigned short int lay = 0; lay < 8; lay++) { + LogDebug("HoughGrouping") << "associateHits - For absolute layer: " << lay; + LogDebug("HoughGrouping") << "associateHits - # of HQ hits: " << returnPC.isThereHitInLayer_[lay]; + LogDebug("HoughGrouping") << "associateHits - # of LQ hits: " << returnPC.isThereNeighBourHitInLayer_[lay]; + } + LogDebug("HoughGrouping") << "associateHits - Abs. diff. between SL1 and SL3 hits: " << returnPC.nHitsDiff_; + for (unsigned short int lay = 0; lay < 8; lay++) { + LogDebug("HoughGrouping") << "associateHits - For absolute layer: " << lay; + LogDebug("HoughGrouping") << "associateHits - Abs. distance to digi: " << returnPC.xDistToPattern_[lay]; + } + } + return returnPC; +} + +void HoughGrouping::setDifferenceBetweenSL(ProtoCand& tupl) { + if (debug_) + LogDebug("HoughGrouping") << "setDifferenceBetweenSL"; + short int absres = 0; + for (unsigned short int lay = 0; lay < 8; lay++) { + if (tupl.dtHits_[lay].channelId() > 0) { + if (lay <= 3) + absres++; + else + absres--; + } + } + + if (absres >= 0) + tupl.nHitsDiff_ = absres; + else + tupl.nHitsDiff_ = (unsigned short int)(-absres); +} + +void HoughGrouping::orderAndFilter(std::vector& invector, MuonPathPtrs& outMuonPath) { + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter"; + // 0: # of layers with hits. + // 1: # of hits of high quality (the expected line crosses the cell). + // 2: # of hits of low quality (the expected line is in a neighbouring cell). + // 3: absolute diff. between the number of hits in SL1 and SL3. + // 4: absolute distance to all hits of the segment. + // 5: DTPrimitive of the candidate. + + std::vector elstoremove; + // ordering: + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter - First ordering"; + std::sort(invector.begin(), invector.end(), HoughOrdering); + + // Now filtering: + unsigned short int ind = 0; + bool filtered = false; + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter - Entering while"; + while (!filtered) { + if (debug_) + LogDebug("HoughGrouping") << "\nHoughGrouping::orderAndFilter - New iteration with ind: " << ind; + elstoremove.clear(); + for (unsigned short int i = ind + 1; i < invector.size(); i++) { + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter - Checking index: " << i; + for (unsigned short int lay = 0; lay < 8; lay++) { + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter - Checking layer number: " << lay; + if (invector.at(i).dtHits_[lay].channelId() == invector.at(ind).dtHits_[lay].channelId() && + invector.at(ind).dtHits_[lay].channelId() != -1) { + invector.at(i).nLayersWithHits_--; + invector.at(i).isThereHitInLayer_[lay] = false; + invector.at(i).isThereNeighBourHitInLayer_[lay] = false; + setDifferenceBetweenSL(invector.at(i)); + // We check that if its a different laterality, the best candidate of the two of them changes its laterality to not-known (that is, both). + if (invector.at(i).dtHits_[lay].laterality() != invector.at(ind).dtHits_[lay].laterality()) + invector.at(ind).dtHits_[lay].setLaterality(NONE); + + invector.at(i).dtHits_[lay] = DTPrimitive(); + } + } + if (debug_) + LogDebug("HoughGrouping") + << "orderAndFilter - Finished checking all the layers, now seeing if we should remove the " + "candidate"; + + if (!areThereEnoughHits(invector.at(i))) { + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter - This candidate shall be removed!"; + elstoremove.push_back((unsigned short int)i); + } + } + + if (debug_) + LogDebug("HoughGrouping") << "orderAndFilter - We are gonna erase " << elstoremove.size() << " elements"; + + for (short int el = (elstoremove.size() - 1); el > -1; el--) { + invector.erase(invector.begin() + elstoremove.at(el)); + } + + if (ind + 1 == (unsigned short int)invector.size()) + filtered = true; + else + std::sort(invector.begin() + ind + 1, invector.end(), HoughOrdering); + ind++; + } + + // Ultimate filter: if the remaining do not fill the requirements (configurable through pset arguments), they are removed also. + for (short int el = (invector.size() - 1); el > -1; el--) { + if (!areThereEnoughHits(invector.at(el))) { + invector.erase(invector.begin() + el); + } + } + + if (invector.empty()) { + if (debug_) + LogDebug("HoughGrouping") << "OrderAndFilter - We do not have candidates with the minimum hits required."; + return; + } else if (debug_) + LogDebug("HoughGrouping") << "OrderAndFilter - At the end, we have only " << invector.size() << " good paths!"; + + // Packing dt primitives + for (unsigned short int i = 0; i < invector.size(); i++) { + DTPrimitivePtrs ptrPrimitive; + unsigned short int tmplowfill = 0; + unsigned short int tmpupfill = 0; + for (unsigned short int lay = 0; lay < 8; lay++) { + auto dtAux = std::make_shared(invector.at(i).dtHits_[lay]); + ptrPrimitive.push_back(std::move(dtAux)); + if (debug_) { + LogDebug("HoughGrouping") << "\nHoughGrouping::OrderAndFilter - cameraid: " << ptrPrimitive[lay]->cameraId(); + LogDebug("HoughGrouping") << "OrderAndFilter - channelid (GOOD): " << ptrPrimitive[lay]->channelId(); + LogDebug("HoughGrouping") << "OrderAndFilter - channelid (AM): " << ptrPrimitive[lay]->channelId() - 1; + } + // Fixing channel ID to AM conventions... + if (ptrPrimitive[lay]->channelId() != -1) + ptrPrimitive[lay]->setChannelId(ptrPrimitive[lay]->channelId() - 1); + + if (ptrPrimitive[lay]->cameraId() > 0) { + if (lay < 4) + tmplowfill++; + else + tmpupfill++; + } + } + + auto ptrMuonPath = std::make_shared(ptrPrimitive, tmplowfill, tmpupfill); + outMuonPath.push_back(ptrMuonPath); + if (debug_) { + for (unsigned short int lay = 0; lay < 8; lay++) { + LogDebug("HoughGrouping") << "OrderAndFilter - Final cameraID: " + << outMuonPath.back()->primitive(lay)->cameraId(); + LogDebug("HoughGrouping") << "OrderAndFilter - Final channelID: " + << outMuonPath.back()->primitive(lay)->channelId(); + LogDebug("HoughGrouping") << "OrderAndFilter - Final time: " + << outMuonPath.back()->primitive(lay)->tdcTimeStamp(); + } + } + } + return; +} + +bool HoughGrouping::areThereEnoughHits(const ProtoCand& tupl) { + if (debug_) + LogDebug("HoughGrouping") << "areThereEnoughHits"; + unsigned short int numhitssl1 = 0; + unsigned short int numhitssl3 = 0; + for (unsigned short int lay = 0; lay < 8; lay++) { + if ((tupl.dtHits_[lay].channelId() > 0) && (lay < 4)) + numhitssl1++; + else if (tupl.dtHits_[lay].channelId() > 0) + numhitssl3++; + } + + if (debug_) + LogDebug("HoughGrouping") << "areThereEnoughHits - Hits in SL1: " << numhitssl1; + if (debug_) + LogDebug("HoughGrouping") << "areThereEnoughHits - Hits in SL3: " << numhitssl3; + + if ((numhitssl1 != 0) && (numhitssl3 != 0)) { // Correlated candidates + if ((numhitssl1 + numhitssl3) >= minNLayerHits_) { + if (numhitssl1 > numhitssl3) { + return ((numhitssl1 >= minSingleSLHitsMax_) && (numhitssl3 >= minSingleSLHitsMin_)); + } else if (numhitssl3 > numhitssl1) { + return ((numhitssl3 >= minSingleSLHitsMax_) && (numhitssl1 >= minSingleSLHitsMin_)); + } else + return true; + } + } else if (allowUncorrelatedPatterns_) { // Uncorrelated candidates + return ((numhitssl1 + numhitssl3) >= minNLayerHits_); + } + return false; +} diff --git a/L1Trigger/DTTriggerPhase2/src/InitialGrouping.cc b/L1Trigger/DTTriggerPhase2/src/InitialGrouping.cc new file mode 100644 index 0000000000000..9f45dde0550dc --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/InitialGrouping.cc @@ -0,0 +1,349 @@ +#include + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "L1Trigger/DTTriggerPhase2/interface/InitialGrouping.h" + +using namespace edm; +using namespace std; +using namespace cmsdt; +using namespace dtamgrouping; +// ============================================================================ +// Constructors and destructor +// ============================================================================ +InitialGrouping::InitialGrouping(const ParameterSet &pset, edm::ConsumesCollector &iC) + : MotherGrouping(pset, iC), currentBaseChannel_(-1) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); + if (debug_) + LogDebug("InitialGrouping") << "InitialGrouping: constructor"; + + // Initialisation of channelIn array + chInDummy_.push_back(DTPrimitive()); + for (int lay = 0; lay < NUM_LAYERS; lay++) { + for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) { + channelIn_[lay][ch] = {chInDummy_}; + channelIn_[lay][ch].clear(); + } + } +} + +InitialGrouping::~InitialGrouping() { + if (debug_) + LogDebug("InitialGrouping") << "InitialGrouping: destructor"; +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void InitialGrouping::initialise(const edm::EventSetup &iEventSetup) { + if (debug_) + LogDebug("InitialGrouping") << "InitialGrouping::initialiase"; +} + +void InitialGrouping::run(Event &iEvent, + const EventSetup &iEventSetup, + const DTDigiCollection &digis, + MuonPathPtrs &mpaths) { + // This function returns the analyzable mpath collection back to the the main function + // so it can be fitted. This is in fact doing the so-called grouping. + + for (int supLayer = 0; supLayer < NUM_SUPERLAYERS; supLayer++) { // for each SL: + if (debug_) + LogDebug("InitialGrouping") << "InitialGrouping::run Reading SL" << supLayer; + setInChannels(&digis, supLayer); + + for (int baseCh = 0; baseCh < TOTAL_BTI; baseCh++) { + currentBaseChannel_ = baseCh; + selectInChannels(currentBaseChannel_); //map a number of wires for a given base channel + if (notEnoughDataInChannels()) + continue; + + if (debug_) + LogDebug("InitialGrouping") << "InitialGrouping::run --> now check pathId"; + for (int pathId = 0; pathId < 8; pathId++) { + resetPrvTDCTStamp(); + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::run] mixChannels calling"; + mixChannels(supLayer, pathId, mpaths); + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::run] mixChannels end"; + } + } + } + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::run] end"; +} + +void InitialGrouping::finish() { return; }; + +// ============================================================================ +// Other methods +// ============================================================================ +void InitialGrouping::setInChannels(const DTDigiCollection *digis, int sl) { + // before setting channels we need to clear + for (int lay = 0; lay < NUM_LAYERS; lay++) { + for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) { + channelIn_[lay][ch].clear(); + } + } + + // now fill with those primitives that makes sense: + for (const auto &dtLayerId_It : *digis) { + const DTLayerId dtLId = dtLayerId_It.first; + if (dtLId.superlayer() != sl + 1) + continue; //skip digis not in SL... + + for (DTDigiCollection::const_iterator digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second; + ++digiIt) { + int layer = dtLId.layer() - 1; + int wire = (*digiIt).wire() - 1; + int digiTIME = (*digiIt).time(); + int digiTIMEPhase2 = digiTIME; + + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::setInChannels] SL" << sl << " L" << layer << " : " << wire + << " " << digiTIMEPhase2; + auto dtpAux = DTPrimitive(); + dtpAux.setTDCTimeStamp(digiTIMEPhase2); + dtpAux.setChannelId(wire); + dtpAux.setLayerId(layer); // L=0,1,2,3 + dtpAux.setSuperLayerId(sl); // SL=0,1,2 + dtpAux.setCameraId(dtLId.rawId()); + channelIn_[layer][wire].push_back(dtpAux); + } + } +} + +void InitialGrouping::selectInChannels(int baseChannel) { + // Channels are labeled following next schema: + // Input Muxer Indexes + // --------------------------------- + // | 6 | 7 | 8 | 9 | + // --------------------------------- + // | 3 | 4 | 5 | + // ------------------------- + // | 1 | 2 | + // ----------------- + // | 0 | + // --------- + + // ****** LAYER 0 ****** + muxInChannels_[0] = channelIn_[0][baseChannel]; + + // ****** LAYER 1 ****** + muxInChannels_[1] = channelIn_[1][baseChannel]; + + if (baseChannel + 1 < NUM_CH_PER_LAYER) + muxInChannels_[2] = channelIn_[1][baseChannel + 1]; + else + muxInChannels_[2] = chInDummy_; + + // ****** LAYER 2 ****** + if (baseChannel - 1 >= 0) + muxInChannels_[3] = channelIn_[2][baseChannel - 1]; + else + muxInChannels_[3] = chInDummy_; + + muxInChannels_[4] = channelIn_[2][baseChannel]; + + if (baseChannel + 1 < NUM_CH_PER_LAYER) + muxInChannels_[5] = channelIn_[2][baseChannel + 1]; + else + muxInChannels_[5] = chInDummy_; + + // ****** LAYER 3 ****** + if (baseChannel - 1 >= 0) + muxInChannels_[6] = channelIn_[3][baseChannel - 1]; + else + muxInChannels_[6] = chInDummy_; + + muxInChannels_[7] = channelIn_[3][baseChannel]; + + if (baseChannel + 1 < NUM_CH_PER_LAYER) + muxInChannels_[8] = channelIn_[3][baseChannel + 1]; + else + muxInChannels_[8] = chInDummy_; + + if (baseChannel + 2 < NUM_CH_PER_LAYER) + muxInChannels_[9] = channelIn_[3][baseChannel + 2]; + else + muxInChannels_[9] = chInDummy_; +} + +bool InitialGrouping::notEnoughDataInChannels(void) { + // Empty layer indicators + bool lEmpty[4]; + + lEmpty[0] = muxInChannels_[0].empty(); + + lEmpty[1] = muxInChannels_[1].empty() && muxInChannels_[2].empty(); + + lEmpty[2] = muxInChannels_[3].empty() && muxInChannels_[4].empty() && muxInChannels_[5].empty(); + + lEmpty[3] = + muxInChannels_[6].empty() && muxInChannels_[7].empty() && muxInChannels_[8].empty() && muxInChannels_[9].empty(); + + // If there are at least two empty layers, you cannot link it to a possible trace + if ((lEmpty[0] && lEmpty[1]) or (lEmpty[0] && lEmpty[2]) or (lEmpty[0] && lEmpty[3]) or (lEmpty[1] && lEmpty[2]) or + (lEmpty[1] && lEmpty[3]) or (lEmpty[2] && lEmpty[3])) { + return true; + } else { + return false; + } +} + +void InitialGrouping::resetPrvTDCTStamp(void) { + for (int i = 0; i < NUM_LAYERS; i++) + prevTDCTimeStamps_[i] = -1; +} + +bool InitialGrouping::isEqualComb2Previous(DTPrimitives &dtPrims) { + bool answer = true; + + for (int i = 0; i < NUM_LAYERS; i++) { + if (prevTDCTimeStamps_[i] != dtPrims[i].tdcTimeStamp()) { + answer = false; + for (int j = 0; j < NUM_LAYERS; j++) { + prevTDCTimeStamps_[j] = dtPrims[j].tdcTimeStamp(); + } + break; + } + } + return answer; +} + +void InitialGrouping::mixChannels(int supLayer, int pathId, MuonPathPtrs &outMuonPath) { + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::mixChannel] begin"; + DTPrimitives data[4]; + + // Real amount of values extracted from each channel. + int numPrimsPerLayer[4] = {0, 0, 0, 0}; + unsigned int canal; + int channelEmptyCnt = 0; + for (int layer = 0; layer <= 3; layer++) { + canal = CHANNELS_PATH_ARRANGEMENTS[pathId][layer]; + if (muxInChannels_[canal].empty()) + channelEmptyCnt++; + } + + if (channelEmptyCnt >= 2) + return; + // + + // We extract the number of elements necesary from each channel as the combination requires + for (int layer = 0; layer < NUM_LAYERS; layer++) { + canal = CHANNELS_PATH_ARRANGEMENTS[pathId][layer]; + unsigned int maxPrimsToBeRetrieved = muxInChannels_[canal].size(); + /* + If the number of primitives is zero, in order to avoid that only one + empty channel avoids mixing data from the other three, we, at least, + consider one dummy element from this channel. + In other cases, where two or more channels has zero elements, the final + combination will be not analyzable (the condition for being analyzable is + that it has at least three good TDC time values, not dummy), so it will + be discarded and not sent to the analyzer. + */ + if (maxPrimsToBeRetrieved == 0) + maxPrimsToBeRetrieved = 1; + + for (unsigned int items = 0; items < maxPrimsToBeRetrieved; items++) { + auto dtpAux = DTPrimitive(); + if (!muxInChannels_[canal].empty()) + dtpAux = DTPrimitive(&(muxInChannels_[canal].at(items))); + + /* + I won't allow a whole loop cycle. When a DTPrimitive has an invalid + time-stamp (TDC value = -1) it means that the buffer is empty or the + buffer has reached the last element within the configurable time window. + In this case the loop is broken, but only if there is, at least, one + DTPrim (even invalid) on the outgoing array. This is mandatory to cope + with the idea explained in the previous comment block + */ + if (dtpAux.tdcTimeStamp() < 0 && items > 0) + break; + + // In this new schema, if the hit corresponds with the SL over which + // you are doing the mixings, it is sent to the intermediate mixing + // buffer. In the opposite case, a blank and invalid copy is sent to + // allow them mixing to be complete, as it was done in the one SL case. + + // This is a kind of quick solution in which there will be no few cases + // where you will have invalid mixings. Because of that, the verification + // that is done later, where the segment is analysed to check whether it + // can be analysed is essential. + if (dtpAux.superLayerId() == supLayer) + data[layer].push_back(dtpAux); // values are 0, 1, 2 + else + data[layer].push_back(DTPrimitive()); + numPrimsPerLayer[layer]++; + } + } + + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] filled data"; + + // Here we do the different combinations and send them to the output FIFO. + DTPrimitives ptrPrimitive; + int chIdx[4]; + for (chIdx[0] = 0; chIdx[0] < numPrimsPerLayer[0]; chIdx[0]++) { + for (chIdx[1] = 0; chIdx[1] < numPrimsPerLayer[1]; chIdx[1]++) { + for (chIdx[2] = 0; chIdx[2] < numPrimsPerLayer[2]; chIdx[2]++) { + for (chIdx[3] = 0; chIdx[3] < numPrimsPerLayer[3]; chIdx[3]++) { + // We build a copy of the object so that we can manipulate each one + // in each thread of the process independently, allowing us also to + // delete them whenever it is necessary, without relying upon a + // unique reference all over the code. + + for (int i = 0; i < NUM_LAYERS; i++) { + ptrPrimitive.push_back((data[i])[chIdx[i]]); + if (debug_) + LogDebug("InitialGrouping") + << "[InitialGrouping::mixChannels] reading " << ptrPrimitive[i].tdcTimeStamp(); + } + + auto ptrMuonPath = std::make_shared(ptrPrimitive); + ptrMuonPath->setCellHorizontalLayout(CELL_HORIZONTAL_LAYOUTS[pathId]); + + /* + This new version of this code is redundant with PathAnalyzer code, + where every MuonPath not analyzable is discarded. + I insert this discarding mechanism here, as well, to avoid inserting + not-analyzable MuonPath into the candidate FIFO. + Equivalent code must be removed in the future from PathAnalyzer, but + it the mean time, at least during the testing state, I'll preserve + both. + Code in the PathAnalyzer should be doing nothing now. + */ + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] muonPath is analyzable? " << ptrMuonPath; + if (ptrMuonPath->isAnalyzable()) { + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] YES"; + /* + This is a very simple filter because, during the tests, it has been + detected that many consecutive MuonPaths are duplicated mainly due + to buffers empty (or dummy) that give a TDC time-stamp = -1 + With this filter, I'm removing those consecutive identical + combinations. + + If duplicated combinations are not consecutive, they won't be + detected here + */ + if (!isEqualComb2Previous(ptrPrimitive)) { + if (debug_) + LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] isNOT equal to previous"; + ptrMuonPath->setBaseChannelId(currentBaseChannel_); + outMuonPath.push_back(std::move(ptrMuonPath)); + } + ptrPrimitive.clear(); + } + } + } + } + } + for (int layer = 0; layer < NUM_LAYERS; layer++) { + data[layer].clear(); + } +} diff --git a/L1Trigger/DTTriggerPhase2/src/MPFilter.cc b/L1Trigger/DTTriggerPhase2/src/MPFilter.cc new file mode 100644 index 0000000000000..8cae5a7884a88 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MPFilter.cc @@ -0,0 +1,14 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" + +using namespace edm; +using namespace std; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MPFilter::MPFilter(const ParameterSet& pset) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); +} + +MPFilter::~MPFilter() {} diff --git a/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc b/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc new file mode 100644 index 0000000000000..4ce76b41c6042 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc @@ -0,0 +1,237 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace edm; +using namespace std; +using namespace cmsdt; +; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MPQualityEnhancerFilter::MPQualityEnhancerFilter(const ParameterSet &pset) : MPFilter(pset) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); + filter_cousins_ = pset.getUntrackedParameter("filter_cousins"); +} + +MPQualityEnhancerFilter::~MPQualityEnhancerFilter() {} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MPQualityEnhancerFilter::initialise(const edm::EventSetup &iEventSetup) {} + +void MPQualityEnhancerFilter::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + std::vector &inMPaths, + std::vector &outMPaths) { + std::vector buff; + std::vector buff2; + + filterCousins(inMPaths, buff); + if (debug_) { + LogDebug("MPQualityEnhancerFilter") << "Ended Cousins Filter. The final primitives before Refiltering are: "; + for (unsigned int i = 0; i < buff.size(); i++) { + printmP(buff[i]); + } + LogDebug("MPQualityEnhancerFilter") << "Total Primitives = " << buff.size(); + } + refilteringCousins(buff, buff2); + if (debug_) { + LogDebug("MPQualityEnhancerFilter") << "Ended Cousins Refilter. The final primitives before UniqueFilter are: "; + for (unsigned int i = 0; i < buff2.size(); i++) { + printmP(buff2[i]); + } + LogDebug("MPQualityEnhancerFilter") << "Total Primitives = " << buff2.size(); + } + filterUnique(buff2, outMPaths); + + if (debug_) { + LogDebug("MPQualityEnhancerFilter") << "Ended Unique Filter. The final primitives are: "; + for (unsigned int i = 0; i < outMPaths.size(); i++) { + printmP(outMPaths[i]); + LogDebug("MPQualityEnhancerFilter"); + } + LogDebug("MPQualityEnhancerFilter") << "Total Primitives = " << outMPaths.size(); + } + + buff.clear(); + buff2.clear(); +} + +void MPQualityEnhancerFilter::finish(){}; + +/////////////////////////// +/// OTHER METHODS +int MPQualityEnhancerFilter::areCousins(metaPrimitive mp, metaPrimitive second_mp) { + if (mp.rawId != second_mp.rawId) + return 0; + if (mp.wi1 == second_mp.wi1 and mp.wi1 != -1 and mp.tdc1 != -1) + return 1; + if (mp.wi2 == second_mp.wi2 and mp.wi2 != -1 and mp.tdc2 != -1) + return 2; + if (mp.wi3 == second_mp.wi3 and mp.wi3 != -1 and mp.tdc3 != -1) + return 3; + if (mp.wi4 == second_mp.wi4 and mp.wi4 != -1 and mp.tdc4 != -1) + return 4; + return 0; +} + +int MPQualityEnhancerFilter::rango(metaPrimitive mp) { + if (mp.quality == 1 or mp.quality == 2) + return 3; + if (mp.quality == 3 or mp.quality == 4) + return 4; + return 0; +} + +void MPQualityEnhancerFilter::filterCousins(std::vector &inMPaths, + std::vector &outMPaths) { + int primo_index = 0; + bool oneof4 = false; + int bestI = -1; + double bestChi2 = 9999; + if (inMPaths.size() == 1) { + if (debug_) { + printmP(inMPaths[0]); + } + outMPaths.push_back(inMPaths[0]); + } else if (inMPaths.size() > 1) { + for (int i = 0; i < int(inMPaths.size()); i++) { + if (debug_) { + printmP(inMPaths[i]); + } + if (areCousins(inMPaths[i], inMPaths[i - primo_index]) == 0) { + if (oneof4) { + outMPaths.push_back(inMPaths[bestI]); + + bestI = -1; + bestChi2 = 9999; + oneof4 = false; + } else { + for (int j = i - primo_index; j < i; j++) { + outMPaths.push_back(inMPaths[j]); + } + } + i--; + primo_index = 0; + continue; + } + if (rango(inMPaths[i]) == 4) { + oneof4 = true; + if (bestChi2 > inMPaths[i].chi2) { + bestChi2 = inMPaths[i].chi2; + bestI = i; + } + } + if (areCousins(inMPaths[i], inMPaths[i + 1]) != 0) { + primo_index++; + } else { //areCousing==0 + if (oneof4) { + outMPaths.push_back(inMPaths[bestI]); + bestI = -1; + bestChi2 = 9999; + oneof4 = false; + } else { + for (int j = i - primo_index; j <= i; j++) { + outMPaths.push_back(inMPaths[j]); + } + } + primo_index = 0; + } + } + } + +} //End filterCousins + +void MPQualityEnhancerFilter::refilteringCousins(std::vector &inMPaths, + std::vector &outMPaths) { + if (debug_) + std::cout << "filtering: starting cousins refiltering" << std::endl; + int bestI = -1; + double bestChi2 = 9999; + bool oneOf4 = false; + int back = 0; + + if (inMPaths.size() > 1) { + for (unsigned int i = 0; i < inMPaths.size(); i++) { + if (debug_) { + LogDebug("MPQualityEnhancerFilter") << "filtering: starting with mp " << i << ": "; + printmP(inMPaths[i]); + LogDebug("MPQualityEnhancerFilter"); + } + if (rango(inMPaths[i]) == 4 && bestChi2 > inMPaths[i].chi2) { // 4h prim with a smaller chi2 + if (debug_) { + LogDebug("MPQualityEnhancerFilter") << "filtering: mp " << i << " is the best 4h primitive"; + } + oneOf4 = true; + bestI = i; + bestChi2 = inMPaths[i].chi2; + } + if (i == inMPaths.size() - 1) { //You can't compare the last one with the next one + if (oneOf4) { + outMPaths.push_back(inMPaths[bestI]); + } else { + for (unsigned int j = i - back; j <= i; j++) { + outMPaths.push_back(inMPaths[j]); + } + } + } else { + if (areCousins(inMPaths[i], inMPaths[i + 1]) == 0) { //they arent cousins + if (debug_) { + LogDebug("MPQualityEnhancerFilter") << "mp " << i << " and mp " << i + 1 << " are not cousins"; + } + if (oneOf4) { + outMPaths.push_back(inMPaths[bestI]); + if (debug_) + LogDebug("MPQualityEnhancerFilter") << "kept4 mp " << bestI; + oneOf4 = false; //reset 4h variables + bestI = -1; + bestChi2 = 9999; + } else { + for (unsigned int j = i - back; j <= i; j++) { + outMPaths.push_back(inMPaths[j]); + if (debug_) + LogDebug("MPQualityEnhancerFilter") << "kept3 mp " << j; + } + } + back = 0; + } else { // they are cousins + back++; + } + } + } + } else if (inMPaths.size() == 1) { + outMPaths.push_back(inMPaths[0]); + } +} + +void MPQualityEnhancerFilter::filterUnique(std::vector &inMPaths, + std::vector &outMPaths) { + constexpr double xTh = 0.001; + constexpr double tPhiTh = 0.001; + constexpr double t0Th = 0.001; + for (size_t i = 0; i < inMPaths.size(); i++) { + bool visto = false; + for (size_t j = i + 1; j < inMPaths.size(); j++) { + if ((std::abs(inMPaths[i].x - inMPaths[j].x) <= xTh) && + (std::abs(inMPaths[i].tanPhi - inMPaths[j].tanPhi) <= tPhiTh) && + (std::abs(inMPaths[i].t0 - inMPaths[j].t0) <= t0Th)) + visto = true; + } + if (!visto) + outMPaths.push_back(inMPaths[i]); + } +} + +void MPQualityEnhancerFilter::printmP(metaPrimitive mP) { + DTSuperLayerId slId(mP.rawId); + LogDebug("MPQualityEnhancerFilter") << slId << "\t" + << " " << setw(2) << left << mP.wi1 << " " << setw(2) << left << mP.wi2 << " " + << setw(2) << left << mP.wi3 << " " << setw(2) << left << mP.wi4 << " " << setw(5) + << left << mP.tdc1 << " " << setw(5) << left << mP.tdc2 << " " << setw(5) << left + << mP.tdc3 << " " << setw(5) << left << mP.tdc4 << " " << setw(10) << right + << mP.x << " " << setw(9) << left << mP.tanPhi << " " << setw(5) << left << mP.t0 + << " " << setw(13) << left << mP.chi2 << " r:" << rango(mP); +} diff --git a/L1Trigger/DTTriggerPhase2/src/MPRedundantFilter.cc b/L1Trigger/DTTriggerPhase2/src/MPRedundantFilter.cc new file mode 100644 index 0000000000000..5fde33e50630e --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MPRedundantFilter.cc @@ -0,0 +1,62 @@ +#include +#include "L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h" + +using namespace edm; +using namespace std; +using namespace cmsdt; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MPRedundantFilter::MPRedundantFilter(const ParameterSet& pset) : MPFilter(pset), maxBufferSize_(8) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); +} + +MPRedundantFilter::~MPRedundantFilter() {} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MPRedundantFilter::initialise(const edm::EventSetup& iEventSetup) { buffer_.clear(); } + +void MPRedundantFilter::run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + MuonPathPtrs& inMPaths, + MuonPathPtrs& outMPaths) { + buffer_.clear(); + for (auto muonpath = inMPaths.begin(); muonpath != inMPaths.end(); ++muonpath) { + filter(*muonpath, outMPaths); + } + buffer_.clear(); +} + +void MPRedundantFilter::filter(MuonPathPtr& mPath, MuonPathPtrs& outMPaths) { + if (mPath == nullptr) + return; + + if (!isInBuffer(mPath)) { + // Remove the first element (the oldest) + if (buffer_.size() == maxBufferSize_) + buffer_.pop_front(); + // Insert last path as new element + buffer_.push_back(mPath); + + // Send a copy + auto mpAux = std::make_shared(mPath); + outMPaths.push_back(mpAux); + } +} + +bool MPRedundantFilter::isInBuffer(MuonPathPtr& mPath) { + bool ans = false; + + if (!buffer_.empty()) { + for (unsigned int i = 0; i < buffer_.size(); i++) + if (mPath->isEqualTo((MuonPath*)buffer_.at(i).get())) { + ans = true; + break; + } + } + return ans; +} diff --git a/L1Trigger/DTTriggerPhase2/src/MotherGrouping.cc b/L1Trigger/DTTriggerPhase2/src/MotherGrouping.cc new file mode 100644 index 0000000000000..9eba4d08be667 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MotherGrouping.cc @@ -0,0 +1,27 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +using namespace edm; +using namespace std; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MotherGrouping::MotherGrouping(const ParameterSet& pset, edm::ConsumesCollector& iC) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); +} + +MotherGrouping::~MotherGrouping() {} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MotherGrouping::initialise(const edm::EventSetup& iEventSetup) {} + +void MotherGrouping::run(Event& iEvent, + const EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& mpaths) {} + +void MotherGrouping::finish(){}; diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPath.cc b/L1Trigger/DTTriggerPhase2/src/MuonPath.cc new file mode 100644 index 0000000000000..77939e1c51913 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MuonPath.cc @@ -0,0 +1,204 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MuonPath.h" + +#include +#include +#include + +using namespace cmsdt; + +MuonPath::MuonPath() { + quality_ = NOPATH; + baseChannelId_ = -1; + + for (int i = 0; i < NUM_LAYERS_2SL; i++) { + prim_.push_back(std::make_shared()); + } + + nprimitives_ = NUM_LAYERS; + bxTimeValue_ = -1; + bxNumId_ = -1; + tanPhi_ = 0; + horizPos_ = 0; + chiSquare_ = 0; + for (int i = 0; i < NUM_LAYERS; i++) { + lateralComb_[i] = LEFT; + setXCoorCell(0, i); + setDriftDistance(0, i); + } +} + +MuonPath::MuonPath(DTPrimitivePtrs &ptrPrimitive, int nprimUp, int nprimDown) { + if (nprimUp > 0 && nprimDown > 0) + nprimitives_ = NUM_LAYERS_2SL; //Instead of nprimUp + nprimDown; + else { + nprimitives_ = NUM_LAYERS; + } + nprimitivesUp_ = nprimUp; + nprimitivesDown_ = nprimDown; + rawId_ = 0; + quality_ = NOPATH; + baseChannelId_ = -1; + bxTimeValue_ = -1; + bxNumId_ = -1; + tanPhi_ = 0; + horizPos_ = 0; + chiSquare_ = 0; + phi_ = 0; + phiB_ = 0; + + for (short i = 0; i < nprimitives_; i++) { + lateralComb_[i] = LEFT; + prim_.push_back(std::make_shared(ptrPrimitive[i])); + + setXCoorCell(0, i); + setDriftDistance(0, i); + setXWirePos(0, i); + setZWirePos(0, i); + setTWireTDC(0, i); + } +} + +MuonPath::MuonPath(DTPrimitives &ptrPrimitive, int nprimUp, int nprimDown) { + if (nprimUp > 0 && nprimDown > 0) + nprimitives_ = NUM_LAYERS_2SL; //Instead of nprimUp + nprimDown; + else { + nprimitives_ = NUM_LAYERS; + } + nprimitivesUp_ = nprimUp; + nprimitivesDown_ = nprimDown; + rawId_ = 0; + quality_ = NOPATH; + baseChannelId_ = -1; + bxTimeValue_ = -1; + bxNumId_ = -1; + tanPhi_ = 0; + horizPos_ = 0; + chiSquare_ = 0; + phi_ = 0; + phiB_ = 0; + + for (short i = 0; i < nprimitives_; i++) { + lateralComb_[i] = LEFT; + prim_.push_back(std::make_shared(ptrPrimitive[i])); + + setXCoorCell(0, i); + setDriftDistance(0, i); + setXWirePos(0, i); + setZWirePos(0, i); + setTWireTDC(0, i); + } +} + +MuonPath::MuonPath(MuonPathPtr &ptr) { + setRawId(ptr->rawId()); + setPhi(ptr->phi()); + setPhiB(ptr->phiB()); + setQuality(ptr->quality()); + setBaseChannelId(ptr->baseChannelId()); + setCellHorizontalLayout(ptr->cellLayout()); + setNPrimitives(ptr->nprimitives()); + + setLateralComb(ptr->lateralComb()); + setBxTimeValue(ptr->bxTimeValue()); + setTanPhi(ptr->tanPhi()); + setHorizPos(ptr->horizPos()); + setChiSquare(ptr->chiSquare()); + + for (int i = 0; i < ptr->nprimitives(); i++) { + prim_.push_back(ptr->primitive(i)); + + setXCoorCell(ptr->xCoorCell(i), i); + setDriftDistance(ptr->xDriftDistance(i), i); + setXWirePos(ptr->xWirePos(i), i); + setZWirePos(ptr->zWirePos(i), i); + setTWireTDC(ptr->tWireTDC(i), i); + } +} + +//------------------------------------------------------------------ +//--- Public +//------------------------------------------------------------------ +void MuonPath::setPrimitive(DTPrimitivePtr &ptr, int layer) { + if (ptr == nullptr) + std::cout << "NULL 'Primitive'." << std::endl; + prim_[layer] = std::move(ptr); +} + +void MuonPath::setCellHorizontalLayout(int layout[4]) { + for (int i = 0; i < NUM_LAYERS; i++) + cellLayout_[i] = layout[i]; +} + +void MuonPath::setCellHorizontalLayout(const int *layout) { + for (int i = 0; i < NUM_LAYERS; i++) + cellLayout_[i] = layout[i]; +} + +bool MuonPath::isEqualTo(MuonPath *ptr) { + for (int i = 0; i < ptr->nprimitives(); i++) { + if (this->primitive(i)->isValidTime() && ptr->primitive(i)->isValidTime()) { + if (ptr->primitive(i)->superLayerId() != this->primitive(i)->superLayerId() || + + ptr->primitive(i)->channelId() != this->primitive(i)->channelId() || + + ptr->primitive(i)->tdcTimeStamp() != this->primitive(i)->tdcTimeStamp() || + + ptr->primitive(i)->orbit() != this->primitive(i)->orbit() || + (ptr->lateralComb())[i] != (this->lateralComb())[i]) + return false; + } else { + if (!this->primitive(i)->isValidTime() && !ptr->primitive(i)->isValidTime()) + continue; + + else + return false; + } + } + + return true; +} + +bool MuonPath::isAnalyzable() { + short countValidHits = 0; + for (int i = 0; i < this->nprimitives(); i++) { + // if (!this->primitive(i)) + // continue; + if (this->primitive(i)->isValidTime()) + countValidHits++; + } + + if (countValidHits >= 3) + return true; + return false; +} + +bool MuonPath::completeMP() { + return (prim_[0]->isValidTime() && prim_[1]->isValidTime() && prim_[2]->isValidTime() && prim_[3]->isValidTime()); +} + +void MuonPath::setBxTimeValue(int time) { + bxTimeValue_ = time; + + float auxBxId = float(time) / LHC_CLK_FREQ; + bxNumId_ = int(auxBxId); + if ((auxBxId - int(auxBxId)) >= 0.5) + bxNumId_ = int(bxNumId_ + 1); +} + +void MuonPath::setLateralCombFromPrimitives() { + for (int i = 0; i < nprimitives_; i++) { + if (!this->primitive(i)->isValidTime()) + continue; + lateralComb_[i] = this->primitive(i)->laterality(); + } +} + +void MuonPath::setLateralComb(LATERAL_CASES latComb[4]) { + for (int i = 0; i < NUM_LAYERS; i++) + lateralComb_[i] = latComb[i]; +} + +void MuonPath::setLateralComb(const LATERAL_CASES *latComb) { + for (int i = 0; i < NUM_LAYERS; i++) + lateralComb_[i] = latComb[i]; +} diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzer.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzer.cc new file mode 100644 index 0000000000000..744ee7f8b7438 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzer.cc @@ -0,0 +1,21 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h" + +using namespace edm; +using namespace std; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MuonPathAnalyzer::MuonPathAnalyzer(const ParameterSet& pset, edm::ConsumesCollector& iC) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); +} + +MuonPathAnalyzer::~MuonPathAnalyzer() {} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MuonPathAnalyzer::initialise(const edm::EventSetup& iEventSetup) {} + +void MuonPathAnalyzer::finish(){}; diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc new file mode 100644 index 0000000000000..42a0aadd2144e --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc @@ -0,0 +1,551 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h" +#include +#include + +using namespace edm; +using namespace std; +using namespace cmsdt; +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MuonPathAnalyzerInChamber::MuonPathAnalyzerInChamber(const ParameterSet &pset, edm::ConsumesCollector &iC) + : MuonPathAnalyzer(pset, iC), + debug_(pset.getUntrackedParameter("debug")), + chi2Th_(pset.getUntrackedParameter("chi2Th")), + shift_filename_(pset.getParameter("shift_filename")), + bxTolerance_(30), + minQuality_(LOWQGHOST), + chiSquareThreshold_(50), + minHits4Fit_(pset.getUntrackedParameter("minHits4Fit")) { + // Obtention of parameters + + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzer: constructor"; + + setChiSquareThreshold(chi2Th_ * 100.); + + //shift + int rawId; + std::ifstream ifin3(shift_filename_.fullPath()); + double shift; + if (ifin3.fail()) { + throw cms::Exception("Missing Input File") + << "MuonPathAnalyzerInChamber::MuonPathAnalyzerInChamber() - Cannot find " << shift_filename_.fullPath(); + } + while (ifin3.good()) { + ifin3 >> rawId >> shift; + shiftinfo_[rawId] = shift; + } + + dtGeomH = iC.esConsumes(); +} + +MuonPathAnalyzerInChamber::~MuonPathAnalyzerInChamber() { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzer: destructor"; +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MuonPathAnalyzerInChamber::initialise(const edm::EventSetup &iEventSetup) { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzerInChamber::initialiase"; + + const MuonGeometryRecord &geom = iEventSetup.get(); + dtGeo_ = &geom.get(dtGeomH); +} + +void MuonPathAnalyzerInChamber::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &muonpaths, + MuonPathPtrs &outmuonpaths) { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzerInChamber: run"; + + // fit per SL (need to allow for multiple outputs for a single mpath) + for (auto muonpath = muonpaths.begin(); muonpath != muonpaths.end(); ++muonpath) { + analyze(*muonpath, outmuonpaths); + } +} + +void MuonPathAnalyzerInChamber::finish() { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzer: finish"; +}; + +//------------------------------------------------------------------ +//--- Private method +//------------------------------------------------------------------ +void MuonPathAnalyzerInChamber::analyze(MuonPathPtr &inMPath, MuonPathPtrs &outMPath) { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t starts"; + + // Clone the analyzed object + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << inMPath->nprimitives(); + auto mPath = std::make_shared(inMPath); + + if (debug_) { + LogDebug("MuonPathAnalyzerInChamber") << "DTp2::analyze, looking at mPath: "; + for (int i = 0; i < mPath->nprimitives(); i++) + LogDebug("MuonPathAnalyzerInChamber") + << mPath->primitive(i)->layerId() << " , " << mPath->primitive(i)->superLayerId() << " , " + << mPath->primitive(i)->channelId() << " , " << mPath->primitive(i)->laterality(); + } + + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t\t is Analyzable? "; + if (!mPath->isAnalyzable()) + return; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t\t yes it is analyzable " << mPath->isAnalyzable(); + + // first of all, get info from primitives, so we can reduce the number of latereralities: + buildLateralities(mPath); + setWirePosAndTimeInMP(mPath); + + std::shared_ptr mpAux; + int bestI = -1; + float best_chi2 = 99999.; + for (int i = 0; i < totalNumValLateralities_; i++) { // LOOP for all lateralities: + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t\t Start with combination " << i; + int NTotalHits = NUM_LAYERS_2SL; + float xwire[NUM_LAYERS_2SL]; + int present_layer[NUM_LAYERS_2SL]; + for (int ii = 0; ii < 8; ii++) { + xwire[ii] = mPath->xWirePos(ii); + if (xwire[ii] == 0) { + present_layer[ii] = 0; + NTotalHits--; + } else { + present_layer[ii] = 1; + } + } + + while (NTotalHits >= minHits4Fit_) { + mPath->setChiSquare(0); + calculateFitParameters(mPath, lateralities_[i], present_layer); + if (mPath->chiSquare() != 0) + break; + NTotalHits--; + } + if (mPath->chiSquare() > chiSquareThreshold_) + continue; + + evaluateQuality(mPath); + + if (mPath->quality() < minQuality_) + continue; + + double z = 0; + double jm_x = (mPath->horizPos()); + int selected_Id = 0; + for (int i = 0; i < mPath->nprimitives(); i++) { + if (mPath->primitive(i)->isValidTime()) { + selected_Id = mPath->primitive(i)->cameraId(); + mPath->setRawId(selected_Id); + break; + } + } + DTLayerId thisLId(selected_Id); + if (thisLId.station() >= 3) + z = Z_SHIFT_MB4; + + DTSuperLayerId MuonPathSLId(thisLId.wheel(), thisLId.station(), thisLId.sector(), thisLId.superLayer()); + GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(MuonPathSLId)->toGlobal(LocalPoint(jm_x, 0., z)); + //jm_x is already extrapolated to the middle of the SL + int thisec = MuonPathSLId.sector(); + if (thisec == 13) + thisec = 4; + if (thisec == 14) + thisec = 10; + double phi = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1); + double psi = atan(mPath->tanPhi()); + mPath->setPhi(jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1)); + mPath->setPhiB(hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? psi - phi : -psi - phi); + + if (mPath->chiSquare() < best_chi2 && mPath->chiSquare() > 0) { + mpAux = std::make_shared(mPath); + bestI = i; + best_chi2 = mPath->chiSquare(); + } + } + if (mpAux != nullptr) { + outMPath.push_back(std::move(mpAux)); + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << "DTp2:analize \t\t\t\t\t Laterality " << bestI << " is the one with smaller chi2"; + } else { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << "DTp2:analize \t\t\t\t\t No Laterality found with chi2 smaller than threshold"; + } + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analize \t\t\t\t\t Ended working with this set of lateralities"; +} + +void MuonPathAnalyzerInChamber::setCellLayout(MuonPathPtr &mpath) { + for (int i = 0; i <= mpath->nprimitives(); i++) { + if (mpath->primitive(i)->isValidTime()) + cellLayout_[i] = mpath->primitive(i)->channelId(); + else + cellLayout_[i] = -99; + } + + // putting info back into the mpath: + mpath->setCellHorizontalLayout(cellLayout_); + for (int i = 0; i <= mpath->nprimitives(); i++) { + if (cellLayout_[i] >= 0) { + mpath->setBaseChannelId(cellLayout_[i]); + break; + } + } +} + +/** + * For a combination of up to 8 cells, build all the lateralities to be tested, + */ +void MuonPathAnalyzerInChamber::buildLateralities(MuonPathPtr &mpath) { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "MPAnalyzer::buildLateralities << setLateralitiesFromPrims "; + mpath->setLateralCombFromPrimitives(); + + totalNumValLateralities_ = 0; + lateralities_.clear(); + latQuality_.clear(); + + /* We generate all the possible laterality combinations compatible with the built + group in the previous step*/ + lateralities_.push_back(TLateralities()); + for (int ilat = 0; ilat < NLayers; ilat++) { + // Get value from input + LATERAL_CASES lr = (mpath->lateralComb())[ilat]; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] Input[" << ilat << "]: " << lr; + + // If left/right fill number + if (lr != NONE) { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] - Adding it to " << lateralities_.size() << " lists..."; + for (unsigned int iall = 0; iall < lateralities_.size(); iall++) { + lateralities_[iall][ilat] = lr; + } + } + // both possibilites + else { + // Get the number of possible options now + auto ncurrentoptions = lateralities_.size(); + + // Duplicate them + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] - Duplicating " << ncurrentoptions << " lists..."; + copy(lateralities_.begin(), lateralities_.end(), back_inserter(lateralities_)); + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] - Now we have " << lateralities_.size() << " lists..."; + + // Asign LEFT to first ncurrentoptions and RIGHT to the last + for (unsigned int iall = 0; iall < ncurrentoptions; iall++) { + lateralities_[iall][ilat] = LEFT; + lateralities_[iall + ncurrentoptions][ilat] = RIGHT; + } + } // else + } // Iterate over input array + + totalNumValLateralities_ = (int)lateralities_.size(); + if (totalNumValLateralities_ > 128) { + // ADD PROTECTION! + LogDebug("MuonPathAnalyzerInChamber") << "[WARNING]: TOO MANY LATERALITIES TO CHECK !!"; + LogDebug("MuonPathAnalyzerInChamber") << "[WARNING]: skipping this muon"; + lateralities_.clear(); + latQuality_.clear(); + totalNumValLateralities_ = 0; + } + + // Dump values + if (debug_) { + for (unsigned int iall = 0; iall < lateralities_.size(); iall++) { + LogDebug("MuonPathAnalyzerInChamber") << iall << " -> ["; + for (int ilat = 0; ilat < NLayers; ilat++) { + if (ilat != 0) + LogDebug("MuonPathAnalyzerInChamber") << ","; + LogDebug("MuonPathAnalyzerInChamber") << lateralities_[iall][ilat]; + } + LogDebug("MuonPathAnalyzerInChamber") << "]"; + } + } +} +void MuonPathAnalyzerInChamber::setLateralitiesInMP(MuonPathPtr &mpath, TLateralities lat) { + LATERAL_CASES tmp[NUM_LAYERS_2SL]; + for (int i = 0; i < 8; i++) + tmp[i] = lat[i]; + + mpath->setLateralComb(tmp); +} +void MuonPathAnalyzerInChamber::setWirePosAndTimeInMP(MuonPathPtr &mpath) { + int selected_Id = 0; + for (int i = 0; i < mpath->nprimitives(); i++) { + if (mpath->primitive(i)->isValidTime()) { + selected_Id = mpath->primitive(i)->cameraId(); + mpath->setRawId(selected_Id); + break; + } + } + DTLayerId thisLId(selected_Id); + DTChamberId chId(thisLId.wheel(), thisLId.station(), thisLId.sector()); + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << "Id " << chId.rawId() << " Wh " << chId.wheel() << " St " << chId.station() << " Se " << chId.sector(); + mpath->setRawId(chId.rawId()); + + DTSuperLayerId MuonPathSLId1(thisLId.wheel(), thisLId.station(), thisLId.sector(), 1); + DTSuperLayerId MuonPathSLId3(thisLId.wheel(), thisLId.station(), thisLId.sector(), 3); + DTWireId wireId1(MuonPathSLId1, 2, 1); + DTWireId wireId3(MuonPathSLId3, 2, 1); + + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << "shift1=" << shiftinfo_[wireId1.rawId()] << " shift3=" << shiftinfo_[wireId3.rawId()]; + + float delta = 42000; //um + float zwire[NUM_LAYERS_2SL] = {-13.7, -12.4, -11.1, -9.8002, 9.79999, 11.1, 12.4, 13.7}; // mm + for (int i = 0; i < mpath->nprimitives(); i++) { + if (mpath->primitive(i)->isValidTime()) { + if (i < 4) + mpath->setXWirePos(10000 * shiftinfo_[wireId1.rawId()] + + (mpath->primitive(i)->channelId() + 0.5 * (double)((i + 1) % 2)) * delta, + i); + if (i >= 4) + mpath->setXWirePos(10000 * shiftinfo_[wireId3.rawId()] + + (mpath->primitive(i)->channelId() + 0.5 * (double)((i + 1) % 2)) * delta, + i); + mpath->setZWirePos(zwire[i] * 1000, i); // in um + mpath->setTWireTDC(mpath->primitive(i)->tdcTimeStamp() * DRIFT_SPEED, i); + } else { + mpath->setXWirePos(0., i); + mpath->setZWirePos(0., i); + mpath->setTWireTDC(-1 * DRIFT_SPEED, i); + } + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << mpath->primitive(i)->tdcTimeStamp() << " "; + } + if (debug_) + LogDebug("MuonPathAnalyzerInChamber"); +} +void MuonPathAnalyzerInChamber::calculateFitParameters(MuonPathPtr &mpath, + TLateralities laterality, + int present_layer[NUM_LAYERS_2SL]) { + // First prepare mpath for fit: + float xwire[NUM_LAYERS_2SL], zwire[NUM_LAYERS_2SL], tTDCvdrift[NUM_LAYERS_2SL]; + double b[NUM_LAYERS_2SL]; + for (int i = 0; i < 8; i++) { + xwire[i] = mpath->xWirePos(i); + zwire[i] = mpath->zWirePos(i); + tTDCvdrift[i] = mpath->tWireTDC(i); + b[i] = 1; + } + + //// NOW Start FITTING: + + // fill hit position + float xhit[NUM_LAYERS_2SL]; + for (int lay = 0; lay < 8; lay++) { + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "In fitPerLat " << lay << " xwire " << xwire[lay] << " zwire " + << zwire[lay] << " tTDCvdrift " << tTDCvdrift[lay]; + xhit[lay] = xwire[lay] + (-1 + 2 * laterality[lay]) * 1000 * tTDCvdrift[lay]; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "In fitPerLat " << lay << " xhit " << xhit[lay]; + } + + //Proceed with calculation of fit parameters + double cbscal = 0.0; + double zbscal = 0.0; + double czscal = 0.0; + double bbscal = 0.0; + double zzscal = 0.0; + double ccscal = 0.0; + + for (int lay = 0; lay < 8; lay++) { + if (present_layer[lay] == 0) + continue; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << " For layer " << lay + 1 << " xwire[lay] " << xwire[lay] << " zwire " << zwire[lay] << " b " << b[lay]; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << " xhit[lat][lay] " << xhit[lay]; + cbscal = (-1 + 2 * laterality[lay]) * b[lay] + cbscal; + zbscal = zwire[lay] * b[lay] + zbscal; //it actually does not depend on laterality + czscal = (-1 + 2 * laterality[lay]) * zwire[lay] + czscal; + + bbscal = b[lay] * b[lay] + bbscal; //it actually does not depend on laterality + zzscal = zwire[lay] * zwire[lay] + zzscal; //it actually does not depend on laterality + ccscal = (-1 + 2 * laterality[lay]) * (-1 + 2 * laterality[lay]) + ccscal; + } + + double cz = 0.0; + double cb = 0.0; + double zb = 0.0; + double zc = 0.0; + double bc = 0.0; + double bz = 0.0; + + cz = (cbscal * zbscal - czscal * bbscal) / (zzscal * bbscal - zbscal * zbscal); + cb = (czscal * zbscal - cbscal * zzscal) / (zzscal * bbscal - zbscal * zbscal); + + zb = (czscal * cbscal - zbscal * ccscal) / (bbscal * ccscal - cbscal * cbscal); + zc = (zbscal * cbscal - czscal * bbscal) / (bbscal * ccscal - cbscal * cbscal); + + bc = (zbscal * czscal - cbscal * zzscal) / (ccscal * zzscal - czscal * czscal); + bz = (cbscal * czscal - zbscal * ccscal) / (ccscal * zzscal - czscal * czscal); + + double c_tilde[NUM_LAYERS_2SL]; + double z_tilde[NUM_LAYERS_2SL]; + double b_tilde[NUM_LAYERS_2SL]; + + for (int lay = 0; lay < 8; lay++) { + if (present_layer[lay] == 0) + continue; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << " For layer " << lay + 1 << " xwire[lay] " << xwire[lay] << " zwire " << zwire[lay] << " b " << b[lay]; + c_tilde[lay] = (-1 + 2 * laterality[lay]) + cz * zwire[lay] + cb * b[lay]; + z_tilde[lay] = zwire[lay] + zb * b[lay] + zc * (-1 + 2 * laterality[lay]); + b_tilde[lay] = b[lay] + bc * (-1 + 2 * laterality[lay]) + bz * zwire[lay]; + } + + //Calculate results per lat + double xctilde = 0.0; + double xztilde = 0.0; + double xbtilde = 0.0; + double ctildectilde = 0.0; + double ztildeztilde = 0.0; + double btildebtilde = 0.0; + + double rect0vdrift = 0.0; + double recslope = 0.0; + double recpos = 0.0; + + for (int lay = 0; lay < 8; lay++) { + if (present_layer[lay] == 0) + continue; + xctilde = xhit[lay] * c_tilde[lay] + xctilde; + ctildectilde = c_tilde[lay] * c_tilde[lay] + ctildectilde; + xztilde = xhit[lay] * z_tilde[lay] + xztilde; + ztildeztilde = z_tilde[lay] * z_tilde[lay] + ztildeztilde; + xbtilde = xhit[lay] * b_tilde[lay] + xbtilde; + btildebtilde = b_tilde[lay] * b_tilde[lay] + btildebtilde; + } + + //Results for t0vdrift (BX), slope and position per lat + rect0vdrift = xctilde / ctildectilde; + recslope = xztilde / ztildeztilde; + recpos = xbtilde / btildebtilde; + if (debug_) { + LogDebug("MuonPathAnalyzerInChamber") << " In fitPerLat Reconstructed values per lat " + << " rect0vdrift " << rect0vdrift; + LogDebug("MuonPathAnalyzerInChamber") + << "rect0 " << rect0vdrift / DRIFT_SPEED << " recBX " << rect0vdrift / DRIFT_SPEED / 25 << " recslope " + << recslope << " recpos " << recpos; + } + + //Get t*v and residuals per layer, and chi2 per laterality + double rectdriftvdrift[NUM_LAYERS_2SL]; + double recres[NUM_LAYERS_2SL]; + double recchi2 = 0.0; + int sign_tdriftvdrift = {0}; + int incell_tdriftvdrift = {0}; + int physical_slope = {0}; + + // Select the worst hit in order to get rid of it + double maxDif = -1; + int maxInt = -1; + + for (int lay = 0; lay < 8; lay++) { + if (present_layer[lay] == 0) + continue; + rectdriftvdrift[lay] = tTDCvdrift[lay] - rect0vdrift / 1000; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << rectdriftvdrift[lay]; + recres[lay] = xhit[lay] - zwire[lay] * recslope - b[lay] * recpos - (-1 + 2 * laterality[lay]) * rect0vdrift; + if ((present_layer[lay] == 1) && (rectdriftvdrift[lay] < -0.1)) { + sign_tdriftvdrift = -1; + if (-0.1 - rectdriftvdrift[lay] > maxDif) { + maxDif = -0.1 - rectdriftvdrift[lay]; + maxInt = lay; + } + } + if ((present_layer[lay] == 1) && (abs(rectdriftvdrift[lay]) > 21.1)) { + incell_tdriftvdrift = -1; //Changed to 2.11 to account for resolution effects + if (rectdriftvdrift[lay] - 21.1 > maxDif) { + maxDif = rectdriftvdrift[lay] - 21.1; + maxInt = lay; + } + } + } + + if (fabs(recslope / 10) > 1.3) + physical_slope = -1; + + if (physical_slope == -1 && debug_) + LogDebug("MuonPathAnalyzerInChamber") << "Combination with UNPHYSICAL slope "; + if (sign_tdriftvdrift == -1 && debug_) + LogDebug("MuonPathAnalyzerInChamber") << "Combination with negative tdrift-vdrift "; + if (incell_tdriftvdrift == -1 && debug_) + LogDebug("MuonPathAnalyzerInChamber") << "Combination with tdrift-vdrift larger than half cell "; + + for (int lay = 0; lay < 8; lay++) { + if (present_layer[lay] == 0) + continue; + recchi2 = recres[lay] * recres[lay] + recchi2; + } + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << "In fitPerLat Chi2 " << recchi2 << " with sign " << sign_tdriftvdrift << " within cell " + << incell_tdriftvdrift << " physical_slope " << physical_slope; + + //LATERALITY IS NOT VALID + if (true && maxInt != -1) { + present_layer[maxInt] = 0; + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") << "We get rid of hit in layer " << maxInt; + } + + // LATERALITY IS VALID... + if (!(sign_tdriftvdrift == -1) && !(incell_tdriftvdrift == -1) && !(physical_slope == -1)) { + mpath->setBxTimeValue((rect0vdrift / DRIFT_SPEED) / 1000); + mpath->setTanPhi(-1 * recslope / 10); + mpath->setHorizPos(recpos / 10000); + mpath->setChiSquare(recchi2 / 100000000); + setLateralitiesInMP(mpath, laterality); + if (debug_) + LogDebug("MuonPathAnalyzerInChamber") + << "In fitPerLat " + << "t0 " << mpath->bxTimeValue() << " slope " << mpath->tanPhi() << " pos " << mpath->horizPos() << " chi2 " + << mpath->chiSquare() << " rawId " << mpath->rawId(); + } +} +void MuonPathAnalyzerInChamber::evaluateQuality(MuonPathPtr &mPath) { + mPath->setQuality(NOPATH); + + if (mPath->nprimitivesUp() >= 4 && mPath->nprimitivesDown() >= 4) { + mPath->setQuality(HIGHHIGHQ); + } else if ((mPath->nprimitivesUp() == 4 && mPath->nprimitivesDown() == 3) || + (mPath->nprimitivesUp() == 3 && mPath->nprimitivesDown() == 4)) { + mPath->setQuality(HIGHLOWQ); + } else if ((mPath->nprimitivesUp() == 4 && mPath->nprimitivesDown() <= 2 && mPath->nprimitivesDown() > 0) || + (mPath->nprimitivesUp() <= 2 && mPath->nprimitivesUp() > 0 && mPath->nprimitivesDown() == 4)) { + mPath->setQuality(CHIGHQ); + } else if ((mPath->nprimitivesUp() == 3 && mPath->nprimitivesDown() == 3)) { + mPath->setQuality(LOWLOWQ); + } else if ((mPath->nprimitivesUp() == 3 && mPath->nprimitivesDown() <= 2 && mPath->nprimitivesDown() > 0) || + (mPath->nprimitivesUp() <= 2 && mPath->nprimitivesUp() > 0 && mPath->nprimitivesDown() == 3) || + (mPath->nprimitivesUp() == 2 && mPath->nprimitivesDown() == 2)) { + mPath->setQuality(CLOWQ); + } else if (mPath->nprimitivesUp() >= 4 || mPath->nprimitivesDown() >= 4) { + mPath->setQuality(HIGHQ); + } else if (mPath->nprimitivesUp() == 3 || mPath->nprimitivesDown() == 3) { + mPath->setQuality(LOWQ); + } +} diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerPerSL.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerPerSL.cc new file mode 100644 index 0000000000000..3fa3436fe06b4 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerPerSL.cc @@ -0,0 +1,1076 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h" +#include +#include + +using namespace edm; +using namespace std; +using namespace cmsdt; +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MuonPathAnalyzerPerSL::MuonPathAnalyzerPerSL(const ParameterSet &pset, edm::ConsumesCollector &iC) + : MuonPathAnalyzer(pset, iC), + bxTolerance_(30), + minQuality_(LOWQGHOST), + chiSquareThreshold_(50), + debug_(pset.getUntrackedParameter("debug")), + chi2Th_(pset.getUntrackedParameter("chi2Th")), + tanPhiTh_(pset.getUntrackedParameter("tanPhiTh")), + use_LSB_(pset.getUntrackedParameter("use_LSB")), + tanPsi_precision_(pset.getUntrackedParameter("tanPsi_precision")), + x_precision_(pset.getUntrackedParameter("x_precision")) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzer: constructor"; + + setChiSquareThreshold(chi2Th_ * 100.); + + //shift + int rawId; + shift_filename_ = pset.getParameter("shift_filename"); + std::ifstream ifin3(shift_filename_.fullPath()); + double shift; + if (ifin3.fail()) { + throw cms::Exception("Missing Input File") + << "MuonPathAnalyzerPerSL::MuonPathAnalyzerPerSL() - Cannot find " << shift_filename_.fullPath(); + } + while (ifin3.good()) { + ifin3 >> rawId >> shift; + shiftinfo_[rawId] = shift; + } + + chosen_sl_ = pset.getUntrackedParameter("trigger_with_sl"); + + if (chosen_sl_ != 1 && chosen_sl_ != 3 && chosen_sl_ != 4) { + LogDebug("MuonPathAnalyzerPerSL") << "chosen sl must be 1,3 or 4(both superlayers)"; + assert(chosen_sl_ != 1 && chosen_sl_ != 3 && chosen_sl_ != 4); //4 means run using the two superlayers + } + + dtGeomH = iC.esConsumes(); +} + +MuonPathAnalyzerPerSL::~MuonPathAnalyzerPerSL() { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzer: destructor"; +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MuonPathAnalyzerPerSL::initialise(const edm::EventSetup &iEventSetup) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzerPerSL::initialiase"; + + const MuonGeometryRecord &geom = iEventSetup.get(); + dtGeo_ = &geom.get(dtGeomH); +} + +void MuonPathAnalyzerPerSL::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &muonpaths, + std::vector &metaPrimitives) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzerPerSL: run"; + + // fit per SL (need to allow for multiple outputs for a single mpath) + for (auto &muonpath : muonpaths) { + analyze(muonpath, metaPrimitives); + } +} + +void MuonPathAnalyzerPerSL::finish() { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "MuonPathAnalyzer: finish"; +}; + +constexpr int MuonPathAnalyzerPerSL::LAYER_ARRANGEMENTS_[NUM_LAYERS][NUM_CELL_COMB] = { + {0, 1, 2}, + {1, 2, 3}, // Consecutive groups + {0, 1, 3}, + {0, 2, 3} // Non-consecutive groups +}; + +//------------------------------------------------------------------ +//--- Métodos privados +//------------------------------------------------------------------ + +void MuonPathAnalyzerPerSL::analyze(MuonPathPtr &inMPath, std::vector &metaPrimitives) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t starts"; + + // LOCATE MPATH + int selected_Id = 0; + if (inMPath->primitive(0)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(0)->cameraId(); + else if (inMPath->primitive(1)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(1)->cameraId(); + else if (inMPath->primitive(2)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(2)->cameraId(); + else if (inMPath->primitive(3)->tdcTimeStamp() != -1) + selected_Id = inMPath->primitive(3)->cameraId(); + + DTLayerId thisLId(selected_Id); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Building up MuonPathSLId from rawId in the Primitive"; + DTSuperLayerId MuonPathSLId(thisLId.wheel(), thisLId.station(), thisLId.sector(), thisLId.superLayer()); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "The MuonPathSLId is" << MuonPathSLId; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t In analyze function checking if inMPath->isAnalyzable() " << inMPath->isAnalyzable(); + + if (chosen_sl_ < 4 && thisLId.superLayer() != chosen_sl_) + return; // avoid running when mpath not in chosen SL (for 1SL fitting) + + auto mPath = std::make_shared(inMPath); + + if (mPath->isAnalyzable()) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t yes it is analyzable " << mPath->isAnalyzable(); + setCellLayout(mPath->cellLayout()); + evaluatePathQuality(mPath); + } else { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t no it is NOT analyzable " << mPath->isAnalyzable(); + return; + } + + int wi[8], tdc[8], lat[8]; + DTPrimitivePtr Prim0(mPath->primitive(0)); + wi[0] = Prim0->channelId(); + tdc[0] = Prim0->tdcTimeStamp(); + DTPrimitivePtr Prim1(mPath->primitive(1)); + wi[1] = Prim1->channelId(); + tdc[1] = Prim1->tdcTimeStamp(); + DTPrimitivePtr Prim2(mPath->primitive(2)); + wi[2] = Prim2->channelId(); + tdc[2] = Prim2->tdcTimeStamp(); + DTPrimitivePtr Prim3(mPath->primitive(3)); + wi[3] = Prim3->channelId(); + tdc[3] = Prim3->tdcTimeStamp(); + for (int i = 4; i < 8; i++) { + wi[i] = -1; + tdc[i] = -1; + lat[i] = -1; + } + + DTWireId wireId(MuonPathSLId, 2, 1); + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t checking if it passes the min quality cut " + << mPath->quality() << ">" << minQuality_; + if (mPath->quality() >= minQuality_) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t min quality achievedCalidad: " << mPath->quality(); + for (int i = 0; i <= 3; i++) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t Capa: " << mPath->primitive(i)->layerId() + << " Canal: " << mPath->primitive(i)->channelId() << " TDCTime: " << mPath->primitive(i)->tdcTimeStamp(); + } + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t Starting lateralities loop, totalNumValLateralities: " + << totalNumValLateralities_; + + double best_chi2 = 99999.; + double chi2_jm_tanPhi = 999; + double chi2_jm_x = -1; + double chi2_jm_t0 = -1; + double chi2_phi = -1; + double chi2_phiB = -1; + double chi2_chi2 = -1; + int chi2_quality = -1; + int bestLat[8]; + for (int i = 0; i < 8; i++) { + bestLat[i] = -1; + } + + for (int i = 0; i < totalNumValLateralities_; i++) { //here + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i; + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " checking quality:"; + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " checking mPath Quality=" << mPath->quality(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " latQuality_[i].val=" << latQuality_[i].valid; + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " before if:"; + + if (latQuality_[i].valid and + (((mPath->quality() == HIGHQ or mPath->quality() == HIGHQGHOST) and latQuality_[i].quality == HIGHQ) or + ((mPath->quality() == LOWQ or mPath->quality() == LOWQGHOST) and latQuality_[i].quality == LOWQ))) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " inside if"; + mPath->setBxTimeValue(latQuality_[i].bxValue); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " settingLateralCombination"; + mPath->setLateralComb(lateralities_[i]); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t laterality #- " << i << " done settingLateralCombination"; + + // Clonamos el objeto analizado. + auto mpAux = std::make_shared(mPath); + lat[0] = mpAux->lateralComb()[0]; + lat[1] = mpAux->lateralComb()[1]; + lat[2] = mpAux->lateralComb()[2]; + lat[3] = mpAux->lateralComb()[3]; + + int wiOk[NUM_LAYERS], tdcOk[NUM_LAYERS], latOk[NUM_LAYERS]; + for (int lay = 0; lay < 4; lay++) { + if (latQuality_[i].invalidateHitIdx == lay) { + wiOk[lay] = -1; + tdcOk[lay] = -1; + latOk[lay] = -1; + } else { + wiOk[lay] = wi[lay]; + tdcOk[lay] = tdc[lay]; + latOk[lay] = lat[lay]; + } + } + + int idxHitNotValid = latQuality_[i].invalidateHitIdx; + if (idxHitNotValid >= 0) { + auto dtpAux = std::make_shared(); + mpAux->setPrimitive(dtpAux, idxHitNotValid); + } + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t calculating parameters "; + calculatePathParameters(mpAux); + /* + * After calculating the parameters, and if it is a 4-hit fit, + * if the resultant chi2 is higher than the programmed threshold, + * the mpath is eliminated and we go to the next element + */ + if ((mpAux->quality() == HIGHQ or mpAux->quality() == HIGHQGHOST) && + mpAux->chiSquare() > chiSquareThreshold_) { //check this if!!! + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t HIGHQ or HIGHQGHOST but min chi2 or Q test not satisfied "; + } else { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t inside else, returning values: "; + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t BX Time = " << mpAux->bxTimeValue(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t BX Id = " << mpAux->bxNumId(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t XCoor = " << mpAux->horizPos(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t tan(Phi)= " << mpAux->tanPhi(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t chi2= " << mpAux->chiSquare(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t lateralities = " + << " " << mpAux->lateralComb()[0] << " " << mpAux->lateralComb()[1] << " " + << mpAux->lateralComb()[2] << " " << mpAux->lateralComb()[3]; + + DTChamberId ChId(MuonPathSLId.wheel(), MuonPathSLId.station(), MuonPathSLId.sector()); + + double jm_tanPhi = -1. * mpAux->tanPhi(); //testing with this line + if (use_LSB_) + jm_tanPhi = floor(jm_tanPhi / tanPsi_precision_) * tanPsi_precision_; + double jm_x = + (((double)mpAux->horizPos()) / 10.) + x_precision_ * (round(shiftinfo_[wireId.rawId()] / x_precision_)); + if (use_LSB_) + jm_x = ((double)round(((double)jm_x) / x_precision_)) * x_precision_; + //changing to chamber frame or reference: + double jm_t0 = mpAux->bxTimeValue(); + int quality = mpAux->quality(); + + //computing phi and phiB + double z = 0; + double z1 = Z_POS_SL; + double z3 = -1. * z1; + if (ChId.station() == 3 or ChId.station() == 4) { + z1 = z1 + Z_SHIFT_MB4; + z3 = z3 + Z_SHIFT_MB4; + } else if (MuonPathSLId.superLayer() == 1) + z = z1; + else if (MuonPathSLId.superLayer() == 3) + z = z3; + + GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(jm_x, 0., z)); + int thisec = MuonPathSLId.sector(); + if (thisec == 13) + thisec = 4; + if (thisec == 14) + thisec = 10; + double phi = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1); + double psi = atan(jm_tanPhi); + double phiB = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? psi - phi : -psi - phi; + double chi2 = mpAux->chiSquare() * 0.01; //in cmssw we need cm, 1 cm^2 = 100 mm^2 + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t\t\t\t pushing back metaPrimitive at x=" << jm_x << " tanPhi:" << jm_tanPhi + << " t0:" << jm_t0; + + if (mpAux->quality() == HIGHQ or + mpAux->quality() == HIGHQGHOST) { //keep only the values with the best chi2 among lateralities + if ((chi2 < best_chi2) && (std::abs(jm_tanPhi) <= tanPhiTh_)) { + chi2_jm_tanPhi = jm_tanPhi; + chi2_jm_x = (mpAux->horizPos() / 10.) + shiftinfo_[wireId.rawId()]; + chi2_jm_t0 = mpAux->bxTimeValue(); + chi2_phi = phi; + chi2_phiB = phiB; + chi2_chi2 = chi2; + best_chi2 = chi2; + chi2_quality = mpAux->quality(); + for (int i = 0; i < 4; i++) { + bestLat[i] = lat[i]; + } + } + } else if (std::abs(jm_tanPhi) <= + tanPhiTh_) { //write the metaprimitive in case no HIGHQ or HIGHQGHOST and tanPhi range + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t\t\t\t pushing back metaprimitive no HIGHQ or HIGHQGHOST"; + metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(), + jm_t0, + jm_x, + jm_tanPhi, + phi, + phiB, + chi2, + quality, + wiOk[0], + tdcOk[0], + latOk[0], + wiOk[1], + tdcOk[1], + latOk[1], + wiOk[2], + tdcOk[2], + latOk[2], + wiOk[3], + tdcOk[3], + latOk[3], + wi[4], + tdc[4], + lat[4], + wi[5], + tdc[5], + lat[5], + wi[6], + tdc[6], + lat[6], + wi[7], + tdc[7], + lat[7], + -1})); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t\t\t\t done pushing back metaprimitive no HIGHQ or HIGHQGHOST"; + } + } + } else { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:analyze \t\t\t\t\t\t\t\t latQuality_[i].valid and (((mPath->quality()==HIGHQ or " + "mPath->quality()==HIGHQGHOST) and latQuality_[i].quality==HIGHQ) or ((mPath->quality() " + "== LOWQ or mPath->quality()==LOWQGHOST) and latQuality_[i].quality==LOWQ)) not passed"; + } + } + if (chi2_jm_tanPhi != 999 and std::abs(chi2_jm_tanPhi) < tanPhiTh_) { // + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t\t\t\t pushing back best chi2 metaPrimitive"; + metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(), + chi2_jm_t0, + chi2_jm_x, + chi2_jm_tanPhi, + chi2_phi, + chi2_phiB, + chi2_chi2, + chi2_quality, + wi[0], + tdc[0], + bestLat[0], + wi[1], + tdc[1], + bestLat[1], + wi[2], + tdc[2], + bestLat[2], + wi[3], + tdc[3], + bestLat[3], + wi[4], + tdc[4], + bestLat[4], + wi[5], + tdc[5], + bestLat[5], + wi[6], + tdc[6], + bestLat[6], + wi[7], + tdc[7], + bestLat[7], + -1})); + } + } + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t finishes"; +} + +void MuonPathAnalyzerPerSL::setCellLayout(const int layout[NUM_LAYERS]) { + memcpy(cellLayout_, layout, 4 * sizeof(int)); + + buildLateralities(); +} + +/** + * For a given 4-cell combination (one per layer), all the possible lateralities + * combinations that are compatible with a straight line are generated. + */ +void MuonPathAnalyzerPerSL::buildLateralities(void) { + LATERAL_CASES(*validCase)[NUM_LAYERS], sideComb[NUM_LAYERS]; + + totalNumValLateralities_ = 0; + /* We generate all the possible lateralities combination for a given group + of cells */ + for (int lowLay = LEFT; lowLay <= RIGHT; lowLay++) + for (int midLowLay = LEFT; midLowLay <= RIGHT; midLowLay++) + for (int midHigLay = LEFT; midHigLay <= RIGHT; midHigLay++) + for (int higLay = LEFT; higLay <= RIGHT; higLay++) { + sideComb[0] = static_cast(lowLay); + sideComb[1] = static_cast(midLowLay); + sideComb[2] = static_cast(midHigLay); + sideComb[3] = static_cast(higLay); + + /* If a laterality combination is valid, we store it */ + if (isStraightPath(sideComb)) { + validCase = lateralities_ + totalNumValLateralities_; + memcpy(validCase, sideComb, 4 * sizeof(LATERAL_CASES)); + + latQuality_[totalNumValLateralities_].valid = false; + latQuality_[totalNumValLateralities_].bxValue = 0; + latQuality_[totalNumValLateralities_].quality = NOPATH; + latQuality_[totalNumValLateralities_].invalidateHitIdx = -1; + + totalNumValLateralities_++; + } + } +} + +/** + * This method checks whether a given combination conform a straight line or not + */ +bool MuonPathAnalyzerPerSL::isStraightPath(LATERAL_CASES sideComb[NUM_LAYERS]) { + return true; //trying with all lateralities to be confirmed + + int i, ajustedLayout[NUM_LAYERS], pairDiff[3], desfase[3]; + + for (i = 0; i <= 3; i++) + ajustedLayout[i] = cellLayout_[i] + sideComb[i]; + for (i = 0; i <= 2; i++) + pairDiff[i] = ajustedLayout[i + 1] - ajustedLayout[i]; + for (i = 0; i <= 1; i++) + desfase[i] = abs(pairDiff[i + 1] - pairDiff[i]); + desfase[2] = abs(pairDiff[2] - pairDiff[0]); + bool resultado = (desfase[0] > 1 or desfase[1] > 1 or desfase[2] > 1); + + return (!resultado); +} +void MuonPathAnalyzerPerSL::evaluatePathQuality(MuonPathPtr &mPath) { + int totalHighQ = 0, totalLowQ = 0; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:evaluatePathQuality \t\t\t\t\t En evaluatePathQuality Evaluando PathQ. Celda base: " + << mPath->baseChannelId(); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t Total lateralidades: " + << totalNumValLateralities_; + + mPath->setQuality(NOPATH); + + for (int latIdx = 0; latIdx < totalNumValLateralities_; latIdx++) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t Analizando combinacion de lateralidad: " + << lateralities_[latIdx][0] << " " << lateralities_[latIdx][1] << " " + << lateralities_[latIdx][2] << " " << lateralities_[latIdx][3]; + + evaluateLateralQuality(latIdx, mPath, &(latQuality_[latIdx])); + + if (latQuality_[latIdx].quality == HIGHQ) { + totalHighQ++; + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t\t Lateralidad HIGHQ"; + } + if (latQuality_[latIdx].quality == LOWQ) { + totalLowQ++; + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluatePathQuality \t\t\t\t\t\t Lateralidad LOWQ"; + } + } + /* + * Quality stablishment + */ + if (totalHighQ == 1) { + mPath->setQuality(HIGHQ); + } else if (totalHighQ > 1) { + mPath->setQuality(HIGHQGHOST); + } else if (totalLowQ == 1) { + mPath->setQuality(LOWQ); + } else if (totalLowQ > 1) { + mPath->setQuality(LOWQGHOST); + } +} + +void MuonPathAnalyzerPerSL::evaluateLateralQuality(int latIdx, MuonPathPtr &mPath, LATQ_TYPE *latQuality) { + int layerGroup[3]; + LATERAL_CASES sideComb[3]; + PARTIAL_LATQ_TYPE latQResult[NUM_LAYERS] = {{false, 0}, {false, 0}, {false, 0}, {false, 0}}; + + // Default values. + latQuality->valid = false; + latQuality->bxValue = 0; + latQuality->quality = NOPATH; + latQuality->invalidateHitIdx = -1; + + /* If, for a given laterality combination, the two consecutive 3-layer combinations + were a valid track, we will have found a right high-quality track, hence + it will be unnecessary to check the remaining 2 combinations. + In order to mimic the FPGA behaviour, we build a code that analyzes the 4 combinations + with an additional logic to discriminate the final quality of the track + */ + for (int i = 0; i <= 3; i++) { + memcpy(layerGroup, LAYER_ARRANGEMENTS_[i], 3 * sizeof(int)); + + // Pick the laterality combination for each cell + for (int j = 0; j < 3; j++) + sideComb[j] = lateralities_[latIdx][layerGroup[j]]; + + validate(sideComb, layerGroup, mPath, &(latQResult[i])); + } + /* + Impose the condition for a complete laterality combination, that all combinations + should give the same BX vale to give a consistent track. + */ + if (!sameBXValue(latQResult)) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad DESCARTADA. Tolerancia de BX excedida"; + return; + } + + // two complementary valid tracks => full muon track. + if ((latQResult[0].latQValid && latQResult[1].latQValid) or (latQResult[0].latQValid && latQResult[2].latQValid) or + (latQResult[0].latQValid && latQResult[3].latQValid) or (latQResult[1].latQValid && latQResult[2].latQValid) or + (latQResult[1].latQValid && latQResult[3].latQValid) or (latQResult[2].latQValid && latQResult[3].latQValid)) { + latQuality->valid = true; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t\t Valid BXs"; + long int sumBX = 0, numValid = 0; + for (int i = 0; i <= 3; i++) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:analyze \t\t\t\t\t\t " + << "[" << latQResult[i].bxValue << "," << latQResult[i].latQValid << "]"; + if (latQResult[i].latQValid) { + sumBX += latQResult[i].bxValue; + numValid++; + } + } + + // mean time of all lateralities. + if (numValid == 1) + latQuality->bxValue = sumBX; + else if (numValid == 2) + latQuality->bxValue = (sumBX * (MEANTIME_2LAT)) / std::pow(2, 15); + else if (numValid == 3) + latQuality->bxValue = (sumBX * (MEANTIME_3LAT)) / std::pow(2, 15); + else if (numValid == 4) + latQuality->bxValue = (sumBX * (MEANTIME_4LAT)) / std::pow(2, 15); + + latQuality->quality = HIGHQ; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad ACEPTADA. HIGHQ."; + } else { + if (latQResult[0].latQValid or latQResult[1].latQValid or latQResult[2].latQValid or latQResult[3].latQValid) { + latQuality->valid = true; + latQuality->quality = LOWQ; + for (int i = 0; i < 4; i++) + if (latQResult[i].latQValid) { + latQuality->bxValue = latQResult[i].bxValue; + latQuality->invalidateHitIdx = omittedHit(i); + break; + } + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad ACEPTADA. LOWQ."; + } else { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:evaluateLateralQuality \t\t\t\t\t Lateralidad DESCARTADA. NOPATH."; + } + } +} + +/** + * Validate, for a layer combination (3), cells and lateralities, if the temporal values + * fullfill the mean-timer criteria. + */ +void MuonPathAnalyzerPerSL::validate(LATERAL_CASES sideComb[3], + int layerIndex[3], + MuonPathPtr &mPath, + PARTIAL_LATQ_TYPE *latq) { + // Valor por defecto. + latq->bxValue = 0; + latq->latQValid = false; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t In validate, checking muon path for layers: " + << layerIndex[0] << "/" << layerIndex[1] << "/" << layerIndex[2]; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t Partial lateralities: " << sideComb[0] << "/" + << sideComb[1] << "/" << sideComb[2]; + + int validCells = 0; + for (int j = 0; j < 3; j++) + if (mPath->primitive(layerIndex[j])->isValidTime()) + validCells++; + + if (validCells != 3) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t There is no valid cells."; + return; + } + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t TDC values: " + << mPath->primitive(layerIndex[0])->tdcTimeStamp() << "/" + << mPath->primitive(layerIndex[1])->tdcTimeStamp() << "/" + << mPath->primitive(layerIndex[2])->tdcTimeStamp() << "."; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t Valid TIMES: " + << mPath->primitive(layerIndex[0])->isValidTime() << "/" + << mPath->primitive(layerIndex[1])->isValidTime() << "/" + << mPath->primitive(layerIndex[2])->isValidTime() << "."; + + /* Vertical distances */ + int dVertMI = layerIndex[1] - layerIndex[0]; + int dVertSM = layerIndex[2] - layerIndex[1]; + + /* Horizontal distances between lower/middle and middle/upper cells */ + int dHorzMI = cellLayout_[layerIndex[1]] - cellLayout_[layerIndex[0]]; + int dHorzSM = cellLayout_[layerIndex[2]] - cellLayout_[layerIndex[1]]; + + /* Pair index of layers that we are using + SM => Upper + Middle + MI => Middle + Lower + We use pointers to simplify the code */ + int *layPairSM = &layerIndex[1]; + int *layPairMI = &layerIndex[0]; + + /* Pair combination of cells to compose the equation. */ + LATERAL_CASES smSides[2], miSides[2]; + + /* Considering the index 0 of "sideComb" the laterality of the lower cells is stored, + we extract the laterality combiantion for SM and MI pairs */ + + memcpy(smSides, &sideComb[1], 2 * sizeof(LATERAL_CASES)); + + memcpy(miSides, &sideComb[0], 2 * sizeof(LATERAL_CASES)); + + long int bxValue = 0; + int coefsAB[2] = {0, 0}, coefsCD[2] = {0, 0}; + /* It's neccesary to be careful with that pointer's indirection. We need to + retrieve the lateral coeficientes (+-1) from the lower/middle and + middle/upper cell's lateral combinations. They are needed to evaluate the + existance of a possible BX value, following it's calculation equation */ + lateralCoeficients(miSides, coefsAB); + lateralCoeficients(smSides, coefsCD); + + /* Each of the summs of the 'coefsCD' & 'coefsAB' give always as results 0, +-2 + */ + + int denominator = dVertMI * (coefsCD[1] + coefsCD[0]) - dVertSM * (coefsAB[1] + coefsAB[0]); + + if (denominator == 0) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t Imposible to calculate BX."; + return; + } + + long int sumA = (long int)floor(MAXDRIFT * (dVertMI * dHorzSM - dVertSM * dHorzMI)); + long int numerator = + (sumA + dVertMI * eqMainBXTerm(smSides, layPairSM, mPath) - dVertSM * eqMainBXTerm(miSides, layPairMI, mPath)); + + // These magic numbers are for doing divisions in the FW. + // These divisions are done with a precision of 18bits. + if (denominator == -1 * DENOM_TYPE1) + bxValue = (numerator * (-1 * DIVISION_HELPER1)) / std::pow(2, NBITS); + else if (denominator == -1 * DENOM_TYPE2) + bxValue = (numerator * (-1 * DIVISION_HELPER2)) / std::pow(2, NBITS); + else if (denominator == -1 * DENOM_TYPE3) + bxValue = (numerator * (-1 * DIVISION_HELPER3)) / std::pow(2, NBITS); + else if (denominator == DENOM_TYPE3) + bxValue = (numerator * (DIVISION_HELPER3)) / std::pow(2, NBITS); + else if (denominator == DENOM_TYPE2) + bxValue = (numerator * (DIVISION_HELPER2)) / std::pow(2, NBITS); + else if (denominator == DENOM_TYPE1) + bxValue = (numerator * (DIVISION_HELPER1)) / std::pow(2, NBITS); + else + LogDebug("MuonPathAnalyzerPerSL") << "Different!"; + if (bxValue < 0) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t No-valid combination. Negative BX."; + return; + } + + for (int i = 0; i < 3; i++) + if (mPath->primitive(layerIndex[i])->isValidTime()) { + int diffTime = mPath->primitive(layerIndex[i])->tdcTimeStampNoOffset() - bxValue; + + if (diffTime <= 0 or diffTime > round(MAXDRIFT)) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:validate \t\t\t\t\t\t\t Invalid BX value. at least one crazt TDC time"; + return; + } + } + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:validate \t\t\t\t\t\t\t BX: " << bxValue; + + /* If you reach here, the BX and partial laterality are considered are valid + */ + latq->bxValue = bxValue; + latq->latQValid = true; +} +int MuonPathAnalyzerPerSL::eqMainBXTerm(LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath) { + int eqTerm = 0, coefs[2]; + + lateralCoeficients(sideComb, coefs); + + eqTerm = coefs[0] * mPath->primitive(layerIdx[0])->tdcTimeStampNoOffset() + + coefs[1] * mPath->primitive(layerIdx[1])->tdcTimeStampNoOffset(); + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:eqMainBXTerm \t\t\t\t\t In eqMainBXTerm EQTerm(BX): " << eqTerm; + + return (eqTerm); +} +int MuonPathAnalyzerPerSL::eqMainTerm(LATERAL_CASES sideComb[2], int layerIdx[2], MuonPathPtr &mPath, int bxValue) { + int eqTerm = 0, coefs[2]; + + lateralCoeficients(sideComb, coefs); + + if (!use_LSB_) + eqTerm = coefs[0] * (mPath->primitive(layerIdx[0])->tdcTimeStampNoOffset() - bxValue) + + coefs[1] * (mPath->primitive(layerIdx[1])->tdcTimeStampNoOffset() - bxValue); + else + eqTerm = coefs[0] * floor((DRIFT_SPEED / (10 * x_precision_)) * + (mPath->primitive(layerIdx[0])->tdcTimeStampNoOffset() - bxValue)) + + coefs[1] * floor((DRIFT_SPEED / (10 * x_precision_)) * + (mPath->primitive(layerIdx[1])->tdcTimeStampNoOffset() - bxValue)); + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:\t\t\t\t\t EQTerm(Main): " << eqTerm; + + return (eqTerm); +} + +void MuonPathAnalyzerPerSL::lateralCoeficients(LATERAL_CASES sideComb[2], int *coefs) { + if ((sideComb[0] == LEFT) && (sideComb[1] == LEFT)) { + *(coefs) = +1; + *(coefs + 1) = -1; + } else if ((sideComb[0] == LEFT) && (sideComb[1] == RIGHT)) { + *(coefs) = +1; + *(coefs + 1) = +1; + } else if ((sideComb[0] == RIGHT) && (sideComb[1] == LEFT)) { + *(coefs) = -1; + *(coefs + 1) = -1; + } else if ((sideComb[0] == RIGHT) && (sideComb[1] == RIGHT)) { + *(coefs) = -1; + *(coefs + 1) = +1; + } +} + +/** + * Determines if all valid partial lateral combinations share the same value + * of 'bxValue'. + */ +bool MuonPathAnalyzerPerSL::sameBXValue(PARTIAL_LATQ_TYPE *latq) { + bool result = true; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue bxTolerance_: " << bxTolerance_; + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d01:" << abs(latq[0].bxValue - latq[1].bxValue); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d02:" << abs(latq[0].bxValue - latq[2].bxValue); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d03:" << abs(latq[0].bxValue - latq[3].bxValue); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d12:" << abs(latq[1].bxValue - latq[2].bxValue); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d13:" << abs(latq[1].bxValue - latq[3].bxValue); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "Dtp2:sameBXValue \t\t\t\t\t\t d23:" << abs(latq[2].bxValue - latq[3].bxValue); + + bool d01, d02, d03, d12, d13, d23; + d01 = (abs(latq[0].bxValue - latq[1].bxValue) <= bxTolerance_) ? true : false; + d02 = (abs(latq[0].bxValue - latq[2].bxValue) <= bxTolerance_) ? true : false; + d03 = (abs(latq[0].bxValue - latq[3].bxValue) <= bxTolerance_) ? true : false; + d12 = (abs(latq[1].bxValue - latq[2].bxValue) <= bxTolerance_) ? true : false; + d13 = (abs(latq[1].bxValue - latq[3].bxValue) <= bxTolerance_) ? true : false; + d23 = (abs(latq[2].bxValue - latq[3].bxValue) <= bxTolerance_) ? true : false; + + /* 4 groups of partial combination of valid lateralities */ + if ((latq[0].latQValid && latq[1].latQValid && latq[2].latQValid && latq[3].latQValid) && !(d01 && d12 && d23)) + result = false; + else + /* 4 posible cases of 3 groups of valid partial lateralities */ + if (((latq[0].latQValid && latq[1].latQValid && latq[2].latQValid) && !(d01 && d12)) or + ((latq[0].latQValid && latq[1].latQValid && latq[3].latQValid) && !(d01 && d13)) or + ((latq[0].latQValid && latq[2].latQValid && latq[3].latQValid) && !(d02 && d23)) or + ((latq[1].latQValid && latq[2].latQValid && latq[3].latQValid) && !(d12 && d23))) + result = false; + else + /* Lastly, the 4 possible cases of partial valid lateralities */ + + if (((latq[0].latQValid && latq[1].latQValid) && !d01) or ((latq[0].latQValid && latq[2].latQValid) && !d02) or + ((latq[0].latQValid && latq[3].latQValid) && !d03) or ((latq[1].latQValid && latq[2].latQValid) && !d12) or + ((latq[1].latQValid && latq[3].latQValid) && !d13) or ((latq[2].latQValid && latq[3].latQValid) && !d23)) + result = false; + + return result; +} + +/** Calculate the parameters of the detected trayectories */ +void MuonPathAnalyzerPerSL::calculatePathParameters(MuonPathPtr &mPath) { + // The order is important. + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:calculatePathParameters \t\t\t\t\t\t calculating calcCellDriftAndXcoor(mPath) "; + calcCellDriftAndXcoor(mPath); + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:calculatePathParameters \t\t\t\t\t\t checking mPath->quality() " + << mPath->quality(); + if (mPath->quality() == HIGHQ or mPath->quality() == HIGHQGHOST) { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:calculatePathParameters \t\t\t\t\t\t\t Quality test passed, now calcTanPhiXPosChamber4Hits(mPath) "; + calcTanPhiXPosChamber4Hits(mPath); + } else { + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") + << "DTp2:calculatePathParameters \t\t\t\t\t\t\t Quality test NOT passed calcTanPhiXPosChamber3Hits(mPath) "; + calcTanPhiXPosChamber3Hits(mPath); + } + + if (debug_) + LogDebug("MuonPathAnalyzerPerSL") << "DTp2:calculatePathParameters \t\t\t\t\t\t calcChiSquare(mPath) "; + calcChiSquare(mPath); +} + +void MuonPathAnalyzerPerSL::calcTanPhiXPosChamber(MuonPathPtr &mPath) { + int layerIdx[2]; + /* + To calculate path's angle are only necessary two valid primitives. + This method should be called only when a 'MuonPath' is determined as valid, + so, at least, three of its primitives must have a valid time. + With this two comparitions (which can be implemented easily as multiplexors + in the FPGA) this method ensures to catch two of those valid primitives to + evaluate the angle. + + The first one is below the middle line of the superlayer, while the other + one is above this line + */ + if (mPath->primitive(0)->isValidTime()) + layerIdx[0] = 0; + else + layerIdx[0] = 1; + + if (mPath->primitive(3)->isValidTime()) + layerIdx[1] = 3; + else + layerIdx[1] = 2; + + /* We identify along which cells' sides the muon travels */ + LATERAL_CASES sideComb[2]; + sideComb[0] = (mPath->lateralComb())[layerIdx[0]]; + sideComb[1] = (mPath->lateralComb())[layerIdx[1]]; + + /* Horizontal gap between cells in cell's semi-length units */ + int dHoriz = (mPath->cellLayout())[layerIdx[1]] - (mPath->cellLayout())[layerIdx[0]]; + + /* Vertical gap between cells in cell's height units */ + int dVert = layerIdx[1] - layerIdx[0]; + + /*-----------------------------------------------------------------*/ + /*--------------------- Phi angle calculation ---------------------*/ + /*-----------------------------------------------------------------*/ + float num = CELL_SEMILENGTH * dHoriz + DRIFT_SPEED * eqMainTerm(sideComb, layerIdx, mPath, mPath->bxTimeValue()); + + float denom = CELL_HEIGHT * dVert; + float tanPhi = num / denom; + + mPath->setTanPhi(tanPhi); + + /*-----------------------------------------------------------------*/ + /*----------------- Horizontal coord. calculation -----------------*/ + /*-----------------------------------------------------------------*/ + + /* + Using known coordinates, relative to superlayer axis reference, (left most + superlayer side, and middle line between 2nd and 3rd layers), calculating + horizontal coordinate implies using a basic line equation: + (y - y0) = (x - x0) * cotg(Phi) + This horizontal coordinate can be obtained setting y = 0 on last equation, + and also setting y0 and x0 with the values of a known muon's path cell + position hit. + It's enough to use the lower cell (layerIdx[0]) coordinates. So: + xC = x0 - y0 * tan(Phi) + */ + float lowerXPHorizPos = mPath->xCoorCell(layerIdx[0]); + + float lowerXPVertPos = 0; // This is only the absolute value distance. + if (layerIdx[0] == 0) + lowerXPVertPos = CELL_HEIGHT + CELL_SEMIHEIGHT; + else + lowerXPVertPos = CELL_SEMIHEIGHT; + + mPath->setHorizPos(lowerXPHorizPos + lowerXPVertPos * tanPhi); +} + +/** + * Coordinate and angle calculations for a 4 HITS cases + */ +void MuonPathAnalyzerPerSL::calcTanPhiXPosChamber4Hits(MuonPathPtr &mPath) { + int x_prec_inv = (int)(1. / (10. * x_precision_)); + int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); + int numerator = 3 * (int)round(mPath->xCoorCell(3) / (10 * x_precision_)) + + (int)round(mPath->xCoorCell(2) / (10 * x_precision_)) - + (int)round(mPath->xCoorCell(1) / (10 * x_precision_)) - + 3 * (int)round(mPath->xCoorCell(0) / (10 * x_precision_)); + int CELL_HEIGHT_JM = pow(2, 15) / ((int)(10 * CELL_HEIGHT)); + int tanPhi_x4096 = (numerator * CELL_HEIGHT_JM) >> (3 + numberOfBits); + mPath->setTanPhi(tanPhi_x4096 * tanPsi_precision_); + + float XPos = (mPath->xCoorCell(0) + mPath->xCoorCell(1) + mPath->xCoorCell(2) + mPath->xCoorCell(3)) / 4; + mPath->setHorizPos(floor(XPos / (10 * x_precision_)) * 10 * x_precision_); +} + +/** + * 3 HITS cases + */ +void MuonPathAnalyzerPerSL::calcTanPhiXPosChamber3Hits(MuonPathPtr &mPath) { + int layerIdx[2]; + int x_prec_inv = (int)(1. / (10. * x_precision_)); + int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); + + if (mPath->primitive(0)->isValidTime()) + layerIdx[0] = 0; + else + layerIdx[0] = 1; + + if (mPath->primitive(3)->isValidTime()) + layerIdx[1] = 3; + else + layerIdx[1] = 2; + + /*-----------------------------------------------------------------*/ + /*--------------------- Phi angle calculation ---------------------*/ + /*-----------------------------------------------------------------*/ + + int tan_division_denominator_bits = 16; + + int num = + ((int)((int)(x_prec_inv * mPath->xCoorCell(layerIdx[1])) - (int)(x_prec_inv * mPath->xCoorCell(layerIdx[0]))) + << (12 - numberOfBits)); + int denominator = (layerIdx[1] - layerIdx[0]) * CELL_HEIGHT; + int denominator_inv = ((int)(0.5 + pow(2, tan_division_denominator_bits) / float(denominator))); + + float tanPhi = ((num * denominator_inv) >> tan_division_denominator_bits) / ((1. / tanPsi_precision_)); + + mPath->setTanPhi(tanPhi); + + /*-----------------------------------------------------------------*/ + /*----------------- Horizontal coord. calculation -----------------*/ + /*-----------------------------------------------------------------*/ + float XPos = 0; + if (mPath->primitive(0)->isValidTime() and mPath->primitive(3)->isValidTime()) + XPos = (mPath->xCoorCell(0) + mPath->xCoorCell(3)) / 2; + else + XPos = (mPath->xCoorCell(1) + mPath->xCoorCell(2)) / 2; + + mPath->setHorizPos(floor(XPos / (10 * x_precision_)) * 10 * x_precision_); +} + +/** + * Calculate the drift distances of each wire and the horizontal position + */ +void MuonPathAnalyzerPerSL::calcCellDriftAndXcoor(MuonPathPtr &mPath) { + long int drift_speed_new = 889; + long int drift_dist_um_x4; + long int wireHorizPos_x4; + long int pos_mm_x4; + int x_prec_inv = (int)(1. / (10. * x_precision_)); + + for (int i = 0; i <= 3; i++) + if (mPath->primitive(i)->isValidTime()) { + drift_dist_um_x4 = + drift_speed_new * ((long int)mPath->primitive(i)->tdcTimeStampNoOffset() - (long int)mPath->bxTimeValue()); + wireHorizPos_x4 = (long)(mPath->primitive(i)->wireHorizPos() * x_prec_inv); + + if ((mPath->lateralComb())[i] == LEFT) + pos_mm_x4 = wireHorizPos_x4 - (drift_dist_um_x4 >> 10); + else + pos_mm_x4 = wireHorizPos_x4 + (drift_dist_um_x4 >> 10); + + mPath->setXCoorCell(pos_mm_x4 * (10 * x_precision_), i); + mPath->setDriftDistance(((float)(drift_dist_um_x4 >> 10)) * (10 * x_precision_), i); + } +} + +/** + * Calculate the quality estimator of each trayectory. + */ +void MuonPathAnalyzerPerSL::calcChiSquare(MuonPathPtr &mPath) { + int x_prec_inv = (int)(1. / (10. * x_precision_)); + int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); + long int Z_FACTOR[NUM_LAYERS] = {-6, -2, 2, 6}; + for (int i = 0; i < 4; i++) { + Z_FACTOR[i] = Z_FACTOR[i] * (long int)CELL_HEIGHT; + } + long int sum_A = 0, sum_B = 0; + long int chi2_mm2_x1024 = 0; + for (int i = 0; i < 4; i++) { + if (mPath->primitive(i)->isValidTime()) { + sum_A = (((int)(mPath->xCoorCell(i) / (10 * x_precision_))) - ((int)(mPath->horizPos() / (10 * x_precision_)))) + << (14 - numberOfBits); + sum_B = Z_FACTOR[i] * ((int)(mPath->tanPhi() / tanPsi_precision_)); + chi2_mm2_x1024 += (sum_A - sum_B) * (sum_A - sum_B); + } + } + chi2_mm2_x1024 = chi2_mm2_x1024 >> 18; + + mPath->setChiSquare(((double)chi2_mm2_x1024 / 1024.)); +} + +int MuonPathAnalyzerPerSL::omittedHit(int idx) { + switch (idx) { + case 0: + return 3; + case 1: + return 0; + case 2: + return 2; + case 3: + return 1; + } + + return -1; +} diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc new file mode 100644 index 0000000000000..b1150be0cc92d --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc @@ -0,0 +1,1023 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAssociator.h" +#include "L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerPerSL.h" +#include "L1Trigger/DTTriggerPhase2/interface/constants.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace edm; +using namespace std; +using namespace cmsdt; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MuonPathAssociator::MuonPathAssociator(const ParameterSet &pset, edm::ConsumesCollector &iC) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); + clean_chi2_correlation_ = pset.getUntrackedParameter("clean_chi2_correlation"); + use_LSB_ = pset.getUntrackedParameter("use_LSB"); + tanPsi_precision_ = pset.getUntrackedParameter("tanPsi_precision"); + x_precision_ = pset.getUntrackedParameter("x_precision"); + useBX_correlation_ = pset.getUntrackedParameter("useBX_correlation"); + allow_confirmation_ = pset.getUntrackedParameter("allow_confirmation"); + dT0_correlate_TP_ = pset.getUntrackedParameter("dT0_correlate_TP"); + dBX_correlate_TP_ = pset.getUntrackedParameter("dBX_correlate_TP"); + dTanPsi_correlate_TP_ = pset.getUntrackedParameter("dTanPsi_correlate_TP"); + minx_match_2digis_ = pset.getUntrackedParameter("minx_match_2digis"); + chi2corTh_ = pset.getUntrackedParameter("chi2corTh"); + + if (debug_) + LogDebug("MuonPathAssociator") << "MuonPathAssociator: constructor"; + + //shift + int rawId; + shift_filename_ = pset.getParameter("shift_filename"); + std::ifstream ifin3(shift_filename_.fullPath()); + double shift; + if (ifin3.fail()) { + throw cms::Exception("Missing Input File") + << "MuonPathAnalyzerPerSL::MuonPathAnalyzerPerSL() - Cannot find " << shift_filename_.fullPath(); + } + while (ifin3.good()) { + ifin3 >> rawId >> shift; + shiftinfo_[rawId] = shift; + } + + dtGeomH_ = iC.esConsumes(); +} + +MuonPathAssociator::~MuonPathAssociator() { + if (debug_) + LogDebug("MuonPathAssociator") << "MuonPathAssociator: destructor"; +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MuonPathAssociator::initialise(const edm::EventSetup &iEventSetup) { + if (debug_) + LogDebug("MuonPathAssociator") << "MuonPathAssociator::initialiase"; + + const MuonGeometryRecord &geom = iEventSetup.get(); + dtGeo_ = &geom.get(dtGeomH_); +} + +void MuonPathAssociator::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + edm::Handle digis, + std::vector &inMPaths, + std::vector &outMPaths) { + if (dT0_correlate_TP_) + correlateMPaths(digis, inMPaths, outMPaths); + else { + outMPaths.insert(outMPaths.end(), inMPaths.begin(), inMPaths.end()); + } +} + +void MuonPathAssociator::finish() { + if (debug_) + LogDebug("MuonPathAssociator") << "MuonPathAssociator: finish"; +}; + +void MuonPathAssociator::correlateMPaths(edm::Handle dtdigis, + std::vector &inMPaths, + std::vector &outMPaths) { + int x_prec_inv = (int)(1. / (10. * x_precision_)); + int numberOfBits = (int)(round(std::log(x_prec_inv) / std::log(2.))); + + //Silvia's code for correlationg filteredMetaPrimitives + + if (debug_) + LogDebug("MuonPathAssociator") << "starting correlation"; + + for (int wh = -2; wh <= 2; wh++) { //wheel num: -2, -1, 0, +1, +2 + for (int st = 1; st <= 4; st++) { //station num (MB): 1, 2, 3, 4 + for (int se = 1; se <= 14; se++) { //sector number: 1-12, special sectors 13, 14 to account for bigger MB4s + if (se >= 13 && st != 4) + continue; + + DTChamberId ChId(wh, st, se); + DTSuperLayerId sl1Id(wh, st, se, 1); + DTSuperLayerId sl3Id(wh, st, se, 3); + + //filterSL1 + std::vector SL1metaPrimitives; + for (const auto &metaprimitiveIt : inMPaths) { + if (metaprimitiveIt.rawId == sl1Id.rawId()) + SL1metaPrimitives.push_back(metaprimitiveIt); + } + + //filterSL3 + std::vector SL3metaPrimitives; + for (const auto &metaprimitiveIt : inMPaths) { + if (metaprimitiveIt.rawId == sl3Id.rawId()) + SL3metaPrimitives.push_back(metaprimitiveIt); + } + + if (SL1metaPrimitives.empty() and SL3metaPrimitives.empty()) + continue; + + if (debug_) + LogDebug("MuonPathAssociator") << "correlating " << SL1metaPrimitives.size() << " metaPrim in SL1 and " + << SL3metaPrimitives.size() << " in SL3 for " << sl3Id; + + bool at_least_one_correlation = false; + bool at_least_one_SL1_confirmation = false; + bool at_least_one_SL3_confirmation = false; + + bool useFitSL1[SL1metaPrimitives.size()]; + for (unsigned int i = 0; i < SL1metaPrimitives.size(); i++) + useFitSL1[i] = false; + bool useFitSL3[SL3metaPrimitives.size()]; + for (unsigned int i = 0; i < SL3metaPrimitives.size(); i++) + useFitSL3[i] = false; + + //SL1-SL3 + vector chamberMetaPrimitives; + vector confirmedMetaPrimitives; + vector normalMetaPrimitives; + int sl1 = 0; + int sl3 = 0; + for (auto SL1metaPrimitive = SL1metaPrimitives.begin(); SL1metaPrimitive != SL1metaPrimitives.end(); + ++SL1metaPrimitive, sl1++, sl3 = -1) { + if (clean_chi2_correlation_) + at_least_one_correlation = false; + for (auto SL3metaPrimitive = SL3metaPrimitives.begin(); SL3metaPrimitive != SL3metaPrimitives.end(); + ++SL3metaPrimitive, sl3++) { + if (std::abs(SL1metaPrimitive->tanPhi - SL3metaPrimitive->tanPhi) > dTanPsi_correlate_TP_) + continue; //TanPsi match, SliceTest only + if (useBX_correlation_) { + if (abs(round(SL1metaPrimitive->t0 / (float)LHC_CLK_FREQ) - + round(SL3metaPrimitive->t0 / (float)LHC_CLK_FREQ)) > dBX_correlate_TP_) + continue; //BX match + } else { + if (std::abs(SL1metaPrimitive->t0 - SL3metaPrimitive->t0) >= dT0_correlate_TP_) + continue; //time match + } + long int PosSL1 = (int)round(10 * SL1metaPrimitive->x / (10 * x_precision_)); + long int PosSL3 = (int)round(10 * SL3metaPrimitive->x / (10 * x_precision_)); + double NewSlope = -999.; + if (use_LSB_) { + long int newConstant = (int)(139.5 * 4); + long int difPos_mm_x4 = PosSL3 - PosSL1; + long int tanPsi_x4096_x128 = (difPos_mm_x4)*newConstant; + long int tanPsi_x4096 = tanPsi_x4096_x128 / ((long int)pow(2, 5 + numberOfBits)); + if (tanPsi_x4096 < 0 && tanPsi_x4096_x128 % ((long int)pow(2, 5 + numberOfBits)) != 0) + tanPsi_x4096--; + NewSlope = -tanPsi_x4096 * tanPsi_precision_; + } + double MeanT0 = (SL1metaPrimitive->t0 + SL3metaPrimitive->t0) / 2; + double MeanPos = (PosSL3 + PosSL1) / (2. / (x_precision_)); + if (use_LSB_) { + MeanPos = floor(round(10. * (MeanPos / x_precision_)) * 0.1) * x_precision_; + } + + DTSuperLayerId SLId1(SL1metaPrimitive->rawId); + DTSuperLayerId SLId3(SL3metaPrimitive->rawId); + DTWireId wireId1(SLId1, 2, 1); + DTWireId wireId3(SLId3, 2, 1); + + int wi[8], tdc[8], lat[8]; + wi[0] = SL1metaPrimitive->wi1; + tdc[0] = SL1metaPrimitive->tdc1; + lat[0] = SL1metaPrimitive->lat1; + wi[1] = SL1metaPrimitive->wi2; + tdc[1] = SL1metaPrimitive->tdc2; + lat[1] = SL1metaPrimitive->lat2; + wi[2] = SL1metaPrimitive->wi3; + tdc[2] = SL1metaPrimitive->tdc3; + lat[2] = SL1metaPrimitive->lat3; + wi[3] = SL1metaPrimitive->wi4; + tdc[3] = SL1metaPrimitive->tdc4; + lat[3] = SL1metaPrimitive->lat4; + wi[4] = SL3metaPrimitive->wi1; + tdc[4] = SL3metaPrimitive->tdc1; + lat[4] = SL3metaPrimitive->lat1; + wi[5] = SL3metaPrimitive->wi2; + tdc[5] = SL3metaPrimitive->tdc2; + lat[5] = SL3metaPrimitive->lat2; + wi[6] = SL3metaPrimitive->wi3; + tdc[6] = SL3metaPrimitive->tdc3; + lat[6] = SL3metaPrimitive->lat3; + wi[7] = SL3metaPrimitive->wi4; + tdc[7] = SL3metaPrimitive->tdc4; + lat[7] = SL3metaPrimitive->lat4; + + long int chi2 = 0; + + long int CH_CENTER_TO_MID_SL_P = (long int)(117.5 * 4); + long int Z_FACTOR_CORR[8] = {-6, -2, 2, 6, -6, -2, 2, 6}; + + for (int i = 0; i < 8; i++) { + int sign = 2 * (i / 4) - 1; + Z_FACTOR_CORR[i] = Z_FACTOR_CORR[i] * CELL_HEIGHT + CH_CENTER_TO_MID_SL_P * sign; + } + long int sum_A, sum_B; + for (int i = 0; i < 8; i++) { + long int shift, slTime; + if (i / 4 == 0) { + shift = round(shiftinfo_[wireId1.rawId()] / x_precision_); + slTime = SL1metaPrimitive->t0; + } else { + shift = round(shiftinfo_[wireId3.rawId()] / x_precision_); + slTime = SL3metaPrimitive->t0; + } + if (wi[i] != -1) { + long int drift_speed_new = 889; + long int drift_dist_um_x4 = drift_speed_new * (((long int)tdc[i]) - slTime); + long int wireHorizPos_x4 = (42 * wi[i] + ((i + 1) % 2) * 21) / (10 * x_precision_); + long int pos_mm_x4; + + if (lat[i] == 0) { + pos_mm_x4 = wireHorizPos_x4 - (drift_dist_um_x4 >> 10); + } else { + pos_mm_x4 = wireHorizPos_x4 + (drift_dist_um_x4 >> 10); + } + sum_A = shift + pos_mm_x4 - (long int)round(MeanPos / x_precision_); + sum_A = sum_A << (14 - numberOfBits); + sum_B = Z_FACTOR_CORR[i] * (long int)round(-NewSlope / tanPsi_precision_); + chi2 += ((sum_A - sum_B) * (sum_A - sum_B)) >> 2; + } + } + + double newChi2 = (double)(chi2 >> 16) / (1024. * 100.); + + if (newChi2 > chi2corTh_) + continue; + + // Fill the used vectors + useFitSL1[sl1] = true; + useFitSL3[sl3] = true; + + int quality = 0; + if (SL3metaPrimitive->quality <= 2 and SL1metaPrimitive->quality <= 2) + quality = 6; + + if ((SL3metaPrimitive->quality >= 3 && SL1metaPrimitive->quality <= 2) or + (SL1metaPrimitive->quality >= 3 && SL3metaPrimitive->quality <= 2)) + quality = 8; + + if (SL3metaPrimitive->quality >= 3 && SL1metaPrimitive->quality >= 3) + quality = 9; + + double z = 0; + if (ChId.station() >= 3) + z = -1.8; + GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal( + LocalPoint(MeanPos, 0., z)); //Jm_x is already extrapolated to the middle of the SL + int thisec = ChId.sector(); + if (se == 13) + thisec = 4; + if (se == 14) + thisec = 10; + double phi = jm_x_cmssw_global.phi() - 0.5235988 * (thisec - 1); + double psi = atan(NewSlope); + double phiB = hasPosRF(ChId.wheel(), ChId.sector()) ? psi - phi : -psi - phi; + + if (!clean_chi2_correlation_) + outMPaths.emplace_back(ChId.rawId(), + MeanT0, + MeanPos, + NewSlope, + phi, + phiB, + newChi2, + quality, + SL1metaPrimitive->wi1, + SL1metaPrimitive->tdc1, + SL1metaPrimitive->lat1, + SL1metaPrimitive->wi2, + SL1metaPrimitive->tdc2, + SL1metaPrimitive->lat2, + SL1metaPrimitive->wi3, + SL1metaPrimitive->tdc3, + SL1metaPrimitive->lat3, + SL1metaPrimitive->wi4, + SL1metaPrimitive->tdc4, + SL1metaPrimitive->lat4, + SL3metaPrimitive->wi1, + SL3metaPrimitive->tdc1, + SL3metaPrimitive->lat1, + SL3metaPrimitive->wi2, + SL3metaPrimitive->tdc2, + SL3metaPrimitive->lat2, + SL3metaPrimitive->wi3, + SL3metaPrimitive->tdc3, + SL3metaPrimitive->lat3, + SL3metaPrimitive->wi4, + SL3metaPrimitive->tdc4, + SL3metaPrimitive->lat4); + else + chamberMetaPrimitives.emplace_back(ChId.rawId(), + MeanT0, + MeanPos, + NewSlope, + phi, + phiB, + newChi2, + quality, + SL1metaPrimitive->wi1, + SL1metaPrimitive->tdc1, + SL1metaPrimitive->lat1, + SL1metaPrimitive->wi2, + SL1metaPrimitive->tdc2, + SL1metaPrimitive->lat2, + SL1metaPrimitive->wi3, + SL1metaPrimitive->tdc3, + SL1metaPrimitive->lat3, + SL1metaPrimitive->wi4, + SL1metaPrimitive->tdc4, + SL1metaPrimitive->lat4, + SL3metaPrimitive->wi1, + SL3metaPrimitive->tdc1, + SL3metaPrimitive->lat1, + SL3metaPrimitive->wi2, + SL3metaPrimitive->tdc2, + SL3metaPrimitive->lat2, + SL3metaPrimitive->wi3, + SL3metaPrimitive->tdc3, + SL3metaPrimitive->lat3, + SL3metaPrimitive->wi4, + SL3metaPrimitive->tdc4, + SL3metaPrimitive->lat4); + + at_least_one_correlation = true; + } + + if (at_least_one_correlation == false && + allow_confirmation_ == true) { //no correlation was found, trying with pairs of two digis in the other SL + int matched_digis = 0; + double minx = minx_match_2digis_; + double min2x = minx_match_2digis_; + int best_tdc = -1; + int next_tdc = -1; + int best_wire = -1; + int next_wire = -1; + int best_layer = -1; + int next_layer = -1; + int best_lat = -1; + int next_lat = -1; + int lat = -1; + + for (const auto &dtLayerId_It : *dtdigis) { + const DTLayerId dtLId = dtLayerId_It.first; + const DTSuperLayerId &dtSLId(dtLId); + if (dtSLId.rawId() != sl3Id.rawId()) + continue; + double l_shift = 0; + if (dtLId.layer() == 4) + l_shift = X_POS_L4; + else if (dtLId.layer() == 3) + l_shift = X_POS_L3; + else if (dtLId.layer() == 2) + l_shift = -1 * X_POS_L3; + else if (dtLId.layer() == 1) + l_shift = -1 * X_POS_L4; + double x_inSL3 = SL1metaPrimitive->x - SL1metaPrimitive->tanPhi * (23.5 + l_shift); + for (auto digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second; ++digiIt) { + DTWireId wireId(dtLId, (*digiIt).wire()); + int x_wire = shiftinfo_[wireId.rawId()] + ((*digiIt).time() - SL1metaPrimitive->t0) * 0.00543; + int x_wire_left = shiftinfo_[wireId.rawId()] - ((*digiIt).time() - SL1metaPrimitive->t0) * 0.00543; + lat = 1; + if (std::abs(x_inSL3 - x_wire) > std::abs(x_inSL3 - x_wire_left)) { + x_wire = x_wire_left; //choose the closest laterality + lat = 0; + } + if (std::abs(x_inSL3 - x_wire) < minx) { + minx = std::abs(x_inSL3 - x_wire); + next_wire = best_wire; + next_tdc = best_tdc; + next_layer = best_layer; + next_lat = best_lat; + + best_wire = (*digiIt).wire(); + best_tdc = (*digiIt).time(); + best_layer = dtLId.layer(); + best_lat = lat; + matched_digis++; + } else if ((std::abs(x_inSL3 - x_wire) >= minx) && (std::abs(x_inSL3 - x_wire) < min2x)) { + min2x = std::abs(x_inSL3 - x_wire); + next_wire = (*digiIt).wire(); + next_tdc = (*digiIt).time(); + next_layer = dtLId.layer(); + next_lat = lat; + matched_digis++; + } + } + } + if (matched_digis >= 2 and best_layer != -1 and next_layer != -1) { + int new_quality = 7; + if (SL1metaPrimitive->quality <= 2) + new_quality = 5; + + int wi1 = -1; + int tdc1 = -1; + int lat1 = -1; + int wi2 = -1; + int tdc2 = -1; + int lat2 = -1; + int wi3 = -1; + int tdc3 = -1; + int lat3 = -1; + int wi4 = -1; + int tdc4 = -1; + int lat4 = -1; + + if (next_layer == 1) { + wi1 = next_wire; + tdc1 = next_tdc; + lat1 = next_lat; + } + if (next_layer == 2) { + wi2 = next_wire; + tdc2 = next_tdc; + lat2 = next_lat; + } + if (next_layer == 3) { + wi3 = next_wire; + tdc3 = next_tdc; + lat3 = next_lat; + } + if (next_layer == 4) { + wi4 = next_wire; + tdc4 = next_tdc; + lat4 = next_lat; + } + + if (best_layer == 1) { + wi1 = best_wire; + tdc1 = best_tdc; + lat1 = best_lat; + } + if (best_layer == 2) { + wi2 = best_wire; + tdc2 = best_tdc; + lat2 = best_lat; + } + if (best_layer == 3) { + wi3 = best_wire; + tdc3 = best_tdc; + lat3 = best_lat; + } + if (best_layer == 4) { + wi4 = best_wire; + tdc4 = best_tdc; + lat4 = best_lat; + } + + if (!clean_chi2_correlation_) + outMPaths.emplace_back(metaPrimitive({ChId.rawId(), + SL1metaPrimitive->t0, + SL1metaPrimitive->x, + SL1metaPrimitive->tanPhi, + SL1metaPrimitive->phi, + SL1metaPrimitive->phiB, + SL1metaPrimitive->chi2, + new_quality, + SL1metaPrimitive->wi1, + SL1metaPrimitive->tdc1, + SL1metaPrimitive->lat1, + SL1metaPrimitive->wi2, + SL1metaPrimitive->tdc2, + SL1metaPrimitive->lat2, + SL1metaPrimitive->wi3, + SL1metaPrimitive->tdc3, + SL1metaPrimitive->lat3, + SL1metaPrimitive->wi4, + SL1metaPrimitive->tdc4, + SL1metaPrimitive->lat4, + wi1, + tdc1, + lat1, + wi2, + tdc2, + lat2, + wi3, + tdc3, + lat3, + wi4, + tdc4, + lat4, + -1})); + else + confirmedMetaPrimitives.emplace_back(metaPrimitive({ChId.rawId(), + SL1metaPrimitive->t0, + SL1metaPrimitive->x, + SL1metaPrimitive->tanPhi, + SL1metaPrimitive->phi, + SL1metaPrimitive->phiB, + SL1metaPrimitive->chi2, + new_quality, + SL1metaPrimitive->wi1, + SL1metaPrimitive->tdc1, + SL1metaPrimitive->lat1, + SL1metaPrimitive->wi2, + SL1metaPrimitive->tdc2, + SL1metaPrimitive->lat2, + SL1metaPrimitive->wi3, + SL1metaPrimitive->tdc3, + SL1metaPrimitive->lat3, + SL1metaPrimitive->wi4, + SL1metaPrimitive->tdc4, + SL1metaPrimitive->lat4, + wi1, + tdc1, + lat1, + wi2, + tdc2, + lat2, + wi3, + tdc3, + lat3, + wi4, + tdc4, + lat4, + -1})); + useFitSL1[sl1] = true; + at_least_one_SL1_confirmation = true; + } + } + } + + //finish SL1-SL3 + + //SL3-SL1 + sl3 = 0; + for (auto SL3metaPrimitive = SL3metaPrimitives.begin(); SL3metaPrimitive != SL3metaPrimitives.end(); + ++SL3metaPrimitive, sl3++) { + if (useFitSL3[sl3]) + continue; + if ((at_least_one_correlation == false || clean_chi2_correlation_) && + allow_confirmation_) { //no correlation was found, trying with pairs of two digis in the other SL + + int matched_digis = 0; + double minx = minx_match_2digis_; + double min2x = minx_match_2digis_; + int best_tdc = -1; + int next_tdc = -1; + int best_wire = -1; + int next_wire = -1; + int best_layer = -1; + int next_layer = -1; + int best_lat = -1; + int next_lat = -1; + int lat = -1; + + for (const auto &dtLayerId_It : *dtdigis) { + const DTLayerId dtLId = dtLayerId_It.first; + const DTSuperLayerId &dtSLId(dtLId); + if (dtSLId.rawId() != sl1Id.rawId()) + continue; + double l_shift = 0; + if (dtLId.layer() == 4) + l_shift = 1.95; + if (dtLId.layer() == 3) + l_shift = 0.65; + if (dtLId.layer() == 2) + l_shift = -0.65; + if (dtLId.layer() == 1) + l_shift = -1.95; + double x_inSL1 = SL3metaPrimitive->x + SL3metaPrimitive->tanPhi * (23.5 - l_shift); + for (auto digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second; ++digiIt) { + DTWireId wireId(dtLId, (*digiIt).wire()); + int x_wire = shiftinfo_[wireId.rawId()] + ((*digiIt).time() - SL3metaPrimitive->t0) * 0.00543; + int x_wire_left = shiftinfo_[wireId.rawId()] - ((*digiIt).time() - SL3metaPrimitive->t0) * 0.00543; + lat = 1; + if (std::abs(x_inSL1 - x_wire) > std::abs(x_inSL1 - x_wire_left)) { + x_wire = x_wire_left; //choose the closest laterality + lat = 0; + } + if (std::abs(x_inSL1 - x_wire) < minx) { + minx = std::abs(x_inSL1 - x_wire); + next_wire = best_wire; + next_tdc = best_tdc; + next_layer = best_layer; + next_lat = best_lat; + + best_wire = (*digiIt).wire(); + best_tdc = (*digiIt).time(); + best_layer = dtLId.layer(); + best_lat = lat; + matched_digis++; + } else if ((std::abs(x_inSL1 - x_wire) >= minx) && (std::abs(x_inSL1 - x_wire) < min2x)) { + minx = std::abs(x_inSL1 - x_wire); + next_wire = (*digiIt).wire(); + next_tdc = (*digiIt).time(); + next_layer = dtLId.layer(); + next_lat = lat; + matched_digis++; + } + } + } + if (matched_digis >= 2 and best_layer != -1 and next_layer != -1) { + int new_quality = 7; + if (SL3metaPrimitive->quality <= 2) + new_quality = 5; + + int wi1 = -1; + int tdc1 = -1; + int lat1 = -1; + int wi2 = -1; + int tdc2 = -1; + int lat2 = -1; + int wi3 = -1; + int tdc3 = -1; + int lat3 = -1; + int wi4 = -1; + int tdc4 = -1; + int lat4 = -1; + + if (next_layer == 1) { + wi1 = next_wire; + tdc1 = next_tdc; + lat1 = next_lat; + } + if (next_layer == 2) { + wi2 = next_wire; + tdc2 = next_tdc; + lat2 = next_lat; + } + if (next_layer == 3) { + wi3 = next_wire; + tdc3 = next_tdc; + lat3 = next_lat; + } + if (next_layer == 4) { + wi4 = next_wire; + tdc4 = next_tdc; + lat4 = next_lat; + } + + if (best_layer == 1) { + wi1 = best_wire; + tdc1 = best_tdc; + lat1 = best_lat; + } + if (best_layer == 2) { + wi2 = best_wire; + tdc2 = best_tdc; + lat2 = best_lat; + } + if (best_layer == 3) { + wi3 = best_wire; + tdc3 = best_tdc; + lat3 = best_lat; + } + if (best_layer == 4) { + wi4 = best_wire; + tdc4 = best_tdc; + lat4 = best_lat; + } + + if (!clean_chi2_correlation_) + outMPaths.push_back(metaPrimitive({ChId.rawId(), + SL3metaPrimitive->t0, + SL3metaPrimitive->x, + SL3metaPrimitive->tanPhi, + SL3metaPrimitive->phi, + SL3metaPrimitive->phiB, + SL3metaPrimitive->chi2, + new_quality, + wi1, + tdc1, + lat1, + wi2, + tdc2, + lat2, + wi3, + tdc3, + lat3, + wi4, + tdc4, + lat4, + SL3metaPrimitive->wi1, + SL3metaPrimitive->tdc1, + SL3metaPrimitive->lat1, + SL3metaPrimitive->wi2, + SL3metaPrimitive->tdc2, + SL3metaPrimitive->lat2, + SL3metaPrimitive->wi3, + SL3metaPrimitive->tdc3, + SL3metaPrimitive->lat3, + SL3metaPrimitive->wi4, + SL3metaPrimitive->tdc4, + SL3metaPrimitive->lat4, + -1})); + else + confirmedMetaPrimitives.push_back(metaPrimitive({ChId.rawId(), + SL3metaPrimitive->t0, + SL3metaPrimitive->x, + SL3metaPrimitive->tanPhi, + SL3metaPrimitive->phi, + SL3metaPrimitive->phiB, + SL3metaPrimitive->chi2, + new_quality, + wi1, + tdc1, + lat1, + wi2, + tdc2, + lat2, + wi3, + tdc3, + lat3, + wi4, + tdc4, + lat4, + SL3metaPrimitive->wi1, + SL3metaPrimitive->tdc1, + SL3metaPrimitive->lat1, + SL3metaPrimitive->wi2, + SL3metaPrimitive->tdc2, + SL3metaPrimitive->lat2, + SL3metaPrimitive->wi3, + SL3metaPrimitive->tdc3, + SL3metaPrimitive->lat3, + SL3metaPrimitive->wi4, + SL3metaPrimitive->tdc4, + SL3metaPrimitive->lat4, + -1})); + useFitSL3[sl3] = true; + at_least_one_SL3_confirmation = true; + } + } + } + // Start correlation cleaning + if (clean_chi2_correlation_) { + if (debug_) + LogDebug("MuonPathAssociator") << "Pushing back correlated MPs to the MPs collection"; + removeSharingFits(chamberMetaPrimitives, outMPaths); + } + if (clean_chi2_correlation_) { + if (debug_) + LogDebug("MuonPathAssociator") << "Pushing back confirmed MPs to the complete vector"; + removeSharingHits(confirmedMetaPrimitives, chamberMetaPrimitives, outMPaths); + } + + //finish SL3-SL1 + if (at_least_one_correlation == false || clean_chi2_correlation_) { + if (debug_ && !at_least_one_correlation) + LogDebug("MuonPathAssociator") + << "correlation we found zero correlations, adding both collections as they are to the outMPaths"; + if (debug_) + LogDebug("MuonPathAssociator") + << "correlation sizes:" << SL1metaPrimitives.size() << " " << SL3metaPrimitives.size(); + if (at_least_one_SL1_confirmation == false || clean_chi2_correlation_) { + sl1 = 0; + for (auto SL1metaPrimitive = SL1metaPrimitives.begin(); SL1metaPrimitive != SL1metaPrimitives.end(); + ++SL1metaPrimitive, sl1++) { + if (useFitSL1[sl1]) + continue; + + DTSuperLayerId SLId(SL1metaPrimitive->rawId); + DTChamberId(SLId.wheel(), SLId.station(), SLId.sector()); + metaPrimitive newSL1metaPrimitive = {ChId.rawId(), + SL1metaPrimitive->t0, + SL1metaPrimitive->x, + SL1metaPrimitive->tanPhi, + SL1metaPrimitive->phi, + SL1metaPrimitive->phiB, + SL1metaPrimitive->chi2, + SL1metaPrimitive->quality, + SL1metaPrimitive->wi1, + SL1metaPrimitive->tdc1, + SL1metaPrimitive->lat1, + SL1metaPrimitive->wi2, + SL1metaPrimitive->tdc2, + SL1metaPrimitive->lat2, + SL1metaPrimitive->wi3, + SL1metaPrimitive->tdc3, + SL1metaPrimitive->lat3, + SL1metaPrimitive->wi4, + SL1metaPrimitive->tdc4, + SL1metaPrimitive->lat4, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1}; + + bool ok = true; + for (auto &metaPrimitive : chamberMetaPrimitives) { + if (!isNotAPrimo(newSL1metaPrimitive, metaPrimitive)) { + ok = false; + break; + } + } + if (!ok) + continue; + + if (!clean_chi2_correlation_) + outMPaths.push_back(newSL1metaPrimitive); + else + normalMetaPrimitives.push_back(newSL1metaPrimitive); + } + } + if (at_least_one_SL3_confirmation == false || clean_chi2_correlation_) { + sl3 = 0; + for (auto SL3metaPrimitive = SL3metaPrimitives.begin(); SL3metaPrimitive != SL3metaPrimitives.end(); + ++SL3metaPrimitive, sl3++) { + if (useFitSL3[sl3]) + continue; + DTSuperLayerId SLId(SL3metaPrimitive->rawId); + DTChamberId(SLId.wheel(), SLId.station(), SLId.sector()); + metaPrimitive newSL3metaPrimitive = {ChId.rawId(), + SL3metaPrimitive->t0, + SL3metaPrimitive->x, + SL3metaPrimitive->tanPhi, + SL3metaPrimitive->phi, + SL3metaPrimitive->phiB, + SL3metaPrimitive->chi2, + SL3metaPrimitive->quality, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + SL3metaPrimitive->wi1, + SL3metaPrimitive->tdc1, + SL3metaPrimitive->lat1, + SL3metaPrimitive->wi2, + SL3metaPrimitive->tdc2, + SL3metaPrimitive->lat2, + SL3metaPrimitive->wi3, + SL3metaPrimitive->tdc3, + SL3metaPrimitive->lat3, + SL3metaPrimitive->wi4, + SL3metaPrimitive->tdc4, + SL3metaPrimitive->lat4, + -1}; + + if (!clean_chi2_correlation_) + outMPaths.push_back(newSL3metaPrimitive); + else + normalMetaPrimitives.push_back(newSL3metaPrimitive); + } + } + } + + SL1metaPrimitives.clear(); + SL1metaPrimitives.erase(SL1metaPrimitives.begin(), SL1metaPrimitives.end()); + SL3metaPrimitives.clear(); + SL3metaPrimitives.erase(SL3metaPrimitives.begin(), SL3metaPrimitives.end()); + + vector auxMetaPrimitives; + if (clean_chi2_correlation_) { + if (debug_) + LogDebug("MuonPathAssociator") << "Pushing back normal MPs to the auxiliar vector"; + removeSharingHits(normalMetaPrimitives, confirmedMetaPrimitives, auxMetaPrimitives); + } + if (clean_chi2_correlation_) { + if (debug_) + LogDebug("MuonPathAssociator") << "Pushing back normal MPs to the MPs collection"; + removeSharingHits(auxMetaPrimitives, chamberMetaPrimitives, outMPaths); + } + } + } + } +} + +void MuonPathAssociator::removeSharingFits(vector &chamberMPaths, vector &allMPaths) { + bool useFit[chamberMPaths.size()]; + for (unsigned int i = 0; i < chamberMPaths.size(); i++) { + useFit[i] = true; + } + for (unsigned int i = 0; i < chamberMPaths.size(); i++) { + if (debug_) + LogDebug("MuonPathAssociator") << "Looking at prim" << i; + if (!useFit[i]) + continue; + for (unsigned int j = i + 1; j < chamberMPaths.size(); j++) { + if (debug_) + LogDebug("MuonPathAssociator") << "Comparing with prim " << j; + if (!useFit[j]) + continue; + metaPrimitive first = chamberMPaths[i]; + metaPrimitive second = chamberMPaths[j]; + if (shareFit(first, second)) { + if (first.quality > second.quality) + useFit[j] = false; + else if (first.quality < second.quality) + useFit[i] = false; + else { + if (first.chi2 < second.chi2) + useFit[j] = false; + else { + useFit[i] = false; + break; + } + } + } + } + if (useFit[i]) { + if (debug_) + printmPC(chamberMPaths[i]); + allMPaths.push_back(chamberMPaths[i]); + } + } + if (debug_) + LogDebug("MuonPathAssociator") << "---Swapping chamber---"; +} + +void MuonPathAssociator::removeSharingHits(std::vector &firstMPaths, + std::vector &secondMPaths, + std::vector &allMPaths) { + for (auto &firstMP : firstMPaths) { + if (debug_) + LogDebug("MuonPathAssociator") << "----------------------------------"; + if (debug_) + LogDebug("MuonPathAssociator") << "Turn for "; + if (debug_) + printmPC(firstMP); + bool ok = true; + for (auto &secondMP : secondMPaths) { + if (debug_) + LogDebug("MuonPathAssociator") << "Comparing with "; + if (debug_) + printmPC(secondMP); + if (!isNotAPrimo(firstMP, secondMP)) { + ok = false; + break; + } + } + if (ok) { + allMPaths.push_back(firstMP); + if (debug_) + printmPC(firstMP); + } + if (debug_) + LogDebug("MuonPathAssociator") << "----------------------------------"; + } +} + +bool MuonPathAssociator::shareFit(metaPrimitive first, metaPrimitive second) { + bool lay1 = (first.wi1 == second.wi1) && (first.tdc1 = second.tdc1); + bool lay2 = (first.wi2 == second.wi2) && (first.tdc2 = second.tdc2); + bool lay3 = (first.wi3 == second.wi3) && (first.tdc3 = second.tdc3); + bool lay4 = (first.wi4 == second.wi4) && (first.tdc4 = second.tdc4); + bool lay5 = (first.wi5 == second.wi5) && (first.tdc5 = second.tdc5); + bool lay6 = (first.wi6 == second.wi6) && (first.tdc6 = second.tdc6); + bool lay7 = (first.wi7 == second.wi7) && (first.tdc7 = second.tdc7); + bool lay8 = (first.wi8 == second.wi8) && (first.tdc8 = second.tdc8); + + if (lay1 && lay2 && lay3 && lay4) { + if (lay5 || lay6 || lay7 || lay8) + return true; + else + return false; + } else if (lay5 && lay6 && lay7 && lay8) { + if (lay1 || lay2 || lay3 || lay4) + return true; + else + return false; + } else + return false; +} + +bool MuonPathAssociator::isNotAPrimo(metaPrimitive first, metaPrimitive second) { + int hitsSL1 = (first.wi1 != -1) + (first.wi2 != -1) + (first.wi3 != -1) + (first.wi4 != -1); + int hitsSL3 = (first.wi5 != -1) + (first.wi6 != -1) + (first.wi7 != -1) + (first.wi8 != -1); + + bool lay1 = (first.wi1 == second.wi1) && (first.tdc1 = second.tdc1) && (first.wi1 != -1); + bool lay2 = (first.wi2 == second.wi2) && (first.tdc2 = second.tdc2) && (first.wi2 != -1); + bool lay3 = (first.wi3 == second.wi3) && (first.tdc3 = second.tdc3) && (first.wi3 != -1); + bool lay4 = (first.wi4 == second.wi4) && (first.tdc4 = second.tdc4) && (first.wi4 != -1); + bool lay5 = (first.wi5 == second.wi5) && (first.tdc5 = second.tdc5) && (first.wi5 != -1); + bool lay6 = (first.wi6 == second.wi6) && (first.tdc6 = second.tdc6) && (first.wi6 != -1); + bool lay7 = (first.wi7 == second.wi7) && (first.tdc7 = second.tdc7) && (first.wi7 != -1); + bool lay8 = (first.wi8 == second.wi8) && (first.tdc8 = second.tdc8) && (first.wi8 != -1); + + return (((!lay1 && !lay2 && !lay3 && !lay4) || hitsSL1 < 3) && ((!lay5 && !lay6 && !lay7 && !lay8) || hitsSL3 < 3)); +} + +void MuonPathAssociator::printmPC(metaPrimitive mP) { + DTChamberId ChId(mP.rawId); + LogDebug("MuonPathAssociator") << ChId << "\t" + << " " << setw(2) << left << mP.wi1 << " " << setw(2) << left << mP.wi2 << " " + << setw(2) << left << mP.wi3 << " " << setw(2) << left << mP.wi4 << " " << setw(2) + << left << mP.wi5 << " " << setw(2) << left << mP.wi6 << " " << setw(2) << left + << mP.wi7 << " " << setw(2) << left << mP.wi8 << " " << setw(5) << left << mP.tdc1 + << " " << setw(5) << left << mP.tdc2 << " " << setw(5) << left << mP.tdc3 << " " + << setw(5) << left << mP.tdc4 << " " << setw(5) << left << mP.tdc5 << " " << setw(5) + << left << mP.tdc6 << " " << setw(5) << left << mP.tdc7 << " " << setw(5) << left + << mP.tdc8 << " " << setw(2) << left << mP.lat1 << " " << setw(2) << left << mP.lat2 + << " " << setw(2) << left << mP.lat3 << " " << setw(2) << left << mP.lat4 << " " + << setw(2) << left << mP.lat5 << " " << setw(2) << left << mP.lat6 << " " << setw(2) + << left << mP.lat7 << " " << setw(2) << left << mP.lat8 << " " << setw(10) << right + << mP.x << " " << setw(9) << left << mP.tanPhi << " " << setw(5) << left << mP.t0 + << " " << setw(13) << left << mP.chi2 << " \n"; +} diff --git a/L1Trigger/DTTriggerPhase2/src/PseudoBayesGrouping.cc b/L1Trigger/DTTriggerPhase2/src/PseudoBayesGrouping.cc new file mode 100644 index 0000000000000..1d0974633d718 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/PseudoBayesGrouping.cc @@ -0,0 +1,471 @@ +#include + +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "TFile.h" + +#include "L1Trigger/DTTriggerPhase2/interface/PseudoBayesGrouping.h" + +using namespace edm; +using namespace std; +using namespace cmsdt; +using namespace dtbayesam; +// ============================================================================ +// Constructors and destructor +// ============================================================================ +PseudoBayesGrouping::PseudoBayesGrouping(const ParameterSet& pset, edm::ConsumesCollector& iC) + : MotherGrouping(pset, iC) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); + pattern_filename_ = pset.getUntrackedParameter("pattern_filename").fullPath(); + minNLayerHits_ = pset.getUntrackedParameter("minNLayerHits"); + minSingleSLHitsMax_ = pset.getUntrackedParameter("minSingleSLHitsMax"); + minSingleSLHitsMin_ = pset.getUntrackedParameter("minSingleSLHitsMin"); + allowedVariance_ = pset.getUntrackedParameter("allowedVariance"); + allowDuplicates_ = pset.getUntrackedParameter("allowDuplicates"); + allowUncorrelatedPatterns_ = pset.getUntrackedParameter("allowUncorrelatedPatterns"); + minUncorrelatedHits_ = pset.getUntrackedParameter("minUncorrelatedHits"); + saveOnPlace_ = pset.getUntrackedParameter("saveOnPlace"); + setLateralities_ = pset.getUntrackedParameter("setLateralities"); + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping:: constructor"; +} + +PseudoBayesGrouping::~PseudoBayesGrouping() { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping:: destructor"; + for (std::vector::iterator pat_it = allPatterns_.begin(); pat_it != allPatterns_.end(); pat_it++) { + delete (*pat_it); + } +} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void PseudoBayesGrouping::initialise(const edm::EventSetup& iEventSetup) { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::initialiase"; + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::initialiase using patterns file " << pattern_filename_; + nPatterns_ = 0; + //Load patterns from pattern root file with expected hits information + TFile* f = TFile::Open(TString(pattern_filename_), "READ"); + std::vector>>* pattern_reader = + (std::vector>>*)f->Get("allPatterns"); + for (std::vector>>::iterator itPattern = (*pattern_reader).begin(); + itPattern != (*pattern_reader).end(); + ++itPattern) { + //Loops over all patterns in the loop and constructs the Pattern object for each one + LoadPattern(itPattern); + } + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::initialiase Total number of loaded patterns: " + << nPatterns_; + f->Close(); + delete f; + + prelimMatches_ = std::make_unique(); + allMatches_ = std::make_unique(); + finalMatches_ = std::make_unique(); +} + +void PseudoBayesGrouping::LoadPattern(std::vector>>::iterator itPattern) { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::LoadPattern Loading patterns seeded by: " + << itPattern->at(0).at(0) << ", " << itPattern->at(0).at(1) << ", " + << itPattern->at(0).at(2) << ", "; + + DTPattern p; + // for (auto itHits = itPattern->begin(); itHits != itPattern->end(); ++itHits) { + bool is_seed = true; + for (const auto& itHits : *itPattern) { + //First entry is the seeding information + if (is_seed) { + p = DTPattern(itHits.at(0), itHits.at(1), itHits.at(2)); + is_seed = false; + } + //Other entries are the hits information + else { + if (itHits.begin() == itHits.end()) + continue; + //We need to correct the geometry from pattern generation to reconstruction as they use slightly displaced basis + else if (itHits.at(0) % 2 == 0) { + p.addHit(std::make_tuple(itHits.at(0), itHits.at(1), itHits.at(2))); + } else if (itHits.at(0) % 2 == 1) { + p.addHit(std::make_tuple(itHits.at(0), itHits.at(1) - 1, itHits.at(2))); + } + } + } + //Classified by seeding layers for optimized search later + //TODO::This can be vastly improved using std::bitset<8>, for example + if (p.sl1() == 0) { + if (p.sl2() == 7) + L0L7Patterns_.push_back(&p); + if (p.sl2() == 6) + L0L6Patterns_.push_back(&p); + if (p.sl2() == 5) + L0L5Patterns_.push_back(&p); + if (p.sl2() == 4) + L0L4Patterns_.push_back(&p); + if (p.sl2() == 3) + L0L3Patterns_.push_back(&p); + if (p.sl2() == 2) + L0L2Patterns_.push_back(&p); + if (p.sl2() == 1) + L0L1Patterns_.push_back(&p); + } + if (p.sl1() == 1) { + if (p.sl2() == 7) + L1L7Patterns_.push_back(&p); + if (p.sl2() == 6) + L1L6Patterns_.push_back(&p); + if (p.sl2() == 5) + L1L5Patterns_.push_back(&p); + if (p.sl2() == 4) + L1L4Patterns_.push_back(&p); + if (p.sl2() == 3) + L1L3Patterns_.push_back(&p); + if (p.sl2() == 2) + L1L2Patterns_.push_back(&p); + } + if (p.sl1() == 2) { + if (p.sl2() == 7) + L2L7Patterns_.push_back(&p); + if (p.sl2() == 6) + L2L6Patterns_.push_back(&p); + if (p.sl2() == 5) + L2L5Patterns_.push_back(&p); + if (p.sl2() == 4) + L2L4Patterns_.push_back(&p); + if (p.sl2() == 3) + L2L3Patterns_.push_back(&p); + } + if (p.sl1() == 3) { + if (p.sl2() == 7) + L3L7Patterns_.push_back(&p); + if (p.sl2() == 6) + L3L6Patterns_.push_back(&p); + if (p.sl2() == 5) + L3L5Patterns_.push_back(&p); + if (p.sl2() == 4) + L3L4Patterns_.push_back(&p); + } + + if (p.sl1() == 4) { + if (p.sl2() == 7) + L4L7Patterns_.push_back(&p); + if (p.sl2() == 6) + L4L6Patterns_.push_back(&p); + if (p.sl2() == 5) + L4L5Patterns_.push_back(&p); + } + if (p.sl1() == 5) { + if (p.sl2() == 7) + L5L7Patterns_.push_back(&p); + if (p.sl2() == 6) + L5L6Patterns_.push_back(&p); + } + if (p.sl1() == 6) { + if (p.sl2() == 7) + L6L7Patterns_.push_back(&p); + } + //Also creating a list of all patterns, needed later for deleting and avoid a memory leak + allPatterns_.push_back(&p); + nPatterns_++; +} + +void PseudoBayesGrouping::run(Event& iEvent, + const EventSetup& iEventSetup, + const DTDigiCollection& digis, + MuonPathPtrs& mpaths) { + //Takes dt digis collection and does the grouping for correlated hits, it is saved in a vector of up to 8 (or 4) correlated hits + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run"; + //Do initial cleaning + CleanDigisByLayer(); + //Sort digis by layer + FillDigisByLayer(&digis); + //Sarch for patterns + RecognisePatternsByLayerPairs(); + //Now sort patterns by qualities + std::sort(prelimMatches_->begin(), prelimMatches_->end(), CandPointGreat()); + if (debug_ && !prelimMatches_->empty()) { + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run Pattern qualities before cleaning: "; + for (const auto& cand_it : *prelimMatches_) { + LogDebug("PseudoBayesGrouping") << cand_it->nLayerhits() << ", " << cand_it->nisGood() << ", " << cand_it->nhits() + << ", " << cand_it->quality() << ", " << cand_it->candId(); + } + } + //And ghostbust patterns to retain higher quality ones + ReCleanPatternsAndDigis(); + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run Number of found patterns: " << finalMatches_->size(); + + //Last organize candidates information into muonpaths to finalize the grouping + FillMuonPaths(mpaths); + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run ended run"; +} + +void PseudoBayesGrouping::FillMuonPaths(MuonPathPtrs& mpaths) { + //Loop over all selected candidates + for (auto itCand = finalMatches_->begin(); itCand != finalMatches_->end(); itCand++) { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run Create pointers "; + DTPrimitivePtrs ptrPrimitive; + for (int i = 0; i < 8; i++) + ptrPrimitive.push_back(std::make_shared()); + + qualitybits qualityDTP; + int intHit = 0; + //And for each candidate loop over all grouped hits + for (auto& itDTP : (*itCand)->candHits()) { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run loop over dt hits to fill pointer"; + + int layerHit = (*itDTP).layerId(); + //Back to the usual basis for SL + if (layerHit >= 4) { + (*itDTP).setLayerId(layerHit - 4); + } + qualitybits ref8Hit(std::pow(2, layerHit)); + //Get the predicted laterality + if (setLateralities_) { + int predLat = (*itCand)->pattern()->latHitIn(layerHit, (*itDTP).channelId(), allowedVariance_); + if (predLat == -10 || predLat == 0) { + (*itDTP).setLaterality(NONE); + } else if (predLat == -1) { + (*itDTP).setLaterality(LEFT); + } else if (predLat == +1) { + (*itDTP).setLaterality(RIGHT); + } + } + //Only fill the DT primitives pointer if there is not one hit already in the layer + if (qualityDTP != (qualityDTP | ref8Hit)) { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::run Adding hit to muon path"; + qualityDTP = (qualityDTP | ref8Hit); + if (saveOnPlace_) { + //This will save the primitive in a place of the vector equal to its L position + ptrPrimitive.at(layerHit) = std::make_shared((*itDTP)); + } + if (!saveOnPlace_) { + //This will save the primitive in order + intHit++; + ptrPrimitive.at(intHit) = std::make_shared((*itDTP)); + } + } + } + //Now, if there are empty spaces in the vector fill them full of daylight + int ipow = 1; + for (int i = 0; i <= 7; i++) { + ipow *= 2; + if (qualityDTP != (qualityDTP | qualitybits(1 << i))) { + ptrPrimitive.at(i) = std::make_shared(); + } + } + + mpaths.emplace_back( + std::make_shared(ptrPrimitive, (short)(*itCand)->nLayerUp(), (short)(*itCand)->nLayerDown())); + } +} + +void PseudoBayesGrouping::RecognisePatternsByLayerPairs() { + //Separated from main run function for clarity. Do all pattern recognition steps + pidx_ = 0; + //Compare L0-L7 + RecognisePatterns(digisinL0_, digisinL7_, L0L7Patterns_); + //Compare L0-L6 and L1-L7 + RecognisePatterns(digisinL0_, digisinL6_, L0L6Patterns_); + RecognisePatterns(digisinL1_, digisinL7_, L1L7Patterns_); + //Compare L0-L5, L1-L6, L2-L7 + RecognisePatterns(digisinL0_, digisinL5_, L0L5Patterns_); + RecognisePatterns(digisinL1_, digisinL6_, L1L6Patterns_); + RecognisePatterns(digisinL2_, digisinL7_, L2L7Patterns_); + //L0-L4, L1-L5, L2-L6, L3-L7 + RecognisePatterns(digisinL0_, digisinL4_, L0L4Patterns_); + RecognisePatterns(digisinL1_, digisinL5_, L1L5Patterns_); + RecognisePatterns(digisinL2_, digisinL6_, L2L6Patterns_); + RecognisePatterns(digisinL3_, digisinL7_, L3L7Patterns_); + //L1-L4, L2-L5, L3-L6 + RecognisePatterns(digisinL1_, digisinL4_, L1L4Patterns_); + RecognisePatterns(digisinL2_, digisinL5_, L2L5Patterns_); + RecognisePatterns(digisinL3_, digisinL6_, L3L6Patterns_); + //L2-L4, L3-L5 + RecognisePatterns(digisinL2_, digisinL4_, L2L4Patterns_); + RecognisePatterns(digisinL3_, digisinL5_, L3L5Patterns_); + //L3-L4 + RecognisePatterns(digisinL3_, digisinL4_, L3L4Patterns_); + //Uncorrelated SL1 + RecognisePatterns(digisinL0_, digisinL1_, L0L1Patterns_); + RecognisePatterns(digisinL0_, digisinL2_, L0L2Patterns_); + RecognisePatterns(digisinL0_, digisinL3_, L0L3Patterns_); + RecognisePatterns(digisinL1_, digisinL2_, L1L2Patterns_); + RecognisePatterns(digisinL1_, digisinL3_, L1L3Patterns_); + RecognisePatterns(digisinL2_, digisinL3_, L2L3Patterns_); + //Uncorrelated SL3 + RecognisePatterns(digisinL4_, digisinL5_, L4L5Patterns_); + RecognisePatterns(digisinL4_, digisinL6_, L4L6Patterns_); + RecognisePatterns(digisinL4_, digisinL7_, L4L7Patterns_); + RecognisePatterns(digisinL5_, digisinL6_, L5L6Patterns_); + RecognisePatterns(digisinL5_, digisinL7_, L5L7Patterns_); + RecognisePatterns(digisinL6_, digisinL7_, L6L7Patterns_); +} + +void PseudoBayesGrouping::RecognisePatterns(std::vector digisinLDown, + std::vector digisinLUp, + std::vector patterns) { + //Loop over all hits and search for matching patterns (there will be four + // amongst ~60, accounting for possible lateralities) + for (auto dtPD_it = digisinLDown.begin(); dtPD_it != digisinLDown.end(); dtPD_it++) { + int LDown = dtPD_it->layerId(); + int wireDown = dtPD_it->channelId(); + for (auto dtPU_it = digisinLUp.begin(); dtPU_it != digisinLUp.end(); dtPU_it++) { + int LUp = dtPU_it->layerId(); + int wireUp = dtPU_it->channelId(); + int diff = wireUp - wireDown; + for (auto pat_it = patterns.begin(); pat_it != patterns.end(); pat_it++) { + //For each pair of hits in the layers search for the seeded patterns + if ((*pat_it)->sl1() != (LDown) || (*pat_it)->sl2() != (LUp) || (*pat_it)->diff() != diff) + continue; + //If we are here a pattern was found and we can start comparing + (*pat_it)->setHitDown(wireDown); + auto cand = std::make_shared(*pat_it); + for (auto dtTest_it = alldigis_.begin(); dtTest_it != alldigis_.end(); dtTest_it++) { + //Find hits matching to the pattern + if (((*pat_it)->latHitIn(dtTest_it->layerId(), dtTest_it->channelId(), allowedVariance_)) != -999) { + if (((*pat_it)->latHitIn(dtTest_it->layerId(), dtTest_it->channelId(), allowedVariance_)) == -10) + cand->addHit((*dtTest_it), dtTest_it->layerId(), false); + else + cand->addHit((*dtTest_it), dtTest_it->layerId(), true); + } + } + if ((cand->nhits() >= minNLayerHits_ && + (cand->nLayerUp() >= minSingleSLHitsMax_ || cand->nLayerDown() >= minSingleSLHitsMax_) && + (cand->nLayerUp() >= minSingleSLHitsMin_ && cand->nLayerDown() >= minSingleSLHitsMin_)) || + (allowUncorrelatedPatterns_ && ((cand->nLayerUp() >= minUncorrelatedHits_ && cand->nLayerDown() == 0) || + (cand->nLayerDown() >= minUncorrelatedHits_ && cand->nLayerUp() == 0)))) { + if (debug_) { + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::RecognisePatterns Pattern found for pair in " + << LDown << " ," << wireDown << " ," << LUp << " ," << wireUp; + LogDebug("PseudoBayesGrouping") + << "Candidate has " << cand->nhits() << " hits with quality " << cand->quality(); + LogDebug("PseudoBayesGrouping") << *(*pat_it); + } + //We currently save everything at this level, might want to be more restrictive + pidx_++; + cand->setCandId(pidx_); + prelimMatches_->push_back(std::move(cand)); + allMatches_->push_back(std::move(cand)); + } + } + } + } +} + +void PseudoBayesGrouping::FillDigisByLayer(const DTDigiCollection* digis) { + //First we need to have separated lists of digis by layer + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping::FillDigisByLayer Classifying digis by layer"; + // for (auto dtDigi_It = digis->begin(); dtDigi_It != digis->end(); dtDigi_It++) { + for (const auto& dtDigi_It : *digis) { + const DTLayerId dtLId = dtDigi_It.first; + //Skip digis in SL theta which we are not interested on for the grouping + for (auto digiIt = (dtDigi_It.second).first; digiIt != (dtDigi_It.second).second; digiIt++) { + //Need to change notation slightly here + if (dtLId.superlayer() == 2) + continue; + int layer = dtLId.layer() - 1; + if (dtLId.superlayer() == 3) + layer += 4; + //Use the same format as for InitialGrouping to avoid tons of replicating classes, we will have some not used variables + DTPrimitive dtpAux = DTPrimitive(); + dtpAux.setTDCTimeStamp(digiIt->time()); + dtpAux.setChannelId(digiIt->wire() - 1); + dtpAux.setLayerId(layer); + dtpAux.setSuperLayerId(dtLId.superlayer()); + dtpAux.setCameraId(dtLId.rawId()); + if (debug_) + LogDebug("PseudoBayesGrouping") << "Hit in L " << layer << " SL " << dtLId.superlayer() << " WIRE " + << digiIt->wire() - 1; + if (layer == 0) + digisinL0_.push_back(dtpAux); + else if (layer == 1) + digisinL1_.push_back(dtpAux); + else if (layer == 2) + digisinL2_.push_back(dtpAux); + else if (layer == 3) + digisinL3_.push_back(dtpAux); + else if (layer == 4) + digisinL4_.push_back(dtpAux); + else if (layer == 5) + digisinL5_.push_back(dtpAux); + else if (layer == 6) + digisinL6_.push_back(dtpAux); + else if (layer == 7) + digisinL7_.push_back(dtpAux); + alldigis_.push_back(dtpAux); + } + } +} + +void PseudoBayesGrouping::ReCleanPatternsAndDigis() { + //GhostbustPatterns that share hits and are of lower quality + if (prelimMatches_->empty()) { + return; + }; + while ((prelimMatches_->at(0)->nLayerhits() >= minNLayerHits_ && + (prelimMatches_->at(0)->nLayerUp() >= minSingleSLHitsMax_ || + prelimMatches_->at(0)->nLayerDown() >= minSingleSLHitsMax_) && + (prelimMatches_->at(0)->nLayerUp() >= minSingleSLHitsMin_ && + prelimMatches_->at(0)->nLayerDown() >= minSingleSLHitsMin_)) || + (allowUncorrelatedPatterns_ && + ((prelimMatches_->at(0)->nLayerUp() >= minUncorrelatedHits_ && prelimMatches_->at(0)->nLayerDown() == 0) || + (prelimMatches_->at(0)->nLayerDown() >= minUncorrelatedHits_ && prelimMatches_->at(0)->nLayerUp() == 0)))) { + finalMatches_->push_back(prelimMatches_->at(0)); + auto itSel = finalMatches_->end() - 1; + prelimMatches_->erase(prelimMatches_->begin()); + if (prelimMatches_->empty()) { + return; + }; + for (auto cand_it = prelimMatches_->begin(); cand_it != prelimMatches_->end(); cand_it++) { + if (*(*cand_it) == *(*itSel) && allowDuplicates_) + continue; + for (const auto& dt_it : (*itSel)->candHits()) { //.begin(); dt_it != (*itSel)->candHits().end(); dt_it++) { + (*cand_it)->removeHit((*dt_it)); + } + } + + std::sort(prelimMatches_->begin(), prelimMatches_->end(), CandPointGreat()); + if (debug_) { + LogDebug("PseudoBayesGrouping") << "Pattern qualities: "; + for (const auto& cand_it : *prelimMatches_) { + LogDebug("PseudoBayesGrouping") << cand_it->nLayerhits() << ", " << cand_it->nisGood() << ", " + << cand_it->nhits() << ", " << cand_it->quality() << ", " << cand_it->candId() + << "\n"; + } + } + } +} + +void PseudoBayesGrouping::CleanDigisByLayer() { + digisinL0_.clear(); + digisinL1_.clear(); + digisinL2_.clear(); + digisinL3_.clear(); + digisinL4_.clear(); + digisinL5_.clear(); + digisinL6_.clear(); + digisinL7_.clear(); + alldigis_.clear(); + allMatches_->clear(); + prelimMatches_->clear(); + finalMatches_->clear(); +} + +void PseudoBayesGrouping::finish() { + if (debug_) + LogDebug("PseudoBayesGrouping") << "PseudoBayesGrouping: finish"; +}; diff --git a/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc b/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc new file mode 100644 index 0000000000000..be8ea54910111 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc @@ -0,0 +1,257 @@ +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/ESInputTag.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h" + +#include + +#include + +using namespace cmsdt; + +RPCIntegrator::RPCIntegrator(const edm::ParameterSet& pset, edm::ConsumesCollector& iC) { + m_debug_ = pset.getUntrackedParameter("debug"); + if (m_debug_) + LogDebug("RPCIntegrator") << "RPCIntegrator constructor"; + m_max_quality_to_overwrite_t0_ = pset.getUntrackedParameter("max_quality_to_overwrite_t0"); + m_bx_window_ = pset.getUntrackedParameter("bx_window"); + m_phi_window_ = pset.getUntrackedParameter("phi_window"); + m_storeAllRPCHits_ = pset.getUntrackedParameter("storeAllRPCHits"); + + rpcGeomH_ = iC.esConsumes(); + dtGeomH_ = iC.esConsumes(); +} + +RPCIntegrator::~RPCIntegrator() { + if (m_debug_) + LogDebug("RPCIntegrator") << "RPCIntegrator destructor"; +} + +void RPCIntegrator::initialise(const edm::EventSetup& iEventSetup, double shift_back_fromDT) { + if (m_debug_) + LogDebug("RPCIntegrator") << "RPCIntegrator initialisation"; + + if (m_debug_) + LogDebug("RPCIntegrator") << "Getting RPC geometry"; + + const MuonGeometryRecord& geom = iEventSetup.get(); + dtGeo_ = &geom.get(dtGeomH_); + rpcGeo_ = &geom.get(rpcGeomH_); + shift_back_ = shift_back_fromDT; +} + +void RPCIntegrator::finish() {} + +void RPCIntegrator::prepareMetaPrimitives(edm::Handle rpcRecHits) { + RPCMetaprimitives_.clear(); + rpcRecHits_translated_.clear(); + for (const auto& rpcIt : *rpcRecHits) { + RPCDetId rpcDetId = (RPCDetId)(rpcIt).rpcId(); + GlobalPoint global_position = RPCGlobalPosition(rpcDetId, rpcIt); + int rpc_region = rpcDetId.region(); + if (rpc_region != 0) + continue; // Region = 0 Barrel + + // set everyone to rpc single hit (3) not matched to DT flag for now + // change last two elements if dt bx centered at zero again + RPCMetaprimitives_.emplace_back( + rpcDetId, &rpcIt, global_position, RPC_HIT, rpcIt.BunchX() + BX_SHIFT, rpcIt.time() + BX_SHIFT * LHC_CLK_FREQ); + } +} +void RPCIntegrator::matchWithDTAndUseRPCTime(std::vector& dt_metaprimitives) { + for (auto dt_metaprimitive = dt_metaprimitives.begin(); dt_metaprimitive != dt_metaprimitives.end(); + dt_metaprimitive++) { + RPCMetaprimitive* bestMatch_rpcRecHit = matchDTwithRPC(&*dt_metaprimitive); + if (bestMatch_rpcRecHit) { + (*dt_metaprimitive).rpcFlag = RPC_CONFIRM; + if ((*dt_metaprimitive).quality < m_max_quality_to_overwrite_t0_) { + (*dt_metaprimitive).t0 = bestMatch_rpcRecHit->rpc_t0 + 25 * shift_back_; + (*dt_metaprimitive).rpcFlag = RPC_TIME; + } + } + } +} + +void RPCIntegrator::makeRPCOnlySegments() { + std::vector rpc_only_segments; + for (auto& rpc_mp_it_layer1 : RPCMetaprimitives_) { + RPCDetId rpc_id_l1 = rpc_mp_it_layer1.rpc_id; + const RPCRecHit* rpc_cluster_l1 = rpc_mp_it_layer1.rpc_cluster; + GlobalPoint rpc_gp_l1 = rpc_mp_it_layer1.global_position; + if (rpc_id_l1.station() > 2 || rpc_id_l1.layer() != 1 || + (rpc_mp_it_layer1.rpcFlag == RPC_ASSOCIATE && !m_storeAllRPCHits_)) + continue; + // only one RPC layer in station three and four && + // avoid duplicating pairs && + // avoid building RPC only segment if DT segment was already there + int min_dPhi = std::numeric_limits::max(); + RPCMetaprimitive* bestMatch_rpc_mp_layer2 = nullptr; + for (auto& rpc_mp_it_layer2 : RPCMetaprimitives_) { + RPCDetId rpc_id_l2 = rpc_mp_it_layer2.rpc_id; + const RPCRecHit* rpc_cluster_l2 = rpc_mp_it_layer2.rpc_cluster; + GlobalPoint rpc_gp_l2 = rpc_mp_it_layer2.global_position; + if (rpc_id_l2.station() == rpc_id_l1.station() && rpc_id_l2.ring() == rpc_id_l1.ring() && + rpc_id_l2.layer() != rpc_id_l1.layer() // ensure to have layer 1 --> layer 2 + && rpc_id_l2.sector() == rpc_id_l1.sector() && rpc_cluster_l2->BunchX() == rpc_cluster_l1->BunchX() && + (rpc_mp_it_layer2.rpcFlag != RPC_ASSOCIATE || m_storeAllRPCHits_)) { + // avoid building RPC only segment with a hit already matched to DT, + // except if one aske to store all RPC info + float tmp_dPhi = rpc_gp_l1.phi() - rpc_gp_l2.phi(); + if (std::abs(tmp_dPhi) < std::abs(min_dPhi)) { + min_dPhi = tmp_dPhi; + bestMatch_rpc_mp_layer2 = &rpc_mp_it_layer2; + } + } + } + if (bestMatch_rpc_mp_layer2) { + rpc_mp_it_layer1.rpcFlag = 6; + // need a new flag (will be removed later) to differentiate + // between "has been matched to DT" and "Has been used in an RPC only segment" + bestMatch_rpc_mp_layer2->rpcFlag = 6; + double phiB = phiBending(&rpc_mp_it_layer1, &*bestMatch_rpc_mp_layer2); + // Arbitrarily choose the phi from layer 1 + double global_phi = rpc_mp_it_layer1.global_position.phi(); + double t0 = (rpc_mp_it_layer1.rpc_t0 + bestMatch_rpc_mp_layer2->rpc_t0) / 2; + // RPC only segment have rpcFlag==2 + L1Phase2MuDTPhDigi rpc_only_segment = + createL1Phase2MuDTPhDigi(rpc_id_l1, rpc_mp_it_layer1.rpc_bx, t0, global_phi, phiB, 2); + rpc_only_segments.push_back(rpc_only_segment); + } + } + rpcRecHits_translated_.insert(rpcRecHits_translated_.end(), rpc_only_segments.begin(), rpc_only_segments.end()); +} + +void RPCIntegrator::storeRPCSingleHits() { + for (auto rpc_mp_it = RPCMetaprimitives_.begin(); rpc_mp_it != RPCMetaprimitives_.end(); rpc_mp_it++) { + RPCDetId rpcDetId = rpc_mp_it->rpc_id; + if (rpc_mp_it->rpcFlag == 6) + rpc_mp_it->rpcFlag = RPC_ASSOCIATE; + L1Phase2MuDTPhDigi rpc_out = createL1Phase2MuDTPhDigi( + rpcDetId, rpc_mp_it->rpc_bx, rpc_mp_it->rpc_t0, rpc_mp_it->global_position.phi(), -10000, rpc_mp_it->rpcFlag); + rpcRecHits_translated_.push_back(rpc_out); + } +} + +void RPCIntegrator::removeRPCHitsUsed() { + if (m_debug_) + LogDebug("RPCIntegrator") << "RPCIntegrator removeRPCHitsUsed method"; + if (!m_storeAllRPCHits_) { + // Remove RPC hit attached to a DT or RPC segment if required by user + // (avoid having two TP's corresponding to the same physical hit) + auto rpcRecHit_translated_ = rpcRecHits_translated_.begin(); + while (rpcRecHit_translated_ != rpcRecHits_translated_.end()) { + if (rpcRecHit_translated_->rpcFlag() == RPC_ASSOCIATE || rpcRecHit_translated_->rpcFlag() == 6) { + rpcRecHit_translated_ = rpcRecHits_translated_.erase(rpcRecHit_translated_); + } else { + ++rpcRecHit_translated_; + } + } + } +} + +RPCMetaprimitive* RPCIntegrator::matchDTwithRPC(metaPrimitive* dt_metaprimitive) { + // metaprimitive dtChId is still in convention with [1 - 12] + // because at this stage the BX of metaprimitive is not yet computed... + // will also have to subtract 20*25 ns because of the recent change + int dt_bx = (int)round(dt_metaprimitive->t0 / 25.) - shift_back_; + DTChamberId dt_chId = DTChamberId(dt_metaprimitive->rawId); + int dt_sector = dt_chId.sector(); + if (dt_sector == 13) + dt_sector = 4; + if (dt_sector == 14) + dt_sector = 10; + RPCMetaprimitive* bestMatch_rpcRecHit = nullptr; + float min_dPhi = std::numeric_limits::max(); + for (auto rpc_mp_it = RPCMetaprimitives_.begin(); rpc_mp_it != RPCMetaprimitives_.end(); rpc_mp_it++) { + RPCDetId rpc_det_id = rpc_mp_it->rpc_id; + if (rpc_det_id.ring() == dt_chId.wheel() // ring() in barrel RPC corresponds to the wheel + && rpc_det_id.station() == dt_chId.station() && rpc_det_id.sector() == dt_sector && + std::abs(rpc_mp_it->rpc_bx - dt_bx) <= m_bx_window_) { + // Select the RPC hit closest in phi to the DT meta primitive + + // just a trick to apply the phi window cut on what could be accessed to fine tune it + int delta_phi = + (int)round((phi_DT_MP_conv(rpc_mp_it->global_position.phi(), rpc_det_id.sector()) - dt_metaprimitive->phi) * + m_dt_phiB_granularity_); + if (std::abs(delta_phi) < min_dPhi && std::abs(delta_phi) < m_phi_window_) { + min_dPhi = std::abs(delta_phi); + bestMatch_rpcRecHit = &*rpc_mp_it; + } + } + } + if (bestMatch_rpcRecHit) { + bestMatch_rpcRecHit->rpcFlag = RPC_ASSOCIATE; + } + return bestMatch_rpcRecHit; +} + +L1Phase2MuDTPhDigi RPCIntegrator::createL1Phase2MuDTPhDigi( + RPCDetId rpcDetId, int rpc_bx, double rpc_time, double rpc_global_phi, double phiB, int rpc_flag) { + if (m_debug_) + LogDebug("RPCIntegrator") << "Creating DT TP out of RPC recHits"; + int rpc_wheel = rpcDetId.ring(); // In barrel, wheel is accessed via ring() method ([-2,+2]) + int trigger_sector = rpcDetId.sector() - 1; // DT Trigger sector:[0,11] while RPC sector:[1,12] + int rpc_station = rpcDetId.station(); + int rpc_layer = rpcDetId.layer(); + int rpc_trigger_phi = phiInDTTPFormat(rpc_global_phi, rpcDetId.sector()); + int rpc_trigger_phiB = (phiB == -10000) ? phiB : (int)round(phiB * m_dt_phiB_granularity_); + int rpc_quality = -1; // dummy for rpc + int rpc_index = 0; // dummy for rpc + return L1Phase2MuDTPhDigi(rpc_bx, + rpc_wheel, + trigger_sector, + rpc_station, + rpc_layer, //this would be the layer in the new dataformat + rpc_trigger_phi, + rpc_trigger_phiB, + rpc_quality, + rpc_index, + rpc_time, + -1, // no chi2 for RPC + rpc_flag); +} + +double RPCIntegrator::phiBending(RPCMetaprimitive* rpc_hit_1, RPCMetaprimitive* rpc_hit_2) { + DTChamberId DT_chamber(rpc_hit_1->rpc_id.ring(), rpc_hit_1->rpc_id.station(), rpc_hit_1->rpc_id.sector()); + LocalPoint lp_rpc_hit_1_dtconv = dtGeo_->chamber(DT_chamber)->toLocal(rpc_hit_1->global_position); + LocalPoint lp_rpc_hit_2_dtconv = dtGeo_->chamber(DT_chamber)->toLocal(rpc_hit_2->global_position); + double slope = (lp_rpc_hit_1_dtconv.x() - lp_rpc_hit_2_dtconv.x()) / distance_between_two_rpc_layers_; + double average_x = (lp_rpc_hit_1_dtconv.x() + lp_rpc_hit_2_dtconv.x()) / 2; + GlobalPoint seg_middle_global = + dtGeo_->chamber(DT_chamber)->toGlobal(LocalPoint(average_x, 0., 0.)); // for station 1 and 2, z = 0 + double seg_phi = phi_DT_MP_conv(seg_middle_global.phi(), rpc_hit_1->rpc_id.sector()); + double psi = atan(slope); + double phiB = hasPosRF_rpc(rpc_hit_1->rpc_id.ring(), rpc_hit_1->rpc_id.sector()) ? psi - seg_phi : -psi - seg_phi; + return phiB; +} + +int RPCIntegrator::phiInDTTPFormat(double rpc_global_phi, int rpcSector) { + double rpc_localDT_phi; + rpc_localDT_phi = phi_DT_MP_conv(rpc_global_phi, rpcSector) * m_dt_phi_granularity_; + return (int)round(rpc_localDT_phi); +} + +double RPCIntegrator::phi_DT_MP_conv(double rpc_global_phi, int rpcSector) { + // Adaptation of https://github.com/cms-sw/cmssw/blob/master/L1Trigger/L1TTwinMux/src/RPCtoDTTranslator.cc#L349 + + if (rpcSector == 1) + return rpc_global_phi; + else { + float conversion = 1 / 6.; + if (rpc_global_phi >= 0) + return rpc_global_phi - (rpcSector - 1) * M_PI * conversion; + else + return rpc_global_phi + (13 - rpcSector) * M_PI * conversion; + } +} + +GlobalPoint RPCIntegrator::RPCGlobalPosition(RPCDetId rpcId, const RPCRecHit& rpcIt) const { + RPCDetId rpcid = RPCDetId(rpcId); + const LocalPoint& rpc_lp = rpcIt.localPosition(); + const GlobalPoint& rpc_gp = rpcGeo_->idToDet(rpcid)->surface().toGlobal(rpc_lp); + + return rpc_gp; +} + +bool RPCIntegrator::hasPosRF_rpc(int wh, int sec) const { return (wh > 0 || (wh == 0 && sec % 4 > 1)); } diff --git a/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg.py b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg.py new file mode 100644 index 0000000000000..42407da17b768 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg.py @@ -0,0 +1,49 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load("Geometry.CMSCommonData.cmsIdealGeometryXML_cff") +process.load("Geometry.DTGeometry.dtGeometry_cfi") +process.DTGeometryESModule.applyAlignment = False + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +#process.GlobalTag.globaltag = "90X_dataRun2_Express_v2" +process.GlobalTag.globaltag = "80X_dataRun2_2016SeptRepro_v7" + +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +#process.CalibratedDigis.flat_calib = 325 #turn to 0 to use the DB , 325 for JM and Jorge benchmark + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +#process.dtTriggerPhase2PrimitiveDigis.trigger_with_sl = 3 #4 means SL 1 and 3 +#for the moment the part working in phase2 format is the slice test +#process.dtTriggerPhase2PrimitiveDigis.p2_df = 0 //0 is phase1, 1 is slice test, 2 is phase2(carlo-federica) + +process.dtTriggerPhase2PrimitiveDigis.scenario = 1 #0 is mc, 1 is data, 2 is slice test + + +process.source = cms.Source("PoolSource",fileNames = cms.untracked.vstring( + #'file:/eos/user/c/carrillo/digis_segments_Run2016BSingleMuonRAW-RECO.root' + 'file:/tmp/carrillo/digis_segments_Run2016BSingleMuonRAW-RECO.root' + ) + ) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1) +) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('keep *'), + fileName = cms.untracked.string('/tmp/carrillo/DTTriggerPhase2Primitives.root') +) + +process.p = cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +process.this_is_the_end = cms.EndPath(process.out) + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg_withRPC.py b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg_withRPC.py new file mode 100644 index 0000000000000..312f6a1137152 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg_withRPC.py @@ -0,0 +1,62 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load("Geometry.CMSCommonData.cmsIdealGeometryXML_cff") +process.load("Geometry.DTGeometry.dtGeometry_cfi") +process.DTGeometryESModule.applyAlignment = False + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +process.GlobalTag.globaltag = "106X_upgrade2018_realistic_v4" +#from Configuration.AlCa.GlobalTag import GlobalTag +#process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') + +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +process.CalibratedDigis.dtDigiTag = "simMuonDTDigis" +process.CalibratedDigis.scenario = 0 # 0 for mc, 1 for data, 2 for slice test +#process.CalibratedDigis.flat_calib = 325 #turn to 0 to use the DB , 325 for JM and Jorge benchmark + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +#process.dtTriggerPhase2PrimitiveDigis.trigger_with_sl = 3 #4 means SL 1 and 3 +#for the moment the part working in phase2 format is the slice test +#process.dtTriggerPhase2PrimitiveDigis.p2_df = 0 //0 is phase1, 1 is slice test, 2 is phase2(carlo-federica) +#process.dtTriggerPhase2PrimitiveDigis.filter_primos = True +#for debugging +process.dtTriggerPhase2PrimitiveDigis.min_phinhits_match_segment = 4 +#process.dtTriggerPhase2PrimitiveDigis.debug = True + +#Produce RPC clusters from RPCDigi +process.load("RecoLocalMuon.RPCRecHit.rpcRecHits_cfi") +process.rpcRecHits.rpcDigiLabel = cms.InputTag('simMuonRPCDigis') +# Use RPC +process.load('Configuration.Geometry.GeometryExtended2023D38Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2023D38_cff') +process.dtTriggerPhase2PrimitiveDigis.useRPC = True +process.dtTriggerPhase2PrimitiveDigis.scenario = 0 # 0 for mc, 1 for data, 2 for slice test +## Parameters that could be optimized (show here the default values) +#process.dtTriggerPhase2PrimitiveDigis.bx_window = 1 # +#process.dtTriggerPhase2PrimitiveDigis.max_quality_to_overwrite_t0 = 9 # strict inequality +#process.dtTriggerPhase2PrimitiveDigis.phi_window = 50 +#process.dtTriggerPhase2PrimitiveDigis.storeAllRPCHits = False + +process.source = cms.Source("PoolSource",fileNames = cms.untracked.vstring( + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_1.root' + #'file:/eos/cms/store/group/dpg_rpc/comm_rpc/UpgradePhaseII/RPC_PLUS_DT/SingleMu_FlatPt-2to100_10_5_0_MaryCruz_WithRPCRecHits/SimRECO_1.root' + ) + ) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(100) +) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('keep *'), + fileName = cms.untracked.string('DTTriggerPhase2Primitives100_withRPC.root') +) + +process.p = cms.Path(process.rpcRecHits*process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +process.this_is_the_end = cms.EndPath(process.out) + diff --git a/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_hlt_parallel_cfg.py b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_hlt_parallel_cfg.py new file mode 100644 index 0000000000000..dfba5f2a9cffc --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_hlt_parallel_cfg.py @@ -0,0 +1,52 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load("Geometry.CMSCommonData.cmsIdealGeometryXML_cff") +process.load("Geometry.DTGeometry.dtGeometry_cfi") +process.DTGeometryESModule.applyAlignment = False + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +#process.GlobalTag.globaltag = "90X_dataRun2_Express_v2" +process.GlobalTag.globaltag = "80X_dataRun2_2016SeptRepro_v7" + +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigishlt_cfi") +#process.CalibratedDigis.flat_calib = 0 #turn to 0 to use the DB , 325 for JM and Jorge benchmark + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigishlt_cfi") + + + + + +process.dtTriggerPhase2PrimitiveDigis.pinta = True +process.dtTriggerPhase2PrimitiveDigis.min_phinhits_match_segment = 4 + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( + 'file:-input-' + ) + ) + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1) +) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('keep *'), + fileName = cms.untracked.string('-output-') + ) + + +process.p = cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +#process.this_is_the_end = cms.EndPath(process.out) + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_mc_cfg.py b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_mc_cfg.py new file mode 100644 index 0000000000000..c196b642a9f18 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_mc_cfg.py @@ -0,0 +1,67 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load("Geometry.CMSCommonData.cmsIdealGeometryXML_cff") +process.load("Geometry.DTGeometry.dtGeometry_cfi") +process.DTGeometryESModule.applyAlignment = False + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +#process.GlobalTag.globaltag = "90X_dataRun2_Express_v2" +#process.GlobalTag.globaltag = "80X_dataRun2_2016SeptRepro_v7" +process.GlobalTag.globaltag = "100X_upgrade2018_realistic_v10" + +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +#process.CalibratedDigis.flat_calib = 325 #turn to 0 to use the DB , 325 for JM and Jorge benchmark +process.CalibratedDigis.dtDigiTag = "simMuonDTDigis" #turn to 0 to use the DB , 325 for JM and Jorge benchmark +process.CalibratedDigis.scenario = 0 # 0 for mc, 1 for data, 2 for slice test + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +#process.dtTriggerPhase2PrimitiveDigis.trigger_with_sl = 3 #4 means SL 1 and 3 +#for the moment the part working in phase2 format is the slice test +#process.dtTriggerPhase2PrimitiveDigis.p2_df = True +#process.dtTriggerPhase2PrimitiveDigis.filter_primos = True +#for debugging +#process.dtTriggerPhase2PrimitiveDigis.pinta = True +#process.dtTriggerPhase2PrimitiveDigis.min_phinhits_match_segment = 4 +#process.dtTriggerPhase2PrimitiveDigis.debug = True +process.dtTriggerPhase2PrimitiveDigis.scenario = 0 +process.dtTriggerPhase2PrimitiveDigis.dump = True + +process.source = cms.Source("PoolSource",fileNames = cms.untracked.vstring( + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_1.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_2.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_3.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_4.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_5.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_6.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_7.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_8.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_9.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_10.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_11.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_12.root', + 'file:/eos/cms/store/group/dpg_dt/comm_dt/TriggerSimulation/SamplesReco/SingleMu_FlatPt-2to100/Version_10_5_0/SimRECO_13.root' + ) + ) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(2) +) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('keep *'), + fileName = cms.untracked.string('DTTriggerPhase2Primitives_testsmc.root') +) + +process.p = cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +process.this_is_the_end = cms.EndPath(process.out) + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_unpacked_cfg.py b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_unpacked_cfg.py new file mode 100644 index 0000000000000..66a588eb7be3e --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/primitivesPhase2Prod_over_unpacked_cfg.py @@ -0,0 +1,52 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load("Geometry.CMSCommonData.cmsIdealGeometryXML_cff") +process.load("Geometry.DTGeometry.dtGeometry_cfi") +process.DTGeometryESModule.applyAlignment = False + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +#process.GlobalTag.globaltag = "90X_dataRun2_Express_v2" +process.GlobalTag.globaltag = "80X_dataRun2_2016SeptRepro_v7" + +#Calibrate Digis +#process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +#process.CalibratedDigis.flat_calib = 325 #turn to 0 to use the DB , 325 for JM and Jorge benchmark + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.dtTriggerPhase2PrimitiveDigis.trigger_with_sl = 4 #4 means SL 1 and 3 +process.dtTriggerPhase2PrimitiveDigis.digiTag=("ogdtab7unpacker") + +#for the moment the part working in phase2 format is the slice test +process.dtTriggerPhase2PrimitiveDigis.do_correlation = False +process.dtTriggerPhase2PrimitiveDigis.p2_df = True +#for debugging +#process.dtTriggerPhase2PrimitiveDigis.debug = True + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(#'file:/eos/user/c/carrillo/digis_segments_Run2016BSingleMuonRAW-RECO.root' + 'file:/tmp/carrillo/unpacker_output.root' + ) + ) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1) +) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('keep *'), + fileName = cms.untracked.string('/tmp/carrillo/unpacked_and_emulator.root') +) + +#process.p = cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +process.p = cms.Path(process.dtTriggerPhase2PrimitiveDigis) +process.this_is_the_end = cms.EndPath(process.out) + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/test/prod_Zmu_digis_segments_cfg.py b/L1Trigger/DTTriggerPhase2/test/prod_Zmu_digis_segments_cfg.py new file mode 100644 index 0000000000000..73cfa52aebcec --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/prod_Zmu_digis_segments_cfg.py @@ -0,0 +1,134 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("DigisSegments") + +process.load("Geometry.CMSCommonData.cmsIdealGeometryXML_cff") +process.load("Geometry.DTGeometry.dtGeometry_cfi") +process.DTGeometryESModule.applyAlignment = False + +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +process.GlobalTag.globaltag = "90X_dataRun2_Express_v2" + +process.load("RecoLocalMuon.Configuration.RecoLocalMuon_cff") + +## DT unpacker +process.load("EventFilter.DTRawToDigi.dtunpacker_cfi") +process.muonDTDigis.inputLabel = 'rawDataCollector' + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/90000/A8CD55CA-1F94-E611-8017-0CC47A7C35A8.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/90000/5E3D3C6E-6594-E611-AB43-0CC47A4D7616.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/FEB68681-5A87-E611-9374-FA163EBB015F.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F8A610D8-6287-E611-845E-FA163E57640C.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F80380BB-7687-E611-84D6-02163E01653D.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F4A6C6FD-B089-E611-9227-002590DE6E64.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F40149E2-7387-E611-B057-0025904CF766.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F21AA882-6C87-E611-8F39-FA163EA18210.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F0A05CAE-5387-E611-BACB-FA163E9FDE85.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/F095A793-B389-E611-8A84-00259021A39E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/EE733CB6-B189-E611-A2A6-B499BAAC054A.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/EA70D05E-4589-E611-BFE3-FA163E3F2846.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/E46AF903-6C87-E611-8658-FA163EDB91EF.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/E4332BCB-D687-E611-A9EA-0025905A6126.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/E09E85A0-EB86-E611-B17D-20CF3019DEEF.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/DEEA9DDD-E187-E611-B13B-FA163E73AE79.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/DA12BA92-B087-E611-B7A3-0242AC130002.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/D615D999-B189-E611-B46C-FA163E8E175A.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/D6055073-6E87-E611-8E91-FA163E8D8332.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/D4FD5F54-658B-E611-BED9-0CC47A4D7646.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/D029A3C8-4B89-E611-9D1F-FA163E631428.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/CE3E1EE9-9789-E611-998C-FA163ED21222.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/CCDC87DF-1A88-E611-9B2A-1CC1DE19274E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/C8F8C3B2-5387-E611-B9FC-FA163E5669B0.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/C4B49819-F286-E611-B127-549F358EB76F.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/C2B91F86-5A87-E611-B7E7-02163E014C10.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/C09B5970-4B88-E611-9C48-901B0E5427A6.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/BE837F4E-9E87-E611-8DC8-3417EBE7047A.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/BAC10123-7787-E611-A0DE-02163E015FDF.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/B856E93F-E586-E611-BA74-FA163E1909D1.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/B64FD56E-6E87-E611-BD9C-02163E016438.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/B4BC5C81-6987-E611-B97A-F04DA275C2FB.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/B43870D6-1A88-E611-A7C0-0026B9F8CC18.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/AE723C49-B287-E611-ACE5-0CC47A78A42E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/AC213957-658B-E611-A7AF-0025905B8612.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/AA51B3CF-4B89-E611-A41A-02163E013C40.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/A8FF1F89-E586-E611-BC37-FA163E08C002.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/A28F9FFD-B489-E611-B864-008CFAFBF132.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/A21B22EA-8888-E611-B0C4-0CC47A4DEEBA.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/A0C3ADD4-0E87-E611-892F-02163E014D8C.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/9EE91F3C-1B87-E611-878C-FA163E775232.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/9CAF60BB-4489-E611-A29C-FA163EEF018D.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/9AAB70FE-D587-E611-834C-FA163ECD5C62.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/9A522CDD-6287-E611-BA23-FA163E3DAA96.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/9A345235-E586-E611-9CE6-FA163EFA00C3.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/98CD93AB-3A88-E611-A4C8-B083FED04276.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/961767D1-B189-E611-A1A3-20CF305B05AE.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/90AAF1A6-5387-E611-B9B8-0025905C3DF6.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/90522755-9587-E611-A29C-C45444922BB0.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/901352B9-B189-E611-89EC-0CC47A6C183A.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/8E949801-8288-E611-B9D6-047D7BD6DF22.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/88ADAECF-5789-E611-81B2-FA163EDB91EF.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/8823F019-8587-E611-A162-00259073E3EA.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/80CD4397-2A88-E611-9639-20474791CCC4.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/8095FC8B-B389-E611-ADD9-7CD30AB7F868.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/767A38E6-6287-E611-B225-02163E015D84.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/744FC7C0-5387-E611-BA6F-FA163E06DFEA.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/6CFB58E7-1587-E611-BD35-FA163EC97E57.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/68DE47B4-7E88-E611-A6AE-001E67792422.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/68A0DCD5-BB87-E611-8BF3-008CFA0F5040.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/68171F81-6187-E611-A9DF-001E67504F1D.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/66421E3C-5489-E611-B0BE-001E67505A2D.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/64FB46E3-8887-E611-AAAA-FA163EFA220C.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/64CC5933-4088-E611-B8DD-0025904C641E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/6448920B-7D87-E611-A5EA-02163E017614.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/6297FABA-5789-E611-A918-0CC47AC08BF8.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/5C7F15A9-9A88-E611-A80B-FA163EC5FCBC.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/5A63963D-B887-E611-88DC-001E6739C801.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/5404AF86-6187-E611-8DB3-44A84225CDA4.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/509458EF-B189-E611-9F85-FA163E17EB18.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/4C3B6518-B189-E611-93B3-0025905A612A.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/48E6AB0F-F286-E611-9792-FA163EDB91EF.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/40E2E2DE-8887-E611-9531-FA163E2AAF83.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/38FF87C2-B189-E611-B665-0CC47A1DF7FA.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/38CE04DC-5788-E611-9240-848F69FD2853.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/32775AB1-6C87-E611-A388-02163E0165D4.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/30A4019E-FE86-E611-B70E-02163E0165B6.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/2C6B53B6-5387-E611-9582-FA163E75F411.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/26D33DC4-3889-E611-B1AF-FA163E743F0B.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/26181B1F-6387-E611-AC9E-02163E01304E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/24A815DC-0E87-E611-8D96-B083FED13C9E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/22256107-6887-E611-847F-002590DE6E86.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/20263DED-9B88-E611-9630-001E67F336E0.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/1EF43C44-DE87-E611-BB70-6C3BE5B5B340.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/128426B7-8988-E611-BB9C-008CFA0A5A10.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/1041B010-6F87-E611-BA26-02163E015FDB.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/0E90E9AF-5387-E611-9FFA-FA163EC80D44.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/0C894F1B-5289-E611-8381-0025904C5DE0.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/0C6DFDD5-4D87-E611-9CF3-FA163E0B7F2E.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/0C153439-B187-E611-96D9-002590E1E9B8.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/083DFA38-B189-E611-BD7C-A0369F7FC770.root", +"/store/data/Run2016B/SingleMuon/RAW-RECO/ZMu-23Sep2016-v1/70000/02A6971D-F286-E611-8364-002590DE6E32.root" + ) + ) + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1) +) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('drop *','keep *_muonDTDigis_*_*','keep *_dt4DSegments_*_*'), + fileName = cms.untracked.string('/store/user/carrillo/digis_segments_Run2016BSingleMuonRAW-RECO.root') +) + + + +process.p = cms.Path(process.muonDTDigis*process.dtlocalreco) +process.this_is_the_end = cms.EndPath(process.out) + + + + + + diff --git a/L1Trigger/DTTriggerPhase2/test/test_primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg.py b/L1Trigger/DTTriggerPhase2/test/test_primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg.py new file mode 100644 index 0000000000000..3dbafe0e1dec4 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/test_primitivesPhase2Prod_over_dTDigis_and_4Dsegments_cfg.py @@ -0,0 +1,74 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load('Configuration.Geometry.GeometryExtended2026D41Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D41_cff') + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff") +process.GlobalTag.globaltag = "80X_dataRun2_2016SeptRepro_v7" + +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") + +#process.source = cms.Source("PoolSource",fileNames = cms.untracked.vstring('file:/eos/cms/store/user/folguera/P2L1TUpgrade/digis_segments_Run2016BSingleMuonRAW-RECO_camilo.root')) +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('file:/eos/cms/store/user/folguera/P2L1TUpgrade/digis_segments_Run2016BSingleMuonRAW-RECO_camilo.root')) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) +process.dtTriggerPhase2PrimitiveDigis.dump = True +process.dtTriggerPhase2PrimitiveDigis.debug = False +process.dtTriggerPhase2PrimitiveDigis.chi2Th = cms.untracked.double(0.16) + +#scenario +process.dtTriggerPhase2PrimitiveDigis.scenario = 1 +process.CalibratedDigis.scenario = 1 + +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger = cms.Service("MessageLogger", + destinations = cms.untracked.vstring("detailedInfo"), + detailedInfo = cms.untracked.PSet(threshold = cms.untracked.string("INFO"), + categories = cms.untracked.vstring("DTTrigPhase2Prod"), + extension = cms.untracked.string(".txt")), + debugModules = cms.untracked.vstring("dtTriggerPhase2PrimitiveDigis"), +) + +####################### SliceTest specials ############################## +#Chi2 -> Changing a lot lately +process.dtTriggerPhase2PrimitiveDigis.chi2Th = cms.untracked.double(0.16) + +#LSB -> Position 0.025 cm instead of 0.004 cm +process.dtTriggerPhase2PrimitiveDigis.use_LSB = True +process.dtTriggerPhase2PrimitiveDigis.x_precision = cms.untracked.double(1./(10.*16.)) +#process.dtTriggerPhase2PrimitiveDigis.x_precision = cms.untracked.double(0.025) +process.dtTriggerPhase2PrimitiveDigis.tanPsi_precision = cms.untracked.double(1./4096.) + +#Correlate with BX +process.dtTriggerPhase2PrimitiveDigis.useBX_correlation = True +process.dtTriggerPhase2PrimitiveDigis.dBX_correlate_TP = 1 + +#Correlate with tanPsi +#process.dtTriggerPhase2PrimitiveDigis.dTanPsi_correlate_TP = cms.untracked.double(9999./4096.) +#process.dtTriggerPhase2PrimitiveDigis.dTanPsi_correlate_TP = cms.untracked.double(900./4096.) + +#Confirmation forbidden +process.dtTriggerPhase2PrimitiveDigis.allow_confirmation = True + +#TanPsi stuff +process.dtTriggerPhase2PrimitiveDigis.tanPhiTh = cms.untracked.double(1.) + + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring('keep *'), + fileName = cms.untracked.string('DTTriggerPhase2Primitives.root') +) + +process.p = cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +process.this_is_the_end = cms.EndPath(process.out) + + + + + + diff --git a/L1Trigger/L1CaloTrigger/BuildFile.xml b/L1Trigger/L1CaloTrigger/BuildFile.xml new file mode 100644 index 0000000000000..ea6148c865666 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/BuildFile.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h b/L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h new file mode 100644 index 0000000000000..51a8efe024e57 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h @@ -0,0 +1,25 @@ +#ifndef L1Trigger_L1CaloTrigger_L1EGammaEECalibrator_h +#define L1Trigger_L1CaloTrigger_L1EGammaEECalibrator_h + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include +#include +#include + +class L1EGammaEECalibrator { +public: + explicit L1EGammaEECalibrator(const edm::ParameterSet&); + + float calibrationFactor(const float& pt, const float& eta) const; + +private: + int etaBin(float eta) const { return bin(eta_bins, std::abs(eta)); } + int ptBin(float pt) const { return bin(pt_bins, pt); } + int bin(const std::set& container, float value) const; + + std::set eta_bins; + std::set pt_bins; + std::vector calib_factors; +}; + +#endif diff --git a/L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h b/L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h new file mode 100644 index 0000000000000..feefed6b752fe --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h @@ -0,0 +1,26 @@ +#ifndef L1Trigger_L1CaloTrigger_ParametricCalibration_h +#define L1Trigger_L1CaloTrigger_ParametricCalibration_h +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include +#include +#include + +namespace l1tp2 { + class ParametricCalibration { + public: + ParametricCalibration() {} + ParametricCalibration(const edm::ParameterSet& cpset); + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + float operator()(const float pt, const float abseta) const; + + protected: + std::vector etas, pts, scales; + }; + +}; // namespace l1tp2 + +#endif diff --git a/L1Trigger/L1CaloTrigger/plugins/BuildFile.xml b/L1Trigger/L1CaloTrigger/plugins/BuildFile.xml new file mode 100644 index 0000000000000..b0d8cc656ff12 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/plugins/BuildFile.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc new file mode 100644 index 0000000000000..2781e7b15d7bd --- /dev/null +++ b/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc @@ -0,0 +1,1204 @@ +// -*- C++ -*- +// +// Package: L1CaloTrigger +// Class: L1EGammaCrystalsEmulatorProducer +// +/**\class L1EGammaCrystalsEmulatorProducer L1EGammaCrystalsEmulatorProducer.cc L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc +Description: Produces crystal clusters using crystal-level information and hardware constraints +Implementation: +[Notes on implementation] +*/ +// +// Original Author: Cecile Caillol +// Created: Tue Aug 10 2018 +// +// Redesign, Calibration: Vladimir Rekovic +// Date: Tue May 12 2020 +// +// $Id$ +// +// + +// system include files +#include +#include +#include +#include + +// user include files +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h" +#include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h" +#include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "DataFormats/HcalDetId/interface/HcalSubdetector.h" +#include "DataFormats/HcalDetId/interface/HcalDetId.h" + +// ECAL TPs +#include "DataFormats/EcalDigi/interface/EcalDigiCollections.h" + +// HCAL TPs +#include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveDigi.h" + +// Output tower collection +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" + +#include "L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h" +#include "L1Trigger/L1TCalorimeter/interface/CaloTools.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +static constexpr bool do_brem = true; + +static constexpr int n_eta_bins = 2; +static constexpr int n_borders_phi = 18; +static constexpr int n_borders_eta = 18; +static constexpr int n_clusters_max = 5; +static constexpr int n_clusters_link = 3; +static constexpr int n_clusters_4link = 4 * 3; +static constexpr int n_crystals_towerEta = 5; +static constexpr int n_crystals_towerPhi = 5; +static constexpr int n_crystals_3towers = 3 * 5; +static constexpr int n_towers_per_link = 17; +static constexpr int n_clusters_per_link = 2; +static constexpr int n_towers_Eta = 34; +static constexpr int n_towers_Phi = 72; +static constexpr int n_towers_halfPhi = 36; +static constexpr int n_links_card = 4; +static constexpr int n_links_GCTcard = 48; +static constexpr int n_GCTcards = 3; +static constexpr float ECAL_eta_range = 1.4841; +static constexpr float half_crystal_size = 0.00873; +static constexpr float slideIsoPtThreshold = 80; +static constexpr float a0_80 = 0.85, a1_80 = 0.0080, a0 = 0.21; // passes_iso +static constexpr float b0 = 0.38, b1 = 1.9, b2 = 0.05; //passes_looseTkiso +static constexpr float c0_ss = 0.94, c1_ss = 0.052, c2_ss = 0.044; //passes_ss +static constexpr float d0 = 0.96, d1 = 0.0003; //passes_photon +static constexpr float e0_looseTkss = 0.944, e1_looseTkss = 0.65, e2_looseTkss = 0.4; //passes_looseTkss +static constexpr float cut_500_MeV = 0.5; + +// absolue IDs range from 0-33 +// 0-16 are iEta -17 to -1 +// 17 to 33 are iEta 1 to 17 +static constexpr int toweriEta_fromAbsoluteID_shift = 16; + +// absolue IDs range from 0-71. +// To align with detector tower IDs (1 - n_towers_Phi) +// shift all indices by 37 and loop over after 72 +static constexpr int toweriPhi_fromAbsoluteID_shift_lowerHalf = 37; +static constexpr int toweriPhi_fromAbsoluteID_shift_upperHalf = 35; + +float getEta_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) { + int etaID = n_crystals_towerEta * (n_towers_per_link * ((link / n_links_card) % 2) + (tower % n_towers_per_link)) + + crystal % n_crystals_towerEta; + float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta); + return etaID * size_cell - ECAL_eta_range + half_crystal_size; +} + +float getPhi_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) { + int phiID = n_crystals_towerPhi * ((card * 24) + (n_links_card * (link / 8)) + (tower / n_towers_per_link)) + + crystal / n_crystals_towerPhi; + float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi); + return phiID * size_cell - M_PI + half_crystal_size; +} + +int getCrystal_etaID(float eta) { + float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta); + int etaID = int((eta + ECAL_eta_range) / size_cell); + return etaID; +} + +int convert_L2toL1_link(int link) { return link % n_links_card; } + +int convert_L2toL1_tower(int tower) { return tower; } + +int convert_L2toL1_card(int card, int link) { return card * n_clusters_4link + link / n_links_card; } + +int getCrystal_phiID(float phi) { + float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi); + int phiID = int((phi + M_PI) / size_cell); + return phiID; +} + +int getTower_absoluteEtaID(float eta) { + float size_cell = 2 * ECAL_eta_range / n_towers_Eta; + int etaID = int((eta + ECAL_eta_range) / size_cell); + return etaID; +} + +int getTower_absolutePhiID(float phi) { + float size_cell = 2 * M_PI / n_towers_Phi; + int phiID = int((phi + M_PI) / size_cell); + return phiID; +} + +int getToweriEta_fromAbsoluteID(int id) { + if (id < n_towers_per_link) + return id - n_towers_per_link; + else + return id - toweriEta_fromAbsoluteID_shift; +} + +int getToweriPhi_fromAbsoluteID(int id) { + if (id < n_towers_Phi / 2) + return id + toweriPhi_fromAbsoluteID_shift_lowerHalf; + else + return id - toweriPhi_fromAbsoluteID_shift_upperHalf; +} + +float getTowerEta_fromAbsoluteID(int id) { + float size_cell = 2 * ECAL_eta_range / n_towers_Eta; + float eta = (id * size_cell) - ECAL_eta_range + 0.5 * size_cell; + return eta; +} + +float getTowerPhi_fromAbsoluteID(int id) { + float size_cell = 2 * M_PI / n_towers_Phi; + float phi = (id * size_cell) - M_PI + 0.5 * size_cell; + return phi; +} + +int getCrystalIDInTower(int etaID, int phiID) { + return int(n_crystals_towerPhi * (phiID % n_crystals_towerPhi) + (etaID % n_crystals_towerEta)); +} + +int get_towerEta_fromCardTowerInCard(int card, int towerincard) { + return n_towers_per_link * (card % 2) + towerincard % n_towers_per_link; +} + +int get_towerPhi_fromCardTowerInCard(int card, int towerincard) { + return 4 * (card / 2) + towerincard / n_towers_per_link; +} + +int get_towerEta_fromCardLinkTower(int card, int link, int tower) { return n_towers_per_link * (card % 2) + tower; } + +int get_towerPhi_fromCardLinkTower(int card, int link, int tower) { return 4 * (card / 2) + link; } + +int getTowerID(int etaID, int phiID) { + return int(n_towers_per_link * ((phiID / n_crystals_towerPhi) % 4) + + (etaID / n_crystals_towerEta) % n_towers_per_link); +} + +int getTower_phiID(int cluster_phiID) { // Tower ID in card given crystal ID in total detector + return int((cluster_phiID / n_crystals_towerPhi) % 4); +} + +int getTower_etaID(int cluster_etaID) { // Tower ID in card given crystal ID in total detector + return int((cluster_etaID / n_crystals_towerEta) % n_towers_per_link); +} + +int getEtaMax_card(int card) { + int etamax = 0; + if (card % 2 == 0) + etamax = n_towers_per_link * n_crystals_towerEta - 1; // First eta half. 5 crystals in eta in 1 tower. + else + etamax = n_towers_Eta * n_crystals_towerEta - 1; + return etamax; +} + +int getEtaMin_card(int card) { + int etamin = 0; + if (card % 2 == 0) + etamin = 0 * n_crystals_towerEta; // First eta half. 5 crystals in eta in 1 tower. + else + etamin = n_towers_per_link * n_crystals_towerEta; + return etamin; +} + +int getPhiMax_card(int card) { + int phimax = ((card / 2) + 1) * 4 * n_crystals_towerPhi - 1; + return phimax; +} + +int getPhiMin_card(int card) { + int phimin = (card / 2) * 4 * n_crystals_towerPhi; + return phimin; +} + +class L1EGCrystalClusterEmulatorProducer : public edm::stream::EDProducer<> { +public: + explicit L1EGCrystalClusterEmulatorProducer(const edm::ParameterSet&); + ~L1EGCrystalClusterEmulatorProducer() override; + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + bool passes_ss(float pt, float ss); + bool passes_photon(float pt, float pss); + bool passes_iso(float pt, float iso); + bool passes_looseTkss(float pt, float ss); + bool passes_looseTkiso(float pt, float iso); + float get_calibrate(float uncorr); + + edm::EDGetTokenT ecalTPEBToken_; + edm::EDGetTokenT > hcalTPToken_; + edm::ESHandle decoder_; + + l1tp2::ParametricCalibration calib_; + + edm::ESHandle caloGeometry_; + const CaloSubdetectorGeometry* ebGeometry; + const CaloSubdetectorGeometry* hbGeometry; + edm::ESHandle hbTopology; + const HcalTopology* hcTopology_; + + struct mycluster { + float c2x2_; + float c2x5_; + float c5x5_; + int cshowershape_; + int cshowershapeloosetk_; + float cvalueshowershape_; + int cphotonshowershape_; + float cpt; // ECAL pt + int cbrem_; // if brem corrections were applied + float cWeightedEta_; + float cWeightedPhi_; + float ciso_; // pt of cluster divided by 7x7 ECAL towers + float chovere_; // 5x5 HCAL towers divided by the ECAL cluster pt + float craweta_; // coordinates between -1.44 and 1.44 + float crawphi_; // coordinates between -pi and pi + float chcal_; // 5x5 HCAL towers + float ceta_; // eta ID in the whole detector (between 0 and 5*34-1) + float cphi_; // phi ID in the whole detector (between 0 and 5*72-1) + int ccrystalid_; // crystal ID inside tower (between 0 and 24) + int cinsidecrystalid_; + int ctowerid_; // tower ID inside card (between 0 and 4*n_towers_per_link-1) + }; + + class SimpleCaloHit { + private: + float pt_ = 0; + float energy_ = 0.; + bool isEndcapHit_ = false; // If using endcap, we won't be using integer crystal indices + bool stale_ = false; // Hits become stale once used in clustering algorithm to prevent overlap in clusters + bool used_ = false; + GlobalVector position_; // As opposed to GlobalPoint, so we can add them (for weighted average) + HcalDetId id_hcal_; + EBDetId id_; + + public: + // tool functions + inline void setPt() { pt_ = (position_.mag2() > 0) ? energy_ * sin(position_.theta()) : 0; }; + inline void setEnergy(float et) { energy_ = et / sin(position_.theta()); }; + inline void setIsEndcapHit(bool isEC) { isEndcapHit_ = isEC; }; + inline void setUsed(bool isUsed) { used_ = isUsed; }; + inline void setPosition(const GlobalVector& pos) { position_ = pos; }; + inline void setIdHcal(const HcalDetId& idhcal) { id_hcal_ = idhcal; }; + inline void setId(const EBDetId& id) { id_ = id; }; + + inline float pt() const { return pt_; }; + inline float energy() const { return energy_; }; + inline bool isEndcapHit() const { return isEndcapHit_; }; + inline bool used() const { return used_; }; + inline const GlobalVector& position() const { return position_; }; + inline const EBDetId& id() const { return id_; }; + + inline float deta(SimpleCaloHit& other) const { return position_.eta() - other.position().eta(); }; + int dieta(SimpleCaloHit& other) const { + if (isEndcapHit_ || other.isEndcapHit()) + return 9999; // We shouldn't compare integer indices in endcap, the map is not linear + if (id_.ieta() * other.id().ieta() > 0) + return id_.ieta() - other.id().ieta(); + return id_.ieta() - other.id().ieta() - 1; + }; + inline float dphi(SimpleCaloHit& other) const { + return reco::deltaPhi(static_cast(position_.phi()), static_cast(other.position().phi())); + }; + int diphi(SimpleCaloHit& other) const { + if (isEndcapHit_ || other.isEndcapHit()) + return 9999; // We shouldn't compare integer indices in endcap, the map is not linear + // Logic from EBDetId::distancePhi() without the abs() + static constexpr int PI = 180; + int result = id().iphi() - other.id().iphi(); + while (result > PI) + result -= 2 * PI; + while (result <= -PI) + result += 2 * PI; + return result; + }; + float distanceTo(SimpleCaloHit& other) const { + // Treat position as a point, measure 3D distance + // This is used for endcap hits, where we don't have a rectangular mapping + return (position() - other.position()).mag(); + }; + bool operator==(SimpleCaloHit& other) const { + return (id_ == other.id() && position() == other.position() && energy_ == other.energy() && + isEndcapHit_ == other.isEndcapHit()); + }; + }; +}; + +L1EGCrystalClusterEmulatorProducer::L1EGCrystalClusterEmulatorProducer(const edm::ParameterSet& iConfig) + : ecalTPEBToken_(consumes(iConfig.getParameter("ecalTPEB"))), + hcalTPToken_( + consumes >(iConfig.getParameter("hcalTP"))), + calib_(iConfig.getParameter("calib")) { + produces(); + produces >(); + produces(); +} + +L1EGCrystalClusterEmulatorProducer::~L1EGCrystalClusterEmulatorProducer() {} + +void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + edm::Handle pcalohits; + iEvent.getByToken(ecalTPEBToken_, pcalohits); + + iSetup.get().get(caloGeometry_); + ebGeometry = caloGeometry_->getSubdetectorGeometry(DetId::Ecal, EcalBarrel); + hbGeometry = caloGeometry_->getSubdetectorGeometry(DetId::Hcal, HcalBarrel); + iSetup.get().get(hbTopology); + hcTopology_ = hbTopology.product(); + HcalTrigTowerGeometry theTrigTowerGeometry(hcTopology_); + iSetup.get().get(decoder_); + + //**************************************************************** + //******************* Get all the hits *************************** + //**************************************************************** + + // Get all the ECAL hits + iEvent.getByToken(ecalTPEBToken_, pcalohits); + std::vector ecalhits; + + for (const auto& hit : *pcalohits.product()) { + if (hit.encodedEt() > 0) // hit.encodedEt() returns an int corresponding to 2x the crystal Et + { + // Et is 10 bit, by keeping the ADC saturation Et at 120 GeV it means that you have to divide by 8 + float et = hit.encodedEt() / 8.; + if (et < cut_500_MeV) + continue; // keep the 500 MeV ET Cut + + auto cell = ebGeometry->getGeometry(hit.id()); + + SimpleCaloHit ehit; + ehit.setId(hit.id()); + ehit.setPosition(GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z())); + ehit.setEnergy(et); + ehit.setPt(); + ecalhits.push_back(ehit); + } + } + + // Get all the HCAL hits + std::vector hcalhits; + edm::Handle > hbhecoll; + iEvent.getByToken(hcalTPToken_, hbhecoll); + for (const auto& hit : *hbhecoll.product()) { + float et = decoder_->hcaletValue(hit.id(), hit.t0()); + if (et <= 0) + continue; + if (!(hcTopology_->validHT(hit.id()))) { + LogError("L1EGCrystalClusterEmulatorProducer") + << " -- Hcal hit DetID not present in HCAL Geom: " << hit.id() << std::endl; + throw cms::Exception("L1EGCrystalClusterEmulatorProducer"); + continue; + } + const std::vector& hcId = theTrigTowerGeometry.detIds(hit.id()); + if (hcId.empty()) { + LogError("L1EGCrystalClusterEmulatorProducer") + << "Cannot find any HCalDetId corresponding to " << hit.id() << std::endl; + throw cms::Exception("L1EGCrystalClusterEmulatorProducer"); + continue; + } + if (hcId[0].subdetId() > 1) + continue; + GlobalVector hcal_tp_position = GlobalVector(0., 0., 0.); + for (const auto& hcId_i : hcId) { + if (hcId_i.subdetId() > 1) + continue; + auto cell = hbGeometry->getGeometry(hcId_i); + if (cell == nullptr) + continue; + GlobalVector tmpVector = GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z()); + hcal_tp_position = tmpVector; + break; + } + SimpleCaloHit hhit; + hhit.setId(hit.id()); + hhit.setIdHcal(hit.id()); + hhit.setPosition(hcal_tp_position); + hhit.setEnergy(et); + hhit.setPt(); + hcalhits.push_back(hhit); + } + + //******************************************************************* + //********************** Do layer 1 ********************************* + //******************************************************************* + + // Definition of L1 outputs + // 36 L1 cards send each 4 links with 17 towers + float ECAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi]; + float HCAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi]; + int iEta_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi]; + int iPhi_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi]; + // 36 L1 cards send each 4 links with 3 clusters + float energy_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + // 36 L1 cards send each 4 links with 3 clusters + int brem_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + int towerID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + int crystalID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + int showerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + int showerShapeLooseTk_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + int photonShowerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi]; + + for (int ii = 0; ii < n_links_card; ++ii) { + for (int jj = 0; jj < n_towers_per_link; ++jj) { + for (int ll = 0; ll < n_towers_halfPhi; ++ll) { + ECAL_tower_L1Card[ii][jj][ll] = 0; + HCAL_tower_L1Card[ii][jj][ll] = 0; + iPhi_tower_L1Card[ii][jj][ll] = -999; + iEta_tower_L1Card[ii][jj][ll] = -999; + } + } + } + for (int ii = 0; ii < n_links_card; ++ii) { + for (int jj = 0; jj < n_clusters_link; ++jj) { + for (int ll = 0; ll < n_towers_halfPhi; ++ll) { + energy_cluster_L1Card[ii][jj][ll] = 0; + brem_cluster_L1Card[ii][jj][ll] = 0; + towerID_cluster_L1Card[ii][jj][ll] = 0; + crystalID_cluster_L1Card[ii][jj][ll] = 0; + } + } + } + + // There is one list of clusters per card. We take the 12 highest pt per card + vector cluster_list[n_towers_halfPhi]; + // After merging the clusters in different regions of a single L1 card + vector cluster_list_merged[n_towers_halfPhi]; + + for (int cc = 0; cc < n_towers_halfPhi; ++cc) { // Loop over 36 L1 cards + // Loop over 3x4 etaxphi regions to search for max 5 clusters + for (int nregion = 0; nregion <= n_clusters_max; ++nregion) { + int nclusters = 0; + bool build_cluster = true; + + // Continue until 5 clusters have been built or there is no cluster left + while (nclusters < n_clusters_max && build_cluster) { + build_cluster = false; + SimpleCaloHit centerhit; + + for (const auto& hit : ecalhits) { + if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && + // Check that the hit is in the good card + getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion && + !hit.used() && hit.pt() >= 1.0 && hit.pt() > centerhit.pt()) // 3 towers x 5 crystals + { + // Highest hit in good region with pt>1 and not used in any other cluster + centerhit = hit; + build_cluster = true; + } + } + if (build_cluster) + nclusters++; + + // Use only the 5 most energetic clusters + if (build_cluster && nclusters > 0 && nclusters <= n_clusters_max) { + mycluster mc1; + mc1.cpt = 0.0; + mc1.cWeightedEta_ = 0.0; + mc1.cWeightedPhi_ = 0.0; + float leftlobe = 0; + float rightlobe = 0; + float e5x5 = 0; + float n5x5 = 0; + float e2x5_1 = 0; + float n2x5_1 = 0; + float e2x5_2 = 0; + float n2x5_2 = 0; + float e2x2_1 = 0; + float n2x2_1 = 0; + float e2x2_2 = 0; + float n2x2_2 = 0; + float e2x2_3 = 0; + float n2x2_3 = 0; + float e2x2_4 = 0; + float n2x2_4 = 0; + for (auto& hit : ecalhits) { + if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0 && + getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion) { + if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) { + rightlobe += hit.pt(); + } + if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) { + leftlobe += hit.pt(); + } + if (abs(hit.dieta(centerhit)) <= 2 && abs(hit.diphi(centerhit)) <= 2) { + e5x5 += hit.energy(); + n5x5++; + } + if ((hit.dieta(centerhit) == 1 or hit.dieta(centerhit) == 0) && + (hit.diphi(centerhit) == 1 or hit.diphi(centerhit) == 0)) { + e2x2_1 += hit.energy(); + n2x2_1++; + } + if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) && + (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == 1)) { + e2x2_2 += hit.energy(); + n2x2_2++; + } + if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) && + (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) { + e2x2_3 += hit.energy(); + n2x2_3++; + } + if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) && + (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) { + e2x2_4 += hit.energy(); + n2x2_4++; + } + if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) && abs(hit.diphi(centerhit)) <= 2) { + e2x5_1 += hit.energy(); + n2x5_1++; + } + if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) && abs(hit.diphi(centerhit)) <= 2) { + e2x5_2 += hit.energy(); + n2x5_2++; + } + } + if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && !hit.used() && hit.pt() > 0 && + abs(hit.dieta(centerhit)) <= 1 && abs(hit.diphi(centerhit)) <= 2 && + getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion) { + // clusters 3x5 in etaxphi using only the hits in the corresponding card and in the corresponding 3x4 region + hit.setUsed(true); + mc1.cpt += hit.pt(); + mc1.cWeightedEta_ += float(hit.pt()) * float(hit.position().eta()); + mc1.cWeightedPhi_ = mc1.cWeightedPhi_ + (float(hit.pt()) * float(hit.position().phi())); + } + } + if (do_brem && (rightlobe > 0.10 * mc1.cpt or leftlobe > 0.10 * mc1.cpt)) { + for (auto& hit : ecalhits) { + if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0 && + getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion && + !hit.used()) { + if (rightlobe > 0.10 * mc1.cpt && (leftlobe < 0.10 * mc1.cpt or rightlobe > leftlobe) && + abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) { + mc1.cpt += hit.pt(); + hit.setUsed(true); + mc1.cbrem_ = 1; + } + if (leftlobe > 0.10 * mc1.cpt && (rightlobe < 0.10 * mc1.cpt or leftlobe >= rightlobe) && + abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) { + mc1.cpt += hit.pt(); + hit.setUsed(true); + mc1.cbrem_ = 1; + } + } + } + } + mc1.c5x5_ = e5x5; + mc1.c2x5_ = max(e2x5_1, e2x5_2); + mc1.c2x2_ = e2x2_1; + if (e2x2_2 > mc1.c2x2_) + mc1.c2x2_ = e2x2_2; + if (e2x2_3 > mc1.c2x2_) + mc1.c2x2_ = e2x2_3; + if (e2x2_4 > mc1.c2x2_) + mc1.c2x2_ = e2x2_4; + mc1.cWeightedEta_ = mc1.cWeightedEta_ / mc1.cpt; + mc1.cWeightedPhi_ = mc1.cWeightedPhi_ / mc1.cpt; + mc1.ceta_ = getCrystal_etaID(centerhit.position().eta()); + mc1.cphi_ = getCrystal_phiID(centerhit.position().phi()); + mc1.crawphi_ = centerhit.position().phi(); + mc1.craweta_ = centerhit.position().eta(); + cluster_list[cc].push_back(mc1); + } // End if 5 clusters per region + } // End while to find the 5 clusters + } // End loop over regions to search for clusters + std::sort(begin(cluster_list[cc]), end(cluster_list[cc]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; }); + + // Merge clusters from different regions + for (unsigned int jj = 0; jj < unsigned(cluster_list[cc].size()); ++jj) { + for (unsigned int kk = jj + 1; kk < unsigned(cluster_list[cc].size()); ++kk) { + if (std::abs(cluster_list[cc][jj].ceta_ - cluster_list[cc][kk].ceta_) < 2 && + std::abs(cluster_list[cc][jj].cphi_ - cluster_list[cc][kk].cphi_) < 2) { //Diagonale + exact neighbors + if (cluster_list[cc][kk].cpt > cluster_list[cc][jj].cpt) { + cluster_list[cc][kk].cpt += cluster_list[cc][jj].cpt; + cluster_list[cc][kk].c5x5_ += cluster_list[cc][jj].c5x5_; + cluster_list[cc][kk].c2x5_ += cluster_list[cc][jj].c2x5_; + cluster_list[cc][jj].cpt = 0; + cluster_list[cc][jj].c5x5_ = 0; + cluster_list[cc][jj].c2x5_ = 0; + cluster_list[cc][jj].c2x2_ = 0; + } else { + cluster_list[cc][jj].cpt += cluster_list[cc][kk].cpt; + cluster_list[cc][jj].c5x5_ += cluster_list[cc][kk].c5x5_; + cluster_list[cc][jj].c2x5_ += cluster_list[cc][kk].c2x5_; + cluster_list[cc][kk].cpt = 0; + cluster_list[cc][kk].c2x2_ = 0; + cluster_list[cc][kk].c2x5_ = 0; + cluster_list[cc][kk].c5x5_ = 0; + } + } + } + if (cluster_list[cc][jj].cpt > 0) { + cluster_list[cc][jj].cpt = + cluster_list[cc][jj].cpt * + calib_(cluster_list[cc][jj].cpt, + std::abs(cluster_list[cc][jj].craweta_)); //Mark's calibration as a function of eta and pt + cluster_list_merged[cc].push_back(cluster_list[cc][jj]); + } + } + std::sort(begin(cluster_list_merged[cc]), end(cluster_list_merged[cc]), [](mycluster a, mycluster b) { + return a.cpt > b.cpt; + }); + + // Fill cluster information in the arrays. We keep max 12 clusters (distributed between 4 links) + for (unsigned int jj = 0; jj < unsigned(cluster_list_merged[cc].size()) && jj < n_clusters_4link; ++jj) { + crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = + getCrystalIDInTower(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_); + towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = + getTowerID(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_); + energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cpt; + brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cbrem_; + if (passes_ss(cluster_list_merged[cc][jj].cpt, + cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_)) + showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1; + else + showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0; + if (passes_looseTkss(cluster_list_merged[cc][jj].cpt, + cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_)) + showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1; + else + showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0; + if (passes_photon(cluster_list_merged[cc][jj].cpt, + cluster_list_merged[cc][jj].c2x2_ / cluster_list_merged[cc][jj].c2x5_)) + photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1; + else + photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0; + } + + // Loop over calo ecal hits to get the ECAL towers. Take only hits that have not been used to make clusters + for (const auto& hit : ecalhits) { + if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && + !hit.used()) { // Take all the hits inside the card that have not been used yet + for (int jj = 0; jj < n_links_card; ++jj) { // loop over 4 links per card + if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % 4 == jj) { // Go to ID tower modulo 4 + for (int ii = 0; ii < n_towers_per_link; ++ii) { + //Apply Mark's calibration at the same time (row of the lowest pT, as a function of eta) + if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) { + ECAL_tower_L1Card[jj][ii][cc] += hit.pt() * calib_(0, std::abs(hit.position().eta())); + iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); //hit.id().ieta(); + iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); //hit.id().iphi(); + } + } // end of loop over eta towers + } + } // end of loop over phi links + // Make sure towers with 0 ET are initialized with proper iEta, iPhi coordinates + static constexpr float tower_width = 0.0873; + for (int jj = 0; jj < n_links_card; ++jj) { + for (int ii = 0; ii < n_towers_per_link; ++ii) { + float phi = getPhiMin_card(cc) * tower_width / n_crystals_towerPhi - M_PI + (jj + 0.5) * tower_width; + float eta = getEtaMin_card(cc) * tower_width / n_crystals_towerEta - n_towers_per_link * tower_width + + (ii + 0.5) * tower_width; + iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(eta); + iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(phi); + } + } + + } // end of check if inside card + } // end of loop over hits to build towers + + // Loop over hcal hits to get the HCAL towers. + for (const auto& hit : hcalhits) { + if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0) { + for (int jj = 0; jj < n_links_card; ++jj) { + if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % n_links_card == jj) { + for (int ii = 0; ii < n_towers_per_link; ++ii) { + if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) { + HCAL_tower_L1Card[jj][ii][cc] += hit.pt(); + iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); //hit.id().ieta(); + iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); //hit.id().iphi(); + } + } // end of loop over eta towers + } + } // end of loop over phi links + } // end of check if inside card + } // end of loop over hits to build towers + + // Give back energy of not used clusters to the towers (if there are more than 12 clusters) + for (unsigned int kk = n_clusters_4link; kk < cluster_list_merged[cc].size(); ++kk) { + if (cluster_list_merged[cc][kk].cpt > 0) { + ECAL_tower_L1Card[getTower_phiID(cluster_list_merged[cc][kk].cphi_)] + [getTower_etaID(cluster_list_merged[cc][kk].ceta_)][cc] += cluster_list_merged[cc][kk].cpt; + } + } + } //End of loop over cards + + //********************************************************* + //******************** Do layer 2 ************************* + //********************************************************* + + // Definition of L2 outputs + float HCAL_tower_L2Card[n_links_GCTcard][n_towers_per_link] + [n_GCTcards]; // 3 L2 cards send each 48 links with 17 towers + float ECAL_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards]; + int iEta_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards]; + int iPhi_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards]; + float energy_cluster_L2Card[n_links_GCTcard][n_clusters_per_link] + [n_GCTcards]; // 3 L2 cards send each 48 links with 2 clusters + float brem_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + int towerID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + int crystalID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + float isolation_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + float HE_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + int showerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + int showerShapeLooseTk_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + int photonShowerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards]; + + for (int ii = 0; ii < n_links_GCTcard; ++ii) { + for (int jj = 0; jj < n_towers_per_link; ++jj) { + for (int ll = 0; ll < n_GCTcards; ++ll) { + HCAL_tower_L2Card[ii][jj][ll] = 0; + ECAL_tower_L2Card[ii][jj][ll] = 0; + iEta_tower_L2Card[ii][jj][ll] = 0; + iPhi_tower_L2Card[ii][jj][ll] = 0; + } + } + } + for (int ii = 0; ii < n_links_GCTcard; ++ii) { + for (int jj = 0; jj < n_clusters_per_link; ++jj) { + for (int ll = 0; ll < n_GCTcards; ++ll) { + energy_cluster_L2Card[ii][jj][ll] = 0; + brem_cluster_L2Card[ii][jj][ll] = 0; + towerID_cluster_L2Card[ii][jj][ll] = 0; + crystalID_cluster_L2Card[ii][jj][ll] = 0; + isolation_cluster_L2Card[ii][jj][ll] = 0; + HE_cluster_L2Card[ii][jj][ll] = 0; + photonShowerShape_cluster_L2Card[ii][jj][ll] = 0; + showerShape_cluster_L2Card[ii][jj][ll] = 0; + showerShapeLooseTk_cluster_L2Card[ii][jj][ll] = 0; + } + } + } + + // There is one list of clusters per equivalent of L1 card. We take the 8 highest pt. + vector cluster_list_L2[n_towers_halfPhi]; + + // Merge clusters on the phi edges + for (int ii = 0; ii < n_borders_phi; ++ii) { // 18 borders in phi + for (int jj = 0; jj < n_eta_bins; ++jj) { // 2 eta bins + int card_left = 2 * ii + jj; + int card_right = 2 * ii + jj + 2; + if (card_right > 35) + card_right = card_right - n_towers_halfPhi; + for (int kk = 0; kk < n_clusters_4link; ++kk) { // 12 clusters in the first card. We check the right side + if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 && + crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 19 && + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) { + for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the 12 clusters in the card on the right + if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link && + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < 5 && + std::abs( + 5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) % n_towers_per_link + + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 - + 5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) % n_towers_per_link - + crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) < 2) { + if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) { + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] += + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]; + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0; + } // The least energetic cluster is merged to the most energetic one + else { + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] += + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]; + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0; + } + } + } + } + } + } + } + + // Bremsstrahlung corrections. Merge clusters on the phi edges depending on pT (pt more than 10 percent, dphi leq 5, deta leq 1) + if (do_brem) { + for (int ii = 0; ii < n_borders_phi; ++ii) { // 18 borders in phi + for (int jj = 0; jj < n_eta_bins; ++jj) { // 2 eta bins + int card_left = 2 * ii + jj; + int card_right = 2 * ii + jj + 2; + if (card_right > 35) + card_right = card_right - n_towers_halfPhi; + // 12 clusters in the first card. We check the right side crystalID_cluster_L1Card[kk%4][kk/4][card_left] + for (int kk = 0; kk < n_clusters_4link; ++kk) { + // if the tower is at the edge there might be brem corrections, whatever the crystal ID + if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 && + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) { + for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the 12 clusters in the card on the right + //Distance of 1 max in eta + if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link && + std::abs(5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) % + n_towers_per_link + + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 - + 5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) % + n_towers_per_link - + crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) <= 1) { + //Distance of 5 max in phi + if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link && + std::abs(5 + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] / 5 - + (crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] / 5)) <= 5) { + if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] && + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] > + 0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) { + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] += + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]; + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0; + brem_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 1; + } + // The least energetic cluster is merged to the most energetic one, if its pt is at least ten percent + else if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right] >= + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] && + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] > + 0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right]) { + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] += + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]; + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0; + brem_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 1; + } + } //max distance eta + } //max distance phi + } //max distance phi + } + } + } + } + } + + // Merge clusters on the eta edges + for (int ii = 0; ii < n_borders_eta; ++ii) { // 18 borders in eta + int card_bottom = 2 * ii; + int card_top = 2 * ii + 1; + for (int kk = 0; kk < n_clusters_4link; ++kk) { // 12 clusters in the first card. We check the top side + if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % n_towers_per_link == 16 && + crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % 5 == n_links_card && + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] > + 0) { // If there is one cluster on the right side of the first card + for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the card on the right + if (std::abs( + 5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / n_towers_per_link) + + crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / 5 - + 5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / n_towers_per_link) - + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / 5) < 2) { + if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] > + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_bottom]) { + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] += + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top]; + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] = 0; + } else { + energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] += + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom]; + energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] = 0; + } + } + } + } + } + } + + // Regroup the new clusters per equivalent of L1 card geometry + for (int ii = 0; ii < n_towers_halfPhi; ++ii) { + for (int jj = 0; jj < n_clusters_4link; ++jj) { + if (energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii] > 0) { + mycluster mc1; + mc1.cpt = energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + mc1.cbrem_ = brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + mc1.ctowerid_ = towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + mc1.ccrystalid_ = crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + mc1.cshowershape_ = showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + mc1.cshowershapeloosetk_ = showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + mc1.cphotonshowershape_ = photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii]; + cluster_list_L2[ii].push_back(mc1); + } + } + std::sort( + begin(cluster_list_L2[ii]), end(cluster_list_L2[ii]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; }); + } + + // If there are more than 8 clusters per equivalent of L1 card we need to put them back in the towers + for (int ii = 0; ii < n_towers_halfPhi; ++ii) { + for (unsigned int jj = 8; jj < n_clusters_4link && jj < cluster_list_L2[ii].size(); ++jj) { + if (cluster_list_L2[ii][jj].cpt > 0) { + ECAL_tower_L1Card[cluster_list_L2[ii][jj].ctowerid_ / n_towers_per_link] + [cluster_list_L2[ii][jj].ctowerid_ % n_towers_per_link][ii] += cluster_list_L2[ii][jj].cpt; + cluster_list_L2[ii][jj].cpt = 0; + cluster_list_L2[ii][jj].ctowerid_ = 0; + cluster_list_L2[ii][jj].ccrystalid_ = 0; + } + } + } + + // Compute isolation (7*7 ECAL towers) and HCAL energy (5x5 HCAL towers) + for (int ii = 0; ii < n_towers_halfPhi; ++ii) { // Loop over the new cluster list (stored in 36x8 format) + for (unsigned int jj = 0; jj < 8 && jj < cluster_list_L2[ii].size(); ++jj) { + int cluster_etaOfTower_fullDetector = get_towerEta_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_); + int cluster_phiOfTower_fullDetector = get_towerPhi_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_); + float hcal_nrj = 0.0; + float isolation = 0.0; + int ntowers = 0; + for (int iii = 0; iii < n_towers_halfPhi; ++iii) { // The clusters have to be added to the isolation + for (unsigned int jjj = 0; jjj < 8 && jjj < cluster_list_L2[iii].size(); ++jjj) { + if (!(iii == ii && jjj == jj)) { + int cluster2_eta = get_towerEta_fromCardTowerInCard(iii, cluster_list_L2[iii][jjj].ctowerid_); + int cluster2_phi = get_towerPhi_fromCardTowerInCard(iii, cluster_list_L2[iii][jjj].ctowerid_); + if (abs(cluster2_eta - cluster_etaOfTower_fullDetector) <= 2 && + (abs(cluster2_phi - cluster_phiOfTower_fullDetector) <= 2 or + abs(cluster2_phi - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) { + isolation += cluster_list_L2[iii][jjj].cpt; + } + } + } + } + for (int kk = 0; kk < n_towers_halfPhi; ++kk) { // 36 cards + for (int ll = 0; ll < n_links_card; ++ll) { // 4 links per card + for (int mm = 0; mm < n_towers_per_link; ++mm) { // 17 towers per link + int etaOftower_fullDetector = get_towerEta_fromCardLinkTower(kk, ll, mm); + int phiOftower_fullDetector = get_towerPhi_fromCardLinkTower(kk, ll, mm); + // First do ECAL + // The towers are within 3. Needs to stitch the two phi sides together + if (abs(etaOftower_fullDetector - cluster_etaOfTower_fullDetector) <= 2 && + (abs(phiOftower_fullDetector - cluster_phiOfTower_fullDetector) <= 2 or + abs(phiOftower_fullDetector - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) { + // Remove the column outside of the L2 card: values (0,71), (23,26), (24,21), (47,50), (48,50), (71,2) + if (!((cluster_phiOfTower_fullDetector == 0 && phiOftower_fullDetector == 71) or + (cluster_phiOfTower_fullDetector == 23 && phiOftower_fullDetector == 26) or + (cluster_phiOfTower_fullDetector == 24 && phiOftower_fullDetector == 21) or + (cluster_phiOfTower_fullDetector == 47 && phiOftower_fullDetector == 50) or + (cluster_phiOfTower_fullDetector == 48 && phiOftower_fullDetector == 45) or + (cluster_phiOfTower_fullDetector == 71 && phiOftower_fullDetector == 2))) { + isolation += ECAL_tower_L1Card[ll][mm][kk]; + ntowers++; + } + } + // Now do HCAL + // The towers are within 2. Needs to stitch the two phi sides together + if (abs(etaOftower_fullDetector - cluster_etaOfTower_fullDetector) <= 2 && + (abs(phiOftower_fullDetector - cluster_phiOfTower_fullDetector) <= 2 or + abs(phiOftower_fullDetector - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) { + hcal_nrj += HCAL_tower_L1Card[ll][mm][kk]; + } + } + } + } + cluster_list_L2[ii][jj].ciso_ = ((isolation) * (25.0 / ntowers)) / cluster_list_L2[ii][jj].cpt; + cluster_list_L2[ii][jj].chovere_ = hcal_nrj / cluster_list_L2[ii][jj].cpt; + } + } + + //Reformat the information inside the 3 L2 cards + //First let's fill the towers + for (int ii = 0; ii < n_links_GCTcard; ++ii) { + for (int jj = 0; jj < n_towers_per_link; ++jj) { + for (int ll = 0; ll < 3; ++ll) { + ECAL_tower_L2Card[ii][jj][ll] = + ECAL_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)]; + HCAL_tower_L2Card[ii][jj][ll] = + HCAL_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)]; + iEta_tower_L2Card[ii][jj][ll] = + iEta_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)]; + iPhi_tower_L2Card[ii][jj][ll] = + iPhi_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)]; + } + } + } + + //Second let's fill the clusters + for (int ii = 0; ii < n_towers_halfPhi; ++ii) { // The cluster list is still in the L1 like geometry + for (unsigned int jj = 0; jj < unsigned(cluster_list_L2[ii].size()) && jj < n_clusters_4link; ++jj) { + crystalID_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ccrystalid_; + towerID_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ctowerid_; + energy_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cpt; + brem_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cbrem_; + isolation_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ciso_; + HE_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].chovere_; + showerShape_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cshowershape_; + showerShapeLooseTk_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cshowershapeloosetk_; + photonShowerShape_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card] + [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cphotonshowershape_; + } + } + + auto L1EGXtalClusters = std::make_unique(); + auto L1EGammas = std::make_unique(); + auto L1CaloTowers = std::make_unique(); + + // Fill the cluster collection and towers as well + for (int ii = 0; ii < n_links_GCTcard; ++ii) { // 48 links + for (int ll = 0; ll < n_GCTcards; ++ll) { // 3 cards + // For looping over the Towers a few lines below + for (int jj = 0; jj < 2; ++jj) { // 2 L1EGs + if (energy_cluster_L2Card[ii][jj][ll] > 0.45) { + reco::Candidate::PolarLorentzVector p4calibrated( + energy_cluster_L2Card[ii][jj][ll], + getEta_fromL2LinkCardTowerCrystal( + ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]), + getPhi_fromL2LinkCardTowerCrystal( + ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]), + 0.); + SimpleCaloHit centerhit; + bool is_iso = passes_iso(energy_cluster_L2Card[ii][jj][ll], isolation_cluster_L2Card[ii][jj][ll]); + bool is_looseTkiso = + passes_looseTkiso(energy_cluster_L2Card[ii][jj][ll], isolation_cluster_L2Card[ii][jj][ll]); + bool is_ss = (showerShape_cluster_L2Card[ii][jj][ll] == 1); + bool is_photon = (photonShowerShape_cluster_L2Card[ii][jj][ll] == 1) && is_ss && is_iso; + bool is_looseTkss = (showerShapeLooseTk_cluster_L2Card[ii][jj][ll] == 1); + // All the ID set to Standalone WP! Some dummy values for non calculated variables + l1tp2::CaloCrystalCluster cluster(p4calibrated, + energy_cluster_L2Card[ii][jj][ll], + HE_cluster_L2Card[ii][jj][ll], + isolation_cluster_L2Card[ii][jj][ll], + centerhit.id(), + -1000, + float(brem_cluster_L2Card[ii][jj][ll]), + -1000, + -1000, + energy_cluster_L2Card[ii][jj][ll], + -1, + is_iso&& is_ss, + is_iso&& is_ss, + is_photon, + is_iso&& is_ss, + is_looseTkiso&& is_looseTkss, + is_iso&& is_ss); + // Experimental parameters, don't want to bother with hardcoding them in data format + std::map params; + params["standaloneWP_showerShape"] = is_ss; + params["standaloneWP_isolation"] = is_iso; + params["trkMatchWP_showerShape"] = is_looseTkss; + params["trkMatchWP_isolation"] = is_looseTkiso; + params["TTiEta"] = getToweriEta_fromAbsoluteID(getTower_absoluteEtaID(p4calibrated.eta())); + params["TTiPhi"] = getToweriPhi_fromAbsoluteID(getTower_absolutePhiID(p4calibrated.phi())); + cluster.setExperimentalParams(params); + L1EGXtalClusters->push_back(cluster); + + int standaloneWP = (int)(is_iso && is_ss); + int looseL1TkMatchWP = (int)(is_looseTkiso && is_looseTkss); + int photonWP = (int)(is_photon); + int quality = + (standaloneWP * std::pow(2, 0)) + (looseL1TkMatchWP * std::pow(2, 1)) + (photonWP * std::pow(2, 2)); + L1EGammas->push_back( + 0, l1t::EGamma(p4calibrated, p4calibrated.pt(), p4calibrated.eta(), p4calibrated.phi(), quality, 1)); + } + } + } + } + + for (int ii = 0; ii < n_links_GCTcard; ++ii) { // 48 links + for (int ll = 0; ll < n_GCTcards; ++ll) { // 3 cards + // Fill the tower collection + for (int jj = 0; jj < n_towers_per_link; ++jj) { // 17 TTs + l1tp2::CaloTower l1CaloTower; + l1CaloTower.setEcalTowerEt(ECAL_tower_L2Card[ii][jj][ll]); + l1CaloTower.setHcalTowerEt(HCAL_tower_L2Card[ii][jj][ll]); + l1CaloTower.setTowerIEta(getToweriEta_fromAbsoluteID(iEta_tower_L2Card[ii][jj][ll])); + l1CaloTower.setTowerIPhi(getToweriPhi_fromAbsoluteID(iPhi_tower_L2Card[ii][jj][ll])); + l1CaloTower.setTowerEta(getTowerEta_fromAbsoluteID(iEta_tower_L2Card[ii][jj][ll])); + l1CaloTower.setTowerPhi(getTowerPhi_fromAbsoluteID(iPhi_tower_L2Card[ii][jj][ll])); + // Some towers have incorrect eta/phi because that wasn't initialized in certain cases, fix these + static float constexpr towerEtaUpperUnitialized = -80; + static float constexpr towerPhiUpperUnitialized = -90; + if (l1CaloTower.towerEta() < towerEtaUpperUnitialized && l1CaloTower.towerPhi() < towerPhiUpperUnitialized) { + l1CaloTower.setTowerEta(l1t::CaloTools::towerEta(l1CaloTower.towerIEta())); + l1CaloTower.setTowerPhi(l1t::CaloTools::towerPhi(l1CaloTower.towerIEta(), l1CaloTower.towerIPhi())); + } + l1CaloTower.setIsBarrel(true); + + // Add L1EGs if they match in iEta / iPhi + // L1EGs are already pT ordered, we will take the ID info for the leading one, but pT as the sum + for (const auto& l1eg : *L1EGXtalClusters) { + if (l1eg.experimentalParam("TTiEta") != l1CaloTower.towerIEta()) + continue; + if (l1eg.experimentalParam("TTiPhi") != l1CaloTower.towerIPhi()) + continue; + + int n_L1eg = l1CaloTower.nL1eg(); + l1CaloTower.setNL1eg(n_L1eg++); + l1CaloTower.setL1egTowerEt(l1CaloTower.l1egTowerEt() + l1eg.pt()); + // Don't record L1EG quality info for subleading L1EG + if (l1CaloTower.nL1eg() > 1) + continue; + l1CaloTower.setL1egTrkSS(l1eg.experimentalParam("trkMatchWP_showerShape")); + l1CaloTower.setL1egTrkIso(l1eg.experimentalParam("trkMatchWP_isolation")); + l1CaloTower.setL1egStandaloneSS(l1eg.experimentalParam("standaloneWP_showerShape")); + l1CaloTower.setL1egStandaloneIso(l1eg.experimentalParam("standaloneWP_isolation")); + } + + L1CaloTowers->push_back(l1CaloTower); + } + } + } + + iEvent.put(std::move(L1EGXtalClusters)); + iEvent.put(std::move(L1EGammas)); + iEvent.put(std::move(L1CaloTowers)); +} + +bool L1EGCrystalClusterEmulatorProducer::passes_iso(float pt, float iso) { + if (pt < slideIsoPtThreshold) { + if (!((a0_80 - a1_80 * pt) > iso)) + return false; + } else { + if (iso > a0) + return false; + } + return true; +} + +bool L1EGCrystalClusterEmulatorProducer::passes_looseTkiso(float pt, float iso) { + return (b0 + b1 * std::exp(-b2 * pt) > iso); +} + +bool L1EGCrystalClusterEmulatorProducer::passes_ss(float pt, float ss) { + return ((c0_ss + c1_ss * std::exp(-c2_ss * pt)) <= ss); +} + +bool L1EGCrystalClusterEmulatorProducer::passes_photon(float pt, float pss) { return (pss > d0 - d1 * pt); } + +bool L1EGCrystalClusterEmulatorProducer::passes_looseTkss(float pt, float ss) { + return ((e0_looseTkss - e1_looseTkss * std::exp(-e2_looseTkss * pt)) <= ss); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1EGCrystalClusterEmulatorProducer); diff --git a/L1Trigger/L1CaloTrigger/plugins/L1EGammaEEProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1EGammaEEProducer.cc new file mode 100644 index 0000000000000..48d37445b3707 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/plugins/L1EGammaEEProducer.cc @@ -0,0 +1,169 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +namespace l1tp2 { + // we sort the clusters in pt + bool compare_cluster_pt(const l1t::HGCalMulticluster *cl1, const l1t::HGCalMulticluster *cl2) { + return cl1->pt() > cl2->pt(); + } +}; // namespace l1tp2 + +int etaBin(const l1t::HGCalMulticluster *cl) { + static float constexpr eta_min = 1.; + static float constexpr eta_max = 4.; + static unsigned constexpr n_eta_bins = 150; + int eta_bin = floor((std::abs(cl->eta()) - eta_min) / ((eta_max - eta_min) / n_eta_bins)); + if (cl->eta() < 0) + return -1 * eta_bin; // bin 0 doesn't exist + return eta_bin; +} + +int get_phi_bin(const l1t::HGCalMulticluster *cl) { + static constexpr float phi_min = -M_PI; + static constexpr float phi_max = M_PI; + static constexpr unsigned n_phi_bins = 63; + return floor(std::abs(reco::deltaPhi(cl->phi(), phi_min)) / ((phi_max - phi_min) / n_phi_bins)); +} + +pair get_eta_phi_bin(const l1t::HGCalMulticluster *cl) { return std::make_pair(etaBin(cl), get_phi_bin(cl)); } + +class L1EGammaEEProducer : public edm::stream::EDProducer<> { +public: + explicit L1EGammaEEProducer(const edm::ParameterSet &); + +private: + void produce(edm::Event &, const edm::EventSetup &) override; + + edm::EDGetToken multiclusters_token_; + L1EGammaEECalibrator calibrator_; +}; + +L1EGammaEEProducer::L1EGammaEEProducer(const edm::ParameterSet &iConfig) + : multiclusters_token_( + consumes(iConfig.getParameter("Multiclusters"))), + calibrator_(iConfig.getParameter("calibrationConfig")) { + produces>("L1EGammaCollectionBXVWithCuts"); +} + +void L1EGammaEEProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + float minEt_ = 0; + + std::unique_ptr> l1EgammaBxCollection(new l1t::EGammaBxCollection); + + // retrieve clusters 3D + edm::Handle multiclusters_h; + iEvent.getByToken(multiclusters_token_, multiclusters_h); + const l1t::HGCalMulticlusterBxCollection &multiclusters = *multiclusters_h; + + std::vector selected_multiclusters; + std::map, std::vector> etaphi_bins; + + // here we loop on the TPGs + for (auto cl3d = multiclusters.begin(0); cl3d != multiclusters.end(0); cl3d++) { + if (cl3d->hwQual()) { + if (cl3d->et() > minEt_) { + int hw_quality = 1; // baseline EG ID passed + if (std::abs(cl3d->eta()) >= 1.52) { + hw_quality = 2; // baseline EG ID passed + cleanup of transition region + } + + float calib_factor = calibrator_.calibrationFactor(cl3d->pt(), cl3d->eta()); + l1t::EGamma eg = + l1t::EGamma(reco::Candidate::PolarLorentzVector(cl3d->pt() / calib_factor, cl3d->eta(), cl3d->phi(), 0.)); + eg.setHwQual(hw_quality); + eg.setHwIso(1); + eg.setIsoEt(-1); // just temporarily as a dummy value + l1EgammaBxCollection->push_back(0, eg); + if (hw_quality == 2) { + // we build the EM interpreted EG object + l1t::EGamma eg_emint = l1t::EGamma(reco::Candidate::PolarLorentzVector( + cl3d->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), cl3d->eta(), cl3d->phi(), 0.)); + eg_emint.setHwQual(4); + eg_emint.setHwIso(1); + eg_emint.setIsoEt(-1); // just temporarily as a dummy value + l1EgammaBxCollection->push_back(0, eg_emint); + // we also prepare for the brem recovery procedure + selected_multiclusters.push_back(&(*cl3d)); + auto eta_phi_bin = get_eta_phi_bin(&(*cl3d)); + auto bucket = etaphi_bins.find(eta_phi_bin); + if (bucket == etaphi_bins.end()) { + std::vector vec; + vec.push_back(&(*cl3d)); + etaphi_bins[eta_phi_bin] = vec; + } else { + bucket->second.push_back(&(*cl3d)); + } + } + } + } + } + + std::sort(selected_multiclusters.begin(), selected_multiclusters.end(), l1tp2::compare_cluster_pt); + std::set used_clusters; + for (const auto &cl3d : selected_multiclusters) { + if (used_clusters.find(cl3d) == used_clusters.end()) { + float pt = cl3d->pt(); + // we drop the Had component of the energy + if (cl3d->hOverE() != -1) + pt = cl3d->pt() / (1 + cl3d->hOverE()); + reco::Candidate::PolarLorentzVector mom(pt, cl3d->eta(), cl3d->phi(), 0.); + reco::Candidate::PolarLorentzVector mom_eint( + cl3d->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), cl3d->eta(), cl3d->phi(), 0.); + + // this is not yet used + used_clusters.insert(cl3d); + auto eta_phi_bin = get_eta_phi_bin(cl3d); + + for (int eta_bin : {eta_phi_bin.first - 1, eta_phi_bin.first, eta_phi_bin.first + 1}) { + for (int phi_bin : {eta_phi_bin.second - 1, eta_phi_bin.second, eta_phi_bin.second + 1}) { + auto bucket = etaphi_bins.find(std::make_pair(eta_bin, phi_bin)); + if (bucket != etaphi_bins.end()) { + // this bucket is not empty + for (const auto &other_cl_ptr : bucket->second) { + if (used_clusters.find(other_cl_ptr) == used_clusters.end()) { + if (std::abs(other_cl_ptr->eta() - cl3d->eta()) < 0.02) { + if (std::abs(reco::deltaPhi(other_cl_ptr->phi(), cl3d->phi())) < 0.1) { + float pt_other = other_cl_ptr->pt(); + if (other_cl_ptr->hOverE() != -1) + pt_other = other_cl_ptr->pt() / (1 + other_cl_ptr->hOverE()); + mom += reco::Candidate::PolarLorentzVector(pt_other, other_cl_ptr->eta(), other_cl_ptr->phi(), 0.); + mom_eint += reco::Candidate::PolarLorentzVector( + other_cl_ptr->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), + other_cl_ptr->eta(), + other_cl_ptr->phi(), + 0.); + used_clusters.insert(other_cl_ptr); + } + } + } + } + } + } + } + float calib_factor = calibrator_.calibrationFactor(mom.pt(), mom.eta()); + l1t::EGamma eg = + l1t::EGamma(reco::Candidate::PolarLorentzVector(mom.pt() / calib_factor, mom.eta(), mom.phi(), 0.)); + eg.setHwQual(3); + eg.setHwIso(1); + l1EgammaBxCollection->push_back(0, eg); + + l1t::EGamma eg_emint_brec = + l1t::EGamma(reco::Candidate::PolarLorentzVector(mom_eint.pt(), mom_eint.eta(), mom_eint.phi(), 0.)); + eg_emint_brec.setHwQual(5); + eg_emint_brec.setHwIso(1); + l1EgammaBxCollection->push_back(0, eg_emint_brec); + } + } + + iEvent.put(std::move(l1EgammaBxCollection), "L1EGammaCollectionBXVWithCuts"); +} + +DEFINE_FWK_MODULE(L1EGammaEEProducer); diff --git a/L1Trigger/L1CaloTrigger/python/L1EGammaCrystalsEmulatorProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/L1EGammaCrystalsEmulatorProducer_cfi.py new file mode 100644 index 0000000000000..16280501c0d10 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/L1EGammaCrystalsEmulatorProducer_cfi.py @@ -0,0 +1,35 @@ +import FWCore.ParameterSet.Config as cms + +L1EGammaClusterEmuProducer = cms.EDProducer("L1EGCrystalClusterEmulatorProducer", + ecalTPEB = cms.InputTag("simEcalEBTriggerPrimitiveDigis","","HLT"), + hcalTP = cms.InputTag("simHcalTriggerPrimitiveDigis","","HLT"), + calib = cms.PSet( + + etaBins = cms.vdouble( 0.087 , 0.174 , 0.261 , 0.348 , 0.435 , 0.522 , 0.609 , 0.696 , 0.783 , 0.870 , 0.957 , 1.044 , 1.131 , 1.218 , 1.305 , 1.392 , 1.479), + ptBins = cms.vdouble( 12, 20, 30, 40, 55, 90, 1e6), + scale = cms.vdouble( + # pt < 12 + 1.18*1.1 ,1.17*1.1 ,1.19*1.1 ,1.18*1.1 ,1.19*1.1 ,1.19*1.1 ,1.19*1.1 ,1.18*1.1 ,1.19*1.1 ,1.18*1.1 ,1.19*1.1 ,1.19*1.1 ,1.19*1.1 ,1.20*1.1 ,1.19*1.1 ,1.20*1.1 ,1.19*1.1, + # pt < 20 + 1.14*1.03 ,1.13*1.03 ,1.13*1.03 ,1.13*1.03 ,1.13*1.03 ,1.13*1.03 ,1.13*1.03 ,1.14*1.03 ,1.14*1.03 ,1.13*1.03 ,1.13*1.03 ,1.14*1.03 ,1.13*1.03 ,1.13*1.03 ,1.14*1.03 ,1.14*1.03 ,1.12*1.03, + # pt < 30 + 1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.11 ,1.10, + # pt < 40 + 1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09 ,1.09, + # pt < 55 + 1.07 ,1.07 ,1.07 ,1.07 ,1.07 ,1.07 ,1.07 ,1.08 ,1.07 ,1.07 ,1.08 ,1.08 ,1.07 ,1.08 ,1.08 ,1.08 ,1.08, + # pt < 90 + 1.06 ,1.06 ,1.06 ,1.06 ,1.05 ,1.05 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06 ,1.06, + # pt < 1e6 + 1.04 ,1.04 ,1.04 ,1.04 ,1.05 ,1.04 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05 ,1.05, + + ), + + ), +) + +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(L1EGammaClusterEmuProducer, + ecalTPEB = cms.InputTag("DMEcalEBTriggerPrimitiveDigis","","HLT"), + hcalTP = cms.InputTag("DMHcalTriggerPrimitiveDigis","","HLT"), +) diff --git a/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py new file mode 100644 index 0000000000000..dcadde6ad3a59 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py @@ -0,0 +1,184 @@ +import FWCore.ParameterSet.Config as cms + +L1TowerCalibrationProducer = cms.EDProducer("L1TowerCalibrator", + # Choosen settings 6 March 2019, 10_3_X MTD samples + HcalTpEtMin = cms.double(0.5), + EcalTpEtMin = cms.double(0.5), + HGCalHadTpEtMin = cms.double(0.25), + HGCalEmTpEtMin = cms.double(0.25), + HFTpEtMin = cms.double(0.5), + puThreshold = cms.double(5.0), + puThresholdL1eg = cms.double(2.0), + puThresholdHcalMin = cms.double(1.0), + puThresholdHcalMax = cms.double(2.0), + puThresholdEcalMin = cms.double(0.75), + puThresholdEcalMax = cms.double(1.5), + puThresholdHGCalEMMin = cms.double(1.25), + puThresholdHGCalEMMax = cms.double(1.75), + puThresholdHGCalHadMin = cms.double(0.75), + puThresholdHGCalHadMax = cms.double(1.25), + puThresholdHFMin = cms.double(10.0), + puThresholdHFMax = cms.double(15.0), + + puThresholdEcal = cms.double(2.0), + puThresholdHcal = cms.double(3.0), + + barrelSF = cms.double(1.0), + hgcalSF = cms.double(1.0), + hfSF = cms.double(1.0), + debug = cms.bool(False), + skipCalibrations = cms.bool(False), + l1CaloTowers = cms.InputTag("L1EGammaClusterEmuProducer",), + L1HgcalTowersInputTag = cms.InputTag("hgcalTowerProducer:HGCalTowerProcessor"), + hcalDigis = cms.InputTag("simHcalTriggerPrimitiveDigis"), + nHits_to_nvtx_params = cms.VPSet( # Parameters derived on 6 March 2019 on 10_3_X MTD samples + cms.PSet( + fit = cms.string( "hf" ), + params = cms.vdouble( 165.706, 0.153 ) + ), + cms.PSet( + fit = cms.string( "ecal" ), + params = cms.vdouble( 168.055, 0.377 ) + ), + cms.PSet( + fit = cms.string( "hgcalEM" ), + params = cms.vdouble( 157.522, 0.090 ) + ), + cms.PSet( + fit = cms.string( "hgcalHad" ), + params = cms.vdouble( 159.295, 0.178 ) + ), + cms.PSet( + fit = cms.string( "hcal" ), + params = cms.vdouble( 168.548, 0.362 ) + ), + ), + + nvtx_to_PU_sub_params = cms.VPSet( + cms.PSet( + calo = cms.string( "ecal" ), + iEta = cms.string( "er1to3" ), + params = cms.vdouble( 0.008955, 0.000298 ) + ), + cms.PSet( + calo = cms.string( "ecal" ), + iEta = cms.string( "er4to6" ), + params = cms.vdouble( 0.009463, 0.000256 ) + ), + cms.PSet( + calo = cms.string( "ecal" ), + iEta = cms.string( "er7to9" ), + params = cms.vdouble( 0.008783, 0.000293 ) + ), + cms.PSet( + calo = cms.string( "ecal" ), + iEta = cms.string( "er10to12" ), + params = cms.vdouble( 0.009308, 0.000255 ) + ), + cms.PSet( + calo = cms.string( "ecal" ), + iEta = cms.string( "er13to15" ), + params = cms.vdouble( 0.009290, 0.000221 ) + ), + cms.PSet( + calo = cms.string( "ecal" ), + iEta = cms.string( "er16to18" ), + params = cms.vdouble( 0.009282, 0.000135 ) + ), + cms.PSet( + calo = cms.string( "hcal" ), + iEta = cms.string( "er1to3" ), + params = cms.vdouble( 0.009976, 0.000377 ) + ), + cms.PSet( + calo = cms.string( "hcal" ), + iEta = cms.string( "er4to6" ), + params = cms.vdouble( 0.009803, 0.000394 ) + ), + cms.PSet( + calo = cms.string( "hcal" ), + iEta = cms.string( "er7to9" ), + params = cms.vdouble( 0.009654, 0.000429 ) + ), + cms.PSet( + calo = cms.string( "hcal" ), + iEta = cms.string( "er10to12" ), + params = cms.vdouble( 0.009107, 0.000528 ) + ), + cms.PSet( + calo = cms.string( "hcal" ), + iEta = cms.string( "er13to15" ), + params = cms.vdouble( 0.008367, 0.000652 ) + ), + cms.PSet( + calo = cms.string( "hcal" ), + iEta = cms.string( "er16to18" ), + params = cms.vdouble( 0.009681, 0.000096 ) + ), + cms.PSet( + calo = cms.string( "hgcalEM" ), + iEta = cms.string( "er1p4to1p8" ), + params = cms.vdouble( -0.011772, 0.004142 ) + ), + cms.PSet( + calo = cms.string( "hgcalEM" ), + iEta = cms.string( "er1p8to2p1" ), + params = cms.vdouble( -0.015488, 0.005410 ) + ), + cms.PSet( + calo = cms.string( "hgcalEM" ), + iEta = cms.string( "er2p1to2p4" ), + params = cms.vdouble( -0.021150, 0.006078 ) + ), + cms.PSet( + calo = cms.string( "hgcalEM" ), + iEta = cms.string( "er2p4to2p7" ), + params = cms.vdouble( -0.015705, 0.005339 ) + ), + cms.PSet( + calo = cms.string( "hgcalEM" ), + iEta = cms.string( "er2p7to3p1" ), + params = cms.vdouble( -0.018492, 0.005620 ) + ), + cms.PSet( + calo = cms.string( "hgcalHad" ), + iEta = cms.string( "er1p4to1p8" ), + params = cms.vdouble( 0.005675, 0.000615 ) + ), + cms.PSet( + calo = cms.string( "hgcalHad" ), + iEta = cms.string( "er1p8to2p1" ), + params = cms.vdouble( 0.004560, 0.001099 ) + ), + cms.PSet( + calo = cms.string( "hgcalHad" ), + iEta = cms.string( "er2p1to2p4" ), + params = cms.vdouble( 0.000036, 0.001608 ) + ), + cms.PSet( + calo = cms.string( "hgcalHad" ), + iEta = cms.string( "er2p4to2p7" ), + params = cms.vdouble( 0.000869, 0.001754 ) + ), + cms.PSet( + calo = cms.string( "hgcalHad" ), + iEta = cms.string( "er2p7to3p1" ), + params = cms.vdouble( -0.006574, 0.003134 ) + ), + cms.PSet( + calo = cms.string( "hf" ), + iEta = cms.string( "er29to33" ), + params = cms.vdouble( -0.203291, 0.044096 ) + ), + cms.PSet( + calo = cms.string( "hf" ), + iEta = cms.string( "er34to37" ), + params = cms.vdouble( -0.210922, 0.045628 ) + ), + cms.PSet( + calo = cms.string( "hf" ), + iEta = cms.string( "er38to41" ), + params = cms.vdouble( -0.229562, 0.050560 ) + ), + ) +) diff --git a/L1Trigger/L1CaloTrigger/python/l1EGammaCrystalsProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/l1EGammaCrystalsProducer_cfi.py new file mode 100644 index 0000000000000..3e90790d23df4 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/l1EGammaCrystalsProducer_cfi.py @@ -0,0 +1,17 @@ +import FWCore.ParameterSet.Config as cms + +l1EGammaCrystalsProducer = cms.EDProducer("L1EGCrystalClusterProducer", + EtminForStore = cms.double(0.), + EcalTpEtMin = cms.untracked.double(0.5), # 500 MeV default per each Ecal TP + EtMinForSeedHit = cms.untracked.double(1.0), # 1 GeV decault for seed hit + debug = cms.untracked.bool(False), + useRecHits = cms.untracked.bool(False), + doBremClustering = cms.untracked.bool(True), # Should always be True when using for E/Gamma + ecalTPEB = cms.InputTag("simEcalEBTriggerPrimitiveDigis","","HLT"), + ecalRecHitEB = cms.InputTag("ecalRecHit","EcalRecHitsEB","RECO"), + hcalRecHit = cms.InputTag("hbhereco"), + hcalTP = cms.InputTag("simHcalTriggerPrimitiveDigis","","HLT"), + useTowerMap = cms.untracked.bool(False) +) + + diff --git a/L1Trigger/L1CaloTrigger/python/l1EGammaEEProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/l1EGammaEEProducer_cfi.py new file mode 100644 index 0000000000000..161e8e8faa27e --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/l1EGammaEEProducer_cfi.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +l1EGammaEEProducer = cms.EDProducer("L1EGammaEEProducer", + calibrationConfig = cms.PSet(calibrationFile = cms.FileInPath('L1Trigger/L1TCalorimeter/data/calib_ee_v1.json')), + Multiclusters=cms.InputTag('hgcalBackEndLayer2Producer:HGCalBackendLayer2Processor3DClustering')) diff --git a/L1Trigger/L1CaloTrigger/python/ntuple_cfi.py b/L1Trigger/L1CaloTrigger/python/ntuple_cfi.py new file mode 100644 index 0000000000000..0abf49530f41d --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/ntuple_cfi.py @@ -0,0 +1,16 @@ +import FWCore.ParameterSet.Config as cms + +ntuple_egammaEE = cms.PSet( + NtupleName = cms.string('L1TriggerNtupleEgammaEE'), + EgammaEE = cms.InputTag('l1EGammaEEProducer:L1EGammaCollectionBXVWithCuts') +) + +ntuple_TTTracks = cms.PSet( + NtupleName = cms.string('L1TriggerNtupleTrackTrigger'), + TTTracks = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") +) + +ntuple_tkEle = cms.PSet( + NtupleName = cms.string('L1TriggerNtupleTkElectrons'), + TkElectrons = cms.InputTag("L1TkElectrons","EG") +) diff --git a/L1Trigger/L1CaloTrigger/python/test_L1EGCrystalClusterEmulator_cfg.py b/L1Trigger/L1CaloTrigger/python/test_L1EGCrystalClusterEmulator_cfg.py new file mode 100644 index 0000000000000..12d320d1ee80b --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/test_L1EGCrystalClusterEmulator_cfg.py @@ -0,0 +1,76 @@ +import FWCore.ParameterSet.Config as cms + +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("L1AlgoTest",eras.Phase2C4) + +process.load('Configuration.StandardSequences.Services_cff') +process.load("FWCore.MessageService.MessageLogger_cfi") +process.load('Configuration.EventContent.EventContent_cff') +process.MessageLogger.categories = cms.untracked.vstring('L1EGRateStudies', 'FwkReport') +process.MessageLogger.cerr.FwkReport = cms.untracked.PSet( + reportEvery = cms.untracked.int32(1) +) + +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) + +process.source = cms.Source("PoolSource", + # Set to do test run on official Phase-2 L1T Ntuples + fileNames = cms.untracked.vstring('file:root://cmsxrootd.fnal.gov///store/mc/PhaseIISpring17D/SingleE_FlatPt-8to100/GEN-SIM-DIGI-RAW/PU200_90X_upgrade2023_realistic_v9-v1/120000/04B4BF1D-1E2C-E711-BE1C-7845C4FC39D1.root'), + inputCommands = cms.untracked.vstring( + "keep *", + "drop l1tEMTFHitExtras_simEmtfDigis_CSC_HLT", + "drop l1tEMTFHitExtras_simEmtfDigis_RPC_HLT", + "drop l1tEMTFTrackExtras_simEmtfDigis__HLT", + ) +) + +# All this stuff just runs the various EG algorithms that we are studying + +# ---- Global Tag : +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, '100X_upgrade2023_realistic_v1', '') + +# Choose a 2023 geometry! +process.load('Configuration.Geometry.GeometryExtended2023D17Reco_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') + +# Add HCAL Transcoder +process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') +process.load('CalibCalorimetry.CaloTPG.CaloTPGTranscoder_cfi') + + + + +# -------------------------------------------------------------------------------------------- +# +# ---- Produce the L1EGCrystal clusters using Emulator + + +process.load('L1Trigger.L1CaloTrigger.L1EGammaCrystalsEmulatorProducer_cfi') + +process.pL1EG = cms.Path( process.L1EGammaClusterEmuProducer ) + + + + +process.Out = cms.OutputModule( "PoolOutputModule", + fileName = cms.untracked.string( "l1egCrystalTest.root" ), + fastCloning = cms.untracked.bool( False ), + outputCommands = cms.untracked.vstring( + "keep *_L1EGammaClusterEmuProducer_*_*", + "keep *_TriggerResults_*_*", + "keep *_simHcalTriggerPrimitiveDigis_*_*", + "keep *_EcalEBTrigPrimProducer_*_*" + ) +) + +process.end = cms.EndPath( process.Out ) + + + +dump_file = open("dump_file.py", "w") +dump_file.write(process.dumpPython()) + + diff --git a/L1Trigger/L1CaloTrigger/src/L1EGammaEECalibrator.cc b/L1Trigger/L1CaloTrigger/src/L1EGammaEECalibrator.cc new file mode 100644 index 0000000000000..ddd9ee590a12c --- /dev/null +++ b/L1Trigger/L1CaloTrigger/src/L1EGammaEECalibrator.cc @@ -0,0 +1,61 @@ +#include "L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "boost/property_tree/ptree.hpp" +#include "boost/property_tree/json_parser.hpp" +#include + +namespace l1tp2 { + std::vector as_vector(boost::property_tree::ptree const& pt, + boost::property_tree::ptree::key_type const& key) { + std::vector ret; + for (const auto& item : pt.get_child(key)) + ret.push_back(item.second.get_value()); + return ret; + } +}; // namespace l1tp2 + +L1EGammaEECalibrator::L1EGammaEECalibrator(const edm::ParameterSet& pset) { + //read the JSON file and populate the eta - pt bins and the value container + boost::property_tree::ptree calibration_map; + read_json(pset.getParameter("calibrationFile").fullPath(), calibration_map); + + auto eta_l = l1tp2::as_vector(calibration_map, "eta_l"); + std::copy(eta_l.begin(), eta_l.end(), std::inserter(eta_bins, eta_bins.end())); + auto eta_h = l1tp2::as_vector(calibration_map, "eta_h"); + eta_bins.insert(eta_h.back()); + + auto pt_l = l1tp2::as_vector(calibration_map, "pt_l"); + std::copy(pt_l.begin(), pt_l.end(), std::inserter(pt_bins, pt_bins.end())); + auto pt_h = l1tp2::as_vector(calibration_map, "pt_h"); + pt_bins.insert(pt_h.back()); + + auto calib_data = l1tp2::as_vector(calibration_map, "calib"); + auto n_bins_eta = eta_bins.size(); + auto n_bins_pt = pt_bins.size(); + calib_factors.reserve(n_bins_eta * n_bins_pt); + for (auto calib_f = calib_data.begin(); calib_f != calib_data.end(); ++calib_f) { + auto index = calib_f - calib_data.begin(); + int eta_bin = etaBin(eta_l[index]); + int pt_bin = ptBin(pt_l[index]); + calib_factors[(eta_bin * n_bins_pt) + pt_bin] = *calib_f; + } +} + +int L1EGammaEECalibrator::bin(const std::set& container, float value) const { + auto bin_l = container.upper_bound(value); + if (bin_l == container.end()) { + // value not mapped to any bin + return -1; + } + return std::distance(container.begin(), bin_l) - 1; +} + +float L1EGammaEECalibrator::calibrationFactor(const float& pt, const float& eta) const { + int bin_eta = etaBin(eta); + int bin_pt = ptBin(pt); + if (bin_eta == -1 || bin_pt == -1) + return 1.; + auto n_bins_pt = pt_bins.size(); + return calib_factors[(bin_eta * n_bins_pt) + bin_pt]; +} diff --git a/L1Trigger/L1CaloTrigger/src/ParametricCalibration.cc b/L1Trigger/L1CaloTrigger/src/ParametricCalibration.cc new file mode 100644 index 0000000000000..60560f431fc01 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/src/ParametricCalibration.cc @@ -0,0 +1,49 @@ +#include "L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h" + +namespace l1tp2 { + ParametricCalibration::ParametricCalibration(const edm::ParameterSet& cpset) { + std::vector etaBins = cpset.getParameter>("etaBins"); + std::vector ptBins = cpset.getParameter>("ptBins"); + std::vector scale = cpset.getParameter>("scale"); + etas.insert(etas.end(), etaBins.begin(), etaBins.end()); + pts.insert(pts.end(), ptBins.begin(), ptBins.end()); + scales.insert(scales.end(), scale.begin(), scale.end()); + + if (pts.size() * etas.size() != scales.size()) + throw cms::Exception("Configuration", + "Bad number of calibration scales, pts.size() * etas.size() != scales.size()"); + } + + // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ + void ParametricCalibration::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.setComment(""); + desc.addUntracked>("etaBins", std::vector{}); + desc.addUntracked>("ptBins", std::vector{}); + desc.addUntracked>("scale", std::vector{}); + descriptions.add("createIdealTkAlRecords", desc); + } + + float ParametricCalibration::operator()(const float pt, const float abseta) const { + int ptBin = -1; + for (unsigned int i = 0, n = pts.size(); i < n; ++i) { + if (pt < pts[i]) { + ptBin = i; + break; + } + } + int etaBin = -1; + for (unsigned int i = 0, n = etas.size(); i < n; ++i) { + if (abseta < etas[i]) { + etaBin = i; + break; + } + } + + if (ptBin == -1 || etaBin == -1) + return 1; + else + return scales[ptBin * etas.size() + etaBin]; + } + +}; // namespace l1tp2 diff --git a/L1Trigger/L1TGlobal/interface/PrescalesVetosFractHelper.h b/L1Trigger/L1TGlobal/interface/PrescalesVetosFractHelper.h new file mode 100644 index 0000000000000..2b43093b50892 --- /dev/null +++ b/L1Trigger/L1TGlobal/interface/PrescalesVetosFractHelper.h @@ -0,0 +1,83 @@ +#ifndef PRESCALESVETOSFRACTHELPERS_H__ +#define PRESCALESVETOSFRACTHELPERS_H__ + +#include +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" + +// If you want to create a new object that you can read and write, use this constructor: +// +// l1t::PrescalesVetosFractHelper x(new L1TPrescalesVetosFract()); +// +// If you wish to read the table from the EventSetup, and will only read, use this: +// +// const PrescalesVetosFractHelper * x = PrescalesVetoFractsHelper::readFromEventSetup(...) +// //... +// delete x; +// +// If you wish to read the table from the EventSetup, but then be able to edit the values locally, use this: +// +// PrescalesVetosFractHelper * x = PrescalesVetosFractHelper::readAndWriteFromEventSetup(...) +// //... +/// delete x; +// +// but there's a performance penalty as a copy is made. + +// +// This class does not take over responsibility for deleting the pointers it is +// initialized with. That is responsibility of the calling code. +// + +namespace l1t { + + class PrescalesVetosFractHelper { + public: + enum { VERSION_ = 1 }; + + ~PrescalesVetosFractHelper(); + + //ctor if creating a new table (e.g. from XML or python file) + PrescalesVetosFractHelper(L1TGlobalPrescalesVetosFract* w); + //create for reading only, from the EventSetup: + static const PrescalesVetosFractHelper* readFromEventSetup(const L1TGlobalPrescalesVetosFract* es); + // create for reading and writing, starting from the EventSetup: + static PrescalesVetosFractHelper* readAndWriteFromEventSetup(const L1TGlobalPrescalesVetosFract* es); + + int bxMaskDefault() const { return read_->bxmask_default_; }; + void setBxMaskDefault(int value) { + check_write(); + write_->bxmask_default_ = value; + }; + + inline const std::vector >& prescaleTable() const { return read_->prescale_table_; }; + void setPrescaleFactorTable(std::vector > value) { + check_write(); + write_->prescale_table_ = value; + }; + inline const std::vector& triggerMaskVeto() const { return read_->veto_; }; + void setTriggerMaskVeto(std::vector value) { + check_write(); + write_->veto_ = value; + }; + + inline const std::map >& triggerAlgoBxMask() const { return read_->bxmask_map_; }; + void setTriggerAlgoBxMask(std::map > value) { + check_write(); + write_->bxmask_map_ = value; + }; + + // access to underlying pointers, mainly for ESProducer: + const L1TGlobalPrescalesVetosFract* getReadInstance() const { return read_; } + L1TGlobalPrescalesVetosFract* getWriteInstance() { return write_; } + + private: + PrescalesVetosFractHelper(const L1TGlobalPrescalesVetosFract* es); + void useCopy(); + void check_write() { assert(write_); } + // separating read from write allows for a high-performance read-only mode (as no copy is made): + const L1TGlobalPrescalesVetosFract* read_; // when reading/getting, use this. + L1TGlobalPrescalesVetosFract* write_; // when writing/setting, use this. + bool we_own_write_; + }; + +} // namespace l1t +#endif diff --git a/L1Trigger/L1TGlobal/src/PrescalesVetosFractHelper.cc b/L1Trigger/L1TGlobal/src/PrescalesVetosFractHelper.cc new file mode 100644 index 0000000000000..9d5c9018dadd0 --- /dev/null +++ b/L1Trigger/L1TGlobal/src/PrescalesVetosFractHelper.cc @@ -0,0 +1,38 @@ +#include "L1Trigger/L1TGlobal/interface/PrescalesVetosFractHelper.h" + +using namespace l1t; + +const PrescalesVetosFractHelper* PrescalesVetosFractHelper::readFromEventSetup(const L1TGlobalPrescalesVetosFract* es) { + return new PrescalesVetosFractHelper(es); +} + +PrescalesVetosFractHelper* PrescalesVetosFractHelper::readAndWriteFromEventSetup( + const L1TGlobalPrescalesVetosFract* es) { + PrescalesVetosFractHelper* x = new PrescalesVetosFractHelper(es); + x->useCopy(); + return x; +} + +PrescalesVetosFractHelper::PrescalesVetosFractHelper(L1TGlobalPrescalesVetosFract* w) { + write_ = w; + check_write(); + we_own_write_ = false; + write_->version_ = VERSION_; + read_ = write_; +} + +PrescalesVetosFractHelper::PrescalesVetosFractHelper(const L1TGlobalPrescalesVetosFract* es) { + read_ = es; + write_ = nullptr; +} + +void PrescalesVetosFractHelper::useCopy() { + write_ = new L1TGlobalPrescalesVetosFract(*read_); + we_own_write_ = true; + read_ = write_; +} + +PrescalesVetosFractHelper::~PrescalesVetosFractHelper() { + if (we_own_write_ && write_) + delete write_; +} diff --git a/L1Trigger/L1THGCal/interface/HGCalProcessorBase.h b/L1Trigger/L1THGCal/interface/HGCalProcessorBase.h index d2928f178bee1..10a3b6bdaa326 100644 --- a/L1Trigger/L1THGCal/interface/HGCalProcessorBase.h +++ b/L1Trigger/L1THGCal/interface/HGCalProcessorBase.h @@ -11,8 +11,11 @@ #include "DataFormats/L1THGCal/interface/HGCalTowerMap.h" #include "DataFormats/L1THGCal/interface/HGCalTower.h" +#include + typedef HGCalProcessorBaseT HGCalVFEProcessorBase; -typedef HGCalProcessorBaseT, l1t::HGCalTriggerCellBxCollection> +typedef HGCalProcessorBaseT, + std::pair > HGCalConcentratorProcessorBase; typedef HGCalProcessorBaseT, l1t::HGCalClusterBxCollection> HGCalBackendLayer1ProcessorBase; diff --git a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorBestChoiceImpl.h b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorBestChoiceImpl.h index 7203f4490239a..9057cab77d2ba 100644 --- a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorBestChoiceImpl.h +++ b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorBestChoiceImpl.h @@ -13,7 +13,8 @@ class HGCalConcentratorBestChoiceImpl { void select(unsigned nLinks, unsigned nWafers, const std::vector& trigCellVecInput, - std::vector& trigCellVecOutput); + std::vector& trigCellVecOutput, + std::vector& trigCellVecNotSelected); void eventSetup(const edm::EventSetup& es) { triggerTools_.eventSetup(es); } diff --git a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorProcessorSelection.h b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorProcessorSelection.h index bc1a8dcd17fa1..21f5f720b15b2 100644 --- a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorProcessorSelection.h +++ b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorProcessorSelection.h @@ -6,11 +6,14 @@ #include "L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorBestChoiceImpl.h" #include "L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorSuperTriggerCellImpl.h" #include "L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorCoarsenerImpl.h" +#include "L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorTrigSumImpl.h" #include "L1Trigger/L1THGCal/interface/HGCalTriggerTools.h" #include "DataFormats/L1THGCal/interface/HGCalTriggerCell.h" #include "DataFormats/L1THGCal/interface/HGCalTriggerSums.h" +#include + class HGCalConcentratorProcessorSelection : public HGCalConcentratorProcessorBase { private: enum SelectionType { thresholdSelect, bestChoiceSelect, superTriggerCellSelect, noSelection }; @@ -19,7 +22,7 @@ class HGCalConcentratorProcessorSelection : public HGCalConcentratorProcessorBas HGCalConcentratorProcessorSelection(const edm::ParameterSet& conf); void run(const edm::Handle& triggerCellCollInput, - l1t::HGCalTriggerCellBxCollection& triggerCellCollOutput, + std::pair& triggerCollOutput, const edm::EventSetup& es) override; private: @@ -34,6 +37,7 @@ class HGCalConcentratorProcessorSelection : public HGCalConcentratorProcessorBas std::unique_ptr bestChoiceImpl_; std::unique_ptr superTriggerCellImpl_; std::unique_ptr coarsenerImpl_; + std::unique_ptr trigSumImpl_; HGCalTriggerTools triggerTools_; }; diff --git a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorThresholdImpl.h b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorThresholdImpl.h index 1623746dee9e0..9fb0ea4e07bae 100644 --- a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorThresholdImpl.h +++ b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorThresholdImpl.h @@ -11,7 +11,8 @@ class HGCalConcentratorThresholdImpl { HGCalConcentratorThresholdImpl(const edm::ParameterSet& conf); void select(const std::vector& trigCellVecInput, - std::vector& trigCellVecOutput); + std::vector& trigCellVecOutput, + std::vector& trigCellVecNotSelected); void eventSetup(const edm::EventSetup& es) { triggerTools_.eventSetup(es); } diff --git a/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorTrigSumImpl.h b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorTrigSumImpl.h new file mode 100644 index 0000000000000..484c30ba24073 --- /dev/null +++ b/L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorTrigSumImpl.h @@ -0,0 +1,24 @@ +#ifndef __L1Trigger_L1THGCal_HGCalConcentratorTrigSumImpl_h__ +#define __L1Trigger_L1THGCal_HGCalConcentratorTrigSumImpl_h__ + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/L1THGCal/interface/HGCalTriggerCell.h" +#include "DataFormats/L1THGCal/interface/HGCalTriggerSums.h" +#include "L1Trigger/L1THGCal/interface/HGCalTriggerTools.h" +#include + +class HGCalConcentratorTrigSumImpl { +public: + HGCalConcentratorTrigSumImpl(const edm::ParameterSet& conf); + + void doSum(uint32_t module_id, + const std::vector& trigCellVecInput, + std::vector& trigSumsVecOutput) const; + + void eventSetup(const edm::EventSetup& es) { triggerTools_.eventSetup(es); } + +private: + HGCalTriggerTools triggerTools_; +}; + +#endif diff --git a/L1Trigger/L1THGCal/plugins/BuildFile.xml b/L1Trigger/L1THGCal/plugins/BuildFile.xml index cfbf8a906b574..63ea8c6be6049 100644 --- a/L1Trigger/L1THGCal/plugins/BuildFile.xml +++ b/L1Trigger/L1THGCal/plugins/BuildFile.xml @@ -12,6 +12,7 @@ + diff --git a/L1Trigger/L1THGCal/plugins/HGCalConcentratorProducer.cc b/L1Trigger/L1THGCal/plugins/HGCalConcentratorProducer.cc index 169934d535216..dd41b4b4e389f 100644 --- a/L1Trigger/L1THGCal/plugins/HGCalConcentratorProducer.cc +++ b/L1Trigger/L1THGCal/plugins/HGCalConcentratorProducer.cc @@ -14,6 +14,7 @@ #include "L1Trigger/L1THGCal/interface/HGCalProcessorBase.h" #include +#include class HGCalConcentratorProducer : public edm::stream::EDProducer<> { public: @@ -54,16 +55,14 @@ void HGCalConcentratorProducer::beginRun(const edm::Run& /*run*/, const edm::Eve void HGCalConcentratorProducer::produce(edm::Event& e, const edm::EventSetup& es) { // Output collections - auto cc_trigcell_output = std::make_unique(); - auto cc_trigsums_output = std::make_unique(); + std::pair cc_output; // Input collections edm::Handle trigCellBxColl; e.getByToken(input_cell_, trigCellBxColl); - concentratorProcess_->run(trigCellBxColl, *cc_trigcell_output, es); + concentratorProcess_->run(trigCellBxColl, cc_output, es); // Put in the event - // At the moment the HGCalTriggerSumsBxCollection is empty - e.put(std::move(cc_trigcell_output), concentratorProcess_->name()); - e.put(std::move(cc_trigsums_output), concentratorProcess_->name()); + e.put(std::make_unique(std::move(cc_output.first)), concentratorProcess_->name()); + e.put(std::make_unique(std::move(cc_output.second)), concentratorProcess_->name()); } diff --git a/L1Trigger/L1THGCal/plugins/concentrator/HGCalConcentratorProcessorSelection.cc b/L1Trigger/L1THGCal/plugins/concentrator/HGCalConcentratorProcessorSelection.cc index dab0986be4899..424850424e13e 100644 --- a/L1Trigger/L1THGCal/plugins/concentrator/HGCalConcentratorProcessorSelection.cc +++ b/L1Trigger/L1THGCal/plugins/concentrator/HGCalConcentratorProcessorSelection.cc @@ -21,10 +21,14 @@ HGCalConcentratorProcessorSelection::HGCalConcentratorProcessorSelection(const e selectionType_[subdet] = thresholdSelect; if (!thresholdImpl_) thresholdImpl_ = std::make_unique(conf); + if (!trigSumImpl_) + trigSumImpl_ = std::make_unique(conf); } else if (selectionType[subdet] == "bestChoiceSelect") { selectionType_[subdet] = bestChoiceSelect; if (!bestChoiceImpl_) bestChoiceImpl_ = std::make_unique(conf); + if (!trigSumImpl_) + trigSumImpl_ = std::make_unique(conf); } else if (selectionType[subdet] == "superTriggerCellSelect") { selectionType_[subdet] = superTriggerCellSelect; if (!superTriggerCellImpl_) @@ -43,9 +47,10 @@ HGCalConcentratorProcessorSelection::HGCalConcentratorProcessorSelection(const e } } -void HGCalConcentratorProcessorSelection::run(const edm::Handle& triggerCellCollInput, - l1t::HGCalTriggerCellBxCollection& triggerCellCollOutput, - const edm::EventSetup& es) { +void HGCalConcentratorProcessorSelection::run( + const edm::Handle& triggerCellCollInput, + std::pair& triggerCollOutput, + const edm::EventSetup& es) { if (thresholdImpl_) thresholdImpl_->eventSetup(es); if (bestChoiceImpl_) @@ -54,8 +59,13 @@ void HGCalConcentratorProcessorSelection::run(const edm::HandleeventSetup(es); if (coarsenerImpl_) coarsenerImpl_->eventSetup(es); + if (trigSumImpl_) + trigSumImpl_->eventSetup(es); triggerTools_.eventSetup(es); + auto& triggerCellCollOutput = triggerCollOutput.first; + auto& triggerSumCollOutput = triggerCollOutput.second; + const l1t::HGCalTriggerCellBxCollection& collInput = *triggerCellCollInput; std::unordered_map> tc_modules; @@ -67,6 +77,8 @@ void HGCalConcentratorProcessorSelection::run(const edm::Handle trigCellVecOutput; std::vector trigCellVecCoarsened; + std::vector trigCellVecNotSelected; + std::vector trigSumsVecOutput; int thickness = triggerTools_.thicknessIndex(module_trigcell.second.at(0).detId(), true); @@ -77,19 +89,21 @@ void HGCalConcentratorProcessorSelection::run(const edm::Handleselect(trigCellVecCoarsened, trigCellVecOutput); + thresholdImpl_->select(trigCellVecCoarsened, trigCellVecOutput, trigCellVecNotSelected); break; case bestChoiceSelect: if (triggerTools_.isEm(module_trigcell.first)) { bestChoiceImpl_->select(geometry_->getLinksInModule(module_trigcell.first), geometry_->getModuleSize(module_trigcell.first), module_trigcell.second, - trigCellVecOutput); + trigCellVecOutput, + trigCellVecNotSelected); } else { bestChoiceImpl_->select(geometry_->getLinksInModule(module_trigcell.first), geometry_->getModuleSize(module_trigcell.first), trigCellVecCoarsened, - trigCellVecOutput); + trigCellVecOutput, + trigCellVecNotSelected); } break; case superTriggerCellSelect: @@ -106,13 +120,14 @@ void HGCalConcentratorProcessorSelection::run(const edm::Handleselect(module_trigcell.second, trigCellVecOutput); + thresholdImpl_->select(module_trigcell.second, trigCellVecOutput, trigCellVecNotSelected); break; case bestChoiceSelect: bestChoiceImpl_->select(geometry_->getLinksInModule(module_trigcell.first), geometry_->getModuleSize(module_trigcell.first), module_trigcell.second, - trigCellVecOutput); + trigCellVecOutput, + trigCellVecNotSelected); break; case superTriggerCellSelect: superTriggerCellImpl_->select(module_trigcell.second, trigCellVecOutput); @@ -126,8 +141,16 @@ void HGCalConcentratorProcessorSelection::run(const edm::HandledoSum(module_trigcell.first, trigCellVecNotSelected, trigSumsVecOutput); + } + for (const auto& trigCell : trigCellVecOutput) { triggerCellCollOutput.push_back(0, trigCell); } + for (const auto& trigSums : trigSumsVecOutput) { + triggerSumCollOutput.push_back(0, trigSums); + } } } diff --git a/L1Trigger/L1THGCal/plugins/geometries/HGCalTriggerGeometryV9Imp2.cc b/L1Trigger/L1THGCal/plugins/geometries/HGCalTriggerGeometryV9Imp2.cc index 45776be1824a0..a78add1871c75 100644 --- a/L1Trigger/L1THGCal/plugins/geometries/HGCalTriggerGeometryV9Imp2.cc +++ b/L1Trigger/L1THGCal/plugins/geometries/HGCalTriggerGeometryV9Imp2.cc @@ -9,6 +9,7 @@ #include "L1Trigger/L1THGCal/interface/HGCalTriggerGeometryBase.h" #include "DataFormats/ForwardDetId/interface/HFNoseDetIdToModule.h" +#include "tbb/concurrent_unordered_set.h" #include #include #include @@ -64,6 +65,7 @@ class HGCalTriggerGeometryV9Imp2 : public HGCalTriggerGeometryBase { std::unordered_map wafer_to_module_; std::unordered_multimap module_to_wafers_; std::unordered_map links_per_module_; + mutable tbb::concurrent_unordered_set cache_missing_wafers_; // Disconnected modules and layers std::unordered_set disconnected_modules_; @@ -111,6 +113,7 @@ HGCalTriggerGeometryV9Imp2::HGCalTriggerGeometryV9Imp2(const edm::ParameterSet& void HGCalTriggerGeometryV9Imp2::reset() { wafer_to_module_.clear(); module_to_wafers_.clear(); + cache_missing_wafers_.clear(); } void HGCalTriggerGeometryV9Imp2::initialize(const CaloGeometry* calo_geometry) { @@ -268,13 +271,20 @@ unsigned HGCalTriggerGeometryV9Imp2::getModuleFromTriggerCell(const unsigned tri int waferu = trigger_cell_trig_id.waferU(); int waferv = trigger_cell_trig_id.waferV(); unsigned layer_with_offset = layerWithOffset(trigger_cell_id); - auto module_itr = wafer_to_module_.find(packLayerWaferId(layer_with_offset, waferu, waferv)); + unsigned packed_wafer = packLayerWaferId(layer_with_offset, waferu, waferv); + auto module_itr = wafer_to_module_.find(packed_wafer); if (module_itr == wafer_to_module_.end()) { - throw cms::Exception("BadGeometry") - << trigger_cell_trig_id << "HGCalTriggerGeometry: Wafer (" << waferu << "," << waferv - << ") is not mapped to any trigger module. The module mapping should be modified. \n"; + // return missing modules as disconnected (id=0) + module = 0; + auto insert_itr = cache_missing_wafers_.emplace(packed_wafer); + if (insert_itr.second) { + edm::LogWarning("HGCalTriggerGeometry") + << "Found missing wafer (layer=" << layer_with_offset << " u=" << waferu << " v=" << waferv + << ") in trigger modules mapping"; + } + } else { + module = module_itr->second; } - module = module_itr->second; } module_id = HGCalDetId((ForwardSubdetector)subdet_old, zside, layer, tc_type, module, HGCalDetId::kHGCalCellMask).rawId(); diff --git a/L1Trigger/L1THGCal/python/customTriggerGeometry.py b/L1Trigger/L1THGCal/python/customTriggerGeometry.py index 8d0d6b024afe6..bc4cd946b66cb 100644 --- a/L1Trigger/L1THGCal/python/customTriggerGeometry.py +++ b/L1Trigger/L1THGCal/python/customTriggerGeometry.py @@ -11,7 +11,7 @@ def custom_geometry_decentralized_V11(process, links='signaldriven'): process.hgcalTriggerGeometryESProducer.TriggerGeometry.TriggerGeometryName = cms.string('HGCalTriggerGeometryV9Imp2') process.hgcalTriggerGeometryESProducer.TriggerGeometry.ScintillatorTriggerCellSize = cms.uint32(2) process.hgcalTriggerGeometryESProducer.TriggerGeometry.ScintillatorModuleSize = cms.uint32(6) - process.hgcalTriggerGeometryESProducer.TriggerGeometry.L1TModulesMapping = cms.FileInPath("L1Trigger/L1THGCal/data/panel_mapping_V11_decentralized_march20_0.txt") + process.hgcalTriggerGeometryESProducer.TriggerGeometry.L1TModulesMapping = cms.FileInPath("L1Trigger/L1THGCal/data/panel_mapping_V11_decentralized_march20_1.txt") process.hgcalTriggerGeometryESProducer.TriggerGeometry.L1TLinksMapping = cms.FileInPath(links_mapping) process.hgcalTriggerGeometryESProducer.TriggerGeometry.DisconnectedModules = cms.vuint32(0) process.hgcalTriggerGeometryESProducer.TriggerGeometry.ScintillatorLinksPerModule = cms.uint32(2) diff --git a/L1Trigger/L1THGCal/python/egammaIdentification.py b/L1Trigger/L1THGCal/python/egammaIdentification.py index fb1c51d755cbc..e54e1bfc5197c 100644 --- a/L1Trigger/L1THGCal/python/egammaIdentification.py +++ b/L1Trigger/L1THGCal/python/egammaIdentification.py @@ -1,6 +1,8 @@ import FWCore.ParameterSet.Config as cms from Configuration.Eras.Modifier_phase2_hgcalV9_cff import phase2_hgcalV9 +from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 inputs_small = ['cl3d_firstlayer', 'cl3d_coreshowerlength', 'cl3d_maxlayer', 'cl3d_srrmean'] inputs_large = ['cl3d_coreshowerlength', 'cl3d_showerlength', 'cl3d_firstlayer', 'cl3d_maxlayer', 'cl3d_szz', 'cl3d_srrmean', 'cl3d_srrtot', 'cl3d_seetot', 'cl3d_spptot'] @@ -75,7 +77,8 @@ def __init__(self, eta_min, eta_max, pt_min, pt_max): input_features_histomax = { "v8_352":inputs_small, "v9_370":inputs_large, - "v9_394":inputs_large + "v9_394":inputs_large, + "v10_3151":inputs_large } bdt_weights_histomax = { @@ -96,6 +99,12 @@ def __init__(self, eta_min, eta_max, pt_min, pt_max): 'L1Trigger/L1THGCal/data/egamma_id_histomax_394_loweta_v0.xml', # High eta 'L1Trigger/L1THGCal/data/egamma_id_histomax_394_higheta_v0.xml' + ], + "v10_3151":[ #trained using TPG software version 3.15.1 + # Low eta + 'L1Trigger/L1THGCal/data/egamma_id_histomax_3151_loweta_v0.xml', + # High eta + 'L1Trigger/L1THGCal/data/egamma_id_histomax_3151_higheta_v0.xml' ] } @@ -128,7 +137,7 @@ def __init__(self, eta_min, eta_max, pt_min, pt_max): { '900':0.7078400, #epsilon_b = 3.5% '950':-0.0239623, #epsilon_b = 6.9% - '975':-0.7045071, #epsilon_b = 11.6% + '975':-0.7045071, #epsilon_b = 11.6% '995':-0.9811426, #epsilon_b = 26.1% } ], @@ -144,9 +153,25 @@ def __init__(self, eta_min, eta_max, pt_min, pt_max): { '900':0.8825340, #epsilon_b = 1.0% '950':0.2856039, #epsilon_b = 1.7% - '975':-0.5274948, #epsilon_b = 2.8% + '975':-0.5274948, #epsilon_b = 2.8% '995':-0.9864445, #epsilon_b = 7.6% } + ], + "v10_3151": [ + # Low eta + { + '900': 0.9903189, + '950': 0.9646683, + '975': 0.8292287, + '995': -0.7099538, + }, + # High eta + { + '900': 0.9932326, + '950': 0.9611762, + '975': 0.7616282, + '995': -0.9163715, + } ] } @@ -192,3 +217,19 @@ def __init__(self, eta_min, eta_max, pt_min, pt_max): [wps[eff] for wps,eff in zip(working_points_histomax['v9_394'],tight_wp)] ) ) + +phase2_hgcalV10.toModify(egamma_identification_histomax, + Inputs=cms.vstring(input_features_histomax['v10_3151']), + Weights=cms.vstring(bdt_weights_histomax['v10_3151']), + WorkingPoints=cms.vdouble( + [wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)] + ) + ) + +phase2_hgcalV11.toModify(egamma_identification_histomax, + Inputs=cms.vstring(input_features_histomax['v10_3151']), + Weights=cms.vstring(bdt_weights_histomax['v10_3151']), + WorkingPoints=cms.vdouble( + [wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)] + ) + ) diff --git a/L1Trigger/L1THGCal/python/hgcalBackEndLayer2Producer_cfi.py b/L1Trigger/L1THGCal/python/hgcalBackEndLayer2Producer_cfi.py index 70729f0b7f3cd..165ba5ee1e385 100644 --- a/L1Trigger/L1THGCal/python/hgcalBackEndLayer2Producer_cfi.py +++ b/L1Trigger/L1THGCal/python/hgcalBackEndLayer2Producer_cfi.py @@ -6,6 +6,7 @@ from Configuration.Eras.Modifier_phase2_hgcalV9_cff import phase2_hgcalV9 from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 from Configuration.Eras.Modifier_phase2_hfnose_cff import phase2_hfnose @@ -144,15 +145,22 @@ energy_interpretations_em = cms.PSet(type = cms.string('HGCalTriggerClusterInterpretationEM'), - layer_containment_corrs = cms.vdouble(0., 0., 1.6144949, 0.92495334, 1.0820811, 0.9753549, 0.9742881, 1.0634482, 1.0599478, 0.9376349, 0.92587173, 0.8003076, 1.0417082, 1.7032381, 2.), - scale_correction_coeff = cms.vdouble(16.68182373, -8.487143517), + layer_containment_corrs = cms.vdouble(0., 0.0, 1.38, 0.97, 1.11, 0.92, 1.06, 1.01, 1.06, 0.89, 1.0, 1.06, 0.89, 1.62, 1.83), + scale_correction_coeff = cms.vdouble(53.94, -27.15), dr_bylayer = cms.vdouble([0.015]*15) ) -phase2_hgcalV10.toModify(energy_interpretations_em, - layer_containment_corrs=cms.vdouble(0., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.), - scale_correction_coeff=cms.vdouble(0., 0.), - ) +phase2_hgcalV10.toModify( + energy_interpretations_em, + layer_containment_corrs=cms.vdouble(0., 0.0, 1.73, 0.97, 1.08, 1.1, 1.01, 0.96, 1.18, 0.98, 1.05, 0.99, 0.89, 1.75, 2.0), + scale_correction_coeff=cms.vdouble(53.92, -27.53), + ) + +phase2_hgcalV11.toModify( + energy_interpretations_em, + layer_containment_corrs=cms.vdouble(0., 0.0, 1.28, 1.09, 1.0, 1.07, 1.09, 1.04, 1.0, 1.09, 1.07, 1.03, 0.93, 1.4, 1.89), + scale_correction_coeff=cms.vdouble(52.99, -24.96), + ) energy_interpretations = cms.VPSet(energy_interpretations_em) diff --git a/L1Trigger/L1THGCal/python/hgcalTriggerPrimitives_cff.py b/L1Trigger/L1THGCal/python/hgcalTriggerPrimitives_cff.py index 8e9fa1545df50..27548946f3919 100644 --- a/L1Trigger/L1THGCal/python/hgcalTriggerPrimitives_cff.py +++ b/L1Trigger/L1THGCal/python/hgcalTriggerPrimitives_cff.py @@ -22,7 +22,7 @@ from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 from L1Trigger.L1THGCal.customTriggerGeometry import custom_geometry_decentralized_V9, custom_geometry_decentralized_V11 from L1Trigger.L1THGCal.customCalibration import custom_cluster_calibration_global -modifyHgcalTriggerPrimitivesWithV9Geometry_ = phase2_hgcalV9.makeProcessModifier(custom_geometry_decentralized_V9) +modifyHgcalTriggerPrimitivesWithV9Geometry_ = (phase2_hgcalV9 & ~phase2_hgcalV11).makeProcessModifier(custom_geometry_decentralized_V9) modifyHgcalTriggerPrimitivesWithV11Geometry_ = phase2_hgcalV11.makeProcessModifier(custom_geometry_decentralized_V11) from Configuration.ProcessModifiers.convertHGCalDigisSim_cff import convertHGCalDigisSim diff --git a/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorBestChoiceImpl.cc b/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorBestChoiceImpl.cc index 569590927d3ce..941163e0d4a18 100644 --- a/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorBestChoiceImpl.cc +++ b/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorBestChoiceImpl.cc @@ -15,8 +15,10 @@ HGCalConcentratorBestChoiceImpl::HGCalConcentratorBestChoiceImpl(const edm::Para void HGCalConcentratorBestChoiceImpl::select(unsigned nLinks, unsigned nWafers, const std::vector& trigCellVecInput, - std::vector& trigCellVecOutput) { + std::vector& trigCellVecOutput, + std::vector& trigCellVecNotSelected) { trigCellVecOutput = trigCellVecInput; + trigCellVecNotSelected.resize(0); // sort, reverse order std::sort( trigCellVecOutput.begin(), @@ -36,6 +38,10 @@ void HGCalConcentratorBestChoiceImpl::select(unsigned nLinks, << " NWafers=" << nWafers << " and NLinks=" << nLinks; } // keep only N trigger cells - if (trigCellVecOutput.size() > nData) + if (trigCellVecOutput.size() > nData) { + // store the last cells (not selected) + std::move(trigCellVecOutput.begin() + nData, trigCellVecOutput.end(), std::back_inserter(trigCellVecNotSelected)); + // keep only N trigger cells trigCellVecOutput.resize(nData); + } } diff --git a/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorThresholdImpl.cc b/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorThresholdImpl.cc index 8f3413643fa28..95f6d46b17cce 100644 --- a/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorThresholdImpl.cc +++ b/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorThresholdImpl.cc @@ -5,12 +5,15 @@ HGCalConcentratorThresholdImpl::HGCalConcentratorThresholdImpl(const edm::Parame threshold_scintillator_(conf.getParameter("threshold_scintillator")) {} void HGCalConcentratorThresholdImpl::select(const std::vector& trigCellVecInput, - std::vector& trigCellVecOutput) { + std::vector& trigCellVecOutput, + std::vector& trigCellVecNotSelected) { for (const auto& trigCell : trigCellVecInput) { bool isScintillator = triggerTools_.isScintillator(trigCell.detId()); double threshold = (isScintillator ? threshold_scintillator_ : threshold_silicon_); if (trigCell.mipPt() >= threshold) { trigCellVecOutput.push_back(trigCell); + } else { + trigCellVecNotSelected.push_back(trigCell); } } } diff --git a/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorTrigSumImpl.cc b/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorTrigSumImpl.cc new file mode 100644 index 0000000000000..09cfb7e1794c4 --- /dev/null +++ b/L1Trigger/L1THGCal/src/concentrator/HGCalConcentratorTrigSumImpl.cc @@ -0,0 +1,31 @@ +#include "L1Trigger/L1THGCal/interface/concentrator/HGCalConcentratorTrigSumImpl.h" + +HGCalConcentratorTrigSumImpl::HGCalConcentratorTrigSumImpl(const edm::ParameterSet& conf) {} + +void HGCalConcentratorTrigSumImpl::doSum(uint32_t module_id, + const std::vector& trigCellVecInput, + std::vector& trigSumsVecOutput) const { + double ptsum = 0; + double mipptsum = 0; + double hwptsum = 0; + + for (const auto& trigCell : trigCellVecInput) { + // detId selection is already done in HGCalConcentratorProcessorSelection: + // here we do not worry about it and assume all cells are from the same module + ptsum += trigCell.pt(); + mipptsum += trigCell.mipPt(); + hwptsum += trigCell.hwPt(); + } + if (!trigCellVecInput.empty()) { + GlobalPoint module_pos = triggerTools_.getTriggerGeometry()->getModulePosition(module_id); + + math::PtEtaPhiMLorentzVector p4(ptsum, module_pos.eta(), module_pos.phi(), 0); + l1t::HGCalTriggerSums ts; + ts.setP4(p4); + ts.setDetId(module_id); + ts.setPosition(module_pos); + ts.setMipPt(mipptsum); + ts.setHwPt(hwptsum); + trigSumsVecOutput.push_back(ts); + } +} diff --git a/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCTriggerSums.cc b/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCTriggerSums.cc new file mode 100644 index 0000000000000..5377cfdf427b7 --- /dev/null +++ b/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCTriggerSums.cc @@ -0,0 +1,177 @@ + +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "DataFormats/L1THGCal/interface/HGCalTriggerSums.h" +#include "DataFormats/ForwardDetId/interface/HGCalDetId.h" +#include "DataFormats/Common/interface/AssociationMap.h" +#include "DataFormats/ForwardDetId/interface/HGCalTriggerDetId.h" +#include "L1Trigger/L1THGCal/interface/HGCalTriggerGeometryBase.h" +#include "L1Trigger/L1THGCalUtilities/interface/HGCalTriggerNtupleBase.h" +#include "L1Trigger/L1THGCal/interface/HGCalTriggerTools.h" + +class HGCalTriggerNtupleHGCTriggerSums : public HGCalTriggerNtupleBase { +public: + HGCalTriggerNtupleHGCTriggerSums(const edm::ParameterSet& conf); + ~HGCalTriggerNtupleHGCTriggerSums() override{}; + void initialize(TTree&, const edm::ParameterSet&, edm::ConsumesCollector&&) final; + void fill(const edm::Event& e, const edm::EventSetup& es) final; + +private: + void clear() final; + + HGCalTriggerTools triggerTools_; + + edm::EDGetToken trigger_sums_token_; + edm::ESHandle geometry_; + + static constexpr unsigned kPanelOffset_ = 0; + static constexpr unsigned kPanelMask_ = 0x7F; + static constexpr unsigned kSectorOffset_ = 7; + static constexpr unsigned kSectorMask_ = 0x7; + + int ts_n_; + std::vector ts_id_; + std::vector ts_subdet_; + std::vector ts_side_; + std::vector ts_layer_; + std::vector ts_panel_number_; + std::vector ts_panel_sector_; + std::vector ts_wafer_; + std::vector ts_wafertype_; + std::vector ts_data_; + std::vector ts_mipPt_; + std::vector ts_pt_; + std::vector ts_energy_; + std::vector ts_eta_; + std::vector ts_phi_; + std::vector ts_x_; + std::vector ts_y_; + std::vector ts_z_; +}; + +DEFINE_EDM_PLUGIN(HGCalTriggerNtupleFactory, HGCalTriggerNtupleHGCTriggerSums, "HGCalTriggerNtupleHGCTriggerSums"); + +HGCalTriggerNtupleHGCTriggerSums::HGCalTriggerNtupleHGCTriggerSums(const edm::ParameterSet& conf) + : HGCalTriggerNtupleBase(conf) {} + +void HGCalTriggerNtupleHGCTriggerSums::initialize(TTree& tree, + const edm::ParameterSet& conf, + edm::ConsumesCollector&& collector) { + trigger_sums_token_ = + collector.consumes(conf.getParameter("TriggerSums")); + + std::string prefix(conf.getUntrackedParameter("Prefix", "ts")); + + std::string bname; + auto withPrefix([&prefix, &bname](char const* vname) -> char const* { + bname = prefix + "_" + vname; + return bname.c_str(); + }); + + tree.Branch(withPrefix("n"), &ts_n_, (prefix + "_n/I").c_str()); + tree.Branch(withPrefix("id"), &ts_id_); + tree.Branch(withPrefix("subdet"), &ts_subdet_); + tree.Branch(withPrefix("zside"), &ts_side_); + tree.Branch(withPrefix("layer"), &ts_layer_); + tree.Branch(withPrefix("wafer"), &ts_wafer_); + tree.Branch(withPrefix("wafertype"), &ts_wafertype_); + tree.Branch(withPrefix("panel_number"), &ts_panel_number_); + tree.Branch(withPrefix("panel_sector"), &ts_panel_sector_); + tree.Branch(withPrefix("data"), &ts_data_); + tree.Branch(withPrefix("pt"), &ts_pt_); + tree.Branch(withPrefix("mipPt"), &ts_mipPt_); + tree.Branch(withPrefix("energy"), &ts_energy_); + tree.Branch(withPrefix("eta"), &ts_eta_); + tree.Branch(withPrefix("phi"), &ts_phi_); + tree.Branch(withPrefix("x"), &ts_x_); + tree.Branch(withPrefix("y"), &ts_y_); + tree.Branch(withPrefix("z"), &ts_z_); +} + +void HGCalTriggerNtupleHGCTriggerSums::fill(const edm::Event& e, const edm::EventSetup& es) { + // retrieve trigger cells + edm::Handle trigger_sums_h; + e.getByToken(trigger_sums_token_, trigger_sums_h); + const l1t::HGCalTriggerSumsBxCollection& trigger_sums = *trigger_sums_h; + + // retrieve geometry + es.get().get(geometry_); + + triggerTools_.eventSetup(es); + + clear(); + for (auto ts_itr = trigger_sums.begin(0); ts_itr != trigger_sums.end(0); ts_itr++) { + if (ts_itr->pt() > 0) { + ts_n_++; + // hardware data + DetId panelId(ts_itr->detId()); + int panel_sector = -999; + int panel_number = -999; + if (panelId.det() == DetId::Forward) { + HGCalDetId panelIdHGCal(panelId); + if (panelId.subdetId() == ForwardSubdetector::HGCHEB) { + panel_number = panelIdHGCal.wafer(); + } else { + panel_sector = (panelIdHGCal.wafer() >> kSectorOffset_) & kSectorMask_; + panel_number = (panelIdHGCal.wafer() >> kPanelOffset_) & kPanelMask_; + } + } else if (panelId.det() == DetId::HGCalHSc) { + HGCScintillatorDetId panelIdSci(panelId); + panel_sector = panelIdSci.iphi(); + panel_number = panelIdSci.ietaAbs(); + } + ts_panel_number_.emplace_back(panel_number); + ts_panel_sector_.emplace_back(panel_sector); + ts_id_.emplace_back(ts_itr->detId()); + ts_side_.emplace_back(triggerTools_.zside(panelId)); + ts_layer_.emplace_back(triggerTools_.layerWithOffset(panelId)); + // V9 detids + if (panelId.det() == DetId::HGCalTrigger) { + HGCalTriggerDetId idv9(panelId); + ts_subdet_.emplace_back(idv9.subdet()); + ts_wafertype_.emplace_back(idv9.type()); + } else if (panelId.det() == DetId::HGCalHSc) { + HGCScintillatorDetId idv9(panelId); + ts_subdet_.emplace_back(idv9.subdet()); + ts_wafertype_.emplace_back(idv9.type()); + } + // V8 detids + else { + HGCalDetId idv8(panelId); + ts_subdet_.emplace_back(panelId.subdetId()); + ts_wafer_.emplace_back(idv8.wafer()); + ts_wafertype_.emplace_back(idv8.waferType()); + } + ts_data_.emplace_back(ts_itr->hwPt()); + ts_mipPt_.emplace_back(ts_itr->mipPt()); + // physical values + ts_pt_.emplace_back(ts_itr->pt()); + ts_energy_.emplace_back(ts_itr->energy()); + ts_eta_.emplace_back(ts_itr->eta()); + ts_phi_.emplace_back(ts_itr->phi()); + ts_x_.emplace_back(ts_itr->position().x()); + ts_y_.emplace_back(ts_itr->position().y()); + ts_z_.emplace_back(ts_itr->position().z()); + } + } +} + +void HGCalTriggerNtupleHGCTriggerSums::clear() { + ts_n_ = 0; + ts_id_.clear(); + ts_subdet_.clear(); + ts_side_.clear(); + ts_layer_.clear(); + ts_wafer_.clear(); + ts_wafertype_.clear(); + ts_panel_number_.clear(); + ts_panel_sector_.clear(); + ts_data_.clear(); + ts_mipPt_.clear(); + ts_pt_.clear(); + ts_energy_.clear(); + ts_eta_.clear(); + ts_phi_.clear(); + ts_x_.clear(); + ts_y_.clear(); + ts_z_.clear(); +} diff --git a/L1Trigger/L1THGCalUtilities/python/hgcalTriggerNtuples_cfi.py b/L1Trigger/L1THGCalUtilities/python/hgcalTriggerNtuples_cfi.py index 32c22428026f5..5299444d74c9c 100644 --- a/L1Trigger/L1THGCalUtilities/python/hgcalTriggerNtuples_cfi.py +++ b/L1Trigger/L1THGCalUtilities/python/hgcalTriggerNtuples_cfi.py @@ -69,6 +69,11 @@ FilterCellsInMulticlusters = cms.bool(False) ) +ntuple_triggersums = cms.PSet( + NtupleName = cms.string('HGCalTriggerNtupleHGCTriggerSums'), + TriggerSums = cms.InputTag('hgcalConcentratorProducer:HGCalConcentratorProcessorSelection'), +) + ntuple_clusters = cms.PSet( NtupleName = cms.string('HGCalTriggerNtupleHGCClusters'), Clusters = cms.InputTag('hgcalBackEndLayer1Producer:HGCalBackendLayer1Processor2DClustering'), @@ -104,6 +109,7 @@ ntuple_gentau, ntuple_digis, ntuple_triggercells, + ntuple_triggersums, ntuple_multiclusters, ntuple_towers ) diff --git a/L1Trigger/L1TMuon/interface/GMTInternalMuon.h b/L1Trigger/L1TMuon/interface/GMTInternalMuon.h index a3bad4f600573..0b8b142a9f196 100644 --- a/L1Trigger/L1TMuon/interface/GMTInternalMuon.h +++ b/L1Trigger/L1TMuon/interface/GMTInternalMuon.h @@ -43,6 +43,8 @@ namespace l1t { const RegionalMuonCand& origin() const { return m_regional; }; inline const int hwPt() const { return m_regional.hwPt(); }; + inline const int hwPtUnconstrained() const { return m_regional.hwPtUnconstrained(); }; + inline const int hwDXY() const { return m_regional.hwDXY(); }; inline const int hwLocalPhi() const { return m_regional.hwPhi(); }; inline const int hwEta() const { return m_regional.hwEta(); }; inline const int hwSign() const { return m_regional.hwSign(); }; diff --git a/L1Trigger/L1TMuon/interface/MicroGMTCancelOutUnit.h b/L1Trigger/L1TMuon/interface/MicroGMTCancelOutUnit.h index c13747b9bdf16..5e722ea920ae7 100644 --- a/L1Trigger/L1TMuon/interface/MicroGMTCancelOutUnit.h +++ b/L1Trigger/L1TMuon/interface/MicroGMTCancelOutUnit.h @@ -8,7 +8,7 @@ #include "L1Trigger/L1TMuon/interface/MicroGMTLUTFactories.h" namespace l1t { - enum cancelmode { tracks, coordinate }; + enum cancelmode { tracks, kftracks, coordinate }; class MicroGMTCancelOutUnit { public: @@ -29,9 +29,18 @@ namespace l1t { void getCoordinateCancelBits(std::vector>&, std::vector>&); /// Compares all muons from coll1 with all muons from coll2 and sets the cancel-bits based on track addresses - void getTrackAddrCancelBits(std::vector>&, + void getTrackAddrCancelBits(cancelmode, + std::vector>&, std::vector>&); + /// Do the track address-based cancel-out for the original BMTF algorithm + void getTrackAddrCancelBitsOrigBMTF(std::vector>&, + std::vector>&); + + /// Do the track address-based cancel-out for the BMTF algorithm using the Kalman Filter + void getTrackAddrCancelBitsKfBMTF(std::vector>&, + std::vector>&); + std::shared_ptr m_boPosMatchQualLUT; std::shared_ptr m_boNegMatchQualLUT; std::shared_ptr m_foPosMatchQualLUT; diff --git a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h index d9fb39fb1e3b5..c980dcd65fed1 100644 --- a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h +++ b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h @@ -6,30 +6,61 @@ namespace l1t { class MuonRawDigiTranslator { public: - static void fillMuon(Muon&, uint32_t, uint32_t, int, unsigned int); - static void fillMuon(Muon&, uint64_t, int, unsigned int); - static void generatePackedDataWords(const Muon&, uint32_t&, uint32_t&); - static uint64_t generate64bitDataWord(const Muon&); - static int calcHwEta(const uint32_t&, const unsigned, const unsigned); + static void fillMuon(Muon& mu, + uint32_t raw_data_spare, + uint32_t raw_data_00_31, + uint32_t raw_data_32_63, + int fed, + unsigned int fw, + int muInBx); + static void fillMuon(Muon& mu, uint32_t raw_data_spare, uint64_t dataword, int fed, unsigned int fw, int muInBx); + static void fillIntermediateMuon(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, unsigned int fw); + static void generatePackedDataWords(const Muon& mu, + uint32_t& raw_data_spare, + uint32_t& raw_data_00_31, + uint32_t& raw_data_32_63, + int fedId, + int fwId, + int muInBx); + static void generate64bitDataWord( + const Muon& mu, uint32_t& raw_data_spare, uint64_t& dataword, int fedId, int fwId, int muInBx); + static int calcHwEta(const uint32_t& raw, const unsigned absEtaShift, const unsigned etaSignShift); - static const unsigned ptMask_ = 0x1FF; - static const unsigned ptShift_ = 10; - static const unsigned qualMask_ = 0xF; - static const unsigned qualShift_ = 19; - static const unsigned absEtaMask_ = 0xFF; - static const unsigned absEtaShift_ = 21; - static const unsigned absEtaAtVtxShift_ = 23; - static const unsigned etaSignShift_ = 29; - static const unsigned etaAtVtxSignShift_ = 31; - static const unsigned phiMask_ = 0x3FF; - static const unsigned phiShift_ = 11; - static const unsigned phiAtVtxShift_ = 0; - static const unsigned chargeShift_ = 2; - static const unsigned chargeValidShift_ = 3; - static const unsigned tfMuonIndexMask_ = 0x7F; - static const unsigned tfMuonIndexShift_ = 4; - static const unsigned isoMask_ = 0x3; - static const unsigned isoShift_ = 0; + static constexpr unsigned ptMask_ = 0x1FF; + static constexpr unsigned ptShift_ = 10; + static constexpr unsigned qualMask_ = 0xF; + static constexpr unsigned qualShift_ = 19; + static constexpr unsigned absEtaMask_ = 0xFF; + static constexpr unsigned absEtaShift_ = 21; + static constexpr unsigned absEtaAtVtxShift_ = 23; + static constexpr unsigned etaSignShift_ = 29; + static constexpr unsigned etaAtVtxSignShift_ = 31; + static constexpr unsigned phiMask_ = 0x3FF; + static constexpr unsigned phiShift_ = 11; + static constexpr unsigned phiAtVtxShift_ = 0; + static constexpr unsigned chargeShift_ = 2; + static constexpr unsigned chargeValidShift_ = 3; + static constexpr unsigned tfMuonIndexMask_ = 0x7F; + static constexpr unsigned tfMuonIndexShift_ = 4; + static constexpr unsigned isoMask_ = 0x3; + static constexpr unsigned isoShift_ = 0; + static constexpr unsigned dxyMask_ = 0x3; + static constexpr unsigned dxyShift_ = 30; + static constexpr unsigned ptUnconstrainedMask_ = 0xFF; + static constexpr unsigned ptUnconstrainedShift_ = 21; + static constexpr unsigned ptUnconstrainedIntermedidateShift_ = 0; + static constexpr unsigned absEtaMu1Shift_ = 12; // For Run-3 + static constexpr unsigned etaMu1SignShift_ = 20; // For Run-3 + static constexpr unsigned absEtaMu2Shift_ = 21; // For Run-3 + static constexpr unsigned etaMu2SignShift_ = 29; // For Run-3 + + private: + static void fillMuonStableQuantities(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63); + static void fillMuonCoordinates2016(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63); + static void fillMuonCoordinatesFrom2017(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63); + static void fillMuonQuantitiesRun3( + Muon& mu, uint32_t raw_data_spare, uint32_t raw_data_00_31, uint32_t raw_data_32_63, int muInBx); + static void fillIntermediateMuonQuantitiesRun3(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63); }; } // namespace l1t diff --git a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h index bf59aa4a15083..0ee774b831864 100644 --- a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h +++ b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h @@ -6,63 +6,72 @@ namespace l1t { class RegionalMuonRawDigiTranslator { public: - static void fillRegionalMuonCand(RegionalMuonCand&, uint32_t, uint32_t, int, tftype); - static void fillRegionalMuonCand(RegionalMuonCand&, uint64_t, int, tftype); - static void generatePackedDataWords(const RegionalMuonCand&, uint32_t&, uint32_t&); - static uint64_t generate64bitDataWord(const RegionalMuonCand&); + static void fillRegionalMuonCand( + RegionalMuonCand& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, int proc, tftype tf, bool isKalman); + static void fillRegionalMuonCand(RegionalMuonCand& mu, uint64_t dataword, int proc, tftype tf, bool isKalman); + static void generatePackedDataWords(const RegionalMuonCand& mu, + uint32_t& raw_data_00_31, + uint32_t& raw_data_32_63, + bool isKalman); + static uint64_t generate64bitDataWord(const RegionalMuonCand& mu, bool isKalman); + static int generateRawTrkAddress(const RegionalMuonCand&, bool isKalman); - static const unsigned ptMask_ = 0x1FF; - static const unsigned ptShift_ = 0; - static const unsigned qualMask_ = 0xF; - static const unsigned qualShift_ = 9; - static const unsigned absEtaMask_ = 0xFF; - static const unsigned absEtaShift_ = 13; - static const unsigned etaSignShift_ = 21; - static const unsigned hfMask_ = 0x1; - static const unsigned hfShift_ = 22; - static const unsigned absPhiMask_ = 0x7F; - static const unsigned absPhiShift_ = 23; - static const unsigned phiSignShift_ = 30; - static const unsigned signShift_ = 0; - static const unsigned signValidShift_ = 1; - static const unsigned trackAddressMask_ = 0x1FFFFFFF; - static const unsigned trackAddressShift_ = 2; + static constexpr unsigned ptMask_ = 0x1FF; + static constexpr unsigned ptShift_ = 0; + static constexpr unsigned qualMask_ = 0xF; + static constexpr unsigned qualShift_ = 9; + static constexpr unsigned absEtaMask_ = 0xFF; + static constexpr unsigned absEtaShift_ = 13; + static constexpr unsigned etaSignShift_ = 21; + static constexpr unsigned hfMask_ = 0x1; + static constexpr unsigned hfShift_ = 22; + static constexpr unsigned absPhiMask_ = 0x7F; + static constexpr unsigned absPhiShift_ = 23; + static constexpr unsigned phiSignShift_ = 30; + static constexpr unsigned signShift_ = 0; + static constexpr unsigned signValidShift_ = 1; + static constexpr unsigned dxyMask_ = 0x3; + static constexpr unsigned dxyShift_ = 18; + static constexpr unsigned ptUnconstrainedMask_ = 0xFF; + static constexpr unsigned ptUnconstrainedShift_ = 23; + static constexpr unsigned trackAddressMask_ = 0x1FFFFFFF; + static constexpr unsigned trackAddressShift_ = 2; // relative shifts within track address - static const unsigned bmtfTrAddrSegSelMask_ = 0xF; - static const unsigned bmtfTrAddrSegSelShift_ = 21; - static const unsigned bmtfTrAddrDetSideShift_ = 20; - static const unsigned bmtfTrAddrWheelMask_ = 0x3; - static const unsigned bmtfTrAddrWheelShift_ = 18; - static const unsigned bmtfTrAddrStat1Mask_ = 0x3; - static const unsigned bmtfTrAddrStat1Shift_ = 14; - static const unsigned bmtfTrAddrStat2Mask_ = 0xF; - static const unsigned bmtfTrAddrStat2Shift_ = 10; - static const unsigned bmtfTrAddrStat3Mask_ = 0xF; - static const unsigned bmtfTrAddrStat3Shift_ = 6; - static const unsigned bmtfTrAddrStat4Mask_ = 0xF; - static const unsigned bmtfTrAddrStat4Shift_ = 2; + static constexpr unsigned bmtfTrAddrSegSelMask_ = 0xF; + static constexpr unsigned bmtfTrAddrSegSelShift_ = 21; + static constexpr unsigned bmtfTrAddrDetSideShift_ = 20; + static constexpr unsigned bmtfTrAddrWheelMask_ = 0x3; + static constexpr unsigned bmtfTrAddrWheelShift_ = 18; + static constexpr unsigned bmtfTrAddrStat1Mask_ = 0x3; + static constexpr unsigned bmtfTrAddrStat1Shift_ = 14; + static constexpr unsigned bmtfTrAddrStat2Mask_ = 0xF; + static constexpr unsigned bmtfTrAddrStat2Shift_ = 10; + static constexpr unsigned bmtfTrAddrStat3Mask_ = 0xF; + static constexpr unsigned bmtfTrAddrStat3Shift_ = 6; + static constexpr unsigned bmtfTrAddrStat4Mask_ = 0xF; + static constexpr unsigned bmtfTrAddrStat4Shift_ = 2; - static const unsigned emtfTrAddrMe1SegShift_ = 0; - static const unsigned emtfTrAddrMe1ChShift_ = 1; - static const unsigned emtfTrAddrMe1ChMask_ = 0x7; - static const unsigned emtfTrAddrMe2SegShift_ = 4; - static const unsigned emtfTrAddrMe2ChShift_ = 5; - static const unsigned emtfTrAddrMe2ChMask_ = 0x7; - static const unsigned emtfTrAddrMe3SegShift_ = 8; - static const unsigned emtfTrAddrMe3ChShift_ = 9; - static const unsigned emtfTrAddrMe3ChMask_ = 0x7; - static const unsigned emtfTrAddrMe4SegShift_ = 12; - static const unsigned emtfTrAddrMe4ChShift_ = 13; - static const unsigned emtfTrAddrMe4ChMask_ = 0x7; - static const unsigned emtfTrAddrTrkNumShift_ = 16; - static const unsigned emtfTrAddrTrkNumMask_ = 0x3; - static const unsigned emtfTrAddrBxShift_ = 18; - static const unsigned emtfTrAddrBxMask_ = 0x7FF; + static constexpr unsigned emtfTrAddrMe1SegShift_ = 0; + static constexpr unsigned emtfTrAddrMe1ChShift_ = 1; + static constexpr unsigned emtfTrAddrMe1ChMask_ = 0x7; + static constexpr unsigned emtfTrAddrMe2SegShift_ = 4; + static constexpr unsigned emtfTrAddrMe2ChShift_ = 5; + static constexpr unsigned emtfTrAddrMe2ChMask_ = 0x7; + static constexpr unsigned emtfTrAddrMe3SegShift_ = 8; + static constexpr unsigned emtfTrAddrMe3ChShift_ = 9; + static constexpr unsigned emtfTrAddrMe3ChMask_ = 0x7; + static constexpr unsigned emtfTrAddrMe4SegShift_ = 12; + static constexpr unsigned emtfTrAddrMe4ChShift_ = 13; + static constexpr unsigned emtfTrAddrMe4ChMask_ = 0x7; + static constexpr unsigned emtfTrAddrTrkNumShift_ = 16; + static constexpr unsigned emtfTrAddrTrkNumMask_ = 0x3; + static constexpr unsigned emtfTrAddrBxShift_ = 18; + static constexpr unsigned emtfTrAddrBxMask_ = 0x7FF; - static const unsigned omtfTrAddrLayersShift_ = 0; - static const unsigned omtfTrAddrLayersMask_ = 0x3FFFF; - static const unsigned omtfTrAddrWeightShift_ = 18; - static const unsigned omtfTrAddrWeightMask_ = 0x1F; + static constexpr unsigned omtfTrAddrLayersShift_ = 0; + static constexpr unsigned omtfTrAddrLayersMask_ = 0x3FFFF; + static constexpr unsigned omtfTrAddrWeightShift_ = 18; + static constexpr unsigned omtfTrAddrWeightMask_ = 0x1F; }; } // namespace l1t diff --git a/L1Trigger/L1TMuon/plugins/L1TMuonProducer.cc b/L1Trigger/L1TMuon/plugins/L1TMuonProducer.cc index 775b4cc15b954..a505990757bb0 100644 --- a/L1Trigger/L1TMuon/plugins/L1TMuonProducer.cc +++ b/L1Trigger/L1TMuon/plugins/L1TMuonProducer.cc @@ -118,6 +118,7 @@ class L1TMuonProducer : public edm::stream::EDProducer<> { MicroGMTIsolationUnit m_isolationUnit; MicroGMTCancelOutUnit m_cancelOutUnit; std::ofstream m_debugOut; + l1t::cancelmode m_bmtfCancelMode; l1t::cancelmode m_emtfCancelMode; edm::EDGetTokenT m_barrelTfInputToken; @@ -138,7 +139,9 @@ class L1TMuonProducer : public edm::stream::EDProducer<> { // constructors and destructor // L1TMuonProducer::L1TMuonProducer(const edm::ParameterSet& iConfig) - : m_debugOut("test/debug/iso_debug.dat"), m_emtfCancelMode(cancelmode::coordinate) { + : m_debugOut("test/debug/iso_debug.dat"), + m_bmtfCancelMode(cancelmode::tracks), + m_emtfCancelMode(cancelmode::coordinate) { // edm::InputTag barrelTfInputTag = iConfig.getParameter("barrelTFInput"); // edm::InputTag overlapTfInputTag = iConfig.getParameter("overlapTFInput"); // edm::InputTag forwardTfInputTag = iConfig.getParameter("forwardTFInput"); @@ -153,8 +156,13 @@ L1TMuonProducer::L1TMuonProducer(const edm::ParameterSet& iConfig) m_bxMax = iConfig.getParameter("bxMax"); m_autoCancelMode = iConfig.getParameter("autoCancelMode"); - if (!m_autoCancelMode && iConfig.getParameter("emtfCancelMode").find("tracks") == 0) { - m_emtfCancelMode = cancelmode::tracks; + if (!m_autoCancelMode) { + if (iConfig.getParameter("bmtfCancelMode").find("kftracks") == 0) { + m_bmtfCancelMode = cancelmode::kftracks; + } + if (iConfig.getParameter("emtfCancelMode").find("tracks") == 0) { + m_emtfCancelMode = cancelmode::tracks; + } } m_barrelTfInputToken = consumes(m_barrelTfInputTag); @@ -266,7 +274,7 @@ void L1TMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) splitAndConvertMuons(omtfMuons, internMuonsOmtfPos, internMuonsOmtfNeg, omtfPosWedges, omtfNegWedges, bx); // cancel out within the track finders: - m_cancelOutUnit.setCancelOutBits(bmtfWedges, tftype::bmtf, cancelmode::tracks); + m_cancelOutUnit.setCancelOutBits(bmtfWedges, tftype::bmtf, m_bmtfCancelMode); m_cancelOutUnit.setCancelOutBits(omtfPosWedges, tftype::omtf_pos, cancelmode::coordinate); m_cancelOutUnit.setCancelOutBits(omtfNegWedges, tftype::omtf_neg, cancelmode::coordinate); m_cancelOutUnit.setCancelOutBits(emtfPosWedges, tftype::emtf_pos, m_emtfCancelMode); @@ -333,16 +341,25 @@ void L1TMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) mu->hwDPhi(), mu->hwDEta(), mu->hwRank()}; + + // Set coordinates at the vertex + outMu.setHwEtaAtVtx(MicroGMTConfiguration::calcMuonHwEtaExtra(outMu)); + outMu.setHwPhiAtVtx(MicroGMTConfiguration::calcMuonHwPhiExtra(outMu)); + outMu.setEtaAtVtx(MicroGMTConfiguration::calcMuonEtaExtra(outMu)); + outMu.setPhiAtVtx(MicroGMTConfiguration::calcMuonPhiExtra(outMu)); + + // Set displacement information + int hwPtUnconstrained{mu->hwPtUnconstrained()}; + outMu.setPtUnconstrained(hwPtUnconstrained == 0 ? 0 + : (hwPtUnconstrained - 1) * 0.5); // Don't want negative pT. + outMu.setHwPtUnconstrained(hwPtUnconstrained); + outMu.setHwDXY(mu->hwDXY()); + if (mu->hwSignValid()) { outMu.setCharge(1 - 2 * mu->hwSign()); } else { outMu.setCharge(0); } - // set the coordinates at the vertex - outMu.setHwEtaAtVtx(MicroGMTConfiguration::calcMuonHwEtaExtra(outMu)); - outMu.setHwPhiAtVtx(MicroGMTConfiguration::calcMuonHwPhiExtra(outMu)); - outMu.setEtaAtVtx(MicroGMTConfiguration::calcMuonEtaExtra(outMu)); - outMu.setPhiAtVtx(MicroGMTConfiguration::calcMuonPhiExtra(outMu)); m_debugOut << mu->hwCaloPhi() << " " << mu->hwCaloEta() << std::endl; outMuons->push_back(bx, outMu); } @@ -430,6 +447,12 @@ void L1TMuonProducer::addMuonsToCollections(MicroGMTConfiguration::InterMuonList mu->hwDPhi(), mu->hwDEta(), mu->hwRank()}; + + int hwPtUnconstrained{mu->hwPtUnconstrained()}; + outMu.setPtUnconstrained(hwPtUnconstrained == 0 ? 0 : (hwPtUnconstrained - 1) * 0.5); // Don't want negative pT. + outMu.setHwPtUnconstrained(hwPtUnconstrained); + outMu.setHwDXY(mu->hwDXY()); + if (mu->hwSignValid()) { outMu.setCharge(1 - 2 * mu->hwSign()); } else { @@ -458,23 +481,26 @@ void L1TMuonProducer::splitAndConvertMuons(const edm::Handlesize(bx); ++i, ++muIdx) { - int link = in->at(bx, i).link(); - if (m_inputsToDisable.test(link) || m_maskedInputs.test(link)) - continue; // only process if input link is enabled and not masked - if (currentLink != link) { - muIdx = 0; - currentLink = link; - } - int gPhi = MicroGMTConfiguration::calcGlobalPhi( - in->at(bx, i).hwPhi(), in->at(bx, i).trackFinderType(), in->at(bx, i).processor()); - int tfMuonIdx = 3 * (currentLink - 36) + muIdx; - std::shared_ptr out = std::make_shared(in->at(bx, i), gPhi, tfMuonIdx); - if (in->at(bx, i).hwEta() > 0) { - out_pos.push_back(out); - wedges_pos[in->at(bx, i).processor()].push_back(out); - } else { - out_neg.emplace_back(out); - wedges_neg[in->at(bx, i).processor()].push_back(out); + if (in->at(bx, i).hwPt() > 0) { + int link = in->at(bx, i).link(); + if (m_inputsToDisable.test(link) || m_maskedInputs.test(link)) { + continue; // only process if input link is enabled and not masked + } + if (currentLink != link) { + muIdx = 0; + currentLink = link; + } + int gPhi = MicroGMTConfiguration::calcGlobalPhi( + in->at(bx, i).hwPhi(), in->at(bx, i).trackFinderType(), in->at(bx, i).processor()); + int tfMuonIdx = 3 * (currentLink - 36) + muIdx; + std::shared_ptr out = std::make_shared(in->at(bx, i), gPhi, tfMuonIdx); + if (in->at(bx, i).hwEta() > 0) { + out_pos.push_back(out); + wedges_pos[in->at(bx, i).processor()].push_back(out); + } else { + out_neg.emplace_back(out); + wedges_neg[in->at(bx, i).processor()].push_back(out); + } } } for (int i = 0; i < 6; ++i) { @@ -501,19 +527,22 @@ void L1TMuonProducer::convertMuons(const edm::Handlesize(bx); ++i, ++muIdx) { - int link = in->at(bx, i).link(); - if (m_inputsToDisable.test(link) || m_maskedInputs.test(link)) - continue; // only process if input link is enabled and not masked - if (currentLink != link) { - muIdx = 0; - currentLink = link; + if (in->at(bx, i).hwPt() > 0) { + int link = in->at(bx, i).link(); + if (m_inputsToDisable.test(link) || m_maskedInputs.test(link)) { + continue; // only process if input link is enabled and not masked + } + if (currentLink != link) { + muIdx = 0; + currentLink = link; + } + int gPhi = MicroGMTConfiguration::calcGlobalPhi( + in->at(bx, i).hwPhi(), in->at(bx, i).trackFinderType(), in->at(bx, i).processor()); + int tfMuonIdx = 3 * (currentLink - 36) + muIdx; + std::shared_ptr outMu = std::make_shared(in->at(bx, i), gPhi, tfMuonIdx); + out.emplace_back(outMu); + wedges[in->at(bx, i).processor()].push_back(outMu); } - int gPhi = MicroGMTConfiguration::calcGlobalPhi( - in->at(bx, i).hwPhi(), in->at(bx, i).trackFinderType(), in->at(bx, i).processor()); - int tfMuonIdx = 3 * (currentLink - 36) + muIdx; - std::shared_ptr outMu = std::make_shared(in->at(bx, i), gPhi, tfMuonIdx); - out.emplace_back(outMu); - wedges[in->at(bx, i).processor()].push_back(outMu); } for (int i = 0; i < 12; ++i) { if (wedges[i].size() > 3) @@ -560,8 +589,14 @@ void L1TMuonProducer::beginRun(edm::Run const& run, edm::EventSetup const& iSetu m_isolationUnit.initialise(microGMTParamsHelper.get()); m_cancelOutUnit.initialise(microGMTParamsHelper.get()); - if (m_autoCancelMode && microGMTParamsHelper->fwVersion() > 0x5000000) { - m_emtfCancelMode = cancelmode::tracks; + if (m_autoCancelMode) { + if (microGMTParamsHelper->fwVersion() >= 0x6000000) { + m_bmtfCancelMode = cancelmode::kftracks; + } + // TODO: No decision yet on when to use EMTF track addresses for cancel-out. + // if (microGMTParamsHelper->fwVersion() > 0x5000000) { + // m_emtfCancelMode = cancelmode::tracks; + // } } } diff --git a/L1Trigger/L1TMuon/python/simDigis_cff.py b/L1Trigger/L1TMuon/python/simDigis_cff.py index b4383b9b1a138..4263ff9b6ea92 100644 --- a/L1Trigger/L1TMuon/python/simDigis_cff.py +++ b/L1Trigger/L1TMuon/python/simDigis_cff.py @@ -75,6 +75,8 @@ # from L1Trigger.L1TTwinMux.simTwinMuxDigis_cfi import * from L1Trigger.L1TMuonBarrel.simBmtfDigis_cfi import * +from L1Trigger.L1TMuonBarrel.simKBmtfStubs_cfi import * +from L1Trigger.L1TMuonBarrel.simKBmtfDigis_cfi import * from L1Trigger.L1TMuonEndCap.simEmtfDigis_cfi import * from L1Trigger.L1TMuonOverlap.simOmtfDigis_cfi import * from L1Trigger.L1TMuon.simGmtCaloSumDigis_cfi import * @@ -82,7 +84,15 @@ from Configuration.Eras.Modifier_stage2L1Trigger_cff import stage2L1Trigger # # -stage2L1Trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis)) +stage2L1Trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simKBmtfStubs, simKBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis)) + +# +# Phase-2 Trigger +# +from L1Trigger.L1TMuonBarrel.simKBmtfStubs_cfi import * +from L1Trigger.L1TMuonBarrel.simKBmtfDigis_cfi import * +from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger +phase2_trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simKBmtfStubs, simKBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis)) ## GEM TPs from L1Trigger.L1TGEM.simGEMDigis_cff import * diff --git a/L1Trigger/L1TMuon/python/simGmtStage2Digis_cfi.py b/L1Trigger/L1TMuon/python/simGmtStage2Digis_cfi.py index 8437714485899..25385e675f480 100644 --- a/L1Trigger/L1TMuon/python/simGmtStage2Digis_cfi.py +++ b/L1Trigger/L1TMuon/python/simGmtStage2Digis_cfi.py @@ -7,7 +7,7 @@ ) simGmtStage2Digis = cms.EDProducer('L1TMuonProducer', - barrelTFInput = cms.InputTag("simBmtfDigis", "BMTF"), + barrelTFInput = cms.InputTag("simKBmtfDigis", "BMTF"), overlapTFInput = cms.InputTag("simOmtfDigis", "OMTF"), forwardTFInput = cms.InputTag("simEmtfDigis", "EMTF"), #triggerTowerInput = cms.InputTag("simGmtCaloSumDigis", "TriggerTower2x2s"), @@ -15,7 +15,8 @@ autoBxRange = cms.bool(True), # if True the output BX range is calculated from the inputs and 'bxMin' and 'bxMax' are ignored bxMin = cms.int32(-2), bxMax = cms.int32(2), - autoCancelMode = cms.bool(False), # if True the cancel out methods are configured depending on the FW version number and 'emtfCancelMode' is ignored + autoCancelMode = cms.bool(True), # if True the cancel out methods are configured depending on the FW version number and 'bmtfCancelMode' + 'emtfCancelMode' are ignored + bmtfCancelMode = cms.string("kftracks"), # 'tracks' or 'kftracks' (when using the Run-3 BMTF) emtfCancelMode = cms.string("coordinate") # 'tracks' or 'coordinate' ) @@ -30,3 +31,19 @@ ) ) ) + +## Era: Run2_2016 +from Configuration.Eras.Modifier_stage2L1Trigger_cff import stage2L1Trigger +stage2L1Trigger.toModify(simGmtStage2Digis, barrelTFInput = cms.InputTag("simBmtfDigis", "BMTF")) + +## Era: Run2_2017 +from Configuration.Eras.Modifier_stage2L1Trigger_2017_cff import stage2L1Trigger_2017 +stage2L1Trigger_2017.toModify(simGmtStage2Digis, barrelTFInput = cms.InputTag("simBmtfDigis", "BMTF")) + +### Era: Run2_2018 +from Configuration.Eras.Modifier_stage2L1Trigger_2018_cff import stage2L1Trigger_2018 +stage2L1Trigger_2018.toModify(simGmtStage2Digis, barrelTFInput = cms.InputTag("simBmtfDigis", "BMTF")) + +### Era: Run3_2021 +from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 +stage2L1Trigger_2021.toModify(simGmtStage2Digis, barrelTFInput = cms.InputTag("simKBmtfDigis", "BMTF")) diff --git a/L1Trigger/L1TMuon/src/MicroGMTCancelOutUnit.cc b/L1Trigger/L1TMuon/src/MicroGMTCancelOutUnit.cc index 0a852a76d4da1..4d97ce7dc32b4 100644 --- a/L1Trigger/L1TMuon/src/MicroGMTCancelOutUnit.cc +++ b/L1Trigger/L1TMuon/src/MicroGMTCancelOutUnit.cc @@ -57,7 +57,7 @@ namespace l1t { if (mode == cancelmode::coordinate) { getCoordinateCancelBits(coll2, coll1); // in case of a tie coll1 muon wins } else { - getTrackAddrCancelBits(coll1, coll2); + getTrackAddrCancelBits(mode, coll1, coll2); } coll1.clear(); @@ -92,7 +92,7 @@ namespace l1t { if (mode == cancelmode::coordinate) { getCoordinateCancelBits(coll1, coll2); } else { - getTrackAddrCancelBits(coll1, coll2); + getTrackAddrCancelBits(mode, coll1, coll2); } coll1.clear(); coll2.clear(); @@ -127,7 +127,7 @@ namespace l1t { if (mode == cancelmode::coordinate) { getCoordinateCancelBits(coll1, coll2); } else { - getTrackAddrCancelBits(coll1, coll2); + getTrackAddrCancelBits(mode, coll1, coll2); } coll1.clear(); coll2.clear(); @@ -194,86 +194,18 @@ namespace l1t { } } - void MicroGMTCancelOutUnit::getTrackAddrCancelBits(std::vector>& coll1, + void MicroGMTCancelOutUnit::getTrackAddrCancelBits(cancelmode mode, + std::vector>& coll1, std::vector>& coll2) { if (coll1.empty() || coll2.empty()) { return; } // Address based cancel out for BMTF if ((*coll1.begin())->trackFinderType() == tftype::bmtf && (*coll2.begin())->trackFinderType() == tftype::bmtf) { - for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) { - std::map trkAddr_w1 = (*mu_w1)->origin().trackAddress(); - int wheelNum_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelNum]; - int wheelSide_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelSide]; - std::vector stations_w1; - stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat1]); - stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat2]); - stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat3]); - stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat4]); - //std::cout << "Track address 1: wheelSide (1 == negative side): " << wheelSide_w1 << ", wheelNum: " << wheelNum_w1 << ", stations1234: 0x" << hex << stations_w1[0] << stations_w1[1] << stations_w1[2] << stations_w1[3] << dec << std::endl; - - for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) { - std::map trkAddr_w2 = (*mu_w2)->origin().trackAddress(); - int wheelNum_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelNum]; - int wheelSide_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelSide]; - std::vector stations_w2; - stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat1]); - stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat2]); - stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat3]); - stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat4]); - //std::cout << "Track address 2: wheelSide (1 == negative side): " << wheelSide_w2 << ", wheelNum: " << wheelNum_w2 << ", stations1234: 0x" << hex << stations_w2[0] << stations_w2[1] << stations_w2[2] << stations_w2[3] << dec << std::endl; - - int nMatchedStations = 0; - // search for duplicates in stations 2-4 - for (int i = 1; i < 4; ++i) { - if (wheelSide_w1 == wheelSide_w2) { // both tracks are on the same detector side - if (wheelNum_w1 == wheelNum_w2) { // both tracks have the same reference wheel - if ((stations_w1[i] == 0x0 && stations_w2[i] == 0x2) || - (stations_w1[i] == 0x1 && stations_w2[i] == 0x3) || - (stations_w1[i] == 0x4 && stations_w2[i] == 0x0) || - (stations_w1[i] == 0x5 && stations_w2[i] == 0x1) || - (stations_w1[i] == 0x8 && stations_w2[i] == 0xA) || - (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) || - (stations_w1[i] == 0xC && stations_w2[i] == 0x8) || - (stations_w1[i] == 0xD && stations_w2[i] == 0x9)) { - ++nMatchedStations; - } - } else if (wheelNum_w1 == wheelNum_w2 - 1) { // track 2 is one wheel higher than track 1 - if ((stations_w1[i] == 0x0 && stations_w2[i] == 0xA) || - (stations_w1[i] == 0x1 && stations_w2[i] == 0xB) || - (stations_w1[i] == 0x4 && stations_w2[i] == 0x8) || - (stations_w1[i] == 0x5 && stations_w2[i] == 0x9)) { - ++nMatchedStations; - } - } else if (wheelNum_w1 == wheelNum_w2 + 1) { // track 2 is one wheel lower than track 1 - if ((stations_w1[i] == 0x8 && stations_w2[i] == 0x2) || - (stations_w1[i] == 0x9 && stations_w2[i] == 0x3) || - (stations_w1[i] == 0xC && stations_w2[i] == 0x0) || - (stations_w1[i] == 0xD && stations_w2[i] == 0x1)) { - ++nMatchedStations; - } - } - } else { - if (wheelNum_w1 == 0 && - wheelNum_w2 == 0) { // both tracks are on either side of the central wheel (+0 and -0) - if ((stations_w1[i] == 0x8 && stations_w2[i] == 0xA) || - (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) || - (stations_w1[i] == 0xC && stations_w2[i] == 0x8) || - (stations_w1[i] == 0xD && stations_w2[i] == 0x9)) { - ++nMatchedStations; - } - } - } - } - //std::cout << "Shared hits found: " << nMatchedStations << std::endl; - if (nMatchedStations > 0) { - if ((*mu_w1)->origin().hwQual() >= (*mu_w2)->origin().hwQual()) { - (*mu_w2)->setHwCancelBit(1); - } else { - (*mu_w1)->setHwCancelBit(1); - } - } - } + if (mode == cancelmode::tracks) { + getTrackAddrCancelBitsOrigBMTF(coll1, coll2); + } else if (mode == cancelmode::kftracks) { + getTrackAddrCancelBitsKfBMTF(coll1, coll2); } // Address based cancel out for EMTF } else if (((*coll1.begin())->trackFinderType() == tftype::emtf_pos && @@ -337,4 +269,168 @@ namespace l1t { } } + void MicroGMTCancelOutUnit::getTrackAddrCancelBitsOrigBMTF(std::vector>& coll1, + std::vector>& coll2) { + for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) { + std::map trkAddr_w1 = (*mu_w1)->origin().trackAddress(); + int wheelNum_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelNum]; + int wheelSide_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelSide]; + std::vector stations_w1; + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat1]); + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat2]); + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat3]); + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat4]); + //std::cout << "Track address 1: wheelSide (1 == negative side): " << wheelSide_w1 << ", wheelNum: " << wheelNum_w1 << ", stations1234: 0x" << hex << stations_w1[0] << stations_w1[1] << stations_w1[2] << stations_w1[3] << dec << std::endl; + + for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) { + std::map trkAddr_w2 = (*mu_w2)->origin().trackAddress(); + int wheelNum_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelNum]; + int wheelSide_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelSide]; + std::vector stations_w2; + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat1]); + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat2]); + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat3]); + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat4]); + //std::cout << "Track address 2: wheelSide (1 == negative side): " << wheelSide_w2 << ", wheelNum: " << wheelNum_w2 << ", stations1234: 0x" << hex << stations_w2[0] << stations_w2[1] << stations_w2[2] << stations_w2[3] << dec << std::endl; + + int nMatchedStations = 0; + // search for duplicates in stations 2-4 + for (int i = 1; i < 4; ++i) { + if (wheelSide_w1 == wheelSide_w2) { // both tracks are on the same detector side + if (wheelNum_w1 == wheelNum_w2) { // both tracks have the same reference wheel + if ((stations_w1[i] == 0x0 && stations_w2[i] == 0x2) || + (stations_w1[i] == 0x1 && stations_w2[i] == 0x3) || + (stations_w1[i] == 0x4 && stations_w2[i] == 0x0) || + (stations_w1[i] == 0x5 && stations_w2[i] == 0x1) || + (stations_w1[i] == 0x8 && stations_w2[i] == 0xA) || + (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) || + (stations_w1[i] == 0xC && stations_w2[i] == 0x8) || + (stations_w1[i] == 0xD && stations_w2[i] == 0x9)) { + ++nMatchedStations; + } + } else if (wheelNum_w1 == wheelNum_w2 - 1) { // track 2 is one wheel higher than track 1 + if ((stations_w1[i] == 0x0 && stations_w2[i] == 0xA) || + (stations_w1[i] == 0x1 && stations_w2[i] == 0xB) || + (stations_w1[i] == 0x4 && stations_w2[i] == 0x8) || + (stations_w1[i] == 0x5 && stations_w2[i] == 0x9)) { + ++nMatchedStations; + } + } else if (wheelNum_w1 == wheelNum_w2 + 1) { // track 2 is one wheel lower than track 1 + if ((stations_w1[i] == 0x8 && stations_w2[i] == 0x2) || + (stations_w1[i] == 0x9 && stations_w2[i] == 0x3) || + (stations_w1[i] == 0xC && stations_w2[i] == 0x0) || + (stations_w1[i] == 0xD && stations_w2[i] == 0x1)) { + ++nMatchedStations; + } + } + } else { + if (wheelNum_w1 == 0 && + wheelNum_w2 == 0) { // both tracks are on either side of the central wheel (+0 and -0) + if ((stations_w1[i] == 0x8 && stations_w2[i] == 0xA) || + (stations_w1[i] == 0x9 && stations_w2[i] == 0xB) || + (stations_w1[i] == 0xC && stations_w2[i] == 0x8) || + (stations_w1[i] == 0xD && stations_w2[i] == 0x9)) { + ++nMatchedStations; + } + } + } + } + //std::cout << "Shared hits found: " << nMatchedStations << std::endl; + if (nMatchedStations > 0) { + if ((*mu_w1)->origin().hwQual() >= (*mu_w2)->origin().hwQual()) { + (*mu_w2)->setHwCancelBit(1); + } else { + (*mu_w1)->setHwCancelBit(1); + } + } + } + } + } + + void MicroGMTCancelOutUnit::getTrackAddrCancelBitsKfBMTF(std::vector>& coll1, + std::vector>& coll2) { + for (auto mu_w1 = coll1.begin(); mu_w1 != coll1.end(); ++mu_w1) { + std::map trkAddr_w1 = (*mu_w1)->origin().trackAddress(); + int wheelNum_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelNum]; + int wheelSide_w1 = trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kWheelSide]; + std::vector stations_w1; + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat1]); + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat2]); + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat3]); + stations_w1.push_back(trkAddr_w1[l1t::RegionalMuonCand::bmtfAddress::kStat4]); + //std::cout << "Track address 1: wheelSide (1 == negative side): " << wheelSide_w1 << ", wheelNum: " << wheelNum_w1 << ", stations1234: 0x" << hex << stations_w1[0] << stations_w1[1] << stations_w1[2] << stations_w1[3] << dec << std::endl; + //std::cout << "Muon1 eta: " << (*mu_w1)->hwEta() << " phi: " << (*mu_w1)->hwGlobalPhi() << " pT: " << (*mu_w1)->hwPt() << " qual: " << (*mu_w1)->origin().hwQual() << std::endl; + + for (auto mu_w2 = coll2.begin(); mu_w2 != coll2.end(); ++mu_w2) { + std::map trkAddr_w2 = (*mu_w2)->origin().trackAddress(); + int wheelNum_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelNum]; + int wheelSide_w2 = trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kWheelSide]; + std::vector stations_w2; + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat1]); + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat2]); + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat3]); + stations_w2.push_back(trkAddr_w2[l1t::RegionalMuonCand::bmtfAddress::kStat4]); + // std::cout << "Track address 2: wheelSide (1 == negative side): " << wheelSide_w2 << ", wheelNum: " << wheelNum_w2 << ", stations1234: 0x" << hex << stations_w2[0] << stations_w2[1] << stations_w2[2] << stations_w2[3] << dec << std::endl; + // std::cout << "Muon2 eta: " << (*mu_w2)->hwEta() << " phi: " << (*mu_w2)->hwGlobalPhi() << " pT: " << (*mu_w2)->hwPt() << " qual: " << (*mu_w2)->origin().hwQual() << std::endl; + + int nMatchedStations = 0; + // search for duplicates in stations 1-3 + for (int i = 0; i < 3; ++i) { + if (wheelSide_w1 == wheelSide_w2) { // both tracks are on the same detector side + if (wheelNum_w1 == wheelNum_w2) { // both tracks have the same reference wheel + if ((stations_w1[i] == 0x2 && stations_w2[i] == 0x0) || + (stations_w1[i] == 0x3 && stations_w2[i] == 0x1) || + (stations_w1[i] == 0x0 && stations_w2[i] == 0x4) || + (stations_w1[i] == 0x1 && stations_w2[i] == 0x5) || + (stations_w1[i] == 0xA && stations_w2[i] == 0x8) || + (stations_w1[i] == 0xB && stations_w2[i] == 0x9) || + (stations_w1[i] == 0x8 && stations_w2[i] == 0xC) || + (stations_w1[i] == 0x9 && stations_w2[i] == 0xD)) { + ++nMatchedStations; + } + } else if (wheelNum_w1 == wheelNum_w2 - 1) { // track 2 is one wheel higher than track 1 + if ((stations_w1[i] == 0xA && stations_w2[i] == 0x0) || + (stations_w1[i] == 0xB && stations_w2[i] == 0x1) || + (stations_w1[i] == 0x8 && stations_w2[i] == 0x4) || + (stations_w1[i] == 0x9 && stations_w2[i] == 0x5)) { + ++nMatchedStations; + } + } else if (wheelNum_w1 == wheelNum_w2 + 1) { // track 2 is one wheel lower than track 1 + if ((stations_w1[i] == 0x2 && stations_w2[i] == 0x8) || + (stations_w1[i] == 0x3 && stations_w2[i] == 0x9) || + (stations_w1[i] == 0x0 && stations_w2[i] == 0xC) || + (stations_w1[i] == 0x1 && stations_w2[i] == 0xD)) { + ++nMatchedStations; + } + } + } else { // If one muon in 0+ and one muon in 0- (0+ and 0- are physically the same wheel), however wheel 0 is not split in kalman algorithm + if (wheelNum_w1 == 0 && wheelNum_w2 == 1) { + if ((stations_w1[i] == 0xA && stations_w2[i] == 0x0) || + (stations_w1[i] == 0xB && stations_w2[i] == 0x1) || + (stations_w1[i] == 0x8 && stations_w2[i] == 0x4) || + (stations_w1[i] == 0x9 && stations_w2[i] == 0x5)) { + ++nMatchedStations; + } + } else if (wheelNum_w1 == 1 && wheelNum_w2 == 0) { + if ((stations_w1[i] == 0x2 && stations_w2[i] == 0x8) || + (stations_w1[i] == 0x3 && stations_w2[i] == 0x9) || + (stations_w1[i] == 0x0 && stations_w2[i] == 0xC) || + (stations_w1[i] == 0x1 && stations_w2[i] == 0xD)) { + ++nMatchedStations; + } + } + } + } + //std::cout << "Shared hits found: " << nMatchedStations << std::endl; + if (nMatchedStations > 0) { + if ((*mu_w1)->origin().hwQual() >= (*mu_w2)->origin().hwQual()) { + (*mu_w2)->setHwCancelBit(1); + } else { + (*mu_w1)->setHwCancelBit(1); + } + } + } + } + } + } // namespace l1t diff --git a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc index 631ab338c1cb8..02fbe67eb6bc5 100644 --- a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc +++ b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc @@ -1,76 +1,169 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "TMath.h" #include "L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h" +void l1t::MuonRawDigiTranslator::fillMuon(Muon& mu, + uint32_t raw_data_spare, + uint32_t raw_data_00_31, + uint32_t raw_data_32_63, + int fed, + unsigned int fw, + int muInBx) { + // Need the hw charge to properly compute dPhi + mu.setHwCharge((raw_data_32_63 >> chargeShift_) & 0x1); + + // The position of the eta and phi coordinates in the RAW data changed between the 2016 run and the 2017 run. + // Eta and phi at the muon system are replaced by eta and phi at the vertex + // Eta and phi at the muon system are moved to spare bits + // In Run-3 we have displacement information. + // To make room for these data the raw eta value was moved to the second "spare" word which we will have to treat separately + // The uGMT (FED 1402) or uGT (FED 1404) FW versions are used to determine the era. + if ((fed == 1402 && fw < 0x4010000) || (fed == 1404 && fw < 0x10A6)) { + fillMuonCoordinates2016(mu, raw_data_00_31, raw_data_32_63); + } else if ((fed == 1402 && fw < 0x6000000) || (fed == 1404 && fw < 0x1120)) { + fillMuonCoordinatesFrom2017(mu, raw_data_00_31, raw_data_32_63); + } else { + fillMuonQuantitiesRun3(mu, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx); + } + + // Fill pT, qual, iso, charge, index bits, coordinates at vtx + fillMuonStableQuantities(mu, raw_data_00_31, raw_data_32_63); +} + +void l1t::MuonRawDigiTranslator::fillIntermediateMuon(Muon& mu, + uint32_t raw_data_00_31, + uint32_t raw_data_32_63, + unsigned int fw) { + // Need the hw charge to properly compute dPhi + mu.setHwCharge((raw_data_32_63 >> chargeShift_) & 0x1); + + if (fw < 0x4010000) { + fillMuonCoordinates2016(mu, raw_data_00_31, raw_data_32_63); + } else if (fw < 0x6000000) { + fillMuonCoordinatesFrom2017(mu, raw_data_00_31, raw_data_32_63); + } else { + fillIntermediateMuonQuantitiesRun3(mu, raw_data_00_31, raw_data_32_63); + } + + // Fill pT, qual, iso, charge, index bits, phys. coordinates at vtx & unconstrained pT + fillMuonStableQuantities(mu, raw_data_00_31, raw_data_32_63); +} + +void l1t::MuonRawDigiTranslator::fillMuonStableQuantities(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63) { + mu.setHwPt((raw_data_00_31 >> ptShift_) & ptMask_); + mu.setHwQual((raw_data_00_31 >> qualShift_) & qualMask_); + mu.setHwIso((raw_data_32_63 >> isoShift_) & isoMask_); + // charge is coded as -1^chargeBit + mu.setHwChargeValid((raw_data_32_63 >> chargeValidShift_) & 0x1); + mu.setTfMuonIndex((raw_data_32_63 >> tfMuonIndexShift_) & tfMuonIndexMask_); + if (mu.hwChargeValid()) { + mu.setCharge(1 - 2 * mu.hwCharge()); + } else { + mu.setCharge(0); + } + + math::PtEtaPhiMLorentzVector vec{(mu.hwPt() - 1) * 0.5, mu.hwEta() * 0.010875, mu.hwPhi() * 0.010908, 0.0}; + mu.setP4(vec); + // generate a muon at the vertex to extract the physical eta and phi coordinates + math::PtEtaPhiMLorentzVector vecAtVtx{ + (mu.hwPt() - 1) * 0.5, mu.hwEtaAtVtx() * 0.010875, mu.hwPhiAtVtx() * 0.010908, 0.0}; + Muon muAtVtx; + muAtVtx.setP4(vecAtVtx); + mu.setEtaAtVtx(muAtVtx.eta()); + mu.setPhiAtVtx(muAtVtx.phi()); + + int hwPtUnconstrained{mu.hwPtUnconstrained()}; + mu.setPtUnconstrained(hwPtUnconstrained == 0 ? 0 : (hwPtUnconstrained - 1) * 0.5); // Don't want negative pT. +} + void l1t::MuonRawDigiTranslator::fillMuon( - Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, int fed, unsigned int fw) { - int hwPt = (raw_data_00_31 >> ptShift_) & ptMask_; - if (hwPt > 0) { - mu.setHwPt(hwPt); - mu.setHwQual((raw_data_00_31 >> qualShift_) & qualMask_); - mu.setHwIso((raw_data_32_63 >> isoShift_) & isoMask_); - // charge is coded as -1^chargeBit - mu.setHwCharge((raw_data_32_63 >> chargeShift_) & 0x1); - mu.setHwChargeValid((raw_data_32_63 >> chargeValidShift_) & 0x1); - mu.setTfMuonIndex((raw_data_32_63 >> tfMuonIndexShift_) & tfMuonIndexMask_); - - // The position of the eta and phi coordinates in the RAW data changed between the 2016 run and the 2017 run. - // Eta and phi at the muon system are replaced by eta and phi at the vertex - // Eta and phi at the muon system are moved to spare bits - // The uGMT (FED 1402) or uGT (FED 1404) FW versions are used to determine the era. - if ((fed == 1402 && fw < 0x4010000) || (fed == 1404 && fw < 0x10A6)) { - // coordinates at the muon system are in 2016 where in 2017 eta and phi at the vertex are - mu.setHwEta(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_)); - mu.setHwPhi((raw_data_00_31 >> phiAtVtxShift_) & phiMask_); - - // set the coordiantes at vertex to be the same as the coordinates at the muon system - mu.setHwEtaAtVtx(mu.hwEta()); - mu.setHwPhiAtVtx(mu.hwPhi()); - // deltas are 0 - mu.setHwDEtaExtra(0); - mu.setHwDPhiExtra(0); - } else { - // coordinates at the muon system - mu.setHwEta(calcHwEta(raw_data_32_63, absEtaShift_, etaSignShift_)); - mu.setHwPhi((raw_data_32_63 >> phiShift_) & phiMask_); - - // coordinates at the vertex - mu.setHwEtaAtVtx(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_)); - mu.setHwPhiAtVtx((raw_data_00_31 >> phiAtVtxShift_) & phiMask_); - // deltas - mu.setHwDEtaExtra(mu.hwEtaAtVtx() - mu.hwEta()); - int dPhi = mu.hwPhiAtVtx() - mu.hwPhi(); - if (mu.hwCharge() == 1 && dPhi > 0) { - dPhi -= 576; - } else if (mu.hwCharge() == 0 && dPhi < 0) { - dPhi += 576; - } - mu.setHwDPhiExtra(dPhi); - } + Muon& mu, uint32_t raw_data_spare, uint64_t dataword, int fed, unsigned int fw, int muInBx) { + fillMuon( + mu, raw_data_spare, (uint32_t)(dataword & 0xFFFFFFFF), (uint32_t)((dataword >> 32) & 0xFFFFFFFF), fed, fw, muInBx); +} - math::PtEtaPhiMLorentzVector vec{(mu.hwPt() - 1) * 0.5, mu.hwEta() * 0.010875, mu.hwPhi() * 0.010908, 0.0}; - mu.setP4(vec); - // generate a muon at the vertex to extract the physical eta and phi coordinates - math::PtEtaPhiMLorentzVector vecAtVtx{ - (mu.hwPt() - 1) * 0.5, mu.hwEtaAtVtx() * 0.010875, mu.hwPhiAtVtx() * 0.010908, 0.0}; - Muon muAtVtx; - muAtVtx.setP4(vecAtVtx); - mu.setEtaAtVtx(muAtVtx.eta()); - mu.setPhiAtVtx(muAtVtx.phi()); - if (mu.hwChargeValid()) { - mu.setCharge(1 - 2 * mu.hwCharge()); - } else { - mu.setCharge(0); - } +void l1t::MuonRawDigiTranslator::fillMuonCoordinates2016(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63) { + // coordinates at the muon system are in 2016 where in 2017 eta and phi at the vertex are + mu.setHwEta(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_)); + mu.setHwPhi((raw_data_00_31 >> phiAtVtxShift_) & phiMask_); + + // set the coordiantes at vertex to be the same as the coordinates at the muon system + mu.setHwEtaAtVtx(mu.hwEta()); + mu.setHwPhiAtVtx(mu.hwPhi()); + // deltas are 0 + mu.setHwDEtaExtra(0); + mu.setHwDPhiExtra(0); +} + +void l1t::MuonRawDigiTranslator::fillMuonCoordinatesFrom2017(Muon& mu, + uint32_t raw_data_00_31, + uint32_t raw_data_32_63) { + // coordinates at the muon system + mu.setHwEta(calcHwEta(raw_data_32_63, absEtaShift_, etaSignShift_)); + mu.setHwPhi((raw_data_32_63 >> phiShift_) & phiMask_); + + // coordinates at the vertex + mu.setHwEtaAtVtx(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_)); + mu.setHwPhiAtVtx((raw_data_00_31 >> phiAtVtxShift_) & phiMask_); + // deltas + mu.setHwDEtaExtra(mu.hwEtaAtVtx() - mu.hwEta()); + int dPhi = mu.hwPhiAtVtx() - mu.hwPhi(); + if (mu.hwCharge() == 1 && dPhi > 0) { + dPhi -= 576; + } else if (mu.hwCharge() == 0 && dPhi < 0) { + dPhi += 576; + } + mu.setHwDPhiExtra(dPhi); +} + +void l1t::MuonRawDigiTranslator::fillMuonQuantitiesRun3( + Muon& mu, uint32_t raw_data_spare, uint32_t raw_data_00_31, uint32_t raw_data_32_63, int muInBx) { + // coordinates at the muon system + // Where to find the raw eta depends on which muon we're looking at + if (muInBx == 1) { + mu.setHwEta(calcHwEta(raw_data_spare, absEtaMu1Shift_, etaMu1SignShift_)); + } else if (muInBx == 2) { + mu.setHwEta(calcHwEta(raw_data_spare, absEtaMu2Shift_, etaMu2SignShift_)); + } else { + edm::LogWarning("L1T") << "Received invalid muon id " << muInBx << ". Cannot fill eta value in the muon system."; + } + mu.setHwPhi((raw_data_32_63 >> phiShift_) & phiMask_); + + // coordinates at the vertex + mu.setHwEtaAtVtx(calcHwEta(raw_data_00_31, absEtaAtVtxShift_, etaAtVtxSignShift_)); + mu.setHwPhiAtVtx((raw_data_00_31 >> phiAtVtxShift_) & phiMask_); + // deltas + mu.setHwDEtaExtra(mu.hwEtaAtVtx() - mu.hwEta()); + int dPhi = mu.hwPhiAtVtx() - mu.hwPhi(); + if (mu.hwCharge() == 1 && dPhi > 0) { + dPhi -= 576; + } else if (mu.hwCharge() == 0 && dPhi < 0) { + dPhi += 576; } + mu.setHwDPhiExtra(dPhi); + + // displacement information + mu.setHwDXY((raw_data_32_63 >> dxyShift_) & dxyMask_); + mu.setHwPtUnconstrained((raw_data_32_63 >> ptUnconstrainedShift_) & ptUnconstrainedMask_); } -void l1t::MuonRawDigiTranslator::fillMuon(Muon& mu, uint64_t dataword, int fed, unsigned int fw) { - fillMuon(mu, (uint32_t)(dataword & 0xFFFFFFFF), (uint32_t)((dataword >> 32) & 0xFFFFFFFF), fed, fw); +void l1t::MuonRawDigiTranslator::fillIntermediateMuonQuantitiesRun3(Muon& mu, + uint32_t raw_data_00_31, + uint32_t raw_data_32_63) { + fillMuonCoordinatesFrom2017(mu, raw_data_00_31, raw_data_32_63); + + // displacement information + mu.setHwDXY((raw_data_32_63 >> dxyShift_) & dxyMask_); + mu.setHwPtUnconstrained((raw_data_00_31 >> ptUnconstrainedIntermedidateShift_) & ptUnconstrainedMask_); } void l1t::MuonRawDigiTranslator::generatePackedDataWords(const Muon& mu, + uint32_t& raw_data_spare, uint32_t& raw_data_00_31, - uint32_t& raw_data_32_63) { + uint32_t& raw_data_32_63, + int fedID, + int fwID, + int muInBx) { int abs_eta = mu.hwEta(); if (abs_eta < 0) { abs_eta += (1 << (etaSignShift_ - absEtaShift_)); @@ -79,22 +172,52 @@ void l1t::MuonRawDigiTranslator::generatePackedDataWords(const Muon& mu, if (abs_eta_at_vtx < 0) { abs_eta_at_vtx += (1 << (etaAtVtxSignShift_ - absEtaAtVtxShift_)); } - raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ | - (abs_eta_at_vtx & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEtaAtVtx() < 0) << etaAtVtxSignShift_ | - (mu.hwPhiAtVtx() & phiMask_) << phiAtVtxShift_; - - raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ | - (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_ | - (abs_eta & absEtaMask_) << absEtaShift_ | (mu.hwEta() < 0) << etaSignShift_ | - (mu.hwPhi() & phiMask_) << phiShift_; + if ((fedID == 1402 && fwID < 0x4010000) || (fedID == 1404 && fwID < 0x10A6)) { + // For 2016 the non-extrapolated coordiantes were in the place that are now occupied by the extrapolated quantities. + raw_data_spare = 0; + raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ | + (abs_eta & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEta() < 0) << etaAtVtxSignShift_ | + (mu.hwPhi() & phiMask_) << phiAtVtxShift_; + raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ | + (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_; + } else if ((fedID == 1402 && fwID < 0x6000000) || (fedID == 1404 && fwID < 0x1120)) { + raw_data_spare = 0; + raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ | + (abs_eta_at_vtx & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEtaAtVtx() < 0) << etaAtVtxSignShift_ | + (mu.hwPhiAtVtx() & phiMask_) << phiAtVtxShift_; + + raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ | + (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_ | + (abs_eta & absEtaMask_) << absEtaShift_ | (mu.hwEta() < 0) << etaSignShift_ | + (mu.hwPhi() & phiMask_) << phiShift_; + } else { + int absEtaShiftRun3{0}, etaSignShiftRun3{0}; + if (muInBx == 1) { + absEtaShiftRun3 = absEtaMu1Shift_; + etaSignShiftRun3 = etaMu1SignShift_; + } else if (muInBx == 2) { + absEtaShiftRun3 = absEtaMu2Shift_; + etaSignShiftRun3 = etaMu2SignShift_; + } + raw_data_spare = (abs_eta & absEtaMask_) << absEtaShiftRun3 | (mu.hwEta() < 0) << etaSignShiftRun3; + raw_data_00_31 = (mu.hwPt() & ptMask_) << ptShift_ | (mu.hwQual() & qualMask_) << qualShift_ | + (abs_eta_at_vtx & absEtaMask_) << absEtaAtVtxShift_ | (mu.hwEtaAtVtx() < 0) << etaAtVtxSignShift_ | + (mu.hwPhiAtVtx() & phiMask_) << phiAtVtxShift_; + raw_data_32_63 = mu.hwCharge() << chargeShift_ | mu.hwChargeValid() << chargeValidShift_ | + (mu.tfMuonIndex() & tfMuonIndexMask_) << tfMuonIndexShift_ | (mu.hwIso() & isoMask_) << isoShift_ | + (mu.hwPhi() & phiMask_) << phiShift_ | + (mu.hwPtUnconstrained() & ptUnconstrainedMask_) << ptUnconstrainedShift_ | + (mu.hwDXY() & dxyMask_) << dxyShift_; + } } -uint64_t l1t::MuonRawDigiTranslator::generate64bitDataWord(const Muon& mu) { +void l1t::MuonRawDigiTranslator::generate64bitDataWord( + const Muon& mu, uint32_t& raw_data_spare, uint64_t& dataword, int fedId, int fwId, int muInBx) { uint32_t lsw; uint32_t msw; - generatePackedDataWords(mu, lsw, msw); - return (((uint64_t)msw) << 32) + lsw; + generatePackedDataWords(mu, raw_data_spare, lsw, msw, fedId, fwId, muInBx); + dataword = (((uint64_t)msw) << 32) + lsw; } int l1t::MuonRawDigiTranslator::calcHwEta(const uint32_t& raw, diff --git a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc index e3681954067d5..dae2fd06445f4 100644 --- a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc +++ b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc @@ -2,7 +2,7 @@ #include "L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h" void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand( - RegionalMuonCand& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, int proc, tftype tf) { + RegionalMuonCand& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, int proc, tftype tf, bool isKalman) { // translations as defined in DN-15-017 mu.setHwPt((raw_data_00_31 >> ptShift_) & ptMask_); mu.setHwQual((raw_data_00_31 >> qualShift_) & qualMask_); @@ -31,7 +31,6 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand( // set track address with subaddresses int rawTrackAddress = (raw_data_32_63 >> trackAddressShift_) & trackAddressMask_; if (tf == bmtf) { - //int segSel = (rawTrackAddress >> bmtfTrAddrSegSelShift_) & bmtfTrAddrSegSelMask_; int detSide = (rawTrackAddress >> bmtfTrAddrDetSideShift_) & 0x1; int wheelNum = (rawTrackAddress >> bmtfTrAddrWheelShift_) & bmtfTrAddrWheelMask_; int statAddr1 = ((rawTrackAddress >> bmtfTrAddrStat1Shift_) & bmtfTrAddrStat1Mask_); @@ -41,10 +40,23 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand( mu.setTrackSubAddress(RegionalMuonCand::kWheelSide, detSide); mu.setTrackSubAddress(RegionalMuonCand::kWheelNum, wheelNum); - mu.setTrackSubAddress(RegionalMuonCand::kStat1, statAddr1); - mu.setTrackSubAddress(RegionalMuonCand::kStat2, statAddr2); - mu.setTrackSubAddress(RegionalMuonCand::kStat3, statAddr3); - mu.setTrackSubAddress(RegionalMuonCand::kStat4, statAddr4); + if (!isKalman) { // The Run-2 standard configuration + mu.setTrackSubAddress(RegionalMuonCand::kStat1, statAddr1); + mu.setTrackSubAddress(RegionalMuonCand::kStat2, statAddr2); + mu.setTrackSubAddress(RegionalMuonCand::kStat3, statAddr3); + mu.setTrackSubAddress(RegionalMuonCand::kStat4, statAddr4); + } else { + // For Run-3 track address encoding has changed as the Kalman Filter tracks from outside in. + // As a result station assignment is inverted + // (i.e. the field that contained the station 1 information for Run-2 now contains station 4 information and so on.) + mu.setTrackSubAddress(RegionalMuonCand::kStat1, statAddr4); + mu.setTrackSubAddress(RegionalMuonCand::kStat2, statAddr3); + mu.setTrackSubAddress(RegionalMuonCand::kStat3, statAddr2); + mu.setTrackSubAddress(RegionalMuonCand::kStat4, statAddr1); + // Additionally we now have displacement information from the BMTF + mu.setHwPtUnconstrained((raw_data_32_63 >> ptUnconstrainedShift_) & ptUnconstrainedMask_); + mu.setHwDXY((raw_data_32_63 >> dxyShift_) & dxyMask_); + } mu.setTrackSubAddress(RegionalMuonCand::kSegSelStat1, 0); mu.setTrackSubAddress(RegionalMuonCand::kSegSelStat2, 0); mu.setTrackSubAddress(RegionalMuonCand::kSegSelStat3, 0); @@ -78,16 +90,16 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand( mu.setDataword(raw_data_32_63, raw_data_00_31); } -void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand(RegionalMuonCand& mu, - uint64_t dataword, - int proc, - tftype tf) { - fillRegionalMuonCand(mu, (uint32_t)(dataword & 0xFFFFFFFF), (uint32_t)((dataword >> 32) & 0xFFFFFFFF), proc, tf); +void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand( + RegionalMuonCand& mu, uint64_t dataword, int proc, tftype tf, bool isKalman) { + fillRegionalMuonCand( + mu, (uint32_t)(dataword & 0xFFFFFFFF), (uint32_t)((dataword >> 32) & 0xFFFFFFFF), proc, tf, isKalman); } void l1t::RegionalMuonRawDigiTranslator::generatePackedDataWords(const RegionalMuonCand& mu, uint32_t& raw_data_00_31, - uint32_t& raw_data_32_63) { + uint32_t& raw_data_32_63, + const bool isKalman) { int abs_eta = mu.hwEta(); if (abs_eta < 0) { abs_eta += (1 << (etaSignShift_ - absEtaShift_)); @@ -102,6 +114,25 @@ void l1t::RegionalMuonRawDigiTranslator::generatePackedDataWords(const RegionalM (mu.hwPhi() < 0) << phiSignShift_; // generate the raw track address from the subaddresses + int rawTrkAddr = generateRawTrkAddress(mu, isKalman); + + raw_data_32_63 = mu.hwSign() << signShift_ | mu.hwSignValid() << signValidShift_ | + (rawTrkAddr & trackAddressMask_) << trackAddressShift_; + if (isKalman) { + raw_data_32_63 |= (mu.hwPtUnconstrained() & ptUnconstrainedMask_) << ptUnconstrainedShift_ | (mu.hwDXY() & dxyMask_) + << dxyShift_; + } +} + +uint64_t l1t::RegionalMuonRawDigiTranslator::generate64bitDataWord(const RegionalMuonCand& mu, const bool isKalman) { + uint32_t lsw; + uint32_t msw; + + generatePackedDataWords(mu, lsw, msw, isKalman); + return (((uint64_t)msw) << 32) + lsw; +} + +int l1t::RegionalMuonRawDigiTranslator::generateRawTrkAddress(const RegionalMuonCand& mu, const bool isKalman) { int tf = mu.trackFinderType(); int rawTrkAddr = 0; if (tf == bmtf) { @@ -113,14 +144,14 @@ void l1t::RegionalMuonRawDigiTranslator::generatePackedDataWords(const RegionalM int stat2 = mu.trackSubAddress(RegionalMuonCand::kStat2); int stat3 = mu.trackSubAddress(RegionalMuonCand::kStat3); int stat4 = mu.trackSubAddress(RegionalMuonCand::kStat4); - - int segSel = mu.trackSubAddress(RegionalMuonCand::kSegSelStat1) | - (mu.trackSubAddress(RegionalMuonCand::kSegSelStat2)) >> 1 | - (mu.trackSubAddress(RegionalMuonCand::kSegSelStat3)) >> 2 | - (mu.trackSubAddress(RegionalMuonCand::kSegSelStat4)) >> 3; - - rawTrkAddr = (segSel & bmtfTrAddrSegSelMask_) << bmtfTrAddrSegSelShift_ | - (detSide & 0x1) << bmtfTrAddrDetSideShift_ | + if (isKalman) { + stat1 = mu.trackSubAddress(RegionalMuonCand::kStat4); + stat2 = mu.trackSubAddress(RegionalMuonCand::kStat3); + stat3 = mu.trackSubAddress(RegionalMuonCand::kStat2); + stat4 = mu.trackSubAddress(RegionalMuonCand::kStat1); + } + + rawTrkAddr = (detSide & 0x1) << bmtfTrAddrDetSideShift_ | (wheelNum & bmtfTrAddrWheelMask_) << bmtfTrAddrWheelShift_ | (stat1 & bmtfTrAddrStat1Mask_) << bmtfTrAddrStat1Shift_ | (stat2 & bmtfTrAddrStat2Mask_) << bmtfTrAddrStat2Shift_ | @@ -168,14 +199,5 @@ void l1t::RegionalMuonRawDigiTranslator::generatePackedDataWords(const RegionalM rawTrkAddr = mu.trackAddress().at(0); } - raw_data_32_63 = mu.hwSign() << signShift_ | mu.hwSignValid() << signValidShift_ | - (rawTrkAddr & trackAddressMask_) << trackAddressShift_; -} - -uint64_t l1t::RegionalMuonRawDigiTranslator::generate64bitDataWord(const RegionalMuonCand& mu) { - uint32_t lsw; - uint32_t msw; - - generatePackedDataWords(mu, lsw, msw); - return (((uint64_t)msw) << 32) + lsw; + return rawTrkAddr; } diff --git a/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanAlgo.cc b/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanAlgo.cc index 7380382040bd8..0909710653d4d 100644 --- a/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanAlgo.cc +++ b/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanAlgo.cc @@ -105,7 +105,7 @@ l1t::RegionalMuonCand L1TMuonBarrelKalmanAlgo::convertToBMTF(const L1MuKBMTrack& l1t::RegionalMuonCand muon(pt, phi, eta, sign, signValid, quality, processor, l1t::bmtf, addr); muon.setHwHF(HF); - muon.setHwPt2(pt2); + muon.setHwPtUnconstrained(pt2); muon.setHwDXY(dxy); //nw the words! @@ -1068,10 +1068,10 @@ std::map L1TMuonBarrelKalmanAlgo::trackAddress(const L1MuKBMTrack& tra out[l1t::RegionalMuonCand::kWheelNum] = 2; else out[l1t::RegionalMuonCand::kWheelNum] = 0; - out[l1t::RegionalMuonCand::kStat1] = 3; + out[l1t::RegionalMuonCand::kStat1] = 15; out[l1t::RegionalMuonCand::kStat2] = 15; out[l1t::RegionalMuonCand::kStat3] = 15; - out[l1t::RegionalMuonCand::kStat4] = 15; + out[l1t::RegionalMuonCand::kStat4] = 3; out[l1t::RegionalMuonCand::kSegSelStat1] = 0; out[l1t::RegionalMuonCand::kSegSelStat2] = 0; out[l1t::RegionalMuonCand::kSegSelStat3] = 0; @@ -1092,24 +1092,24 @@ std::map L1TMuonBarrelKalmanAlgo::trackAddress(const L1MuKBMTrack& tra addr = 1; else addr = 2; - out[l1t::RegionalMuonCand::kStat1] = addr; + out[l1t::RegionalMuonCand::kStat4] = addr; } if (stub->stNum() == 3) { - out[l1t::RegionalMuonCand::kStat2] = addr; + out[l1t::RegionalMuonCand::kStat3] = addr; } if (stub->stNum() == 2) { - out[l1t::RegionalMuonCand::kStat3] = addr; + out[l1t::RegionalMuonCand::kStat2] = addr; } if (stub->stNum() == 1) { - out[l1t::RegionalMuonCand::kStat4] = addr; + out[l1t::RegionalMuonCand::kStat1] = addr; } } word = 0; - word = word | out[l1t::RegionalMuonCand::kStat1] << 12; - word = word | out[l1t::RegionalMuonCand::kStat2] << 8; - word = word | out[l1t::RegionalMuonCand::kStat3] << 4; - word = word | out[l1t::RegionalMuonCand::kStat4]; + word = word | out[l1t::RegionalMuonCand::kStat4] << 12; + word = word | out[l1t::RegionalMuonCand::kStat3] << 8; + word = word | out[l1t::RegionalMuonCand::kStat2] << 4; + word = word | out[l1t::RegionalMuonCand::kStat1]; return out; } diff --git a/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanSectorProcessor.cc b/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanSectorProcessor.cc index bdb84df864f3d..9c28428153de5 100644 --- a/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanSectorProcessor.cc +++ b/L1Trigger/L1TMuonBarrel/src/L1TMuonBarrelKalmanSectorProcessor.cc @@ -114,7 +114,7 @@ L1TMuonBarrelKalmanSectorProcessor::bmtf_out L1TMuonBarrelKalmanSectorProcessor: out.addr4_1 = mu.trackSubAddress(l1t::RegionalMuonCand::kStat4); out.wheel_1 = mu.trackSubAddress(l1t::RegionalMuonCand::kWheelSide) * (1 << 2) + mu.trackSubAddress(l1t::RegionalMuonCand::kWheelNum); - out.ptSTA_1 = mu.hwPt2(); + out.ptSTA_1 = mu.hwPtUnconstrained(); } if (tracks.size() > 1) { @@ -135,7 +135,7 @@ L1TMuonBarrelKalmanSectorProcessor::bmtf_out L1TMuonBarrelKalmanSectorProcessor: out.wheel_2 = mu.trackSubAddress(l1t::RegionalMuonCand::kWheelSide) * (1 << 2) + mu.trackSubAddress(l1t::RegionalMuonCand::kWheelNum); - out.ptSTA_2 = mu.hwPt2(); + out.ptSTA_2 = mu.hwPtUnconstrained(); } if (tracks.size() > 2) { @@ -155,7 +155,7 @@ L1TMuonBarrelKalmanSectorProcessor::bmtf_out L1TMuonBarrelKalmanSectorProcessor: out.addr4_3 = mu.trackSubAddress(l1t::RegionalMuonCand::kStat4); out.wheel_3 = mu.trackSubAddress(l1t::RegionalMuonCand::kWheelSide) * (1 << 2) + mu.trackSubAddress(l1t::RegionalMuonCand::kWheelNum); - out.ptSTA_3 = mu.hwPt2(); + out.ptSTA_3 = mu.hwPtUnconstrained(); } return out; } diff --git a/L1Trigger/L1TMuonBarrel/test/kalmanTools/kmtfAnalysis.py b/L1Trigger/L1TMuonBarrel/test/kalmanTools/kmtfAnalysis.py index f489bd1defca0..a29b918519d17 100644 --- a/L1Trigger/L1TMuonBarrel/test/kalmanTools/kmtfAnalysis.py +++ b/L1Trigger/L1TMuonBarrel/test/kalmanTools/kmtfAnalysis.py @@ -1,9 +1,9 @@ from __future__ import print_function import ROOT,itertools,math # -from array import array # +from array import array # from DataFormats.FWLite import Events, Handle ROOT.FWLiteEnabler.enable() -# +# @@ -24,7 +24,7 @@ class BMTFMuon: def __init__(self,mu,pt,eta,phi): self.muon=mu self.p4 = ROOT.reco.Candidate.PolarLorentzVector(pt,eta,phi,0.105) - + def quality(self): return self.muon.hwQual() @@ -38,7 +38,7 @@ def hasFineEta(self): return self.muon.hwHF() def ptUnconstrained(self): - return self.muon.hwPt2() + return self.muon.hwPtUnconstrained() def dxy(self): return self.muon.hwDXY() @@ -47,7 +47,7 @@ def charge(self): if self.muon.hwSign()>0: return -1 else: - return +1 + return +1 def __getattr__(self, name): return getattr(self.p4,name) @@ -59,7 +59,7 @@ def getQual(track): q=0 for stub in track.stubs(): q+=stub.quality() - return q; + return q; def fetchTP(event,etaMax=0.83): @@ -76,7 +76,7 @@ def fetchTP(event,etaMax=0.83): trigger=tH.product() # for f in range(0,trigger.sizeFilters()): # print(f,trigger.filterLabel(f)) -# import pdb;pdb.set_trace() +# import pdb;pdb.set_trace() obj = trigger.getObjects() index = trigger.filterIndex(ROOT.edm.InputTag("hltL3fL1sMu22Or25L1f0L2f10QL3Filtered27Q::HLT")) if index==trigger.sizeFilters(): @@ -108,7 +108,7 @@ def fetchTP(event,etaMax=0.83): break if isProbe: probes.append(mu) - + return probes @@ -204,10 +204,10 @@ def fetchBMTF(event,isData,etaMax=1.2): K=1.0/pt K=1.181*K/(1+0.4867*K) pt=1.0/K - #### + #### phi=globalBMTFPhi(mu,'BMTF') rawP = rawPhi(mu) - eta = mu.hwEta()*0.010875 + eta = mu.hwEta()*0.010875 if abs(eta)<=etaMax: b = BMTFMuon(mu,pt,eta,phi) b.rawPhi=rawP @@ -231,7 +231,7 @@ def fetchKMTFNew(event,etaMax=1.2,saturate=True): pt=140.0 phi=globalBMTFPhi(mu,'KMTF') rawP = rawPhi(mu) - eta = mu.hwEta()*0.010875 + eta = mu.hwEta()*0.010875 if abs(eta)<=etaMax: b = BMTFMuon(mu,pt,eta,phi) b.rawPhi=rawP @@ -265,7 +265,7 @@ def fetchKMTF(event,etaMax=0.83,patterns=[],comps=[],chis=[],pts=[]): if mu.hitPattern()==p and mu.pt()>pt and (mu.trackCompatibility()>comp or mu.approxChi2()>chi): veto=True break; - if not veto: + if not veto: out.append(mu) return sorted(out,key=lambda x: x.pt(),reverse=True) @@ -299,7 +299,7 @@ def deltaR2( e1, p1, e2, p2): return de*de + dp*dp -def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): +def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): print("--------EVENT"+str(counter)+"------------") print("-----------------------------") print("-----------------------------") @@ -506,7 +506,7 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): # log(counter,stubs,gen,kmtfFull,kmtf,bmtf) - + for track in kmtfFull: chiAll[track.hitPattern()].Fill(abs(track.curvatureAtVertex()),track.approxChi2()) trackCompAll[track.hitPattern()].Fill(abs(track.curvatureAtVertex()),min(track.trackCompatibility(),99.5)); @@ -519,19 +519,19 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): etaKMTF.Fill(track.eta()) fineEtaKMTF.Fill(track.hasFineEta()) - if len(kmtf)>0: - PT=kmtf[0].pt() + if len(kmtf)>0: + PT=kmtf[0].pt() if kmtf[0].pt()>49.99: PT=49.99 - + if abs(kmtf[0].eta())<0.7: rateKMTFp7.Fill(PT) rateKMTF.Fill(PT) - - if len(kmtfFull)>0: - - PT=kmtfFull[0].pt() + + if len(kmtfFull)>0: + + PT=kmtfFull[0].pt() if kmtfFull[0].pt()>49.99: PT=49.99 ratePerTrack[kmtfFull[0].hitPattern()].Fill(PT) @@ -542,17 +542,17 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): etaBMTF.Fill(track.eta()) fineEtaBMTF.Fill(track.hasFineEta()) - if (len(bmtf)>0): - PT=bmtf[0].pt() + if (len(bmtf)>0): + PT=bmtf[0].pt() if bmtf[0].pt()>49.99: - PT=49.99 + PT=49.99 if abs(bmtf[0].eta())<0.7: rateBMTFp7.Fill(PT) rateBMTF.Fill(PT) # if ( len(kmtfFull)>0) and (kmtfFull[0].pt()>50): # log(counter,stubs,gen,kmtfFull,kmtf,bmtf) - + # if (len(kmtf)>0 and kmtf[0].pt()>20) and (len(bmtf)==0 or (len(bmtf)>0 and bmtf[0].pt()<10)): # log(counter,stubs,gen,kmtfFull,kmtf,bmtf) @@ -574,18 +574,18 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): genPhi.Fill(g.phi()) #match *(loosely because we still use coarse eta) - matchedBMTF = filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3,bmtf) - matchedKMTF = filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3,kmtf) - matchedKMTFFull = filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3,kmtfFull) + matchedBMTF = filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3,bmtf) + matchedKMTF = filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3,kmtf) + matchedKMTFFull = filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3,kmtfFull) -# matchedBMTF = filter(lambda x: abs(deltaPhi(g.phi(),x.phi()))<2.5,bmtf) -# matchedKMTF = filter(lambda x: abs(deltaPhi(g.phi(),x.phi()))<2.5,kmtf) -# matchedKMTFFull = filter(lambda x: abs(deltaPhi(g.phi(),x.phi()))<2.5,kmtfFull) +# matchedBMTF = filter(lambda x: abs(deltaPhi(g.phi(),x.phi()))<2.5,bmtf) +# matchedKMTF = filter(lambda x: abs(deltaPhi(g.phi(),x.phi()))<2.5,kmtf) +# matchedKMTFFull = filter(lambda x: abs(deltaPhi(g.phi(),x.phi()))<2.5,kmtfFull) - bestBMTF=None + bestBMTF=None if len(matchedBMTF)>0: bestBMTF = max(matchedBMTF,key = lambda x: x.quality()*1000+x.pt()) resBMTF.Fill(g.pt(),curvResidual(bestBMTF,g)) @@ -598,17 +598,17 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): phiCalibBMTF.Fill(g.charge()/g.pt(),bestBMTF.rawPhi-g.phi()) resRBMTF.Fill(deltaR(g.eta(),g.phi(),bestBMTF.eta(),bestBMTF.phi())) bmtfCalib.Fill(bestBMTF.pt(),bestBMTF.pt()/g.pt()) - - # for the turn on , first cut on pt and then match + + # for the turn on , first cut on pt and then match for threshold in PTThresholds: filteredBMTF = filter(lambda x: x.pt()>=float(threshold),matchedBMTF) if len(filteredBMTF)>0: genPtBMTF[threshold].Fill(g.pt()) if g.pt()>40: genEtaBMTF[threshold].Fill(g.eta()) - - bestKMTF=None + + bestKMTF=None if len(matchedKMTF)>0: bestKMTF = max(matchedKMTF,key = lambda x: 1000*x.quality()+x.pt()) @@ -619,7 +619,7 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): resPTKMTF.Fill(g.pt(),ptResidual(bestKMTF,g)) - + resEtaKMTF.Fill(g.eta(),bestKMTF.eta()-g.eta()) resPhiKMTF.Fill(g.pt(),bestKMTF.rawPhi-genPhiAt2) if g.pt()<140: @@ -629,7 +629,7 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): K = bestKMTF.charge()/bestKMTF.pt() if K==0: K=1; - + # if len(matchedKMTF)>0 and len(matchedBMTF)>0: # if bestBMTF.hasFineEta() and (not bestKMTF.hasFineEta()): @@ -640,18 +640,18 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): # print(s.bxNum(),s.scNum(), s.whNum(), s.stNum(),d ) - + # if abs(curvResidual(bestKMTF,g))>2.: - + for threshold in PTThresholds: filteredKMTF = filter(lambda x: x.pt()>=float(threshold),matchedKMTF) if len(filteredKMTF)>0: genPtKMTF[threshold].Fill(g.pt()) if len(filteredKMTF)>0 and g.pt()>40: genEtaKMTF[threshold].Fill(g.eta()) - + # if (bestKMTF==None or (bestKMTF!=None and bestKMTF.pt()<15)) and bestBMTF!=None and g.pt()>30 and abs(g.eta())>0.15 and abs(g.eta())<0.32: # log(counter,stubs,gen,kmtfFull,kmtf,bmtf) @@ -680,11 +680,11 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): # import pdb;pdb.set_trace() if len(matchedKMTFFull)>0: - bestKMTFFull = max(matchedKMTFFull,key = lambda x: x.rank()*1000+x.pt()) + bestKMTFFull = max(matchedKMTFFull,key = lambda x: x.rank()*1000+x.pt()) chiMatched[bestKMTFFull.hitPattern()].Fill(abs(bestKMTFFull.curvatureAtVertex()),bestKMTFFull.approxChi2()); trackComp[bestKMTFFull.hitPattern()].Fill(abs(bestKMTFFull.curvatureAtVertex()),min(bestKMTFFull.trackCompatibility(),99.5)); - + resKMTFTrack[bestKMTFFull.hitPattern()].Fill(g.pt(),curvResidual(bestKMTFFull,g)) resKMTFTrack[0].Fill(g.pt(),curvResidual(bestKMTFFull,g)) if bestKMTFFull.charge()>0: @@ -697,15 +697,15 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): - - - - + + + + f=ROOT.TFile("results_"+tag+".root","RECREATE") @@ -715,27 +715,27 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): quality.Write() -resKMTF.Write() +resKMTF.Write() for n,t in resKMTFTrack.iteritems(): t.Write() - -resKMTFEta.Write() -resSTAKMTF.Write() -resPTKMTF.Write() + +resKMTFEta.Write() +resSTAKMTF.Write() +resPTKMTF.Write() resBMTF.Write() resBMTFEta.Write() resPTBMTF.Write() -resEtaKMTF.Write() -resEtaBMTF.Write() -resPhiKMTF.Write() -resRKMTF.Write() -resPhiBMTF.Write() +resEtaKMTF.Write() +resEtaBMTF.Write() +resPhiKMTF.Write() +resRKMTF.Write() +resPhiBMTF.Write() phiCalibBMTF.Write() phiCalibKMTF.Write() -resRBMTF.Write() +resRBMTF.Write() #bmtfCalib.Write() #kfCalib.Write() genPt.Write() @@ -761,7 +761,7 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): genPtKMTF[p].Add(genPtBMTF[p],-1) genPtKMTF[p].Divide(genPt) genPtKMTF[p].Write("efficiencyDiffVsPt"+str(p)) - + genEtaKMTF[p].Add(genEtaBMTF[p],-1) genEtaKMTF[p].Divide(genEta) genEtaKMTF[p].Write("efficiencyDiffVsEta"+str(p)) @@ -780,11 +780,11 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): -rateBMTF.Write() +rateBMTF.Write() c = rateBMTF.GetCumulative(False) c.SetLineWidth(3) c.SetLineColor(ROOT.kBlack) -c.Write("normRateBMTF") +c.Write("normRateBMTF") for track in kfCalibPlus.keys(): kfCalibPlus[track].Write() @@ -799,9 +799,9 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): bmtfCalib.Write() -rateKMTF.Write() +rateKMTF.Write() c = rateKMTF.GetCumulative(False) -c.Write("normRateKMTF") +c.Write("normRateKMTF") d = rateBMTF.GetCumulative(False) @@ -809,13 +809,13 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): d.Write("rateRatioBMTFoverKMTF") -rateBMTFp7.Write() +rateBMTFp7.Write() c = rateBMTFp7.GetCumulative(False) -c.Write("normRateBMTFEtaP7") +c.Write("normRateBMTFEtaP7") -rateKMTFp7.Write() +rateKMTFp7.Write() c = rateKMTFp7.GetCumulative(False) -c.Write("normRateKMTFEtaP7") +c.Write("normRateKMTFEtaP7") @@ -823,9 +823,3 @@ def log(counter,mystubs,gen,kmtfFull,kmtf,bmtf): fineEtaBMTF.Write() f.Close() - - - - - - diff --git a/L1Trigger/L1TMuonBarrel/test/kalmanTools/validation.py b/L1Trigger/L1TMuonBarrel/test/kalmanTools/validation.py index 1a58552cd2fb0..a7a515194f274 100644 --- a/L1Trigger/L1TMuonBarrel/test/kalmanTools/validation.py +++ b/L1Trigger/L1TMuonBarrel/test/kalmanTools/validation.py @@ -1,9 +1,9 @@ from __future__ import print_function import ROOT,itertools,math # -from array import array # +from array import array # from DataFormats.FWLite import Events, Handle ROOT.FWLiteEnabler.enable() -# +# @@ -64,7 +64,7 @@ def fetchKMTF(event,etaMax,collection): mu = kbmtf.at(bx,j) kbmtfMuons[bx].append(mu) # kbmtfMuons[bx]=sorted(kbmtfMuons[bx],key=lambda x: x.hwPt(),reverse=True) - return kbmtfMuons + return kbmtfMuons def curvResidual(a,b): return (a.charge()/a.pt()-b.charge()/b.pt())*b.pt()/b.charge() @@ -96,7 +96,7 @@ def deltaR2( e1, p1, e2, p2): return de*de + dp*dp -def log(event,counter,mystubs,kmtf,bmtf): +def log(event,counter,mystubs,kmtf,bmtf): print("--------EVENT"+str(counter)+"------------") print('RUN={run} LUMI={lumi} EVENT={event}'.format(run=event.eventAuxiliary().id().run(),lumi=event.eventAuxiliary().id().luminosityBlock(),event=event.eventAuxiliary().id().event())) print("-----------------------------") @@ -106,10 +106,10 @@ def log(event,counter,mystubs,kmtf,bmtf): print('wheel={w} sector={sc} station={st} high/low={ts} phi={phi} phiB={phiB} qual={qual} BX={BX}'.format(w=stub.whNum(),sc=stub.scNum(),st=stub.stNum(),ts=stub.Ts2Tag(),phi=stub.phi(),phiB=stub.phiB(),qual=stub.code(),BX=stub.bxNum())) print('EMU:') for g in bmtf : - print("EMU sector={sector} pt={pt} eta={eta} phi={phi} qual={qual} dxy={dxy} pt2={pt2} hasFineEta={HF}".format(sector=g.processor(), pt=g.hwPt(),eta=g.hwEta(),phi=g.hwPhi(),qual=g.hwQual(),dxy=g.hwDXY(),pt2=g.hwPt2(),HF=g.hwHF())) + print("EMU sector={sector} pt={pt} eta={eta} phi={phi} qual={qual} dxy={dxy} pt2={pt2} hasFineEta={HF}".format(sector=g.processor(), pt=g.hwPt(),eta=g.hwEta(),phi=g.hwPhi(),qual=g.hwQual(),dxy=g.hwDXY(),pt2=g.hwPtUnconstrained(),HF=g.hwHF())) print('DATA:') for g in kmtf : - print("DATA sector={sector} pt={pt} eta={eta} phi={phi} qual={qual} dxy={dxy} pt2={pt2} hasFineEta={HF}".format(sector=g.processor(),pt=g.hwPt(),eta=g.hwEta(),phi=g.hwPhi(),qual=g.hwQual(),dxy=g.hwDXY(),pt2=g.hwPt2(),HF=g.hwHF())) + print("DATA sector={sector} pt={pt} eta={eta} phi={phi} qual={qual} dxy={dxy} pt2={pt2} hasFineEta={HF}".format(sector=g.processor(),pt=g.hwPt(),eta=g.hwEta(),phi=g.hwPhi(),qual=g.hwQual(),dxy=g.hwDXY(),pt2=g.hwPtUnconstrained(),HF=g.hwHF())) print("-----------------------------") print("-----------------------------") print("c + enter to continue") @@ -185,7 +185,7 @@ def fill(info,mu): info['HF1'].Fill(mu[0].hwHF()) info['qual1'].Fill(mu[0].hwQual()) info['dxy1'].Fill(mu[0].hwDXY()) - info['ptSTA1'].Fill(mu[0].hwPt2()) + info['ptSTA1'].Fill(mu[0].hwPtUnconstrained()) else: info['pt1'].Fill(0) info['eta1'].Fill(0) @@ -202,7 +202,7 @@ def fill(info,mu): info['HF2'].Fill(mu[1].hwHF()) info['qual2'].Fill(mu[1].hwQual()) info['dxy2'].Fill(mu[1].hwDXY()) - info['ptSTA2'].Fill(mu[1].hwPt2()) + info['ptSTA2'].Fill(mu[1].hwPtUnconstrained()) else: info['pt2'].Fill(0) info['eta2'].Fill(0) @@ -219,7 +219,7 @@ def fill(info,mu): info['HF3'].Fill(mu[2].hwHF()) info['qual3'].Fill(mu[2].hwQual()) info['dxy3'].Fill(mu[2].hwDXY()) - info['ptSTA3'].Fill(mu[2].hwPt2()) + info['ptSTA3'].Fill(mu[2].hwPtUnconstrained()) else: info['pt3'].Fill(0) info['eta3'].Fill(0) @@ -248,14 +248,14 @@ def fill(info,mu): stubs=fetchStubsOLD(event,True) unpacker=fetchKMTF(event,100.0,'bmtfDigis:kBMTF') emulator=fetchKMTF(event,100.0,'simKBmtfDigis:BMTF') - - + + for processor in range(0,12): for bx in BUNCHES: emu=filter(lambda x: x.processor()==processor,emulator[bx]) data=filter(lambda x: x.processor()==processor,unpacker[bx]) if (len(emu)+len(data))>0: - + fill(histos['emu'],emu) fill(histos['fw'],data) # if len(emu)!=0 and len(data)==0: @@ -287,16 +287,10 @@ def fill(info,mu): l.AddEntry(histos['fw'][h],"data","p") l.Draw() c.Write("plot_"+h) - - - - - - -f.Close() +f.Close() diff --git a/L1Trigger/L1TMuonEndCap/interface/TrackTools.h b/L1Trigger/L1TMuonEndCap/interface/TrackTools.h index bb45c120a4544..631d347ea83d8 100644 --- a/L1Trigger/L1TMuonEndCap/interface/TrackTools.h +++ b/L1Trigger/L1TMuonEndCap/interface/TrackTools.h @@ -21,7 +21,11 @@ namespace emtf { // CSC max strip & max wire - void get_csc_max_strip_and_wire(int station, int ring, int& max_strip, int& max_wire); + std::pair get_csc_max_strip_and_wire(int station, int ring); + + // CSC max pattern & max quality + + std::pair get_csc_max_pattern_and_quality(int station, int ring); // ___________________________________________________________________________ // coordinate ranges: phi[-180, 180] or [-pi, pi], theta[0, 90] or [0, pi/2] diff --git a/L1Trigger/L1TMuonEndCap/src/PrimitiveSelection.cc b/L1Trigger/L1TMuonEndCap/src/PrimitiveSelection.cc index 4ccc7258fb8a6..be6975902578e 100644 --- a/L1Trigger/L1TMuonEndCap/src/PrimitiveSelection.cc +++ b/L1Trigger/L1TMuonEndCap/src/PrimitiveSelection.cc @@ -50,44 +50,19 @@ void PrimitiveSelection::process(emtf::CSCTag tag, TriggerPrimitiveCollection::const_iterator tp_end = muon_primitives.end(); for (; tp_it != tp_end; ++tp_it) { - TriggerPrimitive new_tp = *tp_it; // make a copy and apply patches to this copy - - // Patch the CLCT pattern number - // It should be 0-10, see: L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc - bool patchPattern = true; - if (patchPattern && new_tp.subsystem() == TriggerPrimitive::kCSC) { - if (new_tp.getCSCData().pattern == 11 || new_tp.getCSCData().pattern == 12 || new_tp.getCSCData().pattern == 13 || - new_tp.getCSCData().pattern == 14) { // 11, 12, 13, 14 -> 10 - edm::LogWarning("L1T") << "EMTF patching corrupt CSC LCT pattern: changing " << new_tp.getCSCData().pattern - << " to 10"; - new_tp.accessCSCData().pattern = 10; - } - } - - // Patch the LCT quality number - // It should be 1-15, see: L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc - bool patchQuality = true; - if (patchQuality && new_tp.subsystem() == TriggerPrimitive::kCSC) { - if (new_tp.getCSCData().quality == 0) { // 0 -> 1 - edm::LogWarning("L1T") << "EMTF patching corrupt CSC LCT quality: changing " << new_tp.getCSCData().quality - << " to 1"; - new_tp.accessCSCData().quality = 1; - } - } - - int selected_csc = select_csc(new_tp); // Returns CSC "link" index (0 - 53) + int selected_csc = select_csc(*tp_it); // Returns CSC "link" index (0 - 53) if (selected_csc >= 0) { emtf_assert(selected_csc < NUM_CSC_CHAMBERS); //FIXME if (selected_csc_map[selected_csc].size() < 2) { - selected_csc_map[selected_csc].push_back(new_tp); + selected_csc_map[selected_csc].push_back(*tp_it); } else { edm::LogWarning("L1T") << "\n******************* EMTF EMULATOR: SUPER-BIZZARE CASE *******************"; edm::LogWarning("L1T") << "Found 3 CSC trigger primitives in the same chamber"; for (int ii = 0; ii < 3; ii++) { - TriggerPrimitive tp_err = (ii < 2 ? selected_csc_map[selected_csc].at(ii) : new_tp); + TriggerPrimitive tp_err = (ii < 2 ? selected_csc_map[selected_csc].at(ii) : *tp_it); edm::LogWarning("L1T") << "LCT #" << ii + 1 << ": BX " << tp_err.getBX() << ", endcap " << tp_err.detId().endcap() << ", sector " << tp_err.detId().triggerSector() << ", station " @@ -623,9 +598,8 @@ int PrimitiveSelection::select_csc(const TriggerPrimitive& muon_primitive) const int tp_bx = tp_data.bx; int tp_csc_ID = tp_data.cscID; - int max_strip = 0; // halfstrip - int max_wire = 0; // wiregroup - emtf::get_csc_max_strip_and_wire(tp_station, tp_ring, max_strip, max_wire); + const auto& [max_strip, max_wire] = emtf::get_csc_max_strip_and_wire(tp_station, tp_ring); + const auto& [max_pattern, max_quality] = emtf::get_csc_max_pattern_and_quality(tp_station, tp_ring); if (endcap_ == 1 && sector_ == 1 && bx_ == -3) { // do assertion checks only once emtf_assert(emtf::MIN_ENDCAP <= tp_endcap && tp_endcap <= emtf::MAX_ENDCAP); @@ -635,21 +609,62 @@ int PrimitiveSelection::select_csc(const TriggerPrimitive& muon_primitive) const emtf_assert(tp_data.strip < max_strip); emtf_assert(tp_data.keywire < max_wire); emtf_assert(tp_data.valid == true); - emtf_assert(tp_data.pattern <= 10); - //emtf_assert(tp_data.quality > 0); + emtf_assert(tp_data.pattern < max_pattern); + emtf_assert(0 < tp_data.quality && tp_data.quality < max_quality); } - // LogWarning - if (!(tp_data.strip < max_strip)) { - edm::LogWarning("L1T") << "EMTF CSC format error in station " << tp_station << ", ring " << tp_ring - << ": tp_data.strip = " << tp_data.strip << " (max = " << max_strip - 1 << ")"; - return selected; - } - if (!(tp_data.keywire < max_wire)) { - edm::LogWarning("L1T") << "EMTF CSC format error in station " << tp_station << ", ring " << tp_ring - << ": tp_data.keywire = " << tp_data.keywire << " (max = " << max_wire - 1 << ")"; - return selected; - } + // Check for corrupted LCT data. Data corruption could occur due to software or hardware issues, If corrupted, reject the LCT. + // Note that the checks are performed in every sector processor for every BX. As a result, the same LCT may be reported multiple times by all 12 sector processors from BX=-3 to BX=+3. + { + if (!(tp_data.strip < max_strip)) { + edm::LogWarning("L1T") << "Found error in LCT strip: " << tp_data.strip << " (allowed range: 0-" + << max_strip - 1 << ")."; + edm::LogWarning("L1T") + << "From endcap " << tp_endcap << ", sector " << tp_sector << ", station " << tp_station << ", ring " + << tp_ring << ", cscid " << tp_csc_ID + << ". (Note that this LCT may be reported multiple times. See source code for explanations.)"; + return selected; + } + + if (!(tp_data.keywire < max_wire)) { + edm::LogWarning("L1T") << "Found error in LCT wire: " << tp_data.keywire << " (allowed range: 0-" + << max_wire - 1 << ")."; + edm::LogWarning("L1T") + << "From endcap " << tp_endcap << ", sector " << tp_sector << ", station " << tp_station << ", ring " + << tp_ring << ", cscid " << tp_csc_ID + << ". (Note that this LCT may be reported multiple times. See source code for explanations.)"; + return selected; + } + + if (!(tp_data.valid == true)) { + edm::LogWarning("L1T") << "Found error in LCT valid: " << tp_data.valid << " (allowed value: 1)."; + edm::LogWarning("L1T") + << "From endcap " << tp_endcap << ", sector " << tp_sector << ", station " << tp_station << ", ring " + << tp_ring << ", cscid " << tp_csc_ID + << ". (Note that this LCT may be reported multiple times. See source code for explanations.)"; + return selected; + } + + if (!(tp_data.pattern < max_pattern)) { + edm::LogWarning("L1T") << "Found error in LCT pattern: " << tp_data.pattern << " (allowed range: 0-" + << max_pattern - 1 << ")."; + edm::LogWarning("L1T") + << "From endcap " << tp_endcap << ", sector " << tp_sector << ", station " << tp_station << ", ring " + << tp_ring << ", cscid " << tp_csc_ID + << ". (Note that this LCT may be reported multiple times. See source code for explanations.)"; + return selected; + } + + if (!(0 < tp_data.quality && tp_data.quality < max_quality)) { + edm::LogWarning("L1T") << "Found error in LCT quality: " << tp_data.quality << " (allowed range: 1-" + << max_quality - 1 << ")."; + edm::LogWarning("L1T") + << "From endcap " << tp_endcap << ", sector " << tp_sector << ", station " << tp_station << ", ring " + << tp_ring << ", cscid " << tp_csc_ID + << ". (Note that this LCT may be reported multiple times. See source code for explanations.)"; + return selected; + } + } // end check for corrupted LCT data // station 1 --> subsector 1 or 2 // station 2,3,4 --> subsector 0 diff --git a/L1Trigger/L1TMuonEndCap/src/SectorProcessorLUT.cc b/L1Trigger/L1TMuonEndCap/src/SectorProcessorLUT.cc index 7491c3c49fa98..88449d68a5997 100644 --- a/L1Trigger/L1TMuonEndCap/src/SectorProcessorLUT.cc +++ b/L1Trigger/L1TMuonEndCap/src/SectorProcessorLUT.cc @@ -138,23 +138,55 @@ void SectorProcessorLUT::read(bool pc_lut_data, int pc_lut_version) { } uint32_t SectorProcessorLUT::get_ph_init(int fw_endcap, int fw_sector, int pc_lut_id) const { - size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; - return ph_init_neighbor_.at(index); + const uint32_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; + uint32_t entry = 0; + + if (index < ph_init_neighbor_.size()) { + entry = ph_init_neighbor_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_endcap: " << fw_endcap + << ", fw_sector: " << fw_sector << ", pc_lut_id: " << pc_lut_id; + } + return entry; } uint32_t SectorProcessorLUT::get_ph_disp(int fw_endcap, int fw_sector, int pc_lut_id) const { - size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; - return ph_disp_neighbor_.at(index); + const uint32_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; + uint32_t entry = 0; + + if (index < ph_disp_neighbor_.size()) { + entry = ph_disp_neighbor_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_endcap: " << fw_endcap + << ", fw_sector: " << fw_sector << ", pc_lut_id: " << pc_lut_id; + } + return entry; } uint32_t SectorProcessorLUT::get_th_init(int fw_endcap, int fw_sector, int pc_lut_id) const { - size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; - return th_init_neighbor_.at(index); + const uint32_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; + uint32_t entry = 0; + + if (index < th_init_neighbor_.size()) { + entry = th_init_neighbor_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_endcap: " << fw_endcap + << ", fw_sector: " << fw_sector << ", pc_lut_id: " << pc_lut_id; + } + return entry; } uint32_t SectorProcessorLUT::get_th_disp(int fw_endcap, int fw_sector, int pc_lut_id) const { - size_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; - return th_disp_neighbor_.at(index); + const uint32_t index = (fw_endcap * 6 + fw_sector) * 61 + pc_lut_id; + uint32_t entry = 0; + + if (index < th_disp_neighbor_.size()) { + entry = th_disp_neighbor_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_endcap: " << fw_endcap + << ", fw_sector: " << fw_sector << ", pc_lut_id: " << pc_lut_id; + } + return entry; } uint32_t SectorProcessorLUT::get_th_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_id) const { @@ -167,8 +199,17 @@ uint32_t SectorProcessorLUT::get_th_lut(int fw_endcap, int fw_sector, int pc_lut if (pc_lut_id2 == 15) pc_lut_id2 -= 3; - size_t index = ((fw_endcap * 6 + fw_sector) * 61 + pc_lut_id2) * 128 + pc_wire_id; - return th_lut_neighbor_.at(index); + const uint32_t index = ((fw_endcap * 6 + fw_sector) * 61 + pc_lut_id2) * 128 + pc_wire_id; + uint32_t entry = 0; + + if (index < th_lut_neighbor_.size()) { + entry = th_lut_neighbor_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_endcap: " << fw_endcap + << ", fw_sector: " << fw_sector << ", pc_lut_id: " << pc_lut_id + << ", pc_wire_id: " << pc_wire_id; + } + return entry; } uint32_t SectorProcessorLUT::get_th_corr_lut(int fw_endcap, int fw_sector, int pc_lut_id, int pc_wire_strip_id) const { @@ -188,25 +229,70 @@ uint32_t SectorProcessorLUT::get_th_corr_lut(int fw_endcap, int fw_sector, int p } else if (16 <= pc_lut_id2 && pc_lut_id2 < 19) { pc_lut_id2 -= 12; } else { - throw cms::Exception("L1TMuonEndCap") << "get_th_corr_lut(): out of range pc_lut_id: " << pc_lut_id; + edm::LogError("L1T") << "get_th_corr_lut(): out of range pc_lut_id: " << pc_lut_id; } - size_t index = ((fw_endcap * 6 + fw_sector) * 7 + pc_lut_id2) * 128 + pc_wire_strip_id; - return th_corr_lut_neighbor_.at(index); + const uint32_t index = ((fw_endcap * 6 + fw_sector) * 7 + pc_lut_id2) * 128 + pc_wire_strip_id; + uint32_t entry = 0; + + if (index < th_corr_lut_neighbor_.size()) { + entry = th_corr_lut_neighbor_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_endcap: " << fw_endcap + << ", fw_sector: " << fw_sector << ", pc_lut_id: " << pc_lut_id + << ", pc_wire_strip_id: " << pc_wire_strip_id; + } + return entry; } -uint32_t SectorProcessorLUT::get_ph_patt_corr(int pattern) const { return ph_patt_corr_.at(pattern); } +uint32_t SectorProcessorLUT::get_ph_patt_corr(int pattern) const { + const uint32_t index = pattern; + uint32_t entry = 0; -uint32_t SectorProcessorLUT::get_ph_patt_corr_sign(int pattern) const { return ph_patt_corr_sign_.at(pattern); } + if (index < ph_patt_corr_.size()) { + entry = ph_patt_corr_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. pattern: " << pattern; + } + return entry; +} + +uint32_t SectorProcessorLUT::get_ph_patt_corr_sign(int pattern) const { + const uint32_t index = pattern; + uint32_t entry = 0; + + if (index < ph_patt_corr_sign_.size()) { + entry = ph_patt_corr_sign_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. pattern: " << pattern; + } + return entry; +} uint32_t SectorProcessorLUT::get_ph_zone_offset(int pc_station, int pc_chamber) const { - size_t index = pc_station * 9 + pc_chamber; - return ph_zone_offset_.at(index); + const uint32_t index = pc_station * 9 + pc_chamber; + uint32_t entry = 0; + + if (index < ph_zone_offset_.size()) { + entry = ph_zone_offset_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. pc_station: " << pc_station + << ", pc_chamber: " << pc_chamber; + } + return entry; } uint32_t SectorProcessorLUT::get_ph_init_hard(int fw_station, int fw_cscid) const { - size_t index = fw_station * 16 + fw_cscid; - return ph_init_hard_.at(index); + const uint32_t index = fw_station * 16 + fw_cscid; + uint32_t entry = 0; + + if (index < ph_init_hard_.size()) { + entry = ph_init_hard_.at(index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. fw_station: " << fw_station + << ", fw_cscid: " << fw_cscid; + } + return entry; } uint32_t SectorProcessorLUT::get_cppf_lut_id( @@ -227,9 +313,20 @@ uint32_t SectorProcessorLUT::get_cppf_ph_lut(int rpc_region, int rpc_roll, int halfstrip, bool is_neighbor) const { - size_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll); - size_t ph_index = (th_index * 64) + (halfstrip - 1); - uint32_t ph = cppf_ph_lut_.at(ph_index); + const uint32_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll); + const uint32_t ph_index = (th_index * 64) + (halfstrip - 1); + uint32_t ph = 0; + + if (ph_index < cppf_ph_lut_.size()) { + ph = cppf_ph_lut_.at(ph_index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. rpc_region: " << rpc_region + << ", rpc_sector: " << rpc_sector << ", rpc_station: " << rpc_station + << ", rpc_ring: " << rpc_ring << ", rpc_subsector: " << rpc_subsector + << ", rpc_roll: " << rpc_roll << ", halfstrip: " << halfstrip + << ", is_neighbor: " << is_neighbor; + } + if (!is_neighbor && rpc_subsector == 2) ph += 900; return ph; @@ -237,8 +334,17 @@ uint32_t SectorProcessorLUT::get_cppf_ph_lut(int rpc_region, uint32_t SectorProcessorLUT::get_cppf_th_lut( int rpc_region, int rpc_sector, int rpc_station, int rpc_ring, int rpc_subsector, int rpc_roll) const { - size_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll); - uint32_t th = cppf_th_lut_.at(th_index); + const uint32_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll); + uint32_t th = 0; + + if (th_index < cppf_th_lut_.size()) { + th = cppf_th_lut_.at(th_index); + } else { + edm::LogError("L1T") << "Could not retrieve entry from LUT. rpc_region: " << rpc_region + << ", rpc_sector: " << rpc_sector << ", rpc_station: " << rpc_station + << ", rpc_ring: " << rpc_ring << ", rpc_subsector: " << rpc_subsector + << ", rpc_roll: " << rpc_roll; + } return th; } @@ -348,8 +454,8 @@ void SectorProcessorLUT::read_cppf_file(const std::string& filename, uint32_t ph = buf5; uint32_t th = buf6; - size_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll); - size_t ph_index = (th_index * 64) + (halfstrip - 1); + const uint32_t th_index = get_cppf_lut_id(rpc_region, rpc_sector, rpc_station, rpc_ring, rpc_subsector, rpc_roll); + const uint32_t ph_index = (th_index * 64) + (halfstrip - 1); // std::cout << id << " " << rpc_region << " " << rpc_sector << " " << rpc_station << " " << rpc_ring << " " // << rpc_subsector << " " << rpc_roll << " " << halfstrip << " " << th_index << " " << ph_index << std::endl; diff --git a/L1Trigger/L1TMuonEndCap/src/TrackTools.cc b/L1Trigger/L1TMuonEndCap/src/TrackTools.cc index 4f315c98bc801..f60a34bd43657 100644 --- a/L1Trigger/L1TMuonEndCap/src/TrackTools.cc +++ b/L1Trigger/L1TMuonEndCap/src/TrackTools.cc @@ -138,9 +138,9 @@ namespace emtf { // | ME2/2, ME3/2, ME4/2 | 160 | 64 | // +----------------------------+------------+------------+ - void get_csc_max_strip_and_wire(int station, int ring, int& max_strip, int& max_wire) { - max_strip = 0; // halfstrip - max_wire = 0; // wiregroup + std::pair get_csc_max_strip_and_wire(int station, int ring) { + int max_strip = 0; // halfstrip + int max_wire = 0; // wiregroup if (station == 1 && ring == 4) { // ME1/1a max_strip = 96; max_wire = 48; @@ -163,7 +163,13 @@ namespace emtf { max_strip = 160; max_wire = 64; } - return; + return std::make_pair(max_strip, max_wire); + } + + std::pair get_csc_max_pattern_and_quality(int station, int ring) { + int max_pattern = 11; + int max_quality = 16; + return std::make_pair(max_pattern, max_quality); } } // namespace emtf diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h index e5978d6e2853b..82168330c0e31 100644 --- a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h @@ -105,11 +105,13 @@ namespace L1Analysis { nMuons = 0; muonEt.clear(); + muonEtUnconstrained.clear(); muonEta.clear(); muonPhi.clear(); muonEtaAtVtx.clear(); muonPhiAtVtx.clear(); muonIEt.clear(); + muonIEtUnconstrained.clear(); muonIEta.clear(); muonIPhi.clear(); muonIEtaAtVtx.clear(); @@ -119,6 +121,7 @@ namespace L1Analysis { muonChg.clear(); muonIso.clear(); muonQual.clear(); + muonDxy.clear(); muonTfMuonIdx.clear(); muonBx.clear(); @@ -188,11 +191,13 @@ namespace L1Analysis { unsigned short int nMuons; std::vector muonEt; + std::vector muonEtUnconstrained; std::vector muonEta; std::vector muonPhi; std::vector muonEtaAtVtx; std::vector muonPhiAtVtx; std::vector muonIEt; + std::vector muonIEtUnconstrained; std::vector muonIEta; std::vector muonIPhi; std::vector muonIEtaAtVtx; @@ -202,6 +207,7 @@ namespace L1Analysis { std::vector muonChg; std::vector muonIso; std::vector muonQual; + std::vector muonDxy; std::vector muonTfMuonIdx; std::vector muonBx; diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonDataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonDataFormat.h index a17065400a8aa..eb1105d2ff8b3 100644 --- a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonDataFormat.h +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonDataFormat.h @@ -1,7 +1,9 @@ #ifndef __L1Analysis_L1AnalysisL1UpgradeTfMuonDataFormat_H__ #define __L1Analysis_L1AnalysisL1UpgradeTfMuonDataFormat_H__ +#include "L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h" #include +#include namespace L1Analysis { struct L1AnalysisL1UpgradeTfMuonDataFormat { @@ -24,6 +26,8 @@ namespace L1Analysis { tfMuonBx.clear(); tfMuonWh.clear(); tfMuonTrAdd.clear(); + tfMuonDecodedTrAdd.clear(); + tfMuonHwTrAdd.clear(); } unsigned short int nTfMuons; @@ -41,6 +45,8 @@ namespace L1Analysis { std::vector tfMuonBx; std::vector tfMuonWh; std::vector tfMuonTrAdd; + std::vector> tfMuonDecodedTrAdd; + std::vector tfMuonHwTrAdd; }; } // namespace L1Analysis #endif diff --git a/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc b/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc index 6a8c3d1540601..e037ce0e76339 100644 --- a/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc +++ b/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc @@ -96,11 +96,13 @@ void L1Analysis::L1AnalysisL1Upgrade::SetMuon(const edm::Handlept() > 0) { l1upgrade_.muonEt.push_back(it->et()); + l1upgrade_.muonEtUnconstrained.push_back(it->ptUnconstrained()); l1upgrade_.muonEta.push_back(it->eta()); l1upgrade_.muonPhi.push_back(it->phi()); l1upgrade_.muonEtaAtVtx.push_back(it->etaAtVtx()); l1upgrade_.muonPhiAtVtx.push_back(it->phiAtVtx()); l1upgrade_.muonIEt.push_back(it->hwPt()); + l1upgrade_.muonIEtUnconstrained.push_back(it->hwPtUnconstrained()); l1upgrade_.muonIEta.push_back(it->hwEta()); l1upgrade_.muonIPhi.push_back(it->hwPhi()); l1upgrade_.muonIEtaAtVtx.push_back(it->hwEtaAtVtx()); @@ -110,6 +112,7 @@ void L1Analysis::L1AnalysisL1Upgrade::SetMuon(const edm::Handlecharge()); l1upgrade_.muonIso.push_back(it->hwIso()); l1upgrade_.muonQual.push_back(it->hwQual()); + l1upgrade_.muonDxy.push_back(it->hwDXY()); l1upgrade_.muonTfMuonIdx.push_back(it->tfMuonIndex()); l1upgrade_.muonBx.push_back(ibx); l1upgrade_.nMuons++; diff --git a/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuon.cc b/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuon.cc index db7d9e6805143..622b4ad3e42f0 100644 --- a/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuon.cc +++ b/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuon.cc @@ -24,15 +24,44 @@ void L1Analysis::L1AnalysisL1UpgradeTfMuon::SetTfMuon(const l1t::RegionalMuonCan l1upgradetfmuon_.tfMuonTrackFinderType.push_back(it->trackFinderType()); l1upgradetfmuon_.tfMuonHwHF.push_back(it->hwHF()); l1upgradetfmuon_.tfMuonBx.push_back(ibx); - std::map trAdd; - trAdd = it->trackAddress(); - int wheel = pow(-1, trAdd[0]) * trAdd[1]; - l1upgradetfmuon_.tfMuonWh.push_back(wheel); - l1upgradetfmuon_.tfMuonTrAdd.push_back(trAdd[2]); - l1upgradetfmuon_.tfMuonTrAdd.push_back(trAdd[3]); - l1upgradetfmuon_.tfMuonTrAdd.push_back(trAdd[4]); - l1upgradetfmuon_.tfMuonTrAdd.push_back(trAdd[5]); + std::map decoded_track_address; + if (it->trackFinderType() == l1t::tftype::bmtf) { + int detSide = it->trackSubAddress(l1t::RegionalMuonCand::kWheelSide); + int wheelNum = it->trackSubAddress(l1t::RegionalMuonCand::kWheelNum); + int stat1 = it->trackSubAddress(l1t::RegionalMuonCand::kStat1); + int stat2 = it->trackSubAddress(l1t::RegionalMuonCand::kStat2); + int stat3 = it->trackSubAddress(l1t::RegionalMuonCand::kStat3); + int stat4 = it->trackSubAddress(l1t::RegionalMuonCand::kStat4); + int wheel = pow(-1, detSide) * wheelNum; + l1upgradetfmuon_.tfMuonWh.push_back(wheel); + l1upgradetfmuon_.tfMuonTrAdd.push_back(stat1); + l1upgradetfmuon_.tfMuonTrAdd.push_back(stat2); + l1upgradetfmuon_.tfMuonTrAdd.push_back(stat3); + l1upgradetfmuon_.tfMuonTrAdd.push_back(stat4); + decoded_track_address["wheel"] = wheel; + decoded_track_address["station1"] = stat1; + decoded_track_address["station2"] = stat2; + decoded_track_address["station3"] = stat3; + decoded_track_address["station4"] = stat4; + } else if (it->trackFinderType() == l1t::omtf_neg || it->trackFinderType() == l1t::omtf_pos) { + decoded_track_address["kLayers"] = it->trackSubAddress(l1t::RegionalMuonCand::kLayers); + decoded_track_address["kWeight"] = it->trackSubAddress(l1t::RegionalMuonCand::kWeight); + } else if (it->trackFinderType() == l1t::emtf_neg || it->trackFinderType() == l1t::emtf_pos) { + decoded_track_address["kME1Seg"] = it->trackSubAddress(l1t::RegionalMuonCand::kME1Seg); + decoded_track_address["kME1Ch"] = it->trackSubAddress(l1t::RegionalMuonCand::kME1Ch); + decoded_track_address["kME2Seg"] = it->trackSubAddress(l1t::RegionalMuonCand::kME2Seg); + decoded_track_address["kME2Ch"] = it->trackSubAddress(l1t::RegionalMuonCand::kME2Ch); + decoded_track_address["kME3Seg"] = it->trackSubAddress(l1t::RegionalMuonCand::kME3Seg); + decoded_track_address["kME3Ch"] = it->trackSubAddress(l1t::RegionalMuonCand::kME3Ch); + decoded_track_address["kME4Seg"] = it->trackSubAddress(l1t::RegionalMuonCand::kME4Seg); + decoded_track_address["kME4Ch"] = it->trackSubAddress(l1t::RegionalMuonCand::kME4Ch); + decoded_track_address["kTrkNum"] = it->trackSubAddress(l1t::RegionalMuonCand::kTrkNum); + decoded_track_address["kBX"] = it->trackSubAddress(l1t::RegionalMuonCand::kBX); + } + l1upgradetfmuon_.tfMuonDecodedTrAdd.push_back(decoded_track_address); + l1upgradetfmuon_.tfMuonHwTrAdd.push_back(l1t::RegionalMuonRawDigiTranslator::generateRawTrkAddress( + *it, true)); // TODO: We're assuming that we're dealing with Kalman muons here. l1upgradetfmuon_.nTfMuons++; } } diff --git a/L1Trigger/L1TTrackMatch/BuildFile.xml b/L1Trigger/L1TTrackMatch/BuildFile.xml new file mode 100644 index 0000000000000..596dc6c8f3683 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/BuildFile.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkElectronEtComparator.h b/L1Trigger/L1TTrackMatch/interface/L1TkElectronEtComparator.h new file mode 100644 index 0000000000000..d0228f7704fa9 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkElectronEtComparator.h @@ -0,0 +1,23 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TkElectronEtComparator_HH +#define L1Trigger_L1TTrackMatch_L1TkElectronEtComparator_HH +#include "DataFormats/L1Trigger/interface/EGamma.h" + +namespace L1TkElectron { + class EtComparator { + public: + bool operator()(const l1t::EGamma& a, const l1t::EGamma& b) const { + double et_a = 0.0; + double et_b = 0.0; + double cosh_a_eta = cosh(a.eta()); + double cosh_b_eta = cosh(b.eta()); + + if (cosh_a_eta > 0.0) + et_a = a.energy() / cosh_a_eta; + if (cosh_b_eta > 0.0) + et_b = b.energy() / cosh_b_eta; + + return et_a > et_b; + } + }; +} // namespace L1TkElectron +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h b/L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h new file mode 100644 index 0000000000000..1fd86fc14656b --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h @@ -0,0 +1,30 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TkElectronTrackMatchAlgo_HH +#define L1Trigger_L1TTrackMatch_L1TkElectronTrackMatchAlgo_HH + +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +namespace L1TkElectronTrackMatchAlgo { + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollection; + void doMatch(BXVector::const_iterator egIter, + const edm::Ptr& pTrk, + double& dph, + double& dr, + double& deta); + void doMatchClusterET(BXVector::const_iterator egIter, + const edm::Ptr& pTrk, + double& dph, + double& dr, + double& deta); + void doMatch(const GlobalPoint& epos, const edm::Ptr& pTrk, double& dph, double& dr, double& deta); + + double deltaR(const GlobalPoint& epos, const edm::Ptr& pTrk); + double deltaPhi(const GlobalPoint& epos, const edm::Ptr& pTrk); + double deltaPhiClusterET(BXVector::const_iterator egIter, const edm::Ptr& pTrk); + double deltaEta(const GlobalPoint& epos, const edm::Ptr& pTrk); + GlobalPoint calorimeterPosition(double phi, double eta, double e); + +} // namespace L1TkElectronTrackMatchAlgo +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h b/L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h new file mode 100644 index 0000000000000..71809f52d6c13 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h @@ -0,0 +1,132 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TKMUCORRDYNAMICWINDOWS_H +#define L1Trigger_L1TTrackMatch_L1TKMUCORRDYNAMICWINDOWS_H + +#include "TFile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1TMuon/interface/EMTFTrack.h" +#include "DataFormats/Math/interface/angle_units.h" + +#include "L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h" +#include "L1Trigger/L1TMuonEndCap/interface/Common.h" + +class L1TkMuCorrDynamicWindows { +public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollectionType; + + L1TkMuCorrDynamicWindows(const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi); + L1TkMuCorrDynamicWindows( + const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi, TFile* fIn_theta_S1, TFile* fIn_phi_S1); + ~L1TkMuCorrDynamicWindows() {} + std::vector find_match( + const EMTFTrackCollection& l1mus, + const L1TTTrackCollectionType& l1trks); // gives a vector with the idxs of muons for each L1TTT + std::vector find_match_stub( + const EMTFHitCollection& l1mus, + const L1TTTrackCollectionType& l1trks, + const int& station, + bool requireBX0 = true); // gives a vector with the idxs of muon stubs from station "station" for each L1TTT + + // ------------------------------ + static std::vector prepare_corr_bounds(const string& fname, const string& hname); + + void set_safety_factor(float sf_l, float sf_h) { + safety_factor_l_ = sf_l; + safety_factor_h_ = sf_h; + } + void set_sf_initialrelax(float sf_l, float sf_h) { + initial_sf_l_ = sf_l; + initial_sf_h_ = sf_h; + } + void set_relaxation_pattern(float pt_start, float pt_end) { + pt_start_ = pt_start; + pt_end_ = pt_end; + } + void set_safety_factor(float sf) { set_safety_factor(sf, sf); } + void set_sf_initialrelax(float sf) { set_sf_initialrelax(sf, sf); } + void set_do_relax_factor(bool val) { do_relax_factor_ = val; } + + void set_do_trk_qual_presel(bool val) { track_qual_presel_ = val; } + + // setters for trk + void set_n_trk_par(int val) { nTrkPars_ = val; } + void set_min_trk_p(float val) { min_trk_p_ = val; } + void set_max_trk_aeta(float val) { max_trk_aeta_ = val; } + void set_max_trk_chi2(float val) { max_trk_chi2_ = val; } + void set_min_trk_nstubs(int val) { min_trk_nstubs_ = val; } + + // getters for trk + const int n_trk_par() { return nTrkPars_; } + const float min_trk_p() { return min_trk_p_; } + const float max_trk_aeta() { return max_trk_aeta_; } + const float max_trk_chi2() { return max_trk_chi2_; } + const int min_trk_nstubs() { return min_trk_nstubs_; } + +private: + int findBin(double val); + + // resolves ambiguities to give max 1 tkmu per EMTF + // if a pointer to narbitrated is passed, this vector is filled with the number of tracks arbitrated that were matched to the same EMTF + std::vector make_unique_coll(const unsigned int& l1musSize, + const L1TTTrackCollectionType& l1trks, + const std::vector& matches); + + // converters + double eta_to_theta(double x) { + // give theta in rad + return (2. * atan(exp(-1. * x))); + } + + double to_mpio2_pio2(double x) { + // put the angle in radians between -pi/2 and pi/2 + while (x >= 0.5 * M_PI) + x -= M_PI; + while (x < -0.5 * M_PI) + x += M_PI; + return x; + } + + double sf_progressive(double x, double xstart, double xstop, double ystart, double ystop) { + if (x < xstart) + return ystart; + if (x >= xstart && x < xstop) + return ystart + (x - xstart) * (ystop - ystart) / (xstop - xstart); + return ystop; + } + + int nbins_; // counts the number of MatchWindow = bounds_.size() - 1 + std::vector bounds_; // counts the boundaries of the MatchWindow (in eta/theta) + std::vector wdws_theta_; + std::vector wdws_phi_; + std::vector wdws_theta_S1_; + std::vector wdws_phi_S1_; + float safety_factor_l_; // increase the lower theta/phi threshold by this fractions + float safety_factor_h_; // increase the upper theta/phi threshold by this fractions + float initial_sf_l_; // the start of the relaxation + float initial_sf_h_; // the start of the relaxation + float pt_start_; // the relaxation of the threshold + float pt_end_; // the relaxation of the threshold + bool do_relax_factor_; // true if applying the linear relaxation + bool track_qual_presel_; // if true, apply the track preselection + + // trk configurable params + int nTrkPars_; // 4 + float min_trk_p_; // 3.5 + float max_trk_aeta_; // 2.5 + float max_trk_chi2_; // 100 + int min_trk_nstubs_; // 4 +}; + +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h b/L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h new file mode 100644 index 0000000000000..0a621d1b036d1 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h @@ -0,0 +1,125 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TKMUMANTRA_H +#define L1Trigger_L1TTrackMatch_L1TKMUMANTRA_H + +/* +** class : GenericDataFormat +** author : L.Cadamuro (UF) +** date : 4/11/2019 +** brief : very generic structs to be used as inputs to the correlator +** : to make sure that Mantra can handle muons and tracks from all the detectors +*/ + +namespace L1TkMuMantraDF { + + struct track_df { + double pt; // GeV + double eta; // rad, -inf / +inf + double theta; // rad, 0 -> +90-90 + double phi; // rad, -pi / + pi + int nstubs; // + double chi2; // + int charge; // -1. +1 + }; + + struct muon_df { + double pt; // GeV + double eta; // rad, -inf / +inf + double theta; // rad, 0 -> +90-90 + double phi; // rad, -pi / + pi + int charge; // -1. +1 + }; +} // namespace L1TkMuMantraDF + +/* +** class : L1TkMuMantra +** author : L.Cadamuro (UF) +** date : 4/11/2019 +** brief : correlates muons and tracks using pre-encoded windows +*/ + +#include +#include +#include +#include +#include "L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h" +#include + +#include "TFile.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "DataFormats/Math/interface/angle_units.h" + +class L1TkMuMantra { +public: + L1TkMuMantra(const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi, std::string name); + ~L1TkMuMantra(){}; + + // returns a vector with the same size of muons, each with an index to the matched L1 track, or -1 if no match is found + std::vector find_match(const std::vector& tracks, + const std::vector& muons); + + void test(double eta, double pt); + + void relax_windows(double& low, double cent, double& high); // will modify low and high + + void set_safety_factor(float sf_l, float sf_h) { + safety_factor_l_ = sf_l; + safety_factor_h_ = sf_h; + if (verbosity_ > 0) + LogTrace("L1TkMuMantra") << name_ << " safety factor LOW is " << safety_factor_l_ << std::endl; + if (verbosity_ > 0) + LogTrace("L1TkMuMantra") << name_ << " safety factor HIGH is " << safety_factor_h_ << std::endl; + } + + int sign(double x) { + if (x == 0) + return 1; + return (0 < x) - (x < 0); + } + + void setArbitrationType(std::string type); // MaxPt, MinDeltaPt + + // static functions, meant to be used from outside to interface with MAnTra + static std::vector prepare_corr_bounds(std::string fname, std::string hname); + + // converters + static double eta_to_theta(double x) { + // give theta in rad + return (2. * atan(exp(-1. * x))); + } + + static double to_mpio2_pio2(double x) { + // put the angle in radians between -pi/2 and pi/2 + while (x >= 0.5 * M_PI) + x -= M_PI; + while (x < -0.5 * M_PI) + x += M_PI; + return x; + } + +private: + int findBin(double val); + + std::string name_; + + int nbins_; // counts the number of MuMatchWindow = bounds_.size() - 1 + std::vector bounds_; // counts the boundaries of the MuMatchWindow (in eta/theta) + std::vector wdws_theta_; + std::vector wdws_phi_; + + int min_nstubs = 4; // >= min_nstubs + double max_chi2 = 100; // < max_chi2 + + float safety_factor_l_; // increase the lower theta/phi threshold by this fractions w.r.t. the center + float safety_factor_h_; // increase the upper theta/phi threshold by this fractions w.r.t. the center + + enum sortParType { + kMaxPt, // pick the highest pt track matched + kMinDeltaPt // pick the track with the smallest pt difference w.r.t the muon + }; + + sortParType sort_type_; + + int verbosity_ = 0; +}; + +#endif // L1TKMUMANTRA_H diff --git a/L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h b/L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h new file mode 100644 index 0000000000000..aa8a6da239bf7 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h @@ -0,0 +1,44 @@ +#ifndef L1Trigger_L1TTrackMatch_MUMATCHWINDOW_H +#define L1Trigger_L1TTrackMatch_MUMATCHWINDOW_H + +#include "TF1.h" +#include +#include +#include + +/* +** class : MuMatchWindow +** author : L.Cadamuro (UF) +** date : 25/12/2018 +** brief : encodes the lower, central, and upper bounds to match a track to a muon +** to be flexible, limits are given as strings to create a TF1 function +*/ + +class MuMatchWindow { +public: + MuMatchWindow(); + MuMatchWindow(std::string name); + ~MuMatchWindow(); + void SetName(std::string name) { name_ = name; } + + void SetLower(std::string formula); + void SetCentral(std::string formula); + void SetUpper(std::string formula); + + void SetLower(TF1* formula); + void SetCentral(TF1* formula); + void SetUpper(TF1* formula); + + // bool matches (double pt); + const double bound_low(double pt) { return fLow_->Eval(pt); } + const double bound_cent(double pt) { return fCent_->Eval(pt); } + const double bound_high(double pt) { return fHigh_->Eval(pt); } + +private: + std::string name_; + std::shared_ptr fLow_; + std::shared_ptr fCent_; + std::shared_ptr fHigh_; +}; + +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h b/L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h new file mode 100644 index 0000000000000..6a716c345decc --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h @@ -0,0 +1,11 @@ +#ifndef L1Trigger_L1TTrackMatch_pTFrom2Stubs_HH +#define L1Trigger_L1TTrackMatch_pTFrom2Stubs_HH + +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +namespace pTFrom2Stubs { + float rInvFrom2(std::vector >::const_iterator trk, const TrackerGeometry* tkGeometry); + float pTFrom2(std::vector >::const_iterator trk, const TrackerGeometry* tkGeometry); +} // namespace pTFrom2Stubs +#endif diff --git a/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml b/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml new file mode 100644 index 0000000000000..d3e7a253469c6 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkElectronTrackProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkElectronTrackProducer.cc new file mode 100644 index 0000000000000..345238919a42c --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TkElectronTrackProducer.cc @@ -0,0 +1,350 @@ +// -*- C++ -*- +// +/**\class L1TkElectronTrackMatchAlgo + + Description: Producer of a TkElectron, for the algorithm matching a L1Track to the L1EG object + + Implementation: + [Notes on implementation] +*/ +// +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" + +#include "DataFormats/Common/interface/Handle.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" + +#include "DataFormats/Math/interface/LorentzVector.h" + +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" + +// Matching Algorithm +#include "L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkElectronEtComparator.h" +#include "L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h" + +#include "DataFormats/Math/interface/deltaPhi.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" + +#include + +static constexpr float EB_MaxEta = 0.9; + +using namespace l1t; + +// +// class declaration +// + +class L1TkElectronTrackProducer : public edm::stream::EDProducer<> { +public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollectionType; + + explicit L1TkElectronTrackProducer(const edm::ParameterSet&); + ~L1TkElectronTrackProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + //void beginJob() override; + void produce(edm::Event&, const edm::EventSetup&) override; + //void endJob() override; + + float isolation(const edm::Handle& trkHandle, int match_index); + double getPtScaledCut(double pt, std::vector& parameters); + bool selectMatchedTrack(double& d_r, double& d_phi, double& d_eta, double& tk_pt, float& eg_eta); + + // ----------member data --------------------------- + std::string label; + + float etMin_; // min ET in GeV of L1EG objects + + float dRMin_; + float dRMax_; + float pTMinTra_; + float maxChi2IsoTracks_; + unsigned int minNStubsIsoTracks_; + + bool primaryVtxConstrain_; // use the primary vertex (default = false) + float deltaZ_; // | z_track - z_ref_track | < deltaZ_ in cm. + // Used only when primaryVtxConstrain_ = True. + float isoCut_; + bool relativeIsolation_; + + float trkQualityChi2_; + bool useTwoStubsPT_; + bool useClusterET_; // use cluster et to extrapolate tracks + float trkQualityPtMin_; + std::vector dPhiCutoff_; + std::vector dRCutoff_; + std::vector dEtaCutoff_; + std::string matchType_; + + const edm::EDGetTokenT egToken_; + const edm::EDGetTokenT > > trackToken_; + const edm::ESGetToken geomToken_; +}; + +// +// constructors and destructor +// +L1TkElectronTrackProducer::L1TkElectronTrackProducer(const edm::ParameterSet& iConfig) + : egToken_(consumes(iConfig.getParameter("L1EGammaInputTag"))), + trackToken_(consumes > >( + iConfig.getParameter("L1TrackInputTag"))), + geomToken_(esConsumes()) { + // label of the collection produced + // e.g. EG or IsoEG if all objects are kept + // EGIsoTrk or IsoEGIsoTrk if only the EG or IsoEG + // objects that pass a cut RelIso < isoCut_ are written + // in the new collection. + label = iConfig.getParameter("label"); + + etMin_ = (float)iConfig.getParameter("ETmin"); + + // parameters for the calculation of the isolation : + pTMinTra_ = (float)iConfig.getParameter("PTMINTRA"); + dRMin_ = (float)iConfig.getParameter("DRmin"); + dRMax_ = (float)iConfig.getParameter("DRmax"); + deltaZ_ = (float)iConfig.getParameter("DeltaZ"); + maxChi2IsoTracks_ = iConfig.getParameter("maxChi2IsoTracks"); + minNStubsIsoTracks_ = iConfig.getParameter("minNStubsIsoTracks"); + // cut applied on the isolation (if this number is <= 0, no cut is applied) + isoCut_ = (float)iConfig.getParameter("IsoCut"); + relativeIsolation_ = iConfig.getParameter("RelativeIsolation"); + + // parameters to select tracks to match with L1EG + trkQualityChi2_ = (float)iConfig.getParameter("TrackChi2"); + trkQualityPtMin_ = (float)iConfig.getParameter("TrackMinPt"); + useTwoStubsPT_ = iConfig.getParameter("useTwoStubsPT"); + useClusterET_ = iConfig.getParameter("useClusterET"); + dPhiCutoff_ = iConfig.getParameter >("TrackEGammaDeltaPhi"); + dRCutoff_ = iConfig.getParameter >("TrackEGammaDeltaR"); + dEtaCutoff_ = iConfig.getParameter >("TrackEGammaDeltaEta"); + matchType_ = iConfig.getParameter("TrackEGammaMatchType"); + + produces(label); +} + +L1TkElectronTrackProducer::~L1TkElectronTrackProducer() {} + +// ------------ method called to produce the data ------------ +void L1TkElectronTrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + std::unique_ptr result(new TkElectronCollection); + + // geometry needed to call pTFrom2Stubs + edm::ESHandle geomHandle = iSetup.getHandle(geomToken_); + const TrackerGeometry* tGeom = geomHandle.product(); + + // the L1EGamma objects + edm::Handle eGammaHandle; + iEvent.getByToken(egToken_, eGammaHandle); + EGammaBxCollection eGammaCollection = (*eGammaHandle.product()); + EGammaBxCollection::const_iterator egIter; + + // the L1Tracks + edm::Handle L1TTTrackHandle; + iEvent.getByToken(trackToken_, L1TTTrackHandle); + L1TTTrackCollectionType::const_iterator trackIter; + + if (!eGammaHandle.isValid()) { + throw cms::Exception("L1TkElectronTrackProducer") + << "\nWarning: L1EmCollection not found in the event. Exit" << std::endl; + return; + } + if (!L1TTTrackHandle.isValid()) { + throw cms::Exception("TkEmProducer") << "\nWarning: L1TTTrackCollectionType not found in the event. Exit." + << std::endl; + return; + } + + int ieg = 0; + for (egIter = eGammaCollection.begin(0); egIter != eGammaCollection.end(0); ++egIter) { // considering BX = only + edm::Ref EGammaRef(eGammaHandle, ieg); + ieg++; + + float e_ele = egIter->energy(); + float eta_ele = egIter->eta(); + float et_ele = 0; + float cosh_eta_ele = cosh(eta_ele); + if (cosh_eta_ele > 0.0) + et_ele = e_ele / cosh_eta_ele; + else + et_ele = -1.0; + if (etMin_ > 0.0 && et_ele <= etMin_) + continue; + // match the L1EG object with a L1Track + float drmin = 999; + int itr = 0; + int itrack = -1; + for (trackIter = L1TTTrackHandle->begin(); trackIter != L1TTTrackHandle->end(); ++trackIter) { + edm::Ptr L1TrackPtr(L1TTTrackHandle, itr); + double trkPt_fit = trackIter->momentum().perp(); + double trkPt_stubs = pTFrom2Stubs::pTFrom2(trackIter, tGeom); + double trkPt = trkPt_fit; + if (useTwoStubsPT_) + trkPt = trkPt_stubs; + + if (trkPt > trkQualityPtMin_ && trackIter->chi2() < trkQualityChi2_) { + double dPhi = 99.; + double dR = 99.; + double dEta = 99.; + if (useClusterET_) + L1TkElectronTrackMatchAlgo::doMatchClusterET(egIter, L1TrackPtr, dPhi, dR, dEta); + else + L1TkElectronTrackMatchAlgo::doMatch(egIter, L1TrackPtr, dPhi, dR, dEta); + if (dR < drmin && selectMatchedTrack(dR, dPhi, dEta, trkPt, eta_ele)) { + drmin = dR; + itrack = itr; + } + } + itr++; + } + if (itrack >= 0) { + edm::Ptr matchedL1TrackPtr(L1TTTrackHandle, itrack); + + const math::XYZTLorentzVector P4 = egIter->p4(); + float trkisol = isolation(L1TTTrackHandle, itrack); + if (relativeIsolation_ && et_ele > 0.0) { // relative isolation + trkisol = trkisol / et_ele; + } + + TkElectron trkEm(P4, EGammaRef, matchedL1TrackPtr, trkisol); + + trkEm.setTrackCurvature(matchedL1TrackPtr->rInv()); // should this have npars? 4? 5? + + //std::cout<rInv()<<" "<rInv(4)<<" "<rInv()<push_back(trkEm); + } else { + // the object is written to the collection only + // if it passes the isolation cut + if (trkisol <= isoCut_) + result->push_back(trkEm); + } + } + + } // end loop over EGamma objects + + iEvent.put(std::move(result), label); +} + +// ------------ method called once each job just before starting event loop ------------ +//void L1TkElectronTrackProducer::beginJob() {} + +// ------------ method called once each job just after ending the event loop ------------ +//void L1TkElectronTrackProducer::endJob() {} + +// ------------ method called when starting to processes a run ------------ +/* +void +L1TkElectronTrackProducer::beginRun(edm::Run& iRun, edm::EventSetup const& iSetup) +{ +} +*/ + +// ------------ method called when ending the processing of a run ------------ +/* +void +L1TkElectronTrackProducer::endRun(edm::Run&, edm::EventSetup const&) +{ +} +*/ + +// ------------ method called when starting to processes a luminosity block ------------ +/* +void +L1TkElectronTrackProducer::beginLuminosityBlock(edm::LuminosityBlock&, edm::EventSetup const&) +{ +} +*/ + +// ------------ method called when ending the processing of a luminosity block ------------ +/* +void +L1TkElectronTrackProducer::endLuminosityBlock(edm::LuminosityBlock&, edm::EventSetup const&) +{ +} +*/ + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TkElectronTrackProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} +// method to calculate isolation +float L1TkElectronTrackProducer::isolation(const edm::Handle& trkHandle, int match_index) { + edm::Ptr matchedTrkPtr(trkHandle, match_index); + L1TTTrackCollectionType::const_iterator trackIter; + + float sumPt = 0.0; + int itr = 0; + + float dRMin2 = dRMin_ * dRMin_; + float dRMax2 = dRMax_ * dRMax_; + + for (trackIter = trkHandle->begin(); trackIter != trkHandle->end(); ++trackIter) { + if (itr++ != match_index) { + if (trackIter->chi2() > maxChi2IsoTracks_ || trackIter->momentum().perp() <= pTMinTra_ || + trackIter->getStubRefs().size() < minNStubsIsoTracks_) { + continue; + } + + float dZ = std::abs(trackIter->POCA().z() - matchedTrkPtr->POCA().z()); + + float phi1 = trackIter->momentum().phi(); + float phi2 = matchedTrkPtr->momentum().phi(); + float dPhi = reco::deltaPhi(phi1, phi2); + float dEta = (trackIter->momentum().eta() - matchedTrkPtr->momentum().eta()); + float dR2 = (dPhi * dPhi + dEta * dEta); + + if (dR2 > dRMin2 && dR2 < dRMax2 && dZ < deltaZ_ && trackIter->momentum().perp() > pTMinTra_) { + sumPt += trackIter->momentum().perp(); + } + } + } + + return sumPt; +} +double L1TkElectronTrackProducer::getPtScaledCut(double pt, std::vector& parameters) { + return (parameters[0] + parameters[1] * exp(parameters[2] * pt)); +} +bool L1TkElectronTrackProducer::selectMatchedTrack( + double& d_r, double& d_phi, double& d_eta, double& tk_pt, float& eg_eta) { + if (matchType_ == "PtDependentCut") { + if (std::abs(d_phi) < getPtScaledCut(tk_pt, dPhiCutoff_) && d_r < getPtScaledCut(tk_pt, dRCutoff_)) + return true; + } else { + double deta_max = dEtaCutoff_[0]; + if (std::abs(eg_eta) < EB_MaxEta) + deta_max = dEtaCutoff_[1]; + double dphi_max = dPhiCutoff_[0]; + if ((d_eta / deta_max) * (d_eta / deta_max) + (d_phi / dphi_max) * (d_phi / dphi_max) < 1) + return true; + } + return false; +} +//define this as a plug-in +DEFINE_FWK_MODULE(L1TkElectronTrackProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkEmParticleProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkEmParticleProducer.cc new file mode 100644 index 0000000000000..e708cd2bf52cc --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TkEmParticleProducer.cc @@ -0,0 +1,293 @@ +// -*- C++ -*- +// +// +// dummy producer for a TkEm +// + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/EventSetup.h" + +#include "DataFormats/Common/interface/Handle.h" +#include "FWCore/Utilities/interface/InputTag.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" + +#include "DataFormats/Math/interface/LorentzVector.h" + +// for L1Tracks: +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include "DataFormats/Math/interface/deltaR.h" + +#include +#include + +static constexpr float EtaECal = 1.479; +static constexpr float REcal = 129.; +static constexpr float ZEcal = 315.4; +using namespace l1t; +// +// class declaration +// + +class L1TkEmParticleProducer : public edm::global::EDProducer<> { +public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollectionType; + + explicit L1TkEmParticleProducer(const edm::ParameterSet&); + ~L1TkEmParticleProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + float CorrectedEta(float eta, float zv) const; + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + // ----------member data --------------------------- + + std::string label_; + + float etMin_; // min ET in GeV of L1EG objects + + float zMax_; // |z_track| < zMax_ in cm + float chi2Max_; + float dRMin_; + float dRMax_; + float pTMinTra_; + bool primaryVtxConstrain_; // use the primary vertex (default = false) + //bool DeltaZConstrain; // use z = z of the leading track within DR < dRMax_; + float deltaZMax_; // | z_track - z_primaryvtx | < deltaZMax_ in cm. + // Used only when primaryVtxConstrain_ = True. + float isoCut_; + bool relativeIsolation_; + + const edm::EDGetTokenT egToken_; + const edm::EDGetTokenT > > trackToken_; + const edm::EDGetTokenT vertexToken_; +}; + +// +// constructors and destructor +// +L1TkEmParticleProducer::L1TkEmParticleProducer(const edm::ParameterSet& iConfig) + : egToken_(consumes(iConfig.getParameter("L1EGammaInputTag"))), + trackToken_(consumes > >( + iConfig.getParameter("L1TrackInputTag"))), + vertexToken_(consumes(iConfig.getParameter("L1VertexInputTag"))) { + label_ = iConfig.getParameter("label"); // label of the collection produced + // e.g. EG or IsoEG if all objects are kept + // EGIsoTrk or IsoEGIsoTrk if only the EG or IsoEG + // objects that pass a cut RelIso < isoCut_ are written + // in the new collection. + + etMin_ = (float)iConfig.getParameter("ETmin"); + + // parameters for the calculation of the isolation : + zMax_ = (float)iConfig.getParameter("ZMAX"); + chi2Max_ = (float)iConfig.getParameter("CHI2MAX"); + pTMinTra_ = (float)iConfig.getParameter("PTMINTRA"); + dRMin_ = (float)iConfig.getParameter("DRmin"); + dRMax_ = (float)iConfig.getParameter("DRmax"); + primaryVtxConstrain_ = iConfig.getParameter("PrimaryVtxConstrain"); + deltaZMax_ = (float)iConfig.getParameter("DeltaZMax"); + // cut applied on the isolation (if this number is <= 0, no cut is applied) + isoCut_ = (float)iConfig.getParameter("IsoCut"); + relativeIsolation_ = iConfig.getParameter("RelativeIsolation"); + + produces(label_); +} + +L1TkEmParticleProducer::~L1TkEmParticleProducer() {} + +// ------------ method called to produce the data ------------ +void L1TkEmParticleProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + using namespace edm; + + auto result = std::make_unique(); + + // the L1EGamma objects + edm::Handle eGammaHandle; + iEvent.getByToken(egToken_, eGammaHandle); + EGammaBxCollection eGammaCollection = (*eGammaHandle.product()); + EGammaBxCollection::const_iterator egIter; + + // the L1Tracks + edm::Handle > > L1TTTrackHandle; + iEvent.getByToken(trackToken_, L1TTTrackHandle); + + // the primary vertex (used only if primaryVtxConstrain_ = true) + float zvtxL1tk = -999; + edm::Handle L1VertexHandle; + iEvent.getByToken(vertexToken_, L1VertexHandle); + bool primaryVtxConstrain = primaryVtxConstrain_; + if (!L1VertexHandle.isValid()) { + LogWarning("L1TkEmParticleProducer") + << "Warning: TkPrimaryVertexCollection not found in the event. Won't use any PrimaryVertex constraint." + << std::endl; + primaryVtxConstrain = false; + } else { + std::vector::const_iterator vtxIter = L1VertexHandle->begin(); + // by convention, the first vertex in the collection is the one that should + // be used by default + zvtxL1tk = vtxIter->zvertex(); + } + + if (!L1TTTrackHandle.isValid()) { + LogError("L1TkEmParticleProducer") << "\nWarning: L1TTTrackCollectionType not found in the event. Exit." + << std::endl; + return; + } + + // Now loop over the L1EGamma objects + + if (!eGammaHandle.isValid()) { + LogError("L1TkEmParticleProducer") << "\nWarning: L1EmCollection not found in the event. Exit." << std::endl; + return; + } + + int ieg = 0; + for (egIter = eGammaCollection.begin(0); egIter != eGammaCollection.end(0); ++egIter) // considering BX = only + { + edm::Ref EGammaRef(eGammaHandle, ieg); + ieg++; + + float eta = egIter->eta(); + // The eta of the L1EG object is seen from (0,0,0). + // if primaryVtxConstrain_ = true, and for the PV constrained iso, use the zvtxL1tk to correct the eta(L1EG) + // that is used in the calculation of DeltaR. + float etaPV = CorrectedEta((float)eta, zvtxL1tk); + + float phi = egIter->phi(); + float et = egIter->et(); + + if (et < etMin_) + continue; + + // calculate the isolation of the L1EG object with + // respect to L1Tracks. + + float trkisol = -999; + float sumPt = 0; + float sumPtPV = 0; + float trkisolPV = -999; + + for (const auto& track : *L1TTTrackHandle) { + float Pt = track.momentum().perp(); + float Eta = track.momentum().eta(); + float Phi = track.momentum().phi(); + float z = track.POCA().z(); + if (fabs(z) > zMax_) + continue; + if (Pt < pTMinTra_) + continue; + float chi2 = track.chi2(); + if (chi2 > chi2Max_) + continue; + + float dr = reco::deltaR(Eta, Phi, eta, phi); + if (dr < dRMax_ && dr >= dRMin_) { + sumPt += Pt; + } + + if (zvtxL1tk > -999 && std::abs(z - zvtxL1tk) >= deltaZMax_) + continue; // Now, PV constrained trackSum: + + dr = reco::deltaR(Eta, Phi, etaPV, phi); // recompute using the corrected eta + + if (dr < dRMax_ && dr >= dRMin_) { + sumPtPV += Pt; + } + } // end loop over tracks + + if (relativeIsolation_) { + if (et > 0) { + trkisol = sumPt / et; + trkisolPV = sumPtPV / et; + } // relative isolation + } else { // absolute isolation + trkisol = sumPt; + trkisolPV = sumPtPV; + } + + float isolation = trkisol; + if (primaryVtxConstrain) { + isolation = trkisolPV; + } + + const math::XYZTLorentzVector P4 = egIter->p4(); + TkEm trkEm(P4, EGammaRef, trkisol, trkisolPV); + + if (isoCut_ <= 0) { + // write the L1TkEm particle to the collection, + // irrespective of its relative isolation + result->push_back(trkEm); + } else { + // the object is written to the collection only + // if it passes the isolation cut + if (isolation <= isoCut_) + result->push_back(trkEm); + } + + } // end loop over EGamma objects + + iEvent.put(std::move(result), label_); +} + +// -------------------------------------------------------------------------------------- + +float L1TkEmParticleProducer::CorrectedEta(float eta, float zv) const { + // Correct the eta of the L1EG object once we know the zvertex + + bool IsBarrel = (std::abs(eta) < EtaECal); + + float theta = 2. * atan(exp(-eta)); + if (theta < 0) + theta = theta + M_PI; + float tantheta = tan(theta); + + float delta; + if (IsBarrel) { + delta = REcal / tantheta; + } else { + if (theta > 0) + delta = ZEcal; + if (theta < 0) + delta = -ZEcal; + } + + float tanthetaprime = delta * tantheta / (delta - zv); + + float thetaprime = atan(tanthetaprime); + if (thetaprime < 0) + thetaprime = thetaprime + M_PI; + + float etaprime = -log(tan(thetaprime / 2.)); + return etaprime; +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TkEmParticleProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TkEmParticleProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkFastVertexProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkFastVertexProducer.cc new file mode 100644 index 0000000000000..1d06ecd7bde7f --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TkFastVertexProducer.cc @@ -0,0 +1,360 @@ +// -*- C++ -*- +// +// +// Original Author: Emmanuelle Perez,40 1-A28,+41227671915, +// Created: Tue Nov 12 17:03:19 CET 2013 +// $Id$ +// +// +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +//////////////////////////// +// DETECTOR GEOMETRY HEADERS +#include "MagneticField/Engine/interface/MagneticField.h" + +#include "Geometry/Records/interface/TrackerTopologyRcd.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" + +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" + +//////////////////////////// +// HepMC products +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h" +#include "DataFormats/Candidate/interface/Candidate.h" + +#include "TH1F.h" + +using namespace l1t; + +// +// class declaration +// + +class L1TkFastVertexProducer : public edm::global::EDProducer<> { +public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollectionType; + + explicit L1TkFastVertexProducer(const edm::ParameterSet&); + ~L1TkFastVertexProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + // ----------member data --------------------------- + + float zMax_; // in cm + float DeltaZ; // in cm + float chi2Max_; + float pTMinTra_; // in GeV + + float pTMax_; // in GeV, saturation / truncation value + int highPtTracks_; // saturate or truncate + + int nStubsmin_; // minimum number of stubs + int nStubsPSmin_; // minimum number of stubs in PS modules + + int nBinning_; // number of bins used in the temp histogram + + bool monteCarloVertex_; // + //const StackedTrackerGeometry* theStackedGeometry; + + bool doPtComp_; + bool doTightChi2_; + + int weight_; // weight (power) of pT 0 , 1, 2 + + constexpr static float xmin_ = -30; + constexpr static float xmax_ = +30; + + const edm::EDGetTokenT hepmcToken_; + const edm::EDGetTokenT > genparticleToken_; + const edm::EDGetTokenT > > trackToken_; + const edm::ESGetToken topoToken_; +}; + +// +// constants, enums and typedefs +// + +// +// static data member definitions +// + +// +// constructors and destructor +// +L1TkFastVertexProducer::L1TkFastVertexProducer(const edm::ParameterSet& iConfig) + : hepmcToken_(consumes(iConfig.getParameter("HepMCInputTag"))), + genparticleToken_( + consumes >(iConfig.getParameter("GenParticleInputTag"))), + trackToken_(consumes > >( + iConfig.getParameter("L1TrackInputTag"))), + topoToken_(esConsumes()) { + zMax_ = (float)iConfig.getParameter("ZMAX"); + chi2Max_ = (float)iConfig.getParameter("CHI2MAX"); + pTMinTra_ = (float)iConfig.getParameter("PTMINTRA"); + + pTMax_ = (float)iConfig.getParameter("PTMAX"); + highPtTracks_ = iConfig.getParameter("HighPtTracks"); + + nStubsmin_ = iConfig.getParameter("nStubsmin"); + nStubsPSmin_ = iConfig.getParameter("nStubsPSmin"); + nBinning_ = iConfig.getParameter("nBinning"); + + monteCarloVertex_ = iConfig.getParameter("MonteCarloVertex"); + doPtComp_ = iConfig.getParameter("doPtComp"); + doTightChi2_ = iConfig.getParameter("doTightChi2"); + + weight_ = iConfig.getParameter("WEIGHT"); + + produces(); +} + +L1TkFastVertexProducer::~L1TkFastVertexProducer() { + // do anything here that needs to be done at desctruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void L1TkFastVertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + using namespace edm; + + auto result = std::make_unique(); + + // Tracker Topology + edm::ESHandle tTopoHandle = iSetup.getHandle(topoToken_); + const TrackerTopology* tTopo = tTopoHandle.product(); + + TH1F htmp("htmp", ";z (cm); Tracks", nBinning_, xmin_, xmax_); + TH1F htmp_weight("htmp_weight", ";z (cm); Tracks", nBinning_, xmin_, xmax_); + + // ---------------------------------------------------------------------- + + if (monteCarloVertex_) { + // MC info ... retrieve the zvertex + edm::Handle HepMCEvt; + iEvent.getByToken(hepmcToken_, HepMCEvt); + + edm::Handle > GenParticleHandle; + iEvent.getByToken(genparticleToken_, GenParticleHandle); + + const double mm = 0.1; + float zvtx_gen = -999; + + if (HepMCEvt.isValid()) { + // using HepMCEvt + + const HepMC::GenEvent* MCEvt = HepMCEvt->GetEvent(); + for (HepMC::GenEvent::vertex_const_iterator ivertex = MCEvt->vertices_begin(); ivertex != MCEvt->vertices_end(); + ++ivertex) { + bool hasParentVertex = false; + + // Loop over the parents looking to see if they are coming from a production vertex + for (HepMC::GenVertex::particle_iterator iparent = (*ivertex)->particles_begin(HepMC::parents); + iparent != (*ivertex)->particles_end(HepMC::parents); + ++iparent) + if ((*iparent)->production_vertex()) { + hasParentVertex = true; + break; + } + + // Reject those vertices with parent vertices + if (hasParentVertex) + continue; + // Get the position of the vertex + HepMC::FourVector pos = (*ivertex)->position(); + zvtx_gen = pos.z() * mm; + break; // there should be one single primary vertex + } // end loop over gen vertices + + } else if (GenParticleHandle.isValid()) { + for (const auto& genpart : *GenParticleHandle) { + int status = genpart.status(); + if (status != 3) + continue; + if (genpart.numberOfMothers() == 0) + continue; // the incoming hadrons + float part_zvertex = genpart.vz(); + zvtx_gen = part_zvertex; + break; // + } + } else { + throw cms::Exception("L1TkFastVertexProducer") + << "\nerror: try to retrieve the MC vertex (monteCarloVertex_ = True) " + << "\nbut the input file contains neither edm::HepMCProduct> nor vector. Exit" + << std::endl; + } + + TkPrimaryVertex genvtx(zvtx_gen, -999.); + + result->push_back(genvtx); + iEvent.put(std::move(result)); + return; + } + + edm::Handle L1TTTrackHandle; + iEvent.getByToken(trackToken_, L1TTTrackHandle); + + if (!L1TTTrackHandle.isValid()) { + throw cms::Exception("L1TkFastVertexProducer") + << "\nWarning: L1TkTrackCollection with not found in the event. Exit" << std::endl; + return; + } + + for (const auto& track : *L1TTTrackHandle) { + float z = track.POCA().z(); + float chi2 = track.chi2(); + float pt = track.momentum().perp(); + float eta = track.momentum().eta(); + + //.............................................................. + float wt = pow(pt, weight_); // calculating the weight for tks in as pt^0,pt^1 or pt^2 based on weight_ + + if (std::abs(z) > zMax_) + continue; + if (chi2 > chi2Max_) + continue; + if (pt < pTMinTra_) + continue; + + // saturation or truncation : + if (pTMax_ > 0 && pt > pTMax_) { + if (highPtTracks_ == 0) + continue; // ignore this track + if (highPtTracks_ == 1) + pt = pTMax_; // saturate + } + + // get the number of stubs and the number of stubs in PS layers + float nPS = 0.; // number of stubs in PS modules + float nstubs = 0; + + // get pointers to stubs associated to the L1 track + const std::vector >, TTStub > >& + theStubs = track.getStubRefs(); + + int tmp_trk_nstub = (int)theStubs.size(); + if (tmp_trk_nstub < 0) { + LogTrace("L1TkFastVertexProducer") + << " ... could not retrieve the vector of stubs in L1TkFastVertexProducer::SumPtVertex " << std::endl; + continue; + } + + // loop over the stubs + for (const auto& stub : theStubs) { + nstubs++; + bool isPS = false; + DetId detId(stub->getDetId()); + if (detId.det() == DetId::Detector::Tracker) { + if (detId.subdetId() == StripSubdetector::TOB && tTopo->tobLayer(detId) <= 3) + isPS = true; + else if (detId.subdetId() == StripSubdetector::TID && tTopo->tidRing(detId) <= 9) + isPS = true; + } + if (isPS) + nPS++; + } // end loop over stubs + if (nstubs < nStubsmin_) + continue; + if (nPS < nStubsPSmin_) + continue; + + // quality cuts from Louise S, based on the pt-stub compatibility (June 20, 2014) + int trk_nstub = (int)track.getStubRefs().size(); + float chi2dof = chi2 / (2 * trk_nstub - 4); + + if (doPtComp_) { + float trk_consistency = track.stubPtConsistency(); + if (trk_nstub == 4) { + if (std::abs(eta) < 2.2 && trk_consistency > 10) + continue; + else if (std::abs(eta) > 2.2 && chi2dof > 5.0) + continue; + } + } + if (doTightChi2_) { + if (pt > 10.0 && chi2dof > 5.0) + continue; + } + + htmp.Fill(z); + htmp_weight.Fill(z, wt); // changed from "pt" to "wt" which is some power of pt (0,1 or 2) + + } // end loop over tracks + + // sliding windows... maximize bin i + i-1 + i+1 + + float zvtx_sliding = -999; + float sigma_max = -999; + int nb = htmp.GetNbinsX(); + for (int i = 2; i <= nb - 1; i++) { + float a0 = htmp.GetBinContent(i - 1); + float a1 = htmp.GetBinContent(i); + float a2 = htmp.GetBinContent(i + 1); + float sigma = a0 + a1 + a2; + if (sigma > sigma_max) { + sigma_max = sigma; + float z0 = htmp.GetBinCenter(i - 1); + float z1 = htmp.GetBinCenter(i); + float z2 = htmp.GetBinCenter(i + 1); + zvtx_sliding = (a0 * z0 + a1 * z1 + a2 * z2) / sigma; + } + } + + zvtx_sliding = -999; + sigma_max = -999; + for (int i = 2; i <= nb - 1; i++) { + float a0 = htmp_weight.GetBinContent(i - 1); + float a1 = htmp_weight.GetBinContent(i); + float a2 = htmp_weight.GetBinContent(i + 1); + float sigma = a0 + a1 + a2; + if (sigma > sigma_max) { + sigma_max = sigma; + float z0 = htmp_weight.GetBinCenter(i - 1); + float z1 = htmp_weight.GetBinCenter(i); + float z2 = htmp_weight.GetBinCenter(i + 1); + zvtx_sliding = (a0 * z0 + a1 * z1 + a2 * z2) / sigma; + } + } + + TkPrimaryVertex vtx4(zvtx_sliding, sigma_max); + + result->push_back(vtx4); + + iEvent.put(std::move(result)); +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TkFastVertexProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TkFastVertexProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc new file mode 100644 index 0000000000000..3030438648824 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc @@ -0,0 +1,679 @@ +// input: L1TkTracks and RegionalMuonCand (standalone with component details) +// match the two and produce a collection of TkMuon +// eventually, this should be made modular and allow to swap out different algorithms + +// user include files +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/Math/interface/LorentzVector.h" +#include "DataFormats/Math/interface/angle_units.h" +#include "DataFormats/Math/interface/deltaR.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" +#include "L1Trigger/L1TMuon/interface/MicroGMTConfiguration.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h" +#include "L1Trigger/L1TMuonEndCap/interface/Common.h" + +// system include files +#include +#include + +static constexpr float mu_mass = 0.105658369; +static constexpr int barrel_MTF_region = 1; +static constexpr int overlap_MTF_region = 2; +static constexpr int endcap_MTF_region = 3; +static constexpr float eta_scale = 0.010875; +static constexpr float phi_scale = 2 * M_PI / 576.; +static constexpr float dr2_cutoff = 0.3; +static constexpr float matching_factor_eta = 3.; +static constexpr float matching_factor_phi = 4.; +static constexpr float min_mu_propagator_p = 3.5; +static constexpr float min_mu_propagator_barrel_pT = 3.5; +static constexpr float max_mu_propagator_eta = 2.5; + +using namespace l1t; + +class L1TkMuonProducer : public edm::stream::EDProducer<> { +public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollectionType; + + struct PropState { //something simple, imagine it's hardware emulation + PropState() : pt(-99), eta(-99), phi(-99), sigmaPt(-99), sigmaEta(-99), sigmaPhi(-99), valid(false) {} + float pt; + float eta; + float phi; + float sigmaPt; + float sigmaEta; + float sigmaPhi; + bool valid; + }; + + enum AlgoType { kTP = 1, kDynamicWindows = 2, kMantra = 3 }; + + explicit L1TkMuonProducer(const edm::ParameterSet&); + ~L1TkMuonProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + PropState propagateToGMT(const L1TTTrackType& l1tk) const; + double sigmaEtaTP(const RegionalMuonCand& mu) const; + double sigmaPhiTP(const RegionalMuonCand& mu) const; + + // the TP algorithm + void runOnMTFCollection_v1(const edm::Handle&, + const edm::Handle&, + TkMuonCollection& tkMuons, + const int detector) const; + + // algo for endcap regions using dynamic windows for making the match + void runOnMTFCollection_v2(const edm::Handle&, + const edm::Handle&, + TkMuonCollection& tkMuons) const; + + // given the matching indexes, build the output collection of track muons + void build_tkMuons_from_idxs(TkMuonCollection& tkMuons, + const std::vector& matches, + const edm::Handle& l1tksH, + const edm::Handle& muonH, + int detector) const; + + // dump and convert tracks to the format needed for the MAnTra correlator + std::vector product_to_trkvec(const L1TTTrackCollectionType& l1tks) const; // tracks + // regional muon finder + std::vector product_to_muvec(const RegionalMuonCandBxCollection& l1mtfs) const; + // endcap muon finder - eventually to be moved to regional candidate + std::vector product_to_muvec(const EMTFTrackCollection& l1mus) const; + + float etaMin_; + float etaMax_; + float zMax_; // |z_track| < zMax_ in cm + float chi2Max_; + float pTMinTra_; + float dRMax_; + int nStubsmin_; // minimum number of stubs + bool correctGMTPropForTkZ_; + bool use5ParameterFit_; + bool useTPMatchWindows_; + + AlgoType bmtfMatchAlgoVersion_; + AlgoType omtfMatchAlgoVersion_; + AlgoType emtfMatchAlgoVersion_; + + std::unique_ptr dwcorr_; + + std::unique_ptr mantracorr_barr_; + std::unique_ptr mantracorr_ovrl_; + std::unique_ptr mantracorr_endc_; + int mantra_n_trk_par_; + + const edm::EDGetTokenT bmtfToken_; + const edm::EDGetTokenT omtfToken_; + const edm::EDGetTokenT emtfToken_; + // the track collection, directly from the EMTF and not formatted by GT + const edm::EDGetTokenT emtfTCToken_; + const edm::EDGetTokenT > > trackToken_; +}; + +L1TkMuonProducer::L1TkMuonProducer(const edm::ParameterSet& iConfig) + : etaMin_((float)iConfig.getParameter("ETAMIN")), + etaMax_((float)iConfig.getParameter("ETAMAX")), + zMax_((float)iConfig.getParameter("ZMAX")), + chi2Max_((float)iConfig.getParameter("CHI2MAX")), + pTMinTra_((float)iConfig.getParameter("PTMINTRA")), + dRMax_((float)iConfig.getParameter("DRmax")), + nStubsmin_(iConfig.getParameter("nStubsmin")), + // --- mantra corr params + mantra_n_trk_par_(iConfig.getParameter("mantra_n_trk_par")), + bmtfToken_(consumes(iConfig.getParameter("L1BMTFInputTag"))), + omtfToken_(consumes(iConfig.getParameter("L1OMTFInputTag"))), + emtfToken_(consumes(iConfig.getParameter("L1EMTFInputTag"))), + emtfTCToken_(consumes(iConfig.getParameter("L1EMTFTrackCollectionInputTag"))), + trackToken_(consumes > >( + iConfig.getParameter("L1TrackInputTag"))) { + // --------------------- configuration of the muon algorithm type + + std::string bmtfMatchAlgoVersionString = iConfig.getParameter("bmtfMatchAlgoVersion"); + std::transform(bmtfMatchAlgoVersionString.begin(), + bmtfMatchAlgoVersionString.end(), + bmtfMatchAlgoVersionString.begin(), + ::tolower); // make lowercase + + std::string omtfMatchAlgoVersionString = iConfig.getParameter("omtfMatchAlgoVersion"); + std::transform(omtfMatchAlgoVersionString.begin(), + omtfMatchAlgoVersionString.end(), + omtfMatchAlgoVersionString.begin(), + ::tolower); // make lowercase + + std::string emtfMatchAlgoVersionString = iConfig.getParameter("emtfMatchAlgoVersion"); + std::transform(emtfMatchAlgoVersionString.begin(), + emtfMatchAlgoVersionString.end(), + emtfMatchAlgoVersionString.begin(), + ::tolower); // make lowercase + + if (bmtfMatchAlgoVersionString == "tp") + bmtfMatchAlgoVersion_ = kTP; + else if (bmtfMatchAlgoVersionString == "mantra") + bmtfMatchAlgoVersion_ = kMantra; + else + throw cms::Exception("TkMuAlgoConfig") + << "the ID " << bmtfMatchAlgoVersionString << " of the BMTF algo matcher passed is invalid\n"; + + if (omtfMatchAlgoVersionString == "tp") + omtfMatchAlgoVersion_ = kTP; + else if (omtfMatchAlgoVersionString == "mantra") + omtfMatchAlgoVersion_ = kMantra; + else + throw cms::Exception("TkMuAlgoConfig") + << "the ID " << omtfMatchAlgoVersionString << " of the OMTF algo matcher passed is invalid\n"; + + if (emtfMatchAlgoVersionString == "tp") + emtfMatchAlgoVersion_ = kTP; + else if (emtfMatchAlgoVersionString == "dynamicwindows") + emtfMatchAlgoVersion_ = kDynamicWindows; + else if (emtfMatchAlgoVersionString == "mantra") + emtfMatchAlgoVersion_ = kMantra; + else + throw cms::Exception("TkMuAlgoConfig") + << "the ID " << emtfMatchAlgoVersionString << " of the EMTF algo matcher passed is invalid\n"; + + correctGMTPropForTkZ_ = iConfig.getParameter("correctGMTPropForTkZ"); + + use5ParameterFit_ = iConfig.getParameter("use5ParameterFit"); + useTPMatchWindows_ = iConfig.getParameter("useTPMatchWindows"); + produces(); + + // initializations + if (emtfMatchAlgoVersion_ == kDynamicWindows) { + // FIXME: to merge eventually into an unique file with bith phi and theta boundaries + std::string fIn_bounds_name = iConfig.getParameter("emtfcorr_boundaries").fullPath(); + std::string fIn_theta_name = iConfig.getParameter("emtfcorr_theta_windows").fullPath(); + std::string fIn_phi_name = iConfig.getParameter("emtfcorr_phi_windows").fullPath(); + const auto& bounds = L1TkMuCorrDynamicWindows::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); + TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); + TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); + dwcorr_ = std::make_unique(bounds, fIn_theta, fIn_phi); + + // files can be closed since the correlator code clones the TF1s + fIn_theta->Close(); + fIn_phi->Close(); + + // FIXME: more initialisation using the parameters passed from the cfg + dwcorr_->set_safety_factor(iConfig.getParameter("final_window_factor")); + dwcorr_->set_sf_initialrelax(iConfig.getParameter("initial_window_factor")); + + dwcorr_->set_relaxation_pattern(iConfig.getParameter("pt_start_relax"), + iConfig.getParameter("pt_end_relax")); + + dwcorr_->set_do_relax_factor(iConfig.getParameter("do_relax_factors")); + + dwcorr_->set_n_trk_par(iConfig.getParameter("n_trk_par")); + dwcorr_->set_min_trk_p(iConfig.getParameter("min_trk_p")); + dwcorr_->set_max_trk_aeta(iConfig.getParameter("max_trk_aeta")); + dwcorr_->set_max_trk_chi2(iConfig.getParameter("max_trk_chi2")); + dwcorr_->set_min_trk_nstubs(iConfig.getParameter("min_trk_nstubs")); + dwcorr_->set_do_trk_qual_presel(true); + } + + if (bmtfMatchAlgoVersion_ == kMantra) { + std::string fIn_bounds_name = iConfig.getParameter("mantra_bmtfcorr_boundaries").fullPath(); + std::string fIn_theta_name = iConfig.getParameter("mantra_bmtfcorr_theta_windows").fullPath(); + std::string fIn_phi_name = iConfig.getParameter("mantra_bmtfcorr_phi_windows").fullPath(); + + const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); + + TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); + TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); + + mantracorr_barr_ = std::make_unique(bounds, fIn_theta, fIn_phi, "mantra_barrel"); + + fIn_theta->Close(); + fIn_phi->Close(); + + // settings : NB : now hardcoded, could be read from cfg + mantracorr_barr_->set_safety_factor(0.5, 0.5); + mantracorr_barr_->setArbitrationType("MaxPt"); + } + + if (omtfMatchAlgoVersion_ == kMantra) { + std::string fIn_bounds_name = iConfig.getParameter("mantra_omtfcorr_boundaries").fullPath(); + std::string fIn_theta_name = iConfig.getParameter("mantra_omtfcorr_theta_windows").fullPath(); + std::string fIn_phi_name = iConfig.getParameter("mantra_omtfcorr_phi_windows").fullPath(); + + const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); + + TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); + TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); + + mantracorr_ovrl_ = std::make_unique(bounds, fIn_theta, fIn_phi, "mantra_overlap"); + + fIn_theta->Close(); + fIn_phi->Close(); + + // settings : NB : now hardcoded, could be read from cfg + mantracorr_ovrl_->set_safety_factor(0.5, 0.5); + mantracorr_ovrl_->setArbitrationType("MaxPt"); + } + + if (emtfMatchAlgoVersion_ == kMantra) { + std::string fIn_bounds_name = iConfig.getParameter("mantra_emtfcorr_boundaries").fullPath(); + std::string fIn_theta_name = iConfig.getParameter("mantra_emtfcorr_theta_windows").fullPath(); + std::string fIn_phi_name = iConfig.getParameter("mantra_emtfcorr_phi_windows").fullPath(); + + const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); + + TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); + TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); + + mantracorr_endc_ = std::make_unique(bounds, fIn_theta, fIn_phi, "mantra_endcap"); + + fIn_theta->Close(); + fIn_phi->Close(); + + // settings : NB : now hardcoded, could be read from cfg + mantracorr_endc_->set_safety_factor(0.5, 0.5); + mantracorr_endc_->setArbitrationType("MaxPt"); + } +} + +L1TkMuonProducer::~L1TkMuonProducer() {} + +// ------------ method called to produce the data ------------ +void L1TkMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // the L1Mu objects + edm::Handle l1bmtfH; + edm::Handle l1omtfH; + edm::Handle l1emtfH; + edm::Handle l1emtfTCH; + + iEvent.getByToken(bmtfToken_, l1bmtfH); + iEvent.getByToken(omtfToken_, l1omtfH); + iEvent.getByToken(emtfToken_, l1emtfH); + iEvent.getByToken(emtfTCToken_, l1emtfTCH); + + // the L1Tracks + edm::Handle l1tksH; + iEvent.getByToken(trackToken_, l1tksH); + + TkMuonCollection oc_bmtf_tkmuon; + TkMuonCollection oc_omtf_tkmuon; + TkMuonCollection oc_emtf_tkmuon; + + std::vector mantradf_tracks; // if needed, just encode once for all trk finders + if (bmtfMatchAlgoVersion_ == kMantra || omtfMatchAlgoVersion_ == kMantra || emtfMatchAlgoVersion_ == kMantra) { + mantradf_tracks = product_to_trkvec(*l1tksH.product()); + } + + // process each of the MTF collections separately! -- we don't want to filter the muons + + // ----------------------------------------------------- barrel + if (bmtfMatchAlgoVersion_ == kTP) + runOnMTFCollection_v1(l1bmtfH, l1tksH, oc_bmtf_tkmuon, barrel_MTF_region); + else if (bmtfMatchAlgoVersion_ == kMantra) { + const auto& muons = product_to_muvec(*l1bmtfH.product()); + const auto& match_idx = mantracorr_barr_->find_match(mantradf_tracks, muons); + build_tkMuons_from_idxs(oc_bmtf_tkmuon, match_idx, l1tksH, l1bmtfH, barrel_MTF_region); + } else + throw cms::Exception("TkMuAlgoConfig") << " barrel : trying to run an invalid algorithm version " + << bmtfMatchAlgoVersion_ << " (this should never happen)\n"; + + // ----------------------------------------------------- overlap + if (omtfMatchAlgoVersion_ == kTP) + runOnMTFCollection_v1(l1omtfH, l1tksH, oc_omtf_tkmuon, overlap_MTF_region); + else if (omtfMatchAlgoVersion_ == kMantra) { + const auto& muons = product_to_muvec(*l1omtfH.product()); + const auto& match_idx = mantracorr_ovrl_->find_match(mantradf_tracks, muons); + build_tkMuons_from_idxs(oc_omtf_tkmuon, match_idx, l1tksH, l1omtfH, overlap_MTF_region); + } else + throw cms::Exception("TkMuAlgoConfig") << " overlap : trying to run an invalid algorithm version " + << omtfMatchAlgoVersion_ << " (this should never happen)\n"; + + // ----------------------------------------------------- endcap + if (emtfMatchAlgoVersion_ == kTP) + runOnMTFCollection_v1(l1emtfH, l1tksH, oc_emtf_tkmuon, endcap_MTF_region); + else if (emtfMatchAlgoVersion_ == kDynamicWindows) + runOnMTFCollection_v2(l1emtfTCH, l1tksH, oc_emtf_tkmuon); + else if (emtfMatchAlgoVersion_ == kMantra) { + const auto& muons = product_to_muvec(*l1emtfTCH.product()); + const auto& match_idx = mantracorr_endc_->find_match(mantradf_tracks, muons); + //for the TkMu that were built from a EMTFCollection - do not produce a valid muon ref + edm::Handle invalidMuonH; + build_tkMuons_from_idxs(oc_emtf_tkmuon, match_idx, l1tksH, invalidMuonH, endcap_MTF_region); + } else + throw cms::Exception("TkMuAlgoConfig") << "endcap : trying to run an invalid algorithm version " + << emtfMatchAlgoVersion_ << " (this should never happen)\n"; + + // now combine all trk muons into a single output collection! + auto oc_tkmuon = std::make_unique(); + for (const auto& p : {oc_bmtf_tkmuon, oc_omtf_tkmuon, oc_emtf_tkmuon}) { + oc_tkmuon->insert(oc_tkmuon->end(), p.begin(), p.end()); + } + + // put the new track+muon objects in the event! + iEvent.put(std::move(oc_tkmuon)); +}; + +void L1TkMuonProducer::runOnMTFCollection_v1(const edm::Handle& muonH, + const edm::Handle& l1tksH, + TkMuonCollection& tkMuons, + const int detector) const { + const L1TTTrackCollectionType& l1tks = (*l1tksH.product()); + const RegionalMuonCandBxCollection& l1mtfs = (*muonH.product()); + + int imu = 0; + for (auto l1mu = l1mtfs.begin(0); l1mu != l1mtfs.end(0); ++l1mu) { // considering BX = only + + edm::Ref l1muRef(muonH, imu); + imu++; + + float l1mu_eta = l1mu->hwEta() * eta_scale; + // get the global phi + float l1mu_phi = + MicroGMTConfiguration::calcGlobalPhi(l1mu->hwPhi(), l1mu->trackFinderType(), l1mu->processor()) * phi_scale; + + float l1mu_feta = std::abs(l1mu_eta); + if (l1mu_feta < etaMin_) + continue; + if (l1mu_feta > etaMax_) + continue; + + float drmin = 999; + + PropState matchProp; + int match_idx = -1; + int il1tk = -1; + + int nTracksMatch = 0; + + for (const auto& l1tk : l1tks) { + il1tk++; + + float l1tk_pt = l1tk.momentum().perp(); + if (l1tk_pt < pTMinTra_) + continue; + + float l1tk_z = l1tk.POCA().z(); + if (std::abs(l1tk_z) > zMax_) + continue; + + float l1tk_chi2 = l1tk.chi2(); + if (l1tk_chi2 > chi2Max_) + continue; + + int l1tk_nstubs = l1tk.getStubRefs().size(); + if (l1tk_nstubs < nStubsmin_) + continue; + + float l1tk_eta = l1tk.momentum().eta(); + float l1tk_phi = l1tk.momentum().phi(); + + float dr2 = reco::deltaR2(l1mu_eta, l1mu_phi, l1tk_eta, l1tk_phi); + if (dr2 > dr2_cutoff) + continue; + + nTracksMatch++; + + const PropState& pstate = propagateToGMT(l1tk); + if (!pstate.valid) + continue; + + float dr2prop = reco::deltaR2(l1mu_eta, l1mu_phi, pstate.eta, pstate.phi); + // FIXME: check if this matching procedure can be improved with + // a pT dependent dR window + if (dr2prop < drmin) { + drmin = dr2prop; + match_idx = il1tk; + matchProp = pstate; + } + } // over l1tks + + LogDebug("L1TkMuonProducer") << "matching index is " << match_idx; + if (match_idx >= 0) { + const L1TTTrackType& matchTk = l1tks[match_idx]; + + float sigmaEta = sigmaEtaTP(*l1mu); + float sigmaPhi = sigmaPhiTP(*l1mu); + + float etaCut = matching_factor_eta * sqrt(sigmaEta * sigmaEta + matchProp.sigmaEta * matchProp.sigmaEta); + float phiCut = matching_factor_phi * sqrt(sigmaPhi * sigmaPhi + matchProp.sigmaPhi * matchProp.sigmaPhi); + + float dEta = std::abs(matchProp.eta - l1mu_eta); + float dPhi = std::abs(deltaPhi(matchProp.phi, l1mu_phi)); + + bool matchCondition = useTPMatchWindows_ ? dEta < etaCut && dPhi < phiCut : drmin < dRMax_; + + if (matchCondition) { + edm::Ptr l1tkPtr(l1tksH, match_idx); + + const auto& p3 = matchTk.momentum(); + float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); + + math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); + + const auto& tkv3 = matchTk.POCA(); + math::XYZPoint v3(tkv3.x(), tkv3.y(), tkv3.z()); // why is this defined? + + float trkisol = -999; + + TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol); + + l1tkmu.setTrackCurvature(matchTk.rInv()); + l1tkmu.setTrkzVtx((float)tkv3.z()); + l1tkmu.setdR(drmin); + l1tkmu.setNTracksMatched(nTracksMatch); + l1tkmu.setMuonDetector(detector); + tkMuons.push_back(l1tkmu); + } + } + } //over l1mus +} + +void L1TkMuonProducer::runOnMTFCollection_v2(const edm::Handle& muonH, + const edm::Handle& l1tksH, + TkMuonCollection& tkMuons) const { + const EMTFTrackCollection& l1mus = (*muonH.product()); + const L1TTTrackCollectionType& l1trks = (*l1tksH.product()); + const auto& corr_mu_idxs = dwcorr_->find_match(l1mus, l1trks); + // it's a vector with as many entries as the L1TT vector. + // >= 0 : the idx in the EMTF vector of matched mu + // < 0: no match + + // sanity check + if (corr_mu_idxs.size() != l1trks.size()) + throw cms::Exception("TkMuAlgoOutput") + << "the size of tkmu indices does not match the size of input trk collection\n"; + + for (uint il1ttrack = 0; il1ttrack < corr_mu_idxs.size(); ++il1ttrack) { + int emtf_idx = corr_mu_idxs[il1ttrack]; + if (emtf_idx < 0) + continue; + + const L1TTTrackType& matchTk = l1trks[il1ttrack]; + const auto& p3 = matchTk.momentum(); + const auto& tkv3 = matchTk.POCA(); + float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); + math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); + + edm::Ref l1muRef; + edm::Ptr l1tkPtr(l1tksH, il1ttrack); + float trkisol = -999; // now doing as in the TP algo + TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol); + l1tkmu.setTrackCurvature(matchTk.rInv()); + l1tkmu.setTrkzVtx((float)tkv3.z()); + l1tkmu.setMuonDetector(endcap_MTF_region); + tkMuons.push_back(l1tkmu); + } + + return; +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TkMuonProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +L1TkMuonProducer::PropState L1TkMuonProducer::propagateToGMT(const L1TkMuonProducer::L1TTTrackType& tk) const { + auto p3 = tk.momentum(); + float tk_pt = p3.perp(); + float tk_p = p3.mag(); + float tk_eta = p3.eta(); + float tk_aeta = std::abs(tk_eta); + float tk_phi = p3.phi(); + float tk_q = tk.rInv() > 0 ? 1. : -1.; + float tk_z = tk.POCA().z(); + if (!correctGMTPropForTkZ_) + tk_z = 0; + + L1TkMuonProducer::PropState dest; + if (tk_p < min_mu_propagator_p) + return dest; + if (tk_aeta < 1.1 && tk_pt < min_mu_propagator_barrel_pT) + return dest; + if (tk_aeta > max_mu_propagator_eta) + return dest; + + //0th order: + dest.valid = true; + + float dzCorrPhi = 1.; + float deta = 0; + float etaProp = tk_aeta; + + if (tk_aeta < 1.1) { + etaProp = 1.1; + deta = tk_z / 550. / cosh(tk_aeta); + } else { + float delta = tk_z / 850.; //roughly scales as distance to 2nd station + if (tk_eta > 0) + delta *= -1; + dzCorrPhi = 1. + delta; + + float zOzs = tk_z / 850.; + if (tk_eta > 0) + deta = zOzs / (1. - zOzs); + else + deta = zOzs / (1. + zOzs); + deta = deta * tanh(tk_eta); + } + float resPhi = tk_phi - 1.464 * tk_q * cosh(1.7) / cosh(etaProp) / tk_pt * dzCorrPhi - M_PI / 144.; + resPhi = reco::reduceRange(resPhi); + + dest.eta = tk_eta + deta; + dest.phi = resPhi; + dest.pt = tk_pt; //not corrected for eloss + + dest.sigmaEta = 0.100 / tk_pt; //multiple scattering term + dest.sigmaPhi = 0.106 / tk_pt; //need a better estimate for these + return dest; +} + +double L1TkMuonProducer::sigmaEtaTP(const RegionalMuonCand& l1mu) const { + float l1mu_eta = l1mu.hwEta() * eta_scale; + if (std::abs(l1mu_eta) <= 1.55) + return 0.0288; + else if (std::abs(l1mu_eta) > 1.55 && std::abs(l1mu_eta) <= 1.65) + return 0.025; + else if (std::abs(l1mu_eta) > 1.65 && std::abs(l1mu_eta) <= 2.4) + return 0.0144; + return 0.0288; +} + +double L1TkMuonProducer::sigmaPhiTP(const RegionalMuonCand& mu) const { return 0.0126; } + +// ------------------------------------------------------------------------------------------------------------ + +std::vector L1TkMuonProducer::product_to_trkvec(const L1TTTrackCollectionType& l1tks) const { + std::vector result(l1tks.size()); + for (uint itrk = 0; itrk < l1tks.size(); ++itrk) { + auto& trk = l1tks[itrk]; + + result[itrk].pt = trk.momentum().perp(); + result[itrk].eta = trk.momentum().eta(); + result[itrk].theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(trk.momentum().eta())); + result[itrk].phi = trk.momentum().phi(); + result[itrk].nstubs = trk.getStubRefs().size(); + result[itrk].chi2 = trk.chi2(); + result[itrk].charge = (trk.rInv() > 0 ? 1 : -1); + } + + return result; +} + +std::vector L1TkMuonProducer::product_to_muvec( + const RegionalMuonCandBxCollection& l1mtfs) const { + std::vector result; + for (auto l1mu = l1mtfs.begin(0); l1mu != l1mtfs.end(0); ++l1mu) // considering BX = 0 only + { + L1TkMuMantraDF::muon_df this_mu; + this_mu.pt = l1mu->hwPt() * 0.5; + this_mu.eta = l1mu->hwEta() * eta_scale; + this_mu.theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(l1mu->hwEta() * eta_scale)); + this_mu.phi = + MicroGMTConfiguration::calcGlobalPhi(l1mu->hwPhi(), l1mu->trackFinderType(), l1mu->processor()) * phi_scale; + this_mu.charge = (l1mu->hwSign() == 0 ? 1 : -1); // charge sign bit (charge = (-1)^(sign)) + result.push_back(this_mu); + } + return result; +} + +std::vector L1TkMuonProducer::product_to_muvec(const EMTFTrackCollection& l1mus) const { + std::vector result(l1mus.size()); + for (uint imu = 0; imu < l1mus.size(); ++imu) { + auto& mu = l1mus[imu]; + result[imu].pt = mu.Pt(); + result[imu].eta = mu.Eta(); + result[imu].theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(mu.Eta())); + result[imu].phi = angle_units::operators::convertDegToRad(mu.Phi_glob()); + result[imu].charge = mu.Charge(); + } + return result; +} + +void L1TkMuonProducer::build_tkMuons_from_idxs(TkMuonCollection& tkMuons, + const std::vector& matches, + const edm::Handle& l1tksH, + const edm::Handle& muonH, + int detector) const { + for (uint imatch = 0; imatch < matches.size(); ++imatch) { + int match_trk_idx = matches[imatch]; + if (match_trk_idx < 0) + continue; // this muon was not matched to any candidate + + // take properties of the track + const L1TTTrackType& matchTk = (*l1tksH.product())[match_trk_idx]; + const auto& p3 = matchTk.momentum(); + const auto& tkv3 = matchTk.POCA(); + float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); + math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); + + edm::Ptr l1tkPtr(l1tksH, match_trk_idx); + auto l1muRef = muonH.isValid() ? edm::Ref(muonH, imatch) + : edm::Ref(); + + float trkisol = -999; + TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol); + l1tkmu.setTrackCurvature(matchTk.rInv()); + l1tkmu.setTrkzVtx((float)tkv3.z()); + l1tkmu.setMuonDetector(detector); + tkMuons.push_back(l1tkmu); + } + return; +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TkMuonProducer); diff --git a/L1Trigger/L1TTrackMatch/python/L1TkElectronTrackProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkElectronTrackProducer_cfi.py new file mode 100644 index 0000000000000..d72323fc374dc --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkElectronTrackProducer_cfi.py @@ -0,0 +1,102 @@ +import FWCore.ParameterSet.Config as cms + +L1TkElectrons = cms.EDProducer("L1TkElectronTrackProducer", + label = cms.string("EG"), # labels the collection of L1TkEmParticleProducer that is produced. + # (not really needed actually) + L1EGammaInputTag = cms.InputTag("simCaloStage2Digis",""), + # Only the L1EG objects that have ET > ETmin in GeV + # are considered. ETmin < 0 means that no cut is applied. + ETmin = cms.double( -1.0 ), + L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + # Quality cuts on Track and Track L1EG matching criteria + TrackChi2 = cms.double(1e10), # minimum Chi2 to select tracks + TrackMinPt = cms.double(10.0), # minimum Pt to select tracks + useTwoStubsPT = cms.bool( False ), + useClusterET = cms.bool( False ), + TrackEGammaMatchType = cms.string("PtDependentCut"), + TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), # functional Delta Phi cut parameters to match Track with L1EG objects + TrackEGammaDeltaR = cms.vdouble(0.08, 0.0, 0.0), # functional Delta R cut parameters to match Track with L1EG objects + TrackEGammaDeltaEta = cms.vdouble(1e10, 0.0, 0.0), # Delta Eta cutoff to match Track with L1EG objects + # are considered. (unused in default configuration) + RelativeIsolation = cms.bool( True ), # default = True. The isolation variable is relative if True, + # else absolute. + # Cut on the (Trk-based) isolation: only the L1TkEmParticle for which + # the isolation is below RelIsoCut are written into + # the output collection. When RelIsoCut < 0, no cut is applied. + # When RelativeIsolation = False, IsoCut is in GeV. + # Determination of the isolation w.r.t. L1Tracks : + IsoCut = cms.double( -0.10 ), + PTMINTRA = cms.double( 2. ), # in GeV + DRmin = cms.double( 0.03), + DRmax = cms.double( 0.2 ), + maxChi2IsoTracks = cms.double(1e10), # max chi2 cut for a track to be considered for isolation computation + minNStubsIsoTracks = cms.int32(0), # min cut on # of stubs for a track to be considered for isolation computation + DeltaZ = cms.double( 0.6 ) # in cm. Used for tracks to be used isolation calculation +) +L1TkIsoElectrons = L1TkElectrons.clone( + IsoCut = cms.double( 0.10 ) +) +# for LowPt Electron +L1TkElectronsLoose = L1TkElectrons.clone( + TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), + TrackEGammaDeltaR = cms.vdouble(0.12, 0.0, 0.0), + TrackMinPt = cms.double( 3.0 ) +) + + +#### Additional collections that right now only the menu team is using - to be renamed/redefined by the EGamma group +# The important change is the EG seed -> PhaseII instead of PhaseI + +#barrel +L1TkElectronsCrystal = L1TkElectrons.clone( + L1EGammaInputTag = cms.InputTag("L1EGammaClusterEmuProducer"), + IsoCut = cms.double(-0.1) +) + +L1TkIsoElectronsCrystal=L1TkElectronsCrystal.clone( + IsoCut = cms.double(0.1) +) + +L1TkElectronsLooseCrystal = L1TkElectronsCrystal.clone( + TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), + TrackEGammaDeltaR = cms.vdouble(0.12, 0.0, 0.0), + TrackMinPt = cms.double( 3.0 ) +) + +L1TkElectronsEllipticMatchCrystal = L1TkElectronsCrystal.clone( +# L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + TrackEGammaMatchType = cms.string("EllipticalCut"), + TrackEGammaDeltaEta = cms.vdouble(0.015, 0.025,1e10) +) + + + +#endcap +L1TkElectronsHGC=L1TkElectrons.clone( + L1EGammaInputTag = cms.InputTag("l1EGammaEEProducer","L1EGammaCollectionBXVWithCuts"), + IsoCut = cms.double(-0.1) +) + + +L1TkElectronsEllipticMatchHGC = L1TkElectronsHGC.clone( + # L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") + TrackEGammaMatchType = cms.string("EllipticalCut"), + TrackEGammaDeltaEta = cms.vdouble(0.01, 0.01,1e10), + maxChi2IsoTracks = cms.double(100), + minNStubsIsoTracks = cms.int32(4), +) + + +L1TkIsoElectronsHGC=L1TkElectronsHGC.clone( + DRmax = cms.double(0.4), + DeltaZ = cms.double(1.0), + maxChi2IsoTracks = cms.double(100), + minNStubsIsoTracks = cms.int32(4), + IsoCut = cms.double(0.1) + ) + +L1TkElectronsLooseHGC = L1TkElectronsHGC.clone( + TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), + TrackEGammaDeltaR = cms.vdouble(0.12, 0.0, 0.0), + TrackMinPt = cms.double( 3.0 ) +) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkEmParticleProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkEmParticleProducer_cfi.py new file mode 100644 index 0000000000000..94128681723e1 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkEmParticleProducer_cfi.py @@ -0,0 +1,57 @@ +import FWCore.ParameterSet.Config as cms + +L1TkPhotons = cms.EDProducer("L1TkEmParticleProducer", + label = cms.string("EG"), # labels the collection of L1TkEmParticleProducer that is produced + # (not really needed actually) + L1EGammaInputTag = cms.InputTag("simCaloStage2Digis",""), + # When the standard sequences are used : + # - for the Run-1 algo, use ("l1extraParticles","NonIsolated") + # or ("l1extraParticles","Isolated") + # - for the "old stage-2" algo (2x2 clustering), use + # ("SLHCL1ExtraParticles","EGamma") or ("SLHCL1ExtraParticles","IsoEGamma") + # - for the new clustering algorithm of Jean-Baptiste et al, + # use ("SLHCL1ExtraParticlesNewClustering","IsoEGamma") or + # ("SLHCL1ExtraParticlesNewClustering","EGamma"). + ETmin = cms.double( -1 ), # Only the L1EG objects that have ET > ETmin in GeV + # are considered. ETmin < 0 means that no cut is applied. + RelativeIsolation = cms.bool( True ), # default = True. The isolation variable is relative if True, + # else absolute. + IsoCut = cms.double( 0.23 ), # Cut on the (Trk-based) isolation: only the L1TkEmParticle for which + # the isolation is below RelIsoCut are written into + # the output collection. When RelIsoCut < 0, no cut is applied. + # When RelativeIsolation = False, IsoCut is in GeV. + # Determination of the isolation w.r.t. L1Tracks : + L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + ZMAX = cms.double( 25. ), # in cm + CHI2MAX = cms.double( 100. ), + PTMINTRA = cms.double( 2. ), # in GeV + DRmin = cms.double( 0.07), + DRmax = cms.double( 0.30 ), + PrimaryVtxConstrain = cms.bool( False ), # default = False + # if set to True, the default isolation is the PV constrained one, where L1TkPrimaryVertex is used to constrain + # the tracks entering in the calculation of the isolation + # if set to False, the isolation is computed and stored, but not used + #DeltaZConstrain = cms.bool( False ), # default = False + # if set to True, constrain to the z of the leading + # track within DR < DRmax + DeltaZMax = cms.double( 0.6 ), # in cm. Used only to compute the isolation with PrimaryVtxConstrain + L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), # in cm. Used to compute the isolation with PrimaryVtxConstrain +) + + +L1TkPhotonsTightIsol = L1TkPhotons.clone() +L1TkPhotonsTightIsol.IsoCut = cms.double( 0.10) + +#### Additional collections that right now only the menu team is using - to be renamed/redefined by the EGamma group +# The important change is the EG seed -> PhaseII instead of PhaseI + +L1TkPhotonsCrystal=L1TkPhotons.clone() +L1TkPhotonsCrystal.L1EGammaInputTag = cms.InputTag("L1EGammaClusterEmuProducer", ) +L1TkPhotonsCrystal.IsoCut = cms.double(-0.1) + + +L1TkPhotonsHGC=L1TkPhotons.clone() +L1TkPhotonsHGC.L1EGammaInputTag = cms.InputTag("l1EGammaEEProducer","L1EGammaCollectionBXVWithCuts") +L1TkPhotonsHGC.IsoCut = cms.double(-0.1) + + diff --git a/L1Trigger/L1TTrackMatch/python/L1TkMuonProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkMuonProducer_cfi.py new file mode 100644 index 0000000000000..cad1428502d4c --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkMuonProducer_cfi.py @@ -0,0 +1,75 @@ +import FWCore.ParameterSet.Config as cms + +L1TkMuons = cms.EDProducer("L1TkMuonProducer", + ############################################### + ## switches that control the algos for the regions + bmtfMatchAlgoVersion = cms.string( 'TP' ), + omtfMatchAlgoVersion = cms.string( 'MAnTra' ), + emtfMatchAlgoVersion = cms.string( 'MAnTra' ), + ############################################### common stuff + L1BMTFInputTag = cms.InputTag("simKBmtfDigis","BMTF"), + L1OMTFInputTag = cms.InputTag("simOmtfDigis","OMTF"), + L1EMTFInputTag = cms.InputTag("simEmtfDigis","EMTF"), + L1EMTFTrackCollectionInputTag = cms.InputTag("simEmtfDigis"), + L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + ############################################### + ############################################### TP algo + ETAMIN = cms.double(0), + ETAMAX = cms.double(5.), # no cut + ZMAX = cms.double( 25. ), # in cm + CHI2MAX = cms.double( 100. ), + PTMINTRA = cms.double( 2. ), # in GeV + DRmax = cms.double( 0.5 ), + nStubsmin = cms.int32( 4 ), # minimum number of stubs +# closest = cms.bool( True ), + correctGMTPropForTkZ = cms.bool(True), + use5ParameterFit = cms.bool(False), #use 4-pars by defaults + useTPMatchWindows = cms.bool(True), + # emtfMatchAlgoVersion = cms.int32( 1 ), # version of matching EMTF with Trackes (1 or 2) + ############################################### + ############################################### DynamicWindows algo + ##### parameters for the DynamicWindows algo - eventually to put in a separate file, that will override some dummy defaults + emtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_boundaries.root'), + emtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_theta_q99.root'), + emtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_phi_q99.root'), + ## block to control the evolution of the matching window vs pt + ## if do_relax_factors = False ==> global scale of upper and lower boundaries by "final_window_factor" + ## if do_relax_factors = True ==> progressive linear scale, the factor is + ## - initial_window_factor for pt <= pt_start_relax + ## - final_window_factor for pt >= pt_end_relax + ## - and a linear interpolation in the middle + ## facror = 0 --> no changes to the window size + initial_window_factor = cms.double(0.0), + final_window_factor = cms.double(0.5), + pt_start_relax = cms.double(2.0), + pt_end_relax = cms.double(6.0), + do_relax_factors = cms.bool(True), + ## + n_trk_par = cms.int32(4), # 4 or 5 + min_trk_p = cms.double(3.5), + max_trk_aeta = cms.double(2.5), + max_trk_chi2 = cms.double(100.0), + min_trk_nstubs = cms.int32(4), + ############################################### + ############################################### Mantra algo + ## please NOTE that as of 6/11/2019, only these parameters are effectively used for the MAnTra correlator + # + mantra_n_trk_par = cms.int32(4), # 4 or 5 + # + mantra_bmtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_barrel/matching_windows_boundaries.root'), + mantra_bmtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_barrel/matching_windows_theta_q99.root'), + mantra_bmtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_barrel/matching_windows_phi_q99.root'), + # + mantra_omtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_overlap/matching_windows_boundaries.root'), + mantra_omtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_overlap/matching_windows_theta_q99.root'), + mantra_omtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_overlap/matching_windows_phi_q99.root'), + # + mantra_emtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_boundaries.root'), + mantra_emtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_theta_q99.root'), + mantra_emtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_phi_q99.root'), +) + +L1TkMuonsTP = L1TkMuons.clone( + emtfMatchAlgoVersion='TP', + useTPMatchWindows = True +) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py b/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py new file mode 100644 index 0000000000000..6b367950d1ec0 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py @@ -0,0 +1,78 @@ +import FWCore.ParameterSet.Config as cms + +# Phase II EG seeds, Barrel (Crystal): + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsCrystal +pL1TkElectronsCrystal = cms.Path( L1TkElectronsCrystal ) + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsEllipticMatchCrystal +pL1TkElectronsEllipticMatchCrystal = cms.Path( L1TkElectronsEllipticMatchCrystal ) + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsLooseCrystal +pL1TkElectronsLooseCrystal = cms.Path( L1TkElectronsLooseCrystal ) + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkIsoElectronsCrystal +pL1TkIsoElectronsCrystal = cms.Path( L1TkIsoElectronsCrystal ) + +from L1Trigger.L1TTrackMatch.L1TkEmParticleProducer_cfi import L1TkPhotonsCrystal +pL1TkPhotonsCrystal = cms.Path( L1TkPhotonsCrystal ) + +#+ from L1Trigger.L1TTrackMatch.L1WP2ElectronProducer_cfi import L1WP2Electrons +#+ pL1WP2Electrons = cms.Path( L1WP2Electrons) + +# Phase II EG seeds, Endcap (HGC): +# Two objects for now to follow 2017 discussions, merging collections would be nice... + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsHGC +pL1TkElectronsHGC = cms.Path( L1TkElectronsHGC ) + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsEllipticMatchHGC +pL1TkElectronsEllipticMatchHGC = cms.Path( L1TkElectronsEllipticMatchHGC ) + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkIsoElectronsHGC +pL1TkIsoElectronsHGC = cms.Path( L1TkIsoElectronsHGC ) + +from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsLooseHGC +pL1TkElectronsLooseHGC = cms.Path( L1TkElectronsLooseHGC ) + +from L1Trigger.L1TTrackMatch.L1TkEmParticleProducer_cfi import L1TkPhotonsHGC +pL1TkPhotonsHGC = cms.Path( L1TkPhotonsHGC ) + + +#Other tk Objects + +# from L1Trigger.L1TTrackMatch.L1TrackerJetProducer_cfi import L1TrackerJets +# pL1TrackerJets = cms.Path( L1TrackerJets) + +# from L1Trigger.TwoLayerJets.TwoLayerJets_cfi import TwoLayerJets +# pL1TwoLayerJets = cms.Path( TwoLayerJets) + +# from L1Trigger.L1TTrackMatch.L1TkCaloJetProducer_cfi import L1TkCaloJets +# pL1TkCaloJets = cms.Path( L1TkCaloJets) + +from L1Trigger.L1TTrackMatch.L1TkPrimaryVertexProducer_cfi import L1TkPrimaryVertex +pL1TkPrimaryVertex = cms.Path( L1TkPrimaryVertex ) + +# from L1Trigger.L1TTrackMatch.L1TrackerEtMissProducer_cfi import L1TrackerEtMiss +# pL1TrkMET = cms.Path( L1TrackerEtMiss ) + +# from L1Trigger.L1TTrackMatch.L1TkHTMissProducer_cfi import L1TkCaloHTMissVtx, L1TrackerHTMiss +# pL1TkCaloHTMissVtx = cms.Path( L1TkCaloHTMissVtx ) +# pL1TrackerHTMiss = cms.Path( L1TrackerHTMiss ) + +from L1Trigger.L1TTrackMatch.L1TkMuonProducer_cfi import L1TkMuons, L1TkMuonsTP +pL1TkMuon = cms.Path( L1TkMuons * L1TkMuonsTP ) + +# from L1Trigger.L1TTrackMatch.L1TkGlbMuonProducer_cfi import L1TkGlbMuons +# pL1TkGlbMuon = cms.Path( L1TkGlbMuons ) + +# from L1Trigger.L1TTrackMatch.L1TkTauFromCaloProducer_cfi import L1TkTauFromCalo +# pL1TkTauFromCalo = cms.Path( L1TkTauFromCalo ) + +# from L1Trigger.Phase2L1Taus.L1TrkTauParticleProducer_cfi import L1TrkTaus +# L1TrackerTaus = L1TrkTaus.clone() + +# from L1Trigger.Phase2L1Taus.L1TkEGTauParticleProducer_cfi import L1TkEGTaus + +# from L1Trigger.Phase2L1Taus.L1CaloTkTauParticleProducer_cfi import L1CaloTkTaus +# L1TkCaloTaus = L1CaloTkTaus.clone() diff --git a/L1Trigger/L1TTrackMatch/python/L1TkPrimaryVertexProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkPrimaryVertexProducer_cfi.py new file mode 100644 index 0000000000000..4b929f74e9f0e --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkPrimaryVertexProducer_cfi.py @@ -0,0 +1,41 @@ +import FWCore.ParameterSet.Config as cms + +L1TkPrimaryVertex = cms.EDProducer('L1TkFastVertexProducer', + +# +# Default parameters used for the plots for the TP +# + HepMCInputTag = cms.InputTag("generator"), + GenParticleInputTag = cms.InputTag("genParticles",""), + L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + ZMAX = cms.double ( 25. ) , # in cm + CHI2MAX = cms.double( 100. ), + PTMINTRA = cms.double( 2.), # PTMIN of L1Tracks, in GeV + nStubsmin = cms.int32( 4 ) , # minimum number of stubs + nStubsPSmin = cms.int32( 3 ), # minimum number of stubs in PS modules + nBinning = cms.int32( 601 ), # number of bins for the temp histo (from -30 cm to + 30 cm) + PTMAX = cms.double( 50. ), # in GeV. When PTMAX > 0, tracks with PT above PTMAX are considered as + # mismeasured and are treated according to HighPtTracks below. + # When PTMAX < 0, no special treatment is done for high PT tracks. + # If PTMAX < 0, no saturation or truncation is done. + HighPtTracks = cms.int32( 0 ), # when = 0 : truncation. Tracks with PT above PTMAX are ignored + # when = 1 : saturation. Tracks with PT above PTMAX are set to PT=PTMAX. + MonteCarloVertex = cms.bool( False ), # when True: dont run the vxt finding algo but pick up the MC generated vtx + doPtComp = cms.bool( True ), # track-stubs PT compatibility cut + doTightChi2 = cms.bool( False ), # chi2dof < 5 for tracks with PT > 10 + WEIGHT = cms.int32(1) # WEIGHT can be set to 0, 1 or 2 for unweighted, pT weighted + # or pT2 weighted tracks respectively. + +# +# Other working point which works better for H -> TauTau, +# cf talk by Moshan Ather, Dec 12, 2014: + +# WEIGHT = cms.int32(2), +# PTMAX = cms.double( 25. ), +# nStubsmin = cms.int32( 5 ), +# HighPtTracks = cms.int32( 1), +# doPtComp = cms.bool( False ), +# CHI2MAX = cms.double( 20 ) +# + +) diff --git a/L1Trigger/L1TTrackMatch/src/L1TkElectronTrackMatchAlgo.cc b/L1Trigger/L1TTrackMatch/src/L1TkElectronTrackMatchAlgo.cc new file mode 100644 index 0000000000000..ea300f226af49 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/L1TkElectronTrackMatchAlgo.cc @@ -0,0 +1,124 @@ +// -*- C++ -*- +// +// +/**\class L1TkElectronTrackMatchAlgo + + Description: Algorithm to match L1EGamma oject with L1Track candidates + + Implementation: + [Notes on implementation] +*/ + +// system include files +#include +#include + +#include "DataFormats/Math/interface/deltaPhi.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h" +namespace L1TkElectronTrackMatchAlgo { + + float constexpr max_eb_eta = 1.479; + float constexpr max_eb_z = 315.4; + float constexpr eb_rperp = 129.0; + // ------------ match EGamma and Track + void doMatch(l1t::EGammaBxCollection::const_iterator egIter, + const edm::Ptr& pTrk, + double& dph, + double& dr, + double& deta) { + GlobalPoint egPos = L1TkElectronTrackMatchAlgo::calorimeterPosition(egIter->phi(), egIter->eta(), egIter->energy()); + dph = L1TkElectronTrackMatchAlgo::deltaPhi(egPos, pTrk); + dr = L1TkElectronTrackMatchAlgo::deltaR(egPos, pTrk); + deta = L1TkElectronTrackMatchAlgo::deltaEta(egPos, pTrk); + } + // ------------ match EGamma and Track + void doMatchClusterET(l1t::EGammaBxCollection::const_iterator egIter, + const edm::Ptr& pTrk, + double& dph, + double& dr, + double& deta) { + GlobalPoint egPos = L1TkElectronTrackMatchAlgo::calorimeterPosition(egIter->phi(), egIter->eta(), egIter->energy()); + dph = L1TkElectronTrackMatchAlgo::deltaPhiClusterET(egIter, pTrk); + dr = L1TkElectronTrackMatchAlgo::deltaR(egPos, pTrk); + deta = L1TkElectronTrackMatchAlgo::deltaEta(egPos, pTrk); + } + // ------------ match EGamma and Track + void doMatch(const GlobalPoint& epos, const edm::Ptr& pTrk, double& dph, double& dr, double& deta) { + dph = L1TkElectronTrackMatchAlgo::deltaPhi(epos, pTrk); + dr = L1TkElectronTrackMatchAlgo::deltaR(epos, pTrk); + deta = L1TkElectronTrackMatchAlgo::deltaEta(epos, pTrk); + } + // --------------- calculate deltaR between Track and EGamma object + double deltaPhi(const GlobalPoint& epos, const edm::Ptr& pTrk) { + double er = epos.perp(); + double curv = pTrk->rInv(); + + double dphi_curv = (asin(er * curv / (2.0))); + double trk_phi_ecal = reco::deltaPhi(pTrk->momentum().phi(), dphi_curv); + + double dphi = reco::deltaPhi(trk_phi_ecal, epos.phi()); + return dphi; + } + // --------------- use cluster et to extrapolate tracks + double deltaPhiClusterET(l1t::EGammaBxCollection::const_iterator egIter, const edm::Ptr& pTrk) { + GlobalPoint epos = L1TkElectronTrackMatchAlgo::calorimeterPosition(egIter->phi(), egIter->eta(), egIter->energy()); + double er = epos.perp(); + double et = egIter->et(); + double pt = pTrk->momentum().perp(); + double curv = pTrk->rInv(); + + double dphi_curv = (asin(er * curv * pt / (2.0 * et))); + double trk_phi_ecal = reco::deltaPhi(pTrk->momentum().phi(), dphi_curv); + + double dphi = reco::deltaPhi(trk_phi_ecal, epos.phi()); + return dphi; + } + // --------------- calculate deltaPhi between Track and EGamma object + double deltaR(const GlobalPoint& epos, const edm::Ptr& pTrk) { + //double dPhi = fabs(reco::deltaPhi(epos.phi(), pTrk->momentum().phi())); + double dPhi = L1TkElectronTrackMatchAlgo::deltaPhi(epos, pTrk); + double dEta = deltaEta(epos, pTrk); + return sqrt(dPhi * dPhi + dEta * dEta); + } + // --------------- calculate deltaEta between Track and EGamma object + double deltaEta(const GlobalPoint& epos, const edm::Ptr& pTrk) { + double corr_eta = 999.0; + double er = epos.perp(); + double ez = epos.z(); + double z0 = pTrk->POCA().z(); + double theta = 0.0; + if (ez - z0 >= 0) + theta = atan(er / fabs(ez - z0)); + else + theta = M_PI - atan(er / fabs(ez - z0)); + corr_eta = -1.0 * log(tan(theta / 2.0)); + double deleta = (corr_eta - pTrk->momentum().eta()); + return deleta; + } + // -------------- get Calorimeter position + GlobalPoint calorimeterPosition(double phi, double eta, double e) { + double x = 0.; + double y = 0.; + double z = 0.; + double depth = 0.89 * (7.7 + log(e)); + double theta = 2 * atan(exp(-1 * eta)); + double r = 0; + if (fabs(eta) > max_eb_eta) { + double ecalZ = max_eb_z * fabs(eta) / eta; + + r = ecalZ / cos(2 * atan(exp(-1 * eta))) + depth; + x = r * cos(phi) * sin(theta); + y = r * sin(phi) * sin(theta); + z = r * cos(theta); + } else { + double zface = sqrt(cos(theta) * cos(theta) / (1 - cos(theta) * cos(theta)) * eb_rperp * eb_rperp); + r = sqrt(eb_rperp * eb_rperp + zface * zface) + depth; + x = r * cos(phi) * sin(theta); + y = r * sin(phi) * sin(theta); + z = r * cos(theta); + } + GlobalPoint pos(x, y, z); + return pos; + } + +} // namespace L1TkElectronTrackMatchAlgo diff --git a/L1Trigger/L1TTrackMatch/src/L1TkMuCorrDynamicWindows.cc b/L1Trigger/L1TTrackMatch/src/L1TkMuCorrDynamicWindows.cc new file mode 100644 index 0000000000000..082174f341a3e --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/L1TkMuCorrDynamicWindows.cc @@ -0,0 +1,408 @@ +#include "L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include "DataFormats/Math/interface/angle_units.h" + +// ROOT includes +#include "TH1.h" +#include "TH2.h" + +L1TkMuCorrDynamicWindows::L1TkMuCorrDynamicWindows(const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi) + : wdws_theta_(bounds.size() - 1, MuMatchWindow()), + wdws_phi_(bounds.size() - 1, MuMatchWindow()), + wdws_theta_S1_(bounds.size() - 1, MuMatchWindow()), + wdws_phi_S1_(bounds.size() - 1, MuMatchWindow()) { + set_safety_factor(0.5); + set_sf_initialrelax(0.0); + set_relaxation_pattern(2.0, 6.0); + set_do_relax_factor(true); + + track_qual_presel_ = true; + + nbins_ = bounds.size() - 1; + bounds_ = bounds; + + // now load in memory the TF1 fits + + for (int ib = 0; ib < nbins_; ++ib) { + std::string wdn; + std::string nml; + std::string nmh; + TF1* fl; + TF1* fh; + + // Station 2 + wdn = std::string("wdw_theta_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_theta->Get(nml.c_str()); + fh = (TF1*)fIn_theta->Get(nmh.c_str()); + if (fl == nullptr || fh == nullptr) + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; + wdws_theta_.at(ib).SetName(wdn); + wdws_theta_.at(ib).SetLower(fl); + wdws_theta_.at(ib).SetUpper(fh); + + wdn = std::string("wdw_phi_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_phi->Get(nml.c_str()); + fh = (TF1*)fIn_phi->Get(nmh.c_str()); + if (fl == nullptr || fh == nullptr) + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; + wdws_phi_.at(ib).SetName(wdn); + wdws_phi_.at(ib).SetLower(fl); + wdws_phi_.at(ib).SetUpper(fh); + } +} + +L1TkMuCorrDynamicWindows::L1TkMuCorrDynamicWindows( + const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi, TFile* fIn_theta_S1, TFile* fIn_phi_S1) + : wdws_theta_(bounds.size() - 1, MuMatchWindow()), + wdws_phi_(bounds.size() - 1, MuMatchWindow()), + wdws_theta_S1_(bounds.size() - 1, MuMatchWindow()), + wdws_phi_S1_(bounds.size() - 1, MuMatchWindow()) { + set_safety_factor(0.0); + set_sf_initialrelax(0.0); + set_relaxation_pattern(2.0, 6.0); + set_do_relax_factor(true); + + track_qual_presel_ = true; + + nbins_ = bounds.size() - 1; + bounds_ = bounds; + + // now load in memory the TF1 fits + + for (int ib = 0; ib < nbins_; ++ib) { + std::string wdn; + std::string nml; + std::string nmh; + TF1* fl; + TF1* fh; + + // Station 2 + wdn = std::string("wdw_theta_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_theta->Get(nml.c_str()); + fh = (TF1*)fIn_theta->Get(nmh.c_str()); + if (fl == nullptr || fh == nullptr) + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; + wdws_theta_.at(ib).SetName(wdn); + wdws_theta_.at(ib).SetLower(fl); + wdws_theta_.at(ib).SetUpper(fh); + + wdn = std::string("wdw_phi_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_phi->Get(nml.c_str()); + fh = (TF1*)fIn_phi->Get(nmh.c_str()); + if (fl == nullptr || fh == nullptr) + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; + wdws_phi_.at(ib).SetName(wdn); + wdws_phi_.at(ib).SetLower(fl); + wdws_phi_.at(ib).SetUpper(fh); + + // Station 1 - MW's don't have to exist for TkMuon correlator + // It is only needed for TkMuStub + wdn = std::string("wdw_theta_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_theta_S1->Get(nml.c_str()); + fh = (TF1*)fIn_theta_S1->Get(nmh.c_str()); + if (fl == nullptr || fh == nullptr) + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; + wdws_theta_S1_.at(ib).SetName(wdn); + wdws_theta_S1_.at(ib).SetLower(fl); + wdws_theta_S1_.at(ib).SetUpper(fh); + + wdn = std::string("wdw_phi_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_phi_S1->Get(nml.c_str()); + fh = (TF1*)fIn_phi_S1->Get(nmh.c_str()); + if (fl == nullptr || fh == nullptr) + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; + wdws_phi_S1_.at(ib).SetName(wdn); + wdws_phi_S1_.at(ib).SetLower(fl); + wdws_phi_S1_.at(ib).SetUpper(fh); + } +} + +int L1TkMuCorrDynamicWindows::findBin(double val) { + // not the most efficient, nor the most elegant implementation for now + if (val < bounds_.at(0)) + return 0; + if (val >= bounds_.back()) + return (nbins_ - 1); // i.e. bounds_size() -2 + + for (uint ib = 0; ib < bounds_.size() - 1; ++ib) { + if (val >= bounds_.at(ib) && val < bounds_.at(ib + 1)) + return ib; + } + + //"Something strange happened at val. + throw cms::Exception("L1TkMuCorrDynamicWindows") << "Can't find bin.\n"; + return 0; +} + +std::vector L1TkMuCorrDynamicWindows::find_match(const EMTFTrackCollection& l1mus, + const L1TTTrackCollectionType& l1trks) { + std::vector out(l1trks.size()); + for (auto l1trkit = l1trks.begin(); l1trkit != l1trks.end(); ++l1trkit) { + float trk_pt = l1trkit->momentum().perp(); + float trk_p = l1trkit->momentum().mag(); + float trk_aeta = std::abs(l1trkit->momentum().eta()); + float trk_theta = to_mpio2_pio2(eta_to_theta(l1trkit->momentum().eta())); + float trk_phi = l1trkit->momentum().phi(); + int trk_charge = (l1trkit->rInv() > 0 ? 1 : -1); + + // porting some selections from the MuonTrackCorr finder + // https://github.com/cms-l1t-offline/cmssw/blob/l1t-phase2-932-v1.6/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc#L264 + // in future, make preselections confiuguable + bool reject_trk = false; + if (trk_p < min_trk_p_) + reject_trk = true; + if (trk_aeta > max_trk_aeta_) + reject_trk = true; + if (track_qual_presel_) { + float l1tk_chi2 = l1trkit->chi2(); + int l1tk_nstubs = l1trkit->getStubRefs().size(); + if (l1tk_chi2 >= max_trk_chi2_) + reject_trk = true; + if (l1tk_nstubs < min_trk_nstubs_) + reject_trk = true; + } + + int ibin = findBin(trk_aeta); + + std::vector> matched; // dtheta, dphi, idx + // loop on muons to see which match + for (auto l1muit = l1mus.begin(); l1muit != l1mus.end(); ++l1muit) { + // match only muons in the central bx - as the track collection refers anyway to bx 0 only + if (l1muit->BX() != 0) + continue; + + // putting everything in rad + float emtf_theta = to_mpio2_pio2(eta_to_theta(l1muit->Eta())); + float emtf_phi = angle_units::operators::convertDegToRad(l1muit->Phi_glob()); + + float dtheta = std::abs(emtf_theta - trk_theta); + float dphi = reco::deltaPhi(emtf_phi, trk_phi); + float adphi = std::abs(dphi); + + double sf_l; + double sf_h; + if (do_relax_factor_) { + sf_l = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_l_, safety_factor_l_); + sf_h = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_h_, safety_factor_h_); + } else { + sf_l = safety_factor_l_; + sf_h = safety_factor_h_; + } + + if ( + // emtf_theta * trk_theta > 0 && + dtheta > (1 - sf_l) * wdws_theta_.at(ibin).bound_low(trk_pt) && + dtheta <= (1 + sf_h) * wdws_theta_.at(ibin).bound_high(trk_pt) && + adphi > (1 - sf_l) * wdws_phi_.at(ibin).bound_low(trk_pt) && + adphi <= (1 + sf_h) * wdws_phi_.at(ibin).bound_high(trk_pt) && dphi * trk_charge < 0 && // sign requirement + // rndm > 0.5 + true) + matched.emplace_back(dtheta, adphi, std::distance(l1mus.begin(), l1muit)); + } + + if (reject_trk) + matched.clear(); // quick fix - to be optimised to avoid the operations above + + if (matched.empty()) + out.at(std::distance(l1trks.begin(), l1trkit)) = -1; + else { + std::sort(matched.begin(), matched.end()); // closest in theta, then in phi + out.at(std::distance(l1trks.begin(), l1trkit)) = std::get<2>(matched.at(0)); + } + } + + // now convert out to a unique set + return make_unique_coll(l1mus.size(), l1trks, out); +} + +std::vector L1TkMuCorrDynamicWindows::find_match_stub(const EMTFHitCollection& l1mus, + const L1TTTrackCollectionType& l1trks, + const int& station, + bool requireBX0) { + std::vector out(l1trks.size()); + for (auto l1trkit = l1trks.begin(); l1trkit != l1trks.end(); ++l1trkit) { + float trk_pt = l1trkit->momentum().perp(); + float trk_p = l1trkit->momentum().mag(); + float trk_aeta = std::abs(l1trkit->momentum().eta()); + float trk_theta = to_mpio2_pio2(eta_to_theta(l1trkit->momentum().eta())); + float trk_phi = l1trkit->momentum().phi(); + int trk_charge = (l1trkit->rInv() > 0 ? 1 : -1); + + // porting some selections from the MuonTrackCorr finder + // https://github.com/cms-l1t-offline/cmssw/blob/l1t-phase2-932-v1.6/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc#L264 + // for future: make preselections confiuguable + bool reject_trk = false; + if (trk_p < min_trk_p_) + reject_trk = true; + if (trk_aeta > max_trk_aeta_) + reject_trk = true; + if (track_qual_presel_) { + float l1tk_chi2 = l1trkit->chi2(); + int l1tk_nstubs = l1trkit->getStubRefs().size(); + if (l1tk_chi2 >= max_trk_chi2_) + reject_trk = true; + if (l1tk_nstubs < min_trk_nstubs_) + reject_trk = true; + } + + int ibin = findBin(trk_aeta); + + std::vector> matched; // dtheta, dphi, idx + // loop on stubs to see which match + for (auto l1muit = l1mus.begin(); l1muit != l1mus.end(); ++l1muit) { + if (!(l1muit->Is_CSC() || l1muit->Is_RPC())) + continue; + + int hit_station = l1muit->Station(); + // match only stubs in the central bx - as the track collection refers anyway to bx 0 only + if (requireBX0 && l1muit->BX() != 0) + continue; + + // allow only track matching to stubs from the given station, station= 1,2,3,4 + if (station < 5 && hit_station != station) + continue; + // in case of station=12 allow track matching to stubs from either station 1 or 2. + else if (station == 12 && hit_station > 2) // good for tkMuStub12 + continue; + // in case of station=123 allow track matching to stubs from either station 1, 2, or 3. + else if (station == 123 && hit_station > 3) // good for tkMuStub123 + continue; + // in case of station=1234 allow track matching to stubs from either station 1, 2, 3, or 4. + else if (station == 1234 && hit_station > 4) // good for tkMuStub1234 + continue; + + float emtf_theta = to_mpio2_pio2(eta_to_theta(l1muit->Eta_sim())); + float emtf_phi = angle_units::operators::convertDegToRad(l1muit->Phi_sim()); + + float dtheta = std::abs(emtf_theta - trk_theta); + float dphi = reco::deltaPhi(emtf_phi, trk_phi); + float adphi = std::abs(dphi); + + double sf_l; + double sf_h; + if (do_relax_factor_) { + sf_l = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_l_, safety_factor_l_); + sf_h = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_h_, safety_factor_h_); + } else { + sf_l = safety_factor_l_; + sf_h = safety_factor_h_; + } + + if (hit_station == 1 && + //if hit in station 1 use these matching windows for checking + + dtheta > (1 - sf_l) * wdws_theta_S1_.at(ibin).bound_low(trk_pt) && + dtheta <= (1 + sf_h) * wdws_theta_S1_.at(ibin).bound_high(trk_pt) && + adphi > (1 - sf_l) * wdws_phi_S1_.at(ibin).bound_low(trk_pt) && + adphi <= (1 + sf_h) * wdws_phi_S1_.at(ibin).bound_high(trk_pt) && + dphi * trk_charge < 0 && // sign requirement + true) + matched.emplace_back(dtheta, adphi, std::distance(l1mus.begin(), l1muit)); + + if (hit_station == 2 && dtheta > (1 - sf_l) * wdws_theta_.at(ibin).bound_low(trk_pt) && + dtheta <= (1 + sf_h) * wdws_theta_.at(ibin).bound_high(trk_pt) && + adphi > (1 - sf_l) * wdws_phi_.at(ibin).bound_low(trk_pt) && + adphi <= (1 + sf_h) * wdws_phi_.at(ibin).bound_high(trk_pt) && dphi * trk_charge < 0 && // sign requirement + // rndm > 0.5 + true) + matched.emplace_back(dtheta, adphi, std::distance(l1mus.begin(), l1muit)); + } + + if (reject_trk) + matched.clear(); // quick fix - to be optimised to avoid the operations above + + if (matched.empty()) + out.at(std::distance(l1trks.begin(), l1trkit)) = -1; + else { + std::sort(matched.begin(), matched.end()); // closest in theta, then in phi + out.at(std::distance(l1trks.begin(), l1trkit)) = std::get<2>(matched.at(0)); + } + } + + // return out; + + // now convert out to a unique set + auto unique_out = make_unique_coll(l1mus.size(), l1trks, out); + + return unique_out; +} + +std::vector L1TkMuCorrDynamicWindows::make_unique_coll(const unsigned int& l1musSize, + const L1TTTrackCollectionType& l1trks, + const std::vector& matches) { + std::vector out(matches.size(), -1); + + std::vector> macthed_to_emtf(l1musSize, + std::vector(0)); // one vector of matched trk idx per EMTF + + for (unsigned int itrack = 0; itrack < matches.size(); ++itrack) { + int iemtf = matches.at(itrack); + if (iemtf < 0) + continue; + macthed_to_emtf.at(iemtf).push_back(itrack); + } + + std::function track_less_than_proto = + [](int idx1, int idx2, const L1TTTrackCollectionType& l1trkcoll, int nTrackParams) { + float pt1 = l1trkcoll.at(idx1).momentum().perp(); + float pt2 = l1trkcoll.at(idx2).momentum().perp(); + return (pt1 < pt2); + }; + + // // and binds to accept only 2 params + std::function track_less_than = + std::bind(track_less_than_proto, std::placeholders::_1, std::placeholders::_2, l1trks, nTrkPars_); + + for (unsigned int iemtf = 0; iemtf < macthed_to_emtf.size(); ++iemtf) { + std::vector& thisv = macthed_to_emtf.at(iemtf); + if (thisv.empty()) + continue; + + std::sort(thisv.begin(), thisv.end(), track_less_than); + + // copy to the output + int best_trk = thisv.back(); + out.at(best_trk) = iemtf; + } + + return out; +} + +std::vector L1TkMuCorrDynamicWindows::prepare_corr_bounds(const string& fname, const string& hname) { + // find the boundaries of the match windoww + TFile* fIn = TFile::Open(fname.c_str()); + if (fIn == nullptr) { + throw cms::Exception("L1TkMuMantra") << "Can't find file " << fname << " to derive bounds.\n"; + } + TH2* h_test = (TH2*)fIn->Get(hname.c_str()); + if (h_test == nullptr) { + throw cms::Exception("L1TkMuCorrDynamicWindows") + << "Can't find histo " << hname << " in file " << fname << " to derive bounds.\n"; + } + + int nbds = h_test->GetNbinsY() + 1; + vector bounds(nbds); + for (int ib = 0; ib < nbds; ++ib) { + bounds.at(ib) = h_test->GetYaxis()->GetBinLowEdge(ib + 1); + } + fIn->Close(); + return bounds; +} diff --git a/L1Trigger/L1TTrackMatch/src/L1TkMuMantra.cc b/L1Trigger/L1TTrackMatch/src/L1TkMuMantra.cc new file mode 100644 index 0000000000000..b26e25af5ab2f --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/L1TkMuMantra.cc @@ -0,0 +1,220 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +#include "TH2.h" +#include "TFile.h" + +using namespace L1TkMuMantraDF; + +L1TkMuMantra::L1TkMuMantra(const std::vector& bounds, + TFile* fIn_theta, + TFile* fIn_phi, + std::string name = "mantra") + : wdws_theta_(bounds.size() - 1, MuMatchWindow()), wdws_phi_(bounds.size() - 1, MuMatchWindow()) { + name_ = name; + + safety_factor_l_ = 0.0; + safety_factor_h_ = 0.0; + + sort_type_ = kMaxPt; + + // copy boundaries + nbins_ = bounds.size() - 1; + bounds_ = bounds; + + // now load in memory the TF1 fits + + for (int ib = 0; ib < nbins_; ++ib) { + std::string wdn; + std::string nml; + std::string nmc; + std::string nmh; + TF1* fl; + TF1* fc; + TF1* fh; + + wdn = name_ + std::string("_wdw_theta_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmc = std::string("fit_cent_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + + fl = (TF1*)fIn_theta->Get(nml.c_str()); + fc = (TF1*)fIn_theta->Get(nmc.c_str()); + fh = (TF1*)fIn_theta->Get(nmh.c_str()); + if (fl == nullptr || fc == nullptr || fh == nullptr) { + if (verbosity_ > 0) { + LogTrace("L1TkMuMantra") << "... fit theta low : " << fl << std::endl; + LogTrace("L1TkMuMantra") << "... fit theta cent : " << fc << std::endl; + LogTrace("L1TkMuMantra") << "... fit theta high : " << fh << std::endl; + } + throw cms::Exception("L1TkMuMantra") << "TF1 named " << nml << " or " << nmc << " or " << nmh + << " not found in file " << fIn_theta->GetName() << ".\n"; + } + wdws_theta_.at(ib).SetName(wdn); + wdws_theta_.at(ib).SetLower(fl); + wdws_theta_.at(ib).SetCentral(fc); + wdws_theta_.at(ib).SetUpper(fh); + + wdn = name_ + std::string("_wdw_phi_") + std::to_string(ib + 1); + nml = std::string("fit_low_") + std::to_string(ib + 1); + nmc = std::string("fit_cent_") + std::to_string(ib + 1); + nmh = std::string("fit_high_") + std::to_string(ib + 1); + fl = (TF1*)fIn_phi->Get(nml.c_str()); + fc = (TF1*)fIn_phi->Get(nmc.c_str()); + fh = (TF1*)fIn_phi->Get(nmh.c_str()); + if (fl == nullptr || fc == nullptr || fh == nullptr) { + if (verbosity_ > 0) { + LogTrace("L1TkMuMantra") << "... fit phi low : " << fl << std::endl; + LogTrace("L1TkMuMantra") << "... fit phi cent : " << fc << std::endl; + LogTrace("L1TkMuMantra") << "... fit phi high : " << fh << std::endl; + } + throw cms::Exception("L1TkMuMantra") << "TF1 named " << nml << " or " << nmc << " or " << nmh + << " not found in file " << fIn_theta->GetName() << ".\n"; + } + wdws_phi_.at(ib).SetName(wdn); + wdws_phi_.at(ib).SetLower(fl); + wdws_phi_.at(ib).SetCentral(fc); + wdws_phi_.at(ib).SetUpper(fh); + } +} + +int L1TkMuMantra::findBin(double val) { + // FIXME: not the most efficient, nor the most elegant implementation for now + if (val < bounds_.at(0)) + return 0; + if (val >= bounds_.back()) + return (nbins_ - 1); // i.e. bounds_size() -2 + + for (uint ib = 0; ib < bounds_.size() - 1; ++ib) { + if (val >= bounds_.at(ib) && val < bounds_.at(ib + 1)) + return ib; + } + + if (verbosity_ > 0) + LogTrace("L1TkMuMantra") << "Something strange happened at val " << val << std::endl; + return 0; +} + +void L1TkMuMantra::test(double eta, double pt) { + int ibin = findBin(eta); + + LogTrace("L1TkMuMantra") << " ---- eta : " << eta << " pt: " << pt << std::endl; + LogTrace("L1TkMuMantra") << " ---- bin " << ibin << std::endl; + LogTrace("L1TkMuMantra") << " ---- " + << "- low_phi : " << wdws_phi_.at(ibin).bound_low(pt) + << "- cent_phi : " << wdws_phi_.at(ibin).bound_cent(pt) + << "- high_phi : " << wdws_phi_.at(ibin).bound_high(pt) << std::endl; + + LogTrace("L1TkMuMantra") << " ---- " + << "- low_theta : " << wdws_theta_.at(ibin).bound_low(pt) + << "- cent_theta : " << wdws_theta_.at(ibin).bound_cent(pt) + << "- high_theta : " << wdws_theta_.at(ibin).bound_high(pt) << std::endl; + + return; +} + +std::vector L1TkMuMantra::find_match(const std::vector& tracks, const std::vector& muons) { + std::vector result(muons.size(), -1); // init all TkMu to index -1 + for (uint imu = 0; imu < muons.size(); ++imu) { + muon_df mu = muons.at(imu); + std::vector> matched_trks; // sort_par, idx + for (uint itrk = 0; itrk < tracks.size(); ++itrk) { + // preselection of tracks + track_df trk = tracks.at(itrk); + if (trk.chi2 >= max_chi2) + continue; // require trk.chi2 < max_chi2 + if (trk.nstubs < min_nstubs) + continue; // require trk.nstubs >= min_nstubs + + double dphi_charge = reco::deltaPhi(trk.phi, mu.phi) * trk.charge; + // sign from theta, to avoid division by 0 + double dtheta_endc = (mu.theta - trk.theta) * sign(mu.theta); + if (sign(mu.theta) != sign(trk.theta)) { + // crossing the barrel -> remove 180 deg to the theta of the neg candidate to avoid jumps at eta = 0 + dtheta_endc -= TMath::Pi(); + } + + // lookup the values + int ibin = findBin(std::abs(trk.eta)); + + double phi_low = wdws_phi_.at(ibin).bound_low(trk.pt); + double phi_cent = wdws_phi_.at(ibin).bound_cent(trk.pt); + double phi_high = wdws_phi_.at(ibin).bound_high(trk.pt); + relax_windows(phi_low, phi_cent, phi_high); // apply the safety factor + bool in_phi = (dphi_charge > phi_low && dphi_charge < phi_high); + + double theta_low = wdws_theta_.at(ibin).bound_low(trk.pt); + double theta_cent = wdws_theta_.at(ibin).bound_cent(trk.pt); + double theta_high = wdws_theta_.at(ibin).bound_high(trk.pt); + relax_windows(theta_low, theta_cent, theta_high); // apply the safety factor + bool in_theta = (dtheta_endc > theta_low && dtheta_endc < theta_high); + + if (in_phi && in_theta) { + double sort_par = 99999; + if (sort_type_ == kMaxPt) + sort_par = trk.pt; + else if (sort_type_ == kMinDeltaPt) { + // trk.pt should always be > 0, but put this protection just in case + sort_par = (trk.pt > 0 ? std::abs(1. - (mu.pt / trk.pt)) : 0); + } + matched_trks.emplace_back(sort_par, itrk); + } + } + + // choose out of the matched tracks the best one + if (!matched_trks.empty()) { + sort(matched_trks.begin(), matched_trks.end()); + int ibest = 99999; + if (sort_type_ == kMaxPt) + ibest = matched_trks.rbegin()->second; // sorted low to high -> take last for highest pT (rbegin) + else if (sort_type_ == kMinDeltaPt) + ibest = matched_trks.begin()->second; // sorted low to high -> take first for min pT distance (begin) + result.at(imu) = ibest; + } + } + + return result; +} + +void L1TkMuMantra::relax_windows(double& low, double cent, double& high) { + double delta_high = high - cent; + double delta_low = cent - low; + + high = high + safety_factor_h_ * delta_high; + low = low - safety_factor_l_ * delta_low; + + return; +} + +void L1TkMuMantra::setArbitrationType(std::string type) { + if (verbosity_ > 0) + LogTrace("L1TkMuMantra") << "L1TkMuMantra : setting arbitration type to " << type << std::endl; + if (type == "MaxPt") + sort_type_ = kMaxPt; + else if (type == "MinDeltaPt") + sort_type_ = kMinDeltaPt; + else + throw cms::Exception("L1TkMuMantra") << "setArbitrationType : cannot understand the arbitration type passed.\n"; +} + +std::vector L1TkMuMantra::prepare_corr_bounds(std::string fname, std::string hname) { + // find the boundaries of the match windoww + TFile* fIn = TFile::Open(fname.c_str()); + if (fIn == nullptr) { + throw cms::Exception("L1TkMuMantra") << "Can't find file " << fname << " to derive bounds.\n"; + } + TH2* h_test = (TH2*)fIn->Get(hname.c_str()); + if (h_test == nullptr) { + throw cms::Exception("L1TkMuMantra") << "Can't find histo " << hname << " in file " << fname + << " to derive bounds.\n"; + } + + int nbds = h_test->GetNbinsY() + 1; + std::vector bounds(nbds); + for (int ib = 0; ib < nbds; ++ib) { + bounds.at(ib) = h_test->GetYaxis()->GetBinLowEdge(ib + 1); + } + fIn->Close(); + return bounds; +} diff --git a/L1Trigger/L1TTrackMatch/src/MuMatchWindow.cc b/L1Trigger/L1TTrackMatch/src/MuMatchWindow.cc new file mode 100644 index 0000000000000..54b527c50d141 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/MuMatchWindow.cc @@ -0,0 +1,40 @@ +#include "L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h" + +MuMatchWindow::MuMatchWindow() { name_ = ""; } + +MuMatchWindow::MuMatchWindow(std::string name) { SetName(name); } + +MuMatchWindow::~MuMatchWindow() {} + +void MuMatchWindow::SetLower(std::string formula) { + TF1 f("tmp", formula.c_str(), 0, 1000); + SetLower(&f); +} + +void MuMatchWindow::SetCentral(std::string formula) { + TF1 f("tmp", formula.c_str(), 0, 1000); + SetCentral(&f); +} + +void MuMatchWindow::SetUpper(std::string formula) { + TF1 f("tmp", formula.c_str(), 0, 1000); + SetUpper(&f); +} + +void MuMatchWindow::SetLower(TF1* formula) { + if (fLow_) + throw std::runtime_error("Cannot initialize twice fLow_"); + fLow_ = std::shared_ptr((TF1*)formula->Clone((name_ + std::string("low")).c_str())); +} + +void MuMatchWindow::SetCentral(TF1* formula) { + if (fCent_) + throw std::runtime_error("Cannot initialize twice fCent_"); + fCent_ = std::shared_ptr((TF1*)formula->Clone((name_ + std::string("cent")).c_str())); +} + +void MuMatchWindow::SetUpper(TF1* formula) { + if (fHigh_) + throw std::runtime_error("Cannot initialize twice fHigh_"); + fHigh_ = std::shared_ptr((TF1*)formula->Clone((name_ + std::string("high")).c_str())); +} diff --git a/L1Trigger/L1TTrackMatch/src/pTFrom2Stubs.cc b/L1Trigger/L1TTrackMatch/src/pTFrom2Stubs.cc new file mode 100644 index 0000000000000..fee8fbf978cc7 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/pTFrom2Stubs.cc @@ -0,0 +1,77 @@ +#include "L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include "Geometry/CommonTopologies/interface/Topology.h" +#include +#include +#include +#include + +static constexpr float local_c_light = 0.00299792; +static constexpr float B_field = 3.8; + +namespace pTFrom2Stubs { + + //==================== + float rInvFrom2(std::vector >::const_iterator trk, + const TrackerGeometry* tkGeometry) { + //vector of R, r and phi for each stub + std::vector > riPhiStubs(0); + //get stub reference + std::vector >, TTStub > > + vecStubRefs = trk->getStubRefs(); + + //loop over L1Track's stubs + int rsize = vecStubRefs.size(); + for (int j = 0; j < rsize; ++j) { + edm::Ref >, TTStub > stubRef = + vecStubRefs.at(j); + const TTStub* stub = &(*stubRef); + MeasurementPoint localPos = stub->clusterRef(0)->findAverageLocalCoordinates(); + + DetId detid = stub->clusterRef(0)->getDetId(); + + if (detid.det() != DetId::Detector::Tracker) + continue; + if (detid.subdetId() != StripSubdetector::TOB && detid.subdetId() != StripSubdetector::TID) + continue; + const GeomDet* geomDet = tkGeometry->idToDet(detid); + if (geomDet) { + const GeomDetUnit* gDetUnit = tkGeometry->idToDetUnit(detid); + GlobalPoint stubPosition = geomDet->surface().toGlobal(gDetUnit->topology().localPosition(localPos)); + + std::vector tmp(0); + float Rad = sqrt(stubPosition.x() * stubPosition.x() + stubPosition.y() * stubPosition.y() + stubPosition.z() + + stubPosition.z()); + float r_i = sqrt(stubPosition.x() * stubPosition.x() + stubPosition.y() * stubPosition.y()); + float phi_i = stubPosition.phi(); + + tmp.push_back(Rad); + tmp.push_back(r_i); + tmp.push_back(phi_i); + + riPhiStubs.push_back(tmp); + } + } + + std::sort(riPhiStubs.begin(), riPhiStubs.end()); + //now calculate the curvature from first 2 stubs + float nr1 = (riPhiStubs[0])[1]; + float nphi1 = (riPhiStubs[0])[2]; + + float nr2 = (riPhiStubs[1])[1]; + float nphi2 = (riPhiStubs[1])[2]; + + float dPhi = reco::deltaPhi(nphi1, nphi2); + + float ndist = sqrt(nr2 * nr2 + nr1 * nr1 - 2 * nr1 * nr2 * cos(dPhi)); + + float curvature = 2 * sin(dPhi) / ndist; + return curvature; + } + //==================== + float pTFrom2(std::vector >::const_iterator trk, const TrackerGeometry* tkGeometry) { + float rinv = rInvFrom2(trk, tkGeometry); + return std::abs(local_c_light * B_field / rinv); + } + //==================== +} // namespace pTFrom2Stubs diff --git a/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml new file mode 100644 index 0000000000000..80c5ef5582689 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h new file mode 100644 index 0000000000000..28f804be48937 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h @@ -0,0 +1,22 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_BitwisePFAlgo_h +#define L1Trigger_Phase2L1ParticleFlow_BitwisePFAlgo_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" + +struct pfalgo_config; + +namespace l1tpf_impl { + class BitwisePFAlgo : public PFAlgoBase { + public: + BitwisePFAlgo(const edm::ParameterSet&); + ~BitwisePFAlgo() override; + void runPF(Region& r) const override; + + protected: + enum class AlgoChoice { algo3, algo2hgc } algo_; + std::shared_ptr config_; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h b/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h new file mode 100644 index 0000000000000..3a61bf2ee8ecd --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h @@ -0,0 +1,44 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_CoeFile_h +#define L1Trigger_Phase2L1ParticleFlow_CoeFile_h + +// system include files +#include +#include +#include +#include +#include +#include + +// user include files +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" + +namespace l1tpf_impl { + class COEFile { + public: + COEFile(const edm::ParameterSet&); + ~COEFile(); + + void close() { fclose(file); } + template + bool getBit(T value, unsigned bit) { + return (value >> bit) & 1; + } + bool is_open() { return (file != nullptr); } + void writeHeaderToFile(); + void writeTracksToFile(const std::vector& regions, bool print = false); + + protected: + FILE* file; + std::string coeFileName, bset_string_; + unsigned int ntracksmax, phiSlices; + static constexpr unsigned int tracksize = 96; + boost::dynamic_bitset<> bset_; + const std::vector track_word_block_sizes = {14, 1, 12, 16, 12, 13, 4, 3, 7, 14}; + int debug_; + }; +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h b/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h new file mode 100644 index 0000000000000..64f0a663b14c2 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h @@ -0,0 +1,297 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_CALOCLUSTERER_H +#define L1Trigger_Phase2L1ParticleFlow_CALOCLUSTERER_H +/** + * Classes for calorimetric re-clustering + * */ + +// fwd declarations +namespace edm { + class ParameterSet; +} + +// real includes +#include +#include +#include +#include +#include +#include "DataFormats/L1TParticleFlow/interface/PFCluster.h" +#include "DataFormats/Common/interface/OrphanHandle.h" + +namespace l1tpf_calo { + class Grid { + public: + virtual ~Grid() {} + unsigned int size() const { return ncells_; } + virtual int find_cell(float eta, float phi) const = 0; + int neighbour(int icell, unsigned int idx) const { return neighbours_[icell][idx]; } + float eta(int icell) const { return eta_[icell]; } + float phi(int icell) const { return phi_[icell]; } + float etaWidth(int icell) const { return etaWidth_[icell]; } + float phiWidth(int icell) const { return phiWidth_[icell]; } + int ieta(int icell) const { return ieta_[icell]; } + int iphi(int icell) const { return iphi_[icell]; } + + protected: + Grid(unsigned int size) + : ncells_(size), + eta_(size), + etaWidth_(size), + phi_(size), + phiWidth_(size), + ieta_(size), + iphi_(size), + neighbours_(size) {} + unsigned int ncells_; + std::vector eta_, etaWidth_, phi_, phiWidth_; + std::vector ieta_, iphi_; + std::vector> neighbours_; // indices of the neigbours, -1 = none + }; + + class Phase1GridBase : public Grid { + public: + Phase1GridBase(int nEta, int nPhi, int ietaCoarse, int ietaVeryCoarse, const float *towerEtas); + + int find_cell(float eta, float phi) const override; + int ifind_cell(int ieta, int iphi) const { return cell_map_[(ieta + nEta_) + 2 * nEta_ * (iphi - 1)]; } + + protected: + const int nEta_, nPhi_, ietaCoarse_, ietaVeryCoarse_; + const float *towerEtas_; + std::vector cell_map_; + // valid ieta, iphi (does not check for outside bounds, only for non-existence of ieta=0, iphi=0, and coarser towers at high eta) + bool valid_ieta_iphi(int ieta, int iphi) const { + if (ieta == 0 || iphi == 0) + return false; + if (std::abs(ieta) >= ietaVeryCoarse_ && (iphi % 4 != 1)) + return false; + if (std::abs(ieta) >= ietaCoarse_ && (iphi % 2 != 1)) + return false; + return true; + } + // move by +/-1 around a cell; return icell or -1 if not available + int imove(int ieta, int iphi, int deta, int dphi); + }; + + class Phase1Grid : public Phase1GridBase { + public: + Phase1Grid() + : Phase1GridBase(phase1_nEta_, phase1_nPhi_, phase1_ietaCoarse_, phase1_ietaVeryCoarse_, phase1_towerEtas_) {} + + protected: + static const int phase1_nEta_ = 41, phase1_nPhi_ = 72, phase1_ietaCoarse_ = 29, phase1_ietaVeryCoarse_ = 40; + static const float phase1_towerEtas_[phase1_nEta_]; + }; + class Phase2Grid : public Phase1GridBase { + public: + Phase2Grid() + : Phase1GridBase(phase2_nEta_, phase2_nPhi_, phase2_ietaCoarse_, phase2_ietaVeryCoarse_, phase2_towerEtas_) {} + + protected: + static const int phase2_nEta_ = 48, phase2_nPhi_ = 72, phase2_ietaCoarse_ = 36, phase2_ietaVeryCoarse_ = 47; + static const float phase2_towerEtas_[phase2_nEta_]; + }; + + template + class GridData { + public: + GridData() : grid_(nullptr), data_(), empty_() {} + GridData(const Grid &grid) : grid_(&grid), data_(grid.size()), empty_() {} + + T &operator()(float eta, float phi) { return data_[grid_->find_cell(eta, phi)]; } + const T &operator()(float eta, float phi) const { return data_[grid_->find_cell(eta, phi)]; } + + const Grid &grid() const { return *grid_; } + + unsigned int size() const { return data_.size(); } + + float eta(int icell) const { return grid().eta(icell); } + float phi(int icell) const { return grid().phi(icell); } + int ieta(int icell) const { return grid().ieta(icell); } + int iphi(int icell) const { return grid().iphi(icell); } + + T &operator[](int icell) { return data_[icell]; } + const T &operator[](int icell) const { return data_[icell]; } + + const T &neigh(int icell, unsigned int idx) const { + int ineigh = grid_->neighbour(icell, idx); + return (ineigh < 0 ? empty_ : data_[ineigh]); + } + + GridData &operator=(const GridData &other) { + assert(grid_ == other.grid_); + data_ = other.data_; + return *this; + } + GridData &operator+=(const GridData &other) { + assert(grid_ == other.grid_); + for (unsigned int i = 0, n = data_.size(); i < n; ++i) { + data_[i] += other.data_[i]; + } + return *this; + } + + // always defined + void fill(const T &val) { std::fill(data_.begin(), data_.end(), val); } + void zero() { fill(T()); } + + // defined only if T has a 'clear' method + void clear() { + for (T &t : data_) + t.clear(); + } + + private: + const Grid *grid_; + std::vector data_; + const T empty_; + }; + typedef GridData EtGrid; + typedef GridData IndexGrid; + + struct PreCluster { + PreCluster() : ptLocalMax(0), ptOverNeighLocalMaxSum(0) {} + float ptLocalMax; // pt if it's a local max, zero otherwise + float ptOverNeighLocalMaxSum; // pt / (sum of ptLocalMax of neighbours); zero if no neighbours + void clear() { ptLocalMax = ptOverNeighLocalMaxSum = 0; } + }; + typedef GridData PreClusterGrid; + + struct Cluster { + Cluster() : et(0), eta(0), phi(0) {} + float et, eta, phi; + std::vector> constituents; + void clear() { + et = eta = phi = 0; + constituents.clear(); + } + }; + + struct CombinedCluster : public Cluster { + float ecal_et, hcal_et; + void clear() { + Cluster::clear(); + ecal_et = hcal_et = 0; + } + }; + + const Grid *getGrid(const std::string &type); + + class SingleCaloClusterer { + public: + SingleCaloClusterer(const edm::ParameterSet &pset); + ~SingleCaloClusterer(); + void clear(); + void add(const reco::Candidate &c) { add(c.pt(), c.eta(), c.phi()); } + void add(float pt, float eta, float phi) { rawet_(eta, phi) += pt; } + void run(); + + /// possibly grow clusters by adding unclustered energy on the sides + // note: there can be some double-counting as the same unclustered energy can go into more clusters + void grow(); + + const EtGrid &raw() const { return rawet_; } + const IndexGrid &indexGrid() const { return clusterIndex_; } + const std::vector &clusters() const { return clusters_; } + const Cluster &cluster(int i) const { + return (i == -1 || clusterIndex_[i] == -1) ? nullCluster_ : clusters_[clusterIndex_[i]]; + } + + /// non-const access to the energy: be careful to use it only before 'run()' + EtGrid &raw() { return rawet_; } + + // for the moment, generic interface that takes a cluster and returns the corrected pt + template + void correct(const Corrector &corrector) { + for (Cluster &c : clusters_) { + c.et = corrector(c); + } + } + + std::unique_ptr fetchCells(bool unclusteredOnly = false, float ptMin = 0.) const; + + std::unique_ptr fetch(float ptMin = 0.) const; + std::unique_ptr fetch(const edm::OrphanHandle &cells, + float ptMin = 0.) const; + + private: + enum class EnergyShareAlgo { + Fractions, /* each local maximum neighbour takes a share proportional to its value */ + None, /* each local maximum neighbour takes all the value (double counting!) */ + Greedy, /* assing cell to the highest local maximum neighbour */ + Crude + }; /* if there's more than one local maximum neighbour, they all take half of the value (no fp division) */ + const Grid *grid_; + EtGrid rawet_, unclustered_; + PreClusterGrid precluster_; + IndexGrid clusterIndex_, cellKey_; + std::vector clusters_; + const Cluster nullCluster_; + float zsEt_, seedEt_, minClusterEt_, minEtToGrow_; + EnergyShareAlgo energyShareAlgo_; + bool energyWeightedPosition_; // do the energy-weighted cluster position instead of the cell center + }; + + class SimpleCaloLinkerBase { + public: + SimpleCaloLinkerBase(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal); + virtual ~SimpleCaloLinkerBase(); + virtual void clear() { clearBase(); } + virtual void run() = 0; + void clearBase() { + clusters_.clear(); + clusterIndex_.fill(-1); + } + + // for the moment, generic interface that takes a cluster and returns the corrected pt + template + void correct(const Corrector &corrector) { + for (CombinedCluster &c : clusters_) { + c.et = corrector(c); + } + } + + std::unique_ptr fetch() const; + std::unique_ptr fetch(const edm::OrphanHandle &ecal, + const edm::OrphanHandle &hcal) const; + + protected: + const Grid *grid_; + const SingleCaloClusterer &ecal_, &hcal_; + IndexGrid clusterIndex_; + std::vector clusters_; + float hoeCut_, minPhotonEt_, minHadronRawEt_, minHadronEt_; + bool noEmInHGC_; + }; + + class SimpleCaloLinker : public SimpleCaloLinkerBase { + public: + SimpleCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal); + ~SimpleCaloLinker() override; + void clear() override; + void run() override; + + protected: + PreClusterGrid ecalToHCal_; + }; + class FlatCaloLinker : public SimpleCaloLinkerBase { + public: + FlatCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal); + ~FlatCaloLinker() override; + void clear() override; + void run() override; + + protected: + SingleCaloClusterer combClusterer_; + }; + + // makes a calo linker (pointer will be owned by the callee) + std::unique_ptr makeCaloLinker(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal); + +} // namespace l1tpf_calo + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h new file mode 100644 index 0000000000000..4de6832b8806b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h @@ -0,0 +1,259 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_H +#define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_H + +#if defined(__GXX_EXPERIMENTAL_CXX0X__) or defined(CMSSW) +#include +#include +#define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE +#else +#include +#endif + +namespace l1t { + class PFTrack; + class PFCluster; + class PFCandidate; + class Muon; +} // namespace l1t + +// the serialization may be hidden if needed +#include +#include + +namespace l1tpf_impl { + + struct CaloCluster { + int16_t hwPt; + int16_t hwEmPt; + int16_t hwPtErr; + int16_t hwEta; + int16_t hwPhi; + uint16_t hwFlags; + bool isEM, used; + const l1t::PFCluster *src; + + // sorting + bool operator<(const CaloCluster &other) const { return hwPt > other.hwPt; } + +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + static constexpr float PT_SCALE = 4.0; // quantize in units of 0.25 GeV (can be changed) + static constexpr float ETAPHI_FACTOR = 4; // size of an ecal crystal in phi in integer units (our choice) + static constexpr float ETAPHI_SCALE = + ETAPHI_FACTOR * + (180. / M_PI); // M_PI/180 is the size of an ECal crystal; we make a grid that is 4 times that size + static constexpr int16_t PHI_WRAP = 360 * ETAPHI_FACTOR; // what is 3.14 in integer + + static int16_t ptToInt16(float pt) { // avoid overflows + return std::min(round(pt * CaloCluster::PT_SCALE), std::numeric_limits::max()); + } + + // filling from floating point + void fill(float pt, + float emPt, + float ptErr, + float eta, + float phi, + bool em, + unsigned int flags, + const l1t::PFCluster *source = nullptr) { + hwPt = CaloCluster::ptToInt16(pt); + hwEmPt = CaloCluster::ptToInt16(emPt); + hwPtErr = CaloCluster::ptToInt16(ptErr); + hwEta = round(eta * CaloCluster::ETAPHI_SCALE); + hwPhi = int16_t(round(phi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP; + isEM = em; + used = false; + hwFlags = flags; + src = source; + } + + float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } + float floatEmPt() const { return float(hwEmPt) / CaloCluster::PT_SCALE; } + float floatPtErr() const { return float(hwPtErr) / CaloCluster::PT_SCALE; } + static float minFloatPt() { return float(1.0) / CaloCluster::PT_SCALE; } + float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } + float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } + void setFloatPt(float pt) { hwPt = round(pt * CaloCluster::PT_SCALE); } + void setFloatEmPt(float emPt) { hwEmPt = round(emPt * CaloCluster::PT_SCALE); } +#endif + }; + + // https://twiki.cern.ch/twiki/bin/view/CMS/L1TriggerPhase2InterfaceSpecifications + struct InputTrack { + uint16_t hwInvpt; + int32_t hwVtxEta; + int32_t hwVtxPhi; + bool hwCharge; + int16_t hwZ0; + uint16_t hwChi2, hwStubs; + uint16_t hwFlags; + const l1t::PFTrack *src; + +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + static constexpr float INVPT_SCALE = 2E4; // 1%/pt @ 100 GeV is 2 bits + static constexpr float VTX_PHI_SCALE = 1 / 1.6E-3; // 5 micro rad is 2 bits + static constexpr float VTX_ETA_SCALE = 1 / 1E-4; // no idea, but assume it's somewhat worse than phi + static constexpr float Z0_SCALE = 20; // 1mm is 2 bits + static constexpr int32_t VTX_ETA_1p3 = 1.3 * InputTrack::VTX_ETA_SCALE; + + // filling from floating point + void fillInput( + float pt, float eta, float phi, int charge, float dz, unsigned int flags, const l1t::PFTrack *source = nullptr) { + hwInvpt = std::min(round(1 / pt * InputTrack::INVPT_SCALE), std::numeric_limits::max()); + hwVtxEta = round(eta * InputTrack::VTX_ETA_SCALE); + hwVtxPhi = round(phi * InputTrack::VTX_PHI_SCALE); + hwCharge = (charge > 0); + hwZ0 = round(dz * InputTrack::Z0_SCALE); + hwFlags = flags; + src = source; + } + + float floatVtxPt() const { return 1 / (float(hwInvpt) / InputTrack::INVPT_SCALE); } + float floatVtxEta() const { return float(hwVtxEta) / InputTrack::VTX_ETA_SCALE; } + float floatVtxPhi() const { return float(hwVtxPhi) / InputTrack::VTX_PHI_SCALE; } + float floatDZ() const { return float(hwZ0) / InputTrack::Z0_SCALE; } + int intCharge() const { return hwCharge ? +1 : -1; } +#endif + }; + + struct PropagatedTrack : public InputTrack { + int16_t hwPt; + int16_t hwPtErr; + int16_t hwCaloPtErr; + int16_t hwEta; // at calo + int16_t hwPhi; // at calo + bool muonLink; + bool used; // note: this flag is not used in the default PF, but is used in alternative algos + bool fromPV; + + // sorting + bool operator<(const PropagatedTrack &other) const { return hwPt > other.hwPt; } + +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + void fillPropagated( + float pt, float ptErr, float caloPtErr, float caloEta, float caloPhi, unsigned int quality, bool isMuon) { + hwPt = CaloCluster::ptToInt16(pt); + hwPtErr = CaloCluster::ptToInt16(ptErr); + hwCaloPtErr = CaloCluster::ptToInt16(caloPtErr); + // saturation protection + if (hwPt == std::numeric_limits::max()) { + hwCaloPtErr = hwPt / 4; + } + hwEta = round(caloEta * CaloCluster::ETAPHI_SCALE); + hwPhi = int16_t(round(caloPhi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP; + muonLink = isMuon; + used = false; + } + + float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } + float floatPtErr() const { return float(hwPtErr) / CaloCluster::PT_SCALE; } + float floatCaloPtErr() const { return float(hwCaloPtErr) / CaloCluster::PT_SCALE; } + float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } + float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } +#endif + }; + + struct Muon { + int16_t hwPt; + int16_t hwEta; // at calo + int16_t hwPhi; // at calo + uint16_t hwFlags; + bool hwCharge; + const l1t::Muon *src; + + // sorting + bool operator<(const Muon &other) const { return hwPt > other.hwPt; } + +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + void fill(float pt, float eta, float phi, int charge, unsigned int flags, const l1t::Muon *source = nullptr) { + // we assume we use the same discrete ieta, iphi grid for all particles + hwPt = round(pt * CaloCluster::PT_SCALE); + hwEta = round(eta * CaloCluster::ETAPHI_SCALE); + hwPhi = int16_t(round(phi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP; + hwCharge = (charge > 0); + hwFlags = flags; + src = source; + } + float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } + float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } + float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } + int intCharge() const { return hwCharge ? +1 : -1; } +#endif + }; + + struct PFParticle { + int16_t hwPt; + int16_t hwEta; // at calo face + int16_t hwPhi; + uint8_t hwId; // CH=0, EL=1, NH=2, GAMMA=3, MU=4 + int16_t hwVtxEta; // propagate back to Vtx for charged particles (if useful?) + int16_t hwVtxPhi; + uint16_t hwFlags; + CaloCluster cluster; + PropagatedTrack track; + bool chargedPV; + uint16_t hwPuppiWeight; + uint16_t hwStatus; // for debugging + const l1t::Muon *muonsrc; + const l1t::PFCandidate *src; + + // sorting + bool operator<(const PFParticle &other) const { return hwPt > other.hwPt; } + +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + static constexpr float PUPPI_SCALE = 100; + + float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } + float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } + float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } + float floatVtxEta() const { + return (track.hwPt > 0 ? track.floatVtxEta() : float(hwVtxEta) / CaloCluster::ETAPHI_SCALE); + } + float floatVtxPhi() const { + return (track.hwPt > 0 ? track.floatVtxPhi() : float(hwVtxPhi) / CaloCluster::ETAPHI_SCALE); + } + float floatDZ() const { return float(track.hwZ0) / InputTrack::Z0_SCALE; } + float floatPuppiW() const { return float(hwPuppiWeight) / PUPPI_SCALE; } + int intCharge() const { return (track.hwPt > 0 ? track.intCharge() : 0); } + void setPuppiW(float w) { hwPuppiWeight = std::round(w * PUPPI_SCALE); } + void setFloatPt(float pt) { hwPt = round(pt * CaloCluster::PT_SCALE); } +#endif + }; + + struct InputRegion { + float etaCenter, etaMin, etaMax, phiCenter, phiHalfWidth; + float etaExtra, phiExtra; + std::vector calo; + std::vector emcalo; + std::vector track; + std::vector muon; + + InputRegion() + : etaCenter(), + etaMin(), + etaMax(), + phiCenter(), + phiHalfWidth(), + etaExtra(), + phiExtra(), + calo(), + emcalo(), + track(), + muon() {} + InputRegion( + float etacenter, float etamin, float etamax, float phicenter, float phihalfwidth, float etaextra, float phiextra) + : etaCenter(etacenter), + etaMin(etamin), + etaMax(etamax), + phiCenter(phicenter), + phiHalfWidth(phihalfwidth), + etaExtra(etaextra), + phiExtra(phiextra), + calo(), + emcalo(), + track(), + muon() {} + }; + +} // namespace l1tpf_impl +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h new file mode 100644 index 0000000000000..ddb8b4f526b57 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h @@ -0,0 +1,143 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputsIO_H +#define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputsIO_H + +#include +#include +#include + +#include "DiscretePFInputs.h" + +namespace l1tpf_impl { + void writeToFile(const CaloCluster &c, FILE *file) { + fwrite(&c.hwPt, 2, 1, file); + fwrite(&c.hwEmPt, 2, 1, file); + fwrite(&c.hwPtErr, 2, 1, file); + fwrite(&c.hwEta, 2, 1, file); + fwrite(&c.hwPhi, 2, 1, file); + fwrite(&c.hwFlags, 2, 1, file); + fwrite(&c.isEM, 1, 1, file); + // used is not written out + // src is not written out + } + void readFromFile(CaloCluster &c, FILE *file) { + fread(&c.hwPt, 2, 1, file); + fread(&c.hwEmPt, 2, 1, file); + fread(&c.hwPtErr, 2, 1, file); + fread(&c.hwEta, 2, 1, file); + fread(&c.hwPhi, 2, 1, file); + fread(&c.hwFlags, 2, 1, file); + fread(&c.isEM, 1, 1, file); + c.used = false; + c.src = nullptr; + } + + void writeToFile(const InputTrack &t, FILE *file) { + fwrite(&t.hwInvpt, 2, 1, file); + fwrite(&t.hwVtxEta, 4, 1, file); + fwrite(&t.hwVtxPhi, 4, 1, file); + fwrite(&t.hwCharge, 1, 1, file); + fwrite(&t.hwZ0, 2, 1, file); + fwrite(&t.hwChi2, 2, 1, file); + fwrite(&t.hwStubs, 2, 1, file); + fwrite(&t.hwFlags, 2, 1, file); + // src is not written out + } + void readFromFile(InputTrack &t, FILE *file) { + fread(&t.hwInvpt, 2, 1, file); + fread(&t.hwVtxEta, 4, 1, file); + fread(&t.hwVtxPhi, 4, 1, file); + fread(&t.hwCharge, 1, 1, file); + fread(&t.hwZ0, 2, 1, file); + fread(&t.hwChi2, 2, 1, file); + fread(&t.hwStubs, 2, 1, file); + fread(&t.hwFlags, 2, 1, file); + t.src = nullptr; + } + void writeToFile(const PropagatedTrack &t, FILE *file) { + writeToFile(static_cast(t), file); + fwrite(&t.hwPt, 2, 1, file); + fwrite(&t.hwPtErr, 2, 1, file); + fwrite(&t.hwCaloPtErr, 2, 1, file); + fwrite(&t.hwEta, 2, 1, file); + fwrite(&t.hwPhi, 2, 1, file); + // muonLink, used, fromPV are transient + } + void readFromFile(PropagatedTrack &t, FILE *file) { + readFromFile(static_cast(t), file); + fread(&t.hwPt, 2, 1, file); + fread(&t.hwPtErr, 2, 1, file); + fread(&t.hwCaloPtErr, 2, 1, file); + fread(&t.hwEta, 2, 1, file); + fread(&t.hwPhi, 2, 1, file); + t.muonLink = false; + t.used = false; + t.fromPV = false; + } + + void writeToFile(const Muon &m, FILE *file) { + fwrite(&m.hwPt, 2, 1, file); + fwrite(&m.hwEta, 2, 1, file); + fwrite(&m.hwPhi, 2, 1, file); + fwrite(&m.hwFlags, 2, 1, file); + fwrite(&m.hwCharge, 1, 1, file); + } + void readFromFile(Muon &m, FILE *file) { + fread(&m.hwPt, 2, 1, file); + fread(&m.hwEta, 2, 1, file); + fread(&m.hwPhi, 2, 1, file); + fread(&m.hwFlags, 2, 1, file); + fread(&m.hwCharge, 1, 1, file); + m.src = nullptr; + } + + void writeToFile(const float &pug, FILE *file) { fwrite(&pug, sizeof(float), 1, file); } + void readFromFile(float &pug, FILE *file) { fread(&pug, sizeof(float), 1, file); } + + template + void writeManyToFile(const std::vector &objs, FILE *file) { + uint32_t number = objs.size(); + fwrite(&number, 4, 1, file); + for (uint32_t i = 0; i < number; ++i) + writeToFile(objs[i], file); + } + + template + void readManyFromFile(std::vector &objs, FILE *file) { + uint32_t number; + fread(&number, 4, 1, file); + objs.resize(number); + for (uint32_t i = 0; i < number; ++i) + readFromFile(objs[i], file); + } + + void writeToFile(const InputRegion &r, FILE *file) { + assert(4 == sizeof(float)); + fwrite(&r.etaCenter, 4, 1, file); + fwrite(&r.etaMin, 4, 1, file); + fwrite(&r.etaMax, 4, 1, file); + fwrite(&r.phiCenter, 4, 1, file); + fwrite(&r.phiHalfWidth, 4, 1, file); + fwrite(&r.etaExtra, 4, 1, file); + fwrite(&r.phiExtra, 4, 1, file); + writeManyToFile(r.calo, file); + writeManyToFile(r.emcalo, file); + writeManyToFile(r.track, file); + writeManyToFile(r.muon, file); + } + void readFromFile(InputRegion &r, FILE *file) { + assert(4 == sizeof(float)); + fread(&r.etaCenter, 4, 1, file); + fread(&r.etaMin, 4, 1, file); + fread(&r.etaMax, 4, 1, file); + fread(&r.phiCenter, 4, 1, file); + fread(&r.phiHalfWidth, 4, 1, file); + fread(&r.etaExtra, 4, 1, file); + fread(&r.phiExtra, 4, 1, file); + readManyFromFile(r.calo, file); + readManyFromFile(r.emcalo, file); + readManyFromFile(r.track, file); + readManyFromFile(r.muon, file); + } + +} // namespace l1tpf_impl +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/HGC3DClusterEgID.h b/L1Trigger/Phase2L1ParticleFlow/interface/HGC3DClusterEgID.h new file mode 100644 index 0000000000000..8eae585f77f1c --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/HGC3DClusterEgID.h @@ -0,0 +1,53 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_HGC3DClusterEgID_h +#define L1Trigger_Phase2L1ParticleFlow_HGC3DClusterEgID_h +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" +#include "DataFormats/L1TParticleFlow/interface/PFCluster.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include "CommonTools/Utils/interface/StringObjectFunction.h" + +#include "TMVA/Factory.h" +#include "TMVA/Reader.h" + +#include +#include + +namespace l1tpf { + class HGC3DClusterEgID { + public: + HGC3DClusterEgID(const edm::ParameterSet &pset); + + void prepareTMVA(); + + float passID(l1t::HGCalMulticluster c, l1t::PFCluster &cpf); + + std::string method() { return method_; } + + private: + class Var { + public: + Var(const std::string &name, const std::string &expr) : name_(name), expr_(expr) {} + void declare(TMVA::Reader &r) { r.AddVariable(name_, &val_); } + void fill(const l1t::HGCalMulticluster &c) { val_ = expr_(c); } + + private: + std::string name_; + StringObjectFunction expr_; + float val_; + }; + + bool isPUFilter_; + StringCutObjectSelector preselection_; + std::vector variables_; + std::string method_, weightsFile_; + std::unique_ptr reader_; + StringObjectFunction wp_; + }; //class +}; // namespace l1tpf + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TPFUtils.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TPFUtils.h new file mode 100644 index 0000000000000..525b780afaf46 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TPFUtils.h @@ -0,0 +1,13 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_L1TPFUtils_h +#define L1Trigger_Phase2L1ParticleFlow_L1TPFUtils_h +#include +#include "DataFormats/Math/interface/LorentzVector.h" + +namespace l1tpf { + std::pair propagateToCalo(const math::XYZTLorentzVector& iMom, + const math::XYZTLorentzVector& iVtx, + double iCharge, + double iBField); +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h new file mode 100644 index 0000000000000..fe5bd5378ec03 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h @@ -0,0 +1,33 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_LinearizedPuppiAlgo_h +#define L1Trigger_Phase2L1ParticleFlow_LinearizedPuppiAlgo_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h" + +namespace l1tpf_impl { + + class LinearizedPuppiAlgo : public PuppiAlgo { + public: + LinearizedPuppiAlgo(const edm::ParameterSet &); + ~LinearizedPuppiAlgo() override; + + const std::vector &puGlobalNames() const override; + void doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const override; + void runNeutralsPU(Region &r, float npu, const std::vector &globals) const override; + + protected: + void computePuppiWeights(Region &r, + float npu, + const std::vector &alphaC, + const std::vector &alphaF) const; + + std::vector puppiPriors_, puppiPriorsPhotons_; + std::vector puppiPtSlopes_, puppiPtSlopesPhotons_; + std::vector puppiPtZeros_, puppiPtZerosPhotons_; + std::vector puppiAlphaSlopes_, puppiAlphaSlopesPhotons_; + std::vector puppiAlphaZeros_, puppiAlphaZerosPhotons_; + std::vector puppiAlphaCrops_, puppiAlphaCropsPhotons_; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h new file mode 100644 index 0000000000000..c6342d9efddfe --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h @@ -0,0 +1,76 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PFAlgo2HGC_h +#define L1Trigger_Phase2L1ParticleFlow_PFAlgo2HGC_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" + +namespace l1tpf_impl { + class PFAlgo2HGC : public PFAlgoBase { + public: + PFAlgo2HGC(const edm::ParameterSet &); + void runPF(Region &r) const override; + + protected: + float drMatchMu_; + enum class MuMatchMode { BoxBestByPtRatio, DrBestByPtRatio, DrBestByPtDiff } muMatchMode_; + float drMatch_, ptMatchLow_, ptMatchHigh_, maxInvisiblePt_; + bool useTrackCaloSigma_, rescaleUnmatchedTrack_, caloTrkWeightedAverage_; + enum class TkCaloLinkMetric { BestByDR = 0, BestByDRPt = 1, BestByDR2Pt2 = 2 }; + TkCaloLinkMetric tkCaloLinkMetric_; + bool caloReLinkStep_; + float caloReLinkDr_, caloReLinkThreshold_; + bool rescaleTracks_, sumTkCaloErr2_, ecalPriority_, trackEmUseAlsoTrackSigma_, emCaloUseAlsoCaloSigma_; + unsigned int tightTrackMinStubs_; + float tightTrackMaxChi2_, tightTrackMaxInvisiblePt_; + enum GoodTrackStatus { GoodTK_Calo_TkPt = 0, GoodTK_Calo_TkCaloPt = 1, GoodTk_Calo_CaloPt = 2, GoodTK_NoCalo = 3 }; + enum BadTrackStatus { BadTK_NoCalo = 1 }; + + /// do muon track linking (also sets track.muonLink) + void link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const; + + /// track to calo matching + // tk2calo[itk] = icalo or -1 + void link_tk2calo(Region &r, std::vector &tk2calo) const; + + /// for each calo, compute the sum of the track pt + void sum_tk2calo(Region &r, + const std::vector &tk2calo, + std::vector &calo2ntk, + std::vector &calo2sumtkpt, + std::vector &calo2sumtkpterr) const; + + /// promote unlinked low pt tracks to hadrons + void unlinkedtk_algo(Region &r, const std::vector &tk2calo) const; + + /// try to recover split hadron showers (v1.0): + // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt + // add this pt to the calo pt of the other cluster + // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events + void calo_relink(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr) const; + + /// process matched calo clusters, compare energy to sum track pt, compute track rescaling factor if needed + // alpha[icalo] = x < 1 if all tracks linked to icalo must have their pt rescaled by x + void linkedcalo_algo(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr, + std::vector &calo2alpha) const; + + /// process matched tracks, if necessary rescale or average + void linkedtk_algo(Region &r, + const std::vector &tk2calo, + const std::vector &calo2ntk, + const std::vector &calo2alpha) const; + + /// process unmatched calo clusters + void unlinkedcalo_algo(Region &r) const; + + /// save muons in output list + void save_muons(Region &r, const std::vector &tk2mu) const; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h new file mode 100644 index 0000000000000..5972218dc10fd --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h @@ -0,0 +1,109 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PFAlgo3_h +#define L1Trigger_Phase2L1ParticleFlow_PFAlgo3_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" + +namespace l1tpf_impl { + class PFAlgo3 : public PFAlgoBase { + public: + PFAlgo3(const edm::ParameterSet &); + void runPF(Region &r) const override; + + protected: + float drMatchMu_; + enum class MuMatchMode { BoxBestByPtRatio, DrBestByPtRatio, DrBestByPtDiff } muMatchMode_; + float drMatch_, ptMatchLow_, ptMatchHigh_, maxInvisiblePt_; + bool useTrackCaloSigma_, rescaleUnmatchedTrack_, caloTrkWeightedAverage_; + enum class TkCaloLinkMetric { BestByDR = 0, BestByDRPt = 1, BestByDR2Pt2 = 2 }; + float drMatchEm_, ptMinFracMatchEm_, drMatchEmHad_; + float emHadSubtractionPtSlope_; + TkCaloLinkMetric tkCaloLinkMetric_; + bool caloReLinkStep_; + float caloReLinkDr_, caloReLinkThreshold_; + bool rescaleTracks_, sumTkCaloErr2_, ecalPriority_, trackEmUseAlsoTrackSigma_, trackEmMayUseCaloMomenta_, + emCaloUseAlsoCaloSigma_; + unsigned int tightTrackMinStubs_; + float tightTrackMaxChi2_, tightTrackMaxInvisiblePt_; + enum GoodTrackStatus { GoodTK_Calo_TkPt = 0, GoodTK_Calo_TkCaloPt = 1, GoodTk_Calo_CaloPt = 2, GoodTK_NoCalo = 3 }; + enum BadTrackStatus { BadTK_NoCalo = 1 }; + + /// do muon track linking (also sets track.muonLink) + void link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const; + + /// match all tracks to the closest EM cluster + // tk2em[itrack] = iem, or -1 if unmatched + void link_tk2em(Region &r, std::vector &tk2em) const; + + /// match all em to the closest had (can happen in parallel to the above) + // em2calo[iem] = icalo or -1 + void link_em2calo(Region &r, std::vector &em2calo) const; + + /// for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) + void sum_tk2em(Region &r, + const std::vector &tk2em, + std::vector &em2ntk, + std::vector &em2sumtkpt, + std::vector &em2sumtkpterr) const; + + /// process ecal clusters after linking + void emcalo_algo(Region &r, + const std::vector &em2ntk, + const std::vector &em2sumtkpt, + const std::vector &em2sumtkpterr) const; + + /// promote all flagged tracks to electrons + void emtk_algo(Region &r, + const std::vector &tk2em, + const std::vector &em2ntk, + const std::vector &em2sumtkpterr) const; + + /// subtract EM component from Calo clusters for all photons and electrons (within tracker coverage) + void sub_em2calo(Region &r, const std::vector &em2calo) const; + + /// track to calo matching + // tk2calo[itk] = icalo or -1 + void link_tk2calo(Region &r, std::vector &tk2calo) const; + + /// for each calo, compute the sum of the track pt + void sum_tk2calo(Region &r, + const std::vector &tk2calo, + std::vector &calo2ntk, + std::vector &calo2sumtkpt, + std::vector &calo2sumtkpterr) const; + + /// promote unlinked low pt tracks to hadrons + void unlinkedtk_algo(Region &r, const std::vector &tk2calo) const; + + /// try to recover split hadron showers (v1.0): + // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt + // add this pt to the calo pt of the other cluster + // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events + void calo_relink(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr) const; + + /// process matched calo clusters, compare energy to sum track pt, compute track rescaling factor if needed + // alpha[icalo] = x < 1 if all tracks linked to icalo must have their pt rescaled by x + void linkedcalo_algo(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr, + std::vector &calo2alpha) const; + + /// process matched tracks, if necessary rescale or average + void linkedtk_algo(Region &r, + const std::vector &tk2calo, + const std::vector &calo2ntk, + const std::vector &calo2alpha) const; + + /// process unmatched calo clusters + void unlinkedcalo_algo(Region &r) const; + + /// save muons in output list + void save_muons(Region &r, const std::vector &tk2mu) const; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h new file mode 100644 index 0000000000000..f0286a221222f --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h @@ -0,0 +1,28 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PFAlgoBase_h +#define L1Trigger_Phase2L1ParticleFlow_PFAlgoBase_h + +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +namespace l1tpf_impl { + + class PFAlgoBase { + public: + PFAlgoBase(const edm::ParameterSet &); + virtual ~PFAlgoBase(); + virtual void runPF(Region &r) const = 0; + + protected: + int debug_; + void initRegion(Region &r) const; + PFParticle &addTrackToPF(Region &r, const PropagatedTrack &tk) const { return addTrackToPF(r.pf, tk); } + PFParticle &addCaloToPF(Region &r, const CaloCluster &calo) const { return addCaloToPF(r.pf, calo); } + PFParticle &addTrackToPF(std::vector &pfs, const PropagatedTrack &tk) const; + PFParticle &addCaloToPF(std::vector &pfs, const CaloCluster &calo) const; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h b/L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h new file mode 100644 index 0000000000000..0b6cfa60f6fca --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h @@ -0,0 +1,34 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PUAlgoBase_h +#define L1Trigger_Phase2L1ParticleFlow_PUAlgoBase_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +namespace l1tpf_impl { + + class PUAlgoBase { + public: + PUAlgoBase(const edm::ParameterSet &); + virtual ~PUAlgoBase(); + + /// global operations + enum class VertexAlgo { Old, TP, External }; + virtual void doVertexing(std::vector &rs, + VertexAlgo algo, + float &vz) const; // region is not const since it sets the fromPV bit of the tracks + + virtual void runChargedPV(Region &r, float z0) const; + + virtual const std::vector &puGlobalNames() const; + virtual void doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const = 0; + virtual void runNeutralsPU(Region &r, float npu, const std::vector &globals) const = 0; + + protected: + int debug_; + float etaCharged_, vtxRes_; + bool vtxAdaptiveCut_; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h b/L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h new file mode 100644 index 0000000000000..6079f96807beb --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h @@ -0,0 +1,27 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_ParametricResolution_h +#define L1Trigger_Phase2L1ParticleFlow_ParametricResolution_h +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/Exception.h" +#include +#include + +namespace l1tpf { + + class ParametricResolution { + public: + static std::vector getVFloat(const edm::ParameterSet &cpset, const std::string &name); + + ParametricResolution() {} + ParametricResolution(const edm::ParameterSet &cpset); + + float operator()(const float pt, const float abseta) const; + + protected: + std::vector etas_, offsets_, scales_, ptMins_, ptMaxs_; + enum class Kind { Calo, Track }; + Kind kind_; + }; + +}; // namespace l1tpf + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h new file mode 100644 index 0000000000000..297209cde949d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h @@ -0,0 +1,38 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PuppiAlgo_h +#define L1Trigger_Phase2L1ParticleFlow_PuppiAlgo_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h" + +namespace l1tpf_impl { + + class PuppiAlgo : public PUAlgoBase { + public: + PuppiAlgo(const edm::ParameterSet &); + ~PuppiAlgo() override; + + const std::vector &puGlobalNames() const override; + void doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const override; + void runNeutralsPU(Region &r, float npu, const std::vector &globals) const override; + + protected: + virtual void computePuppiMedRMS( + const std::vector &rs, float &alphaCMed, float &alphaCRms, float &alphaFMed, float &alphaFRms) const; + virtual void fillPuppi(Region &r) const; + virtual void computePuppiAlphas(const Region &r, std::vector &alphaC, std::vector &alphaF) const; + void computePuppiWeights(Region &r, + const std::vector &alphaC, + const std::vector &alphaF, + float alphaCMed, + float alphaCRms, + float alphaFMed, + float alphaFRms) const; + + float puppiDr_, puppiDrMin_, puppiPtMax_; + std::vector puppiEtaCuts_, puppiPtCuts_, puppiPtCutsPhotons_; + std::vector intPuppiEtaCuts_, intPuppiPtCuts_, intPuppiPtCutsPhotons_; + bool puppiUsingBareTracks_; + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/Region.h b/L1Trigger/Phase2L1ParticleFlow/interface/Region.h new file mode 100644 index 0000000000000..b022bace35f69 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/Region.h @@ -0,0 +1,112 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_Region_h +#define L1Trigger_Phase2L1ParticleFlow_Region_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +namespace l1tpf_impl { + struct Region : public InputRegion { + std::vector pf; + std::vector puppi; + unsigned int caloOverflow, emcaloOverflow, trackOverflow, muonOverflow, pfOverflow, puppiOverflow; + + const bool relativeCoordinates; // whether the eta,phi in each region are global or relative to the region center + const unsigned int ncaloMax, nemcaloMax, ntrackMax, nmuonMax, npfMax, npuppiMax; + Region(float etamin, + float etamax, + float phicenter, + float phiwidth, + float etaextra, + float phiextra, + bool useRelativeCoordinates, + unsigned int ncalomax, + unsigned int nemcalomax, + unsigned int ntrackmax, + unsigned int nmuonmax, + unsigned int npfmax, + unsigned int npuppimax) + : InputRegion(0.5 * (etamin + etamax), etamin, etamax, phicenter, 0.5 * phiwidth, etaextra, phiextra), + pf(), + puppi(), + caloOverflow(), + emcaloOverflow(), + trackOverflow(), + muonOverflow(), + pfOverflow(), + puppiOverflow(), + relativeCoordinates(useRelativeCoordinates), + ncaloMax(ncalomax), + nemcaloMax(nemcalomax), + ntrackMax(ntrackmax), + nmuonMax(nmuonmax), + npfMax(npfmax), + npuppiMax(npuppimax) {} + + enum InputType { calo_type = 0, emcalo_type = 1, track_type = 2, l1mu_type = 3, n_input_types = 4 }; + static const char* inputTypeName(int inputType); + + enum OutputType { + any_type = 0, + charged_type = 1, + neutral_type = 2, + electron_type = 3, + pfmuon_type = 4, + charged_hadron_type = 5, + neutral_hadron_type = 6, + photon_type = 7, + n_output_types = 8 + }; + static const char* outputTypeName(int outputType); + + unsigned int nInput(InputType type) const; + unsigned int nOutput(OutputType type, bool puppi, bool fiducial = true) const; + + // global coordinates + bool contains(float eta, float phi) const { + float dphi = deltaPhi(phiCenter, phi); + return (etaMin - etaExtra < eta && eta <= etaMax + etaExtra && -phiHalfWidth - phiExtra < dphi && + dphi <= phiHalfWidth + phiExtra); + } + // global coordinates + bool fiducial(float eta, float phi) const { + float dphi = deltaPhi(phiCenter, phi); + return (etaMin < eta && eta <= etaMax && -phiHalfWidth < dphi && dphi <= phiHalfWidth); + } + // possibly local coordinates + bool fiducialLocal(float localEta, float localPhi) const { + if (relativeCoordinates) { + float dphi = deltaPhi(0.f, localPhi); + return (etaMin < localEta + etaCenter && localEta + etaCenter <= etaMax && -phiHalfWidth < dphi && + dphi <= phiHalfWidth); + } + float dphi = deltaPhi(phiCenter, localPhi); + return (etaMin < localEta && localEta <= etaMax && -phiHalfWidth < dphi && dphi <= phiHalfWidth); + } + float regionAbsEta() const { return std::abs(etaCenter); } + float globalAbsEta(float localEta) const { return std::abs(relativeCoordinates ? localEta + etaCenter : localEta); } + float globalEta(float localEta) const { return relativeCoordinates ? localEta + etaCenter : localEta; } + float globalPhi(float localPhi) const { return relativeCoordinates ? localPhi + phiCenter : localPhi; } + float localEta(float globalEta) const { return relativeCoordinates ? globalEta - etaCenter : globalEta; } + float localPhi(float globalPhi) const { return relativeCoordinates ? deltaPhi(globalPhi, phiCenter) : globalPhi; } + + void zero() { + calo.clear(); + emcalo.clear(); + track.clear(); + muon.clear(); + pf.clear(); + puppi.clear(); + caloOverflow = 0; + emcaloOverflow = 0; + trackOverflow = 0; + muonOverflow = 0; + pfOverflow = 0; + puppiOverflow = 0; + } + + void inputSort(); + }; + +} // namespace l1tpf_impl + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h b/L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h new file mode 100644 index 0000000000000..11ca55c1d981e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h @@ -0,0 +1,57 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_RegionMapper_h +#define L1Trigger_Phase2L1ParticleFlow_RegionMapper_h + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" + +#include + +namespace l1tpf_impl { + class RegionMapper { + // This does the input and filling of regions. + public: + RegionMapper(const edm::ParameterSet &); + + // add object, without tracking references + void addTrack(const l1t::PFTrack &t); + void addMuon(const l1t::Muon &t); + void addMuon(const l1t::TkMuon &t); + void addCalo(const l1t::PFCluster &t); + void addEmCalo(const l1t::PFCluster &t); + + // add object, tracking references + void addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref); + void addMuon(const l1t::Muon &t, l1t::PFCandidate::MuonRef ref); + void addCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref); + void addEmCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref); + + void clear(); + std::vector ®ions() { return regions_; } + + std::unique_ptr fetch(bool puppi = true, float ptMin = 0.01) const; + std::unique_ptr fetchCalo(float ptMin = 0.01, bool emcalo = false) const; + std::unique_ptr fetchTracks(float ptMin = 0.01, bool fromPV = false) const; + + std::pair totAndMaxInput(/*Region::InputType*/ int type) const; + std::pair totAndMaxOutput(/*Region::OutputType*/ int type, bool puppi) const; + std::unique_ptr> vecInput(int type) const; + std::unique_ptr> vecOutput(int type, bool puppi) const; + + protected: + std::vector regions_; + bool useRelativeRegionalCoordinates_; // whether the eta,phi in each region are global or relative to the region center + enum class TrackAssoMode { atVertex, atCalo, any = 999 } trackRegionMode_; + + // these are used to link items back + std::unordered_map clusterRefMap_; + std::unordered_map trackRefMap_; + std::unordered_map muonRefMap_; + }; + +} // namespace l1tpf_impl +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml new file mode 100644 index 0000000000000..3d1223a3526e1 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc new file mode 100644 index 0000000000000..b642a1bc3f5cb --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc @@ -0,0 +1,58 @@ +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include "DataFormats/JetReco/interface/Jet.h" + +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/InputTag.h" + +#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" + +#include + +class L1TCorrectedPFJetProducer : public edm::global::EDProducer<> { +public: + explicit L1TCorrectedPFJetProducer(const edm::ParameterSet&); + ~L1TCorrectedPFJetProducer() override; + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + edm::EDGetTokenT> jets_; + l1tpf::corrector corrector_; + bool copyDaughters_; +}; + +L1TCorrectedPFJetProducer::L1TCorrectedPFJetProducer(const edm::ParameterSet& iConfig) + : jets_(consumes>(iConfig.getParameter("jets"))), + corrector_(iConfig.getParameter("correctorFile"), iConfig.getParameter("correctorDir")), + copyDaughters_(iConfig.getParameter("copyDaughters")) { + produces>(); +} + +L1TCorrectedPFJetProducer::~L1TCorrectedPFJetProducer() {} + +void L1TCorrectedPFJetProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const { + edm::Handle> jets; + iEvent.getByToken(jets_, jets); + auto out = std::make_unique>(); + + for (const auto& srcjet : *jets) { + // start out as copy + out->emplace_back(srcjet.p4()); + auto& jet = out->back(); + // copy daughters + if (copyDaughters_) { + for (const auto& dau : srcjet.daughterPtrVector()) { + jet.addConstituent(edm::Ptr(dau)); + } + } + // apply corrections + jet.calibratePt(corrector_.correctedPt(jet.pt(), jet.eta())); + } + + iEvent.put(std::move(out)); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TCorrectedPFJetProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc new file mode 100644 index 0000000000000..2387893723f67 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc @@ -0,0 +1,300 @@ +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h" +#include "DataFormats/HcalDigi/interface/HcalDigiCollections.h" +#include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h" +#include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h" +#include "L1Trigger/L1TCalorimeter/interface/CaloTools.h" + +#include "DataFormats/L1THGCal/interface/HGCalTower.h" + +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h" + +#include "DataFormats/Math/interface/deltaPhi.h" + +#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h" + +//-------------------------------------------------------------------------------------------------- +class L1TPFCaloProducer : public edm::stream::EDProducer<> { +public: + explicit L1TPFCaloProducer(const edm::ParameterSet &); + +private: + bool ecalOnly_, debug_; + std::vector> ecalCands_; + std::vector> hcalCands_; + + std::vector> hcalDigis_; + edm::ESGetToken decoderTag_; + bool hcalDigisBarrel_, hcalDigisHF_; + std::vector> phase2barrelTowers_; + std::vector> hcalHGCTowers_; + bool hcalHGCTowersHadOnly_; + + l1tpf::corrector emCorrector_; + l1tpf::corrector hcCorrector_; + l1tpf::corrector hadCorrector_; + + l1tpf_calo::SingleCaloClusterer ecalClusterer_, hcalClusterer_; + std::unique_ptr caloLinker_; + + l1tpf::ParametricResolution resol_; + + void produce(edm::Event &, const edm::EventSetup &) override; + + void readHcalDigis_(edm::Event &event, const edm::EventSetup &); + void readPhase2BarrelCaloTowers_(edm::Event &event, const edm::EventSetup &); + void readHcalHGCTowers_(edm::Event &event, const edm::EventSetup &); + struct SimpleHGCTC { + float et, eta, phi; + SimpleHGCTC(float aet, float aeta, float aphi) : et(aet), eta(aeta), phi(aphi) {} + }; +}; + +// +// constructors and destructor +// +L1TPFCaloProducer::L1TPFCaloProducer(const edm::ParameterSet &iConfig) + : ecalOnly_(iConfig.existsAs("ecalOnly") ? iConfig.getParameter("ecalOnly") : false), + debug_(iConfig.getUntrackedParameter("debug", 0)), + decoderTag_(esConsumes(edm::ESInputTag("", ""))), + emCorrector_(iConfig.getParameter("emCorrector"), -1, debug_), + hcCorrector_(iConfig.getParameter("hcCorrector"), -1, debug_), + hadCorrector_(iConfig.getParameter("hadCorrector"), + iConfig.getParameter("hadCorrectorEmfMax"), + debug_), + ecalClusterer_(iConfig.getParameter("ecalClusterer")), + hcalClusterer_(iConfig.getParameter("hcalClusterer")), + caloLinker_(l1tpf_calo::makeCaloLinker( + iConfig.getParameter("linker"), ecalClusterer_, hcalClusterer_)), + resol_(iConfig.getParameter("resol")) { + produces("ecalCells"); + + produces("emCalibrated"); + produces("emUncalibrated"); + + for (auto &tag : iConfig.getParameter>("ecalCandidates")) { + ecalCands_.push_back(consumes(tag)); + } + + if (ecalOnly_) + return; + + produces("hcalCells"); + + produces("hcalUnclustered"); + produces("hcalUncalibrated"); + produces("hcalCalibrated"); + + produces("uncalibrated"); + produces("calibrated"); + + for (auto &tag : iConfig.getParameter>("hcalCandidates")) { + hcalCands_.push_back(consumes(tag)); + } + + for (auto &tag : iConfig.getParameter>("hcalDigis")) { + hcalDigis_.push_back(consumes(tag)); + } + if (!hcalDigis_.empty()) { + hcalDigisBarrel_ = iConfig.getParameter("hcalDigisBarrel"); + hcalDigisHF_ = iConfig.getParameter("hcalDigisHF"); + } + + for (auto &tag : iConfig.getParameter>("phase2barrelCaloTowers")) { + phase2barrelTowers_.push_back(consumes(tag)); + } + + for (auto &tag : iConfig.getParameter>("hcalHGCTowers")) { + hcalHGCTowers_.push_back(consumes(tag)); + } + if (!hcalHGCTowers_.empty()) + hcalHGCTowersHadOnly_ = iConfig.getParameter("hcalHGCTowersHadOnly"); +} + +// ------------ method called to produce the data ------------ +void L1TPFCaloProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + /// ----------------ECAL INFO------------------- + edm::Handle ecals; + for (const auto &token : ecalCands_) { + iEvent.getByToken(token, ecals); + for (const reco::Candidate &it : *ecals) { + if (debug_) + edm::LogWarning("L1TPFCaloProducer") + << "adding ECal input pt " << it.pt() << ", eta " << it.eta() << ", phi " << it.phi() << "\n"; + ecalClusterer_.add(it); + } + } + + /// ----------------HCAL INFO------------------- + if (!ecalOnly_) { + edm::Handle hcals; + for (const auto &token : hcalCands_) { + iEvent.getByToken(token, hcals); + for (const reco::Candidate &it : *hcals) { + if (debug_) + edm::LogWarning("L1TPFCaloProducer") + << "adding HCal cand input pt " << it.pt() << ", eta " << it.eta() << ", phi " << it.phi() << "\n"; + hcalClusterer_.add(it); + } + } + if (!hcalDigis_.empty()) { + readHcalDigis_(iEvent, iSetup); + } + if (!phase2barrelTowers_.empty()) { + readPhase2BarrelCaloTowers_(iEvent, iSetup); + } + if (!hcalHGCTowers_.empty()) { + readHcalHGCTowers_(iEvent, iSetup); + } + } + + /// --------------- CLUSTERING ------------------ + ecalClusterer_.run(); + + auto ecalCellsH = iEvent.put(ecalClusterer_.fetchCells(), "ecalCells"); + + iEvent.put(ecalClusterer_.fetch(ecalCellsH), "emUncalibrated"); + + if (emCorrector_.valid()) { + ecalClusterer_.correct( + [&](const l1tpf_calo::Cluster &c) -> float { return emCorrector_.correctedPt(0., c.et, std::abs(c.eta)); }); + } + + std::unique_ptr corrEcal = ecalClusterer_.fetch(ecalCellsH); + + if (debug_) { + for (const l1t::PFCluster &it : *corrEcal) { + edm::LogWarning("L1TPFCaloProducer") + << "corrected ECal cluster pt " << it.pt() << ", eta " << it.eta() << ", phi " << it.phi() << "\n"; + } + } + + auto ecalClustH = iEvent.put(std::move(corrEcal), "emCalibrated"); + + if (ecalOnly_) { + ecalClusterer_.clear(); + return; + } + + hcalClusterer_.run(); + + auto hcalCellsH = iEvent.put(hcalClusterer_.fetchCells(), "hcalCells"); + + // this we put separately for debugging + iEvent.put(hcalClusterer_.fetchCells(/*unclustered=*/true), "hcalUnclustered"); + + iEvent.put(hcalClusterer_.fetch(hcalCellsH), "hcalUncalibrated"); + + if (hcCorrector_.valid()) { + hcalClusterer_.correct( + [&](const l1tpf_calo::Cluster &c) -> float { return hcCorrector_.correctedPt(c.et, 0., std::abs(c.eta)); }); + } + + auto hcalClustH = iEvent.put(hcalClusterer_.fetch(hcalCellsH), "hcalCalibrated"); + + // Calorimeter linking + caloLinker_->run(); + + iEvent.put(caloLinker_->fetch(ecalClustH, hcalClustH), "uncalibrated"); + + if (hadCorrector_.valid()) { + caloLinker_->correct([&](const l1tpf_calo::CombinedCluster &c) -> float { + if (debug_) + edm::LogWarning("L1TPFCaloProducer") << "raw linked cluster pt " << c.et << ", eta " << c.eta << ", phi " + << c.phi << ", emPt " << c.ecal_et << "\n"; + return hadCorrector_.correctedPt(c.et, c.ecal_et, std::abs(c.eta)); + }); + } + + std::unique_ptr clusters = caloLinker_->fetch(ecalClustH, hcalClustH); + for (l1t::PFCluster &c : *clusters) { + c.setPtError(resol_(c.pt(), std::abs(c.eta()))); + if (debug_) + edm::LogWarning("L1TPFCaloProducer") << "calibrated linked cluster pt " << c.pt() << ", eta " << c.eta() + << ", phi " << c.phi() << ", emPt " << c.emEt() << "\n"; + } + iEvent.put(std::move(clusters), "calibrated"); + + ecalClusterer_.clear(); + hcalClusterer_.clear(); + caloLinker_->clear(); +} + +void L1TPFCaloProducer::readHcalDigis_(edm::Event &iEvent, const edm::EventSetup &iSetup) { + const auto &decoder = iSetup.getData(decoderTag_); + edm::Handle hcalTPs; + for (const auto &token : hcalDigis_) { + iEvent.getByToken(token, hcalTPs); + for (const auto &itr : *hcalTPs) { + HcalTrigTowerDetId id = itr.id(); + double et = decoder.hcaletValue(itr.id(), itr.t0()); + if (et <= 0) + continue; + float towerEta = l1t::CaloTools::towerEta(id.ieta()); + float towerPhi = l1t::CaloTools::towerPhi(id.ieta(), id.iphi()); + if (!hcalDigisBarrel_ && std::abs(towerEta) < 2) // |eta| < 2 => barrel (there's no HE in Phase2) + continue; + if (!hcalDigisHF_ && std::abs(towerEta) > 2) // |eta| > 2 => HF + continue; + if (debug_) + edm::LogWarning("L1TPFCaloProducer") + << "adding HCal digi input pt " << et << ", eta " << towerEta << ", phi " << towerPhi << "\n"; + hcalClusterer_.add(et, towerEta, towerPhi); + } + } +} + +void L1TPFCaloProducer::readPhase2BarrelCaloTowers_(edm::Event &event, const edm::EventSetup &) { + edm::Handle towers; + for (const auto &token : phase2barrelTowers_) { + event.getByToken(token, towers); + for (const auto &t : *towers) { + // sanity check from https://github.com/cms-l1t-offline/cmssw/blob/l1t-phase2-v3.0.2/L1Trigger/L1CaloTrigger/plugins/L1TowerCalibrator.cc#L259-L263 + if ((int)t.towerIEta() == -1016 && (int)t.towerIPhi() == -962) + continue; + if (debug_ && (t.hcalTowerEt() > 0 || t.ecalTowerEt() > 0)) { + edm::LogWarning("L1TPFCaloProducer") + << "adding phase2 L1 CaloTower eta " << t.towerEta() << " phi " << t.towerPhi() << " ieta " + << t.towerIEta() << " iphi " << t.towerIPhi() << " ecal " << t.ecalTowerEt() << " hcal " + << t.hcalTowerEt() << "\n"; + } + hcalClusterer_.add(t.hcalTowerEt(), t.towerEta(), t.towerPhi()); + ecalClusterer_.add(t.ecalTowerEt(), t.towerEta(), t.towerPhi()); + } + } +} + +void L1TPFCaloProducer::readHcalHGCTowers_(edm::Event &iEvent, const edm::EventSetup &iSetup) { + edm::Handle hgcTowers; + + for (const auto &token : hcalHGCTowers_) { + iEvent.getByToken(token, hgcTowers); + for (auto it = hgcTowers->begin(0), ed = hgcTowers->end(0); it != ed; ++it) { + if (debug_) + edm::LogWarning("L1TPFCaloProducer") + << "adding HGC Tower hadEt " << it->etHad() << ", emEt " << it->etEm() << ", pt " << it->pt() << ", eta " + << it->eta() << ", phi " << it->phi() << "\n"; + hcalClusterer_.add(it->etHad(), it->eta(), it->phi()); + if (!hcalHGCTowersHadOnly_) + ecalClusterer_.add(it->etEm(), it->eta(), it->phi()); + } + } +} + +//define this as a plug-in +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TPFCaloProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMerger.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMerger.cc new file mode 100644 index 0000000000000..e61c8d394282d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMerger.cc @@ -0,0 +1,7 @@ +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "CommonTools/UtilAlgos/interface/Merger.h" + +typedef Merger> L1TPFCandMerger; + +DEFINE_FWK_MODULE(L1TPFCandMerger); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc new file mode 100644 index 0000000000000..96f36c36b794d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc @@ -0,0 +1,51 @@ +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/transform.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "DataFormats/Common/interface/CloneTrait.h" +#include + +class L1TPFCandMultiMerger : public edm::global::EDProducer<> { +public: + explicit L1TPFCandMultiMerger(const edm::ParameterSet&); + ~L1TPFCandMultiMerger() override; + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + std::vector instances_; + std::vector>> tokens_; +}; + +L1TPFCandMultiMerger::L1TPFCandMultiMerger(const edm::ParameterSet& iConfig) + : instances_(iConfig.getParameter>("labelsToMerge")) { + const std::vector& pfProducers = iConfig.getParameter>("pfProducers"); + tokens_.reserve(instances_.size() * pfProducers.size()); + for (unsigned int ii = 0, ni = instances_.size(); ii < ni; ++ii) { + for (const edm::InputTag& tag : pfProducers) { + tokens_.push_back( + consumes>(edm::InputTag(tag.label(), instances_[ii], tag.process()))); + } + produces>(instances_[ii]); + } +} + +L1TPFCandMultiMerger::~L1TPFCandMultiMerger() {} + +void L1TPFCandMultiMerger::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const { + edm::Handle> handle; + for (unsigned int ii = 0, it = 0, ni = instances_.size(), np = tokens_.size() / ni; ii < ni; ++ii) { + auto out = std::make_unique>(); + for (unsigned int ip = 0; ip < np; ++ip, ++it) { + iEvent.getByToken(tokens_[it], handle); + out->insert(out->end(), handle->begin(), handle->end()); + } + iEvent.put(std::move(out), instances_[ii]); + } +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TPFCandMultiMerger); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandSelector.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandSelector.cc new file mode 100644 index 0000000000000..09445cf2ab83a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandSelector.cc @@ -0,0 +1,8 @@ +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "CommonTools/UtilAlgos/interface/StringCutObjectSelector.h" +#include "CommonTools/UtilAlgos/interface/SingleObjectSelector.h" + +typedef SingleObjectSelector, StringCutObjectSelector> L1TPFCandSelector; + +DEFINE_FWK_MODULE(L1TPFCandSelector); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc new file mode 100644 index 0000000000000..8c358b30d2967 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc @@ -0,0 +1,400 @@ +// system include files +#include +#include +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" + +#include "DataFormats/Math/interface/deltaR.h" + +#include "L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h" + +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" + +//-------------------------------------------------------------------------------------------------- +class L1TPFProducer : public edm::stream::EDProducer<> { +public: + explicit L1TPFProducer(const edm::ParameterSet&); + ~L1TPFProducer() override; + +private: + edm::ParameterSet config_; + int debug_; + + bool useStandaloneMuons_; + bool useTrackerMuons_; + + bool hasTracks_; + edm::EDGetTokenT tkCands_; + float trkPt_, trkMaxChi2_; + unsigned trkMinStubs_; + l1tpf_impl::PUAlgoBase::VertexAlgo vtxAlgo_; + edm::EDGetTokenT> extTkVtx_; + + edm::EDGetTokenT muCands_; // standalone muons + edm::EDGetTokenT tkMuCands_; // tk muons + + std::vector> emCands_; + std::vector> hadCands_; + + float emPtCut_, hadPtCut_; + + l1tpf_impl::RegionMapper l1regions_; + std::unique_ptr l1pfalgo_; + std::unique_ptr l1pualgo_; + + edm::EDGetTokenT TokGenOrigin_; + + // Region dump/coe + const std::string regionDumpName_, regionCOEName_; + FILE* fRegionDump_; + std::unique_ptr fRegionCOE_; + unsigned int neventscoemax_, neventsproduced_; + + // region of interest debugging + float debugEta_, debugPhi_, debugR_; + + void beginStream(edm::StreamID) override; + void produce(edm::Event&, const edm::EventSetup&) override; + void addUInt(unsigned int value, std::string iLabel, edm::Event& iEvent); +}; + +// +// constructors and destructor +// +L1TPFProducer::L1TPFProducer(const edm::ParameterSet& iConfig) + : config_(iConfig), + debug_(iConfig.getUntrackedParameter("debug", 0)), + useStandaloneMuons_(iConfig.getParameter("useStandaloneMuons")), + useTrackerMuons_(iConfig.getParameter("useTrackerMuons")), + hasTracks_(!iConfig.getParameter("tracks").label().empty()), + tkCands_(hasTracks_ ? consumes(iConfig.getParameter("tracks")) + : edm::EDGetTokenT()), + trkPt_(iConfig.getParameter("trkPtCut")), + trkMaxChi2_(iConfig.getParameter("trkMaxChi2")), + trkMinStubs_(iConfig.getParameter("trkMinStubs")), + muCands_(consumes(iConfig.getParameter("muons"))), + tkMuCands_(consumes(iConfig.getParameter("tkMuons"))), + emPtCut_(iConfig.getParameter("emPtCut")), + hadPtCut_(iConfig.getParameter("hadPtCut")), + l1regions_(iConfig), + l1pfalgo_(nullptr), + l1pualgo_(nullptr), + regionDumpName_(iConfig.getUntrackedParameter("dumpFileName", "")), + regionCOEName_(iConfig.getUntrackedParameter("coeFileName", "")), + fRegionDump_(nullptr), + fRegionCOE_(nullptr), + neventscoemax_(iConfig.getUntrackedParameter("neventscoemax_", 0)), + neventsproduced_(0), + debugEta_(iConfig.getUntrackedParameter("debugEta", 0)), + debugPhi_(iConfig.getUntrackedParameter("debugPhi", 0)), + debugR_(iConfig.getUntrackedParameter("debugR", -1)) { + produces("PF"); + produces("Puppi"); + + produces("EmCalo"); + produces("Calo"); + produces("TK"); + produces("TKVtx"); + + produces("z0"); + + for (const auto& tag : iConfig.getParameter>("emClusters")) { + emCands_.push_back(consumes(tag)); + } + for (const auto& tag : iConfig.getParameter>("hadClusters")) { + hadCands_.push_back(consumes(tag)); + } + + const std::string& algo = iConfig.getParameter("pfAlgo"); + if (algo == "PFAlgo3") { + l1pfalgo_.reset(new l1tpf_impl::PFAlgo3(iConfig)); + } else if (algo == "PFAlgo2HGC") { + l1pfalgo_.reset(new l1tpf_impl::PFAlgo2HGC(iConfig)); + } else if (algo == "BitwisePFAlgo") { + l1pfalgo_.reset(new l1tpf_impl::BitwisePFAlgo(iConfig)); + } else + throw cms::Exception("Configuration", "Unsupported PFAlgo"); + + const std::string& pualgo = iConfig.getParameter("puAlgo"); + if (pualgo == "Puppi") { + l1pualgo_.reset(new l1tpf_impl::PuppiAlgo(iConfig)); + } else if (pualgo == "LinearizedPuppi") { + l1pualgo_.reset(new l1tpf_impl::LinearizedPuppiAlgo(iConfig)); + } else + throw cms::Exception("Configuration", "Unsupported PUAlgo"); + + std::string vtxAlgo = iConfig.getParameter("vtxAlgo"); + if (vtxAlgo == "TP") + vtxAlgo_ = l1tpf_impl::PUAlgoBase::VertexAlgo::TP; + else if (vtxAlgo == "old") + vtxAlgo_ = l1tpf_impl::PUAlgoBase::VertexAlgo::Old; + else if (vtxAlgo == "external") { + vtxAlgo_ = l1tpf_impl::PUAlgoBase::VertexAlgo::External; + const std::string& vtxFormat = iConfig.getParameter("vtxFormat"); + if (vtxFormat == "TkPrimaryVertex") { + extTkVtx_ = consumes>(iConfig.getParameter("vtxCollection")); + } else + throw cms::Exception("Configuration") << "Unsupported vtxFormat " << vtxFormat << "\n"; + } else + throw cms::Exception("Configuration") << "Unsupported vtxAlgo " << vtxAlgo << "\n"; + + for (const std::string& label : l1pualgo_->puGlobalNames()) { + produces(label); + } + + if (!regionDumpName_.empty()) { + TokGenOrigin_ = consumes(iConfig.getParameter("genOrigin")); + } + for (int tot = 0; tot <= 1; ++tot) { + for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) { + produces(std::string(tot ? "totNL1" : "maxNL1") + l1tpf_impl::Region::inputTypeName(i)); + } + for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) { + produces(std::string(tot ? "totNL1PF" : "maxNL1PF") + l1tpf_impl::Region::outputTypeName(i)); + produces(std::string(tot ? "totNL1Puppi" : "maxNL1Puppi") + l1tpf_impl::Region::outputTypeName(i)); + } + } + for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) { + produces>(std::string("vecNL1") + l1tpf_impl::Region::inputTypeName(i)); + } + for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) { + produces>(std::string("vecNL1PF") + l1tpf_impl::Region::outputTypeName(i)); + produces>(std::string("vecNL1Puppi") + l1tpf_impl::Region::outputTypeName(i)); + } +} + +L1TPFProducer::~L1TPFProducer() { + // do anything here that needs to be done at desctruction time + // (e.g. close files, deallocate resources etc.) + if (fRegionDump_) + fclose(fRegionDump_); + if (fRegionCOE_) + fRegionCOE_->close(); +} + +void L1TPFProducer::beginStream(edm::StreamID id) { + if (!regionDumpName_.empty()) { + if (id == 0) { + fRegionDump_ = fopen(regionDumpName_.c_str(), "wb"); + } else { + edm::LogWarning("L1TPFProducer") + << "Job running with multiple streams, but dump file will have only events on stream zero."; + } + } + if (!regionCOEName_.empty()) { + if (id == 0) { + fRegionCOE_.reset(new l1tpf_impl::COEFile(config_)); + } else { + edm::LogWarning("L1TPFProducer") + << "Job running with multiple streams, but COE file will dump only events on stream zero."; + } + } +} + +// ------------ method called to produce the data ------------ +void L1TPFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + // clear the regions also at the beginning, in case one event didn't complete but the job continues on + l1regions_.clear(); + + /// ------ READ TRACKS ---- + if (hasTracks_) { + edm::Handle htracks; + iEvent.getByToken(tkCands_, htracks); + const auto& tracks = *htracks; + for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) { + const auto& tk = tracks[itk]; + // adding objects to PF + if (debugR_ > 0 && deltaR(tk.eta(), tk.phi(), debugEta_, debugPhi_) > debugR_) + continue; + if (tk.pt() > trkPt_ && tk.nStubs() >= trkMinStubs_ && tk.normalizedChi2() < trkMaxChi2_) { + l1regions_.addTrack(tk, l1t::PFTrackRef(htracks, itk)); + } + } + } + + /// ------ READ MUONS ---- + /// ------- first check that not more than one version of muons (standaloneMu or trackerMu) is set to be used in l1pflow + if (useStandaloneMuons_ && useTrackerMuons_) { + throw cms::Exception( + "Configuration", + "setting useStandaloneMuons=True && useTrackerMuons=True is not to be done, as it would duplicate all muons\n"); + } + + if (useStandaloneMuons_) { + edm::Handle muons; + iEvent.getByToken(muCands_, muons); + for (auto it = muons->begin(0), ed = muons->end(0); it != ed; ++it) { + const l1t::Muon& mu = *it; + if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_) + continue; + l1regions_.addMuon(mu, l1t::PFCandidate::MuonRef(muons, muons->key(it))); + } + } + + if (useTrackerMuons_) { + edm::Handle muons; + iEvent.getByToken(tkMuCands_, muons); + for (auto it = muons->begin(), ed = muons->end(); it != ed; ++it) { + const l1t::TkMuon& mu = *it; + if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_) + continue; + l1regions_.addMuon(mu); // FIXME add a l1t::PFCandidate::MuonRef + } + } + + // ------ READ CALOS ----- + edm::Handle caloHandle; + for (const auto& tag : emCands_) { + iEvent.getByToken(tag, caloHandle); + const auto& calos = *caloHandle; + for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) { + const auto& calo = calos[ic]; + if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_) + continue; + if (calo.pt() > emPtCut_) + l1regions_.addEmCalo(calo, l1t::PFClusterRef(caloHandle, ic)); + } + } + for (const auto& tag : hadCands_) { + iEvent.getByToken(tag, caloHandle); + const auto& calos = *caloHandle; + for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) { + const auto& calo = calos[ic]; + if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_) + continue; + if (calo.pt() > hadPtCut_) + l1regions_.addCalo(calo, l1t::PFClusterRef(caloHandle, ic)); + } + } + + // First, get a copy of the discretized and corrected inputs, and write them out + iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/true), "EmCalo"); + iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/false), "Calo"); + iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/false), "TK"); + if (fRegionDump_) { + uint32_t run = iEvent.id().run(), lumi = iEvent.id().luminosityBlock(); + uint64_t event = iEvent.id().event(); + fwrite(&run, sizeof(uint32_t), 1, fRegionDump_); + fwrite(&lumi, sizeof(uint32_t), 1, fRegionDump_); + fwrite(&event, sizeof(uint64_t), 1, fRegionDump_); + l1tpf_impl::writeManyToFile(l1regions_.regions(), fRegionDump_); + } + + // Then save the regions to the COE file + // Do it here because there is some sorting going on in a later function + if (fRegionCOE_ && fRegionCOE_->is_open() && neventsproduced_ < neventscoemax_) { + std::vector regions = l1regions_.regions(); + fRegionCOE_->writeTracksToFile(regions, neventsproduced_ == 0); + } + neventsproduced_++; + + // Then do the vertexing, and save it out + float z0; + if (vtxAlgo_ == l1tpf_impl::PUAlgoBase::VertexAlgo::External) { + z0 = 0; + double ptsum = 0; + if (!extTkVtx_.isUninitialized()) { + edm::Handle> vtxHandle; + iEvent.getByToken(extTkVtx_, vtxHandle); + for (const l1t::TkPrimaryVertex& vtx : *vtxHandle) { + if (ptsum == 0 || vtx.sum() > ptsum) { + z0 = vtx.zvertex(); + ptsum = vtx.sum(); + } + } + } else + throw cms::Exception("LogicError", "Inconsistent vertex configuration"); + } + l1pualgo_->doVertexing(l1regions_.regions(), vtxAlgo_, z0); + iEvent.put(std::make_unique(z0), "z0"); + if (fRegionDump_) { + fwrite(&z0, sizeof(float), 1, fRegionDump_); + edm::Handle hGenOrigin; + iEvent.getByToken(TokGenOrigin_, hGenOrigin); + const math::XYZPointF& genOrigin = *hGenOrigin; + float genZ = genOrigin.Z(); + fwrite(&genZ, sizeof(float), 1, fRegionDump_); + } + + // Then also save the tracks with a vertex cut + iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/true), "TKVtx"); + + // Then run PF in each region + for (auto& l1region : l1regions_.regions()) { + l1pfalgo_->runPF(l1region); + l1pualgo_->runChargedPV(l1region, z0); + } + // save PF into the event + iEvent.put(l1regions_.fetch(false), "PF"); + + // Then get our alphas (globally) + std::vector puGlobals; + l1pualgo_->doPUGlobals(l1regions_.regions(), -1., puGlobals); // FIXME we don't have yet an external PU estimate + const std::vector& puGlobalNames = l1pualgo_->puGlobalNames(); + if (puGlobals.size() != puGlobalNames.size()) + throw cms::Exception("LogicError", "Mismatch in the number of global pileup inputs"); + for (unsigned int i = 0, n = puGlobalNames.size(); i < n; ++i) { + iEvent.put(std::make_unique(puGlobals[i]), puGlobalNames[i]); + } + if (fRegionDump_) { + l1tpf_impl::writeManyToFile(puGlobals, fRegionDump_); + } + + // Then run puppi (regionally) + for (auto& l1region : l1regions_.regions()) { + l1pualgo_->runNeutralsPU(l1region, -1., puGlobals); + } + // and save puppi + iEvent.put(l1regions_.fetch(true), "Puppi"); + + // Then go do the multiplicities + + for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) { + auto totAndMax = l1regions_.totAndMaxInput(i); + addUInt(totAndMax.first, std::string("totNL1") + l1tpf_impl::Region::inputTypeName(i), iEvent); + addUInt(totAndMax.second, std::string("maxNL1") + l1tpf_impl::Region::inputTypeName(i), iEvent); + iEvent.put(l1regions_.vecInput(i), std::string("vecNL1") + l1tpf_impl::Region::inputTypeName(i)); + } + for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) { + auto totAndMaxPF = l1regions_.totAndMaxOutput(i, false); + auto totAndMaxPuppi = l1regions_.totAndMaxOutput(i, true); + addUInt(totAndMaxPF.first, std::string("totNL1PF") + l1tpf_impl::Region::outputTypeName(i), iEvent); + addUInt(totAndMaxPF.second, std::string("maxNL1PF") + l1tpf_impl::Region::outputTypeName(i), iEvent); + addUInt(totAndMaxPuppi.first, std::string("totNL1Puppi") + l1tpf_impl::Region::outputTypeName(i), iEvent); + addUInt(totAndMaxPuppi.second, std::string("maxNL1Puppi") + l1tpf_impl::Region::outputTypeName(i), iEvent); + iEvent.put(l1regions_.vecOutput(i, false), std::string("vecNL1PF") + l1tpf_impl::Region::outputTypeName(i)); + iEvent.put(l1regions_.vecOutput(i, true), std::string("vecNL1Puppi") + l1tpf_impl::Region::outputTypeName(i)); + } + + // finally clear the regions + l1regions_.clear(); +} + +void L1TPFProducer::addUInt(unsigned int value, std::string iLabel, edm::Event& iEvent) { + iEvent.put(std::make_unique(value), iLabel); +} + +//define this as a plug-in +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TPFProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc new file mode 100644 index 0000000000000..65443eb176fdf --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc @@ -0,0 +1,112 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCluster.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/HGC3DClusterEgID.h" +#include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" + +namespace l1tpf { + class PFClusterProducerFromHGC3DClusters : public edm::stream::EDProducer<> { + public: + explicit PFClusterProducerFromHGC3DClusters(const edm::ParameterSet &); + ~PFClusterProducerFromHGC3DClusters() override {} + + private: + edm::EDGetTokenT src_; + bool emOnly_; + double etCut_; + StringCutObjectSelector preEmId_; + l1tpf::HGC3DClusterEgID emVsPionID_, emVsPUID_; + bool hasEmId_; + l1tpf::corrector corrector_; + l1tpf::ParametricResolution resol_; + + void produce(edm::Event &, const edm::EventSetup &) override; + + }; // class +} // namespace l1tpf + +l1tpf::PFClusterProducerFromHGC3DClusters::PFClusterProducerFromHGC3DClusters(const edm::ParameterSet &iConfig) + : src_(consumes(iConfig.getParameter("src"))), + emOnly_(iConfig.getParameter("emOnly")), + etCut_(iConfig.getParameter("etMin")), + preEmId_(iConfig.getParameter("preEmId")), + emVsPionID_(iConfig.getParameter("emVsPionID")), + emVsPUID_(iConfig.getParameter("emVsPUID")), + hasEmId_((iConfig.existsAs("preEmId") && !iConfig.getParameter("preEmId").empty()) || + !emVsPionID_.method().empty()), + corrector_(iConfig.getParameter("corrector"), + emOnly_ || iConfig.getParameter("corrector").empty() + ? -1 + : iConfig.getParameter("correctorEmfMax")), + resol_(iConfig.getParameter("resol")) { + if (!emVsPionID_.method().empty()) { + emVsPionID_.prepareTMVA(); + } + if (!emVsPUID_.method().empty()) { + emVsPUID_.prepareTMVA(); + } + + produces(); + if (hasEmId_) { + produces("em"); + produces("had"); + } +} + +void l1tpf::PFClusterProducerFromHGC3DClusters::produce(edm::Event &iEvent, const edm::EventSetup &) { + auto out = std::make_unique(); + std::unique_ptr outEm, outHad; + if (hasEmId_) { + outEm.reset(new l1t::PFClusterCollection()); + outHad.reset(new l1t::PFClusterCollection()); + } + edm::Handle multiclusters; + iEvent.getByToken(src_, multiclusters); + + for (auto it = multiclusters->begin(0), ed = multiclusters->end(0); it != ed; ++it) { + float pt = it->pt(), hoe = it->hOverE(); + bool isEM = hasEmId_ ? preEmId_(*it) : emOnly_; + if (emOnly_) { + if (hoe == -1) + continue; + pt /= (1 + hoe); + hoe = 0; + } + if (pt <= etCut_) + continue; + + l1t::PFCluster cluster(pt, it->eta(), it->phi(), hoe, /*isEM=*/isEM); + if (!emVsPUID_.method().empty()) { + if (!emVsPUID_.passID(*it, cluster)) { + continue; + } + } + if (!emVsPionID_.method().empty()) { + cluster.setIsEM(emVsPionID_.passID(*it, cluster)); + } + if (corrector_.valid()) + corrector_.correctPt(cluster); + cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); + + out->push_back(cluster); + out->back().addConstituent(edm::Ptr(multiclusters, multiclusters->key(it))); + if (hasEmId_) { + (isEM ? outEm : outHad)->push_back(out->back()); + } + } + + iEvent.put(std::move(out)); + if (hasEmId_) { + iEvent.put(std::move(outEm), "em"); + iEvent.put(std::move(outHad), "had"); + } +} +using l1tpf::PFClusterProducerFromHGC3DClusters; +DEFINE_FWK_MODULE(PFClusterProducerFromHGC3DClusters); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc new file mode 100644 index 0000000000000..085110ff0c2d9 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc @@ -0,0 +1,60 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCluster.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" + +namespace l1tpf { + class PFClusterProducerFromL1EGClusters : public edm::stream::EDProducer<> { + public: + explicit PFClusterProducerFromL1EGClusters(const edm::ParameterSet &); + ~PFClusterProducerFromL1EGClusters() override {} + + private: + edm::EDGetTokenT src_; + double etCut_; + l1tpf::corrector corrector_; + l1tpf::ParametricResolution resol_; + + void produce(edm::Event &, const edm::EventSetup &) override; + + }; // class +} // namespace l1tpf + +l1tpf::PFClusterProducerFromL1EGClusters::PFClusterProducerFromL1EGClusters(const edm::ParameterSet &iConfig) + : src_(consumes(iConfig.getParameter("src"))), + etCut_(iConfig.getParameter("etMin")), + corrector_(iConfig.getParameter("corrector"), -1), + resol_(iConfig.getParameter("resol")) { + produces(); +} + +void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const edm::EventSetup &) { + std::unique_ptr out(new l1t::PFClusterCollection()); + edm::Handle clusters; + iEvent.getByToken(src_, clusters); + + unsigned int index = 0; + for (auto it = clusters->begin(), ed = clusters->end(); it != ed; ++it, ++index) { + if (it->pt() <= etCut_) + continue; + + l1t::PFCluster cluster( + it->pt(), it->eta(), it->phi(), /*hOverE=*/0., /*isEM=*/true); // it->hovere() seems to return random values + if (corrector_.valid()) + corrector_.correctPt(cluster); + cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); + + out->push_back(cluster); + out->back().addConstituent(edm::Ptr(clusters, index)); + } + + iEvent.put(std::move(out)); +} +using l1tpf::PFClusterProducerFromL1EGClusters; +DEFINE_FWK_MODULE(PFClusterProducerFromL1EGClusters); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc new file mode 100644 index 0000000000000..aee20808fbb8a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc @@ -0,0 +1,88 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/Framework/interface/ESHandle.h" +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "FWCore/Framework/interface/ESWatcher.h" + +#include "DataFormats/L1TParticleFlow/interface/PFTrack.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/L1TPFUtils.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" + +namespace l1tpf { + class PFTrackProducerFromL1Tracks : public edm::stream::EDProducer<> { + public: + explicit PFTrackProducerFromL1Tracks(const edm::ParameterSet &); + ~PFTrackProducerFromL1Tracks() override {} + + private: + edm::EDGetTokenT> TrackTag_; + edm::ESWatcher BFieldWatcher_; + edm::ESGetToken BFieldTag_; + int nParam_; + float fBz_; + l1tpf::ParametricResolution resolCalo_, resolTrk_; + + void produce(edm::Event &, const edm::EventSetup &) override; + + }; // class +} // namespace l1tpf + +l1tpf::PFTrackProducerFromL1Tracks::PFTrackProducerFromL1Tracks(const edm::ParameterSet &iConfig) + : TrackTag_(consumes>(iConfig.getParameter("L1TrackTag"))), + BFieldTag_{esConsumes()}, + nParam_(iConfig.getParameter("nParam")), + resolCalo_(iConfig.getParameter("resolCalo")), + resolTrk_(iConfig.getParameter("resolTrack")) { + produces(); +} + +void l1tpf::PFTrackProducerFromL1Tracks::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + if (BFieldWatcher_.check(iSetup)) { + fBz_ = iSetup.getData(BFieldTag_).inTesla(GlobalPoint(0, 0, 0)).z(); + } + + std::unique_ptr out(new l1t::PFTrackCollection()); + + // https://github.com/skinnari/cmssw/blob/80c19f1b721325c3a02ee0482f72fb974a4c3bf7/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc + edm::Handle> htracks; + iEvent.getByToken(TrackTag_, htracks); + const auto &tracks = *htracks; + + for (unsigned int i = 0, n = tracks.size(); i < n; ++i) { + const auto &tk = tracks[i]; + + float pt = tk.momentum().perp(); + float eta = tk.momentum().eta(); + float phi = tk.momentum().phi(); + float z0 = tk.POCA().z(); //cm + int charge = tk.rInv() > 0 ? +1 : -1; + + reco::Candidate::PolarLorentzVector p4p(pt, eta, phi, 0.137); // pion mass + reco::Particle::LorentzVector p4(p4p.X(), p4p.Y(), p4p.Z(), p4p.E()); + reco::Particle::Point vtx(0., 0., z0); + + auto caloetaphi = l1tpf::propagateToCalo(p4, math::XYZTLorentzVector(0., 0., z0, 0.), charge, fBz_); + + float trkErr = resolTrk_(pt, std::abs(eta)); + float caloErr = resolCalo_(pt, std::abs(eta)); + int quality = 1; + out->emplace_back(charge, + p4, + vtx, + l1t::PFTrack::TrackRef(htracks, i), + nParam_, + caloetaphi.first, + caloetaphi.second, + trkErr, + caloErr, + quality); + } + iEvent.put(std::move(out)); +} +using l1tpf::PFTrackProducerFromL1Tracks; +DEFINE_FWK_MODULE(PFTrackProducerFromL1Tracks); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py new file mode 100644 index 0000000000000..c43e85c93f71d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py @@ -0,0 +1,316 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.Phase2L1ParticleFlow.pfTracksFromL1Tracks_cfi import pfTracksFromL1Tracks +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromL1EGClusters_cfi import pfClustersFromL1EGClusters +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromCombinedCalo_cfi import pfClustersFromCombinedCalo +from L1Trigger.Phase2L1ParticleFlow.l1pfProducer_cfi import l1pfProducer + +# Using phase2_hgcalV10 to customize the config for all 106X samples, since there's no other modifier for it +from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 + +# Calorimeter part: ecal + hcal + hf only +pfClustersFromCombinedCaloHCal = pfClustersFromCombinedCalo.clone( + hcalHGCTowers = [], hcalDigis = [], + hcalDigisBarrel = True, hcalDigisHF = False, + hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 2.582, 2.191, -0.077), + scale = cms.vdouble( 0.122, 0.143, 0.465), + kind = cms.string('calo'), + )) +phase2_hgcalV10.toModify(pfClustersFromCombinedCaloHCal, + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 3.084, 2.715, 0.107), + scale = cms.vdouble( 0.118, 0.130, 0.442), + kind = cms.string('calo'), + ) +) +phase2_hgcalV11.toModify(pfClustersFromCombinedCaloHCal, + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 2.909, 2.864, 0.294), + scale = cms.vdouble( 0.119, 0.127, 0.442), + kind = cms.string('calo'), + ) +) + +pfTracksFromL1TracksBarrel = pfTracksFromL1Tracks.clone( + resolCalo = pfClustersFromCombinedCaloHCal.resol.clone(), +) + +pfClustersFromCombinedCaloHF = pfClustersFromCombinedCalo.clone( + ecalCandidates = [], hcalHGCTowers = [], + phase2barrelCaloTowers = [], + hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hfcorr.root"), + resol = cms.PSet( + etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), + offset = cms.vdouble( 1.099, 0.930, 1.009, 1.369), + scale = cms.vdouble( 0.152, 0.151, 0.144, 0.179), + kind = cms.string('calo'), + )) +phase2_hgcalV10.toModify(pfClustersFromCombinedCaloHF, + hcalCandidates = cms.VInputTag(cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")), + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hfcorr_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), + offset = cms.vdouble(-0.846, 0.696, 1.313, 1.044), + scale = cms.vdouble( 0.815, 0.164, 0.146, 0.192), + kind = cms.string('calo'), + ) +) +phase2_hgcalV11.toModify(pfClustersFromCombinedCaloHF, + hcalCandidates = cms.VInputTag(cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")), + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hfcorr_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), + offset = cms.vdouble(-1.125, 1.220, 1.514, 1.414), + scale = cms.vdouble( 0.868, 0.159, 0.148, 0.194), + kind = cms.string('calo'), + ) +) + +# Calorimeter part: hgcal +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromHGC3DClusters_cfi import pfClustersFromHGC3DClusters + +l1ParticleFlow_calo_Task = cms.Task( + pfClustersFromL1EGClusters , + pfClustersFromCombinedCaloHCal , + pfClustersFromCombinedCaloHF , + pfClustersFromHGC3DClusters +) +l1ParticleFlow_calo = cms.Sequence(l1ParticleFlow_calo_Task) + + +# PF in the barrel +l1pfProducerBarrel = l1pfProducer.clone( + # inputs + tracks = cms.InputTag('pfTracksFromL1TracksBarrel'), + emClusters = [ cms.InputTag('pfClustersFromL1EGClusters') ], + hadClusters = [ cms.InputTag('pfClustersFromCombinedCaloHCal:calibrated') ], + # track-based PUPPI + puppiUsingBareTracks = True, + puppiDrMin = 0.07, + puppiPtMax = 50., + vtxAlgo = "external", + vtxFormat = cms.string("TkPrimaryVertex"), + vtxCollection = cms.InputTag("L1TkPrimaryVertex",""), + # puppi tuning + puAlgo = "LinearizedPuppi", + puppiEtaCuts = cms.vdouble( 1.6 ), # just one bin + puppiPtCuts = cms.vdouble( 1.0 ), + puppiPtCutsPhotons = cms.vdouble( 1.0 ), + puppiPtSlopes = cms.vdouble( 0.3 ), # coefficient for pT + puppiPtSlopesPhotons = cms.vdouble( 0.3 ), + puppiPtZeros = cms.vdouble( 4.0 ), # ballpark pT from PU + puppiPtZerosPhotons = cms.vdouble( 2.5 ), + puppiAlphaSlopes = cms.vdouble( 0.7 ), # coefficient for alpha + puppiAlphaSlopesPhotons = cms.vdouble( 0.7 ), + puppiAlphaZeros = cms.vdouble( 6.0 ), # ballpark alpha from PU + puppiAlphaZerosPhotons = cms.vdouble( 6.0 ), + puppiAlphaCrops = cms.vdouble( 4 ), # max. absolute value for alpha term + puppiAlphaCropsPhotons = cms.vdouble( 4 ), + puppiPriors = cms.vdouble( 5.0 ), + puppiPriorsPhotons = cms.vdouble( 1.0 ), + # regionalize + useRelativeRegionalCoordinates = cms.bool(False), + trackRegionMode = cms.string("atCalo"), + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-1.5,1.5), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.3), + phiExtra = cms.double(0.0) + ), + ), +) +l1ParticleFlow_pf_barrel_Task = cms.Task( + pfTracksFromL1TracksBarrel , + l1pfProducerBarrel +) +l1ParticleFlow_pf_barrel = cms.Sequence(l1ParticleFlow_pf_barrel_Task) + + + +# PF in HGCal +pfTracksFromL1TracksHGCal = pfTracksFromL1Tracks.clone( + resolCalo = pfClustersFromHGC3DClusters.resol.clone(), +) +l1pfProducerHGCal = l1pfProducer.clone( + # algo + pfAlgo = "PFAlgo2HGC", + # inputs + tracks = cms.InputTag('pfTracksFromL1TracksHGCal'), + emClusters = [ ], # EM clusters are not used (only added to NTuple for calibration/monitoring) + hadClusters = [ cms.InputTag("pfClustersFromHGC3DClusters") ], + # track-based PUPPI + puppiDrMin = 0.04, + puppiPtMax = 50., + puppiUsingBareTracks = True, + vtxAlgo = "external", + vtxFormat = cms.string("TkPrimaryVertex"), + vtxCollection = cms.InputTag("L1TkPrimaryVertex",""), + # puppi tuning + puAlgo = "LinearizedPuppi", + puppiEtaCuts = cms.vdouble( 2.0, 2.4, 3.1 ), # two bins in the tracker (different pT), one outside + puppiPtCuts = cms.vdouble( 1.0, 2.0, 4.0 ), + puppiPtCutsPhotons = cms.vdouble( 1.0, 2.0, 4.0 ), + puppiPtSlopes = cms.vdouble( 0.3, 0.3, 0.3 ), # coefficient for pT + puppiPtSlopesPhotons = cms.vdouble( 0.4, 0.4, 0.4 ), #When e/g ID not applied, use: cms.vdouble( 0.3, 0.3, 0.3 ), + puppiPtZeros = cms.vdouble( 5.0, 7.0, 9.0 ), # ballpark pT from PU + puppiPtZerosPhotons = cms.vdouble( 3.0, 4.0, 5.0 ), + puppiAlphaSlopes = cms.vdouble( 1.5, 1.5, 2.2 ), + puppiAlphaSlopesPhotons = cms.vdouble( 1.5, 1.5, 2.2 ), + puppiAlphaZeros = cms.vdouble( 6.0, 6.0, 9.0 ), + puppiAlphaZerosPhotons = cms.vdouble( 6.0, 6.0, 9.0 ), + puppiAlphaCrops = cms.vdouble( 3 , 3 , 4 ), # max. absolute value for alpha term + puppiAlphaCropsPhotons = cms.vdouble( 3 , 3 , 4 ), + puppiPriors = cms.vdouble( 5.0, 5.0, 7.0 ), + puppiPriorsPhotons = cms.vdouble( 1.5, 1.5, 5.0 ), #When e/g ID not applied, use: cms.vdouble( 3.5, 3.5, 7.0 ), + # regionalize + useRelativeRegionalCoordinates = cms.bool(False), + trackRegionMode = cms.string("atCalo"), + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-2.5,-1.5), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.3), + phiExtra = cms.double(0.0) + ), + cms.PSet( + etaBoundaries = cms.vdouble(1.5,2.5), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.3), + phiExtra = cms.double(0.0) + ), + ), +) +l1pfProducerHGCal.linking.trackCaloDR = 0.1 # more precise cluster positions +l1pfProducerHGCal.linking.ecalPriority = False +l1pfProducerHGCalNoTK = l1pfProducerHGCal.clone(regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-3,-2.5), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.3), + phiExtra = cms.double(0.0) + ), + cms.PSet( + etaBoundaries = cms.vdouble(2.5,3), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.3), + phiExtra = cms.double(0.0) + ), +)) + +l1ParticleFlow_pf_hgcal_Task = cms.Task( + pfTracksFromL1TracksHGCal , + l1pfProducerHGCal , + l1pfProducerHGCalNoTK +) +l1ParticleFlow_pf_hgcal = cms.Sequence(l1ParticleFlow_pf_hgcal_Task) + + + +# PF in HF +l1pfProducerHF = l1pfProducer.clone( + # inputs + tracks = cms.InputTag(''), # no tracks + emClusters = [ ], + hadClusters = [ cms.InputTag('pfClustersFromCombinedCaloHF:calibrated') ], + hadPtCut = 15, + # not really useful, but for consistency + puppiDrMin = 0.1, + puppiPtMax = 100., + vtxAlgo = "external", + vtxFormat = cms.string("TkPrimaryVertex"), + vtxCollection = cms.InputTag("L1TkPrimaryVertex",""), + # puppi tuning + puAlgo = "LinearizedPuppi", + puppiEtaCuts = cms.vdouble( 5.5 ), # one bin + puppiPtCuts = cms.vdouble( 10. ), + puppiPtCutsPhotons = cms.vdouble( 10. ), # not used (no photons in HF) + puppiPtSlopes = cms.vdouble( 0.25), + puppiPtSlopesPhotons = cms.vdouble( 0.25), # not used (no photons in HF) + puppiPtZeros = cms.vdouble( 14. ), # ballpark pT from PU + puppiPtZerosPhotons = cms.vdouble( 14. ), # not used (no photons in HF) + puppiAlphaSlopes = cms.vdouble( 0.6 ), + puppiAlphaSlopesPhotons = cms.vdouble( 0.6 ), # not used (no photons in HF) + puppiAlphaZeros = cms.vdouble( 9.0 ), + puppiAlphaZerosPhotons = cms.vdouble( 9.0 ), # not used (no photons in HF) + puppiAlphaCrops = cms.vdouble( 4 ), + puppiAlphaCropsPhotons = cms.vdouble( 4 ), # not used (no photons in HF) + puppiPriors = cms.vdouble( 6.0 ), + puppiPriorsPhotons = cms.vdouble( 6.0 ), # not used (no photons in HF) + # regionalize + useRelativeRegionalCoordinates = cms.bool(False), + trackRegionMode = cms.string("atCalo"), + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-5.5,-3), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.0), + phiExtra = cms.double(0.0) + ), + cms.PSet( + etaBoundaries = cms.vdouble(3,5.5), + phiSlices = cms.uint32(1), + etaExtra = cms.double(0.0), + phiExtra = cms.double(0.0) + ), + ) +) +l1ParticleFlow_pf_hf_Task = cms.Task( + l1pfProducerHF +) +l1ParticleFlow_pf_hf = cms.Sequence(l1ParticleFlow_pf_hf_Task) + + +# PF in the TSA Region +l1pfProducerTSA = l1pfProducerBarrel.clone( + trackRegionMode = cms.string("atVertex"), + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-3,3), + phiSlices = cms.uint32(18), + etaExtra = cms.double(0.0), + phiExtra = cms.double(0.0) + ), + ), +) +l1ParticleFlow_pf_tsa = cms.Sequence( + pfTracksFromL1TracksBarrel + + l1pfProducerTSA +) + +# Merging all outputs +l1pfCandidates = cms.EDProducer("L1TPFCandMultiMerger", + pfProducers = cms.VInputTag( + cms.InputTag("l1pfProducerBarrel"), + cms.InputTag("l1pfProducerHGCal"), + cms.InputTag("l1pfProducerHGCalNoTK"), + cms.InputTag("l1pfProducerHF") + ), + labelsToMerge = cms.vstring("Calo", "TK", "TKVtx", "PF", "Puppi"), +) + +l1ParticleFlow_proper = cms.Sequence( + l1ParticleFlow_calo + + l1ParticleFlow_pf_barrel + + l1ParticleFlow_pf_hgcal + + l1ParticleFlow_pf_hf + + l1pfCandidates +) + +l1ParticleFlow = cms.Sequence(l1ParticleFlow_proper) + +l1ParticleFlowTask = cms.Task( + l1ParticleFlow_calo_Task, + l1ParticleFlow_pf_barrel_Task, + l1ParticleFlow_pf_hgcal_Task, + l1ParticleFlow_pf_hf_Task, + cms.Task(l1pfCandidates) +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py new file mode 100644 index 0000000000000..05d040b0088c9 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py @@ -0,0 +1,38 @@ +import FWCore.ParameterSet.Config as cms + +from RecoMET.METProducers.pfMet_cfi import pfMet +_pfMet = pfMet.clone(calculateSignificance = False) +l1PFMetCalo = _pfMet.clone(src = "l1pfCandidates:Calo") +l1PFMetPF = _pfMet.clone(src = "l1pfCandidates:PF") +l1PFMetPuppi = _pfMet.clone(src = "l1pfCandidates:Puppi") + +l1PFMets = cms.Sequence(l1PFMetCalo + l1PFMetPF + l1PFMetPuppi) + +from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets +_ak4PFJets = ak4PFJets.clone(doAreaFastjet = False) +ak4PFL1Calo = _ak4PFJets.clone(src = 'l1pfCandidates:Calo') +ak4PFL1PF = _ak4PFJets.clone(src = 'l1pfCandidates:PF') +ak4PFL1Puppi = _ak4PFJets.clone(src = 'l1pfCandidates:Puppi') + +_correctedJets = cms.EDProducer("L1TCorrectedPFJetProducer", + jets = cms.InputTag("_tag_"), + correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200.root"), + correctorDir = cms.string("_dir_"), + copyDaughters = cms.bool(False) +) +# Using phase2_hgcalV10 to customize the config for all 106X samples, since there's no other modifier for it +from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +phase2_hgcalV10.toModify(_correctedJets, correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_106X.root") +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 +phase2_hgcalV11.toModify(_correctedJets, correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root") + +ak4PFL1CaloCorrected = _correctedJets.clone(jets = 'ak4PFL1Calo', correctorDir = 'L1CaloJets') +ak4PFL1PFCorrected = _correctedJets.clone(jets = 'ak4PFL1PF', correctorDir = 'L1PFJets') +ak4PFL1PuppiCorrected = _correctedJets.clone(jets = 'ak4PFL1Puppi', correctorDir = 'L1PuppiJets') + +l1PFJets = cms.Sequence( + ak4PFL1Calo + ak4PFL1PF + ak4PFL1Puppi + + ak4PFL1CaloCorrected + ak4PFL1PFCorrected + ak4PFL1PuppiCorrected +) + + diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfProducer_cfi.py new file mode 100644 index 0000000000000..08941eb2bc018 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1pfProducer_cfi.py @@ -0,0 +1,72 @@ +import FWCore.ParameterSet.Config as cms + +from math import sqrt + +l1pfProducer = cms.EDProducer("L1TPFProducer", + tracks = cms.InputTag('pfTracksFromL1Tracks'), + muons = cms.InputTag('simGmtStage2Digis',), + tkMuons = cms.InputTag('L1TkMuons'), + # type of muons to be used in PF (enable only one at a time) + useStandaloneMuons = cms.bool(True), + useTrackerMuons = cms.bool(False), + emClusters = cms.VInputTag(cms.InputTag('pfClustersFromHGC3DClustersEM'), cms.InputTag('pfClustersFromL1EGClusters')), + hadClusters = cms.VInputTag(cms.InputTag('pfClustersFromCombinedCalo:calibrated')), + emPtCut = cms.double(0.5), + hadPtCut = cms.double(1.0), + trkPtCut = cms.double(2.0), + trkMinStubs = cms.uint32(4), + trkMaxChi2 = cms.double(15), + etaCharged = cms.double(2.5), + puppiDr = cms.double(0.3), + puppiDrMin = cms.double(0.1), + puppiPtMax = cms.double(999), + puppiEtaCuts = cms.vdouble(1.5, 2.5, 3.0, 5.5), + puppiPtCuts = cms.vdouble(0.0, 3.0, 6.0, 8.0), + puppiPtCutsPhotons = cms.vdouble(0.0, 3.0, 6.0, 8.0), + puppiUsingBareTracks = cms.bool(False), # use PF + vtxRes = cms.double(0.333), + vtxAlgo = cms.string("TP"), + vtxAdaptiveCut = cms.bool(True), + pfAlgo = cms.string("PFAlgo3"), + puAlgo = cms.string("Puppi"), + linking = cms.PSet( + # track -> mu linking configurables + trackMuDR = cms.double(0.2), # accounts for poor resolution of standalone, and missing propagations + trackMuMatch = cms.string("boxBestByPtRatio"), # also drBestByPtRatio + # track -> em linking configurables + trackEmDR = cms.double(0.04), # 1 Ecal crystal size is 0.02, and ~2 cm in HGCal is ~0.007 + trackEmUseAlsoTrackSigma = cms.bool(True), # also use the track uncertainty for electron linking + trackEmMayUseCaloMomenta = cms.bool(True), # use calo momenta for 1 emcalo to 1 track match electrons + # em -> calo linking configurables + emCaloDR = cms.double(0.10), # 1 Hcal tower size is ~0.09 + caloEmPtMinFrac = cms.double(0.5), # Calo object must have an EM Et at least half of that of the EM cluster to allow linking + emCaloUseAlsoCaloSigma = cms.bool(True), # also use the track uncertainty for electron linking + emCaloSubtractionPtSlope = cms.double(1.2), # e/pi ratio of HCal + # track -> calo linking configurables + trackCaloLinkMetric = cms.string("bestByDRPt"), + #trackCaloLinkMetric = cms.string("bestByDR"), + trackCaloDR = cms.double(0.15), + trackCaloNSigmaLow = cms.double(2.0), + trackCaloNSigmaHigh = cms.double(sqrt(1.0)), # sqrt(x) since in the hardware we use sigma squared + useTrackCaloSigma = cms.bool(True), # take the uncertainty on the calo cluster from the track, for linking purposes + sumTkCaloErr2 = cms.bool(True), # add up track calo errors in quadrature instead of linearly + rescaleTracks = cms.bool(False), # if tracks exceed the calo, rescale the track momenta + useCaloTrkWeightedAverage = cms.bool(False), # do the weighted average of track & calo pTs if it's a 1-1 link + # how to deal with unlinked tracks + maxInvisiblePt = cms.double(10.0), # max allowed pt of a track with no calo energy + tightTrackMinStubs = cms.uint32(6), + tightTrackMaxChi2 = cms.double(50), + tightTrackMaxInvisiblePt = cms.double(20), + # how to deal with neutrals + ecalPriority = cms.bool(True), # take first ecal energy when making neutrals + # other features not turned on: reliniking of neutrals to track-matched calo clusters with track excess + caloReLink = cms.bool(False), + caloReLinkDR = cms.double(0.3), + caloReLinkThreshold = cms.double(0.5), + # other features not turned on: matching too high pt tracks to calo but rescaling track pt (not implemented in PFAlgo3) + rescaleUnmatchedTrack = cms.bool(False), + ), + debug = cms.untracked.int32(0), +) + + diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromCombinedCalo_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromCombinedCalo_cfi.py new file mode 100644 index 0000000000000..1e3c3f2bc8612 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromCombinedCalo_cfi.py @@ -0,0 +1,57 @@ +import FWCore.ParameterSet.Config as cms + +pfClustersFromCombinedCalo = cms.EDProducer("L1TPFCaloProducer", + ecalCandidates = cms.VInputTag(cms.InputTag('pfClustersFromL1EGClusters')), # using EM from towers in HGC, no longer reading also 'pfClustersFromHGC3DClustersEM' + hcalCandidates = cms.VInputTag(), + hcalDigis = cms.VInputTag(cms.InputTag('simHcalTriggerPrimitiveDigis')), + hcalDigisBarrel = cms.bool(False), + hcalDigisHF = cms.bool(True), + phase2barrelCaloTowers = cms.VInputTag(cms.InputTag("L1EGammaClusterEmuProducer",)), + hcalHGCTowers = cms.VInputTag(cms.InputTag("hgcalTowerProducer:HGCalTowerProcessor") ), + hcalHGCTowersHadOnly = cms.bool(False), # take also EM part from towers + emCorrector = cms.string(""), # no need to correct further + hcCorrector = cms.string(""), # no correction to hcal-only in the default scheme + hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr.root"), # correction on linked cluster + hadCorrectorEmfMax = cms.double(-1.0), + ecalClusterer = cms.PSet( + grid = cms.string("phase2"), + zsEt = cms.double(0.4), + seedEt = cms.double(0.5), + minClusterEt = cms.double(0.5), + energyWeightedPosition = cms.bool(True), + energyShareAlgo = cms.string("fractions"), + ), + hcalClusterer = cms.PSet( + grid = cms.string("phase2"), + zsEt = cms.double(0.4), + seedEt = cms.double(0.5), + minClusterEt = cms.double(0.8), + energyWeightedPosition = cms.bool(True), + energyShareAlgo = cms.string("fractions"), + ), + linker = cms.PSet( + algo = cms.string("flat"), + + zsEt = cms.double(0.0), ## Ecal and Hcal are already ZS-ed above + seedEt = cms.double(1.0), + minClusterEt = cms.double(1.0), + energyWeightedPosition = cms.bool(True), + energyShareAlgo = cms.string("fractions"), + + grid = cms.string("phase2"), + hoeCut = cms.double(0.1), + minPhotonEt = cms.double(1.0), + minHadronRawEt = cms.double(1.0), + minHadronEt = cms.double(1.0), + noEmInHGC = cms.bool(False) + ), + resol = cms.PSet( + etaBins = cms.vdouble( 1.300, 1.700, 2.800, 3.200, 4.000, 5.000), + offset = cms.vdouble( 2.572, 1.759, 1.858, 2.407, 1.185, 1.658), + scale = cms.vdouble( 0.132, 0.240, 0.090, 0.138, 0.143, 0.147), + kind = cms.string('calo'), + ), + debug = cms.untracked.int32(0), +) + + diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py new file mode 100644 index 0000000000000..aa13bd5ee3453 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py @@ -0,0 +1,38 @@ +import FWCore.ParameterSet.Config as cms + +import L1Trigger.Phase2L1ParticleFlow.pfClustersFromHGC3DClusters_cfi + +pfClustersFromHGC3DClustersEM = L1Trigger.Phase2L1ParticleFlow.pfClustersFromHGC3DClusters_cfi.pfClustersFromHGC3DClusters.clone( + emOnly = cms.bool(True), + etMin = cms.double(0.0), + corrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/emcorr_hgc.root"), + preEmId = cms.string(""), + resol = cms.PSet( + etaBins = cms.vdouble( 1.900, 2.200, 2.500, 2.800, 2.950), + offset = cms.vdouble( 0.566, 0.557, 0.456, 0.470, 0.324), + scale = cms.vdouble( 0.030, 0.024, 0.024, 0.023, 0.042), + kind = cms.string('calo'), + ) +) + + +from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 +phase2_hgcalV10.toModify(pfClustersFromHGC3DClustersEM, + corrector = "L1Trigger/Phase2L1ParticleFlow/data/emcorr_hgc_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 1.700, 1.900, 2.200, 2.500, 2.800, 2.900), + offset = cms.vdouble( 2.579, 2.176, 1.678, 0.911, 0.672, -2.292), + scale = cms.vdouble( 0.048, 0.026, 0.012, 0.016, 0.022, 0.538), + kind = cms.string('calo') + ), +) +phase2_hgcalV11.toModify(pfClustersFromHGC3DClustersEM, + corrector = "L1Trigger/Phase2L1ParticleFlow/data/emcorr_hgc_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 1.700, 1.900, 2.200, 2.500, 2.800, 2.900), + offset = cms.vdouble( 2.581, 2.289, 1.674, 0.927, 0.604, -2.377), + scale = cms.vdouble( 0.046, 0.025, 0.016, 0.017, 0.023, 0.500), + kind = cms.string('calo') + ), +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py new file mode 100644 index 0000000000000..536835d095d03 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py @@ -0,0 +1,65 @@ +import FWCore.ParameterSet.Config as cms + +pfClustersFromHGC3DClusters = cms.EDProducer("PFClusterProducerFromHGC3DClusters", + src = cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering"), + corrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_HGCal3D_TC.root"), + correctorEmfMax = cms.double(1.125), + preEmId = cms.string("hOverE < 0.3 && hOverE >= 0"), + emVsPionID = cms.PSet( + isPUFilter = cms.bool(False), + preselection = cms.string(""), + method = cms.string("BDT"), # "" to be disabled, "BDT" to be enabled + variables = cms.VPSet( + cms.PSet(name = cms.string("fabs(eta)"), value = cms.string("abs(eta())")), + cms.PSet(name = cms.string("coreShowerLength"), value = cms.string("coreShowerLength()")), + cms.PSet(name = cms.string("maxLayer"), value = cms.string("maxLayer()")), + cms.PSet(name = cms.string("hOverE"), value = cms.string("hOverE()")), + cms.PSet(name = cms.string("sigmaZZ"), value = cms.string("sigmaZZ()")), + ), + weightsFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_vs_Pion_BDTweights.xml.gz"), + wp = cms.string("0.01") + ), + emVsPUID = cms.PSet( + isPUFilter = cms.bool(True), + preselection = cms.string(""), + method = cms.string("BDT"), # "" to be disabled, "BDT" to be enabled + variables = cms.VPSet( + cms.PSet(name = cms.string("fabs(eta)"), value = cms.string("abs(eta())")), + cms.PSet(name = cms.string("coreShowerLength"), value = cms.string("coreShowerLength()")), + cms.PSet(name = cms.string("maxLayer"), value = cms.string("maxLayer()")), + cms.PSet(name = cms.string("sigmaPhiPhiTot"), value = cms.string("sigmaPhiPhiTot()")), + ), + weightsFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_Pion_vs_Neutrino_BDTweights.xml.gz"), + wp = cms.string("-0.02") + ), + emOnly = cms.bool(False), + etMin = cms.double(1.0), + resol = cms.PSet( + etaBins = cms.vdouble( 1.900, 2.200, 2.500, 2.800, 2.950), + offset = cms.vdouble( 2.593, 3.089, 2.879, 2.664, 2.947), + scale = cms.vdouble( 0.120, 0.098, 0.099, 0.098, 0.124), + kind = cms.string('calo') + ), +) + + +from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 +phase2_hgcalV10.toModify(pfClustersFromHGC3DClusters, + corrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_HGCal3D_TC_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 1.700, 1.900, 2.200, 2.500, 2.800, 2.900), + offset = cms.vdouble(-0.819, 0.900, 2.032, 2.841, 2.865, 1.237), + scale = cms.vdouble( 0.320, 0.225, 0.156, 0.108, 0.119, 0.338), + kind = cms.string('calo') + ), +) +phase2_hgcalV11.toModify(pfClustersFromHGC3DClusters, + corrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_HGCal3D_TC_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 1.700, 1.900, 2.200, 2.500, 2.800, 2.900), + offset = cms.vdouble( 1.793, 1.827, 2.363, 2.538, 2.812, 2.642), + scale = cms.vdouble( 0.138, 0.137, 0.124, 0.115, 0.106, 0.121), + kind = cms.string('calo'), + ), +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromL1EGClusters_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromL1EGClusters_cfi.py new file mode 100644 index 0000000000000..ff4e72aa7ec17 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromL1EGClusters_cfi.py @@ -0,0 +1,37 @@ +import FWCore.ParameterSet.Config as cms + +pfClustersFromL1EGClusters = cms.EDProducer("PFClusterProducerFromL1EGClusters", + src = cms.InputTag("L1EGammaClusterEmuProducer",), + etMin = cms.double(0.5), + corrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root"), + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 0.873, 1.081, 1.563), + scale = cms.vdouble( 0.011, 0.015, 0.012), + kind = cms.string('calo'), + ) +) + +# use phase2_hgcalV10 to customize for 106X L1TDR MC even in the barrel, since there's no other modifier for it +from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 +phase2_hgcalV10.toModify(pfClustersFromL1EGClusters, + corrector = "", # In this setup, TP's are already calibrated correctly :-) + # L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 0.946, 0.948, 1.171), + scale = cms.vdouble( 0.011, 0.018, 0.019), + kind = cms.string('calo') + ) +) +phase2_hgcalV11.toModify(pfClustersFromL1EGClusters, + corrector = "", # In this setup, TP's are already calibrated correctly :-) + # L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 0.838, 0.924, 1.101), + scale = cms.vdouble( 0.012, 0.017, 0.018), + kind = cms.string('calo') + ) +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py new file mode 100644 index 0000000000000..93f8ddb758aed --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py @@ -0,0 +1,22 @@ +import FWCore.ParameterSet.Config as cms + +pfTracksFromL1Tracks = cms.EDProducer("PFTrackProducerFromL1Tracks", + L1TrackTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + nParam = cms.uint32(4), + resolCalo = cms.PSet( + etaBins = cms.vdouble( 1.300, 1.700, 2.800, 3.200, 4.000, 5.000), + offset = cms.vdouble( 2.688, 1.382, 2.096, 1.022, 0.757, 0.185), + scale = cms.vdouble( 0.154, 0.341, 0.105, 0.255, 0.208, 0.306), + ptMin = cms.vdouble( 5.000, 5.000, 5.000, 5.000, 5.000, 5.000), + ptMax = cms.vdouble(999999, 999999, 999999, 999999, 999999, 999999), + kind = cms.string('calo'), + ), + resolTrack = cms.PSet( + etaBins = cms.vdouble( 0.800, 1.200, 1.500, 2.000, 2.500), + offset = cms.vdouble( 0.007, 0.009, 0.011, 0.015, 0.025), + scale = cms.vdouble( 0.275, 0.404, 0.512, 0.480, 1.132), + kind = cms.string('track'), + ) + +) + diff --git a/L1Trigger/Phase2L1ParticleFlow/src/BitwisePFAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/BitwisePFAlgo.cc new file mode 100644 index 0000000000000..570d899939449 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/BitwisePFAlgo.cc @@ -0,0 +1,196 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" + +//#define REG_HGCal +#include "ref/pfalgo2hgc_ref.h" +#include "ref/pfalgo3_ref.h" +#include "utils/DiscretePF2Firmware.h" +#include "utils/Firmware2DiscretePF.h" + +using namespace l1tpf_impl; + +BitwisePFAlgo::BitwisePFAlgo(const edm::ParameterSet &iConfig) : PFAlgoBase(iConfig), config_(nullptr) { + const edm::ParameterSet &bitwiseConfig = iConfig.getParameter("bitwiseConfig"); + const std::string &algo = iConfig.getParameter("bitwiseAlgo"); + debug_ = iConfig.getUntrackedParameter("debugBitwisePFAlgo", iConfig.getUntrackedParameter("debug", 0)); + if (algo == "pfalgo3") { + algo_ = AlgoChoice::algo3; + config_ = std::make_shared(bitwiseConfig.getParameter("NTRACK"), + bitwiseConfig.getParameter("NEMCALO"), + bitwiseConfig.getParameter("NCALO"), + bitwiseConfig.getParameter("NMU"), + bitwiseConfig.getParameter("NPHOTON"), + bitwiseConfig.getParameter("NSELCALO"), + bitwiseConfig.getParameter("NALLNEUTRAL"), + bitwiseConfig.getParameter("DR2MAX_TK_MU"), + bitwiseConfig.getParameter("DR2MAX_TK_EM"), + bitwiseConfig.getParameter("DR2MAX_EM_CALO"), + bitwiseConfig.getParameter("DR2MAX_TK_CALO"), + bitwiseConfig.getParameter("TK_MAXINVPT_LOOSE"), + bitwiseConfig.getParameter("TK_MAXINVPT_TIGHT")); + pfalgo3_ref_set_debug(debug_); + } else if (algo == "pfalgo2hgc") { + algo_ = AlgoChoice::algo2hgc; + config_ = std::make_shared(bitwiseConfig.getParameter("NTRACK"), + bitwiseConfig.getParameter("NCALO"), + bitwiseConfig.getParameter("NMU"), + bitwiseConfig.getParameter("NSELCALO"), + bitwiseConfig.getParameter("DR2MAX_TK_MU"), + bitwiseConfig.getParameter("DR2MAX_TK_CALO"), + bitwiseConfig.getParameter("TK_MAXINVPT_LOOSE"), + bitwiseConfig.getParameter("TK_MAXINVPT_TIGHT")); + pfalgo2hgc_ref_set_debug(debug_); + } else { + throw cms::Exception("Configuration", "Unsupported bitwiseAlgo " + algo); + } +} + +BitwisePFAlgo::~BitwisePFAlgo() {} + +void BitwisePFAlgo::runPF(Region &r) const { + initRegion(r); + + std::unique_ptr calo(new HadCaloObj[config_->nCALO]); + std::unique_ptr track(new TkObj[config_->nTRACK]); + std::unique_ptr mu(new MuObj[config_->nMU]); + std::unique_ptr outch(new PFChargedObj[config_->nTRACK]); + std::unique_ptr outne(new PFNeutralObj[config_->nSELCALO]); + std::unique_ptr outmu(new PFChargedObj[config_->nMU]); + + dpf2fw::convert(config_->nTRACK, r.track, track.get()); + dpf2fw::convert(config_->nCALO, r.calo, calo.get()); + dpf2fw::convert(config_->nMU, r.muon, mu.get()); + + if (debug_) { + dbgPrintf( + "BitwisePF\nBitwisePF region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , %+5.2f " + "], phi [ %+5.2f , %+5.2f ], algo = %d\n", + r.etaMin - r.etaExtra, + r.etaMax + r.etaExtra, + r.phiCenter - r.phiHalfWidth - r.phiExtra, + r.phiCenter + r.phiHalfWidth + r.phiExtra, + r.etaMin, + r.etaMax, + r.phiCenter - r.phiHalfWidth, + r.phiCenter + r.phiHalfWidth, + static_cast(algo_)); + dbgPrintf("BitwisePF \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n", + r.track.size(), + r.emcalo.size(), + r.calo.size(), + r.muon.size()); + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + dbgPrintf( + "BitwisePF \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + " fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n", + itk, + tk.floatPt(), + tk.floatPtErr(), + tk.floatVtxEta(), + tk.floatVtxPhi(), + tk.floatEta(), + tk.floatPhi(), + int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())), + tk.floatCaloPtErr(), + int(tk.hwStubs), + tk.hwChi2 * 0.1f); + } + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + const auto &em = r.emcalo[iem]; + dbgPrintf( + "BitwisePF \t EM %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + " fid %1d calo ptErr %7.2f\n", + iem, + em.floatPt(), + em.floatPtErr(), + em.floatEta(), + em.floatPhi(), + em.floatEta(), + em.floatPhi(), + int(r.fiducialLocal(em.floatEta(), em.floatPhi())), + em.floatPtErr()); + } + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + dbgPrintf( + "BitwisePF \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + " fid %1d calo ptErr %7.2f em pt %7.2f \n", + ic, + calo.floatPt(), + calo.floatPtErr(), + calo.floatEta(), + calo.floatPhi(), + calo.floatEta(), + calo.floatPhi(), + int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())), + calo.floatPtErr(), + calo.floatEmPt()); + } + for (int im = 0, nm = r.muon.size(); im < nm; ++im) { + auto &mu = r.muon[im]; + dbgPrintf( + "BitwisePF \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + " fid %1d \n", + im, + mu.floatPt(), + mu.floatEta(), + mu.floatPhi(), + mu.floatEta(), + mu.floatPhi(), + int(r.fiducialLocal(mu.floatEta(), mu.floatPhi()))); + } + } + switch (algo_) { + case AlgoChoice::algo3: { + pfalgo3_config *config3 = static_cast(config_.get()); + std::unique_ptr emcalo(new EmCaloObj[config3->nEMCALO]); + std::unique_ptr outpho(new PFNeutralObj[config3->nPHOTON]); + + dpf2fw::convert(config3->nEMCALO, r.emcalo, emcalo.get()); + pfalgo3_ref(*config3, + emcalo.get(), + calo.get(), + track.get(), + mu.get(), + outch.get(), + outpho.get(), + outne.get(), + outmu.get()); + + fw2dpf::convert(config3->nTRACK, outch.get(), r.track, r.pf); // FIXME works only with a 1-1 mapping + fw2dpf::convert(config3->nPHOTON, outpho.get(), r.pf); + fw2dpf::convert(config3->nSELCALO, outne.get(), r.pf); + } break; + case AlgoChoice::algo2hgc: { + pfalgo2hgc_ref(*config_, calo.get(), track.get(), mu.get(), outch.get(), outne.get(), outmu.get()); + fw2dpf::convert(config_->nTRACK, outch.get(), r.track, r.pf); // FIXME works only with a 1-1 mapping + fw2dpf::convert(config_->nSELCALO, outne.get(), r.pf); + } break; + }; + + if (debug_) { + dbgPrintf("BitwisePF \t Output N(ch) %3u/%3u N(nh) %3u/%3u N(ph) %3u/%u [all/fiducial]\n", + r.nOutput(l1tpf_impl::Region::charged_type, false, false), + r.nOutput(l1tpf_impl::Region::charged_type, false, true), + r.nOutput(l1tpf_impl::Region::neutral_hadron_type, false, false), + r.nOutput(l1tpf_impl::Region::neutral_hadron_type, false, true), + r.nOutput(l1tpf_impl::Region::photon_type, false, false), + r.nOutput(l1tpf_impl::Region::photon_type, false, true)); + for (int ipf = 0, npf = r.pf.size(); ipf < npf; ++ipf) { + const auto &pf = r.pf[ipf]; + dbgPrintf( + "BitwisePF \t pf %3d: pt %7.2f pid %d vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + "fid %1d\n", + ipf, + pf.floatPt(), + int(pf.hwId), + pf.floatVtxEta(), + pf.floatVtxPhi(), + pf.floatEta(), + pf.floatPhi(), + int(r.fiducialLocal(pf.floatEta(), pf.floatPhi()))); + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc new file mode 100644 index 0000000000000..b0b2c8364803e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc @@ -0,0 +1,130 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h" + +using namespace l1tpf_impl; + +COEFile::COEFile(const edm::ParameterSet& iConfig) + : file(nullptr), + coeFileName(iConfig.getUntrackedParameter("coeFileName", "")), + bset_string_(""), + ntracksmax(iConfig.getUntrackedParameter("ntracksmax")), + phiSlices(iConfig.getParameter>("regions")[0].getParameter("phiSlices")), + debug_(iConfig.getUntrackedParameter("debug", 0)) { + file = fopen(coeFileName.c_str(), "w"); + writeHeaderToFile(); + bset_.resize(tracksize); +} + +COEFile::~COEFile() {} + +void COEFile::writeHeaderToFile() { + char depth_width[256]; + snprintf(depth_width, + 255, + "; of depth=%i, and width=%i. In this case, values are specified\n", + ntracksmax, + tracksize * phiSlices); + std::vector vheader = {"; Sample memory initialization file for Dual Port Block Memory,\n", + "; v3.0 or later.\n", + "; Board: VCU118\n", + "; tmux: 1\n", + ";\n", + "; This .COE file specifies the contents for a block memory\n", + std::string(depth_width), + "; in binary format.\n", + "memory_initialization_radix=2;\n", + "memory_initialization_vector=\n"}; + for (uint32_t i = 0; i < vheader.size(); ++i) + fprintf(file, "%s", vheader[i].c_str()); +} + +void COEFile::writeTracksToFile(const std::vector& regions, bool print) { + PropagatedTrack current_track; + bool has_track = false; + for (unsigned int irow = 0; irow < ntracksmax; irow++) { + for (unsigned int icol = 0; icol < regions.size(); icol++) { + if (regions[icol].track.size() <= irow) + has_track = false; + else + has_track = true; + + if (has_track) { + // select the track that will be converted to a bit string + current_track = regions[icol].track[irow]; + + // convert the values in a PropogatedTrack to a 96-bit track word + for (unsigned int iblock = 0; iblock < track_word_block_sizes.size(); iblock++) { + for (unsigned int ibit = 0; ibit < track_word_block_sizes[iblock]; ibit++) { + int offset = std::accumulate(track_word_block_sizes.begin(), track_word_block_sizes.begin() + iblock, 0); + switch (iblock) { + case 0: + bset_.set(ibit + offset, getBit(current_track.hwPt, ibit)); + break; + case 1: + bset_.set(ibit + offset, current_track.hwCharge); + break; + case 2: + bset_.set(ibit + offset, getBit(current_track.hwVtxPhi, ibit)); + break; + case 3: + bset_.set(ibit + offset, getBit(current_track.hwVtxEta, ibit)); + break; + case 4: + bset_.set(ibit + offset, getBit(current_track.hwZ0, ibit)); + break; + case 5: + bset_.set(ibit + offset, false); + break; + case 6: + bset_.set(ibit + offset, getBit(current_track.hwChi2, ibit)); + break; + case 7: + bset_.set(ibit + offset, false); + break; + case 8: + bset_.set(ibit + offset, getBit(current_track.hwStubs, ibit)); + break; + case 9: + bset_.set(ibit + offset, false); + break; + } + } + } + + // print the track word to the COE file + boost::to_string(bset_, bset_string_); + fprintf(file, "%s", bset_string_.c_str()); + + // print some debugging information + if (debug_ && print && irow == 0 && icol == 0) { + printf("region: eta=[%f,%f] phi=%f+/-%f\n", + regions[icol].etaMin, + regions[icol].etaMax, + regions[icol].phiCenter, + regions[icol].phiHalfWidth); + printf("l1t::PFTrack (pT,eta,phi) [float] = (%f,%f,%f)\n", + current_track.src->p4().Pt(), + current_track.src->p4().Eta(), + current_track.src->p4().Phi()); + printf("l1t::PFTrack (pT,eta,phi) [int] = (%i,%i,%i)\n", + current_track.src->hwPt(), + current_track.src->hwEta(), + current_track.src->hwPhi()); + printf("l1tpf_impl::PropagatedTrack (1/pT,eta,phi) [int,10] = (%i,%i,%i)\n", + current_track.hwPt, + current_track.hwVtxEta, + current_track.hwVtxPhi); + printf("l1tpf_impl::PropagatedTrack (1/pT,eta,phi) [int,2] = (%s,%s,%s)\n", + std::bitset<16>(current_track.hwPt).to_string().c_str(), + std::bitset<32>(current_track.hwVtxEta).to_string().c_str(), + std::bitset<32>(current_track.hwVtxPhi).to_string().c_str()); + printf("bitset = %s\n", bset_string_.c_str()); + } + } else { + bset_.reset(); + boost::to_string(bset_, bset_string_); + fprintf(file, "%s", bset_string_.c_str()); + } + } + fprintf(file, (irow == ntracksmax - 1) ? ";\n" : ",\n"); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc b/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc new file mode 100644 index 0000000000000..06e95297e8c3f --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc @@ -0,0 +1,638 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h" + +#include + +#include "DataFormats/Math/interface/deltaPhi.h" +#include "DataFormats/Common/interface/RefToPtr.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/Exception.h" + +const float l1tpf_calo::Phase1Grid::phase1_towerEtas_[l1tpf_calo::Phase1Grid::phase1_nEta_] = { + 0, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131, + 1.218, 1.305, 1.392, 1.479, 1.566, 1.653, 1.740, 1.830, 1.930, 2.043, 2.172, 2.322, 2.5, 2.650, + 2.853, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191}; +const float l1tpf_calo::Phase2Grid::phase2_towerEtas_[l1tpf_calo::Phase2Grid::phase2_nEta_] = { + 0, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131, 1.218, 1.305, + 1.392, 1.479, 1.564, 1.648, 1.732, 1.817, 1.901, 1.986, 2.071, 2.155, 2.240, 2.324, 2.409, 2.493, 2.577, 2.662, + 2.747, 2.831, 2.915, 3.0, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191}; + +l1tpf_calo::Phase1GridBase::Phase1GridBase( + int nEta, int nPhi, int ietaCoarse, int ietaVeryCoarse, const float *towerEtas) + : Grid(2 * ((ietaCoarse - 1) * nPhi + (ietaVeryCoarse - ietaCoarse) * (nPhi / 2) + + (nEta - ietaVeryCoarse + 1) * (nPhi / 4))), + nEta_(nEta), + nPhi_(nPhi), + ietaCoarse_(ietaCoarse), + ietaVeryCoarse_(ietaVeryCoarse), + towerEtas_(towerEtas), + cell_map_(2 * nEta * nPhi, -1) { + int icell = 0; + for (int ie = -nEta_; ie <= nEta_; ++ie) { + int absie = std::abs(ie); + for (int iph = 1; iph <= nPhi_; ++iph) { + if (!valid_ieta_iphi(ie, iph)) + continue; + ieta_[icell] = ie; + iphi_[icell] = iph; + float etaLo = (absie < nEta_ ? towerEtas_[absie - 1] : towerEtas_[absie - 2]); + float etaHi = (absie < nEta_ ? towerEtas_[absie] : towerEtas_[absie - 1]); + eta_[icell] = (ie > 0 ? 0.5 : -0.5) * (etaLo + etaHi); + etaWidth_[icell] = (etaHi - etaLo); + phiWidth_[icell] = 2 * M_PI / nPhi_; + if (absie >= ietaVeryCoarse_) + phiWidth_[icell] *= 4; + else if (absie >= ietaCoarse_) + phiWidth_[icell] *= 2; + phi_[icell] = (iph - 1) * 2 * M_PI / nPhi_ + 0.5 * phiWidth_[icell]; + if (phi_[icell] > M_PI) + phi_[icell] -= 2 * M_PI; + std::fill(neighbours_[icell].begin(), neighbours_[icell].end(), -1); + cell_map_[(ie + nEta_) + 2 * nEta_ * (iph - 1)] = icell; + icell++; + } + } + assert(unsigned(icell) == ncells_); + // now link the cells + for (icell = 0; icell < int(ncells_); ++icell) { + int ie = ieta_[icell], iph = iphi_[icell]; + int ineigh = 0; + for (int deta = -1; deta <= +1; ++deta) { + for (int dphi = -1; dphi <= +1; ++dphi) { + if (deta == 0 && dphi == 0) + continue; + neighbours_[icell][ineigh++] = imove(ie, iph, deta, dphi); + } + } + } + //// consistency check 1: check that find_cell works + //// uncomment to check that there's no holes in the grid + //for (float teta = 0; teta <= 5.0; teta += 0.02) { + // for (float tphi = -M_PI; tphi <= M_PI; tphi += 0.02) { + // find_cell(+teta, tphi); + // find_cell(-teta, tphi); + // } + //} +} + +int l1tpf_calo::Phase1GridBase::find_cell(float eta, float phi) const { + int ieta = + (eta != 0) ? std::distance(towerEtas_, std::lower_bound(towerEtas_, towerEtas_ + nEta_, std::abs(eta))) : 1; + if (ieta == nEta_) + return -1; // outside bounds + assert(ieta > 0 && ieta < nEta_); + if (ieta > nEta_) + ieta = nEta_; + if (eta < 0) + ieta = -ieta; + phi = reco::reduceRange(phi); // [-PI, PI] + if (phi < 0) // then bring to [0, 2*PI] + phi += 2 * M_PI; + int iphi = std::floor(phi * nPhi_ / (2 * M_PI)); + if (phi >= 2 * M_PI) + iphi = nPhi_ - 1; // fix corner case due to roundings etc + assert(iphi < nPhi_); + if (std::abs(ieta) >= ietaVeryCoarse_) + iphi -= (iphi % 4); + else if (std::abs(ieta) >= ietaCoarse_) + iphi -= (iphi % 2); + iphi += 1; + //// uncomment to check validity of derived coordinates + //if (!valid_ieta_iphi(ieta,iphi)) { + // printf("Error in finding cell for eta %+7.4f phi %+7.4f, got ieta = %+3d iphi %2d which is not valid\n", + // eta, phi, ieta, iphi); + //} + assert(valid_ieta_iphi(ieta, iphi)); + int icell = ifind_cell(ieta, iphi); + assert(icell != -1); + + //// uncomment to check that the point is really in the cell + //if (std::abs(eta - eta_[icell]) > 0.501*etaWidth_[icell] || std::abs(deltaPhi(phi, phi_[icell])) > 0.501*phiWidth_[icell]) { + // printf("Mismatch in finding cell for eta %+7.4f phi %+7.4f, got ieta = %+3d iphi %2d which has eta %+7.4f +- %.4f phi %+7.4f +- %.4f ; deta = %+7.4f dphi = %+7.4f\n", + // eta, phi, ieta, iphi, eta_[icell], etaWidth_[icell], phi_[icell], phiWidth_[icell], eta - eta_[icell], deltaPhi(phi, phi_[icell])); + //} + //assert(std::abs(eta - eta_[icell]) <= 0.5*etaWidth_[icell]); + //assert(std::abs(deltaPhi(phi, phi_[icell])) <= 0.5*phiWidth_[icell]); + return icell; +} + +int l1tpf_calo::Phase1GridBase::imove(int ieta, int iphi, int deta, int dphi) { + int ie = ieta, iph = iphi; + switch (deta) { + case -1: + ie = (ie == -nEta_ ? 0 : (ie == +1 ? -1 : ie - 1)); + break; + case +1: + ie = (ie == +nEta_ ? 0 : (ie == -1 ? +1 : ie + 1)); + break; + case 0: + break; + default: + assert(false); + }; + if (ie == 0) + return -1; + switch (dphi) { + case -1: + iph = (iph == 1 ? nPhi_ : iph - 1); + break; + case +1: + iph = (iph == nPhi_ ? 1 : iph + 1); + break; + case 0: + break; + default: + assert(false); + }; + if (!valid_ieta_iphi(ie, iph)) + return -1; + int icell = ifind_cell(ie, iph); + assert(!(ie == ieta && iph == iphi)); + assert(icell != -1); + assert(icell != ifind_cell(ieta, iphi)); + return icell; +} + +const l1tpf_calo::Grid *l1tpf_calo::getGrid(const std::string &type) { + static const Phase1Grid _phase1Grid; + static const Phase2Grid _phase2Grid; + if (type == "phase1") + return &_phase1Grid; + else if (type == "phase2") + return &_phase2Grid; + else + throw cms::Exception("Configuration") << "Unsupported grid type '" << type << "'\n"; +} + +l1tpf_calo::SingleCaloClusterer::SingleCaloClusterer(const edm::ParameterSet &pset) + : grid_(getGrid(pset.getParameter("grid"))), + rawet_(*grid_), + unclustered_(*grid_), + precluster_(*grid_), + clusterIndex_(*grid_), + cellKey_(*grid_), + clusters_(), + nullCluster_(), + zsEt_(pset.getParameter("zsEt")), + seedEt_(pset.getParameter("seedEt")), + minClusterEt_(pset.getParameter("minClusterEt")), + minEtToGrow_(pset.existsAs("minEtToGrow") ? pset.getParameter("minEtToGrow") : -1), + energyWeightedPosition_(pset.getParameter("energyWeightedPosition")) { + std::string energyShareAlgo = pset.getParameter("energyShareAlgo"); + if (energyShareAlgo == "fractions") + energyShareAlgo_ = EnergyShareAlgo::Fractions; + else if (energyShareAlgo == "none") + energyShareAlgo_ = EnergyShareAlgo::None; + else if (energyShareAlgo == "greedy") + energyShareAlgo_ = EnergyShareAlgo::Greedy; + else if (energyShareAlgo == "crude") + energyShareAlgo_ = EnergyShareAlgo::Crude; + else + throw cms::Exception("Configuration") << "Unsupported energyShareAlgo '" << energyShareAlgo << "'\n"; +} + +l1tpf_calo::SingleCaloClusterer::~SingleCaloClusterer() {} + +void l1tpf_calo::SingleCaloClusterer::clear() { + rawet_.zero(); + clusters_.clear(); + clusterIndex_.fill(-1); +} + +void l1tpf_calo::SingleCaloClusterer::run() { + unsigned int i, ncells = grid_->size(); + + // kill zeros. count non-zeros, for linking later + cellKey_.fill(-1); + int key = 0; + for (i = 0; i < ncells; ++i) { + if (rawet_[i] < zsEt_) { + rawet_[i] = 0; + } else { + cellKey_[i] = key++; + } + } + + precluster_.clear(); + // pre-cluster step 1: at each cell, set the value equal to itself if it's a local maxima, zero otherwise + // can be done in parallel on all cells + for (i = 0; i < ncells; ++i) { + if (rawet_[i] > seedEt_) { + precluster_[i].ptLocalMax = rawet_[i]; + //// uncommment code below for debugging the clustering + //printf(" candidate precluster pt %7.2f at %4d (ieta %+3d iphi %2d)\n", rawet_[i], i, grid_->ieta(i), grid_->iphi(i)); + for (int ineigh = 0; ineigh <= 3; ++ineigh) { + if (rawet_.neigh(i, ineigh) > rawet_[i]) + precluster_[i].ptLocalMax = 0; + //// uncommment code below for debugging the clustering + //int ncell = grid_->neighbour(i,ineigh); + //if (ncell == -1) printf(" \t neigh %d is null\n", ineigh); + //else printf(" \t neigh %d at %4d (ieta %+3d iphi %2d) has pt %7.2f: comparison %1d \n", ineigh, ncell, grid_->ieta(ncell), grid_->iphi(ncell), rawet_[ncell], precluster_[i].ptLocalMax > 0); + } + for (int ineigh = 4; ineigh < 8; ++ineigh) { + if (rawet_.neigh(i, ineigh) >= rawet_[i]) + precluster_[i].ptLocalMax = 0; + //// uncommment code below for debugging the clustering + //int ncell = grid_->neighbour(i,ineigh); + //if (ncell == -1) printf(" \t neigh %d is null\n", ineigh); + //else printf(" \t neigh %d at %4d (ieta %+3d iphi %2d) has pt %7.2f: comparison %1d \n", ineigh, ncell, grid_->ieta(ncell), grid_->iphi(ncell), rawet_[ncell], precluster_[i].ptLocalMax > 0); + } + } + } + // pre-cluster step 2: compute information from neighbouring local max, for energy sharing purposes + for (i = 0; i < ncells; ++i) { + if (precluster_[i].ptLocalMax == 0) { + switch (energyShareAlgo_) { + case EnergyShareAlgo::Fractions: { + float tot = 0; + for (int ineigh = 0; ineigh < 8; ++ineigh) { + tot += precluster_.neigh(i, ineigh).ptLocalMax; + } + precluster_[i].ptOverNeighLocalMaxSum = tot ? rawet_[i] / tot : 0; + } break; + case EnergyShareAlgo::None: + precluster_[i].ptOverNeighLocalMaxSum = rawet_[i]; + break; + case EnergyShareAlgo::Greedy: { + float maxet = 0; + for (int ineigh = 0; ineigh < 8; ++ineigh) { + maxet = std::max(maxet, precluster_.neigh(i, ineigh).ptLocalMax); + } + precluster_[i].ptOverNeighLocalMaxSum = maxet; + } break; + case EnergyShareAlgo::Crude: { + int number = 0; + for (int ineigh = 0; ineigh < 8; ++ineigh) { + number += (precluster_.neigh(i, ineigh).ptLocalMax > 0); + } + precluster_[i].ptOverNeighLocalMaxSum = (number > 1 ? 0.5 : 1.0) * rawet_[i]; + } break; + } + } + } + + clusterIndex_.fill(-1); + clusters_.clear(); + unclustered_ = rawet_; + // cluster: at each localMax cell, take itself plus the weighted contributions of the neighbours + Cluster cluster; + for (i = 0; i < ncells; ++i) { + if (precluster_[i].ptLocalMax > 0) { + float myet = rawet_[i]; + float tot = myet; + float avg_eta = 0; + float avg_phi = 0; + cluster.clear(); + cluster.constituents.emplace_back(i, 1.0); + for (int ineigh = 0; ineigh < 8; ++ineigh) { + int ineighcell = grid_->neighbour(i, ineigh); + if (ineighcell == -1) + continue; // skip dummy cells + float fracet = 0; + switch (energyShareAlgo_) { + case EnergyShareAlgo::Fractions: + fracet = myet * precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum; + break; + case EnergyShareAlgo::None: + fracet = precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum; + break; + case EnergyShareAlgo::Greedy: + fracet = (myet == precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum ? rawet_.neigh(i, ineigh) : 0); + break; + case EnergyShareAlgo::Crude: + fracet = precluster_.neigh(i, ineigh).ptOverNeighLocalMaxSum; + break; + } + if (fracet == 0) + continue; + tot += fracet; + cluster.constituents.emplace_back(ineighcell, fracet / rawet_.neigh(i, ineigh)); + if (energyWeightedPosition_) { + avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(i)); + avg_phi += fracet * deltaPhi(grid_->phi(ineighcell), grid_->phi(i)); + } + } + if (tot > minClusterEt_) { + cluster.et = tot; + unclustered_[i] = 0; + for (int ineigh = 0; ineigh < 8; ++ineigh) { + int ineighcell = grid_->neighbour(i, ineigh); + if (ineighcell == -1) + continue; // skip dummy cells + unclustered_[ineighcell] = 0; + } + if (energyWeightedPosition_) { + cluster.eta = grid_->eta(i) + avg_eta / tot; + cluster.phi = grid_->phi(i) + avg_phi / tot; + // wrap around phi + cluster.phi = reco::reduceRange(cluster.phi); + } else { + cluster.eta = grid_->eta(i); + cluster.phi = grid_->phi(i); + } + clusterIndex_[i] = clusters_.size(); + clusters_.push_back(cluster); + } + } + } + if (minEtToGrow_ > 0) + grow(); +} + +void l1tpf_calo::SingleCaloClusterer::grow() { + int selneighs[4] = {1, 3, 4, 6}; // -eta, -phi, +phi, +eta + std::vector toreset; + for (Cluster &cluster : clusters_) { + if (cluster.et > minEtToGrow_) { + int i = cluster.constituents.front().first; + for (int side = 0; side < 4; ++side) { + int neigh = grid_->neighbour(i, selneighs[side]); + if (neigh == -1) + continue; + for (int in = 0; in < 8; ++in) { + int n2 = grid_->neighbour(neigh, in); + if (n2 == -1) + continue; + cluster.et += unclustered_[n2]; + if (unclustered_[n2]) { + cluster.constituents.emplace_back(n2, 1.0); + toreset.push_back(n2); + } + } + } + } + } + for (int i : toreset) + unclustered_[i] = 0; +} + +std::unique_ptr l1tpf_calo::SingleCaloClusterer::fetchCells(bool unclusteredOnly, + float ptMin) const { + auto ret = std::make_unique(); + const EtGrid &src = (unclusteredOnly ? unclustered_ : rawet_); + for (unsigned int i = 0, ncells = grid_->size(); i < ncells; ++i) { + if (src[i] <= ptMin) + continue; + if ((unclusteredOnly == false) && (ptMin == 0)) { + assert(cellKey_[i] == int(ret->size())); + } + ret->emplace_back(src[i], grid_->eta(i), grid_->phi(i)); + ret->back().setHwEta(grid_->ieta(i)); + ret->back().setHwPhi(grid_->iphi(i)); + } + return ret; +} + +std::unique_ptr l1tpf_calo::SingleCaloClusterer::fetch(float ptMin) const { + auto ret = std::make_unique(); + for (const Cluster &cluster : clusters_) { + if (cluster.et > ptMin) { + ret->emplace_back(cluster.et, cluster.eta, cluster.phi); + } + } + return ret; +} + +std::unique_ptr l1tpf_calo::SingleCaloClusterer::fetch( + const edm::OrphanHandle &cells, float ptMin) const { + auto ret = std::make_unique(); + for (const Cluster &cluster : clusters_) { + if (cluster.et > ptMin) { + ret->emplace_back(cluster.et, cluster.eta, cluster.phi); + for (const auto &pair : cluster.constituents) { + edm::Ptr ref(cells, cellKey_[pair.first]); + ret->back().addConstituent(ref, pair.second); + } + } + } + return ret; +} + +l1tpf_calo::SimpleCaloLinkerBase::SimpleCaloLinkerBase(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal) + : grid_(getGrid(pset.getParameter("grid"))), + ecal_(ecal), + hcal_(hcal), + clusterIndex_(*grid_), + clusters_(), + hoeCut_(pset.getParameter("hoeCut")), + minPhotonEt_(pset.getParameter("minPhotonEt")), + minHadronRawEt_(pset.getParameter("minHadronRawEt")), + minHadronEt_(pset.getParameter("minHadronEt")), + noEmInHGC_(pset.getParameter("noEmInHGC")) { + if (grid_ != &ecal.raw().grid()) + throw cms::Exception("LogicError", "Inconsistent grid between ecal and linker\n"); + if (grid_ != &hcal.raw().grid()) + throw cms::Exception("LogicError", "Inconsistent grid between hcal and linker\n"); +} + +l1tpf_calo::SimpleCaloLinkerBase::~SimpleCaloLinkerBase() {} + +std::unique_ptr l1tpf_calo::SimpleCaloLinkerBase::fetch() const { + edm::OrphanHandle ecal, hcal; + return fetch(ecal, hcal); +} + +std::unique_ptr l1tpf_calo::SimpleCaloLinkerBase::fetch( + const edm::OrphanHandle &ecal, + const edm::OrphanHandle &hcal) const { + bool setRefs = (ecal.isValid() && hcal.isValid()); + auto ret = std::make_unique(); + for (const CombinedCluster &cluster : clusters_) { + if (cluster.et > 0) { + bool photon = (cluster.hcal_et < hoeCut_ * cluster.ecal_et); + if (photon && noEmInHGC_) { + if (std::abs(cluster.eta) > 1.5 && std::abs(cluster.eta) < 3.0) { // 1.5-3 = eta range of HGCal + continue; + } + } + if (cluster.et > (photon ? minPhotonEt_ : minHadronEt_)) { + ret->emplace_back(cluster.et, + cluster.eta, + cluster.phi, + cluster.ecal_et > 0 ? std::max(cluster.et - cluster.ecal_et, 0.f) / cluster.ecal_et : -1, + photon); + if (setRefs) { + for (const auto &pair : cluster.constituents) { + assert(pair.first != 0); + if (pair.first > 0) { // 1+hcal index + ret->back().addConstituent(edm::Ptr(hcal, +pair.first - 1), pair.second); + } else { // -1-ecal index + ret->back().addConstituent(edm::Ptr(ecal, -pair.first + 1), pair.second); + } + } + } + } + } + } + return ret; +} + +l1tpf_calo::SimpleCaloLinker::SimpleCaloLinker(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal) + : SimpleCaloLinkerBase(pset, ecal, hcal), ecalToHCal_(*grid_) {} + +l1tpf_calo::SimpleCaloLinker::~SimpleCaloLinker() {} + +void l1tpf_calo::SimpleCaloLinker::clear() { + clearBase(); + ecalToHCal_.clear(); +} + +void l1tpf_calo::SimpleCaloLinker::run() { + unsigned int i, ncells = grid_->size(); + + const EtGrid &hraw = hcal_.raw(); + const IndexGrid &ecals = ecal_.indexGrid(); + const IndexGrid &hcals = hcal_.indexGrid(); + + // for each ECal cluster, get the corresponding HCal cluster and the sum of the neighbour HCal clusters + ecalToHCal_.clear(); + for (i = 0; i < ncells; ++i) { + if (ecals[i] >= 0) { + if (hcals[i] >= 0) { + ecalToHCal_[i].ptLocalMax = hcal_.cluster(i).et; + } else { + float tot = 0; + for (int ineigh = 0; ineigh < 8; ++ineigh) { + tot += hcal_.cluster(grid_->neighbour(i, ineigh)).et; + } + ecalToHCal_[i].ptOverNeighLocalMaxSum = tot ? ecal_.cluster(i).et / tot : 0; + } + } + } + + clusterIndex_.fill(-1); + clusters_.clear(); + CombinedCluster cluster; + // promote HCal clusters to final clusters + for (i = 0; i < ncells; ++i) { + if (hcals[i] >= 0) { + const Cluster &hcal = hcal_.cluster(i); + cluster.clear(); + cluster.constituents.emplace_back(+i + 1, 1); + if (ecalToHCal_[i].ptLocalMax > 0) { + // direct linking is easy + const Cluster &ecal = ecal_.cluster(i); + if (ecal.et + hcal.et > minHadronRawEt_) { + cluster.ecal_et = ecal.et; + cluster.hcal_et = hcal.et; + cluster.et = cluster.ecal_et + cluster.hcal_et; + float wecal = cluster.ecal_et / cluster.et, whcal = 1.0 - wecal; + cluster.eta = ecal.eta * wecal + hcal.eta * whcal; + cluster.phi = ecal.phi * wecal + hcal.phi * whcal; + // wrap around phi + cluster.phi = reco::reduceRange(cluster.phi); + cluster.constituents.emplace_back(-i - 1, 1); + } + } else { + // sidewas linking is more annonying + float myet = hcal.et; + float etot = 0; + float avg_eta = 0; + float avg_phi = 0; + for (int ineigh = 0; ineigh < 8; ++ineigh) { + int ineighcell = grid_->neighbour(i, ineigh); + if (ineighcell == -1) + continue; // skip dummy cells + float fracet = myet * ecalToHCal_.neigh(i, ineigh).ptOverNeighLocalMaxSum; + if (fracet == 0) + continue; + etot += fracet; + avg_eta += fracet * (grid_->eta(ineighcell) - grid_->eta(i)); + avg_phi += fracet * deltaPhi(grid_->phi(ineighcell), grid_->phi(i)); + cluster.constituents.emplace_back(-i - 1, fracet / ecal_.cluster(ineighcell).et); + } + if (myet + etot > minHadronRawEt_) { + cluster.hcal_et = hcal.et; + cluster.ecal_et = etot; + cluster.et = myet + etot; + cluster.eta = hcal.eta + avg_eta / cluster.et; + cluster.phi = hcal.phi + avg_phi / cluster.et; + // wrap around phi + cluster.phi = reco::reduceRange(cluster.phi); + } + } + if (cluster.et > 0) { + clusterIndex_[i] = clusters_.size(); + clusters_.push_back(cluster); + } + } + } + + // promote Unlinked ECal clusters to final clusters + for (i = 0; i < ncells; ++i) { + if (ecals[i] >= 0 && ecalToHCal_[i].ptLocalMax == 0 && ecalToHCal_[i].ptOverNeighLocalMaxSum == 0) { + cluster.clear(); + const Cluster &ecal = ecal_.cluster(i); + cluster.ecal_et = ecal.et; + cluster.hcal_et = hraw[i]; + cluster.et = cluster.ecal_et + cluster.hcal_et; + cluster.eta = ecal.eta; + cluster.phi = ecal.phi; + cluster.constituents.emplace_back(-i - 1, 1); + clusterIndex_[i] = clusters_.size(); + clusters_.push_back(cluster); + } + } +} + +l1tpf_calo::FlatCaloLinker::FlatCaloLinker(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal) + : SimpleCaloLinkerBase(pset, ecal, hcal), combClusterer_(pset) {} + +l1tpf_calo::FlatCaloLinker::~FlatCaloLinker() {} + +void l1tpf_calo::FlatCaloLinker::clear() { + clearBase(); + combClusterer_.clear(); +} + +void l1tpf_calo::FlatCaloLinker::run() { + combClusterer_.clear(); + + const EtGrid &hraw = hcal_.raw(); + const EtGrid &eraw = ecal_.raw(); + combClusterer_.raw() = eraw; + combClusterer_.raw() += hraw; + + combClusterer_.run(); + clusterIndex_ = combClusterer_.indexGrid(); + const std::vector &clustersSrc = combClusterer_.clusters(); + unsigned int nclust = clustersSrc.size(); + clusters_.resize(nclust); + for (unsigned int ic = 0; ic < nclust; ++ic) { + const Cluster &src = clustersSrc[ic]; + CombinedCluster &dst = clusters_[ic]; + dst.et = src.et; + dst.eta = src.eta; + dst.phi = src.phi; + dst.ecal_et = 0; + dst.hcal_et = 0; + for (const auto &pair : src.constituents) { + if (eraw[pair.first]) { + dst.ecal_et += pair.second * eraw[pair.first]; + dst.constituents.emplace_back(-pair.first - 1, pair.second); + } + if (hraw[pair.first]) { + dst.hcal_et += pair.second * hraw[pair.first]; + dst.constituents.emplace_back(+pair.first + 1, pair.second); + } + } + } +} + +std::unique_ptr l1tpf_calo::makeCaloLinker(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal) { + const std::string &algo = pset.getParameter("algo"); + if (algo == "simple") { + return std::make_unique(pset, ecal, hcal); + } else if (algo == "flat") { + return std::make_unique(pset, ecal, hcal); + } else { + throw cms::Exception("Configuration") << "Unsupported linker algo '" << algo << "'\n"; + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/DiscretePFInputsIO.cc b/L1Trigger/Phase2L1ParticleFlow/src/DiscretePFInputsIO.cc new file mode 100644 index 0000000000000..67cc12e16a383 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/DiscretePFInputsIO.cc @@ -0,0 +1 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/src/HGC3DClusterEgID.cc b/L1Trigger/Phase2L1ParticleFlow/src/HGC3DClusterEgID.cc new file mode 100644 index 0000000000000..6cf9b028ad7f6 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/HGC3DClusterEgID.cc @@ -0,0 +1,45 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/HGC3DClusterEgID.h" +#include "CommonTools/MVAUtils/interface/TMVAZipReader.h" + +l1tpf::HGC3DClusterEgID::HGC3DClusterEgID(const edm::ParameterSet &pset) + : isPUFilter_(pset.getParameter("isPUFilter")), + preselection_(pset.getParameter("preselection")), + method_(pset.getParameter("method")), + weightsFile_(pset.getParameter("weightsFile")), + reader_(new TMVA::Reader()), + wp_(pset.getParameter("wp")) { + // first create all the variables + for (const auto &psvar : pset.getParameter>("variables")) { + variables_.emplace_back(psvar.getParameter("name"), psvar.getParameter("value")); + } +} + +void l1tpf::HGC3DClusterEgID::prepareTMVA() { + // Declare the variables + for (auto &var : variables_) + var.declare(*reader_); + // then read the weights + if (weightsFile_[0] != '/' && weightsFile_[0] != '.') { + weightsFile_ = edm::FileInPath(weightsFile_).fullPath(); + } + reco::details::loadTMVAWeights(&*reader_, method_, weightsFile_); +} + +float l1tpf::HGC3DClusterEgID::passID(l1t::HGCalMulticluster c, l1t::PFCluster &cpf) { + if (preselection_(c)) { + for (auto &var : variables_) + var.fill(c); + float mvaOut = reader_->EvaluateMVA(method_); + if (isPUFilter_) + cpf.setEgVsPUMVAOut(mvaOut); + else + cpf.setEgVsPionMVAOut(mvaOut); + return (mvaOut > wp_(c) ? 1 : 0); + } else { + if (isPUFilter_) + cpf.setEgVsPUMVAOut(-100.0); + else + cpf.setEgVsPionMVAOut(-100.0); + return 0; + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TPFUtils.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TPFUtils.cc new file mode 100644 index 0000000000000..d0aec72574472 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TPFUtils.cc @@ -0,0 +1,17 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/L1TPFUtils.h" + +#include "CommonTools/BaseParticlePropagator/interface/BaseParticlePropagator.h" +#include "CommonTools/BaseParticlePropagator/interface/RawParticle.h" +#include "DataFormats/ParticleFlowReco/interface/PFCluster.h" + +std::pair l1tpf::propagateToCalo(const math::XYZTLorentzVector& iMom, + const math::XYZTLorentzVector& iVtx, + double iCharge, + double iBField) { + BaseParticlePropagator prop = BaseParticlePropagator(RawParticle(iMom, iVtx, iCharge), 0., 0., iBField); + prop.propagateToEcalEntrance(false); + double ecalShowerDepth = reco::PFCluster::getDepthCorrection(prop.particle().momentum().E(), false, false); + math::XYZVector point = math::XYZVector(prop.particle().vertex()) + + math::XYZTLorentzVector(prop.particle().momentum()).Vect().Unit() * ecalShowerDepth; + return std::make_pair(point.eta(), point.phi()); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/LinearizedPuppiAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/LinearizedPuppiAlgo.cc new file mode 100644 index 0000000000000..463a114b53f6e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/LinearizedPuppiAlgo.cc @@ -0,0 +1,142 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaR.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" + +#include "Math/ProbFunc.h" + +namespace { + std::vector vd2vf(const std::vector &vd) { + std::vector ret; + ret.insert(ret.end(), vd.begin(), vd.end()); + return ret; + } +} // namespace + +using namespace l1tpf_impl; + +LinearizedPuppiAlgo::LinearizedPuppiAlgo(const edm::ParameterSet &iConfig) + : PuppiAlgo(iConfig), + puppiPriors_(vd2vf(iConfig.getParameter>("puppiPriors"))), + puppiPriorsPhotons_(vd2vf(iConfig.getParameter>("puppiPriorsPhotons"))), + puppiPtSlopes_(vd2vf(iConfig.getParameter>("puppiPtSlopes"))), + puppiPtSlopesPhotons_(vd2vf(iConfig.getParameter>("puppiPtSlopesPhotons"))), + puppiPtZeros_(vd2vf(iConfig.getParameter>("puppiPtZeros"))), + puppiPtZerosPhotons_(vd2vf(iConfig.getParameter>("puppiPtZerosPhotons"))), + puppiAlphaSlopes_(vd2vf(iConfig.getParameter>("puppiAlphaSlopes"))), + puppiAlphaSlopesPhotons_(vd2vf(iConfig.getParameter>("puppiAlphaSlopesPhotons"))), + puppiAlphaZeros_(vd2vf(iConfig.getParameter>("puppiAlphaZeros"))), + puppiAlphaZerosPhotons_(vd2vf(iConfig.getParameter>("puppiAlphaZerosPhotons"))), + puppiAlphaCrops_(vd2vf(iConfig.getParameter>("puppiAlphaCrops"))), + puppiAlphaCropsPhotons_(vd2vf(iConfig.getParameter>("puppiAlphaCropsPhotons"))) { + if (puppiPriors_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiPriors\n"); + if (puppiPtSlopes_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiPtSlopes\n"); + if (puppiPtZeros_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiPtZeros\n"); + if (puppiAlphaSlopes_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaSlopes\n"); + if (puppiAlphaZeros_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaZeros\n"); + if (puppiAlphaCrops_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaCrops\n"); + if (puppiPriorsPhotons_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiPriorsPhotons\n"); + if (puppiPtSlopesPhotons_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiPtSlopesPhotons\n"); + if (puppiPtZerosPhotons_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiPtZerosPhotons\n"); + if (puppiAlphaSlopesPhotons_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaSlopesPhotons\n"); + if (puppiAlphaZerosPhotons_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaZerosPhotons\n"); + if (puppiAlphaCropsPhotons_.size() != puppiEtaCuts_.size()) + throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaCropsPhotons\n"); +} + +LinearizedPuppiAlgo::~LinearizedPuppiAlgo() {} + +const std::vector &LinearizedPuppiAlgo::puGlobalNames() const { + static const std::vector names_{}; + return names_; +} +void LinearizedPuppiAlgo::doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const { + globals.clear(); +} +void LinearizedPuppiAlgo::runNeutralsPU(Region &r, float npu, const std::vector &globals) const { + std::vector alphaC, alphaF; + PuppiAlgo::computePuppiAlphas(r, alphaC, alphaF); + computePuppiWeights(r, npu, alphaC, alphaF); + PuppiAlgo::fillPuppi(r); +} + +void LinearizedPuppiAlgo::computePuppiWeights(Region &r, + float npu, + const std::vector &alphaC, + const std::vector &alphaF) const { + if (debug_ && npu > 0) + dbgPrintf("LinPup\t npu estimate %7.2f --> log(npu/200) = %+6.2f \n", npu, std::log(npu / 200.f)); + for (unsigned int ip = 0, np = r.pf.size(); ip < np; ++ip) { + PFParticle &p = r.pf[ip]; + // charged + if (p.hwId == l1t::PFCandidate::ChargedHadron || p.hwId == l1t::PFCandidate::Electron || + p.hwId == l1t::PFCandidate::Muon) { + p.setPuppiW(p.chargedPV || p.hwId == l1t::PFCandidate::Muon ? 1.0 : 0); + if (debug_ == 2) + dbgPrintf( + "LinPup\t charged id %1d pt %7.2f eta %+5.2f phi %+5.2f fromPV %1d " + " --> puppi weight %.3f puppi pt %7.2f \n", + p.hwId, + p.floatPt(), + p.floatEta(), + p.floatPhi(), + p.chargedPV, + p.floatPuppiW(), + p.floatPt() * p.floatPuppiW()); + continue; + } + // neutral + float absEta = r.relativeCoordinates ? r.globalAbsEta(p.floatEta()) : std::abs(p.floatEta()); + bool central = absEta < etaCharged_; // FIXME could make a better integer implementation + bool photon = (p.hwId == l1t::PFCandidate::Photon); + // get alpha + float alpha = central ? alphaC[ip] : alphaF[ip]; + alpha = (alpha > 0 ? std::log(alpha) : 0); + // get eta bin + unsigned int ietaBin = 0, lastBin = puppiEtaCuts_.size() - 1; + while (ietaBin < lastBin && absEta > puppiEtaCuts_[ietaBin]) { + ietaBin++; + } + float alphaZero = (photon ? puppiAlphaZerosPhotons_ : puppiAlphaZeros_)[ietaBin]; + float alphaSlope = (photon ? puppiAlphaSlopesPhotons_ : puppiAlphaSlopes_)[ietaBin]; + float alphaCrop = (photon ? puppiAlphaCropsPhotons_ : puppiAlphaCrops_)[ietaBin]; + float x2a = std::clamp(alphaSlope * (alpha - alphaZero), -alphaCrop, alphaCrop); + // weight by pT + float ptZero = (photon ? puppiPtZerosPhotons_ : puppiPtZeros_)[ietaBin]; + float ptSlope = (photon ? puppiPtSlopesPhotons_ : puppiPtSlopes_)[ietaBin]; + float x2pt = ptSlope * (p.floatPt() - ptZero); + // weight by prior + float prior = (photon ? puppiPriorsPhotons_ : puppiPriors_)[ietaBin]; + float x2prior = (npu > 0 ? std::log(npu / 200.f) : 0) + prior; + // total + float x2 = x2a + x2pt - x2prior; + p.setPuppiW(1.0 / (1.0 + std::exp(-x2))); + if (debug_ == 1 || debug_ == 2 || debug_ == int(10 + ietaBin)) + dbgPrintf( + "LinPup\t neutral id %1d pt %7.2f eta %+5.2f phi %+5.2f alpha %+6.2f x2a %+5.2f x2pt %+6.2f x2prior " + "%+6.2f --> x2 %+6.2f --> puppi weight %.3f puppi pt %7.2f \n", + p.hwId, + p.floatPt(), + p.floatEta(), + p.floatPhi(), + alpha, + x2a, + x2pt, + -x2prior, + x2, + p.floatPuppiW(), + p.floatPt() * p.floatPuppiW()); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo2HGC.cc b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo2HGC.cc new file mode 100644 index 0000000000000..e5984288e9c4a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo2HGC.cc @@ -0,0 +1,650 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "FWCore/Utilities/interface/Exception.h" + +#include "DataFormats/Math/interface/deltaR.h" + +namespace { + template + float floatDR(const T1 &t1, const T2 &t2) { + return deltaR(t1.floatEta(), t1.floatPhi(), t2.floatEta(), t2.floatPhi()); + } +} // namespace + +using namespace l1tpf_impl; + +PFAlgo2HGC::PFAlgo2HGC(const edm::ParameterSet &iConfig) : PFAlgoBase(iConfig) { + debug_ = iConfig.getUntrackedParameter("debugPFAlgo2HGC", iConfig.getUntrackedParameter("debug", 0)); + edm::ParameterSet linkcfg = iConfig.getParameter("linking"); + drMatchMu_ = linkcfg.getParameter("trackMuDR"); + + std::string muMatchMode = linkcfg.getParameter("trackMuMatch"); + if (muMatchMode == "boxBestByPtRatio") + muMatchMode_ = MuMatchMode::BoxBestByPtRatio; + else if (muMatchMode == "drBestByPtRatio") + muMatchMode_ = MuMatchMode::DrBestByPtRatio; + else if (muMatchMode == "drBestByPtDiff") + muMatchMode_ = MuMatchMode::DrBestByPtDiff; + else + throw cms::Exception("Configuration", "bad value for trackMuMatch configurable"); + + std::string tkCaloLinkMetric = linkcfg.getParameter("trackCaloLinkMetric"); + if (tkCaloLinkMetric == "bestByDR") + tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR; + else if (tkCaloLinkMetric == "bestByDRPt") + tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDRPt; + else if (tkCaloLinkMetric == "bestByDR2Pt2") + tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR2Pt2; + else + throw cms::Exception("Configuration", "bad value for tkCaloLinkMetric configurable"); + + drMatch_ = linkcfg.getParameter("trackCaloDR"); + ptMatchLow_ = linkcfg.getParameter("trackCaloNSigmaLow"); + ptMatchHigh_ = linkcfg.getParameter("trackCaloNSigmaHigh"); + useTrackCaloSigma_ = linkcfg.getParameter("useTrackCaloSigma"); + maxInvisiblePt_ = linkcfg.getParameter("maxInvisiblePt"); + + caloReLinkStep_ = linkcfg.getParameter("caloReLink"); + caloReLinkDr_ = linkcfg.getParameter("caloReLinkDR"); + caloReLinkThreshold_ = linkcfg.getParameter("caloReLinkThreshold"); + rescaleTracks_ = linkcfg.getParameter("rescaleTracks"); + caloTrkWeightedAverage_ = linkcfg.getParameter("useCaloTrkWeightedAverage"); + sumTkCaloErr2_ = linkcfg.getParameter("sumTkCaloErr2"); + ecalPriority_ = linkcfg.getParameter("ecalPriority"); + tightTrackMinStubs_ = linkcfg.getParameter("tightTrackMinStubs"); + tightTrackMaxChi2_ = linkcfg.getParameter("tightTrackMaxChi2"); + tightTrackMaxInvisiblePt_ = linkcfg.getParameter("tightTrackMaxInvisiblePt"); +} + +void PFAlgo2HGC::runPF(Region &r) const { + initRegion(r); + + /// ------------- first step (can all go in parallel) ---------------- + + if (debug_) { + dbgPrintf( + "PFAlgo2HGC\nPFAlgo2HGC region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , " + "%+5.2f ], phi [ %+5.2f , %+5.2f ]\n", + r.etaMin - r.etaExtra, + r.etaMax + r.etaExtra, + r.phiCenter - r.phiHalfWidth - r.phiExtra, + r.phiCenter + r.phiHalfWidth + r.phiExtra, + r.etaMin, + r.etaMax, + r.phiCenter - r.phiHalfWidth, + r.phiCenter + r.phiHalfWidth); + dbgPrintf( + "PFAlgo2HGC \t N(track) %3lu N(calo) %3lu N(mu) %3lu\n", r.track.size(), r.calo.size(), r.muon.size()); + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + dbgPrintf( + "PFAlgo2HGC \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi " + "%+5.2f fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n", + itk, + tk.floatPt(), + tk.floatPtErr(), + tk.floatVtxEta(), + tk.floatVtxPhi(), + tk.floatEta(), + tk.floatPhi(), + int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())), + tk.floatCaloPtErr(), + int(tk.hwStubs), + tk.hwChi2 * 0.1f); + } + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + dbgPrintf( + "PFAlgo2HGC \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi " + "%+5.2f fid %1d calo ptErr %7.2f em pt %7.2f isEM %1d \n", + ic, + calo.floatPt(), + calo.floatPtErr(), + calo.floatEta(), + calo.floatPhi(), + calo.floatEta(), + calo.floatPhi(), + int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())), + calo.floatPtErr(), + calo.floatEmPt(), + calo.isEM); + } + for (int im = 0, nm = r.muon.size(); im < nm; ++im) { + auto &mu = r.muon[im]; + dbgPrintf( + "PFAlgo2HGC \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi " + "%+5.2f fid %1d\n", + im, + mu.floatPt(), + mu.floatEta(), + mu.floatPhi(), + mu.floatEta(), + mu.floatPhi(), + int(r.fiducialLocal(mu.floatEta(), mu.floatPhi()))); + } + } + + std::vector tk2mu(r.track.size(), -1), mu2tk(r.muon.size(), -1); + link_tk2mu(r, tk2mu, mu2tk); + + // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) + std::vector tk2calo(r.track.size(), -1); + link_tk2calo(r, tk2calo); + + /// ------------- next step (needs the previous) ---------------- + // for each calo, compute the sum of the track pt + std::vector calo2ntk(r.calo.size(), 0); + std::vector calo2sumtkpt(r.calo.size(), 0); + std::vector calo2sumtkpterr(r.calo.size(), 0); + sum_tk2calo(r, tk2calo, calo2ntk, calo2sumtkpt, calo2sumtkpterr); + + // in the meantime, promote unlinked low pt tracks to hadrons + unlinkedtk_algo(r, tk2calo); + + /// ------------- next step (needs the previous) ---------------- + /// OPTIONAL STEP: try to recover split hadron showers (v1.0): + // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events + if (caloReLinkStep_) + calo_relink(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr); + + /// ------------- next step (needs the previous) ---------------- + // process matched calo clusters, compare energy to sum track pt + std::vector calo2alpha(r.calo.size(), 1); + linkedcalo_algo(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr, calo2alpha); + + /// ------------- next step (needs the previous) ---------------- + /// process matched tracks, if necessary rescale or average + linkedtk_algo(r, tk2calo, calo2ntk, calo2alpha); + // process unmatched calo clusters + unlinkedcalo_algo(r); + // finally do muons + save_muons(r, tk2mu); +} + +void PFAlgo2HGC::link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const { + // do a rectangular match for the moment; make a box of the same are as a 0.2 cone + int intDrMuonMatchBox = std::ceil(drMatchMu_ * CaloCluster::ETAPHI_SCALE * std::sqrt(M_PI / 4)); + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + tk2mu[itk] = false; + } + for (int imu = 0, nmu = r.muon.size(); imu < nmu; ++imu) { + const auto &mu = r.muon[imu]; + if (debug_) + dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f, eta %+5.2f, phi %+5.2f) \n", + imu, + mu.floatPt(), + mu.floatEta(), + mu.floatPhi()); + float minDistance = 9e9; + switch (muMatchMode_) { + case MuMatchMode::BoxBestByPtRatio: + minDistance = 4.; + break; + case MuMatchMode::DrBestByPtRatio: + minDistance = 4.; + break; + case MuMatchMode::DrBestByPtDiff: + minDistance = 0.5 * mu.floatPt(); + break; + } + int imatch = -1; + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + int deta = std::abs(mu.hwEta - tk.hwEta); + int dphi = std::abs((mu.hwPhi - tk.hwPhi) % CaloCluster::PHI_WRAP); + float dr = floatDR(mu, tk); + float dpt = std::abs(mu.floatPt() - tk.floatPt()); + float dptr = (mu.hwPt > tk.hwPt ? mu.floatPt() / tk.floatPt() : tk.floatPt() / mu.floatPt()); + bool ok = false; + float distance = 9e9; + switch (muMatchMode_) { + case MuMatchMode::BoxBestByPtRatio: + ok = (deta < intDrMuonMatchBox) && (dphi < intDrMuonMatchBox); + distance = dptr; + break; + case MuMatchMode::DrBestByPtRatio: + ok = (dr < drMatchMu_); + distance = dptr; + break; + case MuMatchMode::DrBestByPtDiff: + ok = (dr < drMatchMu_); + distance = dpt; + break; + } + if (debug_ && dr < 0.4) { + dbgPrintf( + "PFAlgo2HGC \t\t possible match with track %3d (pt %7.2f, caloeta %+5.2f, calophi %+5.2f, dr %.2f, eta " + "%+5.2f, phi %+5.2f, dr %.2f): angular %1d, distance %.3f (vs %.3f)\n", + itk, + tk.floatPt(), + tk.floatEta(), + tk.floatPhi(), + dr, + tk.floatVtxEta(), + tk.floatVtxPhi(), + deltaR(mu.floatEta(), mu.floatPhi(), tk.floatVtxEta(), tk.floatVtxPhi()), + (ok ? 1 : 0), + distance, + minDistance); + } + if (!ok) + continue; + // FIXME for the moment, we do the floating point matching in pt + if (distance < minDistance) { + minDistance = distance; + imatch = itk; + } + } + if (debug_ && imatch > -1) + dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f) linked to track %3d (pt %7.2f)\n", + imu, + mu.floatPt(), + imatch, + r.track[imatch].floatPt()); + if (debug_ && imatch == -1) + dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f) not linked to any track\n", imu, mu.floatPt()); + mu2tk[imu] = imatch; + if (imatch > -1) { + tk2mu[imatch] = imu; + r.track[imatch].muonLink = true; + } + } +} + +void PFAlgo2HGC::link_tk2calo(Region &r, std::vector &tk2calo) const { + // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + if (tk.muonLink || tk.used) + continue; // not necessary but just a waste of CPU otherwise + float drbest = drMatch_, dptscale = 0; + switch (tkCaloLinkMetric_) { + case TkCaloLinkMetric::BestByDR: + drbest = drMatch_; + break; + case TkCaloLinkMetric::BestByDRPt: + drbest = 1.0; + dptscale = drMatch_ / tk.floatCaloPtErr(); + break; + case TkCaloLinkMetric::BestByDR2Pt2: + drbest = 1.0; + dptscale = drMatch_ / tk.floatCaloPtErr(); + break; + } + float minCaloPt = tk.floatPt() - ptMatchLow_ * tk.floatCaloPtErr(); + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t track %3d (pt %7.2f) to be matched to calo, min pT %7.2f\n", itk, tk.floatPt(), minCaloPt); + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo.used || calo.floatPt() <= minCaloPt) + continue; + float dr = floatDR(tk, calo), dq; + switch (tkCaloLinkMetric_) { + case TkCaloLinkMetric::BestByDR: + if (dr < drbest) { + tk2calo[itk] = ic; + drbest = dr; + } + break; + case TkCaloLinkMetric::BestByDRPt: + dq = dr + std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale; + if (debug_ > 2 && dr < 0.3) + dbgPrintf("PFAlgo2HGC \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", + itk, + tk.floatPt(), + ic, + calo.floatPt(), + dr, + dq); + if (dr < drMatch_ && dq < drbest) { + tk2calo[itk] = ic; + drbest = dq; + } + break; + case TkCaloLinkMetric::BestByDR2Pt2: + dq = hypot(dr, std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale); + if (debug_ > 2 && dr < 0.3) + dbgPrintf("PFAlgo2HGC \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", + itk, + tk.floatPt(), + ic, + calo.floatPt(), + dr, + dq); + if (dr < drMatch_ && dq < drbest) { + tk2calo[itk] = ic; + drbest = dq; + } + break; + } + } + if (debug_ && tk2calo[itk] != -1) + dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) matches to calo %3d (pt %7.2f) with dist %.3f (dr %.3f)\n", + itk, + tk.floatPt(), + tk2calo[itk], + r.calo[tk2calo[itk]].floatPt(), + drbest, + floatDR(tk, r.calo[tk2calo[itk]])); + // now we re-do this for debugging sake, it may be done for real later + if (debug_ && tk2calo[itk] == -1) { + int ibest = -1; + drbest = 0.3; + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo.used) + continue; + float dr = floatDR(tk, calo); + if (dr < drbest) { + ibest = ic; + drbest = dr; + } + } + if (ibest != -1) + dbgPrintf( + "PFAlgo2HGC \t track %3d (pt %7.2f) would match to calo %3d (pt %7.2f) with dr %.3f if the pt min and dr " + "requirement had been relaxed\n", + itk, + tk.floatPt(), + ibest, + r.calo[ibest].floatPt(), + drbest); + } + } +} + +void PFAlgo2HGC::sum_tk2calo(Region &r, + const std::vector &tk2calo, + std::vector &calo2ntk, + std::vector &calo2sumtkpt, + std::vector &calo2sumtkpterr) const { + // for each calo, compute the sum of the track pt + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + const auto &calo = r.calo[ic]; + if (r.globalAbsEta(calo.floatEta()) > 2.5) + continue; + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + if (tk2calo[itk] == ic) { + const auto &tk = r.track[itk]; + if (tk.muonLink || tk.used) + continue; + calo2ntk[ic]++; + calo2sumtkpt[ic] += tk.floatPt(); + calo2sumtkpterr[ic] += std::pow(tk.floatCaloPtErr(), sumTkCaloErr2_ ? 2 : 1); + } + } + if (sumTkCaloErr2_ && calo2sumtkpterr[ic] > 0) + calo2sumtkpterr[ic] = std::sqrt(calo2sumtkpterr[ic]); + } +} + +void PFAlgo2HGC::unlinkedtk_algo(Region &r, const std::vector &tk2calo) const { + // in the meantime, promote unlinked low pt tracks to hadrons + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + auto &tk = r.track[itk]; + if (tk2calo[itk] != -1 || tk.muonLink || tk.used) + continue; + float maxPt = (tk.hwStubs >= tightTrackMinStubs_ && tk.hwChi2 < 10. * tightTrackMaxChi2_) + ? tightTrackMaxInvisiblePt_ + : maxInvisiblePt_; + if (tk.floatPt() < maxPt) { + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t track %3d (pt %7.2f) not matched to calo, kept as charged hadron\n", itk, tk.floatPt()); + auto &p = addTrackToPF(r, tk); + p.hwStatus = GoodTK_NoCalo; + tk.used = true; + } else { + if (debug_) + dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) not matched to calo, dropped\n", itk, tk.floatPt()); + } + } +} + +void PFAlgo2HGC::calo_relink(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr) const { + /// OPTIONAL STEP: try to recover split hadron showers (v1.0): + // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt + // add this pt to the calo pt of the other cluster + // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events + std::vector addtopt(r.calo.size(), 0); + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo2ntk[ic] != 0 || calo.used || r.globalAbsEta(calo.floatEta()) > 2.5) + continue; + int i2best = -1; + float drbest = caloReLinkDr_; + for (int ic2 = 0; ic2 < nc; ++ic2) { + const auto &calo2 = r.calo[ic2]; + if (calo2ntk[ic2] == 0 || calo2.used || r.globalAbsEta(calo2.floatEta()) > 2.5) + continue; + float dr = floatDR(calo, calo2); + //// uncomment below for more verbose debugging + //if (debug_ && dr < 0.5) dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) with no tracks is at dr %.3f from calo %3d with pt %7.2f (sum tk pt %7.2f), track excess %7.2f +- %7.2f\n", ic, calo.floatPt(), dr, ic2, calo2.floatPt(), calo2sumtkpt[ic2], calo2sumtkpt[ic2] - calo2.floatPt(), useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); + if (dr < drbest) { + float ptdiff = + calo2sumtkpt[ic2] - calo2.floatPt() + (useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); + if (ptdiff >= caloReLinkThreshold_ * calo.floatPt()) { + i2best = ic2; + drbest = dr; + } + } + } + if (i2best != -1) { + const auto &calo2 = r.calo[i2best]; + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t calo %3d (pt %7.2f) with no tracks matched within dr %.3f with calo %3d with pt %7.2f (sum " + "tk pt %7.2f), track excess %7.2f +- %7.2f\n", + ic, + calo.floatPt(), + drbest, + i2best, + calo2.floatPt(), + calo2sumtkpt[i2best], + calo2sumtkpt[i2best] - calo2.floatPt(), + useTrackCaloSigma_ ? calo2sumtkpterr[i2best] : calo2.floatPtErr()); + calo.used = true; + addtopt[i2best] += calo.floatPt(); + } + } + // we do this at the end, so that the above loop is parallelizable + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + if (addtopt[ic]) { + auto &calo = r.calo[ic]; + if (debug_) + dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f, sum tk pt %7.2f) is increased to pt %7.2f after merging\n", + ic, + calo.floatPt(), + calo2sumtkpt[ic], + calo.floatPt() + addtopt[ic]); + calo.setFloatPt(calo.floatPt() + addtopt[ic]); + } + } +} + +void PFAlgo2HGC::linkedcalo_algo(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr, + std::vector &calo2alpha) const { + /// ------------- next step (needs the previous) ---------------- + // process matched calo clusters, compare energy to sum track pt + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo2ntk[ic] == 0 || calo.used) + continue; + float ptdiff = calo.floatPt() - calo2sumtkpt[ic]; + float pterr = useTrackCaloSigma_ ? calo2sumtkpterr[ic] : calo.floatPtErr(); + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t calo %3d (pt %7.2f +- %7.2f, empt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif " + "%7.2f +- %7.2f\n", + ic, + calo.floatPt(), + calo.floatPtErr(), + calo.floatEmPt(), + calo2ntk[ic], + calo2sumtkpt[ic], + calo2sumtkpterr[ic], + ptdiff, + pterr); + if (ptdiff > +ptMatchHigh_ * pterr) { + if (ecalPriority_) { + if (calo.floatEmPt() > 1) { + float emptdiff = std::min(ptdiff, calo.floatEmPt()); + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t calo %3d (pt %7.2f, empt %7.2f) ---> make photon with pt %7.2f, reduce ptdiff to " + "%7.2f +- %7.2f\n", + ic, + calo.floatPt(), + calo.floatEmPt(), + emptdiff, + ptdiff - emptdiff, + pterr); + auto &p = addCaloToPF(r, calo); + p.setFloatPt(emptdiff); + p.hwId = l1t::PFCandidate::Photon; + ptdiff -= emptdiff; + } + if (ptdiff > 2) { + if (debug_) + dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f, empt %7.2f) ---> make also neutral hadron with pt %7.2f\n", + ic, + calo.floatPt(), + calo.floatEmPt(), + ptdiff); + auto &p = addCaloToPF(r, calo); + p.setFloatPt(ptdiff); + p.hwId = l1t::PFCandidate::NeutralHadron; + } + } else { + if (debug_) + dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> promoted to neutral with pt %7.2f\n", + ic, + calo.floatPt(), + ptdiff); + auto &p = addCaloToPF(r, calo); + p.setFloatPt(ptdiff); + calo.hwFlags = 0; + } + } else if (ptdiff > -ptMatchLow_ * pterr) { + // nothing to do (weighted average happens when we process the tracks) + calo.hwFlags = 1; + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t calo %3d (pt %7.2f) ---> to be deleted, will use tracks instead\n", ic, calo.floatPt()); + } else { + // tracks overshoot, rescale to tracks to calo + calo2alpha[ic] = rescaleTracks_ ? calo.floatPt() / calo2sumtkpt[ic] : 1.0; + calo.hwFlags = 2; + if (debug_ && rescaleTracks_) + dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> tracks overshoot and will be scaled down by %.4f\n", + ic, + calo.floatPt(), + calo2alpha[ic]); + if (debug_ && !rescaleTracks_) + dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> tracks overshoot by %.4f\n", + ic, + calo.floatPt(), + calo2sumtkpt[ic] / calo.floatPt()); + } + calo.used = true; + } +} + +void PFAlgo2HGC::linkedtk_algo(Region &r, + const std::vector &tk2calo, + const std::vector &calo2ntk, + const std::vector &calo2alpha) const { + // process matched tracks, if necessary rescale or average + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + auto &tk = r.track[itk]; + if (tk2calo[itk] == -1 || tk.muonLink || tk.used) + continue; + auto &p = addTrackToPF(r, tk); + tk.used = true; + const auto &calo = r.calo[tk2calo[itk]]; + if (calo.isEM) + p.hwId = l1t::PFCandidate::Electron; + p.cluster.src = calo.src; + if (calo.hwFlags == 1) { + // can do weighted average if there's just one track + if (calo2ntk[tk2calo[itk]] == 1 && caloTrkWeightedAverage_) { + p.hwStatus = GoodTK_Calo_TkPt; + float ptavg = tk.floatPt(); + if (tk.floatPtErr() > 0) { + float wcalo = 1.0 / std::pow(tk.floatCaloPtErr(), 2); + float wtk = 1.0 / std::pow(tk.floatPtErr(), 2); + ptavg = (calo.floatPt() * wcalo + tk.floatPt() * wtk) / (wcalo + wtk); + p.hwStatus = GoodTK_Calo_TkCaloPt; + } + p.setFloatPt(ptavg); + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t track %3d (pt %7.2f +- %7.2f) combined with calo %3d (pt %7.2f +- %7.2f (from tk) " + "yielding candidate of pt %7.2f\n", + itk, + tk.floatPt(), + tk.floatPtErr(), + tk2calo[itk], + calo.floatPt(), + tk.floatCaloPtErr(), + ptavg); + } else { + p.hwStatus = GoodTK_Calo_TkPt; + if (debug_) + dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) linked to calo %3d promoted to %s\n", + itk, + tk.floatPt(), + tk2calo[itk], + (p.hwId == l1t::PFCandidate::Electron ? "electron" : "charged hadron")); + } + } else if (calo.hwFlags == 2) { + // must rescale + p.setFloatPt(tk.floatPt() * calo2alpha[tk2calo[itk]]); + p.hwStatus = GoodTk_Calo_CaloPt; + if (debug_) + dbgPrintf( + "PFAlgo2HGC \t track %3d (pt %7.2f, stubs %2d chi2 %7.1f) linked to calo %3d promoted to %s with pt %7.2f " + "after maybe rescaling\n", + itk, + tk.floatPt(), + int(tk.hwStubs), + tk.hwChi2 * 0.1f, + tk2calo[itk], + (p.hwId == l1t::PFCandidate::Electron ? "electron" : "charged hadron"), + p.floatPt()); + } + } +} + +void PFAlgo2HGC::unlinkedcalo_algo(Region &r) const { + // process unmatched calo clusters + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + if (!r.calo[ic].used) { + addCaloToPF(r, r.calo[ic]); + if (debug_) + dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) not linked, promoted to neutral\n", ic, r.calo[ic].floatPt()); + } + } +} + +void PFAlgo2HGC::save_muons(Region &r, const std::vector &tk2mu) const { + // finally do muons + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + if (r.track[itk].muonLink) { + auto &p = addTrackToPF(r, r.track[itk]); + p.muonsrc = r.muon[tk2mu[itk]].src; + if (debug_) + dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) promoted to muon.\n", itk, r.track[itk].floatPt()); + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo3.cc b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo3.cc new file mode 100644 index 0000000000000..41402a431eb6e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo3.cc @@ -0,0 +1,911 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "FWCore/Utilities/interface/Exception.h" + +#include "DataFormats/Math/interface/deltaR.h" + +namespace { + template + float floatDR(const T1 &t1, const T2 &t2) { + return deltaR(t1.floatEta(), t1.floatPhi(), t2.floatEta(), t2.floatPhi()); + } +} // namespace + +using namespace l1tpf_impl; + +PFAlgo3::PFAlgo3(const edm::ParameterSet &iConfig) : PFAlgoBase(iConfig) { + debug_ = iConfig.getUntrackedParameter("debugPFAlgo3", iConfig.getUntrackedParameter("debug", 0)); + edm::ParameterSet linkcfg = iConfig.getParameter("linking"); + drMatchMu_ = linkcfg.getParameter("trackMuDR"); + + std::string muMatchMode = linkcfg.getParameter("trackMuMatch"); + if (muMatchMode == "boxBestByPtRatio") + muMatchMode_ = MuMatchMode::BoxBestByPtRatio; + else if (muMatchMode == "drBestByPtRatio") + muMatchMode_ = MuMatchMode::DrBestByPtRatio; + else if (muMatchMode == "drBestByPtDiff") + muMatchMode_ = MuMatchMode::DrBestByPtDiff; + else + throw cms::Exception("Configuration", "bad value for trackMuMatch configurable"); + + std::string tkCaloLinkMetric = linkcfg.getParameter("trackCaloLinkMetric"); + if (tkCaloLinkMetric == "bestByDR") + tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR; + else if (tkCaloLinkMetric == "bestByDRPt") + tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDRPt; + else if (tkCaloLinkMetric == "bestByDR2Pt2") + tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR2Pt2; + else + throw cms::Exception("Configuration", "bad value for tkCaloLinkMetric configurable"); + + drMatch_ = linkcfg.getParameter("trackCaloDR"); + ptMatchLow_ = linkcfg.getParameter("trackCaloNSigmaLow"); + ptMatchHigh_ = linkcfg.getParameter("trackCaloNSigmaHigh"); + useTrackCaloSigma_ = linkcfg.getParameter("useTrackCaloSigma"); + maxInvisiblePt_ = linkcfg.getParameter("maxInvisiblePt"); + + drMatchEm_ = linkcfg.getParameter("trackEmDR"); + trackEmUseAlsoTrackSigma_ = linkcfg.getParameter("trackEmUseAlsoTrackSigma"); + trackEmMayUseCaloMomenta_ = linkcfg.getParameter("trackEmMayUseCaloMomenta"); + emCaloUseAlsoCaloSigma_ = linkcfg.getParameter("emCaloUseAlsoCaloSigma"); + ptMinFracMatchEm_ = linkcfg.getParameter("caloEmPtMinFrac"); + drMatchEmHad_ = linkcfg.getParameter("emCaloDR"); + emHadSubtractionPtSlope_ = linkcfg.getParameter("emCaloSubtractionPtSlope"); + caloReLinkStep_ = linkcfg.getParameter("caloReLink"); + caloReLinkDr_ = linkcfg.getParameter("caloReLinkDR"); + caloReLinkThreshold_ = linkcfg.getParameter("caloReLinkThreshold"); + rescaleTracks_ = linkcfg.getParameter("rescaleTracks"); + caloTrkWeightedAverage_ = linkcfg.getParameter("useCaloTrkWeightedAverage"); + sumTkCaloErr2_ = linkcfg.getParameter("sumTkCaloErr2"); + ecalPriority_ = linkcfg.getParameter("ecalPriority"); + tightTrackMinStubs_ = linkcfg.getParameter("tightTrackMinStubs"); + tightTrackMaxChi2_ = linkcfg.getParameter("tightTrackMaxChi2"); + tightTrackMaxInvisiblePt_ = linkcfg.getParameter("tightTrackMaxInvisiblePt"); +} + +void PFAlgo3::runPF(Region &r) const { + initRegion(r); + + /// ------------- first step (can all go in parallel) ---------------- + + if (debug_) { + dbgPrintf( + "PFAlgo3\nPFAlgo3 region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , %+5.2f ], " + "phi [ %+5.2f , %+5.2f ]\n", + r.etaMin - r.etaExtra, + r.etaMax + r.etaExtra, + r.phiCenter - r.phiHalfWidth - r.phiExtra, + r.phiCenter + r.phiHalfWidth + r.phiExtra, + r.etaMin, + r.etaMax, + r.phiCenter - r.phiHalfWidth, + r.phiCenter + r.phiHalfWidth); + dbgPrintf("PFAlgo3 \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n", + r.track.size(), + r.emcalo.size(), + r.calo.size(), + r.muon.size()); + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + dbgPrintf( + "PFAlgo3 \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + "fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n", + itk, + tk.floatPt(), + tk.floatPtErr(), + tk.floatVtxEta(), + tk.floatVtxPhi(), + tk.floatEta(), + tk.floatPhi(), + int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())), + tk.floatCaloPtErr(), + int(tk.hwStubs), + tk.hwChi2 * 0.1f); + } + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + const auto &em = r.emcalo[iem]; + dbgPrintf( + "PFAlgo3 \t EM %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + "fid %1d calo ptErr %7.2f\n", + iem, + em.floatPt(), + em.floatPtErr(), + em.floatEta(), + em.floatPhi(), + em.floatEta(), + em.floatPhi(), + int(r.fiducialLocal(em.floatEta(), em.floatPhi())), + em.floatPtErr()); + } + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + dbgPrintf( + "PFAlgo3 \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + "fid %1d calo ptErr %7.2f em pt %7.2f \n", + ic, + calo.floatPt(), + calo.floatPtErr(), + calo.floatEta(), + calo.floatPhi(), + calo.floatEta(), + calo.floatPhi(), + int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())), + calo.floatPtErr(), + calo.floatEmPt()); + } + for (int im = 0, nm = r.muon.size(); im < nm; ++im) { + auto &mu = r.muon[im]; + dbgPrintf( + "PFAlgo3 \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " + "fid %1d \n", + im, + mu.floatPt(), + mu.floatEta(), + mu.floatPhi(), + mu.floatEta(), + mu.floatPhi(), + int(r.fiducialLocal(mu.floatEta(), mu.floatPhi()))); + } + } + + std::vector tk2mu(r.track.size(), -1), mu2tk(r.muon.size(), -1); + link_tk2mu(r, tk2mu, mu2tk); + + // match all tracks to the closest EM cluster + std::vector tk2em(r.track.size(), -1); + link_tk2em(r, tk2em); + + // match all em to the closest had (can happen in parallel to the above) + std::vector em2calo(r.emcalo.size(), -1); + link_em2calo(r, em2calo); + + /// ------------- next step (needs the previous) ---------------- + // for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) + std::vector em2ntk(r.emcalo.size(), 0); + std::vector em2sumtkpt(r.emcalo.size(), 0); + std::vector em2sumtkpterr(r.emcalo.size(), 0); + sum_tk2em(r, tk2em, em2ntk, em2sumtkpt, em2sumtkpterr); + + /// ------------- next step (needs the previous) ---------------- + // process ecal clusters after linking + emcalo_algo(r, em2ntk, em2sumtkpt, em2sumtkpterr); + + /// ------------- next step (needs the previous) ---------------- + // promote all flagged tracks to electrons + emtk_algo(r, tk2em, em2ntk, em2sumtkpterr); + sub_em2calo(r, em2calo); + + /// ------------- next step (needs the previous) ---------------- + // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) + std::vector tk2calo(r.track.size(), -1); + link_tk2calo(r, tk2calo); + + /// ------------- next step (needs the previous) ---------------- + // for each calo, compute the sum of the track pt + std::vector calo2ntk(r.calo.size(), 0); + std::vector calo2sumtkpt(r.calo.size(), 0); + std::vector calo2sumtkpterr(r.calo.size(), 0); + sum_tk2calo(r, tk2calo, calo2ntk, calo2sumtkpt, calo2sumtkpterr); + + // in the meantime, promote unlinked low pt tracks to hadrons + unlinkedtk_algo(r, tk2calo); + + /// ------------- next step (needs the previous) ---------------- + /// OPTIONAL STEP: try to recover split hadron showers (v1.0): + // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events + if (caloReLinkStep_) + calo_relink(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr); + + /// ------------- next step (needs the previous) ---------------- + // process matched calo clusters, compare energy to sum track pt + std::vector calo2alpha(r.calo.size(), 1); + linkedcalo_algo(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr, calo2alpha); + + /// ------------- next step (needs the previous) ---------------- + /// process matched tracks, if necessary rescale or average + linkedtk_algo(r, tk2calo, calo2ntk, calo2alpha); + // process unmatched calo clusters + unlinkedcalo_algo(r); + // finally do muons + save_muons(r, tk2mu); +} + +void PFAlgo3::link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const { + // do a rectangular match for the moment; make a box of the same are as a 0.2 cone + int intDrMuonMatchBox = std::ceil(drMatchMu_ * CaloCluster::ETAPHI_SCALE * std::sqrt(M_PI / 4)); + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + tk2mu[itk] = false; + } + for (int imu = 0, nmu = r.muon.size(); imu < nmu; ++imu) { + const auto &mu = r.muon[imu]; + if (debug_) + dbgPrintf( + "PFAlgo3 \t muon %3d (pt %7.2f, eta %+5.2f, phi %+5.2f) \n", imu, mu.floatPt(), mu.floatEta(), mu.floatPhi()); + float minDistance = 9e9; + switch (muMatchMode_) { + case MuMatchMode::BoxBestByPtRatio: + minDistance = 4.; + break; + case MuMatchMode::DrBestByPtRatio: + minDistance = 4.; + break; + case MuMatchMode::DrBestByPtDiff: + minDistance = 0.5 * mu.floatPt(); + break; + } + int imatch = -1; + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + int deta = std::abs(mu.hwEta - tk.hwEta); + int dphi = std::abs((mu.hwPhi - tk.hwPhi) % CaloCluster::PHI_WRAP); + float dr = floatDR(mu, tk); + float dpt = std::abs(mu.floatPt() - tk.floatPt()); + float dptr = (mu.hwPt > tk.hwPt ? mu.floatPt() / tk.floatPt() : tk.floatPt() / mu.floatPt()); + bool ok = false; + float distance = 9e9; + switch (muMatchMode_) { + case MuMatchMode::BoxBestByPtRatio: + ok = (deta < intDrMuonMatchBox) && (dphi < intDrMuonMatchBox); + distance = dptr; + break; + case MuMatchMode::DrBestByPtRatio: + ok = (dr < drMatchMu_); + distance = dptr; + break; + case MuMatchMode::DrBestByPtDiff: + ok = (dr < drMatchMu_); + distance = dpt; + break; + } + if (debug_ && dr < 0.4) { + dbgPrintf( + "PFAlgo3 \t\t possible match with track %3d (pt %7.2f, caloeta %+5.2f, calophi %+5.2f, dr %.2f, eta " + "%+5.2f, phi %+5.2f, dr %.2f): angular %1d, distance %.3f (vs %.3f)\n", + itk, + tk.floatPt(), + tk.floatEta(), + tk.floatPhi(), + dr, + tk.floatVtxEta(), + tk.floatVtxPhi(), + deltaR(mu.floatEta(), mu.floatPhi(), tk.floatVtxEta(), tk.floatVtxPhi()), + (ok ? 1 : 0), + distance, + minDistance); + } + if (!ok) + continue; + // FIXME for the moment, we do the floating point matching in pt + if (distance < minDistance) { + minDistance = distance; + imatch = itk; + } + } + if (debug_ && imatch > -1) + dbgPrintf("PFAlgo3 \t muon %3d (pt %7.2f) linked to track %3d (pt %7.2f)\n", + imu, + mu.floatPt(), + imatch, + r.track[imatch].floatPt()); + if (debug_ && imatch == -1) + dbgPrintf("PFAlgo3 \t muon %3d (pt %7.2f) not linked to any track\n", imu, mu.floatPt()); + mu2tk[imu] = imatch; + if (imatch > -1) { + tk2mu[imatch] = imu; + r.track[imatch].muonLink = true; + } + } +} + +void PFAlgo3::link_tk2em(Region &r, std::vector &tk2em) const { + // match all tracks to the closest EM cluster + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + //if (tk.muonLink) continue; // not necessary I think + float drbest = drMatchEm_; + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + const auto &em = r.emcalo[iem]; + float dr = floatDR(tk, em); + if (dr < drbest) { + tk2em[itk] = iem; + drbest = dr; + } + } + if (debug_ && tk2em[itk] != -1) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) matches to EM %3d (pt %7.2f) with dr %.3f\n", + itk, + tk.floatPt(), + tk2em[itk], + tk2em[itk] == -1 ? 0.0 : r.emcalo[tk2em[itk]].floatPt(), + drbest); + } +} + +void PFAlgo3::link_em2calo(Region &r, std::vector &em2calo) const { + // match all em to the closest had (can happen in parallel to the above) + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + const auto &em = r.emcalo[iem]; + float drbest = drMatchEmHad_; + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + const auto &calo = r.calo[ic]; + if (calo.floatEmPt() < ptMinFracMatchEm_ * em.floatPt()) + continue; + float dr = floatDR(calo, em); + if (dr < drbest) { + em2calo[iem] = ic; + drbest = dr; + } + } + if (debug_ && em2calo[iem] != -1) + dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) matches to calo %3d (pt %7.2f, empt %7.2f) with dr %.3f\n", + iem, + em.floatPt(), + em2calo[iem], + em2calo[iem] == -1 ? 0.0 : r.calo[em2calo[iem]].floatPt(), + em2calo[iem] == -1 ? 0.0 : r.calo[em2calo[iem]].floatEmPt(), + drbest); + } +} + +void PFAlgo3::sum_tk2em(Region &r, + const std::vector &tk2em, + std::vector &em2ntk, + std::vector &em2sumtkpt, + std::vector &em2sumtkpterr) const { + // for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + const auto &em = r.emcalo[iem]; + if (r.globalAbsEta(em.floatEta()) > 2.5) + continue; + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + if (tk2em[itk] == iem) { + const auto &tk = r.track[itk]; + if (tk.muonLink) + continue; + em2ntk[iem]++; + em2sumtkpt[iem] += tk.floatPt(); + em2sumtkpterr[iem] += tk.floatPtErr(); + } + } + } +} + +void PFAlgo3::emcalo_algo(Region &r, + const std::vector &em2ntk, + const std::vector &em2sumtkpt, + const std::vector &em2sumtkpterr) const { + // process ecal clusters after linking + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + auto &em = r.emcalo[iem]; + em.isEM = false; + em.used = false; + em.hwFlags = 0; + if (r.globalAbsEta(em.floatEta()) > 2.5) + continue; + if (debug_) + dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif %7.2f +- %7.2f\n", + iem, + em.floatPt(), + em2ntk[iem], + em2sumtkpt[iem], + em2sumtkpterr[iem], + em.floatPt() - em2sumtkpt[iem], + std::max(em2sumtkpterr[iem], em.floatPtErr())); + if (em2ntk[iem] == 0) { // Photon + em.isEM = true; + addCaloToPF(r, em); + em.used = true; + if (debug_) + dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to photon\n", iem, em.floatPt()); + continue; + } + float ptdiff = em.floatPt() - em2sumtkpt[iem]; + float pterr = trackEmUseAlsoTrackSigma_ ? std::max(em2sumtkpterr[iem], em.floatPtErr()) : em.floatPtErr(); + // avoid "pt = inf +- inf" track to become an electron. + if (pterr > 2 * em.floatPt()) { + pterr = 2 * em.floatPt(); + if (debug_) + dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> clamp pterr ---> new ptdiff %7.2f +- %7.2f\n", + iem, + em.floatPt(), + ptdiff, + pterr); + } + + if (ptdiff > -ptMatchLow_ * pterr) { + em.isEM = true; + em.used = true; + // convert leftover to a photon if significant + if (ptdiff > +ptMatchHigh_ * pterr) { + auto &p = addCaloToPF(r, em); + p.setFloatPt(ptdiff); + if (debug_) + dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to electron(s) + photon (pt %7.2f)\n", + iem, + em.floatPt(), + ptdiff); + } else { + em.hwFlags = 1; // may use calo momentum + if (debug_) + dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to electron(s)\n", iem, em.floatPt()); + } + } else { + em.isEM = false; + em.used = false; + em.hwFlags = 0; + //discardCalo(r, em, 2); + } + } +} + +void PFAlgo3::emtk_algo(Region &r, + const std::vector &tk2em, + const std::vector &em2ntk, + const std::vector &em2sumtkpterr) const { + // promote all flagged tracks to electrons + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + auto &tk = r.track[itk]; + if (tk2em[itk] == -1 || tk.muonLink) + continue; + const auto &em = r.emcalo[tk2em[itk]]; + if (em.isEM) { + auto &p = addTrackToPF(r, tk); + p.cluster.src = em.src; + // FIXME to check if this is useful + if (trackEmMayUseCaloMomenta_ && em2ntk[tk2em[itk]] == 1 && em.hwFlags == 1) { + if (em.floatPtErr() < em2sumtkpterr[tk2em[itk]]) { + p.setFloatPt(em.floatPt()); + } + } + if (debug_) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) matched to EM %3d (pt %7.2f) promoted to electron with pt %7.2f\n", + itk, + tk.floatPt(), + tk2em[itk], + em.floatPt(), + p.floatPt()); + p.hwId = l1t::PFCandidate::Electron; + tk.used = true; + } + } +} + +void PFAlgo3::sub_em2calo(Region &r, const std::vector &em2calo) const { + // subtract EM component from Calo clusters for all photons and electrons (within tracker coverage) + // kill clusters that end up below their own uncertainty, or that loose 90% of the energy, + // unless they still have live EM clusters pointing to them + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + float pt0 = calo.floatPt(), ept0 = calo.floatEmPt(), pt = pt0, ept = ept0; + bool keepme = false; + for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { + if (em2calo[iem] == ic) { + const auto &em = r.emcalo[iem]; + if (em.isEM) { + if (debug_) + dbgPrintf( + "PFAlgo3 \t EM %3d (pt %7.2f) is subtracted from calo %3d (pt %7.2f) scaled by %.3f (deltaPt = " + "%7.2f)\n", + iem, + em.floatPt(), + ic, + calo.floatPt(), + emHadSubtractionPtSlope_, + emHadSubtractionPtSlope_ * em.floatPt()); + pt -= emHadSubtractionPtSlope_ * em.floatPt(); + ept -= em.floatPt(); + } else { + keepme = true; + if (debug_) + dbgPrintf( + "PFAlgo3 \t EM %3d (pt %7.2f) not subtracted from calo %3d (pt %7.2f), and calo marked to be kept " + "after EM subtraction\n", + iem, + em.floatPt(), + ic, + calo.floatPt()); + } + } + } + if (pt < pt0) { + if (debug_) + dbgPrintf( + "PFAlgo3 \t calo %3d (pt %7.2f +- %7.2f) has a subtracted pt of %7.2f, empt %7.2f -> %7.2f, isem %d\n", + ic, + calo.floatPt(), + calo.floatPtErr(), + pt, + ept0, + ept, + calo.isEM); + calo.setFloatPt(pt); + calo.setFloatEmPt(ept); + if (!keepme && + ((emCaloUseAlsoCaloSigma_ ? pt < calo.floatPtErr() : false) || pt <= 0.125 * pt0 || + (calo.isEM && ept <= 0.125 * ept0))) { // the <= is important since in firmware the pt0/8 can be zero + if (debug_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ----> discarded\n", ic, calo.floatPt()); + calo.used = true; + calo.setFloatPt(pt0); //discardCalo(r, calo, 1); // log this as discarded, for debugging + } + } + } +} + +void PFAlgo3::link_tk2calo(Region &r, std::vector &tk2calo) const { + // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + const auto &tk = r.track[itk]; + if (tk.muonLink || tk.used) + continue; // not necessary but just a waste of CPU otherwise + float drbest = drMatch_, dptscale = 0; + switch (tkCaloLinkMetric_) { + case TkCaloLinkMetric::BestByDR: + drbest = drMatch_; + break; + case TkCaloLinkMetric::BestByDRPt: + drbest = 1.0; + dptscale = drMatch_ / tk.floatCaloPtErr(); + break; + case TkCaloLinkMetric::BestByDR2Pt2: + drbest = 1.0; + dptscale = drMatch_ / tk.floatCaloPtErr(); + break; + } + float minCaloPt = tk.floatPt() - ptMatchLow_ * tk.floatCaloPtErr(); + if (debug_) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) to be matched to calo, min pT %7.2f\n", itk, tk.floatPt(), minCaloPt); + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo.used || calo.floatPt() <= minCaloPt) + continue; + float dr = floatDR(tk, calo), dq; + switch (tkCaloLinkMetric_) { + case TkCaloLinkMetric::BestByDR: + if (dr < drbest) { + tk2calo[itk] = ic; + drbest = dr; + } + break; + case TkCaloLinkMetric::BestByDRPt: + dq = dr + std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale; + //if (debug_ && dr < 0.2) dbgPrintf("PFAlgo3 \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", itk, tk.floatPt(), ic, calo.floatPt(), dr, dq); + if (dr < drMatch_ && dq < drbest) { + tk2calo[itk] = ic; + drbest = dq; + } + break; + case TkCaloLinkMetric::BestByDR2Pt2: + dq = hypot(dr, std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale); + //if (debug_ && dr < 0.2) dbgPrintf("PFAlgo3 \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", itk, tk.floatPt(), ic, calo.floatPt(), dr, dq); + if (dr < drMatch_ && dq < drbest) { + tk2calo[itk] = ic; + drbest = dq; + } + break; + } + } + if (debug_ && tk2calo[itk] != -1) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) matches to calo %3d (pt %7.2f) with dist %.3f\n", + itk, + tk.floatPt(), + tk2calo[itk], + tk2calo[itk] == -1 ? 0.0 : r.calo[tk2calo[itk]].floatPt(), + drbest); + // now we re-do this for debugging sake, it may be done for real later + if (debug_ && tk2calo[itk] == -1) { + int ibest = -1; + drbest = 0.3; + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo.used) + continue; + float dr = floatDR(tk, calo); + if (dr < drbest) { + ibest = ic; + drbest = dr; + } + } + if (ibest != -1) + dbgPrintf( + "PFAlgo3 \t track %3d (pt %7.2f) would match to calo %3d (pt %7.2f) with dr %.3f if the pt min and dr " + "requirement had been relaxed\n", + itk, + tk.floatPt(), + ibest, + r.calo[ibest].floatPt(), + drbest); + } + } +} + +void PFAlgo3::sum_tk2calo(Region &r, + const std::vector &tk2calo, + std::vector &calo2ntk, + std::vector &calo2sumtkpt, + std::vector &calo2sumtkpterr) const { + // for each calo, compute the sum of the track pt + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + const auto &calo = r.calo[ic]; + if (r.globalAbsEta(calo.floatEta()) > 2.5) + continue; + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + if (tk2calo[itk] == ic) { + const auto &tk = r.track[itk]; + if (tk.muonLink || tk.used) + continue; + calo2ntk[ic]++; + calo2sumtkpt[ic] += tk.floatPt(); + calo2sumtkpterr[ic] += std::pow(tk.floatCaloPtErr(), sumTkCaloErr2_ ? 2 : 1); + } + } + if (sumTkCaloErr2_ && calo2sumtkpterr[ic] > 0) + calo2sumtkpterr[ic] = std::sqrt(calo2sumtkpterr[ic]); + } +} + +void PFAlgo3::unlinkedtk_algo(Region &r, const std::vector &tk2calo) const { + // in the meantime, promote unlinked low pt tracks to hadrons + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + auto &tk = r.track[itk]; + if (tk2calo[itk] != -1 || tk.muonLink || tk.used) + continue; + float maxPt = (tk.hwStubs >= tightTrackMinStubs_ && tk.hwChi2 < 10 * tightTrackMaxChi2_) ? tightTrackMaxInvisiblePt_ + : maxInvisiblePt_; + if (tk.floatPt() < maxPt) { + if (debug_) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) not matched to calo, kept as charged hadron\n", itk, tk.floatPt()); + auto &p = addTrackToPF(r, tk); + p.hwStatus = GoodTK_NoCalo; + tk.used = true; + } else { + if (debug_) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) not matched to calo, dropped\n", itk, tk.floatPt()); + //discardTrack(r, tk, BadTK_NoCalo); // log this as discarded, for debugging + } + } +} + +void PFAlgo3::calo_relink(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr) const { + /// OPTIONAL STEP: try to recover split hadron showers (v1.0): + // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt + // add this pt to the calo pt of the other cluster + // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events + std::vector addtopt(r.calo.size(), 0); + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo2ntk[ic] != 0 || calo.used || r.globalAbsEta(calo.floatEta()) > 2.5) + continue; + int i2best = -1; + float drbest = caloReLinkDr_; + for (int ic2 = 0; ic2 < nc; ++ic2) { + const auto &calo2 = r.calo[ic2]; + if (calo2ntk[ic2] == 0 || calo2.used || r.globalAbsEta(calo2.floatEta()) > 2.5) + continue; + float dr = floatDR(calo, calo2); + //// uncomment below for more verbose debugging + //if (debug_ && dr < 0.5) dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) with no tracks is at dr %.3f from calo %3d with pt %7.2f (sum tk pt %7.2f), track excess %7.2f +- %7.2f\n", ic, calo.floatPt(), dr, ic2, calo2.floatPt(), calo2sumtkpt[ic2], calo2sumtkpt[ic2] - calo2.floatPt(), useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); + if (dr < drbest) { + float ptdiff = + calo2sumtkpt[ic2] - calo2.floatPt() + (useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); + if (ptdiff >= caloReLinkThreshold_ * calo.floatPt()) { + i2best = ic2; + drbest = dr; + } + } + } + if (i2best != -1) { + const auto &calo2 = r.calo[i2best]; + if (debug_) + dbgPrintf( + "PFAlgo3 \t calo %3d (pt %7.2f) with no tracks matched within dr %.3f with calo %3d with pt %7.2f (sum tk " + "pt %7.2f), track excess %7.2f +- %7.2f\n", + ic, + calo.floatPt(), + drbest, + i2best, + calo2.floatPt(), + calo2sumtkpt[i2best], + calo2sumtkpt[i2best] - calo2.floatPt(), + useTrackCaloSigma_ ? calo2sumtkpterr[i2best] : calo2.floatPtErr()); + calo.used = true; + addtopt[i2best] += calo.floatPt(); + } + } + // we do this at the end, so that the above loop is parallelizable + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + if (addtopt[ic]) { + auto &calo = r.calo[ic]; + if (debug_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f, sum tk pt %7.2f) is increased to pt %7.2f after merging\n", + ic, + calo.floatPt(), + calo2sumtkpt[ic], + calo.floatPt() + addtopt[ic]); + calo.setFloatPt(calo.floatPt() + addtopt[ic]); + } + } +} + +void PFAlgo3::linkedcalo_algo(Region &r, + const std::vector &calo2ntk, + const std::vector &calo2sumtkpt, + const std::vector &calo2sumtkpterr, + std::vector &calo2alpha) const { + /// ------------- next step (needs the previous) ---------------- + // process matched calo clusters, compare energy to sum track pt + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + auto &calo = r.calo[ic]; + if (calo2ntk[ic] == 0 || calo.used) + continue; + float ptdiff = calo.floatPt() - calo2sumtkpt[ic]; + float pterr = useTrackCaloSigma_ ? calo2sumtkpterr[ic] : calo.floatPtErr(); + if (debug_) + dbgPrintf( + "PFAlgo3 \t calo %3d (pt %7.2f +- %7.2f, empt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif " + "%7.2f +- %7.2f\n", + ic, + calo.floatPt(), + calo.floatPtErr(), + calo.floatEmPt(), + calo2ntk[ic], + calo2sumtkpt[ic], + calo2sumtkpterr[ic], + ptdiff, + pterr); + if (ptdiff > +ptMatchHigh_ * pterr) { + if (ecalPriority_) { + if (calo.floatEmPt() > 1) { + float emptdiff = std::min(ptdiff, calo.floatEmPt()); + if (debug_) + dbgPrintf( + "PFAlgo3 \t calo %3d (pt %7.2f, empt %7.2f) ---> make photon with pt %7.2f, reduce ptdiff to %7.2f " + "+- %7.2f\n", + ic, + calo.floatPt(), + calo.floatEmPt(), + emptdiff, + ptdiff - emptdiff, + pterr); + auto &p = addCaloToPF(r, calo); + p.setFloatPt(emptdiff); + p.hwId = l1t::PFCandidate::Photon; + ptdiff -= emptdiff; + } + if (ptdiff > 2) { + if (debug_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f, empt %7.2f) ---> make also neutral hadron with pt %7.2f\n", + ic, + calo.floatPt(), + calo.floatEmPt(), + ptdiff); + auto &p = addCaloToPF(r, calo); + p.setFloatPt(ptdiff); + p.hwId = l1t::PFCandidate::NeutralHadron; + } + } else { + if (debug_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ---> promoted to neutral with pt %7.2f\n", + ic, + calo.floatPt(), + ptdiff); + auto &p = addCaloToPF(r, calo); + p.setFloatPt(ptdiff); + calo.hwFlags = 0; + } + } else if (ptdiff > -ptMatchLow_ * pterr) { + // nothing to do (weighted average happens when we process the tracks) + calo.hwFlags = 1; + if (debug_) + dbgPrintf( + "PFAlgo3 \t calo %3d (pt %7.2f) ---> to be deleted, will use tracks instead\n", ic, calo.floatPt()); + //discardCalo(r, calo, 0); // log this as discarded, for debugging + } else { + // tracks overshoot, rescale to tracks to calo + calo2alpha[ic] = rescaleTracks_ ? calo.floatPt() / calo2sumtkpt[ic] : 1.0; + calo.hwFlags = 2; + if (debug_ && rescaleTracks_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ---> tracks overshoot and will be scaled down by %.4f\n", + ic, + calo.floatPt(), + calo2alpha[ic]); + if (debug_ && !rescaleTracks_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ---> tracks overshoot by %.4f\n", + ic, + calo.floatPt(), + calo2sumtkpt[ic] / calo.floatPt()); + } + calo.used = true; + } +} + +void PFAlgo3::linkedtk_algo(Region &r, + const std::vector &tk2calo, + const std::vector &calo2ntk, + const std::vector &calo2alpha) const { + // process matched tracks, if necessary rescale or average + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + auto &tk = r.track[itk]; + if (tk2calo[itk] == -1 || tk.muonLink || tk.used) + continue; + auto &p = addTrackToPF(r, tk); + tk.used = true; + const auto &calo = r.calo[tk2calo[itk]]; + p.cluster.src = calo.src; + if (calo.hwFlags == 1) { + // can do weighted average if there's just one track + if (calo2ntk[tk2calo[itk]] == 1 && caloTrkWeightedAverage_) { + p.hwStatus = GoodTK_Calo_TkPt; + float ptavg = tk.floatPt(); + if (tk.floatPtErr() > 0) { + float wcalo = 1.0 / std::pow(tk.floatCaloPtErr(), 2); + float wtk = 1.0 / std::pow(tk.floatPtErr(), 2); + ptavg = (calo.floatPt() * wcalo + tk.floatPt() * wtk) / (wcalo + wtk); + p.hwStatus = GoodTK_Calo_TkCaloPt; + } + p.setFloatPt(ptavg); + if (debug_) + dbgPrintf( + "PFAlgo3 \t track %3d (pt %7.2f +- %7.2f) combined with calo %3d (pt %7.2f +- %7.2f (from tk) yielding " + "candidate of pt %7.2f\n", + itk, + tk.floatPt(), + tk.floatPtErr(), + tk2calo[itk], + calo.floatPt(), + tk.floatCaloPtErr(), + ptavg); + } else { + p.hwStatus = GoodTK_Calo_TkPt; + if (debug_) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) linked to calo %3d promoted to charged hadron\n", + itk, + tk.floatPt(), + tk2calo[itk]); + } + } else if (calo.hwFlags == 2) { + // must rescale + p.setFloatPt(tk.floatPt() * calo2alpha[tk2calo[itk]]); + p.hwStatus = GoodTk_Calo_CaloPt; + if (debug_) + dbgPrintf( + "PFAlgo3 \t track %3d (pt %7.2f, stubs %2d chi2 %7.1f) linked to calo %3d promoted to charged hadron with " + "pt %7.2f after maybe rescaling\n", + itk, + tk.floatPt(), + int(tk.hwStubs), + tk.hwChi2 * 0.1f, + tk2calo[itk], + p.floatPt()); + } + } +} + +void PFAlgo3::unlinkedcalo_algo(Region &r) const { + // process unmatched calo clusters + for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { + if (!r.calo[ic].used) { + addCaloToPF(r, r.calo[ic]); + if (debug_) + dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) not linked, promoted to neutral\n", ic, r.calo[ic].floatPt()); + } + } +} + +void PFAlgo3::save_muons(Region &r, const std::vector &tk2mu) const { + // finally do muons + for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { + if (r.track[itk].muonLink) { + auto &p = addTrackToPF(r, r.track[itk]); + p.muonsrc = r.muon[tk2mu[itk]].src; + if (debug_) + dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) promoted to muon.\n", itk, r.track[itk].floatPt()); + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgoBase.cc b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgoBase.cc new file mode 100644 index 0000000000000..f3b5f3d83652b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgoBase.cc @@ -0,0 +1,57 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +using namespace l1tpf_impl; + +PFAlgoBase::PFAlgoBase(const edm::ParameterSet &iConfig) : debug_(iConfig.getUntrackedParameter("debug", 0)) {} + +PFAlgoBase::~PFAlgoBase() {} + +void PFAlgoBase::initRegion(Region &r) const { + r.inputSort(); + r.pf.clear(); + r.puppi.clear(); + for (auto &c : r.calo) + c.used = false; + for (auto &c : r.emcalo) + c.used = false; + for (auto &t : r.track) { + t.used = false; + t.muonLink = false; + } +} + +PFParticle &PFAlgoBase::addTrackToPF(std::vector &pfs, const PropagatedTrack &tk) const { + PFParticle pf; + pf.hwPt = tk.hwPt; + pf.hwEta = tk.hwEta; + pf.hwPhi = tk.hwPhi; + pf.hwVtxEta = tk.hwEta; // FIXME: get from the track + pf.hwVtxPhi = tk.hwPhi; // before propagation + pf.track = tk; + pf.cluster.hwPt = 0; + pf.cluster.src = nullptr; + pf.muonsrc = nullptr; + pf.hwId = (tk.muonLink ? l1t::PFCandidate::Muon : l1t::PFCandidate::ChargedHadron); + pf.hwStatus = 0; + pfs.push_back(pf); + return pfs.back(); +} + +PFParticle &PFAlgoBase::addCaloToPF(std::vector &pfs, const CaloCluster &calo) const { + PFParticle pf; + pf.hwPt = calo.hwPt; + pf.hwEta = calo.hwEta; + pf.hwPhi = calo.hwPhi; + pf.hwVtxEta = calo.hwEta; + pf.hwVtxPhi = calo.hwPhi; + pf.track.hwPt = 0; + pf.track.src = nullptr; + pf.cluster = calo; + pf.muonsrc = nullptr; + pf.hwId = (calo.isEM ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron); + pf.hwStatus = 0; + pfs.push_back(pf); + return pfs.back(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PUAlgoBase.cc b/L1Trigger/Phase2L1ParticleFlow/src/PUAlgoBase.cc new file mode 100644 index 0000000000000..b1c55079b0aa2 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/PUAlgoBase.cc @@ -0,0 +1,81 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h" + +#include + +using namespace l1tpf_impl; + +PUAlgoBase::PUAlgoBase(const edm::ParameterSet &iConfig) + : debug_(iConfig.getUntrackedParameter("debug", 0)), + etaCharged_(iConfig.getParameter("etaCharged")), + vtxRes_(iConfig.getParameter("vtxRes")), + vtxAdaptiveCut_(iConfig.getParameter("vtxAdaptiveCut")) {} + +PUAlgoBase::~PUAlgoBase() {} + +void PUAlgoBase::runChargedPV(Region &r, float z0) const { + int16_t iZ0 = round(z0 * InputTrack::Z0_SCALE); + int16_t iDZ = round(1.5 * vtxRes_ * InputTrack::Z0_SCALE); + int16_t iDZ2 = vtxAdaptiveCut_ ? round(4.0 * vtxRes_ * InputTrack::Z0_SCALE) : iDZ; + for (PFParticle &p : r.pf) { + bool barrel = std::abs(p.track.hwVtxEta) < InputTrack::VTX_ETA_1p3; + if (r.relativeCoordinates) + barrel = + (std::abs(r.globalAbsEta(p.track.floatVtxEta())) < 1.3); // FIXME could make a better integer implementation + p.chargedPV = (p.hwId <= 1 && std::abs(p.track.hwZ0 - iZ0) < (barrel ? iDZ : iDZ2)); + } +} + +void PUAlgoBase::doVertexing(std::vector &rs, VertexAlgo algo, float &pvdz) const { + int lNBins = int(40. / vtxRes_); + if (algo == VertexAlgo::TP) + lNBins *= 3; + std::unique_ptr h_dz(new TH1F("h_dz", "h_dz", lNBins, -20, 20)); + if (algo != VertexAlgo::External) { + for (const Region &r : rs) { + for (const PropagatedTrack &p : r.track) { + if (rs.size() > 1) { + if (!r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi())) + continue; // skip duplicates + } + h_dz->Fill(p.floatDZ(), std::min(p.floatPt(), 50.f)); + } + } + } + switch (algo) { + case VertexAlgo::External: + break; + case VertexAlgo::Old: { + int imaxbin = h_dz->GetMaximumBin(); + pvdz = h_dz->GetXaxis()->GetBinCenter(imaxbin); + }; break; + case VertexAlgo::TP: { + float max = 0; + int bmax = -1; + for (int b = 1; b <= lNBins; ++b) { + float sum3 = h_dz->GetBinContent(b) + h_dz->GetBinContent(b + 1) + h_dz->GetBinContent(b - 1); + if (bmax == -1 || sum3 > max) { + max = sum3; + bmax = b; + } + } + pvdz = h_dz->GetXaxis()->GetBinCenter(bmax); + }; break; + } + int16_t iZ0 = round(pvdz * InputTrack::Z0_SCALE); + int16_t iDZ = round(1.5 * vtxRes_ * InputTrack::Z0_SCALE); + int16_t iDZ2 = vtxAdaptiveCut_ ? round(4.0 * vtxRes_ * InputTrack::Z0_SCALE) : iDZ; + for (Region &r : rs) { + for (PropagatedTrack &p : r.track) { + bool central = std::abs(p.hwVtxEta) < InputTrack::VTX_ETA_1p3; + if (r.relativeCoordinates) + central = + (std::abs(r.globalAbsEta(p.floatVtxEta())) < 1.3); // FIXME could make a better integer implementation + p.fromPV = (std::abs(p.hwZ0 - iZ0) < (central ? iDZ : iDZ2)); + } + } +} + +const std::vector &PUAlgoBase::puGlobalNames() const { + static const std::vector empty_; + return empty_; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ParametricResolution.cc b/L1Trigger/Phase2L1ParticleFlow/src/ParametricResolution.cc new file mode 100644 index 0000000000000..a37c76bf2ca17 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ParametricResolution.cc @@ -0,0 +1,48 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" + +std::vector l1tpf::ParametricResolution::getVFloat(const edm::ParameterSet &cpset, const std::string &name) { + std::vector vd = cpset.getParameter>(name); + return std::vector(vd.begin(), vd.end()); +} + +l1tpf::ParametricResolution::ParametricResolution(const edm::ParameterSet &cpset) + : etas_(getVFloat(cpset, "etaBins")), offsets_(getVFloat(cpset, "offset")), scales_(getVFloat(cpset, "scale")) { + if (cpset.existsAs>("ptMin")) { + ptMins_ = getVFloat(cpset, "ptMin"); + } else { + float ptMin = cpset.existsAs("ptMin") ? cpset.getParameter("ptMin") : 0; + ptMins_ = std::vector(etas_.size(), ptMin); + } + if (cpset.existsAs>("ptMax")) { + ptMaxs_ = getVFloat(cpset, "ptMax"); + } else { + ptMaxs_ = std::vector(etas_.size(), 1e6); + } + + std::string skind = cpset.getParameter("kind"); + if (skind == "track") + kind_ = Kind::Track; + else if (skind == "calo") + kind_ = Kind::Calo; + else + throw cms::Exception("Configuration", "Bad kind of resolution: " + skind); +} + +float l1tpf::ParametricResolution::operator()(const float pt, const float abseta) const { + for (unsigned int i = 0, n = etas_.size(); i < n; ++i) { + if (pt > ptMaxs_[i]) + continue; + if (abseta < etas_[i]) { + switch (kind_) { + case Kind::Track: + return pt * std::min(1.f, std::hypot(pt * scales_[i] * 0.001, offsets_[i])); + case Kind::Calo: + return std::min(pt, pt * scales_[i] + offsets_[i]); + if (pt < ptMins_[i]) + return pt * std::min(1, scales_[i] + offsets_[i] / ptMins_[i]); + return std::min(pt, pt * scales_[i] + offsets_[i]); + } + } + } + return std::min(pt, 0.3 * pt + 7); // saturate to 100% at 10 GeV, and to 30% at high pt +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PuppiAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/PuppiAlgo.cc new file mode 100644 index 0000000000000..8f93b627902ef --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/PuppiAlgo.cc @@ -0,0 +1,266 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaR.h" +#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" + +#include "Math/ProbFunc.h" + +namespace { + std::vector vd2vf(const std::vector &vd) { + std::vector ret; + ret.insert(ret.end(), vd.begin(), vd.end()); + return ret; + } +} // namespace + +using namespace l1tpf_impl; + +PuppiAlgo::PuppiAlgo(const edm::ParameterSet &iConfig) + : PUAlgoBase(iConfig), + puppiDr_(iConfig.getParameter("puppiDr")), + puppiDrMin_(iConfig.getParameter("puppiDrMin")), + puppiPtMax_(iConfig.getParameter("puppiPtMax")), + puppiEtaCuts_(vd2vf(iConfig.getParameter>("puppiEtaCuts"))), + puppiPtCuts_(vd2vf(iConfig.getParameter>("puppiPtCuts"))), + puppiPtCutsPhotons_(vd2vf(iConfig.getParameter>("puppiPtCutsPhotons"))), + puppiUsingBareTracks_(iConfig.getParameter("puppiUsingBareTracks")) { + debug_ = iConfig.getUntrackedParameter("puppiDebug", debug_); + if (puppiEtaCuts_.size() != puppiPtCuts_.size() || puppiPtCuts_.size() != puppiPtCutsPhotons_.size()) { + throw cms::Exception("Configuration", "Bad PUPPI config"); + } + for (unsigned int i = 0, n = puppiEtaCuts_.size(); i < n; ++i) { + intPuppiEtaCuts_.push_back(std::round(puppiEtaCuts_[i] * CaloCluster::ETAPHI_SCALE)); + intPuppiPtCuts_.push_back(std::round(puppiPtCuts_[i] * CaloCluster::PT_SCALE)); + intPuppiPtCutsPhotons_.push_back(std::round(puppiPtCutsPhotons_[i] * CaloCluster::PT_SCALE)); + } +} + +PuppiAlgo::~PuppiAlgo() {} + +const std::vector &PuppiAlgo::puGlobalNames() const { + static const std::vector names_{"alphaCMed", "alphaCRms", "alphaFMed", "alphaFRms"}; + return names_; +} +void PuppiAlgo::doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const { + globals.resize(4); + computePuppiMedRMS(rs, globals[0], globals[1], globals[2], globals[3]); +} + +void PuppiAlgo::runNeutralsPU(Region &r, float npu, const std::vector &globals) const { + std::vector alphaC, alphaF; + computePuppiAlphas(r, alphaC, alphaF); + computePuppiWeights(r, alphaC, alphaF, globals[0], globals[1], globals[2], globals[3]); + fillPuppi(r); +} + +void PuppiAlgo::computePuppiAlphas(const Region &r, std::vector &alphaC, std::vector &alphaF) const { + alphaC.resize(r.pf.size()); + alphaF.resize(r.pf.size()); + float puppiDr2 = std::pow(puppiDr_, 2), puppiDr2min = std::pow(puppiDrMin_, 2); + for (unsigned int ip = 0, np = r.pf.size(); ip < np; ++ip) { + const PFParticle &p = r.pf[ip]; + if (p.hwId <= 1) + continue; + // neutral + alphaC[ip] = 0; + alphaF[ip] = 0; + for (const PFParticle &p2 : r.pf) { + float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); + if (dr2 > 0 && dr2 < puppiDr2) { + float w = std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); + alphaF[ip] += w; + if (p2.chargedPV) + alphaC[ip] += w; + } + } + if (puppiUsingBareTracks_) { + alphaC[ip] = 0; + for (const PropagatedTrack &p2 : r.track) { + if (!p2.fromPV) + continue; + float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); + if (dr2 > 0 && dr2 < puppiDr2) { + alphaC[ip] += std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); + } + } + } + } +} + +void PuppiAlgo::computePuppiWeights(Region &r, + const std::vector &alphaC, + const std::vector &alphaF, + float alphaCMed, + float alphaCRms, + float alphaFMed, + float alphaFRms) const { + int16_t ietacut = std::round(etaCharged_ * CaloCluster::ETAPHI_SCALE); + for (unsigned int ip = 0, np = r.pf.size(); ip < np; ++ip) { + PFParticle &p = r.pf[ip]; + // charged + if (p.hwId == l1t::PFCandidate::ChargedHadron || p.hwId == l1t::PFCandidate::Electron || + p.hwId == l1t::PFCandidate::Muon) { + p.setPuppiW(p.chargedPV || p.hwId == l1t::PFCandidate::Muon ? 1.0 : 0); + if (debug_) + dbgPrintf( + "PUPPI \t charged id %1d pt %7.2f eta %+5.2f phi %+5.2f alpha %+7.2f x2 %+7.2f --> puppi weight %.3f " + "puppi pt %7.2f \n", + p.hwId, + p.floatPt(), + p.floatEta(), + p.floatPhi(), + 0., + 0., + p.floatPuppiW(), + p.floatPt() * p.floatPuppiW()); + continue; + } + // neutral + float alpha = -99, x2 = -99; + bool central = std::abs(p.hwEta) < ietacut; + if (r.relativeCoordinates) + central = + (std::abs(r.globalAbsEta(p.floatEta())) < etaCharged_); // FIXME could make a better integer implementation + if (central) { + if (alphaC[ip] > 0) { + alpha = std::log(alphaC[ip]); + x2 = (alpha - alphaCMed) * std::abs(alpha - alphaCMed) / std::pow(alphaCRms, 2); + p.setPuppiW(ROOT::Math::chisquared_cdf(x2, 1)); + } else { + p.setPuppiW(0); + } + } else { + if (alphaF[ip] > 0) { + alpha = std::log(alphaF[ip]); + x2 = (alpha - alphaFMed) * std::abs(alpha - alphaFMed) / std::pow(alphaFRms, 2); + p.setPuppiW(ROOT::Math::chisquared_cdf(x2, 1)); + } else { + p.setPuppiW(0); + } + } + if (debug_) + dbgPrintf( + "PUPPI \t neutral id %1d pt %7.2f eta %+5.2f phi %+5.2f alpha %+7.2f x2 %+7.2f --> puppi weight %.3f " + "puppi pt %7.2f \n", + p.hwId, + p.floatPt(), + p.floatEta(), + p.floatPhi(), + alpha, + x2, + p.floatPuppiW(), + p.floatPt() * p.floatPuppiW()); + } +} + +void PuppiAlgo::computePuppiMedRMS( + const std::vector &rs, float &alphaCMed, float &alphaCRms, float &alphaFMed, float &alphaFRms) const { + std::vector alphaFs; + std::vector alphaCs; + int16_t ietacut = std::round(etaCharged_ * CaloCluster::ETAPHI_SCALE); + float puppiDr2 = std::pow(puppiDr_, 2), puppiDr2min = std::pow(puppiDrMin_, 2); + for (const Region &r : rs) { + for (const PFParticle &p : r.pf) { + bool central = std::abs(p.hwEta) < ietacut; + if (r.relativeCoordinates) + central = (r.globalAbsEta(p.floatEta()) < etaCharged_); // FIXME could make a better integer implementation + if (central) { + if (p.hwId > 1 || p.chargedPV) + continue; + } + float alphaC = 0, alphaF = 0; + for (const PFParticle &p2 : r.pf) { + float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); + if (dr2 > 0 && dr2 < puppiDr2) { + float w = std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); + alphaF += w; + if (p2.chargedPV) + alphaC += w; + } + } + if (puppiUsingBareTracks_) { + alphaC = 0; + for (const PropagatedTrack &p2 : r.track) { + if (!p2.fromPV) + continue; + float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); + if (dr2 > 0 && dr2 < puppiDr2) { + alphaC += std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); + } + } + } + if (central) { + if (alphaC > 0) + alphaCs.push_back(std::log(alphaC)); + } else { + if (alphaF > 0) + alphaFs.push_back(std::log(alphaF)); + } + } + } + std::sort(alphaCs.begin(), alphaCs.end()); + std::sort(alphaFs.begin(), alphaFs.end()); + + if (alphaCs.size() > 1) { + alphaCMed = alphaCs[alphaCs.size() / 2 + 1]; + double sum = 0.0; + for (float alpha : alphaCs) + sum += std::pow(alpha - alphaCMed, 2); + alphaCRms = std::sqrt(float(sum) / alphaCs.size()); + } else { + alphaCMed = 8.; + alphaCRms = 8.; + } + + if (alphaFs.size() > 1) { + alphaFMed = alphaFs[alphaFs.size() / 2 + 1]; + double sum = 0.0; + for (float alpha : alphaFs) + sum += std::pow(alpha - alphaFMed, 2); + alphaFRms = std::sqrt(float(sum) / alphaFs.size()); + } else { + alphaFMed = 6.; + alphaFRms = 6.; + } + if (debug_) + dbgPrintf("PUPPI \t alphaC = %+6.2f +- %6.2f (%4lu), alphaF = %+6.2f +- %6.2f (%4lu)\n", + alphaCMed, + alphaCRms, + alphaCs.size(), + alphaFMed, + alphaFRms, + alphaFs.size()); +} + +void PuppiAlgo::fillPuppi(Region &r) const { + uint16_t PUPPIW_0p01 = std::round(0.01 * PFParticle::PUPPI_SCALE); + r.puppi.clear(); + for (PFParticle &p : r.pf) { + if (p.hwId == l1t::PFCandidate::ChargedHadron || p.hwId == l1t::PFCandidate::Electron || + p.hwId == l1t::PFCandidate::Muon) { // charged + if (p.hwPuppiWeight > 0) { + r.puppi.push_back(p); + } + } else { // neutral + if (p.hwPuppiWeight > PUPPIW_0p01) { + // FIXME would work better with PUPPI_SCALE being a power of two, to do the shift + // FIXME done with floats + int16_t hwPt = (float(p.hwPt) * float(p.hwPuppiWeight) / float(PFParticle::PUPPI_SCALE)); + int16_t hwPtCut = 0, hwAbsEta = r.relativeCoordinates + ? round(r.globalAbsEta(p.floatEta()) * CaloCluster::ETAPHI_SCALE) + : std::abs(p.hwEta); + for (unsigned int ietaBin = 0, nBins = intPuppiEtaCuts_.size(); ietaBin < nBins; ++ietaBin) { + if (hwAbsEta < intPuppiEtaCuts_[ietaBin]) { + hwPtCut = (p.hwId == l1t::PFCandidate::Photon ? intPuppiPtCutsPhotons_[ietaBin] : intPuppiPtCuts_[ietaBin]); + break; + } + } + if (hwPt > hwPtCut) { + r.puppi.push_back(p); + r.puppi.back().hwPt = hwPt; + } + } + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/Region.cc b/L1Trigger/Phase2L1ParticleFlow/src/Region.cc new file mode 100644 index 0000000000000..116b95410c94d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/Region.cc @@ -0,0 +1,130 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include +#include + +const char *l1tpf_impl::Region::inputTypeName(int type) { + switch (InputType(type)) { + case calo_type: + return "Calo"; + case emcalo_type: + return "EmCalo"; + case track_type: + return "TK"; + case l1mu_type: + return "Mu"; + case n_input_types: + throw cms::Exception( + "LogicError", "n_input_types is not a type to be used, but only a compile-time const for iterating on types"); + } + return "NO_SUCH_INPUT_TYPE"; +} +const char *l1tpf_impl::Region::outputTypeName(int type) { + switch (OutputType(type)) { + case any_type: + return ""; + case charged_type: + return "Charged"; + case neutral_type: + return "Neutral"; + case electron_type: + return "Electron"; + case pfmuon_type: + return "Muon"; + case charged_hadron_type: + return "ChargedHadron"; + case neutral_hadron_type: + return "NeutralHadron"; + case photon_type: + return "Photon"; + case n_output_types: + throw cms::Exception( + "LogicError", + "n_output_types is not a type to be used, but only a compile-time const for iterating on types"); + } + return "NO_SUCH_OUTPUT_TYPE"; +} + +unsigned int l1tpf_impl::Region::nInput(InputType type) const { + switch (type) { + case calo_type: + return calo.size(); + case emcalo_type: + return emcalo.size(); + case track_type: + return track.size(); + case l1mu_type: + return muon.size(); + case n_input_types: + throw cms::Exception( + "LogicError", "n_input_types is not a type to be used, but only a compile-time const for iterating on types"); + } + return 9999; +} + +unsigned int l1tpf_impl::Region::nOutput(OutputType type, bool usePuppi, bool fiducial) const { + unsigned int ret = 0; + for (const auto &p : (usePuppi ? puppi : pf)) { + if (p.hwPt <= 0) + continue; + if (fiducial && !fiducialLocal(p.floatEta(), p.floatPhi())) + continue; + switch (type) { + case any_type: + ret++; + break; + case charged_type: + if (p.intCharge() != 0) + ret++; + break; + case neutral_type: + if (p.intCharge() == 0) + ret++; + break; + case electron_type: + if (p.hwId == l1t::PFCandidate::Electron) + ret++; + break; + case pfmuon_type: + if (p.hwId == l1t::PFCandidate::Muon) + ret++; + break; + case charged_hadron_type: + if (p.hwId == l1t::PFCandidate::ChargedHadron) + ret++; + break; + case neutral_hadron_type: + if (p.hwId == l1t::PFCandidate::NeutralHadron) + ret++; + break; + case photon_type: + if (p.hwId == l1t::PFCandidate::Photon) + ret++; + break; + case n_output_types: + throw cms::Exception( + "LogicError", + "n_output_types is not a type to be used, but only a compile-time const for iterating on types"); + } + } + return ret; +} + +void l1tpf_impl::Region::inputSort() { + std::sort(calo.begin(), calo.end()); + std::sort(emcalo.begin(), emcalo.end()); + std::sort(track.begin(), track.end()); + std::sort(muon.begin(), muon.end()); + if (ncaloMax > 0 && calo.size() > ncaloMax) { + caloOverflow = calo.size() - ncaloMax; + calo.resize(ncaloMax); + } + if (nemcaloMax > 0 && emcalo.size() > nemcaloMax) { + emcaloOverflow = emcalo.size() - nemcaloMax; + emcalo.resize(nemcaloMax); + } + if (ntrackMax > 0 && track.size() > ntrackMax) { + trackOverflow = track.size() - ntrackMax; + track.resize(ntrackMax); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/RegionMapper.cc b/L1Trigger/Phase2L1ParticleFlow/src/RegionMapper.cc new file mode 100644 index 0000000000000..cb422493dc3a1 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/RegionMapper.cc @@ -0,0 +1,340 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h" + +using namespace l1tpf_impl; + +RegionMapper::RegionMapper(const edm::ParameterSet &iConfig) : useRelativeRegionalCoordinates_(false) { + if (iConfig.existsAs>("regions")) { + useRelativeRegionalCoordinates_ = iConfig.getParameter("useRelativeRegionalCoordinates"); + for (const edm::ParameterSet &preg : iConfig.getParameter>("regions")) { + std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); + unsigned int phiSlices = preg.getParameter("phiSlices"); + float etaExtra = preg.getParameter("etaExtra"); + float phiExtra = preg.getParameter("phiExtra"); + float phiWidth = 2 * M_PI / phiSlices; + unsigned int ncalomax = 0, nemcalomax = 0, ntrackmax = 0, nmuonmax = 0, npfmax = 0, npuppimax = 0; + if (preg.existsAs("caloNMax")) + ncalomax = preg.getParameter("caloNMax"); + if (preg.existsAs("emcaloNMax")) + nemcalomax = preg.getParameter("emcaloNMax"); + if (preg.existsAs("trackNMax")) + ntrackmax = preg.getParameter("trackNMax"); + if (preg.existsAs("muonNMax")) + nmuonmax = preg.getParameter("muonNMax"); + if (preg.existsAs("pfNMax")) + npfmax = preg.getParameter("pfNMax"); + if (preg.existsAs("puppiNMax")) + npuppimax = preg.getParameter("puppiNMax"); + for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { + for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { + float phiCenter = (iphi + 0.5) * phiWidth - M_PI; + regions_.push_back(Region(etaBoundaries[ieta], + etaBoundaries[ieta + 1], + phiCenter, + phiWidth, + etaExtra, + phiExtra, + useRelativeRegionalCoordinates_, + ncalomax, + nemcalomax, + ntrackmax, + nmuonmax, + npfmax, + npuppimax)); + } + } + } + std::string trackRegionMode = "TrackAssoMode::any"; + if (iConfig.existsAs("trackRegionMode")) + trackRegionMode = iConfig.getParameter("trackRegionMode"); + if (trackRegionMode == "atVertex") + trackRegionMode_ = TrackAssoMode::atVertex; + else if (trackRegionMode == "atCalo") + trackRegionMode_ = TrackAssoMode::atCalo; + else if (trackRegionMode == "any") + trackRegionMode_ = TrackAssoMode::any; + else + throw cms::Exception( + "Configuration", + "Unsupported value for trackRegionMode: " + trackRegionMode + " (allowed are 'atVertex', 'atCalo', 'any')"); + } else { + // start off with a dummy region + unsigned int ncalomax = 0, nemcalomax = 0, ntrackmax = 0, nmuonmax = 0, npfmax = 0, npuppimax = 0; + regions_.emplace_back(-5.5, + 5.5, + 0, + 2 * M_PI, + 0.5, + 0.5, + useRelativeRegionalCoordinates_, + ncalomax, + nemcalomax, + ntrackmax, + nmuonmax, + npfmax, + npuppimax); + } +} + +void RegionMapper::clear() { + for (Region &r : regions_) + r.zero(); + clusterRefMap_.clear(); + trackRefMap_.clear(); + muonRefMap_.clear(); +} + +void RegionMapper::addTrack(const l1t::PFTrack &t) { + // now let's be optimistic and make things very simple + // we propagate in floating point the track to the calo + // we add the track to the region corresponding to its vertex (eta,phi) coordinates AND its (eta,phi) calo coordinates + for (Region &r : regions_) { + bool inside = true; + switch (trackRegionMode_) { + case TrackAssoMode::atVertex: + inside = r.contains(t.eta(), t.phi()); + break; + case TrackAssoMode::atCalo: + inside = r.contains(t.caloEta(), t.caloPhi()); + break; + case TrackAssoMode::any: + inside = r.contains(t.eta(), t.phi()) || r.contains(t.caloEta(), t.caloPhi()); + break; + } + if (inside) { + PropagatedTrack prop; + prop.fillInput(t.pt(), r.localEta(t.eta()), r.localPhi(t.phi()), t.charge(), t.vertex().Z(), t.quality(), &t); + prop.fillPropagated(t.pt(), + t.trkPtError(), + t.caloPtError(), + r.localEta(t.caloEta()), + r.localPhi(t.caloPhi()), + t.quality(), + t.isMuon()); + prop.hwStubs = t.nStubs(); + prop.hwChi2 = round(t.chi2() * 10); + r.track.push_back(prop); + } + } +} +void RegionMapper::addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref) { + addTrack(t); + trackRefMap_[&t] = ref; +} + +void RegionMapper::addMuon(const l1t::Muon &mu) { + // now let's be optimistic and make things very simple + // we don't propagate anything + for (Region &r : regions_) { + if (r.contains(mu.eta(), mu.phi())) { + Muon prop; + prop.fill(mu.pt(), r.localEta(mu.eta()), r.localPhi(mu.phi()), mu.charge(), mu.hwQual(), &mu); + r.muon.push_back(prop); + } + } +} + +void RegionMapper::addMuon(const l1t::TkMuon &mu) { + // now let's be optimistic and make things very simple + // we don't propagate anything + for (Region &r : regions_) { + if (r.contains(mu.eta(), mu.phi())) { + Muon prop; + prop.fill(mu.pt(), r.localEta(mu.eta()), r.localPhi(mu.phi()), mu.charge(), mu.hwQual()); + r.muon.push_back(prop); + } + } +} + +void RegionMapper::addMuon(const l1t::Muon &mu, l1t::PFCandidate::MuonRef ref) { + addMuon(mu); + muonRefMap_[&mu] = ref; +} + +void RegionMapper::addCalo(const l1t::PFCluster &p) { + if (p.pt() == 0) + return; + for (Region &r : regions_) { + if (r.contains(p.eta(), p.phi())) { + CaloCluster calo; + calo.fill(p.pt(), p.emEt(), p.ptError(), r.localEta(p.eta()), r.localPhi(p.phi()), p.isEM(), 0, &p); + r.calo.push_back(calo); + } + } +} +void RegionMapper::addCalo(const l1t::PFCluster &p, l1t::PFClusterRef ref) { + addCalo(p); + clusterRefMap_[&p] = ref; +} + +void RegionMapper::addEmCalo(const l1t::PFCluster &p) { + if (p.pt() == 0) + return; + for (Region &r : regions_) { + if (r.contains(p.eta(), p.phi())) { + CaloCluster calo; + calo.fill(p.pt(), p.emEt(), p.ptError(), r.localEta(p.eta()), r.localPhi(p.phi()), p.isEM(), 0, &p); + r.emcalo.push_back(calo); + } + } +} +void RegionMapper::addEmCalo(const l1t::PFCluster &p, l1t::PFClusterRef ref) { + addEmCalo(p); + clusterRefMap_[&p] = ref; +} + +std::unique_ptr RegionMapper::fetch(bool puppi, float ptMin) const { + auto ret = std::make_unique(); + for (const Region &r : regions_) { + for (const PFParticle &p : (puppi ? r.puppi : r.pf)) { + bool inside = true; + switch (trackRegionMode_) { + case TrackAssoMode::atVertex: + inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); + break; + case TrackAssoMode::atCalo: + inside = r.fiducialLocal(p.floatEta(), p.floatPhi()); + break; + case TrackAssoMode::any: + inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); + break; // WARNING: this may not be the best choice + } + if (!inside) + continue; + if (p.floatPt() > ptMin) { + reco::Particle::PolarLorentzVector p4( + p.floatPt(), r.globalEta(p.floatVtxEta()), r.globalPhi(p.floatVtxPhi()), 0.13f); + ret->emplace_back(l1t::PFCandidate::ParticleType(p.hwId), p.intCharge(), p4, p.floatPuppiW()); + ret->back().setVertex(reco::Particle::Point(0, 0, p.floatDZ())); + ret->back().setStatus(p.hwStatus); + if (p.cluster.src) { + auto match = clusterRefMap_.find(p.cluster.src); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.hwId << " pt " + << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); + } + ret->back().setPFCluster(match->second); + } + if (p.track.src) { + auto match = trackRefMap_.find(p.track.src); + if (match == trackRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.hwId << " pt " + << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); + } + ret->back().setPFTrack(match->second); + } + if (p.muonsrc) { + auto match = muonRefMap_.find(p.muonsrc); + if (match == muonRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.hwId << " pt " + << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); + } + ret->back().setMuon(match->second); + } + } + } + } + return ret; +} + +std::unique_ptr RegionMapper::fetchCalo(float ptMin, bool emcalo) const { + auto ret = std::make_unique(); + for (const Region &r : regions_) { + for (const CaloCluster &p : (emcalo ? r.emcalo : r.calo)) { + if (!r.fiducialLocal(p.floatEta(), p.floatPhi())) + continue; + if (p.floatPt() > ptMin) { + reco::Particle::PolarLorentzVector p4(p.floatPt(), r.globalEta(p.floatEta()), r.globalPhi(p.floatPhi()), 0.13f); + l1t::PFCandidate::ParticleType kind = + (p.isEM || emcalo) ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; + ret->emplace_back(kind, 0, p4); + if (p.src) { + auto match = clusterRefMap_.find(p.src); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") + << "Invalid cluster pointer in cluster pt " << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); + } + ret->back().setPFCluster(match->second); + } + } + } + } + return ret; +} + +std::unique_ptr RegionMapper::fetchTracks(float ptMin, bool fromPV) const { + auto ret = std::make_unique(); + for (const Region &r : regions_) { + for (const PropagatedTrack &p : r.track) { + if (fromPV && !p.fromPV) + continue; + bool inside = true; + switch (trackRegionMode_) { + case TrackAssoMode::atVertex: + inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); + break; + case TrackAssoMode::atCalo: + inside = r.fiducialLocal(p.floatEta(), p.floatPhi()); + break; + case TrackAssoMode::any: + inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); + break; // WARNING: this may not be the best choice + } + if (!inside) + continue; + if (p.floatPt() > ptMin) { + reco::Particle::PolarLorentzVector p4( + p.floatVtxPt(), r.globalEta(p.floatVtxEta()), r.globalPhi(p.floatVtxPhi()), 0.13f); + l1t::PFCandidate::ParticleType kind = p.muonLink ? l1t::PFCandidate::Muon : l1t::PFCandidate::ChargedHadron; + ret->emplace_back(kind, p.intCharge(), p4); + ret->back().setVertex(reco::Particle::Point(0, 0, p.floatDZ())); + if (p.src) { + auto match = trackRefMap_.find(p.src); + if (match == trackRefMap_.end()) { + throw cms::Exception("CorruptData") + << "Invalid track pointer in PF track pt " << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); + } + ret->back().setPFTrack(match->second); + } + } + } + } + return ret; +} + +std::pair RegionMapper::totAndMaxInput(int type) const { + unsigned ntot = 0, nmax = 0; + for (const auto &r : regions_) { + unsigned int ni = r.nInput(Region::InputType(type)); + ntot += ni; + nmax = std::max(nmax, ni); + } + return std::make_pair(ntot, nmax); +} + +std::unique_ptr> RegionMapper::vecInput(int type) const { + auto v = std::make_unique>(); + for (const auto &r : regions_) { + unsigned ni = r.nInput(Region::InputType(type)); + v->push_back(ni); + } + return v; +} + +std::pair RegionMapper::totAndMaxOutput(int type, bool puppi) const { + unsigned ntot = 0, nmax = 0; + for (const auto &r : regions_) { + unsigned int ni = r.nOutput(Region::OutputType(type), puppi); + ntot += ni; + nmax = std::max(nmax, ni); + } + return std::make_pair(ntot, nmax); +} + +std::unique_ptr> RegionMapper::vecOutput(int type, bool puppi) const { + auto v = std::make_unique>(); + for (const auto &r : regions_) { + unsigned ni = r.nOutput(Region::OutputType(type), puppi); + v->push_back(ni); + } + return v; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc b/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc new file mode 100644 index 0000000000000..d8c04b82690bd --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc @@ -0,0 +1,188 @@ +#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FWCore/Utilities/interface/CPUTimer.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCluster.h" + +l1tpf::corrector::corrector(const std::string &filename, float emfMax, bool debug) : emfMax_(emfMax) { + if (!filename.empty()) + init_(filename, "", debug); +} +l1tpf::corrector::corrector(const std::string &filename, const std::string &directory, float emfMax, bool debug) + : emfMax_(emfMax) { + if (!filename.empty()) + init_(filename, directory, debug); +} + +l1tpf::corrector::corrector(TDirectory *src, float emfMax, bool debug) : emfMax_(emfMax) { init_(src, debug); } + +void l1tpf::corrector::init_(const std::string &filename, const std::string &directory, bool debug) { + std::string resolvedFileName = filename; + if (filename[0] != '/') + resolvedFileName = edm::FileInPath(filename).fullPath(); + TFile *lFile = TFile::Open(resolvedFileName.c_str()); + if (!lFile || lFile->IsZombie()) + throw cms::Exception("Configuration", "cannot read file " + filename); + + TDirectory *dir = directory.empty() ? lFile : lFile->GetDirectory(directory.c_str()); + if (!dir) + throw cms::Exception("Configuration", "cannot find directory '" + directory + "' in file " + filename); + init_(dir, debug); + + lFile->Close(); +} + +void l1tpf::corrector::init_(TDirectory *lFile, bool debug) { + TH1 *index = (TH1 *)lFile->Get("INDEX"); + if (!index) + throw cms::Exception("Configuration") + << "invalid input file " << lFile->GetPath() << ": INDEX histogram not found.\n"; + index_.reset((TH1 *)index->Clone()); + index_->SetDirectory(nullptr); + + is2d_ = index_->InheritsFrom("TH2"); + + std::unordered_map graphs; + TKey *key; + TIter nextkey(lFile->GetListOfKeys()); + while ((key = (TKey *)nextkey())) { + if (strncmp(key->GetName(), "eta_", 4) == 0) { + TGraph *gr = (TGraph *)key->ReadObj(); + if (!gr->TestBit(TGraph::kIsSortedX)) + gr->Sort(); + graphs[key->GetName()] = gr; + } + } + + neta_ = index_->GetNbinsX(); + nemf_ = (is2d_ ? index_->GetNbinsY() : 1); + corrections_.resize(neta_ * nemf_); + std::fill(corrections_.begin(), corrections_.end(), nullptr); + char buff[32]; + int ngraphs = 0; + for (unsigned int ieta = 0; ieta < neta_; ++ieta) { + for (unsigned int iemf = 0; iemf < nemf_; ++iemf) { + if (is2d_) { + snprintf(buff, 31, "eta_bin%d_emf_bin%d", ieta + 1, iemf + 1); + } else { + snprintf(buff, 31, "eta_bin%d", ieta + 1); + } + TGraph *graph = graphs[buff]; + if (debug) + edm::LogPrint("corrector") << " eta bin " << ieta << " emf bin " << iemf << " graph " << buff + << (graph ? " " : " ") << "\n"; + if (graph) { + ngraphs++; + corrections_[ieta * nemf_ + iemf] = (TGraph *)graph->Clone(); + } + if (std::abs(index_->GetXaxis()->GetBinCenter(ieta + 1)) > 3.0) { + break; // no EMF bins beyond eta = 3 + } + } + } +} + +l1tpf::corrector::corrector(const TH1 *index, float emfMax) + : index_((TH1 *)index->Clone("INDEX")), + is2d_(index->InheritsFrom("TH2")), + neta_(index->GetNbinsX()), + nemf_(is2d_ ? index->GetNbinsY() : 1), + emfMax_(emfMax) { + index_->SetDirectory(nullptr); + corrections_.resize(neta_ * nemf_); + std::fill(corrections_.begin(), corrections_.end(), nullptr); +} + +l1tpf::corrector::~corrector() { + for (TGraph *&p : corrections_) { + delete p; + p = nullptr; + } + corrections_.clear(); +} + +l1tpf::corrector::corrector(corrector &&corr) + : index_(std::move(corr.index_)), + corrections_(std::move(corr.corrections_)), + is2d_(corr.is2d_), + neta_(corr.neta_), + nemf_(corr.nemf_), + emfMax_(corr.emfMax_) {} + +l1tpf::corrector &l1tpf::corrector::operator=(corrector &&corr) { + std::swap(is2d_, corr.is2d_); + std::swap(neta_, corr.neta_); + std::swap(nemf_, corr.nemf_); + std::swap(emfMax_, corr.emfMax_); + + index_.swap(corr.index_); + corrections_.swap(corr.corrections_); + return *this; +} + +float l1tpf::corrector::correctedPt(float pt, float emPt, float eta) const { + float total = std::max(pt, emPt), abseta = std::abs(eta); + float emf = emPt / total; + if (emfMax_ > 0 && emf > emfMax_) + return total; // no correction + unsigned int ieta = std::min(std::max(1, index_->GetXaxis()->FindBin(abseta)), neta_) - 1; + unsigned int iemf = + is2d_ && abseta < 3.0 ? std::min(std::max(1, index_->GetYaxis()->FindBin(emf)), nemf_) - 1 : 0; + TGraph *graph = corrections_[ieta * nemf_ + iemf]; + if (!graph) { + throw cms::Exception("RuntimeError") << "Error trying to read calibration for eta " << eta << " emf " << emf + << " which are not available." << std::endl; + } + float ptcorr = std::min(graph->Eval(total), 4 * total); + return ptcorr; +} + +void l1tpf::corrector::correctPt(l1t::PFCluster &cluster, float preserveEmEt) const { + float newpt = correctedPt(cluster.pt(), cluster.emEt(), cluster.eta()); + cluster.calibratePt(newpt, preserveEmEt); +} + +void l1tpf::corrector::setGraph(const TGraph &graph, int ieta, int iemf) { + char buff[32]; + if (is2d_) { + snprintf(buff, 31, "eta_bin%d_emf_bin%d", (unsigned int)(ieta + 1), (unsigned int)(iemf + 1)); + } else { + snprintf(buff, 31, "eta_bin%d", (unsigned int)(ieta + 1)); + } + TGraph *gclone = (TGraph *)graph.Clone(buff); + delete corrections_[ieta * nemf_ + iemf]; + corrections_[ieta * nemf_ + iemf] = gclone; +} + +void l1tpf::corrector::writeToFile(const std::string &filename, const std::string &directory) const { + TFile *lFile = TFile::Open(filename.c_str(), "RECREATE"); + TDirectory *dir = directory.empty() ? lFile : lFile->mkdir(directory.c_str()); + writeToFile(dir); + lFile->Close(); +} + +void l1tpf::corrector::writeToFile(TDirectory *dest) const { + TH1 *index = (TH1 *)index_->Clone(); + index->SetDirectory(dest); + dest->WriteTObject(index); + + for (const TGraph *p : corrections_) { + if (p != nullptr) { + dest->WriteTObject((TGraph *)p->Clone(), p->GetName()); + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/corrector.h b/L1Trigger/Phase2L1ParticleFlow/src/corrector.h new file mode 100644 index 0000000000000..3ade23a229eb0 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/corrector.h @@ -0,0 +1,65 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_corrector_h +#define L1Trigger_Phase2L1ParticleFlow_corrector_h +#include +#include +#include +#include + +class TDirectory; + +namespace l1t { + class PFCluster; +} + +namespace l1tpf { + class corrector { + public: + corrector() : is2d_(false), neta_(0), nemf_(0), emfMax_(-1) {} + corrector(const std::string &iFile, float emfMax = -1, bool debug = false); + corrector(const std::string &iFile, const std::string &directory, float emfMax = -1, bool debug = false); + corrector(TDirectory *src, float emfMax = -1, bool debug = false); + // create an empty corrector (you'll need to fill the graphs later) + corrector(const TH1 *index, float emfMax = -1); + ~corrector(); + + // no copy, but can move + corrector(const corrector &corr) = delete; + corrector &operator=(const corrector &corr) = delete; + corrector(corrector &&corr); + corrector &operator=(corrector &&corr); + + float correctedPt(float et, float emEt, float eta) const; + float correctedPt(float et, float eta) const { return correctedPt(et, 0, eta); } + void correctPt(l1t::PFCluster &cluster, float preserveEmEt = true) const; + + bool valid() const { return (index_.get() != nullptr); } + + // set the graph (note: it is cloned, and the corrector owns the clone) + void setGraph(const TGraph &graph, int ieta, int iemf = 0); + + bool is2d() const { return is2d_; } + unsigned int neta() const { return neta_; } + unsigned int nemf() const { return nemf_; } + // access the index histogram + const TH1 &getIndex() const { return *index_; } + // access the graphs (owned by the corrector, may be null) + TGraph *getGraph(int ieta, int iemf = 0) { return corrections_[ieta * nemf_ + iemf]; } + const TGraph *getGraph(int ieta, int iemf = 0) const { return corrections_[ieta * nemf_ + iemf]; } + + // store the corrector + void writeToFile(const std::string &filename, const std::string &directory) const; + // store the corrector + void writeToFile(TDirectory *dest) const; + + private: + std::unique_ptr index_; + std::vector corrections_; + bool is2d_; + unsigned int neta_, nemf_; + float emfMax_; + + void init_(const std::string &iFile, const std::string &directory, bool debug); + void init_(TDirectory *src, bool debug); + }; +} // namespace l1tpf +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h b/L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h new file mode 100644 index 0000000000000..35dc25afa32d3 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h @@ -0,0 +1,11 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_dbgPrintf_h +#define L1Trigger_Phase2L1ParticleFlow_dbgPrintf_h + +template +inline void dbgPrintf(const char *formatString, Args &&... args) { +#ifdef L1PF_DEBUG + printf(formatString, std::forward(args)...); +#endif +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/data.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/data.h new file mode 100644 index 0000000000000..c1ccd93ac5812 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/firmware/data.h @@ -0,0 +1,209 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_DATA_H +#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_DATA_H + +#include + +typedef ap_int<16> pt_t; +typedef ap_int<10> etaphi_t; +typedef ap_int<5> vtx_t; +typedef ap_uint<3> particleid_t; +typedef ap_int<10> z0_t; // 40cm / 0.1 +typedef ap_uint<14> tk2em_dr_t; +typedef ap_uint<14> tk2calo_dr_t; +typedef ap_uint<10> em2calo_dr_t; +typedef ap_uint<13> tk2calo_dq_t; + +enum PID { PID_Charged = 0, PID_Neutral = 1, PID_Photon = 2, PID_Electron = 3, PID_Muon = 4 }; + +// DEFINE MULTIPLICITIES +#if defined(REG_HGCal) +#define NTRACK 25 +#define NCALO 20 +#define NMU 4 +#define NSELCALO 15 +#define NALLNEUTRALS NSELCALO +// dummy +#define NEMCALO 1 +#define NPHOTON NEMCALO +// not used but must be there because used in header files +#define NNEUTRALS 1 +//-------------------------------- +#elif defined(REG_HGCalNoTK) +#define NCALO 12 +#define NNEUTRALS 8 +#define NALLNEUTRALS NCALO +// dummy +#define NMU 1 +#define NTRACK 1 +#define NEMCALO 1 +#define NPHOTON NEMCALO +#define NSELCALO 1 +//-------------------------------- +#elif defined(REG_HF) +#define NCALO 18 +#define NNEUTRALS 10 +#define NALLNEUTRALS NCALO +// dummy +#define NMU 1 +#define NTRACK 1 +#define NEMCALO 1 +#define NPHOTON NEMCALO +#define NSELCALO 1 +//-------------------------------- +#else // BARREL +#ifndef REG_Barrel +#ifndef CMSSW_GIT_HASH +#warning "No region defined, assuming it's barrel (#define REG_Barrel to suppress this)" +#endif +#endif +#if defined(BOARD_MP7) +#warning "MP7 NOT SUPPORTED ANYMORE" +#define NTRACK 14 +#define NCALO 10 +#define NMU 2 +#define NEMCALO 10 +#define NPHOTON NEMCALO +#define NSELCALO 10 +#define NALLNEUTRALS (NPHOTON + NSELCALO) +#define NNEUTRALS 15 +#elif defined(BOARD_CTP7) +#error "NOT SUPPORTED ANYMORE" +#elif defined(BOARD_KU15P) +#define NTRACK 14 +#define NCALO 10 +#define NMU 2 +#define NEMCALO 10 +#define NPHOTON NEMCALO +#define NSELCALO 10 +#define NALLNEUTRALS (NPHOTON + NSELCALO) +#define NNEUTRALS 15 +#elif defined(BOARD_VCU118) +#define NTRACK 22 +#define NCALO 15 +#define NEMCALO 13 +#define NMU 2 +#define NPHOTON NEMCALO +#define NSELCALO 10 +#define NALLNEUTRALS (NPHOTON + NSELCALO) +#define NNEUTRALS 25 +#else +#define NTRACK 22 +#define NCALO 15 +#define NEMCALO 13 +#define NMU 2 +#define NPHOTON NEMCALO +#define NSELCALO 10 +#define NALLNEUTRALS (NPHOTON + NSELCALO) +#define NNEUTRALS 25 +#endif + +#endif // region + +#if defined(BOARD_MP7) +#define PACKING_DATA_SIZE 32 +#define PACKING_NCHANN 72 +#elif defined(BOARD_KU15P) +#define PACKING_DATA_SIZE 64 +#define PACKING_NCHANN 42 +#elif defined(BOARD_VCU118) +#define PACKING_DATA_SIZE 64 +#define PACKING_NCHANN 96 +#elif defined(BOARD_APD1) +#define PACKING_DATA_SIZE 64 +#define PACKING_NCHANN 96 +#endif + +struct CaloObj { + pt_t hwPt; + etaphi_t hwEta, hwPhi; // relative to the region center, at calo +}; +struct HadCaloObj : public CaloObj { + pt_t hwEmPt; + bool hwIsEM; +}; +inline void clear(HadCaloObj& c) { + c.hwPt = 0; + c.hwEta = 0; + c.hwPhi = 0; + c.hwEmPt = 0; + c.hwIsEM = false; +} + +struct EmCaloObj { + pt_t hwPt, hwPtErr; + etaphi_t hwEta, hwPhi; // relative to the region center, at calo +}; +inline void clear(EmCaloObj& c) { + c.hwPt = 0; + c.hwPtErr = 0; + c.hwEta = 0; + c.hwPhi = 0; +} + +struct TkObj { + pt_t hwPt, hwPtErr; + etaphi_t hwEta, hwPhi; // relative to the region center, at calo + z0_t hwZ0; + bool hwTightQuality; +}; +inline void clear(TkObj& c) { + c.hwPt = 0; + c.hwPtErr = 0; + c.hwEta = 0; + c.hwPhi = 0; + c.hwZ0 = 0; + c.hwTightQuality = false; +} + +struct MuObj { + pt_t hwPt, hwPtErr; + etaphi_t hwEta, hwPhi; // relative to the region center, at vtx(?) +}; +inline void clear(MuObj& c) { + c.hwPt = 0; + c.hwPtErr = 0; + c.hwEta = 0; + c.hwPhi = 0; +} + +struct PFChargedObj { + pt_t hwPt; + etaphi_t hwEta, hwPhi; // relative to the region center, at calo + particleid_t hwId; + z0_t hwZ0; +}; +inline void clear(PFChargedObj& c) { + c.hwPt = 0; + c.hwEta = 0; + c.hwPhi = 0; + c.hwId = 0; + c.hwZ0 = 0; +} + +struct PFNeutralObj { + pt_t hwPt; + etaphi_t hwEta, hwPhi; // relative to the region center, at calo + particleid_t hwId; + pt_t hwPtPuppi; +}; +inline void clear(PFNeutralObj& c) { + c.hwPt = 0; + c.hwEta = 0; + c.hwPhi = 0; + c.hwId = 0; + c.hwPtPuppi = 0; +} + +//TMUX +#define NETA_TMUX 2 +#define NPHI_TMUX 1 +/* #define TMUX_IN 36 */ +/* #define TMUX_OUT 18 */ +#define TMUX_IN 18 +#define TMUX_OUT 6 +#define NTRACK_TMUX (NTRACK * TMUX_OUT * NETA_TMUX * NPHI_TMUX) +#define NCALO_TMUX (NCALO * TMUX_OUT * NETA_TMUX * NPHI_TMUX) +#define NEMCALO_TMUX (NEMCALO * TMUX_OUT * NETA_TMUX * NPHI_TMUX) +#define NMU_TMUX (NMU * TMUX_OUT * NETA_TMUX * NPHI_TMUX) + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo2hgc.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo2hgc.h new file mode 100644 index 0000000000000..3d36fa37c2b0c --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo2hgc.h @@ -0,0 +1,40 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO2HGC_H +#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO2HGC_H + +#include "pfalgo_common.h" + +void pfalgo2hgc(const HadCaloObj calo[NCALO], + const TkObj track[NTRACK], + const MuObj mu[NMU], + PFChargedObj outch[NTRACK], + PFNeutralObj outne[NSELCALO], + PFChargedObj outmu[NMU]); + +#if defined(PACKING_DATA_SIZE) && defined(PACKING_NCHANN) +void packed_pfalgo2hgc(const ap_uint input[PACKING_NCHANN], + ap_uint output[PACKING_NCHANN]); +void pfalgo2hgc_pack_in(const HadCaloObj calo[NCALO], + const TkObj track[NTRACK], + const MuObj mu[NMU], + ap_uint input[PACKING_NCHANN]); +void pfalgo2hgc_unpack_in(const ap_uint input[PACKING_NCHANN], + HadCaloObj calo[NCALO], + TkObj track[NTRACK], + MuObj mu[NMU]); +void pfalgo2hgc_pack_out(const PFChargedObj outch[NTRACK], + const PFNeutralObj outne[NSELCALO], + const PFChargedObj outmu[NMU], + ap_uint output[PACKING_NCHANN]); +void pfalgo2hgc_unpack_out(const ap_uint output[PACKING_NCHANN], + PFChargedObj outch[NTRACK], + PFNeutralObj outne[NSELCALO], + PFChargedObj outmu[NMU]); +#endif + +#ifndef CMSSW_GIT_HASH +#define PFALGO_DR2MAX_TK_CALO 525 +#define PFALGO_TK_MAXINVPT_LOOSE 40 +#define PFALGO_TK_MAXINVPT_TIGHT 80 +#endif + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo3.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo3.h new file mode 100644 index 0000000000000..cc7c48bff14d4 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo3.h @@ -0,0 +1,50 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO3_H +#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO3_H + +#include "pfalgo_common.h" + +void pfalgo3(const EmCaloObj emcalo[NEMCALO], + const HadCaloObj hadcalo[NCALO], + const TkObj track[NTRACK], + const MuObj mu[NMU], + PFChargedObj outch[NTRACK], + PFNeutralObj outpho[NPHOTON], + PFNeutralObj outne[NSELCALO], + PFChargedObj outmu[NMU]); + +#if defined(PACKING_DATA_SIZE) && defined(PACKING_NCHANN) +void packed_pfalgo3(const ap_uint input[PACKING_NCHANN], + ap_uint output[PACKING_NCHANN]); +void pfalgo3_pack_in(const EmCaloObj emcalo[NEMCALO], + const HadCaloObj hadcalo[NCALO], + const TkObj track[NTRACK], + const MuObj mu[NMU], + ap_uint input[PACKING_NCHANN]); +void pfalgo3_unpack_in(const ap_uint input[PACKING_NCHANN], + EmCaloObj emcalo[NEMCALO], + HadCaloObj hadcalo[NCALO], + TkObj track[NTRACK], + MuObj mu[NMU]); +void pfalgo3_pack_out(const PFChargedObj outch[NTRACK], + const PFNeutralObj outpho[NPHOTON], + const PFNeutralObj outne[NSELCALO], + const PFChargedObj outmu[NMU], + ap_uint output[PACKING_NCHANN]); +void pfalgo3_unpack_out(const ap_uint output[PACKING_NCHANN], + PFChargedObj outch[NTRACK], + PFNeutralObj outpho[NPHOTON], + PFNeutralObj outne[NSELCALO], + PFChargedObj outmu[NMU]); +#endif + +void pfalgo3_set_debug(bool debug); + +#ifndef CMSSW_GIT_HASH +#define PFALGO_DR2MAX_TK_CALO 1182 +#define PFALGO_DR2MAX_EM_CALO 525 +#define PFALGO_DR2MAX_TK_EM 84 +#define PFALGO_TK_MAXINVPT_LOOSE 40 +#define PFALGO_TK_MAXINVPT_TIGHT 80 +#endif + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo_common.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo_common.h new file mode 100644 index 0000000000000..5fe4e1181b9db --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo_common.h @@ -0,0 +1,16 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO_COMMON_H +#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO_COMMON_H + +#include "data.h" + +inline int dr2_int(etaphi_t eta1, etaphi_t phi1, etaphi_t eta2, etaphi_t phi2) { + ap_int deta = (eta1 - eta2); + ap_int dphi = (phi1 - phi2); + return deta * deta + dphi * dphi; +} + +#ifndef CMSSW_GIT_HASH +#define PFALGO_DR2MAX_TK_MU 2101 +#endif + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.cpp new file mode 100644 index 0000000000000..7d407a60ef7a8 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.cpp @@ -0,0 +1,196 @@ +#include "pfalgo2hgc_ref.h" + +#ifndef CMSSW_GIT_HASH +#include "../DiscretePFInputs.h" +#else +#include "../../interface/DiscretePFInputs.h" +#endif + +#include "../utils/Firmware2DiscretePF.h" +#include +#include +#include +#include + +int g_pfalgo2hgc_debug_ref_ = 0; + +void pfalgo2hgc_ref_set_debug(int debug) { g_pfalgo2hgc_debug_ref_ = debug; } + +void pfalgo2hgc_ref(const pfalgo_config &cfg, + const HadCaloObj calo[/*cfg.nCALO*/], + const TkObj track[/*cfg.nTRACK*/], + const MuObj mu[/*cfg.nMU*/], + PFChargedObj outch[/*cfg.nTRACK*/], + PFNeutralObj outne[/*cfg.nSELCALO*/], + PFChargedObj outmu[/*cfg.nMU*/]) { + if (g_pfalgo2hgc_debug_ref_) { +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + for (unsigned int i = 0; i < cfg.nTRACK; ++i) { + if (track[i].hwPt == 0) + continue; + l1tpf_impl::PropagatedTrack tk; + fw2dpf::convert(track[i], tk); + printf( + "FW \t track %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo ptErr %6d [ " + "%7.2f ] tight %d\n", + i, + tk.hwPt, + tk.floatPt(), + tk.hwEta, + tk.floatEta(), + tk.hwPhi, + tk.floatPhi(), + tk.hwCaloPtErr, + tk.floatCaloPtErr(), + int(track[i].hwTightQuality)); + } + for (unsigned int i = 0; i < cfg.nCALO; ++i) { + if (calo[i].hwPt == 0) + continue; + l1tpf_impl::CaloCluster c; + fw2dpf::convert(calo[i], c); + printf( + "FW \t calo %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo emPt %7d [ " + "%7.2f ] isEM %d \n", + i, + c.hwPt, + c.floatPt(), + c.hwEta, + c.floatEta(), + c.hwPhi, + c.floatPhi(), + c.hwEmPt, + c.floatEmPt(), + c.isEM); + } + for (unsigned int i = 0; i < cfg.nMU; ++i) { + if (mu[i].hwPt == 0) + continue; + l1tpf_impl::Muon muon; + fw2dpf::convert(mu[i], muon); + printf("FW \t muon %3d: pt %8d [ %7.2f ] muon eta %+7d [ %+5.2f ] muon phi %+7d [ %+5.2f ] \n", + i, + muon.hwPt, + muon.floatPt(), + muon.hwEta, + muon.floatEta(), + muon.hwPhi, + muon.floatPhi()); + } +#endif + } + + // constants + const pt_t TKPT_MAX_LOOSE = cfg.tk_MAXINVPT_LOOSE; + const pt_t TKPT_MAX_TIGHT = cfg.tk_MAXINVPT_TIGHT; + const int DR2MAX = cfg.dR2MAX_TK_CALO; + + //////////////////////////////////////////////////// + // TK-MU Linking + std::unique_ptr isMu(new bool[cfg.nTRACK]); + pfalgo_mu_ref(cfg, track, mu, &isMu[0], outmu, g_pfalgo2hgc_debug_ref_); + + //////////////////////////////////////////////////// + // TK-HAD Linking + + // initialize sum track pt + std::vector calo_sumtk(cfg.nCALO), calo_subpt(cfg.nCALO); + std::vector calo_sumtkErr2(cfg.nCALO); + for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { + calo_sumtk[ic] = 0; + calo_sumtkErr2[ic] = 0; + } + + // initialize good track bit + std::unique_ptr track_good(new bool[cfg.nTRACK]); + std::unique_ptr isEle(new bool[cfg.nTRACK]); + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + track_good[it] = (track[it].hwPt < (track[it].hwTightQuality ? TKPT_MAX_TIGHT : TKPT_MAX_LOOSE) || isMu[it]); + isEle[it] = false; + } + + // initialize output + for (unsigned int ipf = 0; ipf < cfg.nTRACK; ++ipf) + clear(outch[ipf]); + for (unsigned int ipf = 0; ipf < cfg.nSELCALO; ++ipf) + clear(outne[ipf]); + + // for each track, find the closest calo + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + if (track[it].hwPt > 0 && !isMu[it]) { + int ibest = best_match_with_pt_ref(cfg.nCALO, DR2MAX, calo, track[it]); + if (ibest != -1) { + if (g_pfalgo2hgc_debug_ref_) + printf("FW \t track %3d pt %7d matched to calo' %3d pt %7d\n", + it, + int(track[it].hwPt), + ibest, + int(calo[ibest].hwPt)); + track_good[it] = true; + isEle[it] = calo[ibest].hwIsEM; + calo_sumtk[ibest] += track[it].hwPt; + calo_sumtkErr2[ibest] += sqr(track[it].hwPtErr); + } + } + } + + for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { + if (calo_sumtk[ic] > 0) { + pt_t ptdiff = calo[ic].hwPt - calo_sumtk[ic]; + int sigmamult = + calo_sumtkErr2[ic]; // + (calo_sumtkErr2[ic] >> 1)); // this multiplies by 1.5 = sqrt(1.5)^2 ~ (1.2)^2 + if (g_pfalgo2hgc_debug_ref_ && (calo[ic].hwPt > 0)) { +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + l1tpf_impl::CaloCluster floatcalo; + fw2dpf::convert(calo[ic], floatcalo); + printf( + "FW \t calo' %3d pt %7d [ %7.2f ] eta %+7d [ %+5.2f ] has a sum track pt %7d, difference %7d +- %.2f \n", + ic, + int(calo[ic].hwPt), + floatcalo.floatPt(), + int(calo[ic].hwEta), + floatcalo.floatEta(), + int(calo_sumtk[ic]), + int(ptdiff), + std::sqrt(float(int(calo_sumtkErr2[ic])))); +#endif + } + if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) { + calo_subpt[ic] = ptdiff; + } else { + calo_subpt[ic] = 0; + } + } else { + calo_subpt[ic] = calo[ic].hwPt; + } + if (g_pfalgo2hgc_debug_ref_ && (calo[ic].hwPt > 0)) + printf("FW \t calo' %3d pt %7d ---> %7d \n", ic, int(calo[ic].hwPt), int(calo_subpt[ic])); + } + + // copy out charged hadrons + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + if (track_good[it]) { + assert(!(isEle[it] && isMu[it])); + outch[it].hwPt = track[it].hwPt; + outch[it].hwEta = track[it].hwEta; + outch[it].hwPhi = track[it].hwPhi; + outch[it].hwZ0 = track[it].hwZ0; + outch[it].hwId = isEle[it] ? PID_Electron : (isMu[it] ? PID_Muon : PID_Charged); + } + } + + // copy out neutral hadrons with sorting and cropping + std::vector outne_all(cfg.nCALO); + for (unsigned int ipf = 0; ipf < cfg.nCALO; ++ipf) + clear(outne_all[ipf]); + for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { + if (calo_subpt[ic] > 0) { + outne_all[ic].hwPt = calo_subpt[ic]; + outne_all[ic].hwEta = calo[ic].hwEta; + outne_all[ic].hwPhi = calo[ic].hwPhi; + outne_all[ic].hwId = calo[ic].hwIsEM ? PID_Photon : PID_Neutral; + } + } + + ptsort_ref(cfg.nCALO, cfg.nSELCALO, outne_all, outne); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.h b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.h new file mode 100644 index 0000000000000..c24af621fa28d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.h @@ -0,0 +1,17 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PFALGO2HGC_REF_H +#define L1Trigger_Phase2L1ParticleFlow_PFALGO2HGC_REF_H + +#include "../firmware/pfalgo2hgc.h" +#include "pfalgo_common_ref.h" + +void pfalgo2hgc_ref_set_debug(int debug); + +void pfalgo2hgc_ref(const pfalgo_config &cfg, + const HadCaloObj calo[/*cfg.nCALO*/], + const TkObj track[/*cfg.nTRACK*/], + const MuObj mu[/*cfg.nMU*/], + PFChargedObj outch[/*cfg.nTRACK*/], + PFNeutralObj outne[/*cfg.nSELCALO*/], + PFChargedObj outmu[/*cfg.nMU*/]); + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.cpp new file mode 100644 index 0000000000000..6a2d06a9551ef --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.cpp @@ -0,0 +1,485 @@ +#include "pfalgo3_ref.h" + +#ifndef CMSSW_GIT_HASH +#include "../DiscretePFInputs.h" +#else +#include "../../interface/DiscretePFInputs.h" +#endif + +#include "../utils/Firmware2DiscretePF.h" +#include +#include +#include +#include +#include + +int g_pfalgo3_debug_ref_ = 0; + +void pfalgo3_ref_set_debug(int debug) { g_pfalgo3_debug_ref_ = debug; } + +template +int tk_best_match_ref(unsigned int nCAL, unsigned int dR2MAX, const CO_t calo[/*nCAL*/], const TkObj &track) { + pt_t caloPtMin = track.hwPt - 2 * (track.hwPtErr); + if (caloPtMin < 0) + caloPtMin = 0; + int drmin = dR2MAX, ibest = -1; + for (unsigned int ic = 0; ic < nCAL; ++ic) { + if (calo[ic].hwPt <= 0) + continue; + if (doPtMin && calo[ic].hwPt <= caloPtMin) + continue; + int dr = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); + if (dr < drmin) { + drmin = dr; + ibest = ic; + } + } + return ibest; +} +int em_best_match_ref(unsigned int nCAL, unsigned int dR2MAX, const HadCaloObj calo[/*nCAL*/], const EmCaloObj &em) { + pt_t emPtMin = em.hwPt >> 1; + int drmin = dR2MAX, ibest = -1; + for (unsigned int ic = 0; ic < nCAL; ++ic) { + if (calo[ic].hwEmPt <= emPtMin) + continue; + int dr = dr2_int(em.hwEta, em.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); + if (dr < drmin) { + drmin = dr; + ibest = ic; + } + } + return ibest; +} + +void pfalgo3_em_ref(const pfalgo3_config &cfg, + const EmCaloObj emcalo[/*cfg.nEMCALO*/], + const HadCaloObj hadcalo[/*cfg.nCALO*/], + const TkObj track[/*cfg.nTRACK*/], + const bool isMu[/*cfg.nTRACK*/], + bool isEle[/*cfg.nTRACK*/], + PFNeutralObj outpho[/*cfg.nPHOTON*/], + HadCaloObj hadcalo_out[/*cfg.nCALO*/]) { + // constants + const int DR2MAX_TE = cfg.dR2MAX_TK_EM; + const int DR2MAX_EH = cfg.dR2MAX_EM_CALO; + + // initialize sum track pt + std::vector calo_sumtk(cfg.nEMCALO); + for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { + calo_sumtk[ic] = 0; + } + std::vector tk2em(cfg.nTRACK); + std::vector isEM(cfg.nEMCALO); + // for each track, find the closest calo + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + if (track[it].hwPt > 0 && !isMu[it]) { + tk2em[it] = tk_best_match_ref(cfg.nEMCALO, DR2MAX_TE, emcalo, track[it]); + if (tk2em[it] != -1) { + if (g_pfalgo3_debug_ref_) + printf("FW \t track %3d pt %7d matched to em calo %3d pt %7d\n", + it, + int(track[it].hwPt), + tk2em[it], + int(emcalo[tk2em[it]].hwPt)); + calo_sumtk[tk2em[it]] += track[it].hwPt; + } + } else { + tk2em[it] = -1; + } + } + + if (g_pfalgo3_debug_ref_) { + for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { + if (emcalo[ic].hwPt > 0) + printf("FW \t emcalo %3d pt %7d has sumtk %7d\n", ic, int(emcalo[ic].hwPt), int(calo_sumtk[ic])); + } + } + + for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { + pt_t photonPt; + if (calo_sumtk[ic] > 0) { + pt_t ptdiff = emcalo[ic].hwPt - calo_sumtk[ic]; + int sigma2 = sqr(emcalo[ic].hwPtErr); + int sigma2Lo = 4 * sigma2, + sigma2Hi = sigma2; // + (sigma2>>1); // cut at 1 sigma instead of old cut at sqrt(1.5) sigma's + int ptdiff2 = ptdiff * ptdiff; + if ((ptdiff >= 0 && ptdiff2 <= sigma2Hi) || (ptdiff < 0 && ptdiff2 < sigma2Lo)) { + // electron + photonPt = 0; + isEM[ic] = true; + if (g_pfalgo3_debug_ref_) + printf("FW \t emcalo %3d pt %7d ptdiff %7d [match window: -%.2f / +%.2f] flagged as electron\n", + ic, + int(emcalo[ic].hwPt), + int(ptdiff), + std::sqrt(float(sigma2Lo)), + std::sqrt(float(sigma2Hi))); + } else if (ptdiff > 0) { + // electron + photon + photonPt = ptdiff; + isEM[ic] = true; + if (g_pfalgo3_debug_ref_) + printf( + "FW \t emcalo %3d pt %7d ptdiff %7d [match window: -%.2f / +%.2f] flagged as electron + photon of pt " + "%7d\n", + ic, + int(emcalo[ic].hwPt), + int(ptdiff), + std::sqrt(float(sigma2Lo)), + std::sqrt(float(sigma2Hi)), + int(photonPt)); + } else { + // pion + photonPt = 0; + isEM[ic] = false; + if (g_pfalgo3_debug_ref_) + printf("FW \t emcalo %3d pt %7d ptdiff %7d [match window: -%.2f / +%.2f] flagged as pion\n", + ic, + int(emcalo[ic].hwPt), + int(ptdiff), + std::sqrt(float(sigma2Lo)), + std::sqrt(float(sigma2Hi))); + } + } else { + // photon + isEM[ic] = true; + photonPt = emcalo[ic].hwPt; + if (g_pfalgo3_debug_ref_ && emcalo[ic].hwPt > 0) + printf("FW \t emcalo %3d pt %7d flagged as photon\n", ic, int(emcalo[ic].hwPt)); + } + outpho[ic].hwPt = photonPt; + outpho[ic].hwEta = photonPt ? emcalo[ic].hwEta : etaphi_t(0); + outpho[ic].hwPhi = photonPt ? emcalo[ic].hwPhi : etaphi_t(0); + outpho[ic].hwId = photonPt ? PID_Photon : particleid_t(0); + } + + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + isEle[it] = (tk2em[it] != -1) && isEM[tk2em[it]]; + if (g_pfalgo3_debug_ref_ && isEle[it]) + printf("FW \t track %3d pt %7d flagged as electron.\n", it, int(track[it].hwPt)); + } + + std::vector em2calo(cfg.nEMCALO); + for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { + em2calo[ic] = em_best_match_ref(cfg.nCALO, DR2MAX_EH, hadcalo, emcalo[ic]); + if (g_pfalgo3_debug_ref_ && (emcalo[ic].hwPt > 0)) { + printf("FW \t emcalo %3d pt %7d isEM %d matched to hadcalo %7d pt %7d emPt %7d isEM %d\n", + ic, + int(emcalo[ic].hwPt), + int(isEM[ic]), + em2calo[ic], + (em2calo[ic] >= 0 ? int(hadcalo[em2calo[ic]].hwPt) : -1), + (em2calo[ic] >= 0 ? int(hadcalo[em2calo[ic]].hwEmPt) : -1), + (em2calo[ic] >= 0 ? int(hadcalo[em2calo[ic]].hwIsEM) : 0)); + } + } + + for (unsigned int ih = 0; ih < cfg.nCALO; ++ih) { + hadcalo_out[ih] = hadcalo[ih]; + pt_t sub = 0; + bool keep = false; + for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { + if (em2calo[ic] == int(ih)) { + if (isEM[ic]) + sub += emcalo[ic].hwPt; + else + keep = true; + } + } + pt_t emdiff = hadcalo[ih].hwEmPt - sub; + pt_t alldiff = hadcalo[ih].hwPt - sub; + if (g_pfalgo3_debug_ref_ && (hadcalo[ih].hwPt > 0)) { + printf("FW \t calo %3d pt %7d has a subtracted pt of %7d, empt %7d -> %7d isem %d mustkeep %d \n", + ih, + int(hadcalo[ih].hwPt), + int(alldiff), + int(hadcalo[ih].hwEmPt), + int(emdiff), + int(hadcalo[ih].hwIsEM), + keep); + } + if (alldiff <= (hadcalo[ih].hwPt >> 4)) { + hadcalo_out[ih].hwPt = 0; // kill + hadcalo_out[ih].hwEmPt = 0; // kill + if (g_pfalgo3_debug_ref_ && (hadcalo[ih].hwPt > 0)) + printf("FW \t calo %3d pt %7d --> discarded (zero pt)\n", ih, int(hadcalo[ih].hwPt)); + } else if ((hadcalo[ih].hwIsEM && emdiff <= (hadcalo[ih].hwEmPt >> 3)) && !keep) { + hadcalo_out[ih].hwPt = 0; // kill + hadcalo_out[ih].hwEmPt = 0; // kill + if (g_pfalgo3_debug_ref_ && (hadcalo[ih].hwPt > 0)) + printf("FW \t calo %3d pt %7d --> discarded (zero em)\n", ih, int(hadcalo[ih].hwPt)); + } else { + hadcalo_out[ih].hwPt = alldiff; + hadcalo_out[ih].hwEmPt = (emdiff > 0 ? emdiff : pt_t(0)); + } + } +} + +void pfalgo3_ref(const pfalgo3_config &cfg, + const EmCaloObj emcalo[/*cfg.nEMCALO*/], + const HadCaloObj hadcalo[/*cfg.nCALO*/], + const TkObj track[/*cfg.nTRACK*/], + const MuObj mu[/*cfg.nMU*/], + PFChargedObj outch[/*cfg.nTRACK*/], + PFNeutralObj outpho[/*cfg.nPHOTON*/], + PFNeutralObj outne[/*cfg.nSELCALO*/], + PFChargedObj outmu[/*cfg.nMU*/]) { + if (g_pfalgo3_debug_ref_) { +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + for (unsigned int i = 0; i < cfg.nTRACK; ++i) { + if (track[i].hwPt == 0) + continue; + l1tpf_impl::PropagatedTrack tk; + fw2dpf::convert(track[i], tk); + printf( + "FW \t track %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo ptErr %6d [ " + "%7.2f ] tight %d\n", + i, + tk.hwPt, + tk.floatPt(), + tk.hwEta, + tk.floatEta(), + tk.hwPhi, + tk.floatPhi(), + tk.hwCaloPtErr, + tk.floatCaloPtErr(), + int(track[i].hwTightQuality)); + } + for (unsigned int i = 0; i < cfg.nEMCALO; ++i) { + if (emcalo[i].hwPt == 0) + continue; + l1tpf_impl::CaloCluster em; + fw2dpf::convert(emcalo[i], em); + printf( + "FW \t EM %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo ptErr %6d [ " + "%7.2f ] \n", + i, + em.hwPt, + em.floatPt(), + em.hwEta, + em.floatEta(), + em.hwPhi, + em.floatPhi(), + em.hwPtErr, + em.floatPtErr()); + } + for (unsigned int i = 0; i < cfg.nCALO; ++i) { + if (hadcalo[i].hwPt == 0) + continue; + l1tpf_impl::CaloCluster calo; + fw2dpf::convert(hadcalo[i], calo); + printf( + "FW \t calo %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo emPt %7d [ " + "%7.2f ] isEM %d \n", + i, + calo.hwPt, + calo.floatPt(), + calo.hwEta, + calo.floatEta(), + calo.hwPhi, + calo.floatPhi(), + calo.hwEmPt, + calo.floatEmPt(), + calo.isEM); + } + for (unsigned int i = 0; i < cfg.nMU; ++i) { + if (mu[i].hwPt == 0) + continue; + l1tpf_impl::Muon muon; + fw2dpf::convert(mu[i], muon); + printf("FW \t muon %3d: pt %8d [ %7.2f ] muon eta %+7d [ %+5.2f ] muon phi %+7d [ %+5.2f ] \n", + i, + muon.hwPt, + muon.floatPt(), + muon.hwEta, + muon.floatEta(), + muon.hwPhi, + muon.floatPhi()); + } +#endif + } + + // constants + const pt_t TKPT_MAX_LOOSE = cfg.tk_MAXINVPT_LOOSE; + const pt_t TKPT_MAX_TIGHT = cfg.tk_MAXINVPT_TIGHT; + const int DR2MAX = cfg.dR2MAX_TK_CALO; + + //////////////////////////////////////////////////// + // TK-MU Linking + // // we can't use std::vector here because it's specialized + std::unique_ptr isMu(new bool[cfg.nTRACK]); + pfalgo_mu_ref(cfg, track, mu, &isMu[0], outmu, g_pfalgo3_debug_ref_); + + //////////////////////////////////////////////////// + // TK-EM Linking + std::unique_ptr isEle(new bool[cfg.nTRACK]); + std::vector hadcalo_subem(cfg.nCALO); + pfalgo3_em_ref(cfg, emcalo, hadcalo, track, &isMu[0], &isEle[0], outpho, &hadcalo_subem[0]); + + //////////////////////////////////////////////////// + // TK-HAD Linking + + // initialize sum track pt + std::vector calo_sumtk(cfg.nCALO), calo_subpt(cfg.nCALO); + std::vector calo_sumtkErr2(cfg.nCALO); + for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { + calo_sumtk[ic] = 0; + calo_sumtkErr2[ic] = 0; + } + + // initialize good track bit + std::unique_ptr track_good(new bool[cfg.nTRACK]); + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + track_good[it] = + (track[it].hwPt < (track[it].hwTightQuality ? TKPT_MAX_TIGHT : TKPT_MAX_LOOSE) || isEle[it] || isMu[it]); + } + + // initialize output + for (unsigned int ipf = 0; ipf < cfg.nTRACK; ++ipf) { + clear(outch[ipf]); + } + for (unsigned int ipf = 0; ipf < cfg.nSELCALO; ++ipf) { + clear(outne[ipf]); + } + + // for each track, find the closest calo + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + if (track[it].hwPt > 0 && !isEle[it] && !isMu[it]) { + int ibest = best_match_with_pt_ref(cfg.nCALO, DR2MAX, &hadcalo_subem[0], track[it]); + //int ibest = tk_best_match_ref(cfg.nCALO, DR2MAX, &hadcalo_subem[0], track[it]); + if (ibest != -1) { + if (g_pfalgo3_debug_ref_) + printf("FW \t track %3d pt %7d matched to calo %3d pt %7d\n", + it, + int(track[it].hwPt), + ibest, + int(hadcalo_subem[ibest].hwPt)); + track_good[it] = true; + calo_sumtk[ibest] += track[it].hwPt; + calo_sumtkErr2[ibest] += sqr(track[it].hwPtErr); + } + } + } + + for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { + if (calo_sumtk[ic] > 0) { + pt_t ptdiff = hadcalo_subem[ic].hwPt - calo_sumtk[ic]; + int sigmamult = calo_sumtkErr2 + [ic]; // before we did (calo_sumtkErr2[ic] + (calo_sumtkErr2[ic] >> 1)); to multiply by 1.5 = sqrt(1.5)^2 ~ (1.2)^2 + if (g_pfalgo3_debug_ref_ && (hadcalo_subem[ic].hwPt > 0)) { +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + l1tpf_impl::CaloCluster floatcalo; + fw2dpf::convert(hadcalo_subem[ic], floatcalo); + printf( + "FW \t calo %3d pt %7d [ %7.2f ] eta %+7d [ %+5.2f ] has a sum track pt %7d, difference %7d +- %.2f \n", + ic, + int(hadcalo_subem[ic].hwPt), + floatcalo.floatPt(), + int(hadcalo_subem[ic].hwEta), + floatcalo.floatEta(), + int(calo_sumtk[ic]), + int(ptdiff), + std::sqrt(float(int(calo_sumtkErr2[ic])))); +#endif + } + if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) { + calo_subpt[ic] = ptdiff; + } else { + calo_subpt[ic] = 0; + } + } else { + calo_subpt[ic] = hadcalo_subem[ic].hwPt; + } + if (g_pfalgo3_debug_ref_ && (hadcalo_subem[ic].hwPt > 0)) + printf("FW \t calo %3d pt %7d ---> %7d \n", ic, int(hadcalo_subem[ic].hwPt), int(calo_subpt[ic])); + } + + // copy out charged hadrons + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + if (track_good[it]) { + outch[it].hwPt = track[it].hwPt; + outch[it].hwEta = track[it].hwEta; + outch[it].hwPhi = track[it].hwPhi; + outch[it].hwZ0 = track[it].hwZ0; + outch[it].hwId = isEle[it] ? PID_Electron : (isMu[it] ? PID_Muon : PID_Charged); + } + } + + // copy out neutral hadrons + std::vector outne_all(cfg.nCALO); + for (unsigned int ipf = 0; ipf < cfg.nCALO; ++ipf) { + clear(outne_all[ipf]); + } + for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { + if (calo_subpt[ic] > 0) { + outne_all[ic].hwPt = calo_subpt[ic]; + outne_all[ic].hwEta = hadcalo_subem[ic].hwEta; + outne_all[ic].hwPhi = hadcalo_subem[ic].hwPhi; + outne_all[ic].hwId = PID_Neutral; + } + } + + ptsort_ref(cfg.nCALO, cfg.nSELCALO, outne_all, outne); + + if (g_pfalgo3_debug_ref_) { +#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE + std::vector tmp; + for (unsigned int i = 0; i < cfg.nTRACK; ++i) { + if (outch[i].hwPt == 0) + continue; + fw2dpf::convert(outch[i], track[i], tmp); + auto &pf = tmp.back(); + printf("FW \t outch %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] pid %d\n", + i, + pf.hwPt, + pf.floatPt(), + pf.hwEta, + pf.floatEta(), + pf.hwPhi, + pf.floatPhi(), + pf.hwId); + } + for (unsigned int i = 0; i < cfg.nPHOTON; ++i) { + if (outpho[i].hwPt == 0) + continue; + fw2dpf::convert(outpho[i], tmp); + auto &pf = tmp.back(); + printf("FW \t outph %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] pid %d\n", + i, + pf.hwPt, + pf.floatPt(), + pf.hwEta, + pf.floatEta(), + pf.hwPhi, + pf.floatPhi(), + pf.hwId); + } + for (unsigned int i = 0; i < cfg.nSELCALO; ++i) { + if (outne[i].hwPt == 0) + continue; + fw2dpf::convert(outne[i], tmp); + auto &pf = tmp.back(); + printf("FW \t outne %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] pid %d\n", + i, + pf.hwPt, + pf.floatPt(), + pf.hwEta, + pf.floatEta(), + pf.hwPhi, + pf.floatPhi(), + pf.hwId); + } +#endif + } +} + +void pfalgo3_merge_neutrals_ref(const pfalgo3_config &cfg, + const PFNeutralObj pho[/*cfg.nPHOTON*/], + const PFNeutralObj ne[/*cfg.nSELCALO*/], + PFNeutralObj allne[/*cfg.nALLNEUTRALS*/]) { + int j = 0; + for (unsigned int i = 0; i < cfg.nPHOTON; ++i, ++j) + allne[j] = pho[i]; + for (unsigned int i = 0; i < cfg.nSELCALO; ++i, ++j) + allne[j] = ne[i]; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.h b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.h new file mode 100644 index 0000000000000..43fb37ef40509 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.h @@ -0,0 +1,58 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PFALGO3_REF_H +#define L1Trigger_Phase2L1ParticleFlow_PFALGO3_REF_H + +#include "../firmware/pfalgo3.h" +#include "pfalgo_common_ref.h" + +struct pfalgo3_config : public pfalgo_config { + unsigned int nEMCALO, nPHOTON, nALLNEUTRAL; + unsigned int dR2MAX_TK_EM; + unsigned int dR2MAX_EM_CALO; + + pfalgo3_config(unsigned int nTrack, + unsigned int nEmCalo, + unsigned int nCalo, + unsigned int nMu, + unsigned int nPhoton, + unsigned int nSelCalo, + unsigned int nAllNeutral, + unsigned int dR2Max_Tk_Mu, + unsigned int dR2Max_Tk_Em, + unsigned int dR2Max_Em_Calo, + unsigned int dR2Max_Tk_Calo, + unsigned int tk_MaxInvPt_Loose, + unsigned int tk_MaxInvPt_Tight) + : pfalgo_config(nTrack, nCalo, nMu, nSelCalo, dR2Max_Tk_Mu, dR2Max_Tk_Calo, tk_MaxInvPt_Loose, tk_MaxInvPt_Tight), + nEMCALO(nEmCalo), + nPHOTON(nPhoton), + nALLNEUTRAL(nAllNeutral), + dR2MAX_TK_EM(dR2Max_Tk_Em), + dR2MAX_EM_CALO(dR2Max_Em_Calo) {} + ~pfalgo3_config() override {} +}; + +void pfalgo3_ref_set_debug(int debug); + +void pfalgo3_em_ref(const pfalgo3_config &cfg, + const EmCaloObj emcalo[/*cfg.nEMCALO*/], + const HadCaloObj hadcalo[/*cfg.nCALO*/], + const TkObj track[/*cfg.nTRACK*/], + const bool isMu[/*cfg.nTRACK*/], + bool isEle[/*cfg.nTRACK*/], + PFNeutralObj outpho[/*cfg.nPHOTON*/], + HadCaloObj hadcalo_out[/*cfg.nCALO*/]); +void pfalgo3_ref(const pfalgo3_config &cfg, + const EmCaloObj emcalo[/*cfg.nEMCALO*/], + const HadCaloObj hadcalo[/*cfg.nCALO*/], + const TkObj track[/*cfg.nTRACK*/], + const MuObj mu[/*cfg.nMU*/], + PFChargedObj outch[/*cfg.nTRACK*/], + PFNeutralObj outpho[/*cfg.nPHOTON*/], + PFNeutralObj outne[/*cfg.nSELCALO*/], + PFChargedObj outmu[/*cfg.nMU*/]); + +void pfalgo3_merge_neutrals_ref(const pfalgo3_config &cfg, + const PFNeutralObj pho[/*cfg.nPHOTON*/], + const PFNeutralObj ne[/*cfg.nSELCALO*/], + PFNeutralObj allne[/*cfg.nALLNEUTRALS*/]); +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.cpp new file mode 100644 index 0000000000000..8844c0617149b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.cpp @@ -0,0 +1,49 @@ +#include "pfalgo_common_ref.h" + +#include +#include + +void pfalgo_mu_ref(const pfalgo_config &cfg, + const TkObj track[/*cfg.nTRACK*/], + const MuObj mu[/*cfg.nMU*/], + bool isMu[/*cfg.nTRACK*/], + PFChargedObj outmu[/*cfg.nMU*/], + bool debug) { + // init + for (unsigned int ipf = 0; ipf < cfg.nMU; ++ipf) + clear(outmu[ipf]); + for (unsigned int it = 0; it < cfg.nTRACK; ++it) + isMu[it] = false; + + // for each muon, find the closest track + for (unsigned int im = 0; im < cfg.nMU; ++im) { + if (mu[im].hwPt > 0) { + int ibest = -1; + int dptmin = mu[im].hwPt >> 1; + for (unsigned int it = 0; it < cfg.nTRACK; ++it) { + unsigned int dr = dr2_int(mu[im].hwEta, mu[im].hwPhi, track[it].hwEta, track[it].hwPhi); + //printf("deltaR2(mu %d float pt %5.1f, tk %2d float pt %5.1f) = int %d (float deltaR = %.3f); int cut at %d\n", im, 0.25*int(mu[im].hwPt), it, 0.25*int(track[it].hwPt), dr, std::sqrt(float(dr))/229.2, cfg.dR2MAX_TK_MU); + if (dr < cfg.dR2MAX_TK_MU) { + int dpt = std::abs(int(track[it].hwPt - mu[im].hwPt)); + if (dpt < dptmin) { + dptmin = dpt; + ibest = it; + } + } + } + if (ibest != -1) { + outmu[im].hwPt = track[ibest].hwPt; + outmu[im].hwEta = track[ibest].hwEta; + outmu[im].hwPhi = track[ibest].hwPhi; + outmu[im].hwId = PID_Muon; + outmu[im].hwZ0 = track[ibest].hwZ0; + isMu[ibest] = true; + if (debug) + printf("FW \t muon %3d linked to track %3d \n", im, ibest); + } else { + if (debug) + printf("FW \t muon %3d not linked to any track\n", im); + } + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.h b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.h new file mode 100644 index 0000000000000..87b2b7194697c --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.h @@ -0,0 +1,95 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_PFALGO_COMMON_REF_H +#define L1Trigger_Phase2L1ParticleFlow_PFALGO_COMMON_REF_H + +#include "../firmware/data.h" +#include "../firmware/pfalgo_common.h" +#include + +template +inline int sqr(const T &t) { + return t * t; +} + +template +int best_match_with_pt_ref(int nCAL, int dR2MAX, const CO_t calo[/*nCAL*/], const TkObj &track); + +template +void ptsort_ref(int nIn, int nOut, const T in[/*nIn*/], T out[/*nOut*/]); + +struct pfalgo_config { + unsigned int nTRACK, nCALO, nMU; + unsigned int nSELCALO; + unsigned int dR2MAX_TK_MU; + unsigned int dR2MAX_TK_CALO; + unsigned int tk_MAXINVPT_LOOSE, tk_MAXINVPT_TIGHT; + + pfalgo_config(unsigned int nTrack, + unsigned int nCalo, + unsigned int nMu, + unsigned int nSelCalo, + unsigned int dR2Max_Tk_Mu, + unsigned int dR2Max_Tk_Calo, + unsigned int tk_MaxInvPt_Loose, + unsigned int tk_MaxInvPt_Tight) + : nTRACK(nTrack), + nCALO(nCalo), + nMU(nMu), + nSELCALO(nSelCalo), + dR2MAX_TK_MU(dR2Max_Tk_Mu), + dR2MAX_TK_CALO(dR2Max_Tk_Calo), + tk_MAXINVPT_LOOSE(tk_MaxInvPt_Loose), + tk_MAXINVPT_TIGHT(tk_MaxInvPt_Tight) {} + + virtual ~pfalgo_config() {} +}; + +void pfalgo_mu_ref(const pfalgo_config &cfg, + const TkObj track[/*cfg.nTRACK*/], + const MuObj mu[/*cfg.nMU*/], + bool isMu[/*cfg.nTRACK*/], + PFChargedObj outmu[/*cfg.nMU*/], + bool debug); + +//=== begin implementation part + +template +int best_match_with_pt_ref(int nCAL, int dR2MAX, const CO_t calo[/*nCAL*/], const TkObj &track) { + pt_t caloPtMin = track.hwPt - 2 * (track.hwPtErr); + if (caloPtMin < 0) + caloPtMin = 0; + int dptscale = (dR2MAX << 8) / std::max(1, sqr(track.hwPtErr)); + int drmin = 0, ibest = -1; + for (int ic = 0; ic < nCAL; ++ic) { + if (calo[ic].hwPt <= caloPtMin) + continue; + int dr = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); + if (dr >= dR2MAX) + continue; + dr += ((sqr(std::max(track.hwPt - calo[ic].hwPt, 0)) * dptscale) >> 8); + if (ibest == -1 || dr < drmin) { + drmin = dr; + ibest = ic; + } + } + return ibest; +} + +template +void ptsort_ref(int nIn, int nOut, const TV &in /*[nIn]*/, T out[/*nOut*/]) { + for (int iout = 0; iout < nOut; ++iout) { + out[iout].hwPt = 0; + } + for (int it = 0; it < nIn; ++it) { + for (int iout = 0; iout < nOut; ++iout) { + if (in[it].hwPt >= out[iout].hwPt) { + for (int i2 = nOut - 1; i2 > iout; --i2) { + out[i2] = out[i2 - 1]; + } + out[iout] = in[it]; + break; + } + } + } +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/utils/DiscretePF2Firmware.h b/L1Trigger/Phase2L1ParticleFlow/src/utils/DiscretePF2Firmware.h new file mode 100644 index 0000000000000..0fbf23b86c8e8 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/utils/DiscretePF2Firmware.h @@ -0,0 +1,69 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_DISCRETEPF2FIRMWARE_H +#define L1Trigger_Phase2L1ParticleFlow_DISCRETEPF2FIRMWARE_H + +/// NOTE: this include is not standalone, since the path to DiscretePFInputs is different in CMSSW & Vivado_HLS + +#include "../firmware/data.h" +#include + +namespace dpf2fw { + + // convert inputs from discrete to firmware + void convert(const l1tpf_impl::PropagatedTrack &in, TkObj &out) { + out.hwPt = in.hwPt; + out.hwPtErr = in.hwCaloPtErr; + out.hwEta = in.hwEta; // @calo + out.hwPhi = in.hwPhi; // @calo + out.hwZ0 = in.hwZ0; + out.hwTightQuality = (in.hwStubs >= 6 && in.hwChi2 < 500); + } + + TkObj transformConvert(const l1tpf_impl::PropagatedTrack &in) { + TkObj out; + convert(in, out); + return out; + } + + void convert(const l1tpf_impl::CaloCluster &in, HadCaloObj &out) { + out.hwPt = in.hwPt; + out.hwEmPt = in.hwEmPt; + out.hwEta = in.hwEta; + out.hwPhi = in.hwPhi; + out.hwIsEM = in.isEM; + } + void convert(const l1tpf_impl::CaloCluster &in, EmCaloObj &out) { + out.hwPt = in.hwPt; + out.hwPtErr = in.hwPtErr; + out.hwEta = in.hwEta; + out.hwPhi = in.hwPhi; + } + void convert(const l1tpf_impl::Muon &in, MuObj &out) { + out.hwPt = in.hwPt; + out.hwPtErr = 0; // does not exist in input + out.hwEta = in.hwEta; // @calo + out.hwPhi = in.hwPhi; // @calo + } + + template + void convert(const std::vector &in, Out out[NMAX]) { + for (unsigned int i = 0, n = std::min(NMAX, in.size()); i < n; ++i) { + convert(in[i], out[i]); + } + for (unsigned int i = in.size(); i < NMAX; ++i) { + clear(out[i]); + } + } + + template + void convert(unsigned int NMAX, const std::vector &in, Out out[]) { + for (unsigned int i = 0, n = std::min(NMAX, in.size()); i < n; ++i) { + convert(in[i], out[i]); + } + for (unsigned int i = in.size(); i < NMAX; ++i) { + clear(out[i]); + } + } + +} // namespace dpf2fw + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/utils/Firmware2DiscretePF.h b/L1Trigger/Phase2L1ParticleFlow/src/utils/Firmware2DiscretePF.h new file mode 100644 index 0000000000000..7956a7044861d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/utils/Firmware2DiscretePF.h @@ -0,0 +1,161 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE2DISCRETEPF_H +#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE2DISCRETEPF_H + +/// NOTE: this include is not standalone, since the path to DiscretePFInputs is different in CMSSW & Vivado_HLS + +#include "../firmware/data.h" +#include +#include + +namespace fw2dpf { + + // convert inputs from discrete to firmware + inline void convert(const PFChargedObj &src, + const l1tpf_impl::PropagatedTrack &track, + std::vector &out) { + l1tpf_impl::PFParticle pf; + pf.hwPt = src.hwPt; + pf.hwEta = src.hwEta; + pf.hwPhi = src.hwPhi; + pf.hwVtxEta = src.hwEta; // FIXME: get from the track + pf.hwVtxPhi = src.hwPhi; // before propagation + pf.track = track; // FIXME: ok only as long as there is a 1-1 mapping + pf.cluster.hwPt = 0; + pf.cluster.src = nullptr; + pf.muonsrc = nullptr; + switch (src.hwId) { + case PID_Electron: + pf.hwId = 1; + break; + case PID_Muon: + pf.hwId = 4; + break; + default: + pf.hwId = 0; + break; + }; + pf.hwStatus = 0; + out.push_back(pf); + } + // convert inputs from discrete to firmware + inline void convert(const TkObj &in, l1tpf_impl::PropagatedTrack &out); + inline void convert(const PFChargedObj &src, const TkObj &track, std::vector &out) { + l1tpf_impl::PFParticle pf; + pf.hwPt = src.hwPt; + pf.hwEta = src.hwEta; + pf.hwPhi = src.hwPhi; + pf.hwVtxEta = src.hwEta; // FIXME: get from the track + pf.hwVtxPhi = src.hwPhi; // before propagation + convert(track, pf.track); // FIXME: ok only as long as there is a 1-1 mapping + pf.cluster.hwPt = 0; + pf.cluster.src = nullptr; + pf.muonsrc = nullptr; + switch (src.hwId) { + case PID_Electron: + pf.hwId = 1; + break; + case PID_Muon: + pf.hwId = 4; + break; + default: + pf.hwId = 0; + break; + }; + pf.hwStatus = 0; + out.push_back(pf); + } + inline void convert(const PFNeutralObj &src, std::vector &out) { + l1tpf_impl::PFParticle pf; + pf.hwPt = src.hwPt; + pf.hwEta = src.hwEta; + pf.hwPhi = src.hwPhi; + pf.hwVtxEta = src.hwEta; + pf.hwVtxPhi = src.hwPhi; + pf.track.hwPt = 0; + pf.track.src = nullptr; + pf.cluster.hwPt = src.hwPt; + pf.cluster.src = nullptr; + pf.muonsrc = nullptr; + switch (src.hwId) { + case PID_Photon: + pf.hwId = 3; + break; + default: + pf.hwId = 2; + break; + } + pf.hwStatus = 0; + out.push_back(pf); + } + + // convert inputs from discrete to firmware + inline void convert(const TkObj &in, l1tpf_impl::PropagatedTrack &out) { + out.hwPt = in.hwPt; + out.hwCaloPtErr = in.hwPtErr; + out.hwEta = in.hwEta; // @calo + out.hwPhi = in.hwPhi; // @calo + out.hwZ0 = in.hwZ0; + out.src = nullptr; + } + inline void convert(const HadCaloObj &in, l1tpf_impl::CaloCluster &out) { + out.hwPt = in.hwPt; + out.hwEmPt = in.hwEmPt; + out.hwEta = in.hwEta; + out.hwPhi = in.hwPhi; + out.isEM = in.hwIsEM; + out.src = nullptr; + } + inline void convert(const EmCaloObj &in, l1tpf_impl::CaloCluster &out) { + out.hwPt = in.hwPt; + out.hwPtErr = in.hwPtErr; + out.hwEta = in.hwEta; + out.hwPhi = in.hwPhi; + out.src = nullptr; + } + inline void convert(const MuObj &in, l1tpf_impl::Muon &out) { + out.hwPt = in.hwPt; + out.hwEta = in.hwEta; // @calo + out.hwPhi = in.hwPhi; // @calo + out.src = nullptr; + } + + template + void convert(const In in[NMAX], std::vector &out) { + for (unsigned int i = 0; i < NMAX; ++i) { + if (in[i].hwPt > 0) + convert(in[i], out); + } + } + template + void convert(unsigned int NMAX, const In in[], std::vector &out) { + for (unsigned int i = 0; i < NMAX; ++i) { + if (in[i].hwPt > 0) + convert(in[i], out); + } + } + template + void convert(const PFChargedObj in[NMAX], + std::vector srctracks, + std::vector &out) { + for (unsigned int i = 0; i < NMAX; ++i) { + if (in[i].hwPt > 0) { + assert(i < srctracks.size()); + convert(in[i], srctracks[i], out); + } + } + } + inline void convert(unsigned int NMAX, + const PFChargedObj in[], + std::vector srctracks, + std::vector &out) { + for (unsigned int i = 0; i < NMAX; ++i) { + if (in[i].hwPt > 0) { + assert(i < srctracks.size()); + convert(in[i], srctracks[i], out); + } + } + } + +} // namespace fw2dpf + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml new file mode 100644 index 0000000000000..0b22a9c4949f8 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/L1Trigger/Phase2L1ParticleFlow/test/l1pfJetMetTreeProducer.py b/L1Trigger/Phase2L1ParticleFlow/test/l1pfJetMetTreeProducer.py new file mode 100644 index 0000000000000..c2ec3df0ffa56 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/l1pfJetMetTreeProducer.py @@ -0,0 +1,31 @@ +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("IN", eras.phase2_trigger) +process.load('Configuration.StandardSequences.Services_cff') +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.load('Configuration.Geometry.GeometryExtended2023D17Reco_cff') +process.load('Configuration.StandardSequences.MagneticField_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, '100X_upgrade2023_realistic_v1', '') + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('/store/relval/CMSSW_9_3_7/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/93X_upgrade2023_realistic_v5_2023D17noPU-v2/10000/7EC7DD7F-782C-E811-B469-0CC47A4D76A0.root'), + duplicateCheckMode = cms.untracked.string("noDuplicateCheck"), + inputCommands = cms.untracked.vstring("keep *", + "drop l1tEMTFHit2016Extras_simEmtfDigis_CSC_HLT", + "drop l1tEMTFHit2016Extras_simEmtfDigis_RPC_HLT", + "drop l1tEMTFHit2016s_simEmtfDigis__HLT", + "drop l1tEMTFTrack2016Extras_simEmtfDigis__HLT", + "drop l1tEMTFTrack2016s_simEmtfDigis__HLT") + +) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(500)) +process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True) ) + +process.load('L1Trigger.Phase2L1ParticleFlow.l1pfJetMetTreeProducer_cff') + +process.p = cms.Path(process.l1pfJetMetTreeProducer) +process.TFileService = cms.Service("TFileService", fileName = cms.string("jetmetTuple.root")) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp new file mode 100644 index 0000000000000..fbd92c4a82221 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp @@ -0,0 +1,611 @@ +// STL includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ROOT includes +#include "TROOT.h" +#include "TSystem.h" +#include "TFile.h" +#include "TTree.h" +#include "TLorentzVector.h" + +// CMSSW includes +#include "FWCore/FWLite/interface/FWLiteEnabler.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "DataFormats/FWLite/interface/Handle.h" +#include "DataFormats/FWLite/interface/Run.h" +#include "DataFormats/FWLite/interface/LuminosityBlock.h" +#include "DataFormats/FWLite/interface/Event.h" +#include "DataFormats/L1TParticleFlow/interface/PFTrack.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" + +#define NTEST 64 +#define REPORT_EVERY_N 50 +#define NTRACKS_PER_SECTOR 110 +#define NBITS_PER_TRACK 96 +static std::vector regions_; + +typedef l1tpf_impl::InputRegion Region; +typedef std::pair SectorTrackIndex; +typedef std::map TrackMap; + +struct Event { + uint32_t run, lumi; + uint64_t event; + float z0, genZ0; + std::vector puGlobals; // [float] alphaCMed, alphaCRms, alphaFMed, alphaFRms + std::vector regions; + + Event() : run(0), lumi(0), event(0), z0(0.), regions() {} + bool readFromFile(FILE *fRegionDump) { + if (!fread(&run, sizeof(uint32_t), 1, fRegionDump)) + return false; + fread(&lumi, sizeof(uint32_t), 1, fRegionDump); + fread(&event, sizeof(uint64_t), 1, fRegionDump); + l1tpf_impl::readManyFromFile(regions, fRegionDump); + fread(&z0, sizeof(float), 1, fRegionDump); + fread(&genZ0, sizeof(float), 1, fRegionDump); + l1tpf_impl::readManyFromFile(puGlobals, fRegionDump); + return true; + } +}; + +TLorentzVector makeTLorentzVectorPtEtaPhiE(float pt, float eta, float phi, float e) { + TLorentzVector v; + v.SetPtEtaPhiE(pt, eta, phi, e); + return v; +} + +/* + * Convert a bitset to a signed int64_t. + * std::bitset has built-ins for ulong and ullong. + */ +template 0 && N < 64)>> +int64_t to_int64_from_bitset(const std::bitset &b) { + int const shift = 64 - N; + return (((int64_t)b.to_ullong() << shift) >> shift); +} + +/* + * Generic implementation to search if a given value exists in a map or not. + * Adds all the keys with given value in the vector + */ +template +bool findAllInRegion(std::vector &vec, std::map mapOfElemen, T value) { + bool bResult = false; + auto it = mapOfElemen.begin(); + // Iterate through the map + while (it != mapOfElemen.end()) { + // Check if value of this entry matches with given value + if (it->first.first == value) { + // Yes found + bResult = true; + // Push the key in given map + vec.push_back(it->first); + } + // Go to next entry in map + it++; + } + return bResult; +} + +TrackMap get_tracks_from_root_file(fwlite::Event &ev, int entry = 0, bool print = false) { + TrackMap tracks_root; + + // clear the tracks currently stored in the regions + for (l1tpf_impl::Region &r : regions_) { + r.track.clear(); + } + + // go to the event under test + if (!ev.to(entry)) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_root_file Unable to load the event at entry " << entry + << std::endl; + assert(ev.to(entry)); + } + if (print) + printf("ROOT::Run %u, lumi %u, event %llu \n", + ev.getRun().id().run(), + ev.getLuminosityBlock().id().luminosityBlock(), + ev.eventAuxiliary().id().event()); + + edm::InputTag trackLabel("pfTracksFromL1TracksBarrel"); + edm::Handle> h_track; + ev.getByLabel(trackLabel, h_track); + assert(h_track.isValid()); + + int ntrackstotal(0); + const auto &tracks = *h_track; + for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) { + const auto &tk = tracks[itk]; + if (tk.pt() <= 2.0 || tk.nStubs() < 4 || tk.normalizedChi2() >= 15.0) + continue; + for (l1tpf_impl::Region &r : regions_) { + bool inside = r.contains(tk.eta(), tk.phi()); + ; + if (inside) { + l1tpf_impl::PropagatedTrack prop; + prop.fillInput( + tk.pt(), r.localEta(tk.eta()), r.localPhi(tk.phi()), tk.charge(), tk.vertex().Z(), tk.quality(), &tk); + prop.fillPropagated(tk.pt(), + tk.trkPtError(), + tk.caloPtError(), + r.localEta(tk.caloEta()), + r.localPhi(tk.caloPhi()), + tk.quality(), + tk.isMuon()); + prop.hwStubs = tk.nStubs(); + prop.hwChi2 = round(tk.chi2() * 10); + r.track.push_back(prop); + } + } + //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", ntrackstotal, tk.pt(), tk.eta(), tk.phi()); + ntrackstotal++; + } + for (unsigned int iregion = 0; iregion < regions_.size(); ++iregion) { + std::vector tracks_in_region = regions_[iregion].track; + if (print) + printf("\tFound region %u (eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]) with %lu tracks\n", + iregion, + regions_[iregion].etaMin, + regions_[iregion].etaMax, + regions_[iregion].phiCenter - regions_[iregion].phiHalfWidth, + regions_[iregion].phiCenter + regions_[iregion].phiHalfWidth, + tracks_in_region.size()); + for (unsigned int it = 0; it < tracks_in_region.size(); it++) { + if (print) + printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", + it, + tracks_in_region[it].src->p4().pt(), + tracks_in_region[it].src->p4().eta(), + tracks_in_region[it].src->p4().phi()); + tracks_root[std::make_pair(iregion, it)] = makeTLorentzVectorPtEtaPhiE(tracks_in_region[it].src->pt(), + tracks_in_region[it].src->eta(), + tracks_in_region[it].src->phi(), + tracks_in_region[it].src->pt()); + } + } + if (print) { + printf("\t================================= \n"); + printf("\tTotal tracks %u \n\n", ntrackstotal); + } + + return tracks_root; +} + +std::map, TLorentzVector> get_tracks_from_dump_file(FILE *dfile_ = nullptr, bool print = false) { + std::map, TLorentzVector> tracks_dump; + Event event_; + + if (feof(dfile_)) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file We have already reached the end of the dump file" + << std::endl; + assert(!feof(dfile_)); + } + if (!event_.readFromFile(dfile_)) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file Something went wrong reading from the dump file" + << std::endl; + assert(event_.readFromFile(dfile_)); + } + if (event_.regions.size() != regions_.size()) { + printf("ERROR::testDumpFile::get_tracks_from_dump_file Mismatching number of input regions: %lu\n", + event_.regions.size()); + assert(event_.regions.size() == regions_.size()); + } + if (print) + printf("Dump::Run %u, lumi %u, event %lu, regions %lu \n", + event_.run, + event_.lumi, + event_.event, + event_.regions.size()); + + unsigned int ntrackstotal(0); + float maxabseta(0), maxz(0), minz(0); + + int pv_gen = round(event_.genZ0 * l1tpf_impl::InputTrack::Z0_SCALE); + int pv_cmssw = round(event_.z0 * l1tpf_impl::InputTrack::Z0_SCALE); + + for (unsigned int is = 0; is < regions_.size(); ++is) { + const Region &r = event_.regions[is]; + if (print) + printf("\tRead region %u [%0.2f,%0.2f] with %lu tracks\n", + is, + r.phiCenter - r.phiHalfWidth, + r.phiCenter + r.phiHalfWidth, + r.track.size()); + ntrackstotal += r.track.size(); + for (unsigned int it = 0; it < r.track.size(); it++) { + tracks_dump[std::make_pair(is, it)] = makeTLorentzVectorPtEtaPhiE( + r.track[it].floatVtxPt(), r.track[it].floatVtxEta(), r.track[it].floatVtxPhi(), r.track[it].floatVtxPt()); + if (abs(r.track[it].hwVtxEta) > maxabseta) + maxabseta = abs(r.track[it].hwVtxEta); + if (r.track[it].hwZ0 > maxz) + maxz = r.track[it].hwZ0; + if (r.track[it].hwZ0 < minz) + minz = r.track[it].hwZ0; + if (print) + printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", + it, + r.track[it].floatVtxPt(), + r.track[it].floatVtxEta(), + r.track[it].floatVtxPhi()); + } + } + + if (print) { + printf("\t================================= \n"); + printf("\tTotal tracks %u \n", ntrackstotal); + printf("\tMax abs(eta) %.2f [hw units] \n", maxabseta); + printf("\tMax abs(eta) %.4f \n", maxabseta / l1tpf_impl::InputTrack::VTX_ETA_SCALE); + printf("\t[Min,max] track z0 [%.2f,%.2f] [hw units] \n", minz, maxz); + printf("\t[Min,max] track z0 [%.2f,%.2f] [cm] \n", + minz / l1tpf_impl::InputTrack::Z0_SCALE, + maxz / l1tpf_impl::InputTrack::Z0_SCALE); + printf("\tPV (GEN) %u \n", pv_gen); + printf("\tPV (CMSSW) %u \n\n", pv_cmssw); + } + + return tracks_dump; +} + +std::map, TLorentzVector> get_tracks_from_coe_file(std::ifstream &cfile_, + bool print = false, + bool debug = false) { + std::map, TLorentzVector> tracks_coe; + std::string bset_string_; + int ntrackstotal(0); + bool skip(false); + + // check that we haven't reached the end of the file (i.e. there a more events to be read out) + if (cfile_.eof()) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file We have already reached the end of the coe file" + << std::endl; + assert(!cfile_.eof()); + } + if (print) + printf("COE::Run \"unknown\", lumi \"unknown\", event \"unknown\", regions %lu? \n", regions_.size()); + + // read the lines one by one + for (unsigned int iline = 0; iline < NTRACKS_PER_SECTOR; iline++) { + bset_string_.resize(NBITS_PER_TRACK); + for (unsigned int isector = 0; isector < regions_.size(); isector++) { + cfile_.read(&bset_string_[0], 96); + std::bitset bset_(bset_string_); + if (bset_.none()) { + skip = true; + continue; + } else { + skip = false; + } + + std::bitset<14> hwPt; + std::bitset<16> hwVtxEta; + std::bitset<12> hwVtxPhi; + for (int i = 14 - 1; i >= 0; i--) { + hwPt.set(i, bset_[i]); + } + for (int i = 12 - 1; i >= 0; i--) { + hwVtxPhi.set(i, bset_[i + 15]); + } + for (int i = 16 - 1; i >= 0; i--) { + hwVtxEta.set(i, bset_[i + 27]); + } + float hwVtxPt_f = (float(hwPt.to_ulong()) / l1tpf_impl::CaloCluster::PT_SCALE); + float hwVtxEta_f = float(to_int64_from_bitset(hwVtxEta)) / l1tpf_impl::InputTrack::VTX_ETA_SCALE; + float hwVtxPhi_f = float(to_int64_from_bitset(hwVtxPhi)) / l1tpf_impl::InputTrack::VTX_PHI_SCALE; + + if (debug) { + std::cout << "bset_string_ = " << bset_string_ << std::endl; + std::cout << "\thwPt (0b) = " << std::flush; + for (int i = 14 - 1; i >= 0; i--) { + std::cout << bset_[i] << std::flush; + } + std::cout << std::endl; + std::cout << "\thwVtxPhi (0b) = " << std::flush; + for (int i = 12 - 1; i >= 0; i--) { + std::cout << bset_[i + 15] << std::flush; + } + std::cout << std::endl; + std::cout << "\thwVtxEta (0b) = " << std::flush; + for (int i = 16 - 1; i >= 0; i--) { + std::cout << bset_[i + 27] << std::flush; + } + std::cout << std::endl; + std::cout << "\thwPt (int) = " << hwPt.to_ulong() << std::endl; + std::cout << "\thwVtxPhi (int) = " << to_int64_from_bitset(hwVtxPhi) << std::endl; + std::cout << "\thwVtxEta (int) = " << to_int64_from_bitset(hwVtxEta) << std::endl; + std::cout << "\thwVtxPt_f (float) = " << hwVtxPt_f << std::endl; + std::cout << "\thwVtxPhi_f (float) = " << hwVtxPhi_f << std::endl; + std::cout << "\thwVtxEta_f (float) = " << hwVtxEta_f << std::endl; + } + + if (bset_.any()) { + ntrackstotal++; + tracks_coe[std::make_pair(isector, iline)] = + makeTLorentzVectorPtEtaPhiE(hwVtxPt_f, hwVtxEta_f, hwVtxPhi_f, hwVtxPt_f); + //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", it, hwPt_f, hwVtxEta_f, hwVtxPhi_f); + } + } + + // remove the trailing character + bset_string_.resize(2); + cfile_.read(&bset_string_[0], 2); + if (debug && !skip) + std::cout << "bset_string_ = " << bset_string_ << std::endl; + if (bset_string_ != ",\n" && bset_string_ != ";\n") { + std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file Something went wrong reading line " << 11 + iline + << " of the COE file" << std::endl + << "\tThe line should have ended with \',\' or \';\', but instead ended with \'" + << bset_string_ << "\'" << std::endl; + assert(bset_string_ != "," || bset_string_ != ";"); + } + } + for (unsigned int is = 0; is < regions_.size(); ++is) { + std::vector tracks_in_sector; + findAllInRegion(tracks_in_sector, tracks_coe, is); + if (print) + printf("\tRead region %u (eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]) with %lu tracks\n", + is, + regions_[is].etaMin, + regions_[is].etaMax, + regions_[is].phiCenter - regions_[is].phiHalfWidth, + regions_[is].phiCenter + regions_[is].phiHalfWidth, + tracks_in_sector.size()); + for (unsigned int it = 0; it < tracks_in_sector.size(); it++) { + if (print) + printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", + it, + tracks_coe[tracks_in_sector[it]].Pt(), + tracks_coe[tracks_in_sector[it]].Eta(), + tracks_coe[tracks_in_sector[it]].Phi()); + } + } + + if (print) { + printf("\t================================= \n"); + printf("\tTotal tracks %u \n\n", ntrackstotal); + } + + return tracks_coe; +} + +std::ifstream &GotoLine(std::ifstream &file, unsigned int num) { + file.seekg(std::ios::beg); + for (unsigned int i = 0; i < num - 1; ++i) { + file.ignore(std::numeric_limits::max(), '\n'); + } + return file; +} + +bool compare_lv_with_tolerance(TLorentzVector a, TLorentzVector b, const std::vector &tolerance = {0, 0, 0, 0}) { + /* + Example (Tolerance = 0.0005): + Track from ROOT file: pt=16.3452797 + InputTrack::INVPT_SCALE = 2E4 + std::numeric_limits::max() = 65535 + hwInvpt = std::min(round(1/pt * InputTrack::INVPT_SCALE), std::numeric_limits::max()) = 1224.0000 + floatVtxPt() = 1/(float(hwInvpt) / InputTrack::INVPT_SCALE) = 16.339869 + So loss of precision comes from rounding + Difference is DeltaPt=0.00541114807 + */ + if (abs(a.Pt() - b.Pt()) > tolerance[0] || abs(a.Eta() - b.Eta()) > tolerance[1] || + abs(a.Phi() - b.Phi()) > tolerance[2] || abs(a.E() - b.E()) > tolerance[3]) { + std::cerr << std::setprecision(9); + std::cerr << std::endl << "\tMismatching " << std::flush; + if (abs(a.Pt() - b.Pt()) > tolerance[0]) + std::cerr << "pT! " << a.Pt() << " vs " << b.Pt() << " where DeltaPt=" << abs(a.Pt() - b.Pt()) + << " and epsilon=" << tolerance[0] << std::endl; + else if (abs(a.Eta() - b.Eta()) > tolerance[1]) + std::cerr << "eta! " << a.Eta() << " vs " << b.Eta() << " where DeltaEta=" << abs(a.Eta() - b.Eta()) + << " and epsilon=" << tolerance[1] << std::endl; + else if (abs(a.Phi() - b.Phi()) > tolerance[2]) + std::cerr << "phi! " << a.Phi() << " vs " << b.Phi() << " where DeltaPhi=" << abs(a.Phi() - b.Phi()) + << " and epsilon=" << tolerance[2] << std::endl; + else if (abs(a.E() - b.E()) > tolerance[3]) + std::cerr << "E! " << a.E() << " vs " << b.E() << " where DeltaE=" << abs(a.E() - b.E()) + << " and epsilon=" << tolerance[3] << std::endl; + return false; + } + return true; +} + +bool compare_maps(TrackMap ref, TrackMap test) { + TLorentzVector tlv; + for (auto it = ref.begin(); it != ref.end(); it++) { + if (test.find(it->first) == test.end()) { + std::cerr << std::endl + << "\tERROR::compare_maps Can't find the test track with (sector,index)=(" << it->first.first << "," + << it->first.second << ")" << std::endl; + return false; + } + tlv = (test.find(it->first)->second); + // The pT tolerance should be 1.0/l1tpf_impl::CaloCluster::PT_SCALE, but because of the rounding this is not true and the actual resolution isn't always as good + // Instead, we will use max(1% of the pT of the reference TLorentzVector,0.25) + // We use the max statement because at low pT, the 1% definition doesn't hold anymore. This wouldn't be a problem if 1/pT were encoded rather than pT. + if (!compare_lv_with_tolerance( + (it->second), + tlv, + {float(std::max(it->second.Pt() * 1E-2, 1.0 / l1tpf_impl::CaloCluster::PT_SCALE)), + 1.0 / l1tpf_impl::InputTrack::VTX_ETA_SCALE, + 1.0 / l1tpf_impl::InputTrack::VTX_PHI_SCALE, + float(std::max(it->second.Pt() * 1E-2, 1.0 / l1tpf_impl::CaloCluster::PT_SCALE))})) { + std::cerr << std::endl + << "\tERROR::compare_maps Can't find the test track with TLorentzVector (" << it->second.Pt() << "," + << it->second.Eta() << "," << it->second.Phi() << "," << it->second.E() << ")" << std::endl + << "\t\tInstead found (" << tlv.Pt() << "," << tlv.Eta() << "," << tlv.Phi() << "," << tlv.E() + << ") at the position (sector,index)=(" << it->first.first << "," << it->first.second << ")" + << std::endl; + return false; + } + } + return true; +} + +int main(int argc, char *argv[]) { + // store some programatic information + std::stringstream usage; + usage << "usage: " << argv[0] + << " .root .dump .coe "; + + // load framework libraries + gSystem->Load("libFWCoreFWLite"); + FWLiteEnabler::enable(); + + // argc should be 5 for correct execution + // We print argv[0] assuming it is the program name + if (argc < 9) { + std::cerr << "ERROR::testDumpFile " << argc << " arguments provided" << std::endl; + for (int i = 0; i < argc; i++) { + std::cerr << "\tArgument " << i << ": " << argv[i] << std::endl; + } + std::cerr << usage.str() << std::endl; + return -1; + } + + // assign the command-line parameters to variables and setup the regions + std::string filename_root = argv[1]; + std::string filename_dump = argv[2]; + std::string filename_coe = argv[3]; + float etaExtra, phiExtra; + unsigned int nRegionsPhi; + std::vector etaBoundaries; + try { + etaExtra = atof(argv[4]); + phiExtra = atof(argv[5]); + nRegionsPhi = atoi(argv[6]); + std::vector etaBoundariesStrings(argv + 7, argv + argc); + std::size_t pos; + for (unsigned int i = 0; i < etaBoundariesStrings.size(); i++) { + etaBoundaries.push_back(std::stoi(etaBoundariesStrings[i], &pos)); + if (pos < etaBoundariesStrings[i].size()) { + std::cerr << "Trailing characters after number: " << etaBoundariesStrings[i] << '\n'; + } + } + float phiWidth = 2 * M_PI / nRegionsPhi; + for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { + for (unsigned int iphi = 0; iphi < nRegionsPhi; ++iphi) { + float phiCenter = (iphi + 0.5) * phiWidth - M_PI; + regions_.push_back(l1tpf_impl::Region(etaBoundaries[ieta], + etaBoundaries[ieta + 1], + phiCenter, + phiWidth, + phiExtra, + etaExtra, + false, + 0, + 0, + 0, + 0, + 0, + 0)); + } + } + } catch (std::invalid_argument const &ex) { + std::cerr << "Invalid number in one of the eta-phi arguments" << std::endl; + return -2; + } catch (std::out_of_range const &ex) { + std::cerr << "Number out of range in one of the eta-phi arguments" << std::endl; + return -3; + } + + // check the filenames + if (filename_root.find(".root") == std::string::npos) { + std::cerr << "ERROR::testDumpFile Filename 1 must be a ROOT (.root) file" << std::endl << usage.str() << std::endl; + return -4; + } else if (filename_dump.find(".dump") == std::string::npos) { + std::cerr << "ERROR::testDumpFile Filename 2 must be a binary (.dump) file" << std::endl + << usage.str() << std::endl; + return -5; + } else if (filename_coe.find(".coe") == std::string::npos) { + std::cerr << "ERROR::testDumpFile Filename 3 must be a COE (.coe) file" << std::endl << usage.str() << std::endl; + return -6; + } + + // report the program configuraion + std::cout << "Configuration:" << std::endl + << "==============" << std::endl + << "Number of tests (events): " << NTEST << std::endl + << "Report every N tests: " << REPORT_EVERY_N << std::endl + << "Number of regions (in eta-phi): " << regions_.size() << std::endl; + for (unsigned int iregion = 0; iregion < regions_.size(); iregion++) { + printf("\t%i : eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]\n", + iregion, + regions_[iregion].etaMin, + regions_[iregion].etaMax, + regions_[iregion].phiCenter - regions_[iregion].phiHalfWidth, + regions_[iregion].phiCenter + regions_[iregion].phiHalfWidth); + } + std::cout << "Number of tracks per sector: " << NTRACKS_PER_SECTOR << std::endl + << "Number of bits per track: " << NBITS_PER_TRACK << std::endl + << "==============" << std::endl + << std::endl; + + // open the files for testing + TFile *rfile_ = TFile::Open(filename_root.c_str(), "READ"); + if (!rfile_) { + std::cerr << "ERROR::testDumpFile Cannot open '" << filename_root << "'" << std::endl; + return -7; + } + fwlite::Event rfileentry_(rfile_); + FILE *dfile_(fopen(filename_dump.c_str(), "rb")); + if (!dfile_) { + std::cerr << "ERROR::testDumpFile Cannot read '" << filename_dump << "'" << std::endl; + return -8; + } + std::ifstream cfile_(filename_coe); + if (!cfile_) { + std::cerr << "ERROR::testDumpFile Cannot read '" << filename_coe << "'" << std::endl; + return -9; + } + GotoLine(cfile_, 11); //Skip the header of the COE file + + TrackMap tracks_root, tracks_dump, tracks_coe; + + // run the tests for multiple events + for (int test = 1; test <= NTEST; ++test) { + if (test % REPORT_EVERY_N == 1) + std::cout << "Doing test " << test << " ... " << std::endl; + + tracks_root = get_tracks_from_root_file(rfileentry_, test - 1, test == 1); + tracks_dump = get_tracks_from_dump_file(dfile_, test == 1); + tracks_coe = get_tracks_from_coe_file(cfile_, test == 1); + + if (test % REPORT_EVERY_N == 1) + std::cout << "Comparing the ROOT tracks to the dump tracks in event " << test << " ... " << std::flush; + if (!compare_maps(tracks_root, tracks_dump)) + return -10; + if (test % REPORT_EVERY_N == 1) + std::cout << "DONE" << std::endl; + + if (test % REPORT_EVERY_N == 1) + std::cout << "Comparing the ROOT tracks to the coe tracks in event " << test << " ... " << std::flush; + if (!compare_maps(tracks_root, tracks_coe)) + return -11; + if (test % REPORT_EVERY_N == 1) + std::cout << "DONE" << std::endl << std::endl; + } + + std::cout << std::endl << "The dump and coe outputs match the ROOT outputs for all events!" << std::endl; + return 0; +} + +/* +USE: +g++ -I/uscms_data/d2/aperloff/YOURWORKINGAREA/TSABoard/slc7/CMSSW_10_6_0_pre4/src/L1Trigger/Phase2L1ParticleFlow/interface/ -O0 -g3 -Wall -std=c++0x -c -fmessage-length=0 testDumpFile.cpp +g++ -o testDumpFile testDumpFile.o +./testDumpFile trackerRegion_alltracks_sectors_1x18_TTbar_PU200.dump 18 + +scram b runtests +*/ diff --git a/L1Trigger/RPCTechnicalTrigger/interface/TTUTrackingAlg.h b/L1Trigger/RPCTechnicalTrigger/interface/TTUTrackingAlg.h index d9882cd6d20b7..6463de3278806 100644 --- a/L1Trigger/RPCTechnicalTrigger/interface/TTUTrackingAlg.h +++ b/L1Trigger/RPCTechnicalTrigger/interface/TTUTrackingAlg.h @@ -125,22 +125,6 @@ class TTUTrackingAlg : public TTULogic { std::vector> m_initialseeds; - struct CompareSeeds { - bool operator()(const Seed* a, const Seed* b) { - //std::cout << (*a).m_sectorId << " " << (*b).m_sectorId << " " - //<< (*a).m_stationId << " " << (*b).m_stationId << std::endl; - return ((*a).m_sectorId == (*b).m_sectorId) && ((*a).m_stationId == (*b).m_stationId); - } - }; - - struct SortBySector { - bool operator()(const Seed* a, const Seed* b) { return ((*a).m_sectorId <= (*b).m_sectorId); } - }; - - struct SortByLayer { - bool operator()(const Seed* a, const Seed* b) { return ((*a).m_stationId <= (*b).m_stationId); } - }; - inline void print(const std::vector& seeds) { std::vector::const_iterator itr; for (itr = seeds.begin(); itr != seeds.end(); ++itr) diff --git a/L1Trigger/RPCTechnicalTrigger/src/TTUTrackingAlg.cc b/L1Trigger/RPCTechnicalTrigger/src/TTUTrackingAlg.cc index 8fa9560cd7372..0554fc140ff0e 100644 --- a/L1Trigger/RPCTechnicalTrigger/src/TTUTrackingAlg.cc +++ b/L1Trigger/RPCTechnicalTrigger/src/TTUTrackingAlg.cc @@ -224,10 +224,16 @@ void TTUTrackingAlg::ghostBuster(Track* currentTrk) { std::vector::iterator seedItr; - std::sort(currentTrk->m_seeds.begin(), currentTrk->m_seeds.end(), SortBySector()); - std::sort(currentTrk->m_seeds.begin(), currentTrk->m_seeds.end(), SortByLayer()); + std::sort(currentTrk->m_seeds.begin(), currentTrk->m_seeds.end(), [](const Seed* a, const Seed* b) { + if (a->m_sectorId == b->m_sectorId) { + return a->m_stationId < b->m_stationId; + } + return a->m_sectorId < b->m_sectorId; + }); - seedItr = std::unique(currentTrk->m_seeds.begin(), currentTrk->m_seeds.end(), CompareSeeds()); + seedItr = std::unique(currentTrk->m_seeds.begin(), currentTrk->m_seeds.end(), [](const Seed* a, const Seed* b) { + return a->m_sectorId == b->m_sectorId and a->m_stationId == b->m_stationId; + }); currentTrk->m_seeds.resize(seedItr - currentTrk->m_seeds.begin()); diff --git a/L1Trigger/TrackFindingTMTT/plugins/TMTrackProducer.cc b/L1Trigger/TrackFindingTMTT/plugins/TMTrackProducer.cc index fa917b72eea94..44868419a3dcb 100644 --- a/L1Trigger/TrackFindingTMTT/plugins/TMTrackProducer.cc +++ b/L1Trigger/TrackFindingTMTT/plugins/TMTrackProducer.cc @@ -374,7 +374,7 @@ namespace tmtt { } } PrintL1trk() << "Number of tracks after HT = " << numHTtracks; - for (const auto p : mapFinalTracks) { + for (const auto& p : mapFinalTracks) { const string& fitName = p.first; const list fittedTracks = p.second; PrintL1trk() << "Number of tracks after " << fitName << " track helix fit = " << fittedTracks.size(); diff --git a/L1Trigger/TrackFindingTracklet/BuildFile.xml b/L1Trigger/TrackFindingTracklet/BuildFile.xml new file mode 100644 index 0000000000000..93be87c2f1d1e --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/BuildFile.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h b/L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h new file mode 100644 index 0000000000000..f6367108d9ca4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h @@ -0,0 +1,37 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_AllProjectionsMemory_h +#define L1Trigger_TrackFindingTracklet_interface_AllProjectionsMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include + +namespace trklet { + + class Settings; + class Tracklet; + + class AllProjectionsMemory : public MemoryBase { + public: + AllProjectionsMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~AllProjectionsMemory() override = default; + + void addTracklet(Tracklet* tracklet) { tracklets_.push_back(tracklet); } + + unsigned int nTracklets() const { return tracklets_.size(); } + + const Tracklet* getTracklet(unsigned int i) const { return tracklets_[i]; } + + void clean() override { tracklets_.clear(); } + + void writeAP(bool first); + + private: + std::vector tracklets_; + + int layer_; + int disk_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h b/L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h new file mode 100644 index 0000000000000..c34601997b069 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h @@ -0,0 +1,37 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_AllStubsMemory_h +#define L1Trigger_TrackFindingTracklet_interface_AllStubsMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + + class AllStubsMemory : public MemoryBase { + public: + AllStubsMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~AllStubsMemory() override = default; + + void addStub(const Stub* stub) { stubs_.push_back(stub); } + + unsigned int nStubs() const { return stubs_.size(); } + + const Stub* getStub(unsigned int i) const { return stubs_[i]; } + + void clean() override { stubs_.clear(); } + + void writeStubs(bool first); + + private: + std::vector stubs_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Cabling.h b/L1Trigger/TrackFindingTracklet/interface/Cabling.h new file mode 100644 index 0000000000000..f835b0d446234 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Cabling.h @@ -0,0 +1,39 @@ +// This class holds a list of stubs that are in a given layer and DCT region +#ifndef L1Trigger_TrackFindingTracklet_interface_Cabling_h +#define L1Trigger_TrackFindingTracklet_interface_Cabling_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/DTC.h" +#include "L1Trigger/TrackFindingTracklet/interface/DTCLink.h" + +#include +#include + +namespace trklet { + + class Settings; + + class Cabling { + public: + Cabling(std::string dtcconfig, std::string moduleconfig, Settings const& settings); + + ~Cabling() = default; + + const std::string& dtc(int layer, int ladder, int module) const; + + void addphi(const std::string& dtc, double phi, int layer, int module); + + void writephirange() const; + + std::vector DTCs() const; + + private: + Settings const& settings_; + std::vector links_; + std::map dtcranges_; + std::map dtcs_; + std::map > > modules_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h b/L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h new file mode 100644 index 0000000000000..96358051401c6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h @@ -0,0 +1,38 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_CandidateMatchMemory_h +#define L1Trigger_TrackFindingTracklet_interface_CandidateMatchMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + class Tracklet; + + class CandidateMatchMemory : public MemoryBase { + public: + CandidateMatchMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~CandidateMatchMemory() override = default; + + void addMatch(std::pair tracklet, const Stub* stub); + + unsigned int nMatches() const { return matches_.size(); } + + std::pair, const Stub*> getMatch(unsigned int i) { return matches_[i]; } + + void clean() override { matches_.clear(); } + + void writeCM(bool first); + + private: + std::vector, const Stub*> > matches_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h b/L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h new file mode 100644 index 0000000000000..50ed9aeae58f9 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h @@ -0,0 +1,63 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_CircularBuffer_h +#define L1Trigger_TrackFindingTracklet_interface_CircularBuffer_h + +#include +#include + +namespace trklet { + + template + class CircularBuffer { + public: + CircularBuffer(unsigned int nbits) { + size_ = 1 << nbits; + buffer_.resize(size_); + reset(); + } + + ~CircularBuffer() = default; + + void reset() { + rptr_ = 0; + wptr_ = 0; + } + + //Full if writer ptr incremented is same as read ptr + bool full() const { return ((wptr_ + 1) % size_) == rptr_; } + + //Almost full if writer ptr incremented by 1 or 2 is same as read ptr + bool almostfull() const { return (((wptr_ + 1) % size_) == rptr_) || (((wptr_ + 2) % size_) == rptr_); } + + //Empty buffer is write ptr is same as read ptr + bool empty() const { return wptr_ == rptr_; } + + T read() { + assert(!empty()); + unsigned int oldrptr = rptr_; + rptr_ = (rptr_ + 1) % size_; + return buffer_[oldrptr]; + } + + T peek() const { + assert(!empty()); + return buffer_[rptr_]; + } + + void store(T element) { + assert(!full()); + buffer_[wptr_++] = element; + wptr_ = wptr_ % size_; + } + + private: + std::vector buffer_; + + //buffer size + unsigned int size_; + + //read and write poiters into buffer + unsigned int rptr_; + unsigned int wptr_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h b/L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h new file mode 100644 index 0000000000000..41e64bd302f12 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h @@ -0,0 +1,34 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_CleanTrackMemory_h +#define L1Trigger_TrackFindingTracklet_interface_CleanTrackMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include + +namespace trklet { + + class Settings; + class Tracklet; + + class CleanTrackMemory : public MemoryBase { + public: + CleanTrackMemory(std::string name, Settings const& settings, unsigned int iSector, double phimin, double phimax); + + ~CleanTrackMemory() override = default; + + void addTrack(Tracklet* tracklet) { tracks_.push_back(tracklet); } + + unsigned int nTracks() const { return tracks_.size(); } + + void clean() override { tracks_.clear(); } + + void writeCT(bool first); + + private: + double phimin_; + double phimax_; + std::vector tracks_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DTC.h b/L1Trigger/TrackFindingTracklet/interface/DTC.h new file mode 100644 index 0000000000000..bbdf38c07636b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DTC.h @@ -0,0 +1,46 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_DTC_h +#define L1Trigger_TrackFindingTracklet_interface_DTC_h + +#include "L1Trigger/TrackFindingTracklet/interface/DTCLink.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +namespace trklet { + + class Stub; + class L1TStub; + + class DTC { + public: + DTC(std::string name = ""); + + ~DTC() = default; + + void setName(std::string name); + + void addSec(int sector); + + void addphi(double phi, unsigned int layerdisk); + + void addLink(double phimin, double phimax); + + int addStub(std::pair stub); + + unsigned int nLinks() const { return links_.size(); } + + const DTCLink& link(unsigned int i) const { return links_[i]; } + + void clean(); + + double min(unsigned int i) const { return phimin_[i]; } + double max(unsigned int i) const { return phimax_[i]; } + + private: + std::string name_; + std::vector links_; + std::vector sectors_; + + double phimin_[N_LAYER + N_DISK]; + double phimax_[N_LAYER + N_DISK]; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DTCLink.h b/L1Trigger/TrackFindingTracklet/interface/DTCLink.h new file mode 100644 index 0000000000000..d9f7a0c24bcf5 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DTCLink.h @@ -0,0 +1,34 @@ +// This class holds a list of stubs that are in a given layer and DCT region +#ifndef L1Trigger_TrackFindingTracklet_interface_DTCLink_h +#define L1Trigger_TrackFindingTracklet_interface_DTCLink_h + +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" + +namespace trklet { + + class DTCLink { + public: + DTCLink(double phimin, double phimax); + + ~DTCLink() = default; + + void addStub(std::pair stub); + + bool inRange(double phi, bool overlaplayer); + + unsigned int nStubs() const { return stubs_.size(); } + + Stub* getFPGAStub(unsigned int i) const { return stubs_[i].first; } + L1TStub* getL1TStub(unsigned int i) const { return stubs_[i].second; } + std::pair getStub(unsigned int i) const { return stubs_[i]; } + + void clean() { stubs_.clear(); } + + private: + double phimin_; + double phimax_; + std::vector > stubs_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DiskProjection.h b/L1Trigger/TrackFindingTracklet/interface/DiskProjection.h new file mode 100644 index 0000000000000..83784c5ea042b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DiskProjection.h @@ -0,0 +1,168 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_DiskProjection_h +#define L1Trigger_TrackFindingTracklet_interface_DiskProjection_h + +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include + +namespace trklet { + + class Settings; + + class DiskProjection { + public: + DiskProjection() { valid_ = false; } + + ~DiskProjection() = default; + + void init(Settings const& settings, + int projdisk, + double zproj, + int iphiproj, + int irproj, + int iphider, + int irder, + double phiproj, + double rproj, + double phiprojder, + double rprojder, + double phiprojapprox, + double rprojapprox, + double phiprojderapprox, + double rprojderapprox); + + bool valid() const { return valid_; } + + int projdisk() const { + assert(valid_); + return projdisk_; + }; + + double zproj() const { + assert(valid_); + return zproj_; + }; + + const FPGAWord& fpgaphiproj() const { + assert(valid_); + return fpgaphiproj_; + }; + + const FPGAWord& fpgarproj() const { + assert(valid_); + return fpgarproj_; + }; + + const FPGAWord& fpgaphiprojder() const { + assert(valid_); + return fpgaphiprojder_; + }; + + const FPGAWord& fpgarprojder() const { + assert(valid_); + return fpgarprojder_; + }; + + const FPGAWord& fpgaphiprojvm() const { + assert(valid_); + return fpgaphiprojvm_; + }; + + const FPGAWord& fpgarprojvm() const { + assert(valid_); + return fpgarprojvm_; + }; + + double phiproj() const { + assert(valid_); + return phiproj_; + }; + + const FPGAWord& fpgarbin1projvm() const { + assert(valid_); + return fpgarbin1projvm_; + }; + + const FPGAWord& fpgarbin2projvm() const { + assert(valid_); + return fpgarbin2projvm_; + }; + + const FPGAWord& fpgafinervm() const { + assert(valid_); + return fpgafinervm_; + }; + + double rproj() const { + assert(valid_); + return rproj_; + }; + + double phiprojder() const { + assert(valid_); + return phiprojder_; + }; + + double rprojder() const { + assert(valid_); + return rprojder_; + }; + + double phiprojapprox() const { + assert(valid_); + return phiprojapprox_; + }; + + double rprojapprox() const { + assert(valid_); + return rprojapprox_; + }; + + double phiprojderapprox() const { + assert(valid_); + return phiprojderapprox_; + }; + + double rprojderapprox() const { + assert(valid_); + return rprojderapprox_; + }; + + void setBendIndex(int bendindex) { fpgabendindex_.set(bendindex, 5, true, __LINE__, __FILE__); } + + const FPGAWord& getBendIndex() const { return fpgabendindex_; } + + protected: + bool valid_; + + int projdisk_; + + double zproj_; + + FPGAWord fpgaphiproj_; + FPGAWord fpgarproj_; + FPGAWord fpgaphiprojder_; + FPGAWord fpgarprojder_; + + FPGAWord fpgaphiprojvm_; + FPGAWord fpgarprojvm_; + + FPGAWord fpgarbin1projvm_; + FPGAWord fpgarbin2projvm_; + FPGAWord fpgafinervm_; + + FPGAWord fpgabendindex_; + + double phiproj_; + double rproj_; + double phiprojder_; + double rprojder_; + + double phiprojapprox_; + double rprojapprox_; + double phiprojderapprox_; + double rprojderapprox_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/DiskResidual.h b/L1Trigger/TrackFindingTracklet/interface/DiskResidual.h new file mode 100644 index 0000000000000..546410e5a78b7 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/DiskResidual.h @@ -0,0 +1,112 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_DiskResidual_h +#define L1Trigger_TrackFindingTracklet_interface_DiskResidual_h + +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include + +namespace trklet { + + class Settings; + class Stub; + + class DiskResidual { + public: + DiskResidual() { valid_ = false; } + + ~DiskResidual() = default; + + void init(Settings const& settings, + int disk, + int iphiresid, + int irresid, + int istubid, + double phiresid, + double rresid, + double phiresidapprox, + double rresidapprox, + double zstub, + double alpha, + FPGAWord ialpha, + const Stub* stubptr); + + bool valid() const { return valid_; } + + const FPGAWord& fpgaphiresid() const { + assert(valid_); + return fpgaphiresid_; + }; + + const FPGAWord& fpgarresid() const { + assert(valid_); + return fpgarresid_; + }; + + const FPGAWord& fpgastubid() const { + assert(valid_); + return fpgastubid_; + }; + + double phiresid() const { + assert(valid_); + return phiresid_; + }; + + double rresid() const { + assert(valid_); + return rresid_; + }; + + double phiresidapprox() const { + assert(valid_); + return phiresidapprox_; + }; + + double rresidapprox() const { + assert(valid_); + return rresidapprox_; + }; + + double zstub() const { + assert(valid_); + return zstub_; + }; + + double alpha() const { + assert(valid_); + return alpha_; + }; + + const FPGAWord& ialpha() const { + assert(valid_); + return ialpha_; + }; + + const Stub* stubptr() const { + assert(valid_); + return stubptr_; + }; + + protected: + bool valid_; + + int disk_; + + FPGAWord fpgaphiresid_; + FPGAWord fpgarresid_; + FPGAWord fpgastubid_; + + double phiresid_; + double rresid_; + + double phiresidapprox_; + double rresidapprox_; + + double zstub_; + double alpha_; + FPGAWord ialpha_; + const Stub* stubptr_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/FPGAWord.h b/L1Trigger/TrackFindingTracklet/interface/FPGAWord.h new file mode 100644 index 0000000000000..c67842fbe64c5 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/FPGAWord.h @@ -0,0 +1,37 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_FPGAWord_h +#define L1Trigger_TrackFindingTracklet_interface_FPGAWord_h + +#include +#include + +namespace trklet { + + class FPGAWord { + public: + FPGAWord(); + + FPGAWord(int value, int nbits, bool positive = true, int line = -1, const char* file = nullptr); + + ~FPGAWord() = default; + + void set(int value, int nbits, bool positive = true, int line = -1, const char* file = nullptr); + + std::string str() const; + + //return the nbits starting with the lsb. lsb=0 means the least significant bit + unsigned int bits(unsigned int lsb, unsigned int nbit) const; + + int value() const { return value_; } + int nbits() const { return nbits_; } + + bool atExtreme() const; + + bool operator==(const FPGAWord& other) const; + + private: + int value_{-1}; + int nbits_{-1}; + bool positive_{true}; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/FitTrack.h b/L1Trigger/TrackFindingTracklet/interface/FitTrack.h new file mode 100644 index 0000000000000..fb897ec1660bd --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/FitTrack.h @@ -0,0 +1,54 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_FitTrack_H +#define L1Trigger_TrackFindingTracklet_interface_FitTrack_H + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h" + +#include + +namespace trklet { + + class Settings; + class Globals; + class Stub; + class L1TStub; + + class FitTrack : public ProcessBase { + public: + FitTrack(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~FitTrack() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + + void addInput(MemoryBase* memory, std::string input) override; + + // used if USEHYBRID is not defined + void trackFitChisq(Tracklet* tracklet, std::vector&, std::vector>&); + + // used if USEHYBRID is defined + void trackFitKF(Tracklet* tracklet, + std::vector& trackstublist, + std::vector>& stubidslist); + + // used for propagating tracklet without fitting + void trackFitFake(Tracklet* tracklet, std::vector&, std::vector>&); + + std::vector orderedMatches(std::vector& fullmatch); + + void execute(); + + private: + std::vector seedtracklet_; + std::vector fullmatch1_; + std::vector fullmatch2_; + std::vector fullmatch3_; + std::vector fullmatch4_; + + TrackFitMemory* trackfit_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h b/L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h new file mode 100644 index 0000000000000..10215946939c5 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h @@ -0,0 +1,46 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_FullMatchMemory_h +#define L1Trigger_TrackFindingTracklet_interface_FullMatchMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + class Tracklet; + + class FullMatchMemory : public MemoryBase { + public: + FullMatchMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~FullMatchMemory() override = default; + + void addMatch(Tracklet* tracklet, const Stub* stub); + + unsigned int nMatches() const { return matches_.size(); } + + Tracklet* getTracklet(unsigned int i) { return matches_[i].first; } + + std::pair getMatch(unsigned int i) { return matches_[i]; } + + void clean() override { matches_.clear(); } + + void writeMC(bool first); + + int layer() const { return layer_; } + int disk() const { return disk_; } + + private: + std::vector > matches_; + + int layer_; + int disk_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Globals.h b/L1Trigger/TrackFindingTracklet/interface/Globals.h new file mode 100644 index 0000000000000..cbe4eb2b4c4c9 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Globals.h @@ -0,0 +1,116 @@ +// Globals: holds "global" variables such as the IMATH_TrackletCalculators +#ifndef L1Trigger_TrackFindingTracklet_interface_Globals_h +#define L1Trigger_TrackFindingTracklet_interface_Globals_h + +#include +#include +#include +#include +#include +#include +#include + +#ifdef USEHYBRID +#include "L1Trigger/TrackFindingTMTT/interface/KFParamsComb.h" +#include "L1Trigger/TrackFindingTMTT/interface/Settings.h" +#endif + +namespace trklet { + + class TETableBase; + class TrackDerTable; + class ProjectionRouterBendTable; + class SLHCEvent; + class HistBase; + class Settings; + class VMRouterPhiCorrTable; + struct imathGlobals; + class IMATH_TrackletCalculator; + class IMATH_TrackletCalculatorDisk; + class IMATH_TrackletCalculatorOverlap; + + class Globals { + public: + Globals(Settings const& settings); + + ~Globals(); + + SLHCEvent*& event() { return theEvent_; } + + HistBase*& histograms() { return theHistBase_; } + + TrackDerTable*& trackDerTable() { return trackDerTable_; } + + VMRouterPhiCorrTable*& phiCorr(unsigned int layer) { return thePhiCorr_[layer]; } + + ProjectionRouterBendTable*& projectionRouterBendTable() { return projectionRouterBendTable_; } + + std::map >& ILindex() { return ILindex_; } + + std::map& layerdiskmap() { return layerdiskmap_; } + + IMATH_TrackletCalculator* ITC_L1L2() { return ITC_L1L2_.get(); } + IMATH_TrackletCalculator* ITC_L2L3() { return ITC_L2L3_.get(); } + IMATH_TrackletCalculator* ITC_L3L4() { return ITC_L3L4_.get(); } + IMATH_TrackletCalculator* ITC_L5L6() { return ITC_L5L6_.get(); } + + IMATH_TrackletCalculatorDisk* ITC_F1F2() { return ITC_F1F2_.get(); } + IMATH_TrackletCalculatorDisk* ITC_F3F4() { return ITC_F3F4_.get(); } + IMATH_TrackletCalculatorDisk* ITC_B1B2() { return ITC_B1B2_.get(); } + IMATH_TrackletCalculatorDisk* ITC_B3B4() { return ITC_B3B4_.get(); } + + IMATH_TrackletCalculatorOverlap* ITC_L1F1() { return ITC_L1F1_.get(); } + IMATH_TrackletCalculatorOverlap* ITC_L1B1() { return ITC_L1B1_.get(); } + IMATH_TrackletCalculatorOverlap* ITC_L2F1() { return ITC_L2F1_.get(); } + IMATH_TrackletCalculatorOverlap* ITC_L2B1() { return ITC_L2B1_.get(); } + + std::ofstream& ofstream(std::string fname); + +#ifdef USEHYBRID + std::unique_ptr& tmttSettings() { return tmttSettings_; } + std::unique_ptr& tmttKFParamsComb() { return tmttKFParamsComb_; } +#endif + + private: + std::unordered_map ofstreams_; + + std::unique_ptr imathGlobals_; + + // tracklet calculators + std::unique_ptr ITC_L1L2_; + std::unique_ptr ITC_L2L3_; + std::unique_ptr ITC_L3L4_; + std::unique_ptr ITC_L5L6_; + + std::unique_ptr ITC_F1F2_; + std::unique_ptr ITC_F3F4_; + std::unique_ptr ITC_B1B2_; + std::unique_ptr ITC_B3B4_; + + std::unique_ptr ITC_L1F1_; + std::unique_ptr ITC_L2F1_; + std::unique_ptr ITC_L1B1_; + std::unique_ptr ITC_L2B1_; + + SLHCEvent* theEvent_{nullptr}; + + HistBase* theHistBase_{nullptr}; + + TrackDerTable* trackDerTable_{nullptr}; + + ProjectionRouterBendTable* projectionRouterBendTable_{nullptr}; + +#ifdef USEHYBRID + std::unique_ptr tmttSettings_; + std::unique_ptr tmttKFParamsComb_; +#endif + + std::array thePhiCorr_{{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}}; + + std::map > ILindex_; + + std::map layerdiskmap_; + }; +}; // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/HistBase.h b/L1Trigger/TrackFindingTracklet/interface/HistBase.h new file mode 100644 index 0000000000000..999d94a026da3 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/HistBase.h @@ -0,0 +1,54 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_HistBase_h +#define L1Trigger_TrackFindingTracklet_interface_HistBase_h + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include +#include +#include +#include +#include +#include + +namespace trklet { + class Globals; + + class HistBase { + public: + HistBase() {} + + virtual ~HistBase() = default; + + virtual void open() {} + virtual void close() {} + + virtual void bookLayerResidual() {} + virtual void bookDiskResidual() {} + virtual void bookTrackletParams() {} + virtual void bookSeedEff() {} + + virtual void FillLayerResidual(int, int, double, double, double, double, bool) {} + + virtual void FillDiskResidual(int, int, double, double, double, double, bool) {} + + //arguments are + // int seedIndex + // int iSector + // double irinv, rinv + // double iphi0, phi0 + // double ieta, eta + // double iz0, z0 + // int tp + virtual void fillTrackletParams( + Settings const&, Globals*, int, int, double, double, double, double, double, double, double, double, int) {} + + //int seedIndex + //double etaTP + //bool eff + virtual void fillSeedEff(int, double, bool) {} + + private: + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/HybridFit.h b/L1Trigger/TrackFindingTracklet/interface/HybridFit.h new file mode 100644 index 0000000000000..5ca9437e8189e --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/HybridFit.h @@ -0,0 +1,45 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_HybridFit_h +#define L1Trigger_TrackFindingTracklet_interface_HybridFit_h + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +#ifdef USEHYBRID +#include "DataFormats/L1TrackTrigger/interface/TTStub.h" +#include "DataFormats/L1TrackTrigger/interface/TTCluster.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTStubAssociationMap.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTClusterAssociationMap.h" +#include "L1Trigger/TrackFindingTMTT/interface/L1track3D.h" +#include "L1Trigger/TrackFindingTMTT/interface/Stub.h" +#include "L1Trigger/TrackFindingTMTT/interface/KFParamsComb.h" +#include "L1Trigger/TrackFindingTMTT/interface/Settings.h" +#include "L1Trigger/TrackFindingTMTT/interface/L1fittedTrack.h" +#include "L1Trigger/TrackFindingTMTT/interface/KFTrackletTrack.h" +#endif + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include + +namespace trklet { + + class Stub; + class L1TStub; + class Tracklet; + + class HybridFit { + public: + HybridFit(unsigned int iSector, Settings const& settings, Globals* globals); + + ~HybridFit() = default; + + void Fit(Tracklet* tracklet, std::vector& trackstublist); + + private: + unsigned int iSector_; + + Settings const& settings_; + Globals* globals_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h b/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h new file mode 100644 index 0000000000000..4a14ef1740ec8 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h @@ -0,0 +1,476 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_IMATH_TrackletCalculator_h +#define L1Trigger_TrackFindingTracklet_interface_IMATH_TrackletCalculator_h + +#include "Settings.h" +#include "imath.h" + +// +// Constants used: +// dphisector +// rmaxL6 +// zmaxD5 +// rmaxdisk +// kr, kphi1, kz +// +// rmean[], zmean[] + +namespace trklet { + class Globals; + + class IMATH_TrackletCalculator { + public: + IMATH_TrackletCalculator(Settings const& settings, imathGlobals* globals, int i1, int i2) + : settings_(settings), globals_(globals) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "============================================="; + char s[1024]; + snprintf(s, 1024, "IMATH Tracklet Calculator %i %i dphisector = %f", i1, i2, settings_.dphisector()); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, 1024, "rmaxL6 = %f, zmaxD5 = %f", settings_.rmax(5), settings_.zmax(4)); + edm::LogVerbatim("Tracklet") << s; + snprintf( + s, 1024, " stub Ks: kr, kphi1, kz = %g, %g, %g", settings_.kr(), settings_.kphi1(), settings_.kz()); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + " tracklet Ks: krinvpars, kphi0pars, ktpars, kzpars = %g, %g, %g, %g", + settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()), + settings_.kphi1() * pow(2, settings_.phi0_shift()), + settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()), + settings_.kz() * pow(2, settings_.z0_shift())); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + "layer proj Ks: kphiproj456, kphider, kzproj, kzder = %g, %g, %g, %g", + settings_.kphi1() * pow(2, settings_.SS_phiL_shift()), + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift()), + settings_.kz() * pow(2, settings_.PS_zL_shift()), + settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift())); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + " disk proj Ks: kphiprojdisk, kphiprojderdisk, krprojdisk, krprojderdisk = %g, %g, %g, %g", + settings_.kphi1() * pow(2, settings_.SS_phiD_shift()), + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift()), + settings_.kr() * pow(2, settings_.PS_rD_shift()), + settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift())); + edm::LogVerbatim("Tracklet") << s; + edm::LogVerbatim("Tracklet") << "============================================="; + + snprintf(s, 1024, "initializing 1/dr LUT %f %f", settings_.rmean(i1 - 1), settings_.rmean(i2 - 1)); + edm::LogVerbatim("Tracklet") << s; + } + + drinv.initLUT(settings_.rmean(i2 - 1) - settings_.rmean(i1 - 1)); + r1mean.set_fval(settings_.rmean(i1 - 1)); + r2mean.set_fval(settings_.rmean(i2 - 1)); + r12mean.set_fval(settings_.rmean(i1 - 1) + settings_.rmean(i2 - 1)); + + if (i1 == 1) + z0_final.add_cut(&z0_final_L1_cut); + else + z0_final.add_cut(&z0_final_cut); + + valid_phiL_0.add_cut(&t_layer_cut); + valid_phiL_1.add_cut(&t_layer_cut); + valid_phiL_2.add_cut(&t_layer_cut); + valid_phiL_3.add_cut(&t_layer_cut); + + valid_der_phiL.add_cut(&t_layer_cut); + + valid_zL_0.add_cut(&t_layer_cut); + valid_zL_1.add_cut(&t_layer_cut); + valid_zL_2.add_cut(&t_layer_cut); + valid_zL_3.add_cut(&t_layer_cut); + + valid_der_zL.add_cut(&t_layer_cut); + + valid_phiD_0.add_cut(&t_disk_cut_left); + valid_phiD_1.add_cut(&t_disk_cut_left); + valid_phiD_2.add_cut(&t_disk_cut_left); + valid_phiD_3.add_cut(&t_disk_cut_left); + valid_phiD_4.add_cut(&t_disk_cut_left); + + valid_der_phiD.add_cut(&t_disk_cut_left); + + valid_rD_0.add_cut(&t_disk_cut_left); + valid_rD_1.add_cut(&t_disk_cut_left); + valid_rD_2.add_cut(&t_disk_cut_left); + valid_rD_3.add_cut(&t_disk_cut_left); + valid_rD_4.add_cut(&t_disk_cut_left); + + valid_der_rD.add_cut(&t_disk_cut_left); + + valid_phiD_0.add_cut(&t_disk_cut_right); + valid_phiD_1.add_cut(&t_disk_cut_right); + valid_phiD_2.add_cut(&t_disk_cut_right); + valid_phiD_3.add_cut(&t_disk_cut_right); + valid_phiD_4.add_cut(&t_disk_cut_right); + + valid_der_phiD.add_cut(&t_disk_cut_right); + + valid_rD_0.add_cut(&t_disk_cut_right); + valid_rD_1.add_cut(&t_disk_cut_right); + valid_rD_2.add_cut(&t_disk_cut_right); + valid_rD_3.add_cut(&t_disk_cut_right); + valid_rD_4.add_cut(&t_disk_cut_right); + + valid_der_rD.add_cut(&t_disk_cut_right); + } + + ~IMATH_TrackletCalculator() = default; + + Settings const& settings_; + + imathGlobals* globals_; + + //max values + const double dz_max = 50.; + const double delta0_max = 0.005; + const double a2_max = 3.; + const double a2a_max = 0.1; + const double x6a_max = 0.02; + const double x6m_max = 2.; + const double x8_max = 1.; + const double x13_max = 300.; + const double x22_max = 0.3; + const double x23_max = 200.; + const double t_max = 4.; + const double z0_max = 20.; + const double der_phiD_max = 0.002; + const double t_disk_min = 1; + const double t_disk_max = 4; + const double t_layer_max = 2.5; + + //constants + VarParam plus1{globals_, "plus1", 1., 10}; + VarParam plus2{globals_, "plus2", 2., 10}; + VarParam minus1{globals_, "minus1", -1., 10}; + + VarParam r1mean{globals_, "r1mean", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarParam r2mean{globals_, "r2mean", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarParam r12mean{globals_, "r12mean", "Kr", 2 * settings_.rmax(trklet::N_DISK - 1), settings_.kr()}; + + //inputs + VarDef r1{globals_, "r1", "Kr", settings_.drmax(), settings_.kr()}; + VarDef r2{globals_, "r2", "Kr", settings_.drmax(), settings_.kr()}; + VarDef z1{globals_, "z1", "Kz", settings_.zlength(), settings_.kz()}; + VarDef z2{globals_, "z2", "Kz", settings_.zlength(), settings_.kz()}; + + //0.75 below comes from phi range for coordinate can be larger than for sector + VarDef phi1{globals_, "phi1", "Kphi", settings_.dphisector() / 0.75, settings_.kphi1()}; + VarDef phi2{globals_, "phi2", "Kphi", settings_.dphisector() / 0.75, settings_.kphi1()}; + + VarDef rproj0{globals_, "rproj0", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj1{globals_, "rproj1", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj2{globals_, "rproj2", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj3{globals_, "rproj3", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + + VarDef zproj0{globals_, "zproj0", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj1{globals_, "zproj1", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj2{globals_, "zproj2", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj3{globals_, "zproj3", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj4{globals_, "zproj4", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + + //calculations + + //tracklet + VarAdd r1abs{globals_, "r1abs", &r1, &r1mean, settings_.rmax(trklet::N_LAYER - 1)}; + VarAdd r2abs{globals_, "r2abs", &r2, &r2mean, settings_.rmax(trklet::N_LAYER - 1)}; + + VarSubtract dr{globals_, "dr", &r2, &r1}; + + //R LUT + VarInv drinv{globals_, "drinv", &dr, 0, 18, 24, 0, VarInv::mode::both}; + + VarSubtract dphi{globals_, "dphi", &phi2, &phi1, settings_.dphisector() / 4.}; + VarSubtract dz{globals_, "dz", &z2, &z1, dz_max}; + + VarMult delta0{globals_, "delta0", &dphi, &drinv, delta0_max}; + VarMult deltaZ{globals_, "deltaZ", &dz, &drinv}; + VarMult delta1{globals_, "delta1", &r1abs, &delta0}; + VarMult delta2{globals_, "delta2", &r2abs, &delta0}; + VarMult a2a{globals_, "a2a", &delta1, &delta2, a2a_max}; + VarNounits a2b{globals_, "a2b", &a2a}; + VarSubtract a2{globals_, "a2", &plus2, &a2b, a2_max}; + VarNeg a2n{globals_, "a2n", &a2}; + VarShift a{globals_, "a", &a2, 1}; + + VarAdd Rabs{globals_, "Rabs", &r1abs, &r2abs}; + VarTimesC R6{globals_, "R6", &Rabs, 1. / 6., 12}; + + VarMult x4{globals_, "x4", &R6, &delta0}; + VarMult x6a{globals_, "x6a", &delta2, &x4, 2 * x6a_max}; + VarNounits x6b{globals_, "x6b", &x6a}; + VarAdd x6m{globals_, "x6m", &minus1, &x6b, x6m_max}; + VarMult phi0a{globals_, "phi0a", &delta1, &x6m, settings_.dphisector()}; + + VarMult z0a{globals_, "z0a", &r1abs, &deltaZ, settings_.zlength()}; + VarMult z0b{globals_, "z0b", &z0a, &x6m, settings_.zlength()}; + + VarAdd phi0{globals_, "phi0", &phi1, &phi0a, 2 * settings_.dphisector()}; + VarMult rinv{globals_, "rinv", &a2n, &delta0, 2 * settings_.maxrinv()}; + VarMult t{globals_, "t", &a, &deltaZ, t_max}; + VarAdd z0{globals_, "z0", &z1, &z0b, 2 * z0_max}; + + VarAdjustK rinv_final{ + globals_, "rinv_final", &rinv, settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift())}; + VarAdjustK phi0_final{globals_, "phi0_final", &phi0, settings_.kphi1() * pow(2, settings_.phi0_shift())}; + VarAdjustKR t_final{globals_, "t_final", &t, settings_.kz() / settings_.kr() * pow(2, settings_.t_shift())}; + VarAdjustKR z0_final{globals_, "z0_final", &z0, settings_.kz() * pow(2, settings_.z0_shift())}; + + //projection to r + VarShift x2{globals_, "x2", &delta0, 1}; + + VarMult x1_0{globals_, "x1_0", &x2, &rproj0}; + VarMult x1_1{globals_, "x1_1", &x2, &rproj1}; + VarMult x1_2{globals_, "x1_2", &x2, &rproj2}; + VarMult x1_3{globals_, "x1_3", &x2, &rproj3}; + + VarMult x8_0{globals_, "x8_0", &x1_0, &a2n, x8_max}; + VarMult x8_1{globals_, "x8_1", &x1_1, &a2n, x8_max}; + VarMult x8_2{globals_, "x8_2", &x1_2, &a2n, x8_max}; + VarMult x8_3{globals_, "x8_3", &x1_3, &a2n, x8_max}; + + VarMult x12_0{globals_, "x12_0", &x8_0, &x8_0}; + VarMult x12_1{globals_, "x12_1", &x8_1, &x8_1}; + VarMult x12_2{globals_, "x12_2", &x8_2, &x8_2}; + VarMult x12_3{globals_, "x12_3", &x8_3, &x8_3}; + + VarNounits x12A_0{globals_, "x12A_0", &x12_0}; + VarNounits x12A_1{globals_, "x12A_1", &x12_1}; + VarNounits x12A_2{globals_, "x12A_2", &x12_2}; + VarNounits x12A_3{globals_, "x12A_3", &x12_3}; + + VarTimesC x20_0{globals_, "x20_0", &x12A_0, 1. / 6.}; + VarTimesC x20_1{globals_, "x20_1", &x12A_1, 1. / 6.}; + VarTimesC x20_2{globals_, "x20_2", &x12A_2, 1. / 6.}; + VarTimesC x20_3{globals_, "x20_3", &x12A_3, 1. / 6.}; + + VarAdd x10_0{globals_, "x10_0", &plus1, &x20_0}; + VarAdd x10_1{globals_, "x10_1", &plus1, &x20_1}; + VarAdd x10_2{globals_, "x10_2", &plus1, &x20_2}; + VarAdd x10_3{globals_, "x10_3", &plus1, &x20_3}; + + VarMult x22_0{globals_, "x22_0", &x8_0, &x10_0, 2 * x22_max}; + VarMult x22_1{globals_, "x22_1", &x8_1, &x10_1, 2 * x22_max}; + VarMult x22_2{globals_, "x22_2", &x8_2, &x10_2, 2 * x22_max}; + VarMult x22_3{globals_, "x22_3", &x8_3, &x10_3, 2 * x22_max}; + + VarSubtract phiL_0{globals_, "phiL_0", &phi0_final, &x22_0, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_1{globals_, "phiL_1", &phi0_final, &x22_1, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_2{globals_, "phiL_2", &phi0_final, &x22_2, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_3{globals_, "phiL_3", &phi0_final, &x22_3, -1, phi0_final.nbits() + 1}; + + VarShift x3{globals_, "x3", &rinv, 1}; + VarNeg der_phiL{globals_, "der_phiL", &x3}; + + VarAdjustK phiL_0_final{globals_, "phiL_0_final", &phiL_0, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_1_final{globals_, "phiL_1_final", &phiL_1, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_2_final{globals_, "phiL_2_final", &phiL_2, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_3_final{globals_, "phiL_3_final", &phiL_3, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + + VarAdjustK der_phiL_final{globals_, + "der_phiL_final", + &der_phiL, + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift())}; + + VarMult x11_0{globals_, "x11_0", &rproj0, &t}; + VarMult x11_1{globals_, "x11_1", &rproj1, &t}; + VarMult x11_2{globals_, "x11_2", &rproj2, &t}; + VarMult x11_3{globals_, "x11_3", &rproj3, &t}; + + VarMult x23_0{globals_, "x23_0", &x11_0, &x10_0, 2 * x23_max}; + VarMult x23_1{globals_, "x23_1", &x11_1, &x10_1, 2 * x23_max}; + VarMult x23_2{globals_, "x23_2", &x11_2, &x10_2, 2 * x23_max}; + VarMult x23_3{globals_, "x23_3", &x11_3, &x10_3, 2 * x23_max}; + + VarAdd zL_0{globals_, "zL_0", &z0, &x23_0}; + VarAdd zL_1{globals_, "zL_1", &z0, &x23_1}; + VarAdd zL_2{globals_, "zL_2", &z0, &x23_2}; + VarAdd zL_3{globals_, "zL_3", &z0, &x23_3}; + + VarAdjustKR zL_0_final{globals_, "zL_0_final", &zL_0, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustKR zL_1_final{globals_, "zL_1_final", &zL_1, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustKR zL_2_final{globals_, "zL_2_final", &zL_2, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustKR zL_3_final{globals_, "zL_3_final", &zL_3, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + + VarAdjustK der_zL_final{ + globals_, "der_zL_final", &t_final, settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift())}; + + //projection to z + // + VarInv invt{globals_, "invt", &t_final, 0., 18, 26, 1, VarInv::mode::both, 13}; + + VarMult x7{globals_, "x7", &x2, &a2}; + + VarSubtract x5_0{globals_, "x5_0", &zproj0, &z0}; + VarSubtract x5_1{globals_, "x5_1", &zproj1, &z0}; + VarSubtract x5_2{globals_, "x5_2", &zproj2, &z0}; + VarSubtract x5_3{globals_, "x5_3", &zproj3, &z0}; + VarSubtract x5_4{globals_, "x5_4", &zproj4, &z0}; + + VarMult x13_0{globals_, "x13_0", &x5_0, &invt, x13_max}; + VarMult x13_1{globals_, "x13_1", &x5_1, &invt, x13_max}; + VarMult x13_2{globals_, "x13_2", &x5_2, &invt, x13_max}; + VarMult x13_3{globals_, "x13_3", &x5_3, &invt, x13_max}; + VarMult x13_4{globals_, "x13_4", &x5_4, &invt, x13_max}; + + VarMult x25_0{globals_, "x25_0", &x13_0, &x7, 2 * settings_.dphisector()}; + VarMult x25_1{globals_, "x25_1", &x13_1, &x7, 2 * settings_.dphisector()}; + VarMult x25_2{globals_, "x25_2", &x13_2, &x7, 2 * settings_.dphisector()}; + VarMult x25_3{globals_, "x25_3", &x13_3, &x7, 2 * settings_.dphisector()}; + VarMult x25_4{globals_, "x25_4", &x13_4, &x7, 2 * settings_.dphisector()}; + + VarAdd phiD_0{globals_, "phiD_0", &phi0, &x25_0, 2 * settings_.dphisector()}; + VarAdd phiD_1{globals_, "phiD_1", &phi0, &x25_1, 2 * settings_.dphisector()}; + VarAdd phiD_2{globals_, "phiD_2", &phi0, &x25_2, 2 * settings_.dphisector()}; + VarAdd phiD_3{globals_, "phiD_3", &phi0, &x25_3, 2 * settings_.dphisector()}; + VarAdd phiD_4{globals_, "phiD_4", &phi0, &x25_4, 2 * settings_.dphisector()}; + + VarAdjustK phiD_0_final{globals_, "phiD_0_final", &phiD_0, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_1_final{globals_, "phiD_1_final", &phiD_1, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_2_final{globals_, "phiD_2_final", &phiD_2, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_3_final{globals_, "phiD_3_final", &phiD_3, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_4_final{globals_, "phiD_4_final", &phiD_4, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + + VarMult der_phiD{globals_, "der_phiD", &x7, &invt, 4 * der_phiD_max}; + + VarAdjustK der_phiD_final{globals_, + "der_phiD_final", + &der_phiD, + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift())}; + + VarMult x26_0{globals_, "x26_0", &x25_0, &x25_0}; + VarMult x26_1{globals_, "x26_1", &x25_1, &x25_1}; + VarMult x26_2{globals_, "x26_2", &x25_2, &x25_2}; + VarMult x26_3{globals_, "x26_3", &x25_3, &x25_3}; + VarMult x26_4{globals_, "x26_4", &x25_4, &x25_4}; + + VarNounits x26A_0{globals_, "x26A_0", &x26_0}; + VarNounits x26A_1{globals_, "x26A_1", &x26_1}; + VarNounits x26A_2{globals_, "x26A_2", &x26_2}; + VarNounits x26A_3{globals_, "x26A_3", &x26_3}; + VarNounits x26A_4{globals_, "x26A_4", &x26_4}; + + VarTimesC x9_0{globals_, "x9_0", &x26A_0, 1. / 6.}; + VarTimesC x9_1{globals_, "x9_1", &x26A_1, 1. / 6.}; + VarTimesC x9_2{globals_, "x9_2", &x26A_2, 1. / 6.}; + VarTimesC x9_3{globals_, "x9_3", &x26A_3, 1. / 6.}; + VarTimesC x9_4{globals_, "x9_4", &x26A_4, 1. / 6.}; + + VarSubtract x27m_0{globals_, "x27_0", &plus1, &x9_0}; + VarSubtract x27m_1{globals_, "x27_1", &plus1, &x9_1}; + VarSubtract x27m_2{globals_, "x27_2", &plus1, &x9_2}; + VarSubtract x27m_3{globals_, "x27_3", &plus1, &x9_3}; + VarSubtract x27m_4{globals_, "x27_4", &plus1, &x9_4}; + + VarMult rD_0{globals_, "rD_0", &x13_0, &x27m_0, 2 * settings_.rmaxdisk()}; + VarMult rD_1{globals_, "rD_1", &x13_1, &x27m_1, 2 * settings_.rmaxdisk()}; + VarMult rD_2{globals_, "rD_2", &x13_2, &x27m_2, 2 * settings_.rmaxdisk()}; + VarMult rD_3{globals_, "rD_3", &x13_3, &x27m_3, 2 * settings_.rmaxdisk()}; + VarMult rD_4{globals_, "rD_4", &x13_4, &x27m_4, 2 * settings_.rmaxdisk()}; + + VarAdjustK rD_0_final{globals_, "rD_0_final", &rD_0, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_1_final{globals_, "rD_1_final", &rD_1, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_2_final{globals_, "rD_2_final", &rD_2, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_3_final{globals_, "rD_3_final", &rD_3, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_4_final{globals_, "rD_4_final", &rD_4, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + + VarAdjustK der_rD_final{ + globals_, "der_rD_final", &invt, settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift())}; + + VarCut rinv_final_cut{globals_, &rinv_final, -settings_.rinvcut(), settings_.rinvcut()}; + // the following two are not associated with any variable yet; this is done + // in the constructor of this class since it depends on the layer + VarCut z0_final_L1_cut{globals_, -settings_.z0cut(), settings_.z0cut()}; + VarCut z0_final_cut{globals_, -1.5 * settings_.z0cut(), 1.5 * settings_.z0cut()}; + + VarCut r1abs_cut{globals_, &r1abs, -settings_.rmax(5), settings_.rmax(5)}; + VarCut r2abs_cut{globals_, &r2abs, -settings_.rmax(5), settings_.rmax(5)}; + VarCut dphi_cut{globals_, &dphi, -settings_.dphisector() / 4., settings_.dphisector() / 4.}; + VarCut dz_cut{globals_, &dz, -dz_max, dz_max}; + VarCut delta0_cut{globals_, &delta0, -delta0_max, delta0_max}; + VarCut a2a_cut{globals_, &a2a, -a2a_max, a2a_max}; + VarCut a2_cut{globals_, &a2, -a2_max, a2_max}; + VarCut x6a_cut{globals_, &x6a, -x6a_max, x6a_max}; + VarCut x6m_cut{globals_, &x6m, -x6m_max, x6m_max}; + VarCut phi0a_cut{globals_, &phi0a, -settings_.dphisector(), settings_.dphisector()}; + VarCut z0a_cut{globals_, &z0a, (-1) * settings_.zlength(), settings_.zlength()}; + VarCut phi0_cut{globals_, &phi0, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut rinv_cut{globals_, &rinv, -settings_.maxrinv(), settings_.maxrinv()}; + VarCut t_cut{globals_, &t, -t_max, t_max}; + VarCut z0_cut{globals_, &z0, -z0_max, z0_max}; + VarCut x8_0_cut{globals_, &x8_0, -x8_max, x8_max}; + VarCut x8_1_cut{globals_, &x8_1, -x8_max, x8_max}; + VarCut x8_2_cut{globals_, &x8_2, -x8_max, x8_max}; + VarCut x8_3_cut{globals_, &x8_3, -x8_max, x8_max}; + VarCut x22_0_cut{globals_, &x22_0, -x22_max, x22_max}; + VarCut x22_1_cut{globals_, &x22_1, -x22_max, x22_max}; + VarCut x22_2_cut{globals_, &x22_2, -x22_max, x22_max}; + VarCut x22_3_cut{globals_, &x22_3, -x22_max, x22_max}; + VarCut x23_0_cut{globals_, &x23_0, -x23_max, x23_max}; + VarCut x23_1_cut{globals_, &x23_1, -x23_max, x23_max}; + VarCut x23_2_cut{globals_, &x23_2, -x23_max, x23_max}; + VarCut x23_3_cut{globals_, &x23_3, -x23_max, x23_max}; + VarCut x13_0_cut{globals_, &x13_0, -x13_max, x13_max}; + VarCut x13_1_cut{globals_, &x13_1, -x13_max, x13_max}; + VarCut x13_2_cut{globals_, &x13_2, -x13_max, x13_max}; + VarCut x13_3_cut{globals_, &x13_3, -x13_max, x13_max}; + VarCut x13_4_cut{globals_, &x13_4, -x13_max, x13_max}; + VarCut x25_0_cut{globals_, &x25_0, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_1_cut{globals_, &x25_1, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_2_cut{globals_, &x25_2, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_3_cut{globals_, &x25_3, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_4_cut{globals_, &x25_4, -settings_.dphisector(), settings_.dphisector()}; + VarCut phiD_0_cut{globals_, &phiD_0, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_1_cut{globals_, &phiD_1, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_2_cut{globals_, &phiD_2, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_3_cut{globals_, &phiD_3, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_4_cut{globals_, &phiD_4, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut der_phiD_cut{globals_, &der_phiD, -der_phiD_max, der_phiD_max}; + VarCut rD_0_cut{globals_, &rD_0, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_1_cut{globals_, &rD_1, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_2_cut{globals_, &rD_2, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_3_cut{globals_, &rD_3, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_4_cut{globals_, &rD_4, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + + VarCut t_disk_cut_left{globals_, &t, -t_disk_max, -t_disk_min}; + VarCut t_disk_cut_right{globals_, &t, t_disk_min, t_disk_max}; + VarCut t_layer_cut{globals_, &t, -t_layer_max, t_layer_max}; + + // the following flags are used to apply the cuts in TrackletCalculator + // and in the output Verilog + VarFlag valid_trackpar{globals_, "valid_trackpar", &rinv_final, &phi0_final, &t_final, &z0_final}; + + VarFlag valid_phiL_0{globals_, "valid_phiL_0", &phiL_0_final}; + VarFlag valid_phiL_1{globals_, "valid_phiL_1", &phiL_1_final}; + VarFlag valid_phiL_2{globals_, "valid_phiL_2", &phiL_2_final}; + VarFlag valid_phiL_3{globals_, "valid_phiL_3", &phiL_3_final}; + + VarFlag valid_zL_0{globals_, "valid_zL_0", &zL_0_final}; + VarFlag valid_zL_1{globals_, "valid_zL_1", &zL_1_final}; + VarFlag valid_zL_2{globals_, "valid_zL_2", &zL_2_final}; + VarFlag valid_zL_3{globals_, "valid_zL_3", &zL_3_final}; + + VarFlag valid_der_phiL{globals_, "valid_der_phiL", &der_phiL_final}; + VarFlag valid_der_zL{globals_, "valid_der_zL", &der_zL_final}; + + VarFlag valid_phiD_0{globals_, "valid_phiD_0", &phiD_0_final}; + VarFlag valid_phiD_1{globals_, "valid_phiD_1", &phiD_1_final}; + VarFlag valid_phiD_2{globals_, "valid_phiD_2", &phiD_2_final}; + VarFlag valid_phiD_3{globals_, "valid_phiD_3", &phiD_3_final}; + VarFlag valid_phiD_4{globals_, "valid_phiD_4", &phiD_4_final}; + + VarFlag valid_rD_0{globals_, "valid_rD_0", &rD_0_final}; + VarFlag valid_rD_1{globals_, "valid_rD_1", &rD_1_final}; + VarFlag valid_rD_2{globals_, "valid_rD_2", &rD_2_final}; + VarFlag valid_rD_3{globals_, "valid_rD_3", &rD_3_final}; + VarFlag valid_rD_4{globals_, "valid_rD_4", &rD_4_final}; + + VarFlag valid_der_phiD{globals_, "valid_der_phiD", &der_phiD_final}; + VarFlag valid_der_rD{globals_, "valid_der_rD", &der_rD_final}; + }; +}; // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorDisk.h b/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorDisk.h new file mode 100644 index 0000000000000..351521be5ccea --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorDisk.h @@ -0,0 +1,406 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_IMATH_TrackletCalculatorDisk_h +#define L1Trigger_TrackFindingTracklet_interface_IMATH_TrackletCalculatorDisk_h + +#include "Settings.h" +#include "imath.h" + +// +// Constants used: +// dphisector +// rmaxL6 +// zmaxD5 +// rmaxdisk +// kr, kphi1, kz +// +// rmean[], zmean[] + +namespace trklet { + + class IMATH_TrackletCalculatorDisk { + public: + IMATH_TrackletCalculatorDisk(Settings const& settings, imathGlobals* globals, int i1, int i2) + : settings_(settings), globals_(globals) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "============================================="; + char s[1024]; + snprintf(s, 1024, "IMATH Tracklet Calculator for Disk %i %i dphisector = %f", i1, i2, settings_.dphisector()); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, 1024, "rmaxL6 = %f, zmaxD5 = %f", settings_.rmax(5), settings_.zmax(4)); + edm::LogVerbatim("Tracklet") << s; + snprintf( + s, 1024, " stub Ks: kr, kphi1, kz = %g, %g, %g", settings_.kr(), settings_.kphi1(), settings_.kz()); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + " tracklet Ks: krinvpars, kphi0pars, ktpars, kzpars = %g, %g, %g, %g", + settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()), + settings_.kphi1() * pow(2, settings_.phi0_shift()), + settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()), + settings_.kz() * pow(2, settings_.z0_shift())); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + "layer proj Ks: kphiproj456, kphider, kzproj, kzder = %g, %g, %g, %g", + settings_.kphi1() * pow(2, settings_.SS_phiL_shift()), + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift()), + settings_.kz() * pow(2, settings_.PS_zL_shift()), + settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift())); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + " disk proj Ks: kphiprojdisk, kphiprojderdisk, krprojdisk, krprojderdisk = %g, %g, %g, %g", + settings_.kphi1() * pow(2, settings_.SS_phiD_shift()), + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift()), + settings_.kr() * pow(2, settings_.PS_rD_shift()), + settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift())); + edm::LogVerbatim("Tracklet") << s; + edm::LogVerbatim("Tracklet") << "============================================="; + } + + z1mean.set_fval(settings_.zmean(abs(i1) - 1)); + z2mean.set_fval(settings_.zmean(abs(i2) - 1)); + + if (i2 < 0) { //t is negative + z1mean.set_fval(-settings_.zmean(abs(i1) - 1)); + z2mean.set_fval(-settings_.zmean(abs(i2) - 1)); + invt.set_mode(VarInv::mode::neg); + invt.initLUT(0.); + } + + valid_phiL_0.add_cut(&t_layer_cut); + valid_phiL_1.add_cut(&t_layer_cut); + valid_phiL_2.add_cut(&t_layer_cut); + + valid_der_phiL.add_cut(&t_layer_cut); + + valid_zL_0.add_cut(&t_layer_cut); + valid_zL_1.add_cut(&t_layer_cut); + valid_zL_2.add_cut(&t_layer_cut); + + valid_der_zL.add_cut(&t_layer_cut); + + valid_phiD_0.add_cut(&t_disk_cut_left); + valid_phiD_1.add_cut(&t_disk_cut_left); + valid_phiD_2.add_cut(&t_disk_cut_left); + + valid_der_phiD.add_cut(&t_disk_cut_left); + + valid_rD_0.add_cut(&t_disk_cut_left); + valid_rD_1.add_cut(&t_disk_cut_left); + valid_rD_2.add_cut(&t_disk_cut_left); + + valid_der_rD.add_cut(&t_disk_cut_left); + + valid_phiD_0.add_cut(&t_disk_cut_right); + valid_phiD_1.add_cut(&t_disk_cut_right); + valid_phiD_2.add_cut(&t_disk_cut_right); + + valid_der_phiD.add_cut(&t_disk_cut_right); + + valid_rD_0.add_cut(&t_disk_cut_right); + valid_rD_1.add_cut(&t_disk_cut_right); + valid_rD_2.add_cut(&t_disk_cut_right); + + valid_der_rD.add_cut(&t_disk_cut_right); + } + + ~IMATH_TrackletCalculatorDisk() = default; + + Settings const& settings_; + + imathGlobals* globals_; + + //max values + const double dz_max = 50.; + const double dr_max = 20.; + const double delta0_max = 0.005; + const double a2_max = 3.; + const double a2a_max = 0.1; + const double x6a_max = 0.02; + const double x6m_max = 2.; + const double x8_max = 1.; + const double x13_max = 300.; + const double x22_max = 0.3; + const double x23_max = 200.; + const double deltaZ_max = 8.; + const double der_phiD_max = 0.002; + const double t_max = 7.9; + const double t_disk_min = 1.; + const double t_disk_max = 7.9; + const double t_layer_max = 2.5; + const double z0_max = 20.; + const double z0a_max = 205.; + + //constants + VarParam plus2{globals_, "plus2", 2., 10}; + VarParam plus1{globals_, "plus1", 1., 10}; + VarParam minus1{globals_, "minus1", -1, 10}; + + VarParam z1mean{globals_, "z1mean", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarParam z2mean{globals_, "z2mean", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + + //inputs + VarDef r1{globals_, "r1", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef r2{globals_, "r2", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef z1{globals_, "z1", "Kz", settings_.dzmax(), settings_.kz()}; + VarDef z2{globals_, "z2", "Kz", settings_.dzmax(), settings_.kz()}; + + VarDef phi1{globals_, "phi1", "Kphi", settings_.dphisector() / 0.75, settings_.kphi1()}; + VarDef phi2{globals_, "phi2", "Kphi", settings_.dphisector() / 0.75, settings_.kphi1()}; + + VarDef rproj0{globals_, "rproj0", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj1{globals_, "rproj1", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj2{globals_, "rproj2", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + + VarDef zproj0{globals_, "zproj0", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj1{globals_, "zproj1", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj2{globals_, "zproj2", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + + //calculations + + //tracklet + VarAdd z1abs{globals_, "z1abs", &z1, &z1mean, settings_.zmax(trklet::N_DISK - 1)}; + VarAdd z2abs{globals_, "z2abs", &z2, &z2mean, settings_.zmax(trklet::N_DISK - 1)}; + + VarSubtract dr{globals_, "dr", &r2, &r1, dr_max}; + + //R LUT + VarInv drinv{globals_, "drinv", &dr, 0, 18, 23, 0, VarInv::mode::pos}; + + VarSubtract dphi{globals_, "dphi", &phi2, &phi1, settings_.dphisector() / 4.}; + VarSubtract dz{globals_, "dz", &z2abs, &z1abs, dz_max}; + + VarMult delta0{globals_, "delta0", &dphi, &drinv, 4 * delta0_max}; + VarMult deltaZ{globals_, "deltaZ", &dz, &drinv, deltaZ_max}; + VarMult delta1{globals_, "delta1", &r1, &delta0}; + VarMult delta2{globals_, "delta2", &r2, &delta0}; + VarMult a2a{globals_, "a2a", &delta1, &delta2, 4 * a2a_max}; + VarNounits a2b{globals_, "a2b", &a2a}; + VarSubtract a2{globals_, "a2", &plus2, &a2b, 3.}; + VarNeg a2n{globals_, "a2n", &a2}; + VarShift a{globals_, "a", &a2, 1}; + + VarAdd Rabs{globals_, "Rabs", &r1, &r2}; + VarTimesC R6{globals_, "R6", &Rabs, 1. / 6., 12}; + + VarMult x4{globals_, "x4", &R6, &delta0}; + VarMult x6a{globals_, "x6a", &delta2, &x4, 8 * x6a_max}; + VarNounits x6b{globals_, "x6b", &x6a}; + VarAdd x6m{globals_, "x6m", &minus1, &x6b, 2.}; + VarMult phi0a{globals_, "phi0a", &delta1, &x6m, settings_.dphisector()}; + + VarMult z0a{globals_, "z0a", &r1, &deltaZ, 2 * settings_.zlength()}; + VarMult z0b{globals_, "z0b", &z0a, &x6m, 2 * settings_.zlength()}; + + VarAdd phi0{globals_, "phi0", &phi1, &phi0a, 2 * settings_.dphisector()}; + VarMult rinv{globals_, "rinv", &a2n, &delta0, 4 * settings_.maxrinv()}; + VarMult t{globals_, "t", &a, &deltaZ, 2 * t_max}; + VarAdd z0{globals_, "z0", &z1abs, &z0b, 2 * z0_max}; + + VarAdjustK rinv_final{ + globals_, "rinv_final", &rinv, settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift())}; + VarAdjustK phi0_final{globals_, "phi0_final", &phi0, settings_.kphi1() * pow(2, settings_.phi0_shift())}; + VarAdjustK t_final{globals_, "t_final", &t, settings_.kz() / settings_.kr() * pow(2, settings_.t_shift())}; + VarAdjustK z0_final{globals_, "z0_final", &z0, settings_.kz() * pow(2, settings_.z0_shift())}; + + //projection to r + VarShift x2{globals_, "x2", &delta0, 1}; + + VarMult x1_0{globals_, "x1_0", &x2, &rproj0}; + VarMult x1_1{globals_, "x1_1", &x2, &rproj1}; + VarMult x1_2{globals_, "x1_2", &x2, &rproj2}; + + VarMult x8_0{globals_, "x8_0", &x1_0, &a2n, x8_max}; + VarMult x8_1{globals_, "x8_1", &x1_1, &a2n, x8_max}; + VarMult x8_2{globals_, "x8_2", &x1_2, &a2n, x8_max}; + + VarMult x12_0{globals_, "x12_0", &x8_0, &x8_0}; + VarMult x12_1{globals_, "x12_1", &x8_1, &x8_1}; + VarMult x12_2{globals_, "x12_2", &x8_2, &x8_2}; + + VarNounits x12A_0{globals_, "x12A_0", &x12_0}; + VarNounits x12A_1{globals_, "x12A_1", &x12_1}; + VarNounits x12A_2{globals_, "x12A_2", &x12_2}; + + VarTimesC x20_0{globals_, "x20_0", &x12A_0, 1. / 6.}; + VarTimesC x20_1{globals_, "x20_1", &x12A_1, 1. / 6.}; + VarTimesC x20_2{globals_, "x20_2", &x12A_2, 1. / 6.}; + + VarAdd x10_0{globals_, "x10_0", &plus1, &x20_0}; + VarAdd x10_1{globals_, "x10_1", &plus1, &x20_1}; + VarAdd x10_2{globals_, "x10_2", &plus1, &x20_2}; + + VarMult x22_0{globals_, "x22_0", &x8_0, &x10_0, 2 * x22_max}; + VarMult x22_1{globals_, "x22_1", &x8_1, &x10_1, 2 * x22_max}; + VarMult x22_2{globals_, "x22_2", &x8_2, &x10_2, 2 * x22_max}; + + VarSubtract phiL_0{globals_, "phiL_0", &phi0_final, &x22_0, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_1{globals_, "phiL_1", &phi0_final, &x22_1, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_2{globals_, "phiL_2", &phi0_final, &x22_2, -1, phi0_final.nbits() + 1}; + + VarShift x3{globals_, "x3", &rinv, 1}; + VarNeg der_phiL{globals_, "der_phiL", &x3}; + + VarAdjustK phiL_0_final{globals_, "phiL_0_final", &phiL_0, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_1_final{globals_, "phiL_1_final", &phiL_1, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_2_final{globals_, "phiL_2_final", &phiL_2, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + + VarAdjustK der_phiL_final{globals_, + "der_phiL_final", + &der_phiL, + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift())}; + + VarMult x11_0{globals_, "x11_0", &rproj0, &t}; + VarMult x11_1{globals_, "x11_1", &rproj1, &t}; + VarMult x11_2{globals_, "x11_2", &rproj2, &t}; + + VarMult x23_0{globals_, "x23_0", &x11_0, &x10_0, 4 * x23_max}; + VarMult x23_1{globals_, "x23_1", &x11_1, &x10_1, 4 * x23_max}; + VarMult x23_2{globals_, "x23_2", &x11_2, &x10_2, 4 * x23_max}; + + VarAdd zL_0{globals_, "zL_0", &z0, &x23_0}; + VarAdd zL_1{globals_, "zL_1", &z0, &x23_1}; + VarAdd zL_2{globals_, "zL_2", &z0, &x23_2}; + + VarAdjustK zL_0_final{globals_, "zL_0_final", &zL_0, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustK zL_1_final{globals_, "zL_1_final", &zL_1, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustK zL_2_final{globals_, "zL_2_final", &zL_2, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + + VarAdjustK der_zL_final{ + globals_, "der_zL_final", &t_final, settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift())}; + + //projection to z + VarInv invt{globals_, "invt", &t_final, 0., 18, 26, 1, VarInv::mode::pos, 13}; + + VarMult x7{globals_, "x7", &x2, &a2}; + + VarSubtract x5_0{globals_, "x5_0", &zproj0, &z0}; + VarSubtract x5_1{globals_, "x5_1", &zproj1, &z0}; + VarSubtract x5_2{globals_, "x5_2", &zproj2, &z0}; + + VarMult x13_0{globals_, "x13_0", &x5_0, &invt, x13_max}; + VarMult x13_1{globals_, "x13_1", &x5_1, &invt, x13_max}; + VarMult x13_2{globals_, "x13_2", &x5_2, &invt, x13_max}; + + VarMult x25_0{globals_, "x25_0", &x13_0, &x7, settings_.dphisector()}; + VarMult x25_1{globals_, "x25_1", &x13_1, &x7, settings_.dphisector()}; + VarMult x25_2{globals_, "x25_2", &x13_2, &x7, settings_.dphisector()}; + + VarAdd phiD_0{globals_, "phiD_0", &phi0, &x25_0, 2 * settings_.dphisector()}; + VarAdd phiD_1{globals_, "phiD_1", &phi0, &x25_1, 2 * settings_.dphisector()}; + VarAdd phiD_2{globals_, "phiD_2", &phi0, &x25_2, 2 * settings_.dphisector()}; + + VarAdjustK phiD_0_final{globals_, "phiD_0_final", &phiD_0, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_1_final{globals_, "phiD_1_final", &phiD_1, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_2_final{globals_, "phiD_2_final", &phiD_2, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + + VarMult der_phiD{globals_, "der_phiD", &x7, &invt, 2 * der_phiD_max}; + + VarAdjustK der_phiD_final{globals_, + "der_phiD_final", + &der_phiD, + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift())}; + + VarMult x26_0{globals_, "x26_0", &x25_0, &x25_0}; + VarMult x26_1{globals_, "x26_1", &x25_1, &x25_1}; + VarMult x26_2{globals_, "x26_2", &x25_2, &x25_2}; + + VarNounits x26A_0{globals_, "x26A_0", &x26_0}; + VarNounits x26A_1{globals_, "x26A_1", &x26_1}; + VarNounits x26A_2{globals_, "x26A_2", &x26_2}; + + VarTimesC x9_0{globals_, "x9_0", &x26A_0, 1. / 6.}; + VarTimesC x9_1{globals_, "x9_1", &x26A_1, 1. / 6.}; + VarTimesC x9_2{globals_, "x9_2", &x26A_2, 1. / 6.}; + + VarSubtract x27_0{globals_, "x27_0", &plus1, &x9_0}; + VarSubtract x27_1{globals_, "x27_1", &plus1, &x9_1}; + VarSubtract x27_2{globals_, "x27_2", &plus1, &x9_2}; + + VarMult rD_0{globals_, "rD_0", &x13_0, &x27_0, settings_.rmaxdisk()}; + VarMult rD_1{globals_, "rD_1", &x13_1, &x27_1, settings_.rmaxdisk()}; + VarMult rD_2{globals_, "rD_2", &x13_2, &x27_2, settings_.rmaxdisk()}; + + VarAdjustK rD_0_final{globals_, "rD_0_final", &rD_0, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_1_final{globals_, "rD_1_final", &rD_1, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_2_final{globals_, "rD_2_final", &rD_2, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + + VarAdjustK der_rD_final{ + globals_, "der_rD_final", &invt, settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift())}; + + VarCut rinv_final_cut{globals_, &rinv_final, -settings_.rinvcut(), settings_.rinvcut()}; + VarCut z0_final_cut{globals_, &z0_final, -settings_.z0cut(), settings_.z0cut()}; + + VarCut z1abs_cut{globals_, &z1abs, -settings_.zmax(4), settings_.zmax(4)}; + VarCut z2abs_cut{globals_, &z2abs, -settings_.zmax(4), settings_.zmax(4)}; + VarCut dr_cut{globals_, &dr, -dr_max, dr_max}; + VarCut dphi_cut{globals_, &dphi, -settings_.dphisector() / 4., settings_.dphisector() / 4.}; + VarCut dz_cut{globals_, &dz, -dz_max, dz_max}; + VarCut delta0_cut{globals_, &delta0, -delta0_max, delta0_max}; + VarCut deltaZ_cut{globals_, &deltaZ, -deltaZ_max, deltaZ_max}; + VarCut a2a_cut{globals_, &a2a, -a2a_max, a2a_max}; + VarCut a2_cut{globals_, &a2, -a2_max, a2_max}; + VarCut x6a_cut{globals_, &x6a, -x6a_max, x6a_max}; + VarCut x6m_cut{globals_, &x6m, -x6m_max, x6m_max}; + VarCut phi0a_cut{globals_, &phi0a, -settings_.dphisector(), settings_.dphisector()}; + VarCut z0a_cut{globals_, &z0a, -z0a_max, z0a_max}; + VarCut phi0_cut{globals_, &phi0, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut rinv_cut{globals_, &rinv, -settings_.maxrinv(), settings_.maxrinv()}; + VarCut t_cut{globals_, &t, -t_max, t_max}; + VarCut z0_cut{globals_, &z0, -z0_max, z0_max}; + VarCut x8_0_cut{globals_, &x8_0, -x8_max, x8_max}; + VarCut x8_1_cut{globals_, &x8_1, -x8_max, x8_max}; + VarCut x8_2_cut{globals_, &x8_2, -x8_max, x8_max}; + VarCut x22_0_cut{globals_, &x22_0, -x22_max, x22_max}; + VarCut x22_1_cut{globals_, &x22_1, -x22_max, x22_max}; + VarCut x22_2_cut{globals_, &x22_2, -x22_max, x22_max}; + VarCut x23_0_cut{globals_, &x23_0, -x23_max, x23_max}; + VarCut x23_1_cut{globals_, &x23_1, -x23_max, x23_max}; + VarCut x23_2_cut{globals_, &x23_2, -x23_max, x23_max}; + VarCut x13_0_cut{globals_, &x13_0, -x13_max, x13_max}; + VarCut x13_1_cut{globals_, &x13_1, -x13_max, x13_max}; + VarCut x13_2_cut{globals_, &x13_2, -x13_max, x13_max}; + VarCut x25_0_cut{globals_, &x25_0, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_1_cut{globals_, &x25_1, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_2_cut{globals_, &x25_2, -settings_.dphisector(), settings_.dphisector()}; + VarCut phiD_0_cut{globals_, &phiD_0, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_1_cut{globals_, &phiD_1, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_2_cut{globals_, &phiD_2, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut der_phiD_cut{globals_, &der_phiD, -der_phiD_max, der_phiD_max}; + VarCut rD_0_cut{globals_, &rD_0, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_1_cut{globals_, &rD_1, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_2_cut{globals_, &rD_2, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + + VarCut t_disk_cut_left{globals_, &t, -t_disk_max, -t_disk_min}; + VarCut t_disk_cut_right{globals_, &t, t_disk_min, t_disk_max}; + VarCut t_layer_cut{globals_, &t, -t_layer_max, t_layer_max}; + + // the following flags are used to apply the cuts in TrackletCalculator + // and in the output Verilog + VarFlag valid_trackpar{globals_, "valid_trackpar", &rinv_final, &phi0_final, &t_final, &z0_final}; + + VarFlag valid_phiL_0{globals_, "valid_phiL_0", &phiL_0_final}; + VarFlag valid_phiL_1{globals_, "valid_phiL_1", &phiL_1_final}; + VarFlag valid_phiL_2{globals_, "valid_phiL_2", &phiL_2_final}; + + VarFlag valid_zL_0{globals_, "valid_zL_0", &zL_0_final}; + VarFlag valid_zL_1{globals_, "valid_zL_1", &zL_1_final}; + VarFlag valid_zL_2{globals_, "valid_zL_2", &zL_2_final}; + + VarFlag valid_der_phiL{globals_, "valid_der_phiL", &der_phiL_final}; + VarFlag valid_der_zL{globals_, "valid_der_zL", &der_zL_final}; + + VarFlag valid_phiD_0{globals_, "valid_phiD_0", &phiD_0_final}; + VarFlag valid_phiD_1{globals_, "valid_phiD_1", &phiD_1_final}; + VarFlag valid_phiD_2{globals_, "valid_phiD_2", &phiD_2_final}; + + VarFlag valid_rD_0{globals_, "valid_rD_0", &rD_0_final}; + VarFlag valid_rD_1{globals_, "valid_rD_1", &rD_1_final}; + VarFlag valid_rD_2{globals_, "valid_rD_2", &rD_2_final}; + + VarFlag valid_der_phiD{globals_, "valid_der_phiD", &der_phiD_final}; + VarFlag valid_der_rD{globals_, "valid_der_rD", &der_rD_final}; + }; +}; // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorOverlap.h b/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorOverlap.h new file mode 100644 index 0000000000000..835ada017311a --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorOverlap.h @@ -0,0 +1,429 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_IMATH_TrackletCalculatorOverlap_h +#define L1Trigger_TrackFindingTracklet_interface_IMATH_TrackletCalculatorOverlap_h + +#include "Settings.h" +#include "imath.h" + +// +// Constants used: +// dphisector +// rmaxL6 +// zmaxD5 +// rmaxdisk +// kr, kphi1, kz +// +// rmean[], zmean[] + +namespace trklet { + + class IMATH_TrackletCalculatorOverlap { + public: + IMATH_TrackletCalculatorOverlap(Settings const& settings, imathGlobals* globals, int i1, int i2) + : settings_(settings), globals_(globals) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "============================================="; + char s[1024]; + snprintf( + s, 1024, "IMATH Tracklet Calculator for Overlap %i %i dphisector = %f", i1, i2, settings_.dphisector()); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, 1024, "rmaxL6 = %f, zmaxD5 = %f", settings_.rmax(5), settings_.zmax(4)); + edm::LogVerbatim("Tracklet") << s; + snprintf( + s, 1024, " stub Ks: kr, kphi1, kz = %g, %g, %g", settings_.kr(), settings_.kphi1(), settings_.kz()); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + " tracklet Ks: krinvpars, kphi0pars, ktpars, kzpars = %g, %g, %g, %g", + settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()), + settings_.kphi1() * pow(2, settings_.phi0_shift()), + settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()), + settings_.kz() * pow(2, settings_.z0_shift())); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + "layer proj Ks: kphiproj456, kphider, kzproj, kzder = %g, %g, %g, %g", + settings_.kphi1() * pow(2, settings_.SS_phiL_shift()), + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift()), + settings_.kz() * pow(2, settings_.PS_zL_shift()), + settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift())); + edm::LogVerbatim("Tracklet") << s; + snprintf(s, + 1024, + " disk proj Ks: kphiprojdisk, kphiprojderdisk, krprojdisk, krprojderdisk = %g, %g, %g, %g", + settings_.kphi1() * pow(2, settings_.SS_phiD_shift()), + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift()), + settings_.kr() * pow(2, settings_.PS_rD_shift()), + settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift())); + edm::LogVerbatim("Tracklet") << s; + edm::LogVerbatim("Tracklet") << "============================================="; + } + + r1mean.set_fval(settings_.rmean(i1 - 1)); + z2mean.set_fval(settings_.zmean(abs(i2) - 1)); + + if (i2 < 0) { //t is negative + z2mean.set_fval(-settings_.zmean(abs(i2) - 1)); + invt.set_mode(VarInv::mode::neg); + invt.initLUT(0.); + } + + valid_phiL_0.add_cut(&t_layer_cut); + valid_phiL_1.add_cut(&t_layer_cut); + valid_phiL_2.add_cut(&t_layer_cut); + + valid_der_phiL.add_cut(&t_layer_cut); + + valid_zL_0.add_cut(&t_layer_cut); + valid_zL_1.add_cut(&t_layer_cut); + valid_zL_2.add_cut(&t_layer_cut); + + valid_der_zL.add_cut(&t_layer_cut); + + valid_phiD_0.add_cut(&t_disk_cut_left); + valid_phiD_1.add_cut(&t_disk_cut_left); + valid_phiD_2.add_cut(&t_disk_cut_left); + valid_phiD_3.add_cut(&t_disk_cut_left); + + valid_der_phiD.add_cut(&t_disk_cut_left); + + valid_rD_0.add_cut(&t_disk_cut_left); + valid_rD_1.add_cut(&t_disk_cut_left); + valid_rD_2.add_cut(&t_disk_cut_left); + valid_rD_3.add_cut(&t_disk_cut_left); + + valid_der_rD.add_cut(&t_disk_cut_left); + + valid_phiD_0.add_cut(&t_disk_cut_right); + valid_phiD_1.add_cut(&t_disk_cut_right); + valid_phiD_2.add_cut(&t_disk_cut_right); + valid_phiD_3.add_cut(&t_disk_cut_right); + + valid_der_phiD.add_cut(&t_disk_cut_right); + + valid_rD_0.add_cut(&t_disk_cut_right); + valid_rD_1.add_cut(&t_disk_cut_right); + valid_rD_2.add_cut(&t_disk_cut_right); + valid_rD_3.add_cut(&t_disk_cut_right); + + valid_der_rD.add_cut(&t_disk_cut_right); + } + + ~IMATH_TrackletCalculatorOverlap() = default; + + Settings const& settings_; + + imathGlobals* globals_; + + //max values + const double dz_max = 50.; + const double dr_max = 40; + const double delta0_max = 0.005; + const double a2_max = 3.; + const double a2a_max = 0.1; + const double x6a_max = 0.02; + const double x6m_max = 2.; + const double x8_max = 1.; + const double x13_max = 300.; + const double x22_max = 0.3; + const double x23_max = 200.; + const double deltaZ_max = 8.; + const double der_phiD_max = 0.002; + const double t_max = 7.9; + const double t_disk_min = 1.; + const double t_disk_max = 7.9; + const double t_layer_max = 2.5; + const double z0_max = 20.; + + // constants + // + VarParam plus2{globals_, "plus2", 2., 10}; + VarParam plus1{globals_, "plus1", 1., 10}; + VarParam minus1{globals_, "minus1", -1, 10}; + // + // + VarParam r1mean{globals_, "r1mean", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarParam z2mean{globals_, "z2mean", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + + //inputs + VarDef r1{globals_, "r1", "Kr", settings_.drmax(), settings_.kr()}; + VarDef r2{globals_, "r2", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef z1{globals_, "z1", "Kz", settings_.zlength(), settings_.kz()}; + VarDef z2{globals_, "z2", "Kz", settings_.dzmax(), settings_.kz()}; + + VarDef phi1{globals_, "phi1", "Kphi", settings_.dphisector() / 0.75, settings_.kphi1()}; + VarDef phi2{globals_, "phi2", "Kphi", settings_.dphisector() / 0.75, settings_.kphi1()}; + + VarDef rproj0{globals_, "rproj0", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj1{globals_, "rproj1", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + VarDef rproj2{globals_, "rproj2", "Kr", settings_.rmax(trklet::N_LAYER - 1), settings_.kr()}; + + VarDef zproj0{globals_, "zproj0", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj1{globals_, "zproj1", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj2{globals_, "zproj2", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + VarDef zproj3{globals_, "zproj3", "Kz", settings_.zmax(trklet::N_DISK - 1), settings_.kz()}; + + //calculations + + //tracklet + VarAdd r1abs{globals_, "r1abs", &r1, &r1mean, settings_.rmax(trklet::N_LAYER - 1)}; + VarAdd z2abs{globals_, "z2abs", &z2, &z2mean, settings_.zmax(trklet::N_DISK - 1)}; + + VarSubtract dr{globals_, "dr", &r2, &r1abs, dr_max}; + + //R LUT + VarInv drinv{globals_, "drinv", &dr, 0, 18, 23, 0, VarInv::mode::pos}; + + VarSubtract dphi{globals_, "dphi", &phi2, &phi1, settings_.dphisector() / 4.}; + VarSubtract dz{globals_, "dz", &z2abs, &z1, 2 * dz_max}; + + VarMult delta0{globals_, "delta0", &dphi, &drinv, 8 * delta0_max}; + VarMult deltaZ{globals_, "deltaZ", &dz, &drinv, deltaZ_max}; + VarMult delta1{globals_, "delta1", &r1abs, &delta0}; + VarMult delta2{globals_, "delta2", &r2, &delta0}; + VarMult a2a{globals_, "a2a", &delta1, &delta2, 32 * a2a_max}; + VarNounits a2b{globals_, "a2b", &a2a}; + VarSubtract a2{globals_, "a2", &plus2, &a2b, a2_max}; + VarNeg a2n{globals_, "a2n", &a2}; + VarShift a{globals_, "a", &a2, 1}; + + VarAdd Rabs{globals_, "Rabs", &r1abs, &r2}; + VarTimesC R6{globals_, "R6", &Rabs, 1. / 6., 12}; + + VarMult x4{globals_, "x4", &R6, &delta0}; + VarMult x6a{globals_, "x6a", &delta2, &x4, 32 * x6a_max}; + VarNounits x6b{globals_, "x6b", &x6a}; + VarAdd x6m{globals_, "x6m", &minus1, &x6b, x6m_max}; + VarMult phi0a{globals_, "phi0a", &delta1, &x6m, settings_.dphisector()}; + + VarMult z0a{globals_, "z0a", &r1abs, &deltaZ, 2 * settings_.zlength()}; + VarMult z0b{globals_, "z0b", &z0a, &x6m, 2 * settings_.zlength()}; + + VarAdd phi0{globals_, "phi0", &phi1, &phi0a, 2 * settings_.dphisector()}; + VarMult rinv{globals_, "rinv", &a2n, &delta0, 8 * settings_.maxrinv()}; + VarMult t{globals_, "t", &a, &deltaZ, t_max}; + VarAdd z0{globals_, "z0", &z1, &z0b, 16 * z0_max}; + + VarAdjustK rinv_final{ + globals_, "rinv_final", &rinv, settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift())}; + VarAdjustK phi0_final{globals_, "phi0_final", &phi0, settings_.kphi1() * pow(2, settings_.phi0_shift())}; + VarAdjustK t_final{globals_, "t_final", &t, settings_.kz() / settings_.kr() * pow(2, settings_.t_shift())}; + VarAdjustK z0_final{globals_, "z0_final", &z0, settings_.kz() * pow(2, settings_.z0_shift())}; + + //projection to r + VarShift x2{globals_, "x2", &delta0, 1}; + + VarMult x1_0{globals_, "x1_0", &x2, &rproj0}; + VarMult x1_1{globals_, "x1_1", &x2, &rproj1}; + VarMult x1_2{globals_, "x1_2", &x2, &rproj2}; + + VarMult x8_0{globals_, "x8_0", &x1_0, &a2n, 2 * x8_max}; + VarMult x8_1{globals_, "x8_1", &x1_1, &a2n, 2 * x8_max}; + VarMult x8_2{globals_, "x8_2", &x1_2, &a2n, 2 * x8_max}; + + VarMult x12_0{globals_, "x12_0", &x8_0, &x8_0}; + VarMult x12_1{globals_, "x12_1", &x8_1, &x8_1}; + VarMult x12_2{globals_, "x12_2", &x8_2, &x8_2}; + + VarNounits x12A_0{globals_, "x12A_0", &x12_0}; + VarNounits x12A_1{globals_, "x12A_1", &x12_1}; + VarNounits x12A_2{globals_, "x12A_2", &x12_2}; + + VarTimesC x20_0{globals_, "x20_0", &x12A_0, 1. / 6.}; + VarTimesC x20_1{globals_, "x20_1", &x12A_1, 1. / 6.}; + VarTimesC x20_2{globals_, "x20_2", &x12A_2, 1. / 6.}; + + VarAdd x10_0{globals_, "x10_0", &plus1, &x20_0}; + VarAdd x10_1{globals_, "x10_1", &plus1, &x20_1}; + VarAdd x10_2{globals_, "x10_2", &plus1, &x20_2}; + + VarMult x22_0{globals_, "x22_0", &x8_0, &x10_0, 4 * x22_max}; + VarMult x22_1{globals_, "x22_1", &x8_1, &x10_1, 4 * x22_max}; + VarMult x22_2{globals_, "x22_2", &x8_2, &x10_2, 4 * x22_max}; + + VarSubtract phiL_0{globals_, "phiL_0", &phi0_final, &x22_0, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_1{globals_, "phiL_1", &phi0_final, &x22_1, -1, phi0_final.nbits() + 1}; + VarSubtract phiL_2{globals_, "phiL_2", &phi0_final, &x22_2, -1, phi0_final.nbits() + 1}; + + VarShift x3{globals_, "x3", &rinv, 1}; + VarNeg der_phiL{globals_, "der_phiL", &x3}; + + VarAdjustK phiL_0_final{globals_, "phiL_0_final", &phiL_0, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_1_final{globals_, "phiL_1_final", &phiL_1, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + VarAdjustK phiL_2_final{globals_, "phiL_2_final", &phiL_2, settings_.kphi1() * pow(2, settings_.SS_phiL_shift())}; + + VarAdjustK der_phiL_final{globals_, + "der_phiL_final", + &der_phiL, + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift())}; + + VarMult x11_0{globals_, "x11_0", &rproj0, &t}; + VarMult x11_1{globals_, "x11_1", &rproj1, &t}; + VarMult x11_2{globals_, "x11_2", &rproj2, &t}; + + VarMult x23_0{globals_, "x23_0", &x11_0, &x10_0, 2 * x23_max}; + VarMult x23_1{globals_, "x23_1", &x11_1, &x10_1, 2 * x23_max}; + VarMult x23_2{globals_, "x23_2", &x11_2, &x10_2, 2 * x23_max}; + + VarAdd zL_0{globals_, "zL_0", &z0, &x23_0}; + VarAdd zL_1{globals_, "zL_1", &z0, &x23_1}; + VarAdd zL_2{globals_, "zL_2", &z0, &x23_2}; + + VarAdjustK zL_0_final{globals_, "zL_0_final", &zL_0, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustK zL_1_final{globals_, "zL_1_final", &zL_1, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + VarAdjustK zL_2_final{globals_, "zL_2_final", &zL_2, settings_.kz() * pow(2, settings_.PS_zL_shift())}; + + VarAdjustK der_zL_final{ + globals_, "der_zL_final", &t_final, settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift())}; + + //projection to z + VarInv invt{globals_, "invt", &t_final, 0., 18, 26, 1, VarInv::mode::pos, 13}; + + VarMult x7{globals_, "x7", &x2, &a2}; + + VarSubtract x5_0{globals_, "x5_0", &zproj0, &z0}; + VarSubtract x5_1{globals_, "x5_1", &zproj1, &z0}; + VarSubtract x5_2{globals_, "x5_2", &zproj2, &z0}; + VarSubtract x5_3{globals_, "x5_3", &zproj3, &z0}; + + VarMult x13_0{globals_, "x13_0", &x5_0, &invt, x13_max}; + VarMult x13_1{globals_, "x13_1", &x5_1, &invt, x13_max}; + VarMult x13_2{globals_, "x13_2", &x5_2, &invt, x13_max}; + VarMult x13_3{globals_, "x13_3", &x5_3, &invt, x13_max}; + + VarMult x25_0{globals_, "x25_0", &x13_0, &x7, 4 * settings_.dphisector()}; + VarMult x25_1{globals_, "x25_1", &x13_1, &x7, 4 * settings_.dphisector()}; + VarMult x25_2{globals_, "x25_2", &x13_2, &x7, 4 * settings_.dphisector()}; + VarMult x25_3{globals_, "x25_3", &x13_3, &x7, 4 * settings_.dphisector()}; + + VarAdd phiD_0{globals_, "phiD_0", &phi0, &x25_0, 4 * settings_.dphisector()}; + VarAdd phiD_1{globals_, "phiD_1", &phi0, &x25_1, 4 * settings_.dphisector()}; + VarAdd phiD_2{globals_, "phiD_2", &phi0, &x25_2, 4 * settings_.dphisector()}; + VarAdd phiD_3{globals_, "phiD_3", &phi0, &x25_3, 4 * settings_.dphisector()}; + + VarAdjustK phiD_0_final{globals_, "phiD_0_final", &phiD_0, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_1_final{globals_, "phiD_1_final", &phiD_1, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_2_final{globals_, "phiD_2_final", &phiD_2, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + VarAdjustK phiD_3_final{globals_, "phiD_3_final", &phiD_3, settings_.kphi1() * pow(2, settings_.SS_phiD_shift())}; + + VarMult der_phiD{globals_, "der_phiD", &x7, &invt, 8 * der_phiD_max}; + + VarAdjustK der_phiD_final{globals_, + "der_phiD_final", + &der_phiD, + settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift())}; + + VarMult x26_0{globals_, "x26_0", &x25_0, &x25_0}; + VarMult x26_1{globals_, "x26_1", &x25_1, &x25_1}; + VarMult x26_2{globals_, "x26_2", &x25_2, &x25_2}; + VarMult x26_3{globals_, "x26_3", &x25_3, &x25_3}; + + VarNounits x26A_0{globals_, "x26A_0", &x26_0}; + VarNounits x26A_1{globals_, "x26A_1", &x26_1}; + VarNounits x26A_2{globals_, "x26A_2", &x26_2}; + VarNounits x26A_3{globals_, "x26A_3", &x26_3}; + + VarTimesC x9_0{globals_, "x9_0", &x26A_0, 1. / 6.}; + VarTimesC x9_1{globals_, "x9_1", &x26A_1, 1. / 6.}; + VarTimesC x9_2{globals_, "x9_2", &x26A_2, 1. / 6.}; + VarTimesC x9_3{globals_, "x9_3", &x26A_3, 1. / 6.}; + + VarSubtract x27m_0{globals_, "x27_0", &plus1, &x9_0}; + VarSubtract x27m_1{globals_, "x27_1", &plus1, &x9_1}; + VarSubtract x27m_2{globals_, "x27_2", &plus1, &x9_2}; + VarSubtract x27m_3{globals_, "x27_3", &plus1, &x9_3}; + + VarMult rD_0{globals_, "rD_0", &x13_0, &x27m_0, settings_.rmaxdisk()}; + VarMult rD_1{globals_, "rD_1", &x13_1, &x27m_1, settings_.rmaxdisk()}; + VarMult rD_2{globals_, "rD_2", &x13_2, &x27m_2, settings_.rmaxdisk()}; + VarMult rD_3{globals_, "rD_3", &x13_3, &x27m_3, settings_.rmaxdisk()}; + + VarAdjustK rD_0_final{globals_, "rD_0_final", &rD_0, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_1_final{globals_, "rD_1_final", &rD_1, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_2_final{globals_, "rD_2_final", &rD_2, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + VarAdjustK rD_3_final{globals_, "rD_3_final", &rD_3, settings_.kr() * pow(2, settings_.PS_rD_shift())}; + + VarAdjustK der_rD_final{ + globals_, "der_rD_final", &invt, settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift())}; + + VarCut t_final_cut{globals_, &t_final, -10, 10}; + VarCut rinv_final_cut{globals_, &rinv_final, -settings_.rinvcut(), settings_.rinvcut()}; + VarCut z0_final_cut{globals_, &z0_final, -settings_.z0cut(), settings_.z0cut()}; + + VarCut r1abs_cut{globals_, &r1abs, -settings_.rmax(5), settings_.rmax(5)}; + VarCut z2abs_cut{globals_, &z2abs, -settings_.zmax(4), settings_.zmax(4)}; + VarCut dr_cut{globals_, &dr, -dr_max, dr_max}; + VarCut dphi_cut{globals_, &dphi, -settings_.dphisector() / 4., settings_.dphisector() / 4.}; + VarCut dz_cut{globals_, &dz, -dz_max, dz_max}; + VarCut delta0_cut{globals_, &delta0, -delta0_max, delta0_max}; + VarCut deltaZ_cut{globals_, &deltaZ, -deltaZ_max, deltaZ_max}; + VarCut a2a_cut{globals_, &a2a, -a2a_max, a2a_max}; + VarCut a2_cut{globals_, &a2, -a2_max, a2_max}; + VarCut x6a_cut{globals_, &x6a, -x6a_max, x6a_max}; + VarCut x6m_cut{globals_, &x6m, -x6m_max, x6m_max}; + VarCut phi0a_cut{globals_, &phi0a, -settings_.dphisector(), settings_.dphisector()}; + VarCut z0a_cut{globals_, &z0a, -2 * settings_.zlength(), 2 * settings_.zlength()}; + VarCut phi0_cut{globals_, &phi0, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut rinv_cut{globals_, &rinv, -settings_.maxrinv(), settings_.maxrinv()}; + VarCut t_cut{globals_, &t, -t_max, t_max}; + VarCut z0_cut{globals_, &z0, -z0_max, z0_max}; + VarCut x8_0_cut{globals_, &x8_0, -x8_max, x8_max}; + VarCut x8_1_cut{globals_, &x8_1, -x8_max, x8_max}; + VarCut x8_2_cut{globals_, &x8_2, -x8_max, x8_max}; + VarCut x22_0_cut{globals_, &x22_0, -x22_max, x22_max}; + VarCut x22_1_cut{globals_, &x22_1, -x22_max, x22_max}; + VarCut x22_2_cut{globals_, &x22_2, -x22_max, x22_max}; + VarCut x23_0_cut{globals_, &x23_0, -x23_max, x23_max}; + VarCut x23_1_cut{globals_, &x23_1, -x23_max, x23_max}; + VarCut x23_2_cut{globals_, &x23_2, -x23_max, x23_max}; + VarCut x13_0_cut{globals_, &x13_0, -x13_max, x13_max}; + VarCut x13_1_cut{globals_, &x13_1, -x13_max, x13_max}; + VarCut x13_2_cut{globals_, &x13_2, -x13_max, x13_max}; + VarCut x13_3_cut{globals_, &x13_3, -x13_max, x13_max}; + VarCut x25_0_cut{globals_, &x25_0, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_1_cut{globals_, &x25_1, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_2_cut{globals_, &x25_2, -settings_.dphisector(), settings_.dphisector()}; + VarCut x25_3_cut{globals_, &x25_3, -settings_.dphisector(), settings_.dphisector()}; + VarCut phiD_0_cut{globals_, &phiD_0, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_1_cut{globals_, &phiD_1, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_2_cut{globals_, &phiD_2, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut phiD_3_cut{globals_, &phiD_3, -2 * settings_.dphisector(), 2 * settings_.dphisector()}; + VarCut der_phiD_cut{globals_, &der_phiD, -der_phiD_max, der_phiD_max}; + VarCut rD_0_cut{globals_, &rD_0, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_1_cut{globals_, &rD_1, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_2_cut{globals_, &rD_2, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + VarCut rD_3_cut{globals_, &rD_3, -settings_.rmaxdisk(), settings_.rmaxdisk()}; + + VarCut t_disk_cut_left{globals_, &t, -t_disk_max, -t_disk_min}; + VarCut t_disk_cut_right{globals_, &t, t_disk_min, t_disk_max}; + VarCut t_layer_cut{globals_, &t, -t_layer_max, t_layer_max}; + + // the following flags are used to apply the cuts in TrackletCalculator + // and in the output Verilog + VarFlag valid_trackpar{globals_, "valid_trackpar", &rinv_final, &phi0_final, &t_final, &z0_final}; + + VarFlag valid_phiL_0{globals_, "valid_phiL_0", &phiL_0_final}; + VarFlag valid_phiL_1{globals_, "valid_phiL_1", &phiL_1_final}; + VarFlag valid_phiL_2{globals_, "valid_phiL_2", &phiL_2_final}; + + VarFlag valid_zL_0{globals_, "valid_zL_0", &zL_0_final}; + VarFlag valid_zL_1{globals_, "valid_zL_1", &zL_1_final}; + VarFlag valid_zL_2{globals_, "valid_zL_2", &zL_2_final}; + + VarFlag valid_der_phiL{globals_, "valid_der_phiL", &der_phiL_final}; + VarFlag valid_der_zL{globals_, "valid_der_zL", &der_zL_final}; + + VarFlag valid_phiD_0{globals_, "valid_phiD_0", &phiD_0_final}; + VarFlag valid_phiD_1{globals_, "valid_phiD_1", &phiD_1_final}; + VarFlag valid_phiD_2{globals_, "valid_phiD_2", &phiD_2_final}; + VarFlag valid_phiD_3{globals_, "valid_phiD_3", &phiD_3_final}; + + VarFlag valid_rD_0{globals_, "valid_rD_0", &rD_0_final}; + VarFlag valid_rD_1{globals_, "valid_rD_1", &rD_1_final}; + VarFlag valid_rD_2{globals_, "valid_rD_2", &rD_2_final}; + VarFlag valid_rD_3{globals_, "valid_rD_3", &rD_3_final}; + + VarFlag valid_der_phiD{globals_, "valid_der_phiD", &der_phiD_final}; + VarFlag valid_der_rD{globals_, "valid_der_rD", &der_rD_final}; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h b/L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h new file mode 100644 index 0000000000000..02879946c8eb7 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h @@ -0,0 +1,41 @@ +// This class holds a list of stubs for an input link. +// This modules 'owns' the pointers to the stubs. All subsequent modules that handles stubs uses a pointer to the original stored here. +#ifndef L1Trigger_TrackFindingTracklet_interface_InputLinkMemory_h +#define L1Trigger_TrackFindingTracklet_interface_InputLinkMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include + +namespace trklet { + + class Settings; + class Globals; + class Stub; + class L1TStub; + class VMRouterPhiCorrTable; + + class InputLinkMemory : public MemoryBase { + public: + InputLinkMemory(std::string name, Settings const& settings, unsigned int iSector, double, double); + + ~InputLinkMemory() override = default; + + bool addStub(Settings const& settings, Globals* globals, L1TStub& al1stub, Stub& stub, std::string dtc); + + unsigned int nStubs() const { return stubs_.size(); } + + Stub* getStub(unsigned int i) { return stubs_[i]; } + + void writeStubs(bool first); + + void clean() override; + + private: + std::vector stubs_; + int phiregion_; + unsigned int layerdisk_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/L1TStub.h b/L1Trigger/TrackFindingTracklet/interface/L1TStub.h new file mode 100644 index 0000000000000..2010d1eae1bb6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/L1TStub.h @@ -0,0 +1,122 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_L1TStub_h +#define L1Trigger_TrackFindingTracklet_interface_L1TStub_h + +#include +#include +#include +#include +#include + +namespace trklet { + + class L1TStub { + public: + L1TStub(); + L1TStub(int eventid, + std::vector tps, + int iphi, + int iz, + int layer, + int ladder, + int module, + int strip, + double x, + double y, + double z, + double sigmax, + double sigmaz, + double pt, + double bend, + int isPSmodule, + int isFlipped); + + ~L1TStub() = default; + + void write(std::ofstream& out); + void write(std::ostream& out); + + double diphi(); + + double iphiouter(); + + double diz(); + + unsigned int layer() const { return layer_; } + int disk() const { + if (z_ < 0.0) { + return -module_; + } + return module_; + } + unsigned int ladder() const { return ladder_; } + unsigned int module() const { return module_; } + + double x() const { return x_; } + double y() const { return y_; } + double z() const { return z_; } + double r() const { return std::hypot(x_, y_); } + double pt() const { return pt_; } + double r2() const { return x_ * x_ + y_ * y_; } + double bend() const { return bend_; } + + double phi() const { return atan2(y_, x_); } + + unsigned int iphi() const { return iphi_; } + unsigned int iz() const { return iz_; } + + void setiphi(int iphi) { iphi_ = iphi; } + void setiz(int iz) { iz_ = iz; } + + double sigmax() const { return sigmax_; } + double sigmaz() const { return sigmaz_; } + + bool operator==(const L1TStub& other) const; + + void lorentzcor(double shift); + + int eventid() const { return eventid_; } + std::vector tps() const { return tps_; } + + void setAllStubIndex(unsigned int index) { allstubindex_ = index; } + + unsigned int allStubIndex() const { return allstubindex_; } + + unsigned int strip() const { return strip_; } + + double alpha(double pitch) const; + + //Scaled to go between -1 and +1 + double alphanorm() const; + + void setXY(double x, double y); + + unsigned int isPSmodule() const { return isPSmodule_; } + unsigned int isFlipped() const { return isFlipped_; } + + bool isTilted() const; + + bool tpmatch(int tp) const; + + private: + int eventid_; + std::vector tps_; + unsigned int iphi_; + unsigned int iz_; + unsigned int layer_; + unsigned int ladder_; + unsigned int module_; + unsigned int strip_; + double x_; + double y_; + double z_; + double sigmax_; + double sigmaz_; + double pt_; + double bend_; + unsigned int allstubindex_; + + unsigned int isPSmodule_; + unsigned int isFlipped_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/LayerProjection.h b/L1Trigger/TrackFindingTracklet/interface/LayerProjection.h new file mode 100644 index 0000000000000..1b55b4e0b5f8c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/LayerProjection.h @@ -0,0 +1,162 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_LayerProjection_h +#define L1Trigger_TrackFindingTracklet_interface_LayerProjection_h + +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +namespace trklet { + + class Settings; + + class LayerProjection { + public: + LayerProjection() { valid_ = false; } + + ~LayerProjection() = default; + + void init(Settings const& settings, + int projlayer, + double rproj, + int iphiproj, + int izproj, + int iphider, + int izder, + double phiproj, + double zproj, + double phiprojder, + double zprojder, + double phiprojapprox, + double zprojapprox, + double phiprojderapprox, + double zprojderapprox); + + bool valid() const { return valid_; } + + int projlayer() const { + assert(valid_); + return projlayer_; + }; + + double rproj() const { + assert(valid_); + return rproj_; + }; + + const FPGAWord& fpgaphiproj() const { + assert(valid_); + return fpgaphiproj_; + }; + + const FPGAWord& fpgazproj() const { + assert(valid_); + return fpgazproj_; + }; + + const FPGAWord& fpgaphiprojder() const { + assert(valid_); + return fpgaphiprojder_; + }; + + const FPGAWord& fpgazprojder() const { + assert(valid_); + return fpgazprojder_; + }; + + const FPGAWord& fpgaphiprojvm() const { + assert(valid_); + return fpgaphiprojvm_; + }; + + const FPGAWord& fpgazbin1projvm() const { + assert(valid_); + return fpgazbin1projvm_; + }; + + const FPGAWord& fpgazbin2projvm() const { + assert(valid_); + return fpgazbin2projvm_; + }; + + const FPGAWord& fpgafinezvm() const { + assert(valid_); + return fpgafinezvm_; + }; + + const FPGAWord& fpgazprojvm() const { + assert(valid_); + return fpgazprojvm_; + }; + + double phiproj() const { + assert(valid_); + return phiproj_; + }; + + double zproj() const { + assert(valid_); + return zproj_; + }; + + double phiprojder() const { + assert(valid_); + return phiprojder_; + }; + + double zprojder() const { + assert(valid_); + return zprojder_; + }; + + double phiprojapprox() const { + assert(valid_); + return phiprojapprox_; + }; + + double zprojapprox() const { + assert(valid_); + return zprojapprox_; + }; + + double phiprojderapprox() const { + assert(valid_); + return phiprojderapprox_; + }; + + double zprojderapprox() const { + assert(valid_); + return zprojderapprox_; + }; + + protected: + bool valid_; + + int projlayer_; + + double rproj_; + + FPGAWord fpgaphiproj_; + FPGAWord fpgazproj_; + FPGAWord fpgaphiprojder_; + FPGAWord fpgazprojder_; + + FPGAWord fpgaphiprojvm_; + FPGAWord fpgazprojvm_; + + FPGAWord fpgazbin1projvm_; + FPGAWord fpgazbin2projvm_; + FPGAWord fpgafinezvm_; + + double phiproj_; + double zproj_; + double phiprojder_; + double zprojder_; + + double zbin1_; + double zbin2_; + + double phiprojapprox_; + double zprojapprox_; + double phiprojderapprox_; + double zprojderapprox_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/LayerResidual.h b/L1Trigger/TrackFindingTracklet/interface/LayerResidual.h new file mode 100644 index 0000000000000..1c2cf303ae479 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/LayerResidual.h @@ -0,0 +1,98 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_LayerResidual_h +#define L1Trigger_TrackFindingTracklet_interface_LayerResidual_h + +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include + +namespace trklet { + + class Settings; + class Stub; + + class LayerResidual { + public: + LayerResidual() { valid_ = false; } + + ~LayerResidual() = default; + + void init(Settings const& settings, + int layer, + int iphiresid, + int izresid, + int istubid, + double phiresid, + double zresid, + double phiresidapprox, + double zresidapprox, + double rstub, + const Stub* stubptr); + + bool valid() const { return valid_; } + + const FPGAWord& fpgaphiresid() const { + assert(valid_); + return fpgaphiresid_; + }; + + const FPGAWord& fpgazresid() const { + assert(valid_); + return fpgazresid_; + }; + + const FPGAWord& fpgastubid() const { + assert(valid_); + return fpgastubid_; + }; + + double phiresid() const { + assert(valid_); + return phiresid_; + }; + + double zresid() const { + assert(valid_); + return zresid_; + }; + + double phiresidapprox() const { + assert(valid_); + return phiresidapprox_; + }; + + double zresidapprox() const { + assert(valid_); + return zresidapprox_; + }; + + double rstub() const { + assert(valid_); + return rstub_; + } + + const Stub* stubptr() const { + assert(valid_); + return stubptr_; + } + + protected: + bool valid_; + + int layer_; + + FPGAWord fpgaphiresid_; + FPGAWord fpgazresid_; + FPGAWord fpgastubid_; + + double phiresid_; + double zresid_; + + double phiresidapprox_; + double zresidapprox_; + + double rstub_; + const Stub* stubptr_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/MatchCalculator.h b/L1Trigger/TrackFindingTracklet/interface/MatchCalculator.h new file mode 100644 index 0000000000000..16d95f9d85f33 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/MatchCalculator.h @@ -0,0 +1,63 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_MatchCalculator_h +#define L1Trigger_TrackFindingTracklet_interface_MatchCalculator_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include +#include + +namespace trklet { + + class Globals; + class Stub; + class L1TStub; + class Tracklet; + class AllStubsMemory; + class AllProjectionsMemory; + class CandidateMatchMemory; + class FullMatchMemory; + + class MatchCalculator : public ProcessBase { + public: + MatchCalculator(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~MatchCalculator() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + std::vector, const Stub*> > mergeMatches( + std::vector& candmatch); + + private: + unsigned int layerdisk_; + unsigned int phiregion_; + + int fact_; + int icorrshift_; + int icorzshift_; + int phi0shift_; + double phioffset_; + + unsigned int phimatchcut_[N_SEED]; + unsigned int zmatchcut_[N_SEED]; + unsigned int rphicutPS_[N_SEED]; + unsigned int rphicut2S_[N_SEED]; + unsigned int rcutPS_[N_SEED]; + unsigned int rcut2S_[N_SEED]; + + int ialphafactinner_[N_DSS_MOD * 2]; + int ialphafactouter_[N_DSS_MOD * 2]; + + AllStubsMemory* allstubs_; + AllProjectionsMemory* allprojs_; + + std::vector matches_; + std::vector fullMatches_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/MatchEngine.h b/L1Trigger/TrackFindingTracklet/interface/MatchEngine.h new file mode 100644 index 0000000000000..2457be5a0c09a --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/MatchEngine.h @@ -0,0 +1,45 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_MatchEngine_h +#define L1Trigger_TrackFindingTracklet_interface_MatchEngine_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class VMStubsMEMemory; + class VMProjectionsMemory; + class CandidateMatchMemory; + + class MatchEngine : public ProcessBase { + public: + MatchEngine(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~MatchEngine() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + private: + VMStubsMEMemory* vmstubs_; + VMProjectionsMemory* vmprojs_; + + CandidateMatchMemory* candmatches_; + + int layer_; + int disk_; + + //used in the layers + std::vector table_; + + //used in the disks + std::vector tablePS_; + std::vector table2S_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/MatchEngineUnit.h b/L1Trigger/TrackFindingTracklet/interface/MatchEngineUnit.h new file mode 100644 index 0000000000000..b8bd055564db7 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/MatchEngineUnit.h @@ -0,0 +1,72 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_MatchEngineUnit_h +#define L1Trigger_TrackFindingTracklet_interface_MatchEngineUnit_h + +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + + class MatchEngineUnit { + public: + MatchEngineUnit(bool barrel, std::vector table, std::vector tablePS, std::vector table2S); + + ~MatchEngineUnit() = default; + + void init(VMStubsMEMemory* vmstubsmemory, + unsigned int slot, + int projrinv, + int projfinerz, + int projfinephi, + bool isPSseed, + Tracklet* proj); + + bool empty() const { return candmatches_.empty(); } + + std::pair read() { return candmatches_.read(); } + + std::pair peek() const { return candmatches_.peek(); } + + Tracklet* currentProj() const { return proj_; } + + bool idle() const { return idle_; } + + void step(); + + private: + VMStubsMEMemory* vmstubsmemory_; + + //unsigned int memory slot + unsigned int slot_; + unsigned int istub_; + + bool barrel_; + int projrinv_; + int projfinerz_; + int projfinephi_; + bool isPSseed_; + Tracklet* proj_; + + bool idle_; + + //used in the layers + std::vector table_; + + //used in the disks + std::vector tablePS_; + std::vector table2S_; + + //save the candidate matches + CircularBuffer > candmatches_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/MatchProcessor.h b/L1Trigger/TrackFindingTracklet/interface/MatchProcessor.h new file mode 100644 index 0000000000000..1ecdaa08ac872 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/MatchProcessor.h @@ -0,0 +1,93 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_MatchProcessor_h +#define L1Trigger_TrackFindingTracklet_interface_MatchProcessor_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/MatchEngineUnit.h" +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionTemp.h" +#include "L1Trigger/TrackFindingTracklet/interface/CircularBuffer.h" +#include "L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" + +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class Stub; + class L1TStub; + class Tracklet; + + class MatchProcessor : public ProcessBase { + public: + MatchProcessor(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~MatchProcessor() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + bool matchCalculator(Tracklet* tracklet, const Stub* fpgastub); + + private: + int layer_; + int disk_; + bool barrel_; + + unsigned int phiregion_; + + int nvm_; //VMs in sector + int nvmbits_; //# of bits for VMs in sector + int nvmbins_; //VMs in in phi region + + int fact_; + int icorrshift_; + int icorzshift_; + int phi0shift_; + + double phioffset_; + + unsigned int phimatchcut_[N_SEED]; + unsigned int zmatchcut_[N_SEED]; + + unsigned int rphicutPS_[N_SEED]; + unsigned int rphicut2S_[N_SEED]; + unsigned int rcutPS_[N_SEED]; + unsigned int rcut2S_[N_SEED]; + + double phifact_; + double rzfact_; + + int nrbits_; + int nphiderbits_; + + AllStubsMemory* allstubs_; + std::vector vmstubs_; + std::vector inputprojs_; + + int ialphafactinner_[N_DSS_MOD * 2]; + int ialphafactouter_[N_DSS_MOD * 2]; + + //Memory for the full matches + std::vector fullmatches_; + + //used in the layers + std::vector table_; + + //used in the disks + std::vector tablePS_; + std::vector table2S_; + + unsigned int nMatchEngines_; + std::vector matchengines_; + + CircularBuffer inputProjBuffer_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/MemoryBase.h b/L1Trigger/TrackFindingTracklet/interface/MemoryBase.h new file mode 100644 index 0000000000000..fc2d77ea8ce04 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/MemoryBase.h @@ -0,0 +1,53 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_MemoryBase_h +#define L1Trigger_TrackFindingTracklet_interface_MemoryBase_h + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include +#include +#include +#include + +namespace trklet { + + class MemoryBase { + public: + MemoryBase(std::string name, Settings const& settings, unsigned int iSector); + + virtual ~MemoryBase() = default; + + std::string const& getName() const { return name_; } + std::string getLastPartOfName() const { return name_.substr(name_.find_last_of('_') + 1); } + + virtual void clean() = 0; + + //method sets the layer and disk based on the name. pos is the position in the memory name where the layer or disk is specified + void initLayerDisk(unsigned int pos, int& layer, int& disk); + + unsigned int initLayerDisk(unsigned int pos); + + // Based on memory name check if this memory is used for special seeding: + // overlap is layer-disk seeding + // extra is the L2L3 seeding + // extended is the seeding for displaced tracks + void initSpecialSeeding(unsigned int pos, bool& overlap, bool& extra, bool& extended); + + //Used for a hack below due to MAC OS case sensitiviy problem for files + void findAndReplaceAll(std::string& data, std::string toSearch, std::string replaceStr); + + void openFile(bool first, std::string filebase); + + static size_t find_nth(const std::string& haystack, size_t pos, const std::string& needle, size_t nth); + + protected: + std::string name_; + unsigned int iSector_; + + std::ofstream out_; + int bx_; + int event_; + + Settings const& settings_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/ProcessBase.h b/L1Trigger/TrackFindingTracklet/interface/ProcessBase.h new file mode 100644 index 0000000000000..7482d24b21768 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/ProcessBase.h @@ -0,0 +1,48 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_ProcessBase_h +#define L1Trigger_TrackFindingTracklet_interface_ProcessBase_h + +#include + +namespace trklet { + + class MemoryBase; + class Settings; + class Globals; + + class ProcessBase { + public: + ProcessBase(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + virtual ~ProcessBase() = default; + + // Add wire from pin "output" or "input" this proc module to memory instance "memory". + virtual void addOutput(MemoryBase* memory, std::string output) = 0; + virtual void addInput(MemoryBase* memory, std::string input) = 0; + + std::string const& getName() const { return name_; } + + unsigned int nbits(unsigned int power); + + //method sets the layer and disk based on the name. pos is the position in the memory name where the layer or disk is specified + void initLayerDisk(unsigned int pos, int& layer, int& disk); + void initLayerDisk(unsigned int pos, int& layer, int& disk, int& layerdisk); + + unsigned int initLayerDisk(unsigned int pos); + + //This function processes the name of a TE module to determine the layerdisks and iseed + void initLayerDisksandISeed(unsigned int& layerdisk1, unsigned int& layerdisk2, unsigned int& iSeed); + + unsigned int getISeed(std::string name); + + protected: + std::string name_; + unsigned int iSector_; + + double phimin_; + double phimax_; + + Settings const& settings_; + Globals* globals_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/ProjectionRouter.h b/L1Trigger/TrackFindingTracklet/interface/ProjectionRouter.h new file mode 100644 index 0000000000000..2559a22a96fbf --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/ProjectionRouter.h @@ -0,0 +1,40 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_ProjectionRouter_h +#define L1Trigger_TrackFindingTracklet_interface_ProjectionRouter_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionRouterBendTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h" + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + + class ProjectionRouter : public ProcessBase { + public: + ProjectionRouter(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~ProjectionRouter() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + private: + unsigned int layerdisk_; + + int nrbits_; + int nphiderbits_; + + std::vector inputproj_; + + AllProjectionsMemory* allproj_; + std::vector vmprojs_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/ProjectionRouterBendTable.h b/L1Trigger/TrackFindingTracklet/interface/ProjectionRouterBendTable.h new file mode 100644 index 0000000000000..0cd798d758d08 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/ProjectionRouterBendTable.h @@ -0,0 +1,31 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_ProjectionRouterBendTable_h +#define L1Trigger_TrackFindingTracklet_interface_ProjectionRouterBendTable_h + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + class Globals; + + class ProjectionRouterBendTable { + public: + ProjectionRouterBendTable() {} + + ~ProjectionRouterBendTable() = default; + + void init(Settings const& settings, Globals* globals, unsigned int nrbits, unsigned int nphiderbits); + + int bendLoookup(int diskindex, int bendindex); + + private: + std::vector bendtable_[N_DISK]; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/ProjectionTemp.h b/L1Trigger/TrackFindingTracklet/interface/ProjectionTemp.h new file mode 100644 index 0000000000000..65970995ce7da --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/ProjectionTemp.h @@ -0,0 +1,41 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_ProjectionTemp_h +#define L1Trigger_TrackFindingTracklet_interface_ProjectionTemp_h + +#include +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" + +namespace trklet { + + class ProjectionTemp { + public: + ProjectionTemp(Tracklet* proj, + unsigned int slot, + unsigned int projrinv, + int projfinerz, + unsigned int projfinephi, + unsigned int iphi, + bool isPSseed); + + ProjectionTemp(); + + ~ProjectionTemp() = default; + + Tracklet* proj() const { return proj_; } + unsigned int slot() const { return slot_; } + unsigned int projrinv() const { return projrinv_; } + int projfinerz() const { return projfinerz_; } + unsigned int projfinephi() const { return projfinephi_; } + unsigned int iphi() const { return iphi_; } + bool isPSseed() const { return isPSseed_; } + + private: + Tracklet* proj_; + unsigned int slot_; + unsigned int projrinv_; + unsigned int projfinerz_; + unsigned int projfinephi_; + unsigned int iphi_; + bool isPSseed_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h b/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h new file mode 100644 index 0000000000000..833c41e30a7b4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h @@ -0,0 +1,44 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_PurgeDuplicate_h +#define L1Trigger_TrackFindingTracklet_interface_PurgeDuplicate_h + +#include "L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" + +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class Stub; + class L1TStub; + class Track; + class Tracklet; + + class PurgeDuplicate : public ProcessBase { + public: + PurgeDuplicate(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~PurgeDuplicate() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(std::vector& outputtracks_); + + private: + double getPhiRes(Tracklet* curTracklet, const Stub* curStub); + + std::vector inputtracks_; + std::vector> inputstublists_; + std::vector>> inputstubidslists_; + std::vector>> mergedstubidslists_; + std::vector inputtrackfits_; + std::vector inputtracklets_; + std::vector outputtracklets_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h b/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h new file mode 100644 index 0000000000000..0ef6024854059 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h @@ -0,0 +1,114 @@ +// This holds two classes: L1SimTrack (truth level simulated track), and SLHCEvent (support for maintaining standalone running) +#ifndef L1Trigger_TrackFindingTracklet_interface_SLHCEvent_h +#define L1Trigger_TrackFindingTracklet_interface_SLHCEvent_h + +#include +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" + +namespace trklet { + + class L1SimTrack { + public: + L1SimTrack(); + L1SimTrack(int eventid, int trackid, int type, double pt, double eta, double phi, double vx, double vy, double vz); + ~L1SimTrack() = default; + + void write(std::ofstream& out); + void write(std::ostream& out); + + int eventid() const { return eventid_; } + int trackid() const { return trackid_; } + int type() const { return type_; } + double pt() const { return pt_; } + double eta() const { return eta_; } + double phi() const { return phi_; } + double vx() const { return vx_; } + double vy() const { return vy_; } + double vz() const { return vz_; } + double dxy() const { return -vx() * sin(phi()) + vy() * cos(phi()); } + double d0() const { return -dxy(); } + int charge() const { + if (type_ == 11 || type_ == 13 || type_ == -211 || type_ == -321 || type_ == -2212) + return -1; + return 1; + } + + private: + int eventid_; + int trackid_; + int type_; + double pt_; + double eta_; + double phi_; + double vx_; + double vy_; + double vz_; + }; + + class SLHCEvent { + public: + SLHCEvent() { + //empty constructor to be used with 'filler' functions + eventnum_ = 0; + } + SLHCEvent(std::istream& in); + ~SLHCEvent() = default; + + void setIPx(double x) { x_offset_ = x; } + void setIPy(double y) { y_offset_ = y; } + + void setEventNum(int eventnum) { eventnum_ = eventnum; } + + void addL1SimTrack( + int eventid, int trackid, int type, double pt, double eta, double phi, double vx, double vy, double vz); + + bool addStub(int layer, + int ladder, + int module, + int strip, + int eventid, + std::vector tps, + double pt, + double bend, + double x, + double y, + double z, + int isPSmodule, + int isFlipped); + + const L1TStub& lastStub() const { return stubs_.back(); } + + void write(std::ofstream& out); + void write(std::ostream& out); + + unsigned int layersHit(int tpid, int& nlayers, int& ndisks); + + int nstubs() const { return stubs_.size(); } + + const L1TStub& stub(int i) const { return stubs_[i]; } + + unsigned int nsimtracks() const { return simtracks_.size(); } + + const L1SimTrack& simtrack(int i) const { return simtracks_[i]; } + + int eventnum() const { return eventnum_; } + + int getSimtrackFromSimtrackid(int simtrackid, int eventid = 0) const; + + private: + int eventnum_; + std::vector simtracks_; + std::vector stubs_; + + double x_offset_{0.0}; + double y_offset_{0.0}; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Sector.h b/L1Trigger/TrackFindingTracklet/interface/Sector.h new file mode 100644 index 0000000000000..5d25f2996afd0 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Sector.h @@ -0,0 +1,170 @@ +//This class holds functional blocks of a sector +#ifndef L1Trigger_TrackFindingTracklet_interface_Sector_h +#define L1Trigger_TrackFindingTracklet_interface_Sector_h + +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" + +#include +#include +#include +#include +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class ProcessBase; + class MemoryBase; + class Tracklet; + class Track; + class Stub; + + //Memory modules + class InputLinkMemory; + class AllStubsMemory; + class VMStubsTEMemory; + class VMStubsMEMemory; + class StubPairsMemory; + class StubTripletsMemory; + class TrackletParametersMemory; + class TrackletProjectionsMemory; + class AllProjectionsMemory; + class VMProjectionsMemory; + class CandidateMatchMemory; + class FullMatchMemory; + class TrackFitMemory; + class CleanTrackMemory; + + //Processing modules + class VMRouter; + class TrackletEngine; + class TrackletEngineDisplaced; + class TripletEngine; + class TrackletCalculator; + class TrackletProcessor; + class TrackletCalculatorDisplaced; + class ProjectionRouter; + class MatchEngine; + class MatchCalculator; + class MatchProcessor; + class FitTrack; + class PurgeDuplicate; + + class Sector { + public: + Sector(unsigned int i, Settings const& settings, Globals* globals); + + ~Sector(); + + bool addStub(L1TStub stub, std::string dtc); //TODO - should be pointer or string + + // Creates all required memory modules based on wiring map (args: module type, module instance) + void addMem(std::string memType, std::string memName); + + // Creates all required processing modules based on wiring map (args: module type, module instance) + void addProc(std::string procType, std::string procName); + + //--- Create all required proc -> mem module connections, based on wiring map + //--- (args: memory instance & input/output proc modules it connects to in format procName.pinName) + void addWire(std::string mem, std::string procinfull, std::string procoutfull); + + ProcessBase* getProc(std::string procName); + MemoryBase* getMem(std::string memName); + + void writeInputStubs(bool first); + void writeVMSTE(bool first); + void writeVMSME(bool first); + void writeAS(bool first); + void writeSP(bool first); + void writeST(bool first); + void writeTPAR(bool first); + void writeTPROJ(bool first); + void writeAP(bool first); + void writeVMPROJ(bool first); + void writeCM(bool first); + void writeMC(bool first); + void writeTF(bool first); + void writeCT(bool first); + + void clean(); + + // execute the different tracklet processing modules + void executeVMR(); + void executeTE(); + void executeTED(); + void executeTRE(); + void executeTP(); + void executeTC(); + void executeTCD(); + void executePR(); + void executeME(); + void executeMC(); + void executeMP(); + void executeFT(); + void executePD(std::vector& tracks); + + std::vector getAllTracklets() const; + std::vector getStubs() const; + + std::unordered_set seedMatch(int itp) const; + + double phimin() const { return phimin_; } + double phimax() const { return phimax_; } + + template + void addMemToVec(std::vector& memvec, TV* mem, const std::string& memName) { + memvec.push_back(mem); + Memories_[memName].reset(mem); + MemoriesV_.push_back(mem); + } + + template + void addProcToVec(std::vector& procvec, TV* proc, const std::string& procName) { + procvec.push_back(proc); + Processes_[procName].reset(proc); + } + + private: + int isector_; + Settings const& settings_; + Globals* globals_; + double phimin_; + double phimax_; + + std::map > Memories_; + std::vector MemoriesV_; + std::vector IL_; + std::vector AS_; + std::vector VMSTE_; + std::vector VMSME_; + std::vector SP_; + std::vector ST_; + std::vector TPAR_; + std::vector TPROJ_; + std::vector AP_; + std::vector VMPROJ_; + std::vector CM_; + std::vector FM_; + std::vector TF_; + std::vector CT_; + + std::map > Processes_; + std::vector VMR_; + std::vector TE_; + std::vector TED_; + std::vector TRE_; + std::vector TP_; + std::vector TC_; + std::vector TCD_; + std::vector PR_; + std::vector ME_; + std::vector MC_; + std::vector MP_; + std::vector FT_; + std::vector PD_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Settings.h b/L1Trigger/TrackFindingTracklet/interface/Settings.h new file mode 100644 index 0000000000000..6516fa77bee95 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Settings.h @@ -0,0 +1,742 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_Settings_h +#define L1Trigger_TrackFindingTracklet_interface_Settings_h + +#include +#include +#include +#include +#include +#include +#include + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +namespace trklet { + + constexpr unsigned int N_SECTOR = 9; // # of phi sectors for L1TK processing + + constexpr int N_LAYER = 6; // # of barrel layers assumed + constexpr int N_DISK = 5; // # of endcap disks assumed + constexpr unsigned int N_PSLAYER = 3; // # of barrel PS layers assumed + constexpr unsigned int N_SEED = 12; // # of tracklet+triplet seeds + + constexpr unsigned int N_DSS_MOD = 5; // # of rings with 2S modules per disk + + class Settings { + public: + Settings() { + //Comment out to run tracklet-only algorithm +#ifdef CMSSW_GIT_HASH +#ifndef USEHYBRID +#error USEHYBRID is not defined +#endif +#endif + } + + ~Settings() = default; + + // processing & memory modules, wiring, etc. + std::string DTCLinkFile() const { return DTCLinkFile_; } + std::string const& moduleCablingFile() const { return moduleCablingFile_; } + std::string const& DTCLinkLayerDiskFile() const { return DTCLinkLayerDiskFile_; } + std::string const& fitPatternFile() const { return fitPatternFile_; } + std::string const& processingModulesFile() const { return processingModulesFile_; } + std::string const& memoryModulesFile() const { return memoryModulesFile_; } + std::string const& wiresFile() const { return wiresFile_; } + std::string const& tableTEDFile() const { return tableTEDFile_; } + std::string const& tableTREFile() const { return tableTREFile_; } + + void setDTCLinkFile(std::string DTCLinkFileName) { DTCLinkFile_ = DTCLinkFileName; } + void setModuleCablingFile(std::string moduleCablingFileName) { moduleCablingFile_ = moduleCablingFileName; } + void setDTCLinkLayerDiskFile(std::string DTCLinkLayerDiskFileName) { + DTCLinkLayerDiskFile_ = DTCLinkLayerDiskFileName; + } + void setFitPatternFile(std::string fitPatternFileName) { fitPatternFile_ = fitPatternFileName; } + void setProcessingModulesFile(std::string processingModulesFileName) { + processingModulesFile_ = processingModulesFileName; + } + void setMemoryModulesFile(std::string memoryModulesFileName) { memoryModulesFile_ = memoryModulesFileName; } + void setWiresFile(std::string wiresFileName) { wiresFile_ = wiresFileName; } + void setTableTEDFile(std::string tableTEDFileName) { tableTEDFile_ = tableTEDFileName; } + void setTableTREFile(std::string tableTREFileName) { tableTREFile_ = tableTREFileName; } + + unsigned int nzbitsstub(unsigned int layerdisk) const { return nzbitsstub_[layerdisk]; } + unsigned int nphibitsstub(unsigned int layerdisk) const { return nphibitsstub_[layerdisk]; } + unsigned int nrbitsstub(unsigned int layerdisk) const { return nrbitsstub_[layerdisk]; } + + unsigned int nrbitsprojderdisk() const { return nrbitsprojderdisk_; } + unsigned int nbitsphiprojderL123() const { return nbitsphiprojderL123_; } + unsigned int nbitsphiprojderL456() const { return nbitsphiprojderL456_; } + unsigned int nbitszprojderL123() const { return nbitszprojderL123_; } + unsigned int nbitszprojderL456() const { return nbitszprojderL456_; } + + unsigned int nbendbitsmedisk() const { return nbendbitsmedisk_; } + + bool useSeed(unsigned int iSeed) const { return useseeding_.find(iSeed) != useseeding_.end(); } + unsigned int nbitsvmte(unsigned int inner, unsigned int iSeed) const { return nbitsvmte_[inner][iSeed]; } + unsigned int nvmte(unsigned int inner, unsigned int iSeed) const { return (1 << nbitsvmte_[inner][iSeed]); } + + unsigned int nbitsvmme(unsigned int layerdisk) const { return nbitsvmme_[layerdisk]; } + unsigned int nvmme(unsigned int layerdisk) const { return (1 << nbitsvmme_[layerdisk]); } + + unsigned int nbitsallstubs(unsigned int layerdisk) const { return nbitsallstubs_[layerdisk]; } + unsigned int nallstubs(unsigned int layerdisk) const { return (1 << nbitsallstubs_[layerdisk]); } + + bool writeMonitorData(std::string module) const { + if (writeMonitorData_.find(module) == writeMonitorData_.end()) { + throw cms::Exception("BadConfig") << "Settings::writeMonitorData module = " << module << " not known"; + } + return writeMonitorData_.at(module); + } + + unsigned int maxStep(std::string module) const { + if (maxstep_.find(module) == maxstep_.end()) { + throw cms::Exception("BadConfig") + << __FILE__ << " " << __LINE__ << " maxStep module = " << module << " not known"; + } + return maxstep_.at(module) + maxstepoffset_; + } + + double zlength() const { return zlength_; } + double rmaxdisk() const { return rmaxdisk_; } + double rmindisk() const { return rmindisk_; } + + double drmax() const { return rmaxdisk_ / deltarzfract_; } + double dzmax() const { return zlength_ / deltarzfract_; } + + double half2SmoduleWidth() const { return half2SmoduleWidth_; } + + double bendcutte(unsigned int inner, unsigned int iSeed) const { return bendcutte_[inner][iSeed]; } + double bendcutme(unsigned int layerdisk) const { return bendcutme_[layerdisk]; } + double nfinephi(unsigned int inner, unsigned int iSeed) const { return nfinephi_[inner][iSeed]; } + double nphireg(unsigned int inner, unsigned int iSeed) const { return nphireg_[inner][iSeed]; } + double lutwidthtab(unsigned int inner, unsigned int iSeed) const { return lutwidthtab_[inner][iSeed]; } + double lutwidthtabextended(unsigned int inner, unsigned int iSeed) const { + return lutwidthtabextended_[inner][iSeed]; + } + + unsigned int projlayers(unsigned int iSeed, unsigned int i) const { return projlayers_[iSeed][i]; } + unsigned int projdisks(unsigned int iSeed, unsigned int i) const { return projdisks_[iSeed][i]; } + double rphimatchcut(unsigned int iSeed, unsigned int ilayer) const { return rphimatchcut_[ilayer][iSeed]; } + double zmatchcut(unsigned int iSeed, unsigned int ilayer) const { return zmatchcut_[ilayer][iSeed]; } + double rphicutPS(unsigned int iSeed, unsigned int idisk) const { return rphicutPS_[idisk][iSeed]; } + double rcutPS(unsigned int iSeed, unsigned int idisk) const { return rcutPS_[idisk][iSeed]; } + double rphicut2S(unsigned int iSeed, unsigned int idisk) const { return rphicut2S_[idisk][iSeed]; } + double rcut2S(unsigned int iSeed, unsigned int idisk) const { return rcut2S_[idisk][iSeed]; } + + double rmean(unsigned int iLayer) const { return irmean_[iLayer] * rmaxdisk_ / 4096; } + double rmax(unsigned int iLayer) const { return rmean(iLayer) + drmax(); } + double rmin(unsigned int iLayer) const { return rmean(iLayer) - drmax(); } + double zmean(unsigned int iDisk) const { return izmean_[iDisk] * zlength_ / 2048; } + double zmax(unsigned int iDisk) const { return zmean(iDisk) + dzmax(); } + double zmin(unsigned int iDisk) const { return zmean(iDisk) - dzmax(); } + + double rDSSinner(unsigned int iBin) const { + return rDSSinner_mod_[iBin / 2] + halfstrip_ * ((iBin % 2 == 0) ? -1 : 1); + } + double rDSSouter(unsigned int iBin) const { + return rDSSouter_mod_[iBin / 2] + halfstrip_ * ((iBin % 2 == 0) ? -1 : 1); + } + + unsigned int vmrlutzbits(unsigned int layerdisk) const { return vmrlutzbits_[layerdisk]; } + unsigned int vmrlutrbits(unsigned int layerdisk) const { return vmrlutrbits_[layerdisk]; } + + bool printDebugKF() const { return printDebugKF_; } + bool debugTracklet() const { return debugTracklet_; } + bool writetrace() const { return writetrace_; } + + bool warnNoMem() const { return warnNoMem_; } + bool warnNoDer() const { return warnNoDer_; } + + bool writeMem() const { return writeMem_; } + bool writeTable() const { return writeTable_; } + + bool writeVerilog() const { return writeVerilog_; } + bool writeHLS() const { return writeHLS_; } + bool writeInvTable() const { return writeInvTable_; } + bool writeHLSInvTable() const { return writeHLSInvTable_; } + + unsigned int writememsect() const { return writememsect_; } + + bool writeTripletTables() const { return writeTripletTables_; } + + bool writeoutReal() const { return writeoutReal_; } + + bool bookHistos() const { return bookHistos_; } + + double ptcut() const { return ptcut_; } + double rinvcut() const { return 0.01 * c_ * bfield_ / ptcut_; } //0.01 to convert to cm-1 + + double c() const { return c_; } + + double rinvmax() const { return 0.01 * c_ * bfield_ / ptmin_; } + + int alphashift() const { return alphashift_; } + int nbitsalpha() const { return nbitsalpha_; } + int alphaBitsTable() const { return alphaBitsTable_; } + int nrinvBitsTable() const { return nrinvBitsTable_; } + + unsigned int MEBinsBits() const { return MEBinsBits_; } + unsigned int MEBins() const { return 1u << MEBinsBits_; } + unsigned int MEBinsDisks() const { return MEBinsDisks_; } + unsigned int maxStubsPerBin() const { return maxStubsPerBin_; } + + std::string geomext() const { + if (combined_) + return "hourglassCombined"; + return extended_ ? "hourglassExtended" : "hourglass"; + } + + bool exactderivatives() const { return exactderivatives_; } + bool exactderivativesforfloating() const { return exactderivativesforfloating_; } + bool useapprox() const { return useapprox_; } + bool usephicritapprox() const { return usephicritapprox_; } + + unsigned int minIndStubs() const { return minIndStubs_; } + std::string removalType() const { return removalType_; } + std::string mergeComparison() const { return mergeComparison_; } + bool doKF() const { return doKF_; } + bool doMultipleMatches() const { return doMultipleMatches_; } + bool fakefit() const { return fakefit_; } + + // configurable + unsigned int nHelixPar() const { return nHelixPar_; } + void setNHelixPar(unsigned int nHelixPar) { nHelixPar_ = nHelixPar; } + + bool extended() const { return extended_; } + void setExtended(bool extended) { extended_ = extended; } + bool combined() const { return combined_; } + void setCombined(bool combined) { combined_ = combined; } + + double bfield() const { return bfield_; } + void setBfield(double bfield) { bfield_ = bfield; } + + unsigned int nStrips(bool isPSmodule) const { return isPSmodule ? nStrips_PS_ : nStrips_2S_; } + void setNStrips_PS(unsigned int nStrips_PS) { nStrips_PS_ = nStrips_PS; } + void setNStrips_2S(unsigned int nStrips_2S) { nStrips_2S_ = nStrips_2S; } + + double stripPitch(bool isPSmodule) const { return isPSmodule ? stripPitch_PS_ : stripPitch_2S_; } + void setStripPitch_PS(double stripPitch_PS) { stripPitch_PS_ = stripPitch_PS; } + void setStripPitch_2S(double stripPitch_2S) { stripPitch_2S_ = stripPitch_2S; } + + double stripLength(bool isPSmodule) const { return isPSmodule ? stripLength_PS_ : stripLength_2S_; } + void setStripLength_PS(double stripLength_PS) { stripLength_PS_ = stripLength_PS; } + void setStripLength_2S(double stripLength_2S) { stripLength_2S_ = stripLength_2S; } + + std::string skimfile() const { return skimfile_; } + void setSkimfile(std::string skimfile) { skimfile_ = skimfile; } + + double dphisectorHG() const { + return 2 * M_PI / N_SECTOR + + 2 * std::max(std::abs(asin(0.5 * rinvmax() * rmean(0)) - asin(0.5 * rinvmax() * rcrit_)), + std::abs(asin(0.5 * rinvmax() * rmean(5)) - asin(0.5 * rinvmax() * rcrit_))); + } + + double rcrit() const { return rcrit_; } + + double dphisector() const { return 2 * M_PI / N_SECTOR; } + + double phicritmin() const { return 0.5 * dphisectorHG() - M_PI / N_SECTOR; } + double phicritmax() const { return dphisectorHG() - 0.5 * dphisectorHG() + M_PI / N_SECTOR; } + + double phicritminmc() const { return phicritmin() - dphicritmc_; } + double phicritmaxmc() const { return phicritmax() + dphicritmc_; } + + double kphi() const { return dphisectorHG() / (1 << nphibitsstub(0)); } + double kphi1() const { return dphisectorHG() / (1 << nphibitsstub(5)); } + + double kz() const { return 2 * zlength_ / (1 << nzbitsstub_[0]); } + double kr() const { return rmaxdisk_ / (1 << nrbitsstub_[6]); } + + double maxrinv() const { return maxrinv_; } + double maxd0() const { return maxd0_; } + unsigned int nbitsd0() const { return nbitsd0_; } + + double kd0() const { return 2 * maxd0_ / (1 << nbitsd0_); } + + double rinvcutte() const { return 0.01 * c_ * bfield_ / ptcutte_; } //0.01 to convert to cm-1 + + double rmindiskvm() const { return rmindiskvm_; } + double rmaxdiskvm() const { return rmaxdiskvm_; } + + double rmaxdiskl1overlapvm() const { return rmaxdiskl1overlapvm_; } + double rmindiskl2overlapvm() const { return rmindiskl2overlapvm_; } + double rmindiskl3overlapvm() const { return rmindiskl3overlapvm_; } + + double rPS2S() const { return rPS2S_; } + + double z0cut() const { return z0cut_; } + + unsigned int NLONGVMBITS() const { return NLONGVMBITS_; } + unsigned int NLONGVMBINS() const { return (1 << NLONGVMBITS_); } + + unsigned int ntrackletmax() const { return ntrackletmax_; } + + //Bits used to store track parameter in tracklet + int nbitsrinv() const { return nbitsrinv_; } + int nbitsphi0() const { return nbitsphi0_; } + int nbitst() const { return nbitst_; } + int nbitsz0() const { return nbitsz0_; } + + //track and tracklet parameters + int rinv_shift() const { return rinv_shift_; } + int phi0_shift() const { return phi0_shift_; } + int t_shift() const { return t_shift_; } + int z0_shift() const { return z0_shift_; } + + //projections are coarsened from global to stub precision + + //projection to R parameters + int SS_phiL_shift() const { return SS_phiL_shift_; } + int PS_zL_shift() const { return PS_zL_shift_; } + + int SS_phiderL_shift() const { return SS_phiderL_shift_; } + int PS_zderL_shift() const { return PS_zderL_shift_; } + int SS_zderL_shift() const { return SS_zderL_shift_; } + + //projection to Z parameters + int SS_phiD_shift() const { return SS_phiD_shift_; } + int PS_rD_shift() const { return PS_rD_shift_; } + + int SS_phiderD_shift() const { return SS_phiderD_shift_; } + int PS_rderD_shift() const { return PS_rderD_shift_; } + + //numbers needed for matches & fit, unclear what they are. + int phi0bitshift() const { return phi0bitshift_; } + int phiderbitshift() const { return phiderbitshift_; } + int zderbitshift() const { return zderbitshift_; } + + int phiresidbits() const { return phiresidbits_; } + int zresidbits() const { return zresidbits_; } + int rresidbits() const { return rresidbits_; } + + //Trackfit + int fitrinvbitshift() const { return fitrinvbitshift_; } + int fitphi0bitshift() const { return fitphi0bitshift_; } + int fittbitshift() const { return fittbitshift_; } + int fitz0bitshift() const { return fitz0bitshift_; } + + //r correction bits + int rcorrbits() const { return rcorrbits_; } + + int chisqphifactbits() const { return chisqphifactbits_; } + int chisqzfactbits() const { return chisqzfactbits_; } + + //0.02 here is the maximum range in rinv values that can be represented + double krinvpars() const { + int shift = ceil(-log2(0.02 * rmaxdisk_ / ((1 << nbitsrinv_) * dphisectorHG()))); + return dphisectorHG() / rmaxdisk_ / (1 << shift); + } + double kphi0pars() const { return 2 * kphi1(); } + double ktpars() const { return maxt_ / (1 << nbitst_); } + double kz0pars() const { return kz(); } + double kd0pars() const { return kd0(); } + + double kphider() const { return krinvpars() / (1 << phiderbitshift_); } + double kzder() const { return ktpars() / (1 << zderbitshift_); } + + //This is a 'historical accident' and should be fixed so that we don't + //have the factor if 2 + double krprojshiftdisk() const { return 2 * kr(); } + + private: + std::string DTCLinkFile_; + std::string moduleCablingFile_; + std::string DTCLinkLayerDiskFile_; + std::string fitPatternFile_; + std::string processingModulesFile_; + std::string memoryModulesFile_; + std::string wiresFile_; + std::string tableTEDFile_; + std::string tableTREFile_; + + double rcrit_{55.0}; // critical radius for the hourglass configuration + + double dphicritmc_{0.005}; + + //fraction of full r and z range that stubs can be located within layer/disk + double deltarzfract_{32.0}; + + double maxt_{32.0}; //range in t that we must cover + + std::array irmean_{{851, 1269, 1784, 2347, 2936, 3697}}; + std::array izmean_{{2239, 2645, 3163, 3782, 4523}}; + + std::array nzbitsstub_{{12, 12, 12, 8, 8, 8, 7, 7, 7, 7, 7}}; + std::array nphibitsstub_{{14, 14, 14, 17, 17, 17, 14, 14, 14, 14, 14}}; + std::array nrbitsstub_{{7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12}}; + + unsigned int nrbitsprojderdisk_{9}; + unsigned int nbitsphiprojderL123_{10}; + unsigned int nbitsphiprojderL456_{10}; + unsigned int nbitszprojderL123_{10}; + unsigned int nbitszprojderL456_{9}; + + unsigned int nbendbitsmedisk_{4}; // Always 4 bits even for PS disk hits, for HLS compatibility + + std::set useseeding_{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + + std::array nbitsallstubs_{{3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}}; + std::array nbitsvmme_{{2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2}}; + std::array, 3> nbitsvmte_{ + {{{2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 3, 2}}, // (3 = #stubs/triplet, only row 1+2 used for tracklet) + {{3, 2, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1}}}}; + + std::array, 2> bendcutte_{ + {{{1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25}}, //inner (2 = #stubs/tracklet) + {{1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25}}}}; //outer + + std::array bendcutme_{{2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5}}; + + double rmindiskvm_{22.5}; + double rmaxdiskvm_{67.0}; + + double rmaxdiskl1overlapvm_{45.0}; + double rmindiskl2overlapvm_{40.0}; + double rmindiskl3overlapvm_{50.0}; + + double rPS2S_{60.0}; + + double z0cut_{15.0}; + + unsigned int NLONGVMBITS_{3}; + + double zlength_{120.0}; + double rmaxdisk_{120.0}; + double rmindisk_{20.0}; + + double half2SmoduleWidth_{4.57}; + + double maxrinv_{0.006}; + double maxd0_{10.0}; + + unsigned int nbitsd0_{13}; + + double ptmin_{2.0}; //minumim pt for tracks + + double ptcutte_{1.8}; //Minimum pt in TE + + unsigned int ntrackletmax_{127}; //maximum number of tracklets that can be stored + + //Bits used to store track parameter in tracklet + int nbitsrinv_{14}; + int nbitsphi0_{18}; + int nbitst_{14}; + int nbitsz0_{10}; + + //track and tracklet parameters + int rinv_shift_{-8}; // Krinv = 2^shift * Kphi/Kr + int phi0_shift_{1}; // Kphi0 = 2^shift * Kphi + int t_shift_{-10}; // Kt = 2^shift * Kz/Kr + int z0_shift_{0}; // Kz0 = 2^shift * kz + + //projections are coarsened from global to stub precision + + //projection to R parameters + int SS_phiL_shift_{0}; + int PS_zL_shift_{0}; // z projections have global precision in ITC + + int SS_phiderL_shift_{-5}; + int PS_zderL_shift_{-7}; // Kderz = 2^shift * Kz/Kr + int SS_zderL_shift_{-7}; + + //projection to Z parameters + int SS_phiD_shift_{3}; + int PS_rD_shift_{1}; // a bug?! coarser by a factor of two then stubs?? + + int SS_phiderD_shift_{-4}; + int PS_rderD_shift_{-6}; //Kderrdisk = 2^shift * Kr/Kz + + //numbers needed for matches & fit, unclear what they are. + int phi0bitshift_{1}; + int phiderbitshift_{7}; + int zderbitshift_{6}; + + int phiresidbits_{12}; + int zresidbits_{9}; + int rresidbits_{7}; + + //Trackfit + int fitrinvbitshift_{9}; //6 OK? + int fitphi0bitshift_{6}; //4 OK? + int fittbitshift_{10}; //4 OK? //lower number gives rounding problems + int fitz0bitshift_{8}; //6 OK? + + //r correction bits + int rcorrbits_{6}; + + int chisqphifactbits_{14}; + int chisqzfactbits_{14}; + + std::array vmrlutzbits_{ + {7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3}}; // zbits used by LUT in VMR + std::array vmrlutrbits_{ + {4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8}}; // rbits used by LUT in VMR + + std::array, 3> nfinephi_{ + {{{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}}, //inner (3 = #stubs/triplet, only row 1+2 used for tracklet) + {{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}, //outer + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3}}}}; //outermost (triplets only) + + //These are the number of bits used for the VM regions in the TE by seedindex + std::array, 3> nphireg_{ + {{{5, 4, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4}}, //inner + {{5, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4}}, //outer + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4}}}}; //outermost (triplets only) + + std::array, 3> lutwidthtab_{{{{10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 11, 0}}, + {{6, 6, 6, 6, 10, 10, 10, 10, 0, 0, 6, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6}}}}; + + std::array, 3> lutwidthtabextended_{ + {{{11, 11, 21, 21, 21, 21, 11, 11, 0, 0, 21, 0}}, + {{6, 6, 6, 6, 10, 10, 10, 10, 0, 0, 6, 0}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6}}}}; + + //projection layers by seed index. For each seeding index (row) the list of layers that we consider projections to + std::array, N_SEED> projlayers_{{{{3, 4, 5, 6}}, //0 L1L2 + {{1, 4, 5, 6}}, //1 L2L3 + {{1, 2, 5, 6}}, //2 L3L4 + {{1, 2, 3, 4}}, //3 L5L6 + {{1, 2}}, //4 D1D2 + {{1}}, //5 D3D4 + {{}}, //6 L1D1 + {{1}}, //7 L2D1 + {{1, 5, 6}}, //8 L2L3L4 + {{1, 2, 3}}, //9 L4L5L6 + {{1}}, //10 L2L3D1 + {{1}}}}; //11 D1D2L2 + + //projection disks by seed index. For each seeding index (row) the list of diks that we consider projections to + std::array, N_SEED> projdisks_{{{{1, 2, 3, 4}}, //0 L1L2 + {{1, 2, 3, 4}}, //1 L2L3 + {{1, 2}}, //2 L3L4 + {{}}, //3 L5L6 + {{3, 4, 5}}, //4 D1D2 + {{1, 2, 5}}, //5 D3D4 + {{2, 3, 4, 5}}, //6 L1D1 + {{2, 3, 4}}, //7 L2D1 + {{1, 2}}, //8 L2L3L4 + {{}}, //9 L4L5L6 + {{2, 3, 4}}, //10 L2L3D1 + {{3, 4}}}}; //11 D1D2L2 + + //rphi cuts for layers - the column is the seedindex + std::array, N_LAYER> rphimatchcut_{ + {{{0.0, 0.1, 0.07, 0.08, 0.07, 0.05, 0.0, 0.05, 0.08, 0.15, 0.125, 0.15}}, //Layer 1 + {{0.0, 0.0, 0.06, 0.08, 0.05, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0}}, //Layer 2 + {{0.1, 0.0, 0.0, 0.08, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08, 0.0, 0.0}}, //Layer 3 + {{0.19, 0.19, 0.0, 0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}, //Layer 4 + {{0.4, 0.4, 0.08, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08, 0.0, 0.0, 0.0}}, //Layer 5 + {{0.5, 0.0, 0.19, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0}}}}; //Layer 6 + + //z cuts for layers - the column is the seedindex + std::array, N_LAYER> zmatchcut_{ + {{{0.0, 0.7, 5.5, 15.0, 1.5, 2.0, 0.0, 1.5, 1.0, 8.0, 1.0, 1.5}}, //Layer 1 + {{0.0, 0.0, 3.5, 15.0, 1.25, 0.0, 0.0, 0.0, 0.0, 7.0, 0.0, 0.0}}, //Layer 2 + {{0.7, 0.0, 0.0, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0}}, //Layer 3 + {{3.0, 3.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}, //Layer 4 + {{3.0, 3.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.5, 0.0, 0.0, 0.0}}, //Layer 5 + {{4.0, 0.0, 9.5, 0.0, 0.0, 0.0, 0.0, 0.0, 4.5, 0.0, 0.0, 0.0}}}}; //Layer 6 + + //rphi cuts for PS modules in disks - the column is the seedindex + std::array, N_DISK> rphicutPS_{ + {{{0.2, 0.2, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}, //disk 1 + {{0.2, 0.2, 0.0, 0.0, 0.0, 0.1, 0.1, 0.1, 0.0, 0.0, 0.15, 0.0}}, //disk 2 + {{0.25, 0.2, 0.0, 0.0, 0.15, 0.0, 0.2, 0.15, 0.0, 0.0, 0.0, 0.2}}, //disk 3 + {{0.5, 0.2, 0.0, 0.0, 0.2, 0.0, 0.3, 0.5, 0.0, 0.0, 0.0, 0.0}}, //disk 4 + {{0.0, 0.0, 0.0, 0.0, 0.25, 0.1, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}}}}; //disk 5 + + //r cuts for PS modules in disks - the column is the seedindex + std::array, N_DISK> rcutPS_{ + {{{0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}, //disk 1 + {{0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.0, 0.0, 0.5, 0.0}}, //disk 2 + {{0.5, 0.5, 0.0, 0.0, 0.5, 0.0, 0.6, 0.8, 0.0, 0.0, 0.0, 0.4}}, //disk 3 + {{0.5, 0.5, 0.0, 0.0, 0.8, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}}, //disk 4 + {{0.0, 0.0, 0.0, 0.0, 1.0, 0.5, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0}}}}; //disk 5 + + //rphi cuts for 2S modules in disks = the column is the seedindex + std::array, N_DISK> rphicut2S_{ + {{{0.5, 0.5, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0}}, //disk 1 + {{0.5, 0.5, 0.8, 0.0, 0.0, 0.0, 0.5, 0.15, 0.3, 0.0, 0.68, 0.0}}, //disk 2 + {{0.5, 0.5, 0.0, 0.0, 0.15, 0.0, 0.2, 0.25, 0.0, 0.0, 0.8, 0.1}}, //disk 3 + {{0.5, 0.5, 0.0, 0.0, 0.2, 0.0, 0.25, 0.5, 0.0, 0.0, 0.6, 0.4}}, //disk 4 + {{0.0, 0.0, 0.0, 0.0, 0.4, 0.2, 0.4, 0.0, 0.0, 0.0, 0.0, 0.8}}}}; //disk 5 + + //r cuts for 2S modules in disks -the column is the seedindex + std::array, N_DISK> rcut2S_{ + {{{3.8, 3.8, 3.8, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0}}, //disk 1 + {{3.8, 3.8, 3.8, 0.0, 0.0, 0.0, 3.8, 3.4, 3.0, 0.0, 3.0, 0.0}}, //disk 2 + {{3.6, 3.8, 0.0, 0.0, 3.6, 0.0, 3.6, 3.8, 0.0, 0.0, 3.8, 3.0}}, //disk 3 + {{3.6, 3.8, 0.0, 0.0, 3.6, 0.0, 3.5, 3.8, 0.0, 0.0, 3.0, 3.0}}, //disk 4 + {{0.0, 0.0, 0.0, 0.0, 3.6, 3.4, 3.7, 0.0, 0.0, 0.0, 0.0, 3.0}}}}; //disk 5 + + //Offset to the maximum number of steps in each processing step. Set to 0 for standard + //trunction. Set to large value, e.g. 10000 to remove truncation + unsigned int maxstepoffset_{10000}; + + //Default number of processing steps for one event + std::unordered_map maxstep_{{"Link", 108}, + {"MC", 108}, + {"ME", 108}, + {"MP", 108}, + {"PR", 108}, + {"TC", 108}, + {"TE", 108}, + {"TP", 108}, + {"TRE", 108}, + {"VMR", 108}}; + + // If set to true this will generate debub printout in text files + std::unordered_map writeMonitorData_{{"IL", false}, + {"TE", false}, + {"CT", false}, + {"HitPattern", false}, + {"ChiSq", false}, + {"Seeds", false}, + {"FT", false}, + {"Residuals", false}, + {"MC", false}, + {"ME", false}, + {"AP", false}, + {"VMP", false}, + {"NMatches", false}, + {"TrackProjOcc", false}, + {"TC", false}, + {"Pars", false}, + {"TPars", false}, + {"TPD", false}, + {"TrackletPars", false}, + {"TED", false}, + {"TP", false}, + {"TRE", false}, + {"VMR", false}, + {"StubsLayer", false}, + {"StubsLayerSector", false}, + {"HitEff", false}, + {"MatchEff", false}, + {"Cabling", false}, + {"IFit", false}, + {"AS", false}}; + + std::array rDSSinner_mod_{{68.9391, 78.7750, 85.4550, 96.3150, 102.3160}}; + std::array rDSSouter_mod_{{66.4903, 76.7750, 84.4562, 94.9920, 102.3160}}; + + //we want the center of the two strip positions in a module, not just the center of a module + double halfstrip_{2.5}; + + // various printouts for debugging and warnings + bool printDebugKF_{false}; // if true print lots of debugging statements related to the KF fit + bool debugTracklet_{false}; //Print detailed debug information about tracklet tracking + bool writetrace_{false}; //Print out details about parsing configuration files + + bool warnNoMem_{false}; //If true will print out warnings about missing projection memories + bool warnNoDer_{false}; //If true will print out warnings about missing track fit derivatives + + bool writeMem_{false}; //If true will print out content of memories to files + bool writeTable_{false}; //IF true will print out content of LUTs to files + + // Write various lookup tables and autogenerated code (from iMath) + bool writeVerilog_{false}; //Write out auto-generated Verilog mudules used by TCs + bool writeHLS_{false}; //Write out auto-generated HLS mudules used by TCs + bool writeInvTable_{false}; //Write out tables of drinv and invt in tracklet calculator for Verilog module + bool writeHLSInvTable_{false}; //Write out tables of drinv and invt in tracklet calculator for HLS module + + unsigned int writememsect_{3}; //writemem only for this sector (note that the files will have _4 extension) + + bool writeTripletTables_{false}; //Train and write the TED and TRE tables. N.B.: the tables + //cannot be applied while they are being trained, i.e., + //this flag effectively turns off the cuts in + //TrackletEngineDisplaced and TripletEngine + + bool writeoutReal_{false}; + + //set to true/false to turn on/off histogram booking internal to the tracking (class "HistBase/HistImp", does nothing in central CMSSW) + bool bookHistos_{false}; + + // pt constants + double ptcut_{1.91}; //Minimum pt cut + + // Parameters for bit sizes + int alphashift_{12}; + int nbitsalpha_{4}; //bits used to store alpha + int alphaBitsTable_{2}; //For number of bits in track derivative table + int nrinvBitsTable_{3}; //number of bits for tabulating rinv dependence + + unsigned int MEBinsBits_{3}; + unsigned int MEBinsDisks_{8}; //on each side + unsigned int maxStubsPerBin_{16}; + + // Options for chisq fit + bool exactderivatives_{false}; + bool exactderivativesforfloating_{true}; //only for the floating point + bool useapprox_{true}; //use approximate postion based on integer representation for floating point + bool usephicritapprox_{false}; //use floating point approximate version of phicrit cut if true + + // Duplicate Removal + // "merge" (hybrid dup removal) + // "ichi" (pairwise, keep track with best ichisq), "nstub" (pairwise, keep track with more stubs) + // "grid" (TMTT-like removal), "" (no removal) + unsigned int minIndStubs_{3}; // not used with merge removal + +#ifdef USEHYBRID + std::string removalType_{"merge"}; + // "CompareBest" (recommended) Compares only the best stub in each track for each region (best = smallest phi residual) + // and will merge the two tracks if stubs are shared in three or more regions + // "CompareAll" Compares all stubs in a region, looking for matches, and will merge the two tracks if stubs are shared in three or more regions + std::string mergeComparison_{"CompareBest"}; + bool doKF_{true}; +#endif + +#ifndef USEHYBRID + bool doKF_{false}; + std::string removalType_{"ichi"}; + std::string mergeComparison_{""}; +#endif + + // When false, match calculator does not save multiple matches, even when doKF=true. + // This is a temporary fix for compatibilty with HLS. We will need to implement multiple match + // printing in emulator eventually, possibly after CMSSW-integration inspired rewrites + // Use false when generating HLS files, use true when doing full hybrid tracking + bool doMultipleMatches_{true}; + + // if true, run a dummy fit, producing TTracks directly from output of tracklet pattern reco stage + bool fakefit_{false}; + + unsigned int nHelixPar_{4}; // 4 or 5 param helix fit + bool extended_{false}; // turn on displaced tracking + bool combined_{false}; // use combined TP (TE+TC) and MP (PR+ME+MC) configuration + + std::string skimfile_{""}; //if not empty events will be written out in ascii format to this file + + double bfield_{3.8112}; //B-field in T + double c_{0.299792458}; //speed of light m/ns + + unsigned int nStrips_PS_{960}; + unsigned int nStrips_2S_{1016}; + + double stripPitch_PS_{0.01}; + double stripPitch_2S_{0.009}; + + double stripLength_PS_{0.1467}; + double stripLength_2S_{5.0250}; + }; + + constexpr unsigned int N_TILTED_RINGS = 12; // # of tilted rings per half-layer in TBPS layers + constexpr std::array N_MOD_PLANK = {{7, 11, 15}}; // # of modules/plank in TBPS + + constexpr unsigned int N_TRKLSEED = 7; // # of tracklet seeds + constexpr unsigned int N_PROJ = 4; // # of projections (beyond stubs from tracklet seed) + + // chi2 fitting + constexpr unsigned int N_FITPARAM = 4; // # of fit parameters for chi2 fit + constexpr unsigned int N_FITSTUB = 6; // max # of number of stubs used + + constexpr unsigned int N_TRACKDER_PTBIN = 4; + constexpr unsigned int N_TRACKDER_INDEX = 1000; + +} // namespace trklet + +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Stub.h b/L1Trigger/TrackFindingTracklet/interface/Stub.h new file mode 100644 index 0000000000000..8b5536d270d84 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Stub.h @@ -0,0 +1,92 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_Stub_h +#define L1Trigger_TrackFindingTracklet_interface_Stub_h + +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +namespace trklet { + + class Stub { + public: + Stub(Settings const& settings); + + Stub(L1TStub& stub, Settings const& settings, double phiminsec, double phimaxsec); + + ~Stub() = default; + + FPGAWord iphivmFineBins(int VMbits, int finebits) const; + + std::string str() const { + if (layer_.value() != -1) { + return r_.str() + "|" + z_.str() + "|" + phi_.str() + "|" + bend_.str(); + } else { + if (isPSmodule()) { + return r_.str() + "|" + z_.str() + "|" + phi_.str() + "|" + bend_.str(); + } else { + return "000" + r_.str() + "|" + z_.str() + "|" + phi_.str() + "|" + alphanew_.str() + "|" + bend_.str(); + } + } + } + + std::string strbare() const { return bend_.str() + r_.str() + z_.str() + phi_.str(); } + + unsigned int phiregionaddress() const; + std::string phiregionaddressstr() const; + + void setAllStubIndex(int nstub); //should migrate away from using this method + + void setPhiCorr(int phiCorr); + + const FPGAWord& bend() const { return bend_; } + + const FPGAWord& r() const { return r_; } + const FPGAWord& z() const { return z_; } + const FPGAWord& phi() const { return phi_; } + const FPGAWord& phicorr() const { return phicorr_; } + const FPGAWord& alphanew() const { return alphanew_; } + + const FPGAWord& stubindex() const { return stubindex_; } + const FPGAWord& layer() const { return layer_; } + const FPGAWord& disk() const { return disk_; } + unsigned int layerdisk() const; + + bool isBarrel() const { return layer_.value() != -1; } + bool isDisk() const { return disk_.value() != 0; } + + bool isPSmodule() const { return isBarrel() ? (layer_.value() < (int)N_PSLAYER) : (r_.value() > 10); } + + double rapprox() const; + double zapprox() const; + double phiapprox(double phimin, double) const; + + L1TStub* l1tstub() { return l1tstub_; } + const L1TStub* l1tstub() const { return l1tstub_; } + void setl1tstub(L1TStub* l1tstub) { l1tstub_ = l1tstub; } + + private: + FPGAWord layer_; + FPGAWord disk_; + FPGAWord r_; + FPGAWord z_; + FPGAWord phi_; + FPGAWord alphanew_; + + FPGAWord bend_; + + FPGAWord phicorr_; //Corrected for bend to nominal radius + + FPGAWord stubindex_; + + L1TStub* l1tstub_; + Settings const& settings_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h b/L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h new file mode 100644 index 0000000000000..cc219691a61ff --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h @@ -0,0 +1,52 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_StubPairsMemory_h +#define L1Trigger_TrackFindingTracklet_interface_StubPairsMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubTE.h" + +#include + +namespace trklet { + + class Settings; + + class StubPairsMemory : public MemoryBase { + public: + StubPairsMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~StubPairsMemory() override = default; + + void addStubPair(const VMStubTE& stub1, + const VMStubTE& stub2, + const unsigned index = 0, + const std::string& tedName = "") { + stubs_.emplace_back(stub1, stub2); + indices_.push_back(index); + tedNames_.push_back(tedName); + } + + unsigned int nStubPairs() const { return stubs_.size(); } + + const VMStubTE& getVMStub1(unsigned int i) const { return stubs_[i].first; } + const VMStubTE& getVMStub2(unsigned int i) const { return stubs_[i].second; } + + unsigned getIndex(const unsigned i) const { return indices_.at(i); } + const std::string& getTEDName(const unsigned i) const { return tedNames_.at(i); } + + void clean() override { + stubs_.clear(); + indices_.clear(); + tedNames_.clear(); + } + + void writeSP(bool first); + + private: + std::vector > stubs_; + + std::vector indices_; + std::vector tedNames_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h b/L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h new file mode 100644 index 0000000000000..ecb2163251a38 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h @@ -0,0 +1,47 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_StubTripletsMemory_h +#define L1Trigger_TrackFindingTracklet_interface_StubTripletsMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + + class StubTripletsMemory : public MemoryBase { + public: + StubTripletsMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~StubTripletsMemory() override = default; + + void addStubs(const Stub* stub1, const Stub* stub2, const Stub* stub3) { + stubs1_.push_back(stub1); + stubs2_.push_back(stub2); + stubs3_.push_back(stub3); + } + + unsigned int nStubTriplets() const { return stubs1_.size(); } + + const Stub* getFPGAStub1(unsigned int i) const { return stubs1_[i]; } + const Stub* getFPGAStub2(unsigned int i) const { return stubs2_[i]; } + const Stub* getFPGAStub3(unsigned int i) const { return stubs3_[i]; } + + void clean() override { + stubs1_.clear(); + stubs2_.clear(); + stubs3_.clear(); + } + + void writeST(bool first); + + private: + std::vector stubs1_; + std::vector stubs2_; + std::vector stubs3_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TETableBase.h b/L1Trigger/TrackFindingTracklet/interface/TETableBase.h new file mode 100644 index 0000000000000..754ac6345c4c4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TETableBase.h @@ -0,0 +1,33 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TETableBase_h +#define L1Trigger_TrackFindingTracklet_interface_TETableBase_h + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + class Settings; + + class TETableBase { + public: + TETableBase(Settings const& settings); + + virtual ~TETableBase() = default; + + virtual void lookup(int, int) {} + + void writeVMTable(std::string name, bool positive = true); + + protected: + Settings const& settings_; + std::vector table_; + int nbits_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Timer.h b/L1Trigger/TrackFindingTracklet/interface/Timer.h new file mode 100644 index 0000000000000..866fe655aec68 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Timer.h @@ -0,0 +1,30 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_Timer_h +#define L1Trigger_TrackFindingTracklet_interface_Timer_h + +#include +#include + +namespace trklet { + + class Timer { + public: + Timer() {} + + ~Timer() = default; + + void start(); + void stop(); + unsigned int ntimes() const { return ntimes_; } + double avgtime() const { return ttot_ / ntimes_; } + double rms() const { return sqrt((ttot_ * ttot_ - ttotsq_)) / ntimes_; } + double tottime() const { return ttot_; } + + private: + unsigned int ntimes_{0}; + double ttot_{0.0}; + double ttotsq_{0.0}; + + std::chrono::high_resolution_clock::time_point tstart_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Track.h b/L1Trigger/TrackFindingTracklet/interface/Track.h new file mode 100644 index 0000000000000..cbf27a81c3f63 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Track.h @@ -0,0 +1,100 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_Track_h +#define L1Trigger_TrackFindingTracklet_interface_Track_h + +#include +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackPars.h" + +namespace trklet { + + class Track { + public: + Track(TrackPars ipars, + int ichisqrphi, + int ichisqrz, + double chisqrphi, + double chisqrz, + int hitpattern, + std::map stubID, + const std::vector& l1stub, + int seed); + + ~Track() = default; + + void setDuplicate(bool flag) { duplicate_ = flag; } + void setSector(int nsec) { sector_ = nsec; } + void setStubIDpremerge(std::vector> stubIDpremerge) { stubIDpremerge_ = stubIDpremerge; } + void setStubIDprefit(std::vector> stubIDprefit) { stubIDprefit_ = stubIDprefit; } + + const TrackPars& pars() const { return ipars_; } + + int ichisq() const { return ichisqrphi_ + ichisqrz_; } + + const std::map& stubID() const { return stubID_; } + const std::vector& stubs() const { return l1stub_; } + + //These are not used? Should be removed? + const std::vector>& stubIDpremerge() const { return stubIDpremerge_; } + const std::vector>& stubIDprefit() const { return stubIDprefit_; } + + int hitpattern() const { return hitpattern_; } + int seed() const { return seed_; } + int duplicate() const { return duplicate_; } + int sector() const { return sector_; } + + double pt(Settings const& settings) const { + return (settings.c() * settings.bfield() * 0.01) / (ipars_.rinv() * settings.krinvpars()); + } + + double phi0(Settings const& settings) const; + + double eta(Settings const& settings) const { return asinh(ipars_.t() * settings.ktpars()); } + double tanL(Settings const& settings) const { return ipars_.t() * settings.ktpars(); } + double z0(Settings const& settings) const { return ipars_.z0() * settings.kz0pars(); } + double rinv(Settings const& settings) const { return ipars_.rinv() * settings.krinvpars(); } + double d0(Settings const& settings) const { return ipars_.d0() * settings.kd0pars(); } + double chisq() const { return chisqrphi_ + chisqrz_; } + + double chisqrphi() const { return chisqrphi_; } + double chisqrz() const { return chisqrz_; } + + int nPSstubs() const { + int npsstubs = 0; + for (auto istub : l1stub_) { + if (istub->layer() < N_PSLAYER) + npsstubs++; + } + return npsstubs; + } + + private: + TrackPars ipars_; + int ichisqrphi_; + int ichisqrz_; + + double chisqrphi_; + double chisqrz_; + + int hitpattern_; + + std::vector> stubIDpremerge_; + std::vector> stubIDprefit_; + std::map stubID_; + std::vector l1stub_; + + unsigned int nstubs_; + int seed_; + bool duplicate_; + int sector_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackDer.h b/L1Trigger/TrackFindingTracklet/interface/TrackDer.h new file mode 100644 index 0000000000000..d8ac1cae0eb91 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackDer.h @@ -0,0 +1,120 @@ +// +// This class holdes the 'deriviatives' used in the linearized chi^2 fit. +// This is also referred to as the weight matrix which is used to weight +// the residuls when calculating the updated track parameters. +// +// +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackDer_h +#define L1Trigger_TrackFindingTracklet_interface_TrackDer_h + +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +namespace trklet { + + class TrackDer { + public: + TrackDer(); + + ~TrackDer() = default; + + void setIndex(int layermask, int diskmask, int alphamask, int irinv); + + int layerMask() const { return layermask_; } + int diskMask() const { return diskmask_; } + int alphaMask() const { return alphamask_; } + int irinv() const { return irinv_; } + + void setirinvdphi(int i, int irinvdphi) { irinvdphi_[i] = irinvdphi; } + void setirinvdzordr(int i, int irinvdzordr) { irinvdzordr_[i] = irinvdzordr; } + void setiphi0dphi(int i, int iphi0dphi) { iphi0dphi_[i] = iphi0dphi; } + void setiphi0dzordr(int i, int iphi0dzordr) { iphi0dzordr_[i] = iphi0dzordr; } + void setitdphi(int i, int itdphi) { itdphi_[i] = itdphi; } + void setitdzordr(int i, int itdzordr) { itdzordr_[i] = itdzordr; } + void setiz0dphi(int i, int iz0dphi) { iz0dphi_[i] = iz0dphi; } + void setiz0dzordr(int i, int iz0dzordr) { iz0dzordr_[i] = iz0dzordr; } + + void setitdzcorr(int i, int j, int itdzcorr) { itdzcorr_[i][j] = itdzcorr; } + void setiz0dzcorr(int i, int j, int iz0dzcorr) { iz0dzcorr_[i][j] = iz0dzcorr; } + + void setrinvdphi(int i, double rinvdphi) { rinvdphi_[i] = rinvdphi; } + void setrinvdzordr(int i, double rinvdzordr) { rinvdzordr_[i] = rinvdzordr; } + void setphi0dphi(int i, double phi0dphi) { phi0dphi_[i] = phi0dphi; } + void setphi0dzordr(int i, double phi0dzordr) { phi0dzordr_[i] = phi0dzordr; } + void settdphi(int i, double tdphi) { tdphi_[i] = tdphi; } + void settdzordr(int i, double tdzordr) { tdzordr_[i] = tdzordr; } + void setz0dphi(int i, double z0dphi) { z0dphi_[i] = z0dphi; } + void setz0dzordr(int i, double z0dzordr) { z0dzordr_[i] = z0dzordr; } + + void settdzcorr(int i, int j, double tdzcorr) { tdzcorr_[i][j] = tdzcorr; } + void setz0dzcorr(int i, int j, double z0dzcorr) { z0dzcorr_[i][j] = z0dzcorr; } + + double rinvdphi(int i) const { return rinvdphi_[i]; } + double rinvdzordr(int i) const { return rinvdzordr_[i]; } + double phi0dphi(int i) const { return phi0dphi_[i]; } + double phi0dzordr(int i) const { return phi0dzordr_[i]; } + double tdphi(int i) const { return tdphi_[i]; } + double tdzordr(int i) const { return tdzordr_[i]; } + double z0dphi(int i) const { return z0dphi_[i]; } + double z0dzordr(int i) const { return z0dzordr_[i]; } + + double tdzcorr(int i, int j) const { return tdzcorr_[i][j]; } + double z0dzcorr(int i, int j) const { return z0dzcorr_[i][j]; } + + double irinvdphi(int i) const { return irinvdphi_[i]; } + double irinvdzordr(int i) const { return irinvdzordr_[i]; } + double iphi0dphi(int i) const { return iphi0dphi_[i]; } + double iphi0dzordr(int i) const { return iphi0dzordr_[i]; } + double itdphi(int i) const { return itdphi_[i]; } + double itdzordr(int i) const { return itdzordr_[i]; } + double iz0dphi(int i) const { return iz0dphi_[i]; } + double iz0dzordr(int i) const { return iz0dzordr_[i]; } + + int itdzcorr(int i, int j) const { return itdzcorr_[i][j]; } + int iz0dzcorr(int i, int j) const { return iz0dzcorr_[i][j]; } + + void settpar(double t) { t_ = t; } + double tpar() const { return t_; } + + void fill(int t, double MinvDt[N_FITPARAM][N_FITSTUB * 2], int iMinvDt[N_FITPARAM][N_FITSTUB * 2]) const; + + private: + int irinvdphi_[N_FITSTUB]; + int irinvdzordr_[N_FITSTUB]; + int iphi0dphi_[N_FITSTUB]; + int iphi0dzordr_[N_FITSTUB]; + int itdphi_[N_FITSTUB]; + int itdzordr_[N_FITSTUB]; + int iz0dphi_[N_FITSTUB]; + int iz0dzordr_[N_FITSTUB]; + + int itdzcorr_[N_PSLAYER][N_PSLAYER]; + int iz0dzcorr_[N_PSLAYER][N_PSLAYER]; + + double rinvdphi_[N_FITSTUB]; + double rinvdzordr_[N_FITSTUB]; + double phi0dphi_[N_FITSTUB]; + double phi0dzordr_[N_FITSTUB]; + double tdphi_[N_FITSTUB]; + double tdzordr_[N_FITSTUB]; + double z0dphi_[N_FITSTUB]; + double z0dzordr_[N_FITSTUB]; + + double tdzcorr_[N_PSLAYER][N_PSLAYER]; + double z0dzcorr_[N_PSLAYER][N_PSLAYER]; + + double t_; + + int layermask_; + int diskmask_; + int alphamask_; + int irinv_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackDerTable.h b/L1Trigger/TrackFindingTracklet/interface/TrackDerTable.h new file mode 100644 index 0000000000000..b88ce5e26ef38 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackDerTable.h @@ -0,0 +1,86 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackDerTable_h +#define L1Trigger_TrackFindingTracklet_interface_TrackDerTable_h + +#include +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/TrackDer.h" + +namespace trklet { + + class Settings; + class Globals; + + class TrackDerTable { + public: + TrackDerTable(Settings const& settings); + + ~TrackDerTable() = default; + + const TrackDer* getDerivatives(int index) const { return &derivatives_[index]; } + + const TrackDer* getDerivatives(unsigned int layermask, + unsigned int diskmask, + unsigned int alphaindex, + unsigned int rinvindex) const; + + int getIndex(unsigned int layermask, unsigned int diskmask) const; + + void addEntry(unsigned int layermask, unsigned int diskmask, int multiplicity, int nrinv); + + void readPatternFile(std::string fileName); + + int getEntries() const { return nextLayerDiskValue_; } + + void fillTable(); + + static void invert(double M[4][8], unsigned int n); + + static void invert(std::vector >& M, unsigned int n); + + static void calculateDerivatives(Settings const& settings, + unsigned int nlayers, + double r[N_LAYER], + unsigned int ndisks, + double z[N_DISK], + double alpha[N_DISK], + double t, + double rinv, + double D[N_FITPARAM][N_FITSTUB * 2], + int iD[N_FITPARAM][N_FITSTUB * 2], + double MinvDt[N_FITPARAM][N_FITSTUB * 2], + int iMinvDt[N_FITPARAM][N_FITSTUB * 2], + double sigma[N_FITSTUB * 2], + double kfactor[N_FITSTUB * 2]); + + static double tpar(Settings const& settings, int diskmask, int layermask); + + private: + Settings const& settings_; + + std::vector LayerMem_; + std::vector DiskMem_; + std::vector LayerDiskMem_; + + unsigned int LayerMemBits_; + unsigned int DiskMemBits_; + unsigned int LayerDiskMemBits_; + unsigned int alphaBits_; + + unsigned int Nlay_; + unsigned int Ndisk_; + + std::vector derivatives_; + + int nextLayerValue_; + int nextDiskValue_; + int nextLayerDiskValue_; + int lastMultiplicity_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h b/L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h new file mode 100644 index 0000000000000..6775080971f1a --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h @@ -0,0 +1,50 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackFitMemory_h +#define L1Trigger_TrackFindingTracklet_interface_TrackFitMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + class Tracklet; + + class TrackFitMemory : public MemoryBase { + public: + TrackFitMemory(std::string name, Settings const& settings, unsigned int iSector, double phimin, double phimax); + + ~TrackFitMemory() override = default; + + void addTrack(Tracklet* tracklet) { tracks_.push_back(tracklet); } + void addStubList(std::vector stublist) { stublists_.push_back(stublist); } + void addStubidsList(std::vector> stubidslist) { stubidslists_.push_back(stubidslist); } + + unsigned int nTracks() const { return tracks_.size(); } + unsigned int nStublists() const { return stublists_.size(); } + unsigned int nStubidslists() const { return stubidslists_.size(); } + + Tracklet* getTrack(unsigned int i) { return tracks_[i]; } + std::vector getStublist(unsigned int i) const { return stublists_[i]; } + std::vector> getStubidslist(unsigned int i) const { return stubidslists_[i]; } + + void clean() override { + tracks_.clear(); + stublists_.clear(); + stubidslists_.clear(); + } + + void writeTF(bool first); + + private: + double phimin_; + double phimax_; + std::vector tracks_; + std::vector> stublists_; + std::vector>> stubidslists_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackPars.h b/L1Trigger/TrackFindingTracklet/interface/TrackPars.h new file mode 100644 index 0000000000000..1a394e6dac8a1 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackPars.h @@ -0,0 +1,50 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackPars_h +#define L1Trigger_TrackFindingTracklet_interface_TrackPars_h + +namespace trklet { + + template + class TrackPars { + public: + TrackPars() = default; + + TrackPars(T rinv, T phi0, T d0, T t, T z0) { + rinv_ = rinv; + phi0_ = phi0; + d0_ = d0; + t_ = t; + z0_ = z0; + } + + ~TrackPars() = default; + + void init(T rinv, T phi0, T d0, T t, T z0) { + rinv_ = rinv; + phi0_ = phi0; + d0_ = d0; + t_ = t; + z0_ = z0; + } + + const T& rinv() const { return rinv_; } + const T& phi0() const { return phi0_; } + const T& d0() const { return d0_; } + const T& t() const { return t_; } + const T& z0() const { return z0_; } + + T& rinv() { return rinv_; } + T& phi0() { return phi0_; } + T& d0() { return d0_; } + T& t() { return t_; } + T& z0() { return z0_; } + + private: + T rinv_; + T phi0_; + T d0_; + T t_; + T z0_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Tracklet.h b/L1Trigger/TrackFindingTracklet/interface/Tracklet.h new file mode 100644 index 0000000000000..41899ba349500 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Tracklet.h @@ -0,0 +1,567 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_Tracklet_h +#define L1Trigger_TrackFindingTracklet_interface_Tracklet_h + +#include +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" +#include "L1Trigger/TrackFindingTracklet/interface/Track.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackPars.h" +#include "L1Trigger/TrackFindingTracklet/interface/LayerProjection.h" +#include "L1Trigger/TrackFindingTracklet/interface/DiskProjection.h" +#include "L1Trigger/TrackFindingTracklet/interface/LayerResidual.h" +#include "L1Trigger/TrackFindingTracklet/interface/DiskResidual.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" + +namespace trklet { + + class Settings; + class Stub; + class Track; + + class Tracklet { + public: + Tracklet(Settings const& settings, + const L1TStub* innerStub, + const L1TStub* middleStub, + const L1TStub* outerStub, + const Stub* innerFPGAStub, + const Stub* middleFPGAStub, + const Stub* outerFPGAStub, + double rinv, + double phi0, + double d0, + double z0, + double t, + double rinvapprox, + double phi0approx, + double d0approx, + double z0approx, + double tapprox, + int irinv, + int iphi0, + int id0, + int iz0, + int it, + LayerProjection layerprojs[N_PROJ], + DiskProjection diskprojs[N_PROJ], + bool disk, + bool overlap = false); + + ~Tracklet() = default; + + //Find tp corresponding to seed. + //Will require 'tight match' such that tp is part of each of the four clustes returns 0 if no tp matches + int tpseed(); + + bool stubtruthmatch(const L1TStub* stub); + + const L1TStub* innerStub() { return innerStub_; } + const Stub* innerFPGAStub() { return innerFPGAStub_; } + + const L1TStub* middleStub() { return middleStub_; } + const Stub* middleFPGAStub() { return middleFPGAStub_; } + + const L1TStub* outerStub() { return outerStub_; } + const Stub* outerFPGAStub() { return outerFPGAStub_; } + + std::string addressstr(); + + //Tracklet parameters print out + std::string trackletparstr(); + + std::string vmstrlayer(int layer, unsigned int allstubindex); + + std::string vmstrdisk(int disk, unsigned int allstubindex); + + std::string trackletprojstr(int layer) const; + std::string trackletprojstrD(int disk) const; + + std::string trackletprojstrlayer(int layer) const { return trackletprojstr(layer); } + std::string trackletprojstrdisk(int disk) const { return trackletprojstrD(disk); } + + bool validProj(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].valid(); + } + + const FPGAWord& fpgaphiprojder(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgaphiprojder(); + } + + const FPGAWord& fpgazproj(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgazproj(); + } + + const FPGAWord& fpgaphiproj(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgaphiproj(); + } + + const FPGAWord& fpgazprojder(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgazprojder(); + } + + int zbin1projvm(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgazbin1projvm().value(); + } + + int zbin2projvm(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgazbin2projvm().value(); + } + + int finezvm(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgafinezvm().value(); + } + + int rbin1projvm(int disk) const { + assert(disk > 0 && disk <= N_DISK); + return diskproj_[disk - 1].fpgarbin1projvm().value(); + } + + int rbin2projvm(int disk) const { + assert(disk > 0 && disk <= N_DISK); + return diskproj_[disk - 1].fpgarbin2projvm().value(); + } + + int finervm(int disk) const { + assert(disk > 0 && disk <= N_DISK); + return diskproj_[disk - 1].fpgafinervm().value(); + } + + int phiprojvm(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgaphiprojvm().value(); + } + + int zprojvm(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].fpgazprojvm().value(); + } + + double phiproj(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].phiproj(); + } + + double phiprojder(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].phiprojder(); + } + + double zproj(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].zproj(); + } + + double zprojder(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].zprojder(); + } + + double zprojapprox(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].zprojapprox(); + } + + double zprojderapprox(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].zprojderapprox(); + } + + double phiprojapprox(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].phiprojapprox(); + } + + double phiprojderapprox(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].phiprojderapprox(); + } + + double rproj(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerproj_[layer - 1].rproj(); + } + + double rstub(int layer) { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].rstub(); + } + + //Disks residuals + + bool validProjDisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].valid(); + } + + const FPGAWord& fpgaphiresiddisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].fpgaphiresid(); + } + + const FPGAWord& fpgarresiddisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].fpgarresid(); + } + + double phiresiddisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].phiresid(); + } + + double rresiddisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].rresid(); + } + + double phiresidapproxdisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].phiresidapprox(); + } + + double rresidapproxdisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].rresidapprox(); + } + + double zstubdisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].zstub(); + } + + void setBendIndex(int bendIndex, int disk) { + assert(abs(disk) <= N_DISK); + diskproj_[abs(disk) - 1].setBendIndex(bendIndex); + } + + const FPGAWord& getBendIndex(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].getBendIndex(); + } + + double alphadisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].alpha(); + } + + const FPGAWord& ialphadisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].ialpha(); + } + + const FPGAWord& fpgaphiprojdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].fpgaphiproj(); + } + + const FPGAWord& fpgaphiprojderdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].fpgaphiprojder(); + } + + const FPGAWord& fpgarprojdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].fpgarproj(); + } + + const FPGAWord& fpgarprojderdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].fpgarprojder(); + } + + double phiprojapproxdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].phiprojapprox(); + } + + double phiprojderapproxdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].phiprojderapprox(); + } + + double rprojapproxdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].rprojapprox(); + } + + double rprojderapproxdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].rprojderapprox(); + } + + double phiprojdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].phiproj(); + } + + double phiprojderdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].phiprojder(); + } + + double rprojdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].rproj(); + } + + double rprojderdisk(int disk) const { + assert(abs(disk) <= N_DISK); + return diskproj_[abs(disk) - 1].rprojder(); + } + + bool matchdisk(int disk) { + assert(abs(disk) <= N_DISK); + return diskresid_[abs(disk) - 1].valid(); + } + + void addMatch(int layer, + int ideltaphi, + int ideltaz, + double dphi, + double dz, + double dphiapprox, + double dzapprox, + int stubid, + double rstub, + const trklet::Stub* stubptr); + + void addMatchDisk(int disk, + int ideltaphi, + int ideltar, + double dphi, + double dr, + double dphiapprox, + double drapprox, + double alpha, + int stubid, + double zstub, + const trklet::Stub* stubptr); + + int nMatches(); + int nMatchesDisk(); + + bool match(int layer) { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].valid(); + } + + std::string fullmatchstr(int layer); + std::string fullmatchdiskstr(int disk); + + bool validResid(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].valid(); + } + + const trklet::Stub* stubptr(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].stubptr(); + } + + double phiresid(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].phiresid(); + } + + double phiresidapprox(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].phiresidapprox(); + } + + double zresid(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].zresid(); + } + + double zresidapprox(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].zresidapprox(); + } + + const FPGAWord& fpgaphiresid(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].fpgaphiresid(); + } + + const FPGAWord& fpgazresid(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + return layerresid_[layer - 1].fpgazresid(); + } + + std::vector getL1Stubs(); + + std::map getStubIDs(); + + double rinv() const { return trackpars_.rinv(); } + double phi0() const { return trackpars_.phi0(); } + double d0() const { return trackpars_.d0(); } + double t() const { return trackpars_.t(); } + double z0() const { return trackpars_.z0(); } + + double rinvapprox() const { return trackparsapprox_.rinv(); } + double phi0approx() const { return trackparsapprox_.phi0(); } + double d0approx() const { return trackparsapprox_.d0(); } + double tapprox() const { return trackparsapprox_.t(); } + double z0approx() const { return trackparsapprox_.z0(); } + + const FPGAWord& fpgarinv() const { return fpgapars_.rinv(); } + const FPGAWord& fpgaphi0() const { return fpgapars_.phi0(); } + const FPGAWord& fpgad0() const { return fpgapars_.d0(); } + const FPGAWord& fpgat() const { return fpgapars_.t(); } + const FPGAWord& fpgaz0() const { return fpgapars_.z0(); } + + double rinvfit() const { return fitpars_.rinv(); } + double phi0fit() const { return fitpars_.phi0(); } + double d0fit() const { return fitpars_.d0(); } + double tfit() const { return fitpars_.t(); } + double z0fit() const { return fitpars_.z0(); } + double chiSqfit() const { return chisqrphifit_ + chisqrzfit_; } + + double rinvfitexact() const { return fitparsexact_.rinv(); } + double phi0fitexact() const { return fitparsexact_.phi0(); } + double d0fitexact() const { return fitparsexact_.d0(); } + double tfitexact() const { return fitparsexact_.t(); } + double z0fitexact() const { return fitparsexact_.z0(); } + + const FPGAWord& irinvfit() const { return fpgafitpars_.rinv(); } + const FPGAWord& iphi0fit() const { return fpgafitpars_.phi0(); } + const FPGAWord& id0fit() const { return fpgafitpars_.d0(); } + const FPGAWord& itfit() const { return fpgafitpars_.t(); } + const FPGAWord& iz0fit() const { return fpgafitpars_.z0(); } + FPGAWord ichiSqfit() const { + return FPGAWord(ichisqrphifit_.value() + ichisqrzfit_.value(), ichisqrphifit_.nbits()); + } + + void setFitPars(double rinvfit, + double phi0fit, + double d0fit, + double tfit, + double z0fit, + double chisqrphifit, + double chisqrzfit, + double rinvfitexact, + double phi0fitexact, + double d0fitexact, + double tfitexact, + double z0fitexact, + double chisqrphifitexact, + double chisqrzfitexact, + int irinvfit, + int iphi0fit, + int id0fit, + int itfit, + int iz0fit, + int ichisqrphifit, + int ichisqrzfit, + int hitpattern, + const std::vector& l1stubs = std::vector()); + + std::string trackfitstr(); + + Track makeTrack(const std::vector& l1stubs); + + Track* getTrack() { + assert(fpgatrack_ != nullptr); + return fpgatrack_.get(); + } + + bool fit() const { return ichisqrphifit_.value() != -1; } + + int layer() const; + int disk() const; + int disk2() const; + + bool isBarrel() const { return barrel_; } + bool isOverlap() const { return overlap_; } + int isDisk() const { return disk_; } + + void setTrackletIndex(int index); + + int trackletIndex() const { return trackletIndex_; } + + void setTCIndex(int index) { TCIndex_ = index; } + + int TCIndex() const { return TCIndex_; } + + int TCID() const { return TCIndex_ * (1 << 7) + trackletIndex_; } + + int getISeed() const; + int getITC() const; + + unsigned int PSseed() const { return ((layer() == 1) || (layer() == 2) || (disk() != 0)) ? 1 : 0; } + + unsigned int seedIndex() const { return seedIndex_; } + + unsigned int calcSeedIndex() const; + + private: + unsigned int seedIndex_; + + // three types of tracklets + one triplet + bool barrel_; + bool disk_; + bool overlap_; + bool triplet_; + + const Stub* innerFPGAStub_; + const Stub* middleFPGAStub_; + const Stub* outerFPGAStub_; + + const L1TStub* innerStub_; + const L1TStub* middleStub_; + const L1TStub* outerStub_; + + int trackletIndex_; + int TCIndex_; + + //Tracklet track parameters + TrackPars fpgapars_; + + TrackPars trackpars_; + TrackPars trackparsapprox_; + + // the layer/disk ids that we project to (never project to >4 barrel layers) + int projlayer_[N_LAYER - 2]; + int projdisk_[N_DISK]; + + //Track parameters from track fit + TrackPars fpgafitpars_; + FPGAWord ichisqrphifit_; + FPGAWord ichisqrzfit_; + + TrackPars fitpars_; + double chisqrphifit_; + double chisqrzfit_; + + TrackPars fitparsexact_; + double chisqrphifitexact_; + double chisqrzfitexact_; + + int hitpattern_; + + std::unique_ptr fpgatrack_; + + LayerProjection layerproj_[N_LAYER]; + DiskProjection diskproj_[N_DISK]; + + LayerResidual layerresid_[N_LAYER]; + DiskResidual diskresid_[N_DISK]; + + Settings const& settings_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletCalculator.h b/L1Trigger/TrackFindingTracklet/interface/TrackletCalculator.h new file mode 100644 index 0000000000000..cb1fb663b2978 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletCalculator.h @@ -0,0 +1,38 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletCalculator_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletCalculator_h + +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorBase.h" + +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class TrackletProjectionsMemory; + class MemoryBase; + class AllStubsMemory; + class StubPairsMemory; + + class TrackletCalculator : public TrackletCalculatorBase { + public: + TrackletCalculator(std::string name, Settings const& settings, Globals* globals, unsigned int iSector); + + ~TrackletCalculator() override = default; + + void addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory); + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + private: + int iTC_; + + std::vector innerallstubs_; + std::vector outerallstubs_; + std::vector stubpairs_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorBase.h b/L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorBase.h new file mode 100644 index 0000000000000..46bc10760ac1c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorBase.h @@ -0,0 +1,147 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletCalculatorBase_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletCalculatorBase_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" + +#include + +namespace trklet { + + class Settings; + class Globals; + class Stub; + class L1TStub; + class Tracklet; + + class TrackletCalculatorBase : public ProcessBase { + public: + TrackletCalculatorBase(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~TrackletCalculatorBase() override = default; + + void exacttracklet(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double, + double& rinv, + double& phi0, + double& t, + double& z0, + double phiproj[N_LAYER - 2], //=4 + double zproj[N_LAYER - 2], + double phider[N_LAYER - 2], + double zder[N_LAYER - 2], + double phiprojdisk[N_DISK], //=5 + double rprojdisk[N_DISK], + double phiderdisk[N_DISK], + double rderdisk[N_DISK]); + + void exacttrackletdisk(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double, + double& rinv, + double& phi0, + double& t, + double& z0, + double phiprojLayer[N_PSLAYER], //=3 + double zprojLayer[N_PSLAYER], + double phiderLayer[N_PSLAYER], + double zderLayer[N_PSLAYER], + double phiproj[N_DISK - 2], //=3 + double rproj[N_DISK - 2], + double phider[N_DISK - 2], + double rder[N_DISK - 2]); + + void exacttrackletOverlap(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double, + double& rinv, + double& phi0, + double& t, + double& z0, + double phiprojLayer[N_PSLAYER], //=3 + double zprojLayer[N_PSLAYER], + double phiderLayer[N_PSLAYER], + double zderLayer[N_PSLAYER], + double phiproj[N_DISK - 2], //=3 + double rproj[N_DISK - 2], + double phider[N_DISK - 2], + double rder[N_DISK - 2]); + + void exactproj(double rproj, + double rinv, + double phi0, + double t, + double z0, + double& phiproj, + double& zproj, + double& phider, + double& zder); + + void exactprojdisk(double zproj, + double rinv, + double phi0, + double t, + double z0, + double& phiproj, + double& rproj, + double& phider, + double& rder); + + void addDiskProj(Tracklet* tracklet, int disk); + bool addLayerProj(Tracklet* tracklet, int layer); + + void addProjection(int layer, int iphi, TrackletProjectionsMemory* trackletprojs, Tracklet* tracklet); + void addProjectionDisk(int disk, int iphi, TrackletProjectionsMemory* trackletprojs, Tracklet* tracklet); + + bool goodTrackPars(bool goodrinv, bool goodz0); + + bool inSector(int iphi0, int irinv, double phi0approx, double rinvapprox); + + bool barrelSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub); + bool diskSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub); + bool overlapSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub); + + protected: + unsigned int iSeed_; + unsigned int layerdisk1_; + unsigned int layerdisk2_; + + int TCIndex_; + + double phioffset_; + + int layer_; + int disk_; + + TrackletParametersMemory* trackletpars_; + + //First index is layer/disk second is phi region + std::vector > trackletprojlayers_; + std::vector > trackletprojdisks_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorDisplaced.h b/L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorDisplaced.h new file mode 100644 index 0000000000000..4d86e7a98310b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorDisplaced.h @@ -0,0 +1,132 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletCalculatorDisplaced_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletCalculatorDisplaced_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" + +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class Stub; + class L1TStub; + + class TrackletCalculatorDisplaced : public ProcessBase { + public: + TrackletCalculatorDisplaced(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~TrackletCalculatorDisplaced() override = default; + + void addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory); + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + void addDiskProj(Tracklet* tracklet, int disk); + bool addLayerProj(Tracklet* tracklet, int layer); + + void addProjection(int layer, int iphi, TrackletProjectionsMemory* trackletprojs, Tracklet* tracklet); + void addProjectionDisk(int disk, int iphi, TrackletProjectionsMemory* trackletprojs, Tracklet* tracklet); + + bool LLLSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* middleFPGAStub, + const L1TStub* middleStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub); + bool DDLSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* middleFPGAStub, + const L1TStub* middleStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub); + bool LLDSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* middleFPGAStub, + const L1TStub* middleStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub); + + void exactproj(double rproj, + double rinv, + double phi0, + double d0, + double t, + double z0, + double r0, + double& phiproj, + double& zproj, + double& phider, + double& zder); + + void exactprojdisk(double zproj, + double rinv, + double, + double, //phi0 and d0 are not used. + double t, + double z0, + double x0, + double y0, + double& phiproj, + double& rproj, + double& phider, + double& rder); + + void exacttracklet(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double r3, + double z3, + double phi3, + int take3, + double& rinv, + double& phi0, + double& d0, + double& t, + double& z0, + double phiproj[N_LAYER - 2], + double zproj[N_LAYER - 2], + double phiprojdisk[N_DISK], + double rprojdisk[N_DISK], + double phider[N_LAYER - 2], + double zder[N_LAYER - 2], + double phiderdisk[N_DISK], + double rderdisk[N_DISK]); + + private: + int TCIndex_; + int layer_; + int disk_; + double rproj_[N_LAYER - 2]; + int lproj_[N_LAYER - 2]; + double zproj_[N_DISK - 2]; + int dproj_[N_DISK - 2]; + + std::vector toR_; + std::vector toZ_; + + std::vector innerallstubs_; + std::vector middleallstubs_; + std::vector outerallstubs_; + std::vector stubtriplets_; + + TrackletParametersMemory* trackletpars_; + + //First index is layer/disk second is phi region + std::vector > trackletprojlayers_; + std::vector > trackletprojdisks_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletEngine.h b/L1Trigger/TrackFindingTracklet/interface/TrackletEngine.h new file mode 100644 index 0000000000000..a6fd3f9492fe2 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletEngine.h @@ -0,0 +1,55 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletEngine_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletEngine_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" + +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class VMStubsTEMemory; + class StubPairsMemory; + + class TrackletEngine : public ProcessBase { + public: + TrackletEngine(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~TrackletEngine() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + void setVMPhiBin(); + + void writeTETable(); + + private: + //Which seed type and which layer/disk is used + unsigned int iSeed_; + unsigned int layerdisk1_; //inner seeding layer + unsigned int layerdisk2_; //outer seeding layer + + //The input vmstubs memories + VMStubsTEMemory* innervmstubs_; + VMStubsTEMemory* outervmstubs_; + + //The output stub pair memory + StubPairsMemory* stubpairs_; + + //The stub pt (bend) lookup table for the inner and outer stub + std::vector pttableinner_; + std::vector pttableouter_; + + //Number of phi bits used in the lookup table + unsigned int innerphibits_; + unsigned int outerphibits_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletEngineDisplaced.h b/L1Trigger/TrackFindingTracklet/interface/TrackletEngineDisplaced.h new file mode 100644 index 0000000000000..6affb50111dfb --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletEngineDisplaced.h @@ -0,0 +1,52 @@ +// TrackletEngineDisplaced: this class forms tracklets (pairs of stubs) w/o beamspot constraint for the displaced (extended) tracking. +// Triplet seeds are formed in the TripletEngine from these (=TrackletEngineDisplaced) + a third stub. +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletEngineDisplaced_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletEngineDisplaced_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" + +#include +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class VMStubsTEMemory; + class StubPairsMemory; + + class TrackletEngineDisplaced : public ProcessBase { + public: + TrackletEngineDisplaced(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~TrackletEngineDisplaced() override; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + void readTables(); + + private: + int layer1_; + int layer2_; + int disk1_; + int disk2_; + + std::vector firstvmstubs_; + VMStubsTEMemory* secondvmstubs_; + + std::vector stubpairs_; + + std::vector > table_; + + int firstphibits_; + int secondphibits_; + + int iSeed_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h b/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h new file mode 100644 index 0000000000000..b22e775b89a07 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h @@ -0,0 +1,70 @@ +// TrackletEventProcessor: Class responsible for the main event processing for the tracklet algorithm +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletEventProcessor_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletEventProcessor_h + +#include "L1Trigger/TrackFindingTracklet/interface/Timer.h" + +#include +#include +#include +#include + +namespace trklet { + + class Settings; + class SLHCEvent; + class Globals; + class Sector; + class HistBase; + class Track; + class Cabling; + + class TrackletEventProcessor { + public: + TrackletEventProcessor(); + + ~TrackletEventProcessor(); + + void init(Settings const& theSettings); + + void event(SLHCEvent& ev); + + void printSummary(); + + std::vector& tracks() { return tracks_; } + + private: + const Settings* settings_{nullptr}; + + std::unique_ptr globals_; + + std::vector > sectors_; + + HistBase* histbase_{}; + + int eventnum_ = {0}; + + std::unique_ptr cabling_; + + Timer cleanTimer_; + Timer addStubTimer_; + Timer VMRouterTimer_; + Timer TETimer_; + Timer TEDTimer_; + Timer TRETimer_; + Timer TCTimer_; + Timer TCDTimer_; + Timer PRTimer_; + Timer METimer_; + Timer MCTimer_; + Timer MPTimer_; + Timer FTTimer_; + Timer PDTimer_; + + std::vector tracks_; + + std::map > dtclayerdisk_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h b/L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h new file mode 100644 index 0000000000000..088f937dcbc4c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h @@ -0,0 +1,40 @@ +// TrackletParametersMemory: This class holds the tracklet parameters for selected stub pairs. +// This class owns the tracklets. Further modules only holds pointers. +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletParametersMemory_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletParametersMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class Tracklet; + + class TrackletParametersMemory : public MemoryBase { + public: + TrackletParametersMemory(std::string name, Settings const &settings, unsigned int iSector); + + ~TrackletParametersMemory() override = default; + + void addTracklet(Tracklet *tracklet) { tracklets_.push_back(tracklet); } + + unsigned int nTracklets() const { return tracklets_.size(); } + + Tracklet *getTracklet(unsigned int i) { return tracklets_[i]; } + + void clean() override; + + void writeMatches(Globals *globals, int &matchesL1, int &matchesL3, int &matchesL5); + + void writeTPAR(bool first); + + private: + std::vector tracklets_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletProcessor.h b/L1Trigger/TrackFindingTracklet/interface/TrackletProcessor.h new file mode 100644 index 0000000000000..b8cb5601cf8c0 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletProcessor.h @@ -0,0 +1,59 @@ +// TrackletProcessor: this class is an evolved version, performing the tasks of the TrackletEngine+TrackletCalculator. +// It will combine TEs that feed into a TC to a single module. +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletProcessor_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletProcessor_h + +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" + +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + + class TrackletProcessor : public TrackletCalculatorBase { + public: + TrackletProcessor(std::string name, Settings const& settings, Globals* globals, unsigned int iSector); + + ~TrackletProcessor() override = default; + + void addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory); + + void addOutput(MemoryBase* memory, std::string output) override; + + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + void setVMPhiBin(); + + void writeTETable(); + + private: + int iTC_; + + std::vector innervmstubs_; + std::vector outervmstubs_; + + std::vector innerallstubs_; + std::vector outerallstubs_; + + bool extra_; + + std::map > phitable_; + std::map > pttableinner_; + std::map > pttableouter_; + + int innerphibits_; + int outerphibits_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h b/L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h new file mode 100644 index 0000000000000..3d376d3b98dcc --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h @@ -0,0 +1,42 @@ +// TrackletProjectionsMemory: this class holds the +#ifndef L1Trigger_TrackFindingTracklet_interface_TrackletProjectionsMemory_h +#define L1Trigger_TrackFindingTracklet_interface_TrackletProjectionsMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include +#include + +namespace trklet { + + class Settings; + class Tracklet; + + class TrackletProjectionsMemory : public MemoryBase { + public: + TrackletProjectionsMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~TrackletProjectionsMemory() override = default; + + void addProj(Tracklet* tracklet); + + unsigned int nTracklets() const { return tracklets_.size(); } + + Tracklet* getTracklet(unsigned int i) { return tracklets_[i]; } + + void clean() override; + + void writeTPROJ(bool first); + + int layer() const { return layer_; } + int disk() const { return disk_; } + + private: + std::vector tracklets_; + + int layer_; + int disk_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/TripletEngine.h b/L1Trigger/TrackFindingTracklet/interface/TripletEngine.h new file mode 100644 index 0000000000000..1652262c1808a --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/TripletEngine.h @@ -0,0 +1,70 @@ +// TripletEngine: Adds third stub to stub pairs found by TrackletEngineDisplaced to form "triplet" seeds for the displaced (extended) tracking +#ifndef L1Trigger_TrackFindingTracklet_interface_TripletEngine_h +#define L1Trigger_TrackFindingTracklet_interface_TripletEngine_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" + +#include +#include + +namespace trklet { + + class Settings; + class Globals; + + class TripletEngine : public ProcessBase { + public: + TripletEngine(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~TripletEngine() override; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + void readTables(); + void writeTables(); + + private: + int count_; + + int layer1_; + int layer2_; + int layer3_; + int disk1_; + int disk2_; + int disk3_; + int dct1_; + int dct2_; + int dct3_; + int phi1_; + int phi2_; + int phi3_; + int z1_; + int z2_; + int z3_; + int r1_; + int r2_; + int r3_; + + std::vector thirdvmstubs_; + std::vector stubpairs_; + + StubTripletsMemory* stubtriplets_; + + std::map > > tmpSPTable_; + std::map > > spTable_; + std::vector table_; + + int secondphibits_; + int thirdphibits_; + + int iSeed_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/Util.h b/L1Trigger/TrackFindingTracklet/interface/Util.h new file mode 100644 index 0000000000000..6d448d3109bff --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/Util.h @@ -0,0 +1,179 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_Util_h +#define L1Trigger_TrackFindingTracklet_interface_Util_h + +#include +#include +#include + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +namespace trklet { + + //Converts string in binary to hex (used in writing out memory content) + inline std::string hexFormat(const std::string& binary) { + std::string tmp = ""; + + unsigned int value = 0; + + for (unsigned int i = 0; i < binary.size(); i++) { + unsigned int slot = binary.size() - i - 1; + if (!(binary[slot] == '0' || binary[slot] == '1')) + continue; + value = value + (binary[slot] - '0'); + } + + std::stringstream ss; + ss << "0x" << std::hex << value; + + return ss.str(); + } + + //Should be optimized by layer - now first implementation to make sure it works OK + inline int bendencode(double bend, bool isPS) { + int ibend = 2.0 * bend; + + assert(std::abs(ibend - 2.0 * bend) < 0.1); + + if (isPS) { + if (ibend == 0 || ibend == 1) + return 0; + if (ibend == 2 || ibend == 3) + return 1; + if (ibend == 4 || ibend == 5) + return 2; + if (ibend >= 6) + return 3; + if (ibend == -1 || ibend == -2) + return 4; + if (ibend == -3 || ibend == -4) + return 5; + if (ibend == -5 || ibend == -6) + return 6; + if (ibend <= -7) + return 7; + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ + << " Unknown bendencode for PS module for bend = " << bend + << " ibend = " << ibend; + } + + if (ibend == 0 || ibend == 1) + return 0; + if (ibend == 2 || ibend == 3) + return 1; + if (ibend == 4 || ibend == 5) + return 2; + if (ibend == 6 || ibend == 7) + return 3; + if (ibend == 8 || ibend == 9) + return 4; + if (ibend == 10 || ibend == 11) + return 5; + if (ibend == 12 || ibend == 13) + return 6; + if (ibend >= 14) + return 7; + if (ibend == -1 || ibend == -2) + return 8; + if (ibend == -3 || ibend == -4) + return 9; + if (ibend == -5 || ibend == -6) + return 10; + if (ibend == -7 || ibend == -8) + return 11; + if (ibend == -9 || ibend == -10) + return 12; + if (ibend == -11 || ibend == -12) + return 13; + if (ibend == -13 || ibend == -14) + return 14; + if (ibend <= -15) + return 15; + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ + << " Unknown bendencode for 2S module for bend = " << bend + << " ibend = " << ibend; + } + + //Should be optimized by layer - now first implementation to make sure it works OK + inline double benddecode(int ibend, bool isPS) { + if (isPS) { + if (ibend == 0) + return 0.25; + if (ibend == 1) + return 1.25; + if (ibend == 2) + return 2.25; + if (ibend == 3) + return 3.25; + if (ibend == 4) + return -0.75; + if (ibend == 5) + return -1.75; + if (ibend == 6) + return -2.75; + if (ibend == 7) + return -3.75; + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ + << " Unknown benddecode for PS module for ibend = " << ibend; + } + + if (ibend == 0) + return 0.25; + if (ibend == 1) + return 1.25; + if (ibend == 2) + return 2.25; + if (ibend == 3) + return 3.25; + if (ibend == 4) + return 4.25; + if (ibend == 5) + return 5.25; + if (ibend == 6) + return 6.25; + if (ibend == 7) + return 7.25; + if (ibend == 8) + return -0.75; + if (ibend == 9) + return -1.75; + if (ibend == 10) + return -2.75; + if (ibend == 11) + return -3.75; + if (ibend == 12) + return -4.75; + if (ibend == 13) + return -5.75; + if (ibend == 14) + return -6.75; + if (ibend == 15) + return -7.75; + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ + << " Unknown benddecode for 2S module for ibend = " << ibend; + } + + inline double bend(double r, double rinv, double stripPitch) { + constexpr double dr = 0.18; + double delta = r * dr * 0.5 * rinv; + double bend = -delta / stripPitch; + return bend; + } + + inline double rinv(double phi1, double phi2, double r1, double r2) { + if (r2 <= r1) { //can not form tracklet + return 20.0; + } + + double dphi = phi2 - phi1; + double dr = r2 - r1; + + return 2.0 * sin(dphi) / dr / sqrt(1.0 + 2 * r1 * r2 * (1.0 - cos(dphi)) / (dr * dr)); + } + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h b/L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h new file mode 100644 index 0000000000000..1b3e37aba7184 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h @@ -0,0 +1,41 @@ +// VMProjectionsMemory: Class to hold a reduced format of the tracklet projections (from ProjectionRouter) +#ifndef L1Trigger_TrackFindingTracklet_interface_VMProjectionsMemory_h +#define L1Trigger_TrackFindingTracklet_interface_VMProjectionsMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include + +namespace trklet { + + class Settings; + class Tracklet; + + class VMProjectionsMemory : public MemoryBase { + public: + VMProjectionsMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~VMProjectionsMemory() override = default; + + void addTracklet(Tracklet* tracklet, unsigned int allprojindex); + + unsigned int nTracklets() const { return tracklets_.size(); } + + Tracklet* getTracklet(unsigned int i) { return tracklets_[i].first; } + int getAllProjIndex(unsigned int i) const { return tracklets_[i].second; } + + void writeVMPROJ(bool first); + + void clean() override { tracklets_.clear(); } + + int layer() const { return layer_; } + int disk() const { return disk_; } + + private: + int layer_; + int disk_; + std::vector > tracklets_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMRouter.h b/L1Trigger/TrackFindingTracklet/interface/VMRouter.h new file mode 100644 index 0000000000000..5e93482182cfe --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMRouter.h @@ -0,0 +1,73 @@ +// VMRouter: sorts input stubs into smaller units in phi (and possibly z), referred to as "Virtual Modules" (VMs) +#ifndef L1Trigger_TrackFindingTracklet_interface_VMRouter_h +#define L1Trigger_TrackFindingTracklet_interface_VMRouter_h + +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMRouterTable.h" + +#include +#include +#include + +namespace trklet { + + class Settings; + class Globals; + class MemoryBase; + class InputLinkMemory; + class AllStubsMemory; + class VMStubsMEMemory; + class VMStubsTEMemory; + + struct VMStubsTEPHI { + VMStubsTEPHI(unsigned int seednumber_, + unsigned int stubposition_, + std::vector > vmstubmem_) + : seednumber(seednumber_), stubposition(stubposition_), vmstubmem(vmstubmem_){}; + + unsigned int seednumber; //seed number [0,11] + unsigned int stubposition; //stub position in the seed + std::vector > + vmstubmem; // m_vmstubmem[iVM][n] is the VMStubsTEMemory for iVM and the nth copy + }; + + class VMRouter : public ProcessBase { + public: + VMRouter(std::string name, Settings const& settings, Globals* global, unsigned int iSector); + + ~VMRouter() override = default; + + void addOutput(MemoryBase* memory, std::string output) override; + void addInput(MemoryBase* memory, std::string input) override; + + void execute(); + + private: + //0-5 are the layers and 6-10 are the disks + unsigned int layerdisk_; + + //overlapbits_ is the top bits of phicorr used to add or subtract one to see if stub should be added to + //two VMs. nextrabits_ is the number of bits beyond the bits for the phivm that is used by overlapbits_ + unsigned int overlapbits_; + unsigned int nextrabits_; + + int nbitszfinebintable_; + int nbitsrfinebintable_; + + VMRouterTable vmrtable_; + + //The input stub memories + std::vector stubinputs_; + + //The all stub memories + std::vector allstubs_; + + //The VM stubs memories used by the MEs + std::vector vmstubsMEPHI_; + + //The VM stubs memories used by the TEs (using structure defined above) + std::vector vmstubsTEPHI_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMRouterPhiCorrTable.h b/L1Trigger/TrackFindingTracklet/interface/VMRouterPhiCorrTable.h new file mode 100644 index 0000000000000..ec1907230e6b0 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMRouterPhiCorrTable.h @@ -0,0 +1,44 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_VMRouterPhiCorrTable_h +#define L1Trigger_TrackFindingTracklet_interface_VMRouterPhiCorrTable_h + +#include "L1Trigger/TrackFindingTracklet/interface/TETableBase.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + class Settings; + + class VMRouterPhiCorrTable : public TETableBase { + public: + VMRouterPhiCorrTable(Settings const& settings); + + ~VMRouterPhiCorrTable() override = default; + + void init(int layer, int bendbits, int rbits); + + int getphiCorrValue(int ibend, int irbin) const; + + int lookupPhiCorr(int ibend, int rbin); + + private: + double rmean_; + double rmin_; + double rmax_; + + double dr_; + + int bendbits_; + int rbits_; + + int bendbins_; + int rbins_; + + int layer_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMRouterTable.h b/L1Trigger/TrackFindingTracklet/interface/VMRouterTable.h new file mode 100644 index 0000000000000..1f6e3a660c6e4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMRouterTable.h @@ -0,0 +1,60 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_VMRouterTable_h +#define L1Trigger_TrackFindingTracklet_interface_VMRouterTable_h + +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include +#include +#include +#include +#include + +namespace trklet { + + class Settings; + + class VMRouterTable { + public: + VMRouterTable(Settings const& settings); + VMRouterTable(Settings const& settings, unsigned int layerdisk); + + ~VMRouterTable() = default; + + void init(unsigned int layerdisk); + + // negative return means that seed can not be formed + int getLookup(unsigned int layerdisk, double z, double r, int iseed = -1); + + int lookup(int zbin, int rbin); + int lookupdisk(int zbin, int rbin); + int lookupinner(int zbin, int rbin); + int lookupinneroverlap(int zbin, int rbin); + int lookupinnerThird(int zbin, int rbin); + + private: + Settings const& settings_; + + double rmin_; + double rmax_; + + double zmin_; + double zmax_; + + double dr_; + double dz_; + + int zbits_; + int rbits_; + + int zbins_; + int rbins_; + + //int layer_; + std::vector vmrtable_; //used for ME and outer TE + std::vector vmrtabletedisk_; //outer disk used by D1, D2, and D4 + std::vector vmrtableteinner_; //projection to next layer/disk + std::vector vmrtableteinneroverlap_; //projection to disk + std::vector vmrtableteinnerThird_; //projection to disk1 for extended - iseed=10 + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMStubME.h b/L1Trigger/TrackFindingTracklet/interface/VMStubME.h new file mode 100644 index 0000000000000..498c8e8819e05 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMStubME.h @@ -0,0 +1,46 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_VMStubME_h +#define L1Trigger_TrackFindingTracklet_interface_VMStubME_h + +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +namespace trklet { + + class VMStubME { + public: + VMStubME() {} + + VMStubME(const Stub* stub, FPGAWord finephi, FPGAWord finerz, FPGAWord bend, FPGAWord allstubindex); + + ~VMStubME() = default; + + const FPGAWord& finephi() const { return finephi_; } + const FPGAWord& finerz() const { return finerz_; } + + const FPGAWord& bend() const { return bend_; } + + const Stub* stub() const { return stub_; } + + bool isPSmodule() const { return stub_->isPSmodule(); } + + const FPGAWord& stubindex() const { return allStubIndex_; } + + //return binary string for memory printout + std::string str() const; + + private: + FPGAWord allStubIndex_; + FPGAWord finephi_; + FPGAWord finerz_; + FPGAWord bend_; + const Stub* stub_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMStubTE.h b/L1Trigger/TrackFindingTracklet/interface/VMStubTE.h new file mode 100644 index 0000000000000..62160ea63440d --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMStubTE.h @@ -0,0 +1,46 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_VMStubTE_h +#define L1Trigger_TrackFindingTracklet_interface_VMStubTE_h + +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +namespace trklet { + + class VMStubTE { + public: + VMStubTE() {} + + VMStubTE(const Stub* stub, FPGAWord finephi, FPGAWord bend, FPGAWord vmbits, FPGAWord allstubindex); + + ~VMStubTE() = default; + + const FPGAWord& finephi() const { return finephi_; } + + const FPGAWord& bend() const { return bend_; } + + const FPGAWord& vmbits() const { return vmbits_; } + + const Stub* stub() const { return stub_; } + + bool isPSmodule() const { return stub_->isPSmodule(); } + + const FPGAWord& stubindex() const { return allStubIndex_; } + + //return binary string for memory printout + std::string str() const; + + private: + FPGAWord finephi_; + FPGAWord bend_; + FPGAWord vmbits_; + FPGAWord allStubIndex_; + const Stub* stub_; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h b/L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h new file mode 100644 index 0000000000000..57e7dcf085d41 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h @@ -0,0 +1,58 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_VMStubsMEMemory_h +#define L1Trigger_TrackFindingTracklet_interface_VMStubsMEMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubME.h" + +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + + class VMStubsMEMemory : public MemoryBase { + public: + VMStubsMEMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~VMStubsMEMemory() override = default; + + void addStub(VMStubME stub, unsigned int bin) { + if (binnedstubs_[bin].size() < settings_.maxStubsPerBin()) { + binnedstubs_[bin].push_back(stub); + } + } + + unsigned int nStubsBin(unsigned int bin) const { + assert(bin < binnedstubs_.size()); + return binnedstubs_[bin].size(); + } + + const VMStubME& getVMStubMEBin(unsigned int bin, unsigned int i) const { + assert(bin < binnedstubs_.size()); + assert(i < binnedstubs_[bin].size()); + return binnedstubs_[bin][i]; + } + + const Stub* getStubBin(unsigned int bin, unsigned int i) const { + assert(bin < binnedstubs_.size()); + assert(i < binnedstubs_[bin].size()); + return binnedstubs_[bin][i].stub(); + } + + void clean() override { + for (auto& binnedstub : binnedstubs_) { + binnedstub.clear(); + } + } + + void writeStubs(bool first); + + private: + std::vector > binnedstubs_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h b/L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h new file mode 100644 index 0000000000000..f16a0a35a10c4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h @@ -0,0 +1,72 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_VMStubsTEMemory_h +#define L1Trigger_TrackFindingTracklet_interface_VMStubsTEMemory_h + +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubTE.h" + +#include +#include + +namespace trklet { + + class Settings; + class Stub; + class L1TStub; + + class VMStubsTEMemory : public MemoryBase { + public: + VMStubsTEMemory(std::string name, Settings const& settings, unsigned int iSector); + + ~VMStubsTEMemory() override = default; + + bool addVMStub(VMStubTE vmstub, int bin); + + bool addVMStub(VMStubTE vmstub); + + unsigned int nVMStubs() const { return stubsvm_.size(); } + + unsigned int nVMStubsBinned(unsigned int bin) const { return stubsbinnedvm_[bin].size(); } + + const VMStubTE& getVMStubTE(unsigned int i) const { return stubsvm_[i]; } + + const VMStubTE& getVMStubTEBinned(unsigned int bin, unsigned int i) const { return stubsbinnedvm_[bin][i]; } + + void clean() override; + + void writeStubs(bool first); + + int phibin() const { return phibin_; } + + void getPhiRange(double& phimin, double& phimax, unsigned int iSeed, unsigned int inner); + + void setother(VMStubsTEMemory* other) { other_ = other; } + + VMStubsTEMemory* other() { return other_; } + + void setbendtable(std::vector vmbendtable); + + bool passbend(unsigned int ibend) const { + assert(ibend < vmbendtable_.size()); + return vmbendtable_[ibend]; + } + + void writeVMBendTable(); + + private: + int layer_; + int disk_; + int phibin_; + VMStubsTEMemory* other_; + bool overlap_; + bool extra_; + bool extended_; // for the L2L3->D1 and D1D2->L2 + bool isinner_; // is inner layer/disk for TE purpose + + std::vector vmbendtable_; + + std::vector stubsvm_; + std::vector > stubsbinnedvm_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/interface/imath.h b/L1Trigger/TrackFindingTracklet/interface/imath.h new file mode 100644 index 0000000000000..3db657cda0ed6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/interface/imath.h @@ -0,0 +1,1121 @@ +// // Integer representation of floating point arithmetic suitable for FPGA designs +// +// Author: Yuri Gershtein +// Date: March 2018 +// +// Functionality: +// +// *note* all integers are assumed to be signed +// +// all variables have units, stored in a map , with string a unit (i.e. "phi") and int the power +// "2" is always present in the map, and it's int pair is referred to as 'shift' +// units are properly combined / propagated through calculations +// adding/subtracting variables with different units throws an exception +// adding/subtracting variables with different shifts is allowed and is handled correctly +// +// calculate() method re-calculates the variable double and int values based on its operands +// returns false in case of overflows and/or mismatches between double and int calculations. +// +// the maximum and minimum values that the variable assumes are stored and updated each time calculate() is called +// if IMATH_ROOT is defined, all values are also stored in a histogram +// +// VarDef (string name, string units, double fmax, double K): +// define variable with bit value fval = K*ival, and maximum absolute value fmax. +// calculates nbins on its own +// one can assign value to it using set_ methods +// +// VarParam (string name, string units, double fval, int nbits): +// define a parameter. K is calculated based on the fval and nbits +// +// or (string name, std::string units, double fval, double K): +// define a parameer with bit value fval = K*ival. +// calculates nbins on its own +// +// VarAdd (string name, VarBase *p1, VarBase *p2, double range = -1, int nmax = 18): +// VarSubtract(string name, VarBase *p1, VarBase *p2, double range = -1, int nmax = 18): +// add/subtract variables. Bit length increases by 1, but capped at nmax +// if range>0 specified, bit length is decreased to drop unnecessary high bits +// +// VarMult (string name, VarBase *p1, VarBase *p2, double range = -1, int nmax = 18): +// multiplication. Bit length is a sum of the lengths of the operads, but capped at nmax +// if range>0 specified, bit length is decreased to drop unnecessary high bits or post-shift is reduced +// +// VarTimesC (string name, VarBase *p1, double cF, int ps = 17): +// multiplication by a constant. Bit length stays the same +// ps defines number of bits used to represent the constant +// +// VarDSPPostadd (string name, VarBase *p1, VarBase *p2, VarBase *p3, double range = -1, int nmax = 18): +// explicit instantiation of the 3-clock DSP postaddition: p1*p2+p3 +// range and nmax have the same meaning as for the VarMult. +// +// VarShift (string name, VarBase *p1, int shift): +// shifts the variable right by shift (equivalent to multiplication by pow(2, -shift)); +// Units stay the same, nbits are adjusted. +// +// VarShiftround (string name, VarBase *p1, int shift): +// shifts the variable right by shift, but doing rounding, i.e. +// (p>>(shift-1)+1)>>1; +// Units stay the same, nbits are adjusted. +// +// VarNeg (string name, VarBase *p1): +// multiplies the variable by -1 +// +// VarInv (string name, VarBase *p1, double offset, int nbits, int n, unsigned int shift, mode m, int nbaddr=-1): +// LUT-based inversion, f = 1./(offset + f1) and i = 2^n / (offsetI + i1) +// nbits is the width of the LUT (signed) +// m is from enum mode {pos, neg, both} and refers to possible sign values of f +// for pos and neg, the most significant bit of p1 (i.e. the sign bit) is ignored +// shift is a shift applied in i1<->address conversions (used to reduce size of LUT) +// nbaddr: if not specified, it is taken to be equal to p1->nbits() +// +// +// VarNounits (string name, VarBase *p1, int ps = 17): +// convert a number with units to a number - needed for trig function expansion (i.e. 1 - 0.5*phi^2) +// ps is a number of bits to represent the unit conversion constant +// +// VarAdjustK (string name, VarBase *p1, double Knew, double epsilon = 1e-5, bool do_assert = false, int nbits = -1) +// adjust variable shift so the K is as close to Knew as possible (needed for bit length adjustments) +// if do_assert is true, throw an exeption if Knew/Kold is not a power of two +// epsilon is a comparison precision, nbits forces the bit length (possibly discarding MSBs) +// +// VarAdjustKR (string name, VarBase *p1, double Knew, double epsilon = 1e-5, bool do_assert = false, int nbits = -1) +// - same as adjustK(), but with rounding, and therefore latency=1 +// +// bool calculate(int debug_level) runs through the entire formula tree recalculating both ineteger and floating point values +// returns true if everything is OK, false if obvious problems with the calculation exist, i.e +// - integer value does not fit into the alotted number of bins +// - integer value is more then 10% or more then 2 away from fval_/K_ +// debug_level: 0 - no warnings +// 1 - limited warning +// 2 - as 1, but also include explicit warnings when LUT was used out of its range +// 3 - maximum complaints level +// +// VarFlag (string name, VarBase *cut_var, VarBase *...) +// +// flag to apply cuts defined for any variable. When output as Verilog, the flag +// is true if and only if the following conditions are all true: +// 1) the cut defined by each VarCut pointer in the argument list must be passed +// by the associated variable +// 2) each VarBase pointer in the argument list that is not also a VarCut +// pointer must pass all of its associated cuts +// 3) all children of the variables in the argument list must pass all of their +// associated cuts +// The VarFlag::passes() method replicates the behavior of the output Verilog, +// returning true if and only if the above conditions are all true. The +// VarBase::local_passes() method can be used to query if a given variable passes +// its associated cuts, regardless of whether its children do. +// +#ifndef L1Trigger_TrackFindingTracklet_interface_imath_h +#define L1Trigger_TrackFindingTracklet_interface_imath_h + +//use root if uncommented +//#ifndef CMSSW_GIT_HASH +//#define IMATH_ROOT +//#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +#ifdef IMATH_ROOT +#include +#include +#include +#include +#endif + +//operation latencies for proper HDL pipelining +#define MULT_LATENCY 1 +#define LUT_LATENCY 2 +#define DSP_LATENCY 3 + +// Print out information on the pass/fail status of all variables. Warning: +// this outputs a lot of information for busy events! + +namespace trklet { + + struct imathGlobals { + bool printCutInfo_{false}; +#ifdef IMATH_ROOT + TFile *h_file_ = new TFile("imath.root", "RECREATE"); + bool use_root; +#endif + }; + + class VarCut; + class VarFlag; + + class VarBase { + public: + VarBase(imathGlobals *globals, std::string name, VarBase *p1, VarBase *p2, VarBase *p3, int l) { + globals_ = globals; + p1_ = p1; + p2_ = p2; + p3_ = p3; + name_ = name; + latency_ = l; + int step1 = (p1) ? p1->step() + p1->latency() : 0; + int step2 = (p2) ? p2->step() + p2->latency() : 0; + step_ = std::max(step1, step2); + + cuts_.clear(); + cut_var_ = nullptr; + + pipe_counter_ = 0; + pipe_delays_.clear(); + + minval_ = std::numeric_limits::max(); + maxval_ = -std::numeric_limits::max(); + readytoprint_ = true; + readytoanalyze_ = true; + usedasinput_ = false; + Kmap_.clear(); + Kmap_["2"] = 0; // initially, zero shift +#ifdef IMATH_ROOT + h_ = 0; + h_nbins_ = 1024; + h_precision_ = 0.02; +#endif + } + virtual ~VarBase() { +#ifdef IMATH_ROOT + if (globals_->h_file_) { + globals_->h_file_->ls(); + globals_->h_file_->Close(); + globals_->h_file_ = 0; + } +#endif + } + + static struct Verilog { + } verilog; + static struct HLS { + } hls; + + std::string kstring() const; + std::string name() const { return name_; } + std::string op() const { return op_; } + VarBase *p1() const { return p1_; } + VarBase *p2() const { return p2_; } + VarBase *p3() const { return p3_; } + double fval() const { return fval_; } + long int ival() const { return ival_; } + + bool local_passes() const; + void passes(std::map > &passes, + const std::map > *const previous_passes = nullptr) const; + void print_cuts(std::map > &cut_strings, + const int step, + Verilog, + const std::map > *const previous_cut_strings = nullptr) const; + void print_cuts(std::map > &cut_strings, + const int step, + HLS, + const std::map > *const previous_cut_strings = nullptr) const; + void add_cut(VarCut *cut, const bool call_set_cut_var = true); + VarBase *cut_var(); + + double minval() const { return minval_; } + double maxval() const { return maxval_; } + void analyze(); +#ifdef IMATH_ROOT + TH2F *h() { return h_; } +#endif + void reset() { + minval_ = std::numeric_limits::max(); + maxval_ = -std::numeric_limits::max(); +#ifdef IMATH_ROOT + h_->Clear(); +#endif + } + + int nbits() const { return nbits_; } + std::map Kmap() const { return Kmap_; } + double range() const { return (1 << (nbits_ - 1)) * K_; } // everything is signed + double K() const { return K_; }; + int shift() const { return Kmap_.at("2"); } + + void makeready(); + int step() const { return step_; } + int latency() const { return latency_; } + void add_latency(unsigned int l) { latency_ += l; } //only call before using the variable in calculation! + bool calculate(int debug_level); + bool calculate() { return calculate(0); } + virtual void local_calculate() {} + virtual void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) { + fs << "// VarBase here. Soemthing is wrong!! " << l1 << ", " << l2 << ", " << l3 << "\n"; + } + virtual void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) { + fs << "// VarBase here. Soemthing is wrong!! " << l1 << ", " << l2 << ", " << l3 << "\n"; + } + void print_step(int step, std::ofstream &fs, Verilog); + void print_step(int step, std::ofstream &fs, HLS); + void print_all(std::ofstream &fs, Verilog); + void print_all(std::ofstream &fs, HLS); + void print_truncation(std::string &t, const std::string &o1, const int ps, Verilog) const; + void print_truncation(std::string &t, const std::string &o1, const int ps, HLS) const; + void inputs(std::vector *vd); //collect all inputs + + int pipe_counter() { return pipe_counter_; } + void pipe_increment() { pipe_counter_++; } + void add_delay(int i) { pipe_delays_.push_back(i); } + bool has_delay(int i); //returns true if already have this variable delayed. + static void verilog_print(std::vector v, std::ofstream &fs) { design_print(v, fs, verilog); } + static void hls_print(std::vector v, std::ofstream &fs) { design_print(v, fs, hls); } + static void design_print(std::vector v, std::ofstream &fs, Verilog); + static void design_print(std::vector v, std::ofstream &fs, HLS); + static std::string pipe_delay(VarBase *v, int nbits, int delay); + std::string pipe_delays(const int step); + static std::string pipe_delay_wire(VarBase *v, std::string name_delayed, int nbits, int delay); + +#ifdef IMATH_ROOT + static TTree *addToTree(imathGlobals *globals, VarBase *v, char *s = 0); + static TTree *addToTree(imathGlobals *globals, int *v, char *s); + static TTree *addToTree(imathGlobals *globals, double *v, char *s); + static void fillTree(imathGlobals *globals); + static void writeTree(imathGlobals *globals); +#endif + + void dump_msg(); + std::string dump(); + static std::string itos(int i); + + protected: + imathGlobals *globals_; + std::string name_; + VarBase *p1_; + VarBase *p2_; + VarBase *p3_; + std::string op_; // operation + int latency_; // number of clock cycles for the operation (for HDL output) + int step_; // step number in the calculation (for HDL output) + + double fval_; // exact calculation + long int ival_; // integer calculation + double val_; // integer calculation converted to double, ival_*K + + std::vector cuts_; + VarBase *cut_var_; + + int nbits_; + double K_; + std::map Kmap_; + + int pipe_counter_; + std::vector pipe_delays_; + + bool readytoanalyze_; + bool readytoprint_; + bool usedasinput_; + + double minval_; + double maxval_; +#ifdef IMATH_ROOT + void set_hist_pars(int n = 256, double p = 0.05) { + h_nbins_ = n; + h_precision_ = p; + } + int h_nbins_; + double h_precision_; + TH2F *h_; +#endif + }; + + class VarAdjustK : public VarBase { + public: + VarAdjustK(imathGlobals *globals, + std::string name, + VarBase *p1, + double Knew, + double epsilon = 1e-5, + bool do_assert = false, + int nbits = -1) + : VarBase(globals, name, p1, nullptr, nullptr, 0) { + op_ = "adjustK"; + K_ = p1->K(); + Kmap_ = p1->Kmap(); + + double r = Knew / K_; + + lr_ = (r > 1) ? log2(r) + epsilon : log2(r); + K_ = K_ * pow(2, lr_); + if (do_assert) + assert(std::abs(Knew / K_ - 1) < epsilon); + + if (nbits > 0) + nbits_ = nbits; + else + nbits_ = p1->nbits() - lr_; + + Kmap_["2"] = Kmap_["2"] + lr_; + } + + ~VarAdjustK() override = default; + + void adjust(double Knew, double epsilon = 1e-5, bool do_assert = false, int nbits = -1); + + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int lr_; + }; + + class VarAdjustKR : public VarBase { + public: + VarAdjustKR(imathGlobals *globals, + std::string name, + VarBase *p1, + double Knew, + double epsilon = 1e-5, + bool do_assert = false, + int nbits = -1) + : VarBase(globals, name, p1, nullptr, nullptr, 1) { + op_ = "adjustKR"; + K_ = p1->K(); + Kmap_ = p1->Kmap(); + + double r = Knew / K_; + + lr_ = (r > 1) ? log2(r) + epsilon : log2(r); + K_ = K_ * pow(2, lr_); + if (do_assert) + assert(std::abs(Knew / K_ - 1) < epsilon); + + if (nbits > 0) + nbits_ = nbits; + else + nbits_ = p1->nbits() - lr_; + + Kmap_["2"] = Kmap_["2"] + lr_; + } + + ~VarAdjustKR() override = default; + + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int lr_; + }; + + class VarParam : public VarBase { + public: + VarParam(imathGlobals *globals, std::string name, double fval, int nbits) + : VarBase(globals, name, nullptr, nullptr, nullptr, 0) { + op_ = "const"; + nbits_ = nbits; + int l = log2(std::abs(fval)) + 1.9999999 - nbits; + Kmap_["2"] = l; + K_ = pow(2, l); + fval_ = fval; + ival_ = fval / K_; + } + VarParam(imathGlobals *globals, std::string name, std::string units, double fval, double K) + : VarBase(globals, name, nullptr, nullptr, nullptr, 0) { + op_ = "const"; + K_ = K; + nbits_ = log2(fval / K) + 1.999999; //plus one to round up + if (!units.empty()) + Kmap_[units] = 1; + else { + //defining a constant, K should be a power of two + int l = log2(K); + if (std::abs(pow(2, l) / K - 1) > 1e-5) { + char slog[100]; + snprintf(slog, 100, "defining unitless constant, yet K is not a power of 2! %g, %g", K, pow(2, l)); + edm::LogVerbatim("Tracklet") << slog; + } + Kmap_["2"] = l; + } + } + + ~VarParam() override = default; + + void set_fval(double fval) { + fval_ = fval; + if (fval > 0) + ival_ = fval / K_ + 0.5; + else + ival_ = fval / K_ - 0.5; + val_ = ival_ * K_; + } + void set_ival(int ival) { + ival_ = ival; + fval_ = ival * K_; + val_ = fval_; + } + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + }; + + class VarDef : public VarBase { + public: + //construct from scratch + VarDef(imathGlobals *globals, std::string name, std::string units, double fmax, double K) + : VarBase(globals, name, nullptr, nullptr, nullptr, 1) { + op_ = "def"; + K_ = K; + nbits_ = log2(fmax / K) + 1.999999; //plus one to round up + if (!units.empty()) + Kmap_[units] = 1; + else { + //defining a constant, K should be a power of two + int l = log2(K); + if (std::abs(pow(2, l) / K - 1) > 1e-5) { + char slog[100]; + snprintf(slog, 100, "defining unitless constant, yet K is not a power of 2! %g, %g", K, pow(2, l)); + edm::LogVerbatim("Tracklet") << slog; + } + Kmap_["2"] = l; + } + } + //construct from abother variable (all provenance info is lost!) + VarDef(imathGlobals *globals, std::string name, VarBase *p) : VarBase(globals, name, nullptr, nullptr, nullptr, 1) { + op_ = "def"; + K_ = p->K(); + nbits_ = p->nbits(); + Kmap_ = p->Kmap(); + } + void set_fval(double fval) { + fval_ = fval; + if (fval > 0) + ival_ = fval / K_; + else + ival_ = fval / K_ - 1; + val_ = ival_ * K_; + } + void set_ival(int ival) { + ival_ = ival; + fval_ = ival * K_; + val_ = ival_ * K_; + } + ~VarDef() override = default; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + }; + + class VarAdd : public VarBase { + public: + VarAdd(imathGlobals *globals, std::string name, VarBase *p1, VarBase *p2, double range = -1, int nmax = 18) + : VarBase(globals, name, p1, p2, nullptr, 1) { + op_ = "add"; + + std::map map1 = p1->Kmap(); + std::map map2 = p2->Kmap(); + int s1 = map1["2"]; + int s2 = map2["2"]; + + //first check if the constants are all lined up + //go over the two maps subtracting the units + for (const auto &it : map2) { + if (map1.find(it.first) == map1.end()) + map1[it.first] = -it.second; + else + map1[it.first] = map1[it.first] - it.second; + } + + char slog[100]; + + //assert if different + for (const auto &it : map1) { + if (it.second != 0) { + if (it.first != "2") { + snprintf( + slog, 100, "VarAdd: bad units! %s^%i for variable %s", (it.first).c_str(), it.second, name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + p1->dump_msg(); + p2->dump_msg(); + throw cms::Exception("BadConfig") << "imath units are different!"; + } + } + } + + double ki1 = p1->K() / pow(2, s1); + double ki2 = p2->K() / pow(2, s2); + //those should be the same + if (std::abs(ki1 / ki2 - 1.) > 1e-6) { + snprintf(slog, 100, "VarAdd: bad constants! %f %f for variable %s", ki1, ki2, name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + p1->dump_msg(); + p2->dump_msg(); + throw cms::Exception("BadConfig") << "imath constants are different!"; + } + //everything checks out! + + Kmap_ = p1->Kmap(); + + int s0 = s1 < s2 ? s1 : s2; + shift1 = s1 - s0; + shift2 = s2 - s0; + + int n1 = p1->nbits() + shift1; + int n2 = p2->nbits() + shift2; + int n0 = 1 + (n1 > n2 ? n1 : n2); + + //before shifting, check the range + if (range > 0) { + n0 = log2(range / ki1 / pow(2, s0)) + 1e-9; + n0 = n0 + 2; + } + + if (n0 <= nmax) { //if it fits, we're done + ps_ = 0; + Kmap_["2"] = s0; + nbits_ = n0; + } else { + ps_ = n0 - nmax; + Kmap_["2"] = s0 + ps_; + nbits_ = nmax; + } + + K_ = ki1 * pow(2, Kmap_["2"]); + } + ~VarAdd() override = default; + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int ps_; + int shift1; + int shift2; + }; + + class VarSubtract : public VarBase { + public: + VarSubtract(imathGlobals *globals, std::string name, VarBase *p1, VarBase *p2, double range = -1, int nmax = 18) + : VarBase(globals, name, p1, p2, nullptr, 1) { + op_ = "subtract"; + + std::map map1 = p1->Kmap(); + std::map map2 = p2->Kmap(); + int s1 = map1["2"]; + int s2 = map2["2"]; + + //first check if the constants are all lined up go over the two maps subtracting the units + for (const auto &it : map2) { + if (map1.find(it.first) == map1.end()) + map1[it.first] = -it.second; + else + map1[it.first] = map1[it.first] - it.second; + } + + char slog[100]; + + //assert if different + for (const auto &it : map1) { + if (it.second != 0) { + if (it.first != "2") { + snprintf( + slog, 100, "VarAdd: bad units! %s^%i for variable %s", (it.first).c_str(), it.second, name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + p1->dump_msg(); + p2->dump_msg(); + throw cms::Exception("BadConfig") << "imath units are different!"; + } + } + } + + double ki1 = p1->K() / pow(2, s1); + double ki2 = p2->K() / pow(2, s2); + //those should be the same + if (std::abs(ki1 / ki2 - 1.) > 1e-6) { + snprintf(slog, 100, "VarAdd: bad constants! %f %f for variable %s", ki1, ki2, name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + p1->dump_msg(); + p2->dump_msg(); + throw cms::Exception("BadConfig") << "imath constants are different!"; + } + //everything checks out! + + Kmap_ = p1->Kmap(); + + int s0 = s1 < s2 ? s1 : s2; + shift1 = s1 - s0; + shift2 = s2 - s0; + + int n1 = p1->nbits() + shift1; + int n2 = p2->nbits() + shift2; + int n0 = 1 + (n1 > n2 ? n1 : n2); + + //before shifting, check the range + if (range > 0) { + n0 = log2(range / ki1 / pow(2, s0)) + 1e-9; + n0 = n0 + 2; + } + + if (n0 <= nmax) { //if it fits, we're done + ps_ = 0; + Kmap_["2"] = s0; + nbits_ = n0; + } else { + ps_ = n0 - nmax; + Kmap_["2"] = s0 + ps_; + nbits_ = nmax; + } + + K_ = ki1 * pow(2, Kmap_["2"]); + } + + ~VarSubtract() override = default; + + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int ps_; + int shift1; + int shift2; + }; + + class VarNounits : public VarBase { + public: + VarNounits(imathGlobals *globals, std::string name, VarBase *p1, int ps = 17) + : VarBase(globals, name, p1, nullptr, nullptr, MULT_LATENCY) { + op_ = "nounits"; + ps_ = ps; + nbits_ = p1->nbits(); + + int s1 = p1->shift(); + double ki = p1->K() / pow(2, s1); + int m = log2(ki); + + K_ = pow(2, s1 + m); + Kmap_["2"] = s1 + m; + double c = ki * pow(2, -m); + cI_ = c * pow(2, ps_); + } + ~VarNounits() override = default; + + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int ps_; + int cI_; + }; + + class VarShiftround : public VarBase { + public: + VarShiftround(imathGlobals *globals, std::string name, VarBase *p1, int shift) + : VarBase(globals, name, p1, nullptr, nullptr, 1) { // latency is one because there is an addition + op_ = "shiftround"; + shift_ = shift; + + nbits_ = p1->nbits() - shift; + Kmap_ = p1->Kmap(); + K_ = p1->K(); + } + ~VarShiftround() override = default; + + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int shift_; + }; + + class VarShift : public VarBase { + public: + VarShift(imathGlobals *globals, std::string name, VarBase *p1, int shift) + : VarBase(globals, name, p1, nullptr, nullptr, 0) { + op_ = "shift"; + shift_ = shift; + + nbits_ = p1->nbits() - shift; + Kmap_ = p1->Kmap(); + K_ = p1->K(); + } + ~VarShift() override = default; + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int shift_; + }; + + class VarNeg : public VarBase { + public: + VarNeg(imathGlobals *globals, std::string name, VarBase *p1) : VarBase(globals, name, p1, nullptr, nullptr, 1) { + op_ = "neg"; + nbits_ = p1->nbits(); + Kmap_ = p1->Kmap(); + K_ = p1->K(); + } + ~VarNeg() override = default; + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + }; + + class VarTimesC : public VarBase { + public: + VarTimesC(imathGlobals *globals, std::string name, VarBase *p1, double cF, int ps = 17) + : VarBase(globals, name, p1, nullptr, nullptr, MULT_LATENCY) { + op_ = "timesC"; + cF_ = cF; + ps_ = ps; + + nbits_ = p1->nbits(); + Kmap_ = p1->Kmap(); + K_ = p1->K(); + + int s1 = Kmap_["2"]; + double l = log2(std::abs(cF)); + if (l > 0) + l += 0.999999; + int m = l; + + cI_ = cF * pow(2, ps - m); + K_ = K_ * pow(2, m); + Kmap_["2"] = s1 + m; + } + ~VarTimesC() override = default; + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int ps_; + int cI_; + double cF_; + }; + + class VarMult : public VarBase { + public: + VarMult(imathGlobals *globals, std::string name, VarBase *p1, VarBase *p2, double range = -1, int nmax = 18) + : VarBase(globals, name, p1, p2, nullptr, MULT_LATENCY) { + op_ = "mult"; + + const std::map map1 = p1->Kmap(); + const std::map map2 = p2->Kmap(); + for (const auto &it : map1) { + if (Kmap_.find(it.first) == Kmap_.end()) + Kmap_[it.first] = it.second; + else + Kmap_[it.first] = Kmap_[it.first] + it.second; + } + for (const auto &it : map2) { + if (Kmap_.find(it.first) == Kmap_.end()) + Kmap_[it.first] = it.second; + else + Kmap_[it.first] = Kmap_[it.first] + it.second; + } + K_ = p1->K() * p2->K(); + int s0 = Kmap_["2"]; + + int n0 = p1->nbits() + p2->nbits(); + if (range > 0) { + n0 = log2(range / K_) + 1e-9; + n0 = n0 + 2; + } + if (n0 < nmax) { + ps_ = 0; + nbits_ = n0; + } else { + ps_ = n0 - nmax; + nbits_ = nmax; + Kmap_["2"] = s0 + ps_; + K_ = K_ * pow(2, ps_); + } + } + ~VarMult() override = default; + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int ps_; + }; + + class VarDSPPostadd : public VarBase { + public: + VarDSPPostadd( + imathGlobals *globals, std::string name, VarBase *p1, VarBase *p2, VarBase *p3, double range = -1, int nmax = 18) + : VarBase(globals, name, p1, p2, p3, DSP_LATENCY) { + op_ = "DSP_postadd"; + + //first, get constants for the p1*p2 + std::map map1 = p1->Kmap(); + std::map map2 = p2->Kmap(); + for (const auto &it : map2) { + if (map1.find(it.first) == map1.end()) + map1[it.first] = it.second; + else + map1[it.first] = map1[it.first] + it.second; + } + double k0 = p1->K() * p2->K(); + int s0 = map1["2"]; + + //now addition + std::map map3 = p3->Kmap(); + int s3 = map3["2"]; + + //first check if the constants are all lined up + //go over the two maps subtracting the units + for (const auto &it : map3) { + if (map1.find(it.first) == map1.end()) + map1[it.first] = -it.second; + else + map1[it.first] = map1[it.first] - it.second; + } + + char slog[100]; + + //assert if different + for (const auto &it : map1) { + if (it.second != 0) { + if (it.first != "2") { + snprintf(slog, + 100, + "VarDSPPostadd: bad units! %s^%i for variable %s", + (it.first).c_str(), + it.second, + name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + p1->dump_msg(); + p2->dump_msg(); + p3->dump_msg(); + throw cms::Exception("BadConfig") << "imath units are different!"; + } + } + } + + double ki1 = k0 / pow(2, s0); + double ki2 = p3->K() / pow(2, s3); + //those should be the same + if (std::abs(ki1 / ki2 - 1.) > 1e-6) { + snprintf(slog, 100, "VarDSPPostadd: bad constants! %f %f for variable %s", ki1, ki2, name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + p1->dump_msg(); + p2->dump_msg(); + p3->dump_msg(); + throw cms::Exception("BadConfig") << "imath constants are different!"; + } + //everything checks out! + + shift3_ = s3 - s0; + if (shift3_ < 0) { + throw cms::Exception("BadConfig") << "imath VarDSPPostadd: loosing precision on C in A*B+C: " << shift3_; + } + + Kmap_ = p3->Kmap(); + Kmap_["2"] = Kmap_["2"] - shift3_; + + int n12 = p1->nbits() + p2->nbits(); + int n3 = p3->nbits() + shift3_; + int n0 = 1 + (n12 > n3 ? n12 : n3); + + //before shifting, check the range + if (range > 0) { + n0 = log2(range / ki2 / pow(2, s3)) + 1e-9; + n0 = n0 + 2; + } + + if (n0 <= nmax) { //if it fits, we're done + ps_ = 0; + nbits_ = n0; + } else { + ps_ = n0 - nmax; + Kmap_["2"] = Kmap_["2"] + ps_; + nbits_ = nmax; + } + + K_ = ki2 * pow(2, Kmap_["2"]); + } + ~VarDSPPostadd() override = default; + + void local_calculate() override; + using VarBase::print; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + + protected: + int ps_; + int shift3_; + }; + + class VarInv : public VarBase { + public: + enum mode { pos, neg, both }; + + VarInv(imathGlobals *globals, + std::string name, + VarBase *p1, + double offset, + int nbits, + int n, + unsigned int shift, + mode m, + int nbaddr = -1) + : VarBase(globals, name, p1, nullptr, nullptr, LUT_LATENCY) { + op_ = "inv"; + offset_ = offset; + nbits_ = nbits; + n_ = n; + shift_ = shift; + m_ = m; + if (nbaddr < 0) + nbaddr = p1->nbits(); + nbaddr_ = nbaddr - shift; + if (m_ != mode::both) + nbaddr_--; + Nelements_ = 1 << nbaddr_; + mask_ = Nelements_ - 1; + ashift_ = sizeof(int) * 8 - nbaddr_; + + const std::map map1 = p1->Kmap(); + for (const auto &it : map1) + Kmap_[it.first] = -it.second; + Kmap_["2"] = Kmap_["2"] - n; + K_ = pow(2, -n) / p1->K(); + + LUT = new int[Nelements_]; + double offsetI = lround(offset_ / p1_->K()); + for (int i = 0; i < Nelements_; ++i) { + int i1 = addr_to_ival(i); + LUT[i] = gen_inv(offsetI + i1); + } + } + ~VarInv() override { delete[] LUT; } + + void set_mode(mode m) { m_ = m; } + void initLUT(double offset); + double offset() { return offset_; } + double Ioffset() { return offset_ / p1_->K(); } + + void local_calculate() override; + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + void writeLUT(std::ofstream &fs) const { writeLUT(fs, verilog); } + void writeLUT(std::ofstream &fs, Verilog) const; + void writeLUT(std::ofstream &fs, HLS) const; + + int ival_to_addr(int ival) { return ((ival >> shift_) & mask_); } + int addr_to_ival(int addr) { + switch (m_) { + case mode::pos: + return addr << shift_; + case mode::neg: + return (addr - Nelements_) << shift_; + case mode::both: + return (addr << ashift_) >> (ashift_ - shift_); + } + assert(0); + } + int gen_inv(int i) { + unsigned int ms = sizeof(int) * 8 - nbits_; + int lut = 0; + if (i > 0) { + int i1 = i + (1 << shift_) - 1; + int lut1 = (lround((1 << n_) / i) << ms) >> ms; + int lut2 = (lround((1 << n_) / (i1)) << ms) >> ms; + lut = 0.5 * (lut1 + lut2); + } else if (i < -1) { + int i1 = i + (1 << shift_) - 1; + int i2 = i; + int lut1 = (lround((1 << n_) / i1) << ms) >> ms; + int lut2 = (lround((1 << n_) / i2) << ms) >> ms; + lut = 0.5 * (lut1 + lut2); + } + return lut; + } + + protected: + double offset_; + int n_; + mode m_; + unsigned int shift_; + unsigned int mask_; + unsigned int ashift_; + int Nelements_; + int nbaddr_; + + int *LUT; + }; + + class VarCut : public VarBase { + public: + VarCut(imathGlobals *globals, double lower_cut, double upper_cut) + : VarBase(globals, "", nullptr, nullptr, nullptr, 0), + lower_cut_(lower_cut), + upper_cut_(upper_cut), + parent_flag_(nullptr) { + op_ = "cut"; + } + + VarCut(imathGlobals *globals, VarBase *cut_var, double lower_cut, double upper_cut) + : VarCut(globals, lower_cut, upper_cut) { + set_cut_var(cut_var); + } + ~VarCut() override = default; + + double lower_cut() const { return lower_cut_; } + double upper_cut() const { return upper_cut_; } + + void local_passes(std::map > &passes, + const std::map > *const previous_passes = nullptr) const; + using VarBase::print; + void print(std::map > &cut_strings, + const int step, + Verilog, + const std::map > *const previous_cut_strings = nullptr) const; + void print(std::map > &cut_strings, + const int step, + HLS, + const std::map > *const previous_cut_strings = nullptr) const; + + void set_parent_flag(VarFlag *parent_flag, const bool call_add_cut); + VarFlag *parent_flag() { return parent_flag_; } + void set_cut_var(VarBase *cut_var, const bool call_add_cut = true); + + protected: + double lower_cut_; + double upper_cut_; + VarFlag *parent_flag_; + }; + + class VarFlag : public VarBase { + public: + template + VarFlag(imathGlobals *globals, std::string name, VarBase *cut, Args... args) + : VarBase(globals, name, nullptr, nullptr, nullptr, 0) { + op_ = "flag"; + nbits_ = 1; + add_cuts(cut, args...); + } + + template + void add_cuts(VarBase *cut, Args... args) { + add_cut(cut); + add_cuts(args...); + } + + void add_cuts(VarBase *cut) { add_cut(cut); } + + void add_cut(VarBase *cut, const bool call_set_parent_flag = true); + + void calculate_step(); + bool passes(); + void print(std::ofstream &fs, Verilog, int l1 = 0, int l2 = 0, int l3 = 0) override; + void print(std::ofstream &fs, HLS, int l1 = 0, int l2 = 0, int l3 = 0) override; + }; +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/plugins/BuildFile.xml b/L1Trigger/TrackFindingTracklet/plugins/BuildFile.xml new file mode 100644 index 0000000000000..14554c40bb531 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/BuildFile.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc new file mode 100644 index 0000000000000..88f050ea6271b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc @@ -0,0 +1,699 @@ +////////////////////////// +// Producer by Anders // +// and Emmanuele // +// july 2012 @ CU // +////////////////////////// + +//////////////////// +// FRAMEWORK HEADERS +#include "FWCore/PluginManager/interface/ModuleDef.h" +#include "FWCore/Framework/interface/MakerMacros.h" +// +#include "FWCore/Framework/interface/one/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +// +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" + +/////////////////////// +// DATA FORMATS HEADERS +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/Ref.h" +// +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/SiPixelDetId/interface/PXBDetId.h" +#include "DataFormats/SiPixelDetId/interface/PXFDetId.h" +#include "DataFormats/Common/interface/DetSetVector.h" +// +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" + +#include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" +#include "SimDataFormats/Track/interface/SimTrack.h" +#include "SimDataFormats/Track/interface/SimTrackContainer.h" +#include "SimDataFormats/Vertex/interface/SimVertex.h" +#include "SimDataFormats/Vertex/interface/SimVertexContainer.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTStubAssociationMap.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTClusterAssociationMap.h" +// +#include "DataFormats/Math/interface/LorentzVector.h" +#include "DataFormats/Math/interface/Vector3D.h" +// +#include "DataFormats/L1TrackTrigger/interface/TTCluster.h" +#include "DataFormats/L1TrackTrigger/interface/TTStub.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +// +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include "DataFormats/Candidate/interface/Candidate.h" +// +#include "DataFormats/GeometryCommonDetAlgo/interface/MeasurementPoint.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/SiPixelDetId/interface/PixelChannelIdentifier.h" +#include "TrackingTools/GeomPropagators/interface/HelixArbitraryPlaneCrossing.h" + +//////////////////////////// +// DETECTOR GEOMETRY HEADERS +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" +#include "Geometry/CommonTopologies/interface/PixelGeomDetType.h" +#include "Geometry/TrackerGeometryBuilder/interface/PixelTopologyBuilder.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "Geometry/TrackerGeometryBuilder/interface/RectangularPixelTopology.h" +#include "Geometry/CommonDetUnit/interface/GeomDetType.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" +// +#include "Geometry/Records/interface/StackedTrackerGeometryRecord.h" + +/////////////// +// Tracklet emulation +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Sector.h" +#include "L1Trigger/TrackFindingTracklet/interface/Cabling.h" +#include "L1Trigger/TrackFindingTracklet/interface/Track.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h" + +//////////////// +// PHYSICS TOOLS +#include "RecoTracker/TkSeedGenerator/interface/FastHelix.h" +#include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h" + +#include "DataFormats/GeometryCommonDetAlgo/interface/MeasurementVector.h" +#include "DataFormats/GeometrySurface/interface/BoundPlane.h" + +#include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h" + +////////////// +// STD HEADERS +#include +#include +#include +#include + +////////////// +// NAMESPACES +using namespace edm; +using namespace std; + +////////////////////////////// +// // +// CLASS DEFINITION // +// // +////////////////////////////// + +///////////////////////////////////// +// this class is needed to make a map +// between different types of stubs +struct L1TStubCompare { +public: + bool operator()(const trklet::L1TStub& x, const trklet::L1TStub& y) const { + if (x.x() != y.x()) + return (y.x() > x.x()); + else { + if (x.y() != y.y()) + return (y.y() > x.y()); + else + return (x.z() > y.z()); + } + } +}; + +class L1FPGATrackProducer : public edm::one::EDProducer { +public: + /// Constructor/destructor + explicit L1FPGATrackProducer(const edm::ParameterSet& iConfig); + ~L1FPGATrackProducer() override; + +private: + int eventnum; + + /// Containers of parameters passed by python configuration file + edm::ParameterSet config; + + bool readMoreMcTruth_; + + /// File path for configuration files + edm::FileInPath fitPatternFile; + edm::FileInPath memoryModulesFile; + edm::FileInPath processingModulesFile; + edm::FileInPath wiresFile; + + edm::FileInPath DTCLinkFile; + edm::FileInPath moduleCablingFile; + edm::FileInPath DTCLinkLayerDiskFile; + + edm::FileInPath tableTEDFile; + edm::FileInPath tableTREFile; + + string asciiEventOutName_; + std::ofstream asciiEventOut_; + + string geometryType_; + + // settings containing various constants for the tracklet processing + trklet::Settings settings; + + // event processor for the tracklet track finding + trklet::TrackletEventProcessor eventProcessor; + + unsigned int nHelixPar_; + bool extended_; + + std::map> dtclayerdisk; + + edm::ESHandle tTopoHandle; + edm::ESHandle tGeomHandle; + + edm::InputTag MCTruthClusterInputTag; + edm::InputTag MCTruthStubInputTag; + edm::InputTag TrackingParticleInputTag; + edm::InputTag TrackingVertexInputTag; + edm::InputTag ttStubSrc_; + edm::InputTag bsSrc_; + + const edm::EDGetTokenT>> ttStubToken_; + const edm::EDGetTokenT bsToken_; + + edm::EDGetTokenT> ttClusterMCTruthToken_; + edm::EDGetTokenT> ttStubMCTruthToken_; + edm::EDGetTokenT> TrackingParticleToken_; + edm::EDGetTokenT> TrackingVertexToken_; + + /// ///////////////// /// + /// MANDATORY METHODS /// + void beginRun(const edm::Run& run, const edm::EventSetup& iSetup) override; + void endRun(edm::Run const&, edm::EventSetup const&) override; + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; +}; + +////////////// +// CONSTRUCTOR +L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) + : config(iConfig), + readMoreMcTruth_(iConfig.getParameter("readMoreMcTruth")), + MCTruthClusterInputTag(readMoreMcTruth_ ? config.getParameter("MCTruthClusterInputTag") + : edm::InputTag()), + MCTruthStubInputTag(readMoreMcTruth_ ? config.getParameter("MCTruthStubInputTag") + : edm::InputTag()), + TrackingParticleInputTag(readMoreMcTruth_ ? iConfig.getParameter("TrackingParticleInputTag") + : edm::InputTag()), + TrackingVertexInputTag(readMoreMcTruth_ ? iConfig.getParameter("TrackingVertexInputTag") + : edm::InputTag()), + ttStubSrc_(config.getParameter("TTStubSource")), + bsSrc_(config.getParameter("BeamSpotSource")), + + ttStubToken_(consumes>>(ttStubSrc_)), + bsToken_(consumes(bsSrc_)) { + if (readMoreMcTruth_) { + ttClusterMCTruthToken_ = consumes>(MCTruthClusterInputTag); + ttStubMCTruthToken_ = consumes>(MCTruthStubInputTag); + TrackingParticleToken_ = consumes>(TrackingParticleInputTag); + TrackingVertexToken_ = consumes>(TrackingVertexInputTag); + } + + produces>>("Level1TTTracks").setBranchAlias("Level1TTTracks"); + + asciiEventOutName_ = iConfig.getUntrackedParameter("asciiFileName", ""); + + fitPatternFile = iConfig.getParameter("fitPatternFile"); + processingModulesFile = iConfig.getParameter("processingModulesFile"); + memoryModulesFile = iConfig.getParameter("memoryModulesFile"); + wiresFile = iConfig.getParameter("wiresFile"); + + DTCLinkFile = iConfig.getParameter("DTCLinkFile"); + moduleCablingFile = iConfig.getParameter("moduleCablingFile"); + DTCLinkLayerDiskFile = iConfig.getParameter("DTCLinkLayerDiskFile"); + + extended_ = iConfig.getParameter("Extended"); + nHelixPar_ = iConfig.getParameter("Hnpar"); + + if (extended_) { + tableTEDFile = iConfig.getParameter("tableTEDFile"); + tableTREFile = iConfig.getParameter("tableTREFile"); + } + + // -------------------------------------------------------------------------------- + // set options in Settings based on inputs from configuration files + // -------------------------------------------------------------------------------- + + settings.setExtended(extended_); + settings.setNHelixPar(nHelixPar_); + + settings.setDTCLinkFile(DTCLinkFile.fullPath()); + settings.setModuleCablingFile(moduleCablingFile.fullPath()); + settings.setDTCLinkLayerDiskFile(DTCLinkLayerDiskFile.fullPath()); + settings.setFitPatternFile(fitPatternFile.fullPath()); + settings.setProcessingModulesFile(processingModulesFile.fullPath()); + settings.setMemoryModulesFile(memoryModulesFile.fullPath()); + settings.setWiresFile(wiresFile.fullPath()); + + if (extended_) { + settings.setTableTEDFile(tableTEDFile.fullPath()); + settings.setTableTREFile(tableTREFile.fullPath()); + } + + eventnum = 0; + if (not asciiEventOutName_.empty()) { + asciiEventOut_.open(asciiEventOutName_.c_str()); + } + + if (settings.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "cabling DTC links : " << DTCLinkFile.fullPath() + << "\n module cabling : " << moduleCablingFile.fullPath() + << "\n DTC link layer disk : " << DTCLinkLayerDiskFile.fullPath() + << "\n fit pattern : " << fitPatternFile.fullPath() + << "\n process modules : " << processingModulesFile.fullPath() + << "\n memory modules : " << memoryModulesFile.fullPath() + << "\n wires : " << wiresFile.fullPath(); + if (extended_) { + edm::LogVerbatim("Tracklet") << "table_TED : " << tableTEDFile.fullPath() + << "\n table_TRE : " << tableTREFile.fullPath(); + } + } +} + +///////////// +// DESTRUCTOR +L1FPGATrackProducer::~L1FPGATrackProducer() { + if (asciiEventOut_.is_open()) { + asciiEventOut_.close(); + } +} + +///////END RUN +// +void L1FPGATrackProducer::endRun(const edm::Run& run, const edm::EventSetup& iSetup) {} + +//////////// +// BEGIN JOB +void L1FPGATrackProducer::beginRun(const edm::Run& run, const edm::EventSetup& iSetup) { + //////////////////////// + // GET MAGNETIC FIELD // + edm::ESHandle magneticFieldHandle; + iSetup.get().get(magneticFieldHandle); + const MagneticField* theMagneticField = magneticFieldHandle.product(); + double mMagneticFieldStrength = theMagneticField->inTesla(GlobalPoint(0, 0, 0)).z(); + settings.setBfield(mMagneticFieldStrength); + + // initialize the tracklet event processing (this sets all the processing & memory modules, wiring, etc) + eventProcessor.init(settings); +} + +////////// +// PRODUCE +void L1FPGATrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + typedef std::map>, TTStub>, + L1TStubCompare> + stubMapType; + typedef edm::Ref>, TTCluster> + TTClusterRef; + + /// Prepare output + auto L1TkTracksForOutput = std::make_unique>>(); + + stubMapType stubMap; + + /// Geometry handles etc + edm::ESHandle geometryHandle; + + /// Set pointers to Stacked Modules + iSetup.get().get(geometryHandle); + + //////////// + // GET BS // + edm::Handle beamSpotHandle; + iEvent.getByToken(bsToken_, beamSpotHandle); + math::XYZPoint bsPosition = beamSpotHandle->position(); + + iSetup.get().get(tTopoHandle); + iSetup.get().get(tGeomHandle); + + eventnum++; + trklet::SLHCEvent ev; + ev.setEventNum(eventnum); + ev.setIPx(bsPosition.x()); + ev.setIPy(bsPosition.y()); + + // tracking particles + edm::Handle> TrackingParticleHandle; + edm::Handle> TrackingVertexHandle; + if (readMoreMcTruth_) + iEvent.getByToken(TrackingParticleToken_, TrackingParticleHandle); + if (readMoreMcTruth_) + iEvent.getByToken(TrackingVertexToken_, TrackingVertexHandle); + + // tracker topology + const TrackerTopology* const tTopo = tTopoHandle.product(); + const TrackerGeometry* const theTrackerGeom = tGeomHandle.product(); + + //////////////////////// + // GET THE PRIMITIVES // + edm::Handle>> Phase2TrackerDigiTTStubHandle; + iEvent.getByToken(ttStubToken_, Phase2TrackerDigiTTStubHandle); + + // must be defined for code to compile, even if it's not used unless readMoreMcTruth_ is true + map, int> translateTP; + + // MC truth association maps + edm::Handle> MCTruthTTClusterHandle; + edm::Handle> MCTruthTTStubHandle; + if (readMoreMcTruth_) { + iEvent.getByToken(ttClusterMCTruthToken_, MCTruthTTClusterHandle); + iEvent.getByToken(ttStubMCTruthToken_, MCTruthTTStubHandle); + + //////////////////////////////////////////////// + /// LOOP OVER TRACKING PARTICLES & GET SIMTRACKS + + int ntps = 1; //count from 1 ; 0 will mean invalid + + int this_tp = 0; + for (const auto& iterTP : *TrackingParticleHandle) { + edm::Ptr tp_ptr(TrackingParticleHandle, this_tp); + this_tp++; + + // only keep TPs producing a cluster + if (MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr).empty()) + continue; + + if (iterTP.g4Tracks().empty()) { + continue; + } + + int sim_eventid = iterTP.g4Tracks().at(0).eventId().event(); + int sim_type = iterTP.pdgId(); + float sim_pt = iterTP.pt(); + float sim_eta = iterTP.eta(); + float sim_phi = iterTP.phi(); + + float vx = iterTP.vertex().x(); + float vy = iterTP.vertex().y(); + float vz = iterTP.vertex().z(); + + if (sim_pt < 1.0 || std::abs(vz) > 100.0 || hypot(vx, vy) > 50.0) + continue; + + ev.addL1SimTrack(sim_eventid, ntps, sim_type, sim_pt, sim_eta, sim_phi, vx, vy, vz); + + translateTP[tp_ptr] = ntps; + ntps++; + + } //end loop over TPs + + } // end if (readMoreMcTruth_) + + //////////////////////////////// + /// COLLECT STUB INFORMATION /// + //////////////////////////////// + + bool firstPS = true; + bool first2S = true; + + for (const auto& gd : theTrackerGeom->dets()) { + DetId detid = (*gd).geographicalId(); + if (detid.subdetId() != StripSubdetector::TOB && detid.subdetId() != StripSubdetector::TID) + continue; // only run on OT + if (!tTopo->isLower(detid)) + continue; // loop on the stacks: choose the lower arbitrarily + DetId stackDetid = tTopo->stack(detid); // Stub module detid + + if (Phase2TrackerDigiTTStubHandle->find(stackDetid) == Phase2TrackerDigiTTStubHandle->end()) + continue; + + // Get the DetSets of the Clusters + edmNew::DetSet> stubs = (*Phase2TrackerDigiTTStubHandle)[stackDetid]; + const GeomDetUnit* det0 = theTrackerGeom->idToDetUnit(detid); + const auto* theGeomDet = dynamic_cast(det0); + const PixelTopology* topol = dynamic_cast(&(theGeomDet->specificTopology())); + + bool isPSmodule = theTrackerGeom->getDetectorType(detid) == TrackerGeometry::ModuleType::Ph2PSP; + + // set constants that are common for all modules/stubs of a given type (PS vs 2S) + if (isPSmodule && firstPS) { + settings.setNStrips_PS(topol->nrows()); + settings.setStripPitch_PS(topol->pitch().first); + settings.setStripLength_PS(topol->pitch().second); + firstPS = false; + } + if (!isPSmodule && first2S) { + settings.setNStrips_2S(topol->nrows()); + settings.setStripPitch_2S(topol->pitch().first); + settings.setStripLength_2S(topol->pitch().second); + first2S = false; + } + + // loop over stubs + for (auto stubIter = stubs.begin(); stubIter != stubs.end(); ++stubIter) { + edm::Ref>, TTStub> tempStubPtr = + edmNew::makeRefTo(Phase2TrackerDigiTTStubHandle, stubIter); + + vector assocTPs; + + if (readMoreMcTruth_) { + for (unsigned int iClus = 0; iClus <= 1; iClus++) { // Loop over both clusters that make up stub. + + const TTClusterRef& ttClusterRef = tempStubPtr->clusterRef(iClus); + + // Now identify all TP's contributing to either cluster in stub. + vector> vecTpPtr = MCTruthTTClusterHandle->findTrackingParticlePtrs(ttClusterRef); + + for (const edm::Ptr& tpPtr : vecTpPtr) { + if (translateTP.find(tpPtr) != translateTP.end()) { + if (iClus == 0) { + assocTPs.push_back(translateTP.at(tpPtr)); + } else { + assocTPs.push_back(-translateTP.at(tpPtr)); + } + // N.B. Since not all tracking particles are stored in InputData::vTPs_, sometimes no match will be found. + } else { + assocTPs.push_back(0); + } + } + } + } // end if (readMoreMcTruth_) + + MeasurementPoint coords = tempStubPtr->clusterRef(0)->findAverageLocalCoordinatesCentered(); + LocalPoint clustlp = topol->localPosition(coords); + GlobalPoint posStub = theGeomDet->surface().toGlobal(clustlp); + + int eventID = -1; + + if (readMoreMcTruth_) { + edm::Ptr my_tp = MCTruthTTStubHandle->findTrackingParticlePtr(tempStubPtr); + } + + int layer = -999999; + int ladder = -999999; + int module = -999999; + + int strip = 460; + + if (detid.subdetId() == StripSubdetector::TOB) { + layer = static_cast(tTopo->layer(detid)); + module = static_cast(tTopo->module(detid)); + ladder = static_cast(tTopo->tobRod(detid)); + + // https://github.com/cms-sw/cmssw/tree/master/Geometry/TrackerNumberingBuilder + // tobSide = 1: ring- (tilted) + // tobSide = 2: ring+ (tilted) + // tobSide = 3: barrel (flat) + enum TypeBarrel { nonBarrel = 0, tiltedMinus = 1, tiltedPlus = 2, flat = 3 }; + const TypeBarrel type = static_cast(tTopo->tobSide(detid)); + + // modules in the flat part of barrel are mounted on planks, while modules in tilted part are on rings + // below, "module" is the module number in the z direction (from minus z to positive), + // while "ladder" is the module number in the phi direction + + if (layer > 0 && layer <= (int)trklet::N_PSLAYER) { + if (type == tiltedMinus) { + module = static_cast(tTopo->tobRod(detid)); + ladder = static_cast(tTopo->module(detid)); + } + if (type == tiltedPlus) { + module = + trklet::N_TILTED_RINGS + trklet::N_MOD_PLANK.at(layer - 1) + static_cast(tTopo->tobRod(detid)); + ladder = static_cast(tTopo->module(detid)); + } + if (type == flat) { + module = trklet::N_TILTED_RINGS + static_cast(tTopo->module(detid)); + } + } + } else if (detid.subdetId() == StripSubdetector::TID) { + layer = 1000 + static_cast(tTopo->tidRing(detid)); + ladder = static_cast(tTopo->module(detid)); + module = static_cast(tTopo->tidWheel(detid)); + } + + /// Get the Inner and Outer TTCluster + edm::Ref>, TTCluster> innerCluster = + tempStubPtr->clusterRef(0); + edm::Ref>, TTCluster> outerCluster = + tempStubPtr->clusterRef(1); + + std::vector irphi; + std::vector innerrows = innerCluster->getRows(); + irphi.reserve(innerrows.size()); + for (int innerrow : innerrows) { + irphi.push_back(innerrow); + } + std::vector outerrows = outerCluster->getRows(); + for (int outerrow : outerrows) { + irphi.push_back(outerrow); + } + + // ----------------------------------------------------- + // check module orientation, if flipped, need to store that information for track fit + // ----------------------------------------------------- + + const DetId innerDetId = innerCluster->getDetId(); + const GeomDetUnit* det_inner = theTrackerGeom->idToDetUnit(innerDetId); + const auto* theGeomDet_inner = dynamic_cast(det_inner); + const PixelTopology* topol_inner = dynamic_cast(&(theGeomDet_inner->specificTopology())); + + MeasurementPoint coords_inner = innerCluster->findAverageLocalCoordinatesCentered(); + LocalPoint clustlp_inner = topol_inner->localPosition(coords_inner); + GlobalPoint posStub_inner = theGeomDet_inner->surface().toGlobal(clustlp_inner); + + const DetId outerDetId = outerCluster->getDetId(); + const GeomDetUnit* det_outer = theTrackerGeom->idToDetUnit(outerDetId); + const auto* theGeomDet_outer = dynamic_cast(det_outer); + const PixelTopology* topol_outer = dynamic_cast(&(theGeomDet_outer->specificTopology())); + + MeasurementPoint coords_outer = outerCluster->findAverageLocalCoordinatesCentered(); + LocalPoint clustlp_outer = topol_outer->localPosition(coords_outer); + GlobalPoint posStub_outer = theGeomDet_outer->surface().toGlobal(clustlp_outer); + + bool isFlipped = (posStub_outer.mag() < posStub_inner.mag()); + + // ----------------------------------------------------- + // correct sign for stubs in negative endcap + float stub_bend = tempStubPtr->bendFE(); + float stub_pt = -1; + if (layer > 999 && posStub.z() < 0.0) { + stub_bend = -stub_bend; + } + if (!irphi.empty()) { + strip = irphi[0]; + } + + //if module FE inefficiencies are calculated, a stub is thrown out if rawBend > 100 + if ((tempStubPtr->rawBend() < 100.) && (ev.addStub(layer, + ladder, + module, + strip, + eventID, + assocTPs, + stub_pt, + stub_bend, + posStub.x(), + posStub.y(), + posStub.z(), + isPSmodule, + isFlipped))) { + const trklet::L1TStub& lastStub = ev.lastStub(); + stubMap[lastStub] = tempStubPtr; + } + } + } + + ////////////////////////// + // NOW RUN THE L1 tracking + + if (!asciiEventOutName_.empty()) { + ev.write(asciiEventOut_); + } + + std::vector& tracks = eventProcessor.tracks(); + + trklet::L1SimTrack simtrk(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + + // this performs the actual tracklet event processing + eventProcessor.event(ev); + + int ntracks = 0; + + for (auto track : tracks) { + if (track->duplicate()) + continue; + + ntracks++; + + // this is where we create the TTTrack object + double tmp_rinv = track->rinv(settings); + double tmp_phi = track->phi0(settings); + double tmp_tanL = track->tanL(settings); + double tmp_z0 = track->z0(settings); + double tmp_d0 = track->d0(settings); + double tmp_chi2rphi = track->chisqrphi(); + double tmp_chi2rz = track->chisqrz(); + unsigned int tmp_hit = track->hitpattern(); + + TTTrack aTrack(tmp_rinv, + tmp_phi, + tmp_tanL, + tmp_z0, + tmp_d0, + tmp_chi2rphi, + tmp_chi2rz, + 0, + 0, + 0, + tmp_hit, + settings.nHelixPar(), + settings.bfield()); + + unsigned int trksector = track->sector(); + unsigned int trkseed = (unsigned int)abs(track->seed()); + + aTrack.setPhiSector(trksector); + aTrack.setTrackSeedType(trkseed); + + const vector& stubptrs = track->stubs(); + vector stubs; + + stubs.reserve(stubptrs.size()); + for (auto stubptr : stubptrs) { + stubs.push_back(*stubptr); + } + + stubMapType::const_iterator it; + for (const auto& itstubs : stubs) { + it = stubMap.find(itstubs); + if (it != stubMap.end()) { + aTrack.addStubRef(it->second); + } else { + // could not find stub in stub map + } + } + + // pt consistency + aTrack.setStubPtConsistency( + StubPtConsistency::getConsistency(aTrack, theTrackerGeom, tTopo, settings.bfield(), settings.nHelixPar())); + + // set TTTrack word + aTrack.setTrackWordBits(); + + // test track word + //aTrack.testTrackWordBits(); + + L1TkTracksForOutput->push_back(aTrack); + } + + iEvent.put(std::move(L1TkTracksForOutput), "Level1TTTracks"); + +} /// End of produce() + +// /////////////////////////// +// // DEFINE THIS AS A PLUG-IN +DEFINE_FWK_MODULE(L1FPGATrackProducer); diff --git a/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py b/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py new file mode 100644 index 0000000000000..e977bd04faa73 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/L1HybridEmulationTracks_cff.py @@ -0,0 +1,26 @@ +import FWCore.ParameterSet.Config as cms + +from RecoVertex.BeamSpotProducer.BeamSpot_cfi import * + +from L1Trigger.TrackFindingTracklet.Tracklet_cfi import * + +from SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff import * + +# prompt hybrid emulation +TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag(cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") ) + +L1HybridTracks = cms.Sequence(offlineBeamSpot*TTTracksFromTrackletEmulation) +L1HybridTracksWithAssociators = cms.Sequence(offlineBeamSpot*TTTracksFromTrackletEmulation*TrackTriggerAssociatorTracks) + +# extended hybrid emulation +TTTrackAssociatorFromPixelDigisExtended = TTTrackAssociatorFromPixelDigis.clone( + TTTracks = cms.VInputTag(cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks") ) +) + +L1ExtendedHybridTracks = cms.Sequence(offlineBeamSpot*TTTracksFromExtendedTrackletEmulation) +L1ExtendedHybridTracksWithAssociators = cms.Sequence(offlineBeamSpot*TTTracksFromExtendedTrackletEmulation*TTTrackAssociatorFromPixelDigisExtended) + +# both (prompt + extended) hybrid emulation +L1PromptExtendedHybridTracks = cms.Sequence(offlineBeamSpot*TTTracksFromTrackletEmulation*TTTracksFromExtendedTrackletEmulation) +L1PromptExtendedHybridTracksWithAssociators = cms.Sequence(offlineBeamSpot*TTTracksFromTrackletEmulation*TrackTriggerAssociatorTracks*TTTracksFromExtendedTrackletEmulation*TTTrackAssociatorFromPixelDigisExtended) + diff --git a/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py b/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py new file mode 100644 index 0000000000000..998ca97e35fed --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/python/Tracklet_cfi.py @@ -0,0 +1,34 @@ +import FWCore.ParameterSet.Config as cms + +TTTracksFromTrackletEmulation = cms.EDProducer("L1FPGATrackProducer", + TTStubSource = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), + readMoreMcTruth = cms.bool(True), + MCTruthClusterInputTag = cms.InputTag("TTClusterAssociatorFromPixelDigis", "ClusterAccepted"), + MCTruthStubInputTag = cms.InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted"), + TrackingParticleInputTag = cms.InputTag("mix", "MergedTrackTruth"), + TrackingVertexInputTag = cms.InputTag("mix", "MergedTrackTruth"), + BeamSpotSource = cms.InputTag("offlineBeamSpot"), + asciiFileName = cms.untracked.string(""), + # (if running on CRAB use "../../fitpattern.txt" etc instead) + Extended=cms.bool(False), + Hnpar=cms.uint32(4), + fitPatternFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/fitpattern.txt'), + memoryModulesFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/memorymodules_hourglass.dat'), + processingModulesFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/processingmodules_hourglass.dat'), + wiresFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/wires_hourglass.dat'), + DTCLinkFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/calcNumDTCLinks.txt'), + DTCLinkLayerDiskFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/dtclinklayerdisk.dat'), + moduleCablingFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/modules_T5v3_27SP_nonant_tracklet.dat') + ) + +TTTracksFromExtendedTrackletEmulation = TTTracksFromTrackletEmulation.clone( + Extended=cms.bool(True), + Hnpar=cms.uint32(5), + memoryModulesFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/memorymodules_hourglassExtended.dat'), + processingModulesFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/processingmodules_hourglassExtended.dat'), + wiresFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/wires_hourglassExtended.dat'), + # specifying where the TrackletEngineDisplaced(TED)/TripletEngine(TRE) tables are located + tableTEDFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/table_TED/table_TED_D1PHIA1_D2PHIA1.txt'), + tableTREFile = cms.FileInPath('L1Trigger/TrackFindingTracklet/data/table_TRE/table_TRE_D1AD2A_1.txt') + ) + diff --git a/L1Trigger/TrackFindingTracklet/src/AllProjectionsMemory.cc b/L1Trigger/TrackFindingTracklet/src/AllProjectionsMemory.cc new file mode 100644 index 0000000000000..7f4af45f7cadf --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/AllProjectionsMemory.cc @@ -0,0 +1,44 @@ +#include "L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace trklet; +using namespace std; + +AllProjectionsMemory::AllProjectionsMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) { + initLayerDisk(3, layer_, disk_); +} + +void AllProjectionsMemory::writeAP(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/TrackletProjections/AllProj_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < tracklets_.size(); j++) { + string proj = + (layer_ > 0) ? tracklets_[j]->trackletprojstrlayer(layer_) : tracklets_[j]->trackletprojstrdisk(disk_); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << proj << " " << trklet::hexFormat(proj) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/AllStubsMemory.cc b/L1Trigger/TrackFindingTracklet/src/AllStubsMemory.cc new file mode 100644 index 0000000000000..9fab053a55905 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/AllStubsMemory.cc @@ -0,0 +1,23 @@ +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include + +using namespace std; +using namespace trklet; + +AllStubsMemory::AllStubsMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) {} + +void AllStubsMemory::writeStubs(bool first) { + openFile(first, "../data/MemPrints/Stubs/AllStubs_"); + + for (unsigned int j = 0; j < stubs_.size(); j++) { + string stub = stubs_[j]->str(); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << stub << " " << hexFormat(stub) << endl; + } + out_.close(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/Cabling.cc b/L1Trigger/TrackFindingTracklet/src/Cabling.cc new file mode 100644 index 0000000000000..c0b48b3e494ad --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Cabling.cc @@ -0,0 +1,126 @@ +#include "L1Trigger/TrackFindingTracklet/interface/Cabling.h" +#include "L1Trigger/TrackFindingTracklet/interface/DTCLink.h" +#include "L1Trigger/TrackFindingTracklet/interface/DTC.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +Cabling::Cabling(string dtcconfig, string moduleconfig, Settings const& settings) : settings_(settings) { + ifstream indtc(dtcconfig.c_str()); + assert(indtc.good()); + + string dtc; + int isec; + + while (indtc.good()) { + indtc >> dtc >> isec; + + if (!indtc.good()) + continue; + + if (dtcs_.find(dtc) == dtcs_.end()) { + dtcs_[dtc].setName(dtc); + } + + dtcs_[dtc].addSec(isec); + + string dtcbase = dtc.substr(2, dtc.size() - 2); + if (dtc[0] == 'n') { + dtcbase = "neg_" + dtc.substr(6, dtc.size() - 6); + } + if (dtcranges_.find(dtcbase) == dtcranges_.end()) { + dtcranges_[dtcbase].setName(dtcbase); + } + } + + ifstream inmodules(moduleconfig.c_str()); + + int layer, ladder, module; + + while (inmodules.good()) { + inmodules >> layer >> ladder >> module >> dtc; + + // in the cabling module map, module# 300+ is flat part of barrel, 200-299 is tilted z-, 100-199 is tilted z+ + if (module > 300) { + if (layer > 0 && layer <= (int)N_PSLAYER) { + module = (module - 300) + N_TILTED_RINGS; + } else if (layer > (int)N_PSLAYER) { + module = (module - 300); + } + } + if (module > 200) { + module = (module - 200); + } + if ((module > 100) && (layer > 0 && layer <= (int)N_PSLAYER)) { + module = (module - 100) + N_TILTED_RINGS + N_MOD_PLANK.at(layer - 1); + } + if (!inmodules.good()) + break; + modules_[layer][ladder][module] = dtc; + } +} + +const string& Cabling::dtc(int layer, int ladder, int module) const { + auto it1 = modules_.find(layer); + assert(it1 != modules_.end()); + auto it2 = it1->second.find(ladder); + assert(it2 != it1->second.end()); + auto it3 = it2->second.find(module); + if (it3 == it2->second.end()) { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << "Could not find stub " << layer << " " + << ladder << " " << module; + } + return it3->second; +} + +void Cabling::addphi(const string& dtc, double phi, int layer, int module) { + unsigned int layerdisk = layer - 1; + + if (layer > 1000) + layerdisk = module + N_DISK; + + assert(layerdisk < N_LAYER + N_DISK); + + int isec = dtc[0] - '0'; + + string dtcbase = dtc.substr(2, dtc.size() - 2); + if (dtc[0] == 'n') { + dtcbase = "neg_" + dtc.substr(6, dtc.size() - 6); + isec = dtc[4] - '0'; + } + + double phisec = reco::reduceRange(phi - isec * settings_.dphisector()); + + assert(dtcranges_.find(dtcbase) != dtcranges_.end()); + + dtcranges_[dtcbase].addphi(phisec, layerdisk); +} + +void Cabling::writephirange() const { + ofstream out("dtcphirange.txt"); + + for (auto&& it : dtcranges_) { + for (unsigned int i = 0; i < N_LAYER + N_DISK; i++) { + double min = it.second.min(i); + double max = it.second.max(i); + if (min < max) { + out << it.first << " " << i + 1 << " " << min << " " << max << endl; + } + } + } +} + +std::vector Cabling::DTCs() const { + std::vector tmp; + + for (const auto& it : dtcs_) { + tmp.push_back(it.first); + } + + return tmp; +} diff --git a/L1Trigger/TrackFindingTracklet/src/CandidateMatchMemory.cc b/L1Trigger/TrackFindingTracklet/src/CandidateMatchMemory.cc new file mode 100644 index 0000000000000..6c535de1c93c2 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/CandidateMatchMemory.cc @@ -0,0 +1,63 @@ +#include "L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +CandidateMatchMemory::CandidateMatchMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) {} + +void CandidateMatchMemory::addMatch(std::pair tracklet, const Stub* stub) { + std::pair, const Stub*> tmp(tracklet, stub); + + //Check for consistency + for (auto& match : matches_) { + if (tracklet.first->TCID() < match.first.first->TCID()) { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " In " << getName() << " adding tracklet " + << tracklet.first << " with lower TCID : " << tracklet.first->TCID() + << " than earlier TCID " << match.first.first->TCID(); + } + } + matches_.push_back(tmp); +} + +void CandidateMatchMemory::writeCM(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/Matches/CandidateMatches_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < matches_.size(); j++) { + string stubid = matches_[j].second->stubindex().str(); // stub ID + int projindex = matches_[j].first.second; // Allproj index + FPGAWord tmp; + if (projindex >= (1 << 7)) { + projindex = (1 << 7) - 1; + } + tmp.set(projindex, 7, true, __LINE__, __FILE__); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << tmp.str() << "|" << stubid << " " << trklet::hexFormat(tmp.str() + stubid) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/CleanTrackMemory.cc b/L1Trigger/TrackFindingTracklet/src/CleanTrackMemory.cc new file mode 100644 index 0000000000000..209c66431a5be --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/CleanTrackMemory.cc @@ -0,0 +1,68 @@ +#include "L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" +#include + +using namespace std; +using namespace trklet; + +CleanTrackMemory::CleanTrackMemory( + string name, Settings const& settings, unsigned int iSector, double phimin, double phimax) + : MemoryBase(name, settings, iSector) { + phimin_ = phimin; + phimax_ = phimax; +} + +void CleanTrackMemory::writeCT(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/CleanTrack/CleanTrack_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < tracks_.size(); j++) { + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec << " "; + out_ << tracks_[j]->trackfitstr() << " " << trklet::hexFormat(tracks_[j]->trackfitstr()); + out_ << "\n"; + } + out_.close(); + + // -------------------------------------------------------------- + // print separately ALL cleaned tracks in single file + if (settings_.writeMonitorData("CT")) { + std::string fnameAll = "CleanTracksAll.dat"; + if (first && getName() == "CT_L1L2" && iSector_ == 0) + out_.open(fnameAll.c_str()); + else + out_.open(fnameAll.c_str(), std::ofstream::app); + + if (!tracks_.empty()) + out_ << "BX= " << (bitset<3>)bx_ << " event= " << event_ << " seed= " << getName() + << " phisector= " << iSector_ + 1 << endl; + + for (unsigned int j = 0; j < tracks_.size(); j++) { + if (j < 16) + out_ << "0"; + out_ << hex << j << dec << " "; + out_ << tracks_[j]->trackfitstr(); + out_ << "\n"; + } + out_.close(); + } + // -------------------------------------------------------------- + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/DTC.cc b/L1Trigger/TrackFindingTracklet/src/DTC.cc new file mode 100644 index 0000000000000..6fb97d524565e --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DTC.cc @@ -0,0 +1,52 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DTC.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" + +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +DTC::DTC(string name) { + name_ = name; + for (unsigned int i = 0; i < N_LAYER + N_DISK; i++) { + phimin_[i] = 10.0; + phimax_[i] = -10.0; + } +} + +void DTC::setName(string name) { name_ = name; } + +void DTC::addSec(int sector) { sectors_.push_back(sector); } + +void DTC::addphi(double phi, unsigned int layerdisk) { + assert(layerdisk < N_LAYER + N_DISK); + if (phi < phimin_[layerdisk]) + phimin_[layerdisk] = phi; + if (phi > phimax_[layerdisk]) + phimax_[layerdisk] = phi; +} + +void DTC::addLink(double phimin, double phimax) { + DTCLink link(phimin, phimax); + links_.push_back(link); +} + +int DTC::addStub(std::pair stub) { + double phi = reco::reduceRange(stub.second->phi()); + bool overlaplayer = ((stub.second->layer() + 1) % 2 == 0); + int added = 0; + for (auto& link : links_) { + if (link.inRange(phi, overlaplayer)) { + added++; + link.addStub(stub); + } + } + return added; +} + +void DTC::clean() { + for (auto& link : links_) { + link.clean(); + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/DTCLink.cc b/L1Trigger/TrackFindingTracklet/src/DTCLink.cc new file mode 100644 index 0000000000000..8b5c59c671fd2 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DTCLink.cc @@ -0,0 +1,29 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DTCLink.h" + +using namespace std; +using namespace trklet; + +DTCLink::DTCLink(double phimin, double phimax) { + if (phimin > M_PI) { + phimin -= 2 * M_PI; + phimax -= 2 * M_PI; + } + assert(phimax > phimin); + phimin_ = phimin; + phimax_ = phimax; +} + +void DTCLink::addStub(std::pair stub) { stubs_.push_back(stub); } + +bool DTCLink::inRange(double phi, bool overlaplayer) { + double phimax = phimax_; + double phimin = phimin_; + if (overlaplayer) { + double dphi = phimax - phimin; + assert(dphi > 0.0); + assert(dphi < M_PI); + phimin -= dphi / 6.0; + phimax += dphi / 6.0; + } + return (phi < phimax && phi > phimin) || (phi + 2 * M_PI < phimax && phi + 2 * M_PI > phimin); +} diff --git a/L1Trigger/TrackFindingTracklet/src/DiskProjection.cc b/L1Trigger/TrackFindingTracklet/src/DiskProjection.cc new file mode 100644 index 0000000000000..4fa054be39805 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DiskProjection.cc @@ -0,0 +1,94 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DiskProjection.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include +#include + +using namespace std; +using namespace trklet; + +void DiskProjection::init(Settings const& settings, + int projdisk, + double zproj, + int iphiproj, + int irproj, + int iphider, + int irder, + double phiproj, + double rproj, + double phiprojder, + double rprojder, + double phiprojapprox, + double rprojapprox, + double phiprojderapprox, + double rprojderapprox) { + assert(abs(projdisk) >= 0); + assert(abs(projdisk) <= N_DISK); + + valid_ = true; + + zproj_ = zproj; + + projdisk_ = projdisk; + + assert(iphiproj >= 0); + + fpgaphiproj_.set(iphiproj, settings.nphibitsstub(0), true, __LINE__, __FILE__); + int iphivm = (iphiproj >> (settings.nphibitsstub(0) - 5)) & 0x7; + if ((abs(projdisk_) % 2) == 1) { + iphivm ^= 4; + } + fpgaphiprojvm_.set(iphivm, 3, true, __LINE__, __FILE__); + fpgarproj_.set(irproj, settings.nrbitsstub(6), false, __LINE__, __FILE__); + int irvm = irproj >> (13 - 7) & 0xf; + fpgarprojvm_.set(irvm, 4, true, __LINE__, __FILE__); + fpgaphiprojder_.set(iphider, settings.nbitsphiprojderL123(), false, __LINE__, __FILE__); + fpgarprojder_.set(irder, settings.nrbitsprojderdisk(), false, __LINE__, __FILE__); + + //TODO the -3 and +3 should be evaluated and efficiency for matching hits checked. + //This code should be migrated in the ProjectionRouter + int rbin1 = 8.0 * (irproj * settings.krprojshiftdisk() - 3 - settings.rmindiskvm()) / + (settings.rmaxdisk() - settings.rmindiskvm()); + int rbin2 = 8.0 * (irproj * settings.krprojshiftdisk() + 3 - settings.rmindiskvm()) / + (settings.rmaxdisk() - settings.rmindiskvm()); + + if (irproj * settings.krprojshiftdisk() < 20.0) { + edm::LogPrint("Tracklet") << " WARNING : irproj = " << irproj << " " << irproj * settings.krprojshiftdisk() << " " + << projdisk_; + } + + if (rbin1 < 0) + rbin1 = 0; + rbin2 = clamp(rbin2, 0, 7); + + assert(rbin1 <= rbin2); + assert(rbin2 - rbin1 <= 1); + + int finer = 64 * + ((irproj * settings.krprojshiftdisk() - settings.rmindiskvm()) - + rbin1 * (settings.rmaxdisk() - settings.rmindiskvm()) / 8.0) / + (settings.rmaxdisk() - settings.rmindiskvm()); + + finer = clamp(finer, 0, 15); + + int diff = rbin1 != rbin2; + if (irder < 0) + rbin1 += 8; + + fpgarbin1projvm_.set(rbin1, 4, true, __LINE__, __FILE__); // first r bin + fpgarbin2projvm_.set(diff, 1, true, __LINE__, __FILE__); // need to check adjacent r bin + + fpgafinervm_.set(finer, 4, true, __LINE__, __FILE__); // fine r postions starting at rbin1 + + phiproj_ = phiproj; + rproj_ = rproj; + phiprojder_ = phiprojder; + rprojder_ = rprojder; + + phiprojapprox_ = phiprojapprox; + rprojapprox_ = rprojapprox; + phiprojderapprox_ = phiprojderapprox; + rprojderapprox_ = rprojderapprox; +} diff --git a/L1Trigger/TrackFindingTracklet/src/DiskResidual.cc b/L1Trigger/TrackFindingTracklet/src/DiskResidual.cc new file mode 100644 index 0000000000000..99213f18b9848 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/DiskResidual.cc @@ -0,0 +1,47 @@ +#include "L1Trigger/TrackFindingTracklet/interface/DiskResidual.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +using namespace std; +using namespace trklet; + +void DiskResidual::init(Settings const& settings, + int disk, + int iphiresid, + int irresid, + int istubid, + double phiresid, + double rresid, + double phiresidapprox, + double rresidapprox, + double zstub, + double alpha, + FPGAWord ialpha, + const Stub* stubptr) { + assert(abs(disk) > 0); + assert(abs(disk) <= N_DISK); + + if (valid_ && (std::abs(iphiresid) > std::abs(fpgaphiresid_.value()))) + return; + + valid_ = true; + + disk_ = disk; + + fpgaphiresid_.set(iphiresid, settings.phiresidbits(), false, __LINE__, __FILE__); + fpgarresid_.set(irresid, settings.rresidbits(), false, __LINE__, __FILE__); + assert(istubid >= 0); + unsigned int nbitsstubid = 10; + fpgastubid_.set(istubid, nbitsstubid, true, __LINE__, __FILE__); + assert(!fpgaphiresid_.atExtreme()); + + phiresid_ = phiresid; + rresid_ = rresid; + + phiresidapprox_ = phiresidapprox; + rresidapprox_ = rresidapprox; + + zstub_ = zstub; + alpha_ = alpha; + ialpha_ = ialpha; + stubptr_ = stubptr; +} diff --git a/L1Trigger/TrackFindingTracklet/src/FPGAWord.cc b/L1Trigger/TrackFindingTracklet/src/FPGAWord.cc new file mode 100644 index 0000000000000..08109d4574224 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/FPGAWord.cc @@ -0,0 +1,88 @@ +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +FPGAWord::FPGAWord() {} + +FPGAWord::FPGAWord(int value, int nbits, bool positive, int line, const char* file) { + set(value, nbits, positive, line, file); +} + +void FPGAWord::set(int value, int nbits, bool positive, int line, const char* file) { + value_ = value; + nbits_ = nbits; + positive_ = positive; + if (positive) { + if (value < 0) { + edm::LogProblem("Tracklet") << "FPGAWord got negative value:" << value << " (" << file << ":" << line << ")"; + } + assert(value >= 0); + } + if (nbits >= 22) { + edm::LogPrint("Tracklet") << "FPGAWord got too many bits:" << nbits << " (" << file << ":" << line << ")"; + } + assert(nbits < 22); + if (nbits <= 0) { + edm::LogPrint("Tracklet") << "FPGAWord got too few bits:" << nbits << " (" << file << ":" << line << ")"; + } + assert(nbits > 0); + if (positive) { + if (value >= (1 << nbits)) { + if (file != nullptr) { + edm::LogProblem("Tracklet") << "value too large:" << value << " " << (1 << nbits) << " (" << file << ":" << line + << ")"; + } + } + assert(value < (1 << nbits)); + } else { + if (value > (1 << (nbits - 1))) { + edm::LogProblem("Tracklet") << "value too large:" << value << " " << (1 << (nbits - 1)) << " (" << file << ":" + << line << ")"; + } + assert(value <= (1 << (nbits - 1))); + if (value < -(1 << (nbits - 1))) { + edm::LogProblem("Tracklet") << "value too negative:" << value << " " << -(1 << (nbits - 1)) << " (" << file << ":" + << line << ")"; + } + assert(value >= -(1 << (nbits - 1))); + } +} + +std::string FPGAWord::str() const { + const int nbit = nbits_; + + if (!(nbit > 0 && nbit < 22)) + edm::LogVerbatim("Tracklet") << "nbit: " << nbit; + if (nbit == -1) + return "?"; + if (nbit == 0) + return "~"; + + int valtmp = value_; + string str = ""; + for (int i = 0; i < nbit; i++) { + str = ((valtmp & 1) ? "1" : "0") + str; + valtmp >>= 1; + } + + return str; +} + +unsigned int FPGAWord::bits(unsigned int lsb, unsigned int nbit) const { + assert(lsb + nbit <= (unsigned int)nbits()); + return (value_ >> lsb) & ((1 << nbit) - 1); +} + +bool FPGAWord::atExtreme() const { + if (positive_) { + return (value_ == 0) || (value_ == (1 << nbits_) - 1); + } + return ((value_ == (-(1 << (nbits_ - 1)))) || (value_ == ((1 << (nbits_ - 1)) - 1))); +} + +bool FPGAWord::operator==(const FPGAWord& other) const { + return (value_ == other.value_) && (nbits_ == other.nbits_) && (positive_ == other.positive_); +} diff --git a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc new file mode 100644 index 0000000000000..c304a0d048c45 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc @@ -0,0 +1,1025 @@ +#include "L1Trigger/TrackFindingTracklet/interface/FitTrack.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackDerTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/HybridFit.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +FitTrack::FitTrack(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector), trackfit_(nullptr) {} + +void FitTrack::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "trackout") { + TrackFitMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + trackfit_ = tmp; + return; + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " addOutput, output = " << output << " not known"; +} + +void FitTrack::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input.substr(0, 4) == "tpar") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + seedtracklet_.push_back(tmp); + return; + } + if (input.substr(0, 10) == "fullmatch1") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + fullmatch1_.push_back(tmp); + return; + } + if (input.substr(0, 10) == "fullmatch2") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + fullmatch2_.push_back(tmp); + return; + } + if (input.substr(0, 10) == "fullmatch3") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + fullmatch3_.push_back(tmp); + return; + } + if (input.substr(0, 10) == "fullmatch4") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + fullmatch4_.push_back(tmp); + return; + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " input = " << input << " not found"; +} + +#ifdef USEHYBRID +void FitTrack::trackFitKF(Tracklet* tracklet, + std::vector& trackstublist, + std::vector>& stubidslist) { + if (settings_.doKF()) { + // From full match lists, collect all the stubs associated with the tracklet seed + + // Get seed stubs first + trackstublist.emplace_back(tracklet->innerFPGAStub()); + if (tracklet->getISeed() >= (int)N_TRKLSEED + 1) + trackstublist.emplace_back(tracklet->middleFPGAStub()); + trackstublist.emplace_back(tracklet->outerFPGAStub()); + + // Now get ALL matches (can have multiple per layer) + for (const auto& i : fullmatch1_) { + for (unsigned int j = 0; j < i->nMatches(); j++) { + if (i->getTracklet(j)->TCID() == tracklet->TCID()) { + trackstublist.push_back(i->getMatch(j).second); + } + } + } + + for (const auto& i : fullmatch2_) { + for (unsigned int j = 0; j < i->nMatches(); j++) { + if (i->getTracklet(j)->TCID() == tracklet->TCID()) { + trackstublist.push_back(i->getMatch(j).second); + } + } + } + + for (const auto& i : fullmatch3_) { + for (unsigned int j = 0; j < i->nMatches(); j++) { + if (i->getTracklet(j)->TCID() == tracklet->TCID()) { + trackstublist.push_back(i->getMatch(j).second); + } + } + } + + for (const auto& i : fullmatch4_) { + for (unsigned int j = 0; j < i->nMatches(); j++) { + if (i->getTracklet(j)->TCID() == tracklet->TCID()) { + trackstublist.push_back(i->getMatch(j).second); + } + } + } + + // For merge removal, loop through the resulting list of stubs to calculate their stubids + if (settings_.removalType() == "merge") { + for (const auto& it : trackstublist) { + int layer = it->layer().value() + 1; // Assume layer (1-6) stub first + if (it->layer().value() < 0) { // if disk stub, though... + layer = it->disk().value() + 10 * it->disk().value() / abs(it->disk().value()); //disk = +/- 11-15 + } + stubidslist.push_back(std::make_pair(layer, it->phiregionaddress())); + } + + // And that's all we need! The rest is just for fitting (in PurgeDuplicate) + return; + } + + HybridFit hybridFitter(iSector_, settings_, globals_); + hybridFitter.Fit(tracklet, trackstublist); + return; + } +} +#endif + +void FitTrack::trackFitChisq(Tracklet* tracklet, std::vector&, std::vector>&) { + if (globals_->trackDerTable() == nullptr) { + TrackDerTable* derTablePtr = new TrackDerTable(settings_); + + derTablePtr->readPatternFile(settings_.fitPatternFile()); + derTablePtr->fillTable(); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Number of entries in derivative table: " << derTablePtr->getEntries(); + } + assert(derTablePtr->getEntries() != 0); + + globals_->trackDerTable() = derTablePtr; + } + + const TrackDerTable& derTable = *globals_->trackDerTable(); + + //First step is to build list of layers and disks. + int layers[N_LAYER]; + double r[N_LAYER]; + unsigned int nlayers = 0; // layers with found stub-projections + int disks[N_DISK]; + double z[N_DISK]; + unsigned int ndisks = 0; // disks with found stub-projections + + // residuals for each stub + double phiresid[N_FITSTUB]; + double zresid[N_FITSTUB]; + double phiresidexact[N_FITSTUB]; + double zresidexact[N_FITSTUB]; + int iphiresid[N_FITSTUB]; + int izresid[N_FITSTUB]; + double alpha[N_FITSTUB]; + + for (unsigned int i = 0; i < N_FITSTUB; i++) { + iphiresid[i] = 0; + izresid[i] = 0; + alpha[i] = 0.0; + + phiresid[i] = 0.0; + zresid[i] = 0.0; + phiresidexact[i] = 0.0; + zresidexact[i] = 0.0; + } + + std::bitset lmatches; //layer matches + std::bitset dmatches; //disk matches (2 per disk to separate 2S from PS) + + int mult = 1; + + unsigned int layermask = 0; + unsigned int diskmask = 0; + unsigned int alphaindex = 0; + unsigned int power = 1; + + double t = tracklet->t(); + double rinv = tracklet->rinv(); + + if (tracklet->isBarrel()) { + for (unsigned int l = 1; l <= N_LAYER; l++) { + if (l == (unsigned int)tracklet->layer() || l == (unsigned int)tracklet->layer() + 1) { + lmatches.set(N_LAYER - l); + layermask |= (1 << (N_LAYER - l)); + layers[nlayers++] = l; + continue; + } + if (tracklet->match(l)) { + lmatches.set(N_LAYER - l); + layermask |= (1 << (N_LAYER - l)); + phiresid[nlayers] = tracklet->phiresidapprox(l); + zresid[nlayers] = tracklet->zresidapprox(l); + phiresidexact[nlayers] = tracklet->phiresid(l); + zresidexact[nlayers] = tracklet->zresid(l); + iphiresid[nlayers] = tracklet->fpgaphiresid(l).value(); + izresid[nlayers] = tracklet->fpgazresid(l).value(); + + layers[nlayers++] = l; + } + } + + for (unsigned int d = 1; d <= N_DISK; d++) { + if (layermask & (1 << (d - 1))) + continue; + + if (mult == 1 << (3 * settings_.alphaBitsTable())) + continue; + + if (ndisks + nlayers >= N_FITSTUB) + continue; + if (tracklet->matchdisk(d)) { + if (std::abs(tracklet->alphadisk(d)) < 1e-20) { + dmatches.set(2 * d - 1); + diskmask |= (1 << (2 * (N_DISK - d) + 1)); + } else { + int ialpha = tracklet->ialphadisk(d).value(); + int nalpha = tracklet->ialphadisk(d).nbits(); + nalpha = nalpha - settings_.alphaBitsTable(); + ialpha = (1 << (settings_.alphaBitsTable() - 1)) + (ialpha >> nalpha); + + alphaindex += ialpha * power; + power = power << settings_.alphaBitsTable(); + dmatches.set(2 * (N_DISK - d)); + diskmask |= (1 << (2 * (N_DISK - d))); + mult = mult << settings_.alphaBitsTable(); + } + alpha[ndisks] = tracklet->alphadisk(d); + phiresid[nlayers + ndisks] = tracklet->phiresidapproxdisk(d); + zresid[nlayers + ndisks] = tracklet->rresidapproxdisk(d); + phiresidexact[nlayers + ndisks] = tracklet->phiresiddisk(d); + zresidexact[nlayers + ndisks] = tracklet->rresiddisk(d); + iphiresid[nlayers + ndisks] = tracklet->fpgaphiresiddisk(d).value(); + izresid[nlayers + ndisks] = tracklet->fpgarresiddisk(d).value(); + + disks[ndisks++] = d; + } + } + + if (settings_.writeMonitorData("HitPattern")) { + if (mult <= 1 << (3 * settings_.alphaBitsTable())) { + globals_->ofstream("hitpattern.txt") + << lmatches.to_string() << " " << dmatches.to_string() << " " << mult << endl; + } + } + } + + if (tracklet->isDisk()) { + for (unsigned int l = 1; l <= 2; l++) { + if (tracklet->match(l)) { + lmatches.set(N_LAYER - l); + + layermask |= (1 << (N_LAYER - l)); + + phiresid[nlayers] = tracklet->phiresidapprox(l); + zresid[nlayers] = tracklet->zresidapprox(l); + phiresidexact[nlayers] = tracklet->phiresid(l); + zresidexact[nlayers] = tracklet->zresid(l); + iphiresid[nlayers] = tracklet->fpgaphiresid(l).value(); + izresid[nlayers] = tracklet->fpgazresid(l).value(); + + layers[nlayers++] = l; + } + } + + for (int d1 = 1; d1 <= N_DISK; d1++) { + int d = d1; + + // skip F/B5 if there's already a L2 match + if (d == 5 and layermask & (1 << 4)) + continue; + + if (tracklet->fpgat().value() < 0.0) + d = -d1; + if (d1 == abs(tracklet->disk()) || d1 == abs(tracklet->disk()) + 1) { + dmatches.set(2 * d1 - 1); + diskmask |= (1 << (2 * (N_DISK - d1) + 1)); + alpha[ndisks] = 0.0; + disks[ndisks++] = d; + continue; + } + + if (ndisks + nlayers >= N_FITSTUB) + continue; + if (tracklet->matchdisk(d)) { + if (std::abs(tracklet->alphadisk(d)) < 1e-20) { + dmatches.set(2 * d1 - 1); + diskmask |= (1 << (2 * (N_DISK - d1) + 1)); + } else { + int ialpha = tracklet->ialphadisk(d).value(); + int nalpha = tracklet->ialphadisk(d).nbits(); + nalpha = nalpha - settings_.alphaBitsTable(); + ialpha = (1 << (settings_.alphaBitsTable() - 1)) + (ialpha >> nalpha); + + alphaindex += ialpha * power; + power = power << settings_.alphaBitsTable(); + dmatches.set(2 * (N_DISK - d1)); + diskmask |= (1 << (2 * (N_DISK - d1))); + mult = mult << settings_.alphaBitsTable(); + } + + alpha[ndisks] = tracklet->alphadisk(d); + assert(std::abs(tracklet->phiresidapproxdisk(d)) < 0.2); + phiresid[nlayers + ndisks] = tracklet->phiresidapproxdisk(d); + zresid[nlayers + ndisks] = tracklet->rresidapproxdisk(d); + assert(std::abs(tracklet->phiresiddisk(d)) < 0.2); + phiresidexact[nlayers + ndisks] = tracklet->phiresiddisk(d); + zresidexact[nlayers + ndisks] = tracklet->rresiddisk(d); + iphiresid[nlayers + ndisks] = tracklet->fpgaphiresiddisk(d).value(); + izresid[nlayers + ndisks] = tracklet->fpgarresiddisk(d).value(); + + disks[ndisks++] = d; + } + } + } + + if (tracklet->isOverlap()) { + for (unsigned int l = 1; l <= 2; l++) { + if (l == (unsigned int)tracklet->layer()) { + lmatches.set(N_LAYER - l); + layermask |= (1 << (N_LAYER - l)); + layers[nlayers++] = l; + continue; + } + if (tracklet->match(l)) { + lmatches.set(N_LAYER - l); + layermask |= (1 << (N_LAYER - l)); + assert(std::abs(tracklet->phiresidapprox(l)) < 0.2); + phiresid[nlayers] = tracklet->phiresidapprox(l); + zresid[nlayers] = tracklet->zresidapprox(l); + assert(std::abs(tracklet->phiresid(l)) < 0.2); + phiresidexact[nlayers] = tracklet->phiresid(l); + zresidexact[nlayers] = tracklet->zresid(l); + iphiresid[nlayers] = tracklet->fpgaphiresid(l).value(); + izresid[nlayers] = tracklet->fpgazresid(l).value(); + + layers[nlayers++] = l; + } + } + + for (unsigned int d1 = 1; d1 <= N_DISK; d1++) { + if (mult == 1 << (3 * settings_.alphaBitsTable())) + continue; + int d = d1; + if (tracklet->fpgat().value() < 0.0) + d = -d1; + if (d == tracklet->disk()) { //All seeds in PS modules + disks[ndisks] = tracklet->disk(); + dmatches.set(2 * d1 - 1); + diskmask |= (1 << (2 * (N_DISK - d1) + 1)); + ndisks++; + continue; + } + + if (ndisks + nlayers >= N_FITSTUB) + continue; + if (tracklet->matchdisk(d)) { + if (std::abs(tracklet->alphadisk(d)) < 1e-20) { + dmatches.set(2 * (N_DISK - d1)); + diskmask |= (1 << (2 * (N_DISK - d1) + 1)); + FPGAWord tmp; + tmp.set(diskmask, 10); + } else { + int ialpha = tracklet->ialphadisk(d).value(); + int nalpha = tracklet->ialphadisk(d).nbits(); + nalpha = nalpha - settings_.alphaBitsTable(); + ialpha = (1 << (settings_.alphaBitsTable() - 1)) + (ialpha >> nalpha); + + alphaindex += ialpha * power; + power = power << settings_.alphaBitsTable(); + dmatches.set(2 * (N_DISK - d1)); + diskmask |= (1 << (2 * (N_DISK - d1))); + FPGAWord tmp; + tmp.set(diskmask, 10); + mult = mult << settings_.alphaBitsTable(); + } + + alpha[ndisks] = tracklet->alphadisk(d); + assert(std::abs(tracklet->phiresidapproxdisk(d)) < 0.2); + phiresid[nlayers + ndisks] = tracklet->phiresidapproxdisk(d); + zresid[nlayers + ndisks] = tracklet->rresidapproxdisk(d); + assert(std::abs(tracklet->phiresiddisk(d)) < 0.2); + phiresidexact[nlayers + ndisks] = tracklet->phiresiddisk(d); + zresidexact[nlayers + ndisks] = tracklet->rresiddisk(d); + iphiresid[nlayers + ndisks] = tracklet->fpgaphiresiddisk(d).value(); + izresid[nlayers + ndisks] = tracklet->fpgarresiddisk(d).value(); + + disks[ndisks++] = d; + } + } + } + + int rinvindex = + (1 << (settings_.nrinvBitsTable() - 1)) * rinv / settings_.rinvmax() + (1 << (settings_.nrinvBitsTable() - 1)); + if (rinvindex < 0) + rinvindex = 0; + if (rinvindex >= (1 << settings_.nrinvBitsTable())) + rinvindex = (1 << settings_.nrinvBitsTable()) - 1; + + const TrackDer* derivatives = derTable.getDerivatives(layermask, diskmask, alphaindex, rinvindex); + + if (derivatives == nullptr) { + if (settings_.warnNoDer()) { + FPGAWord tmpl, tmpd; + tmpl.set(layermask, 6); + tmpd.set(diskmask, 10); + edm::LogVerbatim("Tracklet") << "No derivative for layermask, diskmask : " << layermask << " " << tmpl.str() + << " " << diskmask << " " << tmpd.str() << " eta = " << asinh(t); + } + return; + } + + double ttabi = TrackDerTable::tpar(settings_, diskmask, layermask); + if (t < 0.0) + ttabi = -ttabi; + double ttab = ttabi; + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Doing trackfit in " << getName(); + } + + int sign = 1; + if (t < 0.0) + sign = -1; + + double rstub[6]; + + double realrstub[3]; + realrstub[0] = -1.0; + realrstub[1] = -1.0; + realrstub[2] = -1.0; + + for (unsigned i = 0; i < nlayers; i++) { + r[i] = settings_.rmean(layers[i] - 1); + if (layers[i] == tracklet->layer()) { + if (tracklet->isOverlap()) { + realrstub[i] = tracklet->outerStub()->r(); + } else { + realrstub[i] = tracklet->innerStub()->r(); + } + } + if (layers[i] == tracklet->layer() + 1) { + realrstub[i] = tracklet->outerStub()->r(); + } + if (tracklet->validResid(layers[i]) && layers[i] < 4) { + const Stub* stubptr = tracklet->stubptr(layers[i]); + realrstub[i] = stubptr->l1tstub()->r(); + assert(std::abs(realrstub[i] - r[i]) < 5.0); + } + rstub[i] = r[i]; + } + for (unsigned i = 0; i < ndisks; i++) { + z[i] = sign * settings_.zmean(abs(disks[i]) - 1); + rstub[i + nlayers] = z[i] / ttabi; + } + + double D[N_FITPARAM][N_FITSTUB * 2]; + double MinvDt[N_FITPARAM][N_FITSTUB * 2]; + int iD[N_FITPARAM][N_FITSTUB * 2]; + int iMinvDt[N_FITPARAM][N_FITSTUB * 2]; + double sigma[N_FITSTUB * 2]; + double kfactor[N_FITSTUB * 2]; + + unsigned int n = nlayers + ndisks; + + if (settings_.exactderivatives()) { + TrackDerTable::calculateDerivatives( + settings_, nlayers, r, ndisks, z, alpha, t, rinv, D, iD, MinvDt, iMinvDt, sigma, kfactor); + ttabi = t; + ttab = t; + } else { + if (settings_.exactderivativesforfloating()) { + TrackDerTable::calculateDerivatives( + settings_, nlayers, r, ndisks, z, alpha, t, rinv, D, iD, MinvDt, iMinvDt, sigma, kfactor); + + double MinvDtDummy[N_FITPARAM][N_FITSTUB * 2]; + derivatives->fill(tracklet->fpgat().value(), MinvDtDummy, iMinvDt); + ttab = t; + } else { + derivatives->fill(tracklet->fpgat().value(), MinvDt, iMinvDt); + } + } + + if (!settings_.exactderivatives()) { + for (unsigned int i = 0; i < nlayers; i++) { + if (r[i] > settings_.rPS2S()) + continue; + for (unsigned int ii = 0; ii < nlayers; ii++) { + if (r[ii] > settings_.rPS2S()) + continue; + + double tder = derivatives->tdzcorr(i, ii); + double zder = derivatives->z0dzcorr(i, ii); + + double dr = realrstub[i] - r[i]; + + MinvDt[2][2 * ii + 1] += dr * tder; + MinvDt[3][2 * ii + 1] += dr * zder; + + int itder = derivatives->itdzcorr(i, ii); + int izder = derivatives->iz0dzcorr(i, ii); + + int idr = dr / settings_.kr(); + + iMinvDt[2][2 * ii + 1] += ((idr * itder) >> settings_.rcorrbits()); + iMinvDt[3][2 * ii + 1] += ((idr * izder) >> settings_.rcorrbits()); + } + } + } + + double rinvseed = tracklet->rinvapprox(); + double phi0seed = tracklet->phi0approx(); + double tseed = tracklet->tapprox(); + double z0seed = tracklet->z0approx(); + + double rinvseedexact = tracklet->rinv(); + double phi0seedexact = tracklet->phi0(); + double tseedexact = tracklet->t(); + double z0seedexact = tracklet->z0(); + + double chisqseed = 0.0; + double chisqseedexact = 0.0; + + double delta[2 * N_FITSTUB]; + double deltaexact[2 * N_FITSTUB]; + int idelta[2 * N_FITSTUB]; + + for (unsigned int i = 0; i < 2 * N_FITSTUB; i++) { + delta[i] = 0.0; + deltaexact[i] = 0.0; + idelta[i] = 0; + } + + int j = 0; + + for (unsigned int i = 0; i < n; i++) { + if (i >= nlayers) { + iphiresid[i] *= (t / ttabi); + phiresid[i] *= (t / ttab); + phiresidexact[i] *= (t / ttab); + } + + idelta[j] = iphiresid[i]; + delta[j] = phiresid[i]; + if (std::abs(phiresid[i]) > 0.2) { + edm::LogWarning("Tracklet") << getName() << " WARNING too large phiresid: " << phiresid[i] << " " + << phiresidexact[i]; + } + assert(std::abs(phiresid[i]) < 1.0); + assert(std::abs(phiresidexact[i]) < 1.0); + deltaexact[j++] = phiresidexact[i]; + + idelta[j] = izresid[i]; + delta[j] = zresid[i]; + deltaexact[j++] = zresidexact[i]; + + chisqseed += (delta[j - 2] * delta[j - 2] + delta[j - 1] * delta[j - 1]); + chisqseedexact += (deltaexact[j - 2] * deltaexact[j - 2] + deltaexact[j - 1] * deltaexact[j - 1]); + } + assert(j <= 12); + + double drinv = 0.0; + double dphi0 = 0.0; + double dt = 0.0; + double dz0 = 0.0; + + double drinvexact = 0.0; + double dphi0exact = 0.0; + double dtexact = 0.0; + double dz0exact = 0.0; + + int idrinv = 0; + int idphi0 = 0; + int idt = 0; + int idz0 = 0; + + double drinv_cov = 0.0; + double dphi0_cov = 0.0; + double dt_cov = 0.0; + double dz0_cov = 0.0; + + double drinv_covexact = 0.0; + double dphi0_covexact = 0.0; + double dt_covexact = 0.0; + double dz0_covexact = 0.0; + + for (unsigned int j = 0; j < 2 * n; j++) { + drinv -= MinvDt[0][j] * delta[j]; + dphi0 -= MinvDt[1][j] * delta[j]; + dt -= MinvDt[2][j] * delta[j]; + dz0 -= MinvDt[3][j] * delta[j]; + + drinv_cov += D[0][j] * delta[j]; + dphi0_cov += D[1][j] * delta[j]; + dt_cov += D[2][j] * delta[j]; + dz0_cov += D[3][j] * delta[j]; + + drinvexact -= MinvDt[0][j] * deltaexact[j]; + dphi0exact -= MinvDt[1][j] * deltaexact[j]; + dtexact -= MinvDt[2][j] * deltaexact[j]; + dz0exact -= MinvDt[3][j] * deltaexact[j]; + + drinv_covexact += D[0][j] * deltaexact[j]; + dphi0_covexact += D[1][j] * deltaexact[j]; + dt_covexact += D[2][j] * deltaexact[j]; + dz0_covexact += D[3][j] * deltaexact[j]; + + idrinv += ((iMinvDt[0][j] * idelta[j])); + idphi0 += ((iMinvDt[1][j] * idelta[j])); + idt += ((iMinvDt[2][j] * idelta[j])); + idz0 += ((iMinvDt[3][j] * idelta[j])); + + if (false && j % 2 == 0) { + edm::LogVerbatim("Tracklet") << "DEBUG CHI2FIT " << j << " " << rinvseed << " + " << MinvDt[0][j] * delta[j] + << " " << MinvDt[0][j] << " " << delta[j] * rstub[j / 2] * 10000 << " \n" + << j << " " << tracklet->fpgarinv().value() * settings_.krinvpars() << " + " + << ((iMinvDt[0][j] * idelta[j])) * settings_.krinvpars() / 1024.0 << " " + << iMinvDt[0][j] * settings_.krinvpars() / settings_.kphi() / 1024.0 << " " + << idelta[j] * settings_.kphi() * rstub[j / 2] * 10000 << " " << idelta[j]; + } + } + + double deltaChisqexact = + drinvexact * drinv_covexact + dphi0exact * dphi0_covexact + dtexact * dt_covexact + dz0exact * dz0_covexact; + + int irinvseed = tracklet->fpgarinv().value(); + int iphi0seed = tracklet->fpgaphi0().value(); + + int itseed = tracklet->fpgat().value(); + int iz0seed = tracklet->fpgaz0().value(); + + int irinvfit = irinvseed + ((idrinv + (1 << settings_.fitrinvbitshift())) >> settings_.fitrinvbitshift()); + + int iphi0fit = iphi0seed + (idphi0 >> settings_.fitphi0bitshift()); + int itfit = itseed + (idt >> settings_.fittbitshift()); + + int iz0fit = iz0seed + (idz0 >> settings_.fitz0bitshift()); + + double rinvfit = rinvseed - drinv; + double phi0fit = phi0seed - dphi0; + + double tfit = tseed - dt; + double z0fit = z0seed - dz0; + + double rinvfitexact = rinvseedexact - drinvexact; + double phi0fitexact = phi0seedexact - dphi0exact; + + double tfitexact = tseedexact - dtexact; + double z0fitexact = z0seedexact - dz0exact; + + double chisqfitexact = chisqseedexact + deltaChisqexact; + + ////////////// NEW CHISQ ///////////////////// + bool NewChisqDebug = false; + double chisqfit = 0.0; + uint ichisqfit = 0; + + double phifactor; + double rzfactor; + double iphifactor; + double irzfactor; + int k = 0; // column index of D matrix + + if (NewChisqDebug) { + edm::LogVerbatim("Tracklet") << "OG chisq: \n" + << "drinv/cov = " << drinv << "/" << drinv_cov << " \n" + << "dphi0/cov = " << drinv << "/" << dphi0_cov << " \n" + << "dt/cov = " << drinv << "/" << dt_cov << " \n" + << "dz0/cov = " << drinv << "/" << dz0_cov << "\n"; + std::string myout = "D[0][k]= "; + for (unsigned int i = 0; i < 2 * n; i++) { + myout += std::to_string(D[0][i]); + myout += ", "; + } + edm::LogVerbatim("Tracklet") << myout; + } + + for (unsigned int i = 0; i < n; i++) { // loop over stubs + + phifactor = rstub[k / 2] * delta[k] / sigma[k] + D[0][k] * drinv + D[1][k] * dphi0 + D[2][k] * dt + D[3][k] * dz0; + iphifactor = kfactor[k] * rstub[k / 2] * idelta[k] * (1 << settings_.chisqphifactbits()) / sigma[k] - + iD[0][k] * idrinv - iD[1][k] * idphi0 - iD[2][k] * idt - iD[3][k] * idz0; + + if (NewChisqDebug) { + edm::LogVerbatim("Tracklet") << "delta[k]/sigma = " << delta[k] / sigma[k] << " delta[k] = " << delta[k] << "\n" + << "sum = " << phifactor - delta[k] / sigma[k] << " drinvterm = " << D[0][k] * drinv + << " dphi0term = " << D[1][k] * dphi0 << " dtterm = " << D[2][k] * dt + << " dz0term = " << D[3][k] * dz0 << "\n phifactor = " << phifactor; + } + + chisqfit += phifactor * phifactor; + ichisqfit += iphifactor * iphifactor / (1 << (2 * settings_.chisqphifactbits() - 4)); + + k++; + + rzfactor = delta[k] / sigma[k] + D[0][k] * drinv + D[1][k] * dphi0 + D[2][k] * dt + D[3][k] * dz0; + irzfactor = kfactor[k] * idelta[k] * (1 << settings_.chisqzfactbits()) / sigma[k] - iD[0][k] * idrinv - + iD[1][k] * idphi0 - iD[2][k] * idt - iD[3][k] * idz0; + + if (NewChisqDebug) { + edm::LogVerbatim("Tracklet") << "delta[k]/sigma = " << delta[k] / sigma[k] << " delta[k] = " << delta[k] << "\n" + << "sum = " << rzfactor - delta[k] / sigma[k] << " drinvterm = " << D[0][k] * drinv + << " dphi0term = " << D[1][k] * dphi0 << " dtterm = " << D[2][k] * dt + << " dz0term = " << D[3][k] * dz0 << "\n rzfactor = " << rzfactor; + } + + chisqfit += rzfactor * rzfactor; + ichisqfit += irzfactor * irzfactor / (1 << (2 * settings_.chisqzfactbits() - 4)); + + k++; + } + + if (settings_.writeMonitorData("ChiSq")) { + globals_->ofstream("chisq.txt") << asinh(itfit * settings_.ktpars()) << " " << chisqfit << " " << ichisqfit / 16.0 + << endl; + } + + // Chisquare per DOF capped out at 11 bits, so 15 is an educated guess + if (ichisqfit >= (1 << 15)) { + if (NewChisqDebug) { + edm::LogVerbatim("Tracklet") << "CHISQUARE (" << ichisqfit << ") LARGER THAN 11 BITS!"; + } + ichisqfit = (1 << 15) - 1; + } + + // Eliminate lower bits to fit in 8 bits + ichisqfit = ichisqfit >> 7; + // Probably redundant... enforce 8 bit cap + if (ichisqfit >= (1 << 8)) + ichisqfit = (1 << 8) - 1; + + double phicrit = phi0fit - asin(0.5 * settings_.rcrit() * rinvfit); + bool keep = (phicrit > settings_.phicritmin()) && (phicrit < settings_.phicritmax()); + + if (!keep) { + return; + } + + // NOTE: setFitPars in Tracklet.h now accepts chi2 r-phi and chi2 r-z values. This class only has access + // to the composite chi2. When setting fit parameters on a tracklet, this places all of the chi2 into the + // r-phi fit, and sets the r-z fit value to zero. + // + // This is also true for the call to setFitPars in trackFitFake. + tracklet->setFitPars(rinvfit, + phi0fit, + 0.0, + tfit, + z0fit, + chisqfit, + 0.0, + rinvfitexact, + phi0fitexact, + 0.0, + tfitexact, + z0fitexact, + chisqfitexact, + 0.0, + irinvfit, + iphi0fit, + 0, + itfit, + iz0fit, + ichisqfit, + 0, + 0); +} + +void FitTrack::trackFitFake(Tracklet* tracklet, std::vector&, std::vector>&) { + tracklet->setFitPars(tracklet->rinvapprox(), + tracklet->phi0approx(), + tracklet->d0approx(), + tracklet->tapprox(), + tracklet->z0approx(), + 0.0, + 0.0, + tracklet->rinv(), + tracklet->phi0(), + tracklet->d0(), + tracklet->t(), + tracklet->z0(), + 0.0, + 0.0, + tracklet->fpgarinv().value(), + tracklet->fpgaphi0().value(), + tracklet->fpgad0().value(), + tracklet->fpgat().value(), + tracklet->fpgaz0().value(), + 0, + 0, + 0); + return; +} + +std::vector FitTrack::orderedMatches(vector& fullmatch) { + std::vector tmp; + + std::vector indexArray; + for (auto& imatch : fullmatch) { + //check that we have correct order + if (imatch->nMatches() > 1) { + for (unsigned int j = 0; j < imatch->nMatches() - 1; j++) { + assert(imatch->getTracklet(j)->TCID() <= imatch->getTracklet(j + 1)->TCID()); + } + } + + if (settings_.debugTracklet() && imatch->nMatches() != 0) { + edm::LogVerbatim("Tracklet") << "orderedMatches: " << imatch->getName() << " " << imatch->nMatches(); + } + + indexArray.push_back(0); + } + + int bestIndex = -1; + do { + int bestTCID = (1 << 16); + bestIndex = -1; + for (unsigned int i = 0; i < fullmatch.size(); i++) { + if (indexArray[i] >= fullmatch[i]->nMatches()) { + //skip as we were at the end + continue; + } + int TCID = fullmatch[i]->getTracklet(indexArray[i])->TCID(); + if (TCID < bestTCID) { + bestTCID = TCID; + bestIndex = i; + } + } + if (bestIndex != -1) { + tmp.push_back(fullmatch[bestIndex]->getTracklet(indexArray[bestIndex])); + indexArray[bestIndex]++; + } + } while (bestIndex != -1); + + for (unsigned int i = 0; i < tmp.size(); i++) { + if (i > 0) { + //This allows for equal TCIDs. This means that we can e.g. have a track seeded in L1L2 that projects to both L3 and D4. + //The algorithm will pick up the first hit and drop the second. + if (tmp[i - 1]->TCID() > tmp[i]->TCID()) { + edm::LogVerbatim("Tracklet") << "Wrong TCID ordering in " << getName() << " : " << tmp[i - 1]->TCID() << " " + << tmp[i]->TCID(); + } + } + } + + return tmp; +} + +void FitTrack::execute() { + // merge + const std::vector& matches1 = orderedMatches(fullmatch1_); + const std::vector& matches2 = orderedMatches(fullmatch2_); + const std::vector& matches3 = orderedMatches(fullmatch3_); + const std::vector& matches4 = orderedMatches(fullmatch4_); + + if (settings_.debugTracklet() && (matches1.size() + matches2.size() + matches3.size() + matches4.size()) > 0) { + for (auto& imatch : fullmatch1_) { + edm::LogVerbatim("Tracklet") << imatch->getName() << " " << imatch->nMatches(); + } + edm::LogVerbatim("Tracklet") << getName() << "[" << iSector_ << "] matches : " << matches1.size() << " " + << matches2.size() << " " << matches3.size() << " " << matches4.size(); + } + + unsigned int indexArray[4]; + for (unsigned int i = 0; i < 4; i++) { + indexArray[i] = 0; + } + + int countAll = 0; + int countFit = 0; + + Tracklet* bestTracklet = nullptr; + do { + countAll++; + bestTracklet = nullptr; + + if (indexArray[0] < matches1.size()) { + if (bestTracklet == nullptr) { + bestTracklet = matches1[indexArray[0]]; + } else { + if (matches1[indexArray[0]]->TCID() < bestTracklet->TCID()) + bestTracklet = matches1[indexArray[0]]; + } + } + + if (indexArray[1] < matches2.size()) { + if (bestTracklet == nullptr) { + bestTracklet = matches2[indexArray[1]]; + } else { + if (matches2[indexArray[1]]->TCID() < bestTracklet->TCID()) + bestTracklet = matches2[indexArray[1]]; + } + } + + if (indexArray[2] < matches3.size()) { + if (bestTracklet == nullptr) { + bestTracklet = matches3[indexArray[2]]; + } else { + if (matches3[indexArray[2]]->TCID() < bestTracklet->TCID()) + bestTracklet = matches3[indexArray[2]]; + } + } + + if (indexArray[3] < matches4.size()) { + if (bestTracklet == nullptr) { + bestTracklet = matches4[indexArray[3]]; + } else { + if (matches4[indexArray[3]]->TCID() < bestTracklet->TCID()) + bestTracklet = matches4[indexArray[3]]; + } + } + + if (bestTracklet == nullptr) + break; + + //Counts total number of matched hits + int nMatches = 0; + + //Counts unique hits in each layer + int nMatchesUniq = 0; + bool match = false; + + if (indexArray[0] < matches1.size()) { + while (matches1[indexArray[0]] == bestTracklet && indexArray[0] < matches1.size()) { + indexArray[0]++; + nMatches++; + match = true; + } + } + + if (match) + nMatchesUniq++; + match = false; + + if (indexArray[1] < matches2.size()) { + while (matches2[indexArray[1]] == bestTracklet && indexArray[1] < matches2.size()) { + indexArray[1]++; + nMatches++; + match = true; + } + } + + if (match) + nMatchesUniq++; + match = false; + + if (indexArray[2] < matches3.size()) { + while (matches3[indexArray[2]] == bestTracklet && indexArray[2] < matches3.size()) { + indexArray[2]++; + nMatches++; + match = true; + } + } + + if (match) + nMatchesUniq++; + match = false; + + if (indexArray[3] < matches4.size()) { + while (matches4[indexArray[3]] == bestTracklet && indexArray[3] < matches4.size()) { + indexArray[3]++; + nMatches++; + match = true; + } + } + + if (match) + nMatchesUniq++; + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " : nMatches = " << nMatches << " nMatchesUniq = " << nMatchesUniq + << " " << asinh(bestTracklet->t()); + } + + std::vector trackstublist; + std::vector> stubidslist; + if ((bestTracklet->getISeed() >= 8 && nMatchesUniq >= 1) || + nMatchesUniq >= 2) { //For seeds index >=8 (triplet seeds), there are three stubs associated from start. + countFit++; + +#ifdef USEHYBRID + trackFitKF(bestTracklet, trackstublist, stubidslist); +#else + if (settings_.fakefit()) { + trackFitFake(bestTracklet, trackstublist, stubidslist); + } else { + trackFitChisq(bestTracklet, trackstublist, stubidslist); + } +#endif + + if (settings_.removalType() == "merge") { + trackfit_->addStubList(trackstublist); + trackfit_->addStubidsList(stubidslist); + trackfit_->addTrack(bestTracklet); + } else if (bestTracklet->fit()) { + assert(trackfit_ != nullptr); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << bestTracklet->getISeed() + << endl; + fout.close(); + } + trackfit_->addTrack(bestTracklet); + } + } + + } while (bestTracklet != nullptr); + + if (settings_.writeMonitorData("FT")) { + globals_->ofstream("fittrack.txt") << getName() << " " << countAll << " " << countFit << endl; + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/FullMatchMemory.cc b/L1Trigger/TrackFindingTracklet/src/FullMatchMemory.cc new file mode 100644 index 0000000000000..6a8b239ee93a9 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/FullMatchMemory.cc @@ -0,0 +1,69 @@ +#include "L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +FullMatchMemory::FullMatchMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) { + size_t pos = find_nth(name, 0, "_", 1); + assert(pos != string::npos); + initLayerDisk(pos + 1, layer_, disk_); +} + +void FullMatchMemory::addMatch(Tracklet* tracklet, const Stub* stub) { + if (!settings_.doKF() || !settings_.doMultipleMatches()) { //When using KF we allow multiple matches + for (auto& match : matches_) { + if (match.first == tracklet) { //Better match, replace + match.second = stub; + return; + } + } + } + std::pair tmp(tracklet, stub); + //Check that we have the right TCID order + if (!matches_.empty()) { + if ((!settings_.doKF() && matches_[matches_.size() - 1].first->TCID() >= tracklet->TCID()) || + (settings_.doKF() && matches_[matches_.size() - 1].first->TCID() > tracklet->TCID())) { + edm::LogPrint("Tracklet") << "Wrong TCID ordering in " << getName() << " : " + << matches_[matches_.size() - 1].first->TCID() << " " << tracklet->TCID() << " " + << matches_[matches_.size() - 1].first->trackletIndex() << " " + << tracklet->trackletIndex(); + } + } + matches_.push_back(tmp); +} + +void FullMatchMemory::writeMC(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/Matches/FullMatches_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < matches_.size(); j++) { + string match = (layer_ > 0) ? matches_[j].first->fullmatchstr(layer_) : matches_[j].first->fullmatchdiskstr(disk_); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << match << " " << trklet::hexFormat(match) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/Globals.cc b/L1Trigger/TrackFindingTracklet/src/Globals.cc new file mode 100644 index 0000000000000..da35939f46014 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Globals.cc @@ -0,0 +1,51 @@ +// Globals: holds "global" variables such as the IMATH_TrackletCalculators +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/imath.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorDisk.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorOverlap.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMRouterPhiCorrTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/HistBase.h" + +using namespace std; +using namespace trklet; + +Globals::Globals(Settings const& settings) { + imathGlobals* imathGlobs = new imathGlobals(); + + //takes owernship of globals pointer + imathGlobals_.reset(imathGlobs); + + // tracklet calculators + ITC_L1L2_ = make_unique(settings, imathGlobs, 1, 2); + ITC_L2L3_ = make_unique(settings, imathGlobs, 2, 3); + ITC_L3L4_ = make_unique(settings, imathGlobs, 3, 4); + ITC_L5L6_ = make_unique(settings, imathGlobs, 5, 6); + + ITC_F1F2_ = make_unique(settings, imathGlobs, 1, 2); + ITC_F3F4_ = make_unique(settings, imathGlobs, 3, 4); + ITC_B1B2_ = make_unique(settings, imathGlobs, -1, -2); + ITC_B3B4_ = make_unique(settings, imathGlobs, -3, -4); + + ITC_L1F1_ = make_unique(settings, imathGlobs, 1, 1); + ITC_L2F1_ = make_unique(settings, imathGlobs, 2, 1); + ITC_L1B1_ = make_unique(settings, imathGlobs, 1, -1); + ITC_L2B1_ = make_unique(settings, imathGlobs, 2, -1); +} + +Globals::~Globals() { + for (auto i : thePhiCorr_) { + delete i; + i = nullptr; + } +} + +std::ofstream& Globals::ofstream(std::string fname) { + if (ofstreams_.find(fname) != ofstreams_.end()) { + return *(ofstreams_[fname]); + } + std::ofstream* outptr = new std::ofstream(fname.c_str()); + ofstreams_[fname] = outptr; + return *outptr; +} diff --git a/L1Trigger/TrackFindingTracklet/src/HybridFit.cc b/L1Trigger/TrackFindingTracklet/src/HybridFit.cc new file mode 100644 index 0000000000000..2867bb70a0dbd --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/HybridFit.cc @@ -0,0 +1,251 @@ +#include "L1Trigger/TrackFindingTracklet/interface/HybridFit.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" + +#ifdef USEHYBRID +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +HybridFit::HybridFit(unsigned int iSector, Settings const& settings, Globals* globals) : settings_(settings) { + iSector_ = iSector; + globals_ = globals; +} + +void HybridFit::Fit(Tracklet* tracklet, std::vector& trackstublist) { + if (settings_.fakefit()) { + tracklet->setFitPars(tracklet->rinvapprox(), + tracklet->phi0approx(), + tracklet->d0approx(), + tracklet->tapprox(), + tracklet->z0approx(), + 0., + 0., + tracklet->rinv(), + tracklet->phi0(), + tracklet->d0(), + tracklet->t(), + tracklet->z0(), + 0., + 0., + tracklet->fpgarinv().value(), + tracklet->fpgaphi0().value(), + tracklet->fpgad0().value(), + tracklet->fpgat().value(), + tracklet->fpgaz0().value(), + 0, + 0, + 0); + return; + } + + std::vector TMTTstubs; + std::map L1StubIndices; + unsigned int L1stubID = 0; + + if (globals_->tmttSettings() == nullptr) { + if (settings_.printDebugKF()) + edm::LogVerbatim("L1track") << "Creating TMTT::Settings in HybridFit::Fit"; + globals_->tmttSettings() = make_unique(); + globals_->tmttSettings()->setMagneticField(settings_.bfield()); + } + + const tmtt::Settings& TMTTsettings = *globals_->tmttSettings(); + + int kf_phi_sec = iSector_; + + for (unsigned int k = 0; k < trackstublist.size(); k++) { + const L1TStub* L1stubptr = trackstublist[k]->l1tstub(); + + double kfphi = L1stubptr->phi(); + double kfr = L1stubptr->r(); + double kfz = L1stubptr->z(); + double kfbend = L1stubptr->bend(); + bool psmodule = L1stubptr->isPSmodule(); + unsigned int iphi = L1stubptr->iphi(); + double alpha = L1stubptr->alpha(settings_.stripPitch(psmodule)); + bool isTilted = L1stubptr->isTilted(); + + bool isBarrel = trackstublist[k]->isBarrel(); + int kflayer; + + if (isBarrel) { // Barrel-specific + kflayer = L1stubptr->layer() + 1; + if (settings_.printDebugKF()) + edm::LogVerbatim("L1track") << "Will create layer stub with : "; + } else { // Disk-specific + kflayer = abs(L1stubptr->disk()); + if (kfz > 0) { + kflayer += 10; + } else { + kflayer += 20; + } + if (settings_.printDebugKF()) + edm::LogVerbatim("L1track") << "Will create disk stub with : "; + } + + float stripPitch = settings_.stripPitch(psmodule); + float stripLength = settings_.stripLength(psmodule); + unsigned int nStrips = settings_.nStrips(psmodule); + + if (settings_.printDebugKF()) { + edm::LogVerbatim("L1track") << kfphi << " " << kfr << " " << kfz << " " << kfbend << " " << kflayer << " " + << isBarrel << " " << psmodule << " " << isTilted << " \n" + << stripPitch << " " << stripLength << " " << nStrips; + } + + unsigned int uniqueStubIndex = 1000 * L1stubID + L1stubptr->allStubIndex(); + tmtt::Stub* TMTTstubptr = new tmtt::Stub(&TMTTsettings, + uniqueStubIndex, + kfphi, + kfr, + kfz, + kfbend, + iphi, + -alpha, + kflayer, + kf_phi_sec, + psmodule, + isBarrel, + isTilted, + stripPitch, + stripLength, + nStrips); + TMTTstubs.push_back(TMTTstubptr); + L1StubIndices[uniqueStubIndex] = L1stubptr; + L1stubID++; + } + + if (settings_.printDebugKF()) { + edm::LogVerbatim("L1track") << "Made TMTTstubs: trackstublist.size() = " << trackstublist.size(); + } + + double kfrinv = tracklet->rinvapprox(); + double kfphi0 = tracklet->phi0approx(); + double kfz0 = tracklet->z0approx(); + double kft = tracklet->tapprox(); + double kfd0 = tracklet->d0approx(); + + if (settings_.printDebugKF()) { + edm::LogVerbatim("L1track") << "tracklet phi0 = " << kfphi0 << "\n" + << "iSector = " << iSector_ << "\n" + << "dphisectorHG = " << settings_.dphisectorHG(); + } + + // KF wants global phi0, not phi0 measured with respect to lower edge of sector (Tracklet convention). + kfphi0 = reco::reduceRange(kfphi0 + iSector_ * settings_.dphisector() - 0.5 * settings_.dphisectorHG()); + + std::pair helixrphi(kfrinv / (0.01 * settings_.c() * settings_.bfield()), kfphi0); + std::pair helixrz(kfz0, kft); + + // KF HLS uses HT mbin (which is binned q/Pt) to allow for scattering. So estimate it from tracklet. + double chargeOverPt = helixrphi.first; + int mBin = std::floor(TMTTsettings.houghNbinsPt() / 2) + + std::floor((TMTTsettings.houghNbinsPt() / 2) * chargeOverPt / (1. / TMTTsettings.houghMinPt())); + mBin = max(min(mBin, int(TMTTsettings.houghNbinsPt() - 1)), 0); // protect precision issues. + std::pair celllocation(mBin, 1); + + // Get range in z of tracks covered by this sector at chosen radius from beam-line + const vector etaRegions = TMTTsettings.etaRegions(); + const float chosenRofZ = TMTTsettings.chosenRofZ(); + + float kfzRef = kfz0 + chosenRofZ * kft; + + unsigned int kf_eta_reg = 0; + for (unsigned int iEtaSec = 1; iEtaSec < etaRegions.size() - 1; iEtaSec++) { // Doesn't apply eta < 2.4 cut. + const float etaMax = etaRegions[iEtaSec]; + const float zRefMax = chosenRofZ / tan(2. * atan(exp(-etaMax))); + if (kfzRef > zRefMax) + kf_eta_reg = iEtaSec; + } + + tmtt::L1track3D l1track3d( + &TMTTsettings, TMTTstubs, celllocation, helixrphi, helixrz, kfd0, kf_phi_sec, kf_eta_reg, 1, false); + unsigned int seedType = tracklet->getISeed(); + unsigned int numPS = tracklet->PSseed(); // Function PSseed() is out of date! + l1track3d.setSeedLayerType(seedType); + l1track3d.setSeedPS(numPS); + + if (globals_->tmttKFParamsComb() == nullptr) { + if (settings_.printDebugKF()) + edm::LogVerbatim("L1track") << "Will make KFParamsComb for " << settings_.nHelixPar() << " param fit"; + globals_->tmttKFParamsComb() = make_unique(&TMTTsettings, settings_.nHelixPar(), "KFfitter"); + } + + tmtt::KFParamsComb& fitterKF = *globals_->tmttKFParamsComb(); + + // Call Kalman fit + tmtt::L1fittedTrack fittedTrk = fitterKF.fit(l1track3d); + + if (fittedTrk.accepted()) { + tmtt::KFTrackletTrack trk = fittedTrk.returnKFTrackletTrack(); + + if (settings_.printDebugKF()) + edm::LogVerbatim("L1track") << "Done with Kalman fit. Pars: pt = " << trk.pt() + << ", 1/2R = " << settings_.bfield() * 3 * trk.qOverPt() / 2000 + << ", phi0 = " << trk.phi0() << ", eta = " << trk.eta() << ", z0 = " << trk.z0() + << ", chi2 = " << trk.chi2() << ", accepted = " << trk.accepted(); + + // Tracklet wants phi0 with respect to lower edge of sector, not global phi0. + double phi0fit = reco::reduceRange(trk.phi0() - iSector_ * 2 * M_PI / N_SECTOR + 0.5 * settings_.dphisectorHG()); + + double rinvfit = 0.01 * settings_.c() * settings_.bfield() * trk.qOverPt(); + + int irinvfit = rinvfit / settings_.krinvpars(); + int iphi0fit = phi0fit / settings_.kphi0pars(); + int itanlfit = trk.tanLambda() / settings_.ktpars(); + int iz0fit = trk.z0() / settings_.kz0pars(); + int id0fit = trk.d0() / settings_.kd0pars(); + int ichi2rphifit = trk.chi2rphi() / 16; + int ichi2rzfit = trk.chi2rz() / 16; + + const vector& stubsFromFit = trk.stubs(); + vector l1stubsFromFit; + for (const tmtt::Stub* s : stubsFromFit) { + unsigned int IDf = s->index(); + const L1TStub* l1s = L1StubIndices.at(IDf); + l1stubsFromFit.push_back(l1s); + } + + if (settings_.printDebugKF()) { + edm::LogVerbatim("L1track") << "#stubs before/after KF fit = " << TMTTstubs.size() << "/" + << l1stubsFromFit.size(); + } + + tracklet->setFitPars(rinvfit, + phi0fit, + trk.d0(), + trk.tanLambda(), + trk.z0(), + trk.chi2rphi(), + trk.chi2rz(), + rinvfit, + phi0fit, + trk.d0(), + trk.tanLambda(), + trk.z0(), + trk.chi2rphi(), + trk.chi2rz(), + irinvfit, + iphi0fit, + id0fit, + itanlfit, + iz0fit, + ichi2rphifit, + ichi2rzfit, + trk.hitPattern(), + l1stubsFromFit); + } else { + if (settings_.printDebugKF()) { + edm::LogVerbatim("L1track") << "FitTrack:KF rejected track"; + } + } + + for (const tmtt::Stub* s : TMTTstubs) { + delete s; + } +} +#endif diff --git a/L1Trigger/TrackFindingTracklet/src/InputLinkMemory.cc b/L1Trigger/TrackFindingTracklet/src/InputLinkMemory.cc new file mode 100644 index 0000000000000..de31792a719ea --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/InputLinkMemory.cc @@ -0,0 +1,106 @@ +#include "L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMRouterPhiCorrTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +#include +#include +#include +#include + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace trklet; +using namespace std; + +InputLinkMemory::InputLinkMemory(string name, Settings const& settings, unsigned int iSector, double, double) + : MemoryBase(name, settings, iSector) { + string subname = name.substr(5, 7); + phiregion_ = subname[3] - 'A'; + assert(phiregion_ >= 0 && phiregion_ < 8); + + layerdisk_ = initLayerDisk(3); +} + +bool InputLinkMemory::addStub( + Settings const& settings, Globals* globals, L1TStub& al1stub, Stub& stub, string dtc = "") { + if (layerdisk_ < N_LAYER && globals->phiCorr(layerdisk_) == nullptr) { + globals->phiCorr(layerdisk_) = new VMRouterPhiCorrTable(settings); + int nbits = 3; + if (layerdisk_ >= N_PSLAYER) + nbits = 4; + globals->phiCorr(layerdisk_)->init(layerdisk_ + 1, nbits, 3); + } + + unsigned int stublayerdisk = stub.layerdisk(); + assert(stublayerdisk < 11); + + if (stublayerdisk != layerdisk_) + return false; + + if (layerdisk_ < N_LAYER) { + FPGAWord r = stub.r(); + int bendbin = stub.bend().value(); + int rbin = (r.value() + (1 << (r.nbits() - 1))) >> (r.nbits() - 3); + const VMRouterPhiCorrTable& phiCorrTable = *globals->phiCorr(layerdisk_); + int iphicorr = phiCorrTable.getphiCorrValue(bendbin, rbin); + stub.setPhiCorr(iphicorr); + } + + FPGAWord iphi = stub.phicorr(); + unsigned int nallbits = settings_.nbitsallstubs(layerdisk_); + int phibin = iphi.bits(iphi.nbits() - nallbits, nallbits); + int iphivmRaw = iphi.bits(iphi.nbits() - 5, 5); + + if (phibin != phiregion_) + return false; + + if (getName().substr(10, dtc.size()) != dtc) + return false; + + string half = getName().substr(getName().size() - 3, 3); + if (half[1] != 'n') { + half = getName().substr(getName().size() - 1, 1); + } + + assert(half[0] == 'A' || half[0] == 'B'); + + if (half[0] == 'B' && iphivmRaw <= 15) + return false; + if (half[0] == 'A' && iphivmRaw > 15) + return false; + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will add stub in " << getName() << " " + << "iphiwmRaw = " << iphivmRaw << " phi=" << al1stub.phi() << " z=" << al1stub.z() + << " r=" << al1stub.r(); + } + if (stubs_.size() < settings_.maxStep("Link")) { + Stub* stubptr = new Stub(stub); + stubptr->setl1tstub(new L1TStub(al1stub)); + + stubs_.emplace_back(stubptr); + } + return true; +} + +void InputLinkMemory::writeStubs(bool first) { + openFile(first, "../data/MemPrints/InputStubs/InputStubs_"); + + for (unsigned int j = 0; j < stubs_.size(); j++) { + string stub = stubs_[j]->str(); + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << stub << " " << trklet::hexFormat(stub) << endl; + } + out_.close(); +} + +void InputLinkMemory::clean() { + for (auto& stub : stubs_) { + delete stub->l1tstub(); + delete stub; + } + stubs_.clear(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/L1TStub.cc b/L1Trigger/TrackFindingTracklet/src/L1TStub.cc new file mode 100644 index 0000000000000..1ae8497e75396 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/L1TStub.cc @@ -0,0 +1,127 @@ +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +using namespace std; +using namespace trklet; + +L1TStub::L1TStub() {} + +L1TStub::L1TStub(int eventid, + vector tps, + int iphi, + int iz, + int layer, + int ladder, + int module, + int strip, + double x, + double y, + double z, + double sigmax, + double sigmaz, + double pt, + double bend, + int isPSmodule, + int isFlipped) { + eventid_ = eventid; + tps_ = tps; + iphi_ = iphi; + iz_ = iz; + layer_ = layer; + ladder_ = ladder; + module_ = module; + strip_ = strip; + x_ = x; + y_ = y; + z_ = z; + sigmax_ = sigmax; + sigmaz_ = sigmaz; + pt_ = pt; + bend_ = bend; + isPSmodule_ = isPSmodule; + isFlipped_ = isFlipped; + + allstubindex_ = 999; +} + +void L1TStub::write(ofstream& out) { + out << "Stub: " << layer_ + 1 << "\t" << ladder_ << "\t" << module_ << "\t" << strip_ << "\t" << eventid_ << "\t" + << pt_ << "\t" << x_ << "\t" << y_ << "\t" << z_ << "\t" << bend_ << "\t" << isPSmodule_ << "\t" << isFlipped_ + << "\t" << tps_.size() << " \t"; + for (int itp : tps_) { + out << itp << " \t"; + } + out << endl; +} + +void L1TStub::write(ostream& out) { + out << "Stub: " << layer_ + 1 << "\t" << ladder_ << "\t" << module_ << "\t" << strip_ << "\t" << eventid_ << "\t" + << pt_ << "\t" << x_ << "\t" << y_ << "\t" << z_ << "\t" << bend_ << "\t" << isPSmodule_ << "\t" << isFlipped_ + << "\t" << tps_.size() << " \t"; + for (int itp : tps_) { + out << itp << " \t"; + } + out << endl; +} + +bool L1TStub::operator==(const L1TStub& other) const { + return (other.iphi() == iphi_ && other.iz() == iz_ && other.layer() == layer_ && other.ladder() == ladder_ && + other.module() == module_); +} + +void L1TStub::lorentzcor(double shift) { + double r = this->r(); + double phi = this->phi() - shift / r; + this->x_ = r * cos(phi); + this->y_ = r * sin(phi); +} + +double L1TStub::alpha(double pitch) const { + if (isPSmodule()) + return 0.0; + int flip = 1; + if (isFlipped()) + flip = -1; + if (z_ > 0.0) { + return ((int)strip_ - 509.5) * pitch * flip / r2(); + } + return -((int)strip_ - 509.5) * pitch * flip / r2(); +} + +double L1TStub::alphanorm() const { + if (isPSmodule()) + return 0.0; + int flip = 1; + if (isFlipped()) + flip = -1; + if (z_ > 0.0) { + return ((int)strip_ - 509.5) * flip / 510.0; + } + return -((int)strip_ - 509.5) * flip / 510.0; +} + +void L1TStub::setXY(double x, double y) { + x_ = x; + y_ = y; +} + +bool L1TStub::tpmatch(int tp) const { + for (int itp : tps_) { + if (tp == itp) + return true; + } + + return false; +} + +bool L1TStub::isTilted() const { + //here layer_ runs 0-5 for barrel, >1000 for disk + //disk modules and outer barrel modules are not tilted by construction + if (layer_ >= N_PSLAYER) + return false; + + assert(layer_ < N_PSLAYER); // safety for acccessing # modules/plank + if ((module_ <= N_TILTED_RINGS) || (module_ >= N_TILTED_RINGS + N_MOD_PLANK.at(layer_))) + return true; + return false; +} diff --git a/L1Trigger/TrackFindingTracklet/src/LayerProjection.cc b/L1Trigger/TrackFindingTracklet/src/LayerProjection.cc new file mode 100644 index 0000000000000..e6480bc930f7d --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/LayerProjection.cc @@ -0,0 +1,97 @@ +#include "L1Trigger/TrackFindingTracklet/interface/LayerProjection.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +void LayerProjection::init(Settings const& settings, + int projlayer, + double rproj, + int iphiproj, + int izproj, + int iphider, + int izder, + double phiproj, + double zproj, + double phiprojder, + double zprojder, + double phiprojapprox, + double zprojapprox, + double phiprojderapprox, + double zprojderapprox) { + assert(projlayer > 0); + assert(projlayer <= N_LAYER); + + valid_ = true; + + rproj_ = rproj; + + projlayer_ = projlayer; + + assert(iphiproj >= 0); + + if (rproj < settings.rPS2S()) { + fpgaphiproj_.set(iphiproj, settings.nphibitsstub(0), true, __LINE__, __FILE__); + int iphivm = (iphiproj >> (settings.nphibitsstub(0) - 5)) & 0x7; + if ((projlayer_ % 2) == 1) { + iphivm ^= 4; + } + fpgaphiprojvm_.set(iphivm, 3, true, __LINE__, __FILE__); + fpgazproj_.set(izproj, settings.nzbitsstub(0), false, __LINE__, __FILE__); + int izvm = izproj >> (12 - 7) & 0xf; + fpgazprojvm_.set(izvm, 4, true, __LINE__, __FILE__); + fpgaphiprojder_.set(iphider, settings.nbitsphiprojderL123(), false, __LINE__, __FILE__); + fpgazprojder_.set(izder, settings.nbitszprojderL123(), false, __LINE__, __FILE__); + } else { + fpgaphiproj_.set(iphiproj, settings.nphibitsstub(5), true, __LINE__, __FILE__); + int iphivm = (iphiproj >> (settings.nphibitsstub(5) - 5)) & 0x7; + if ((projlayer_ % 2) == 1) { + iphivm ^= 4; + } + fpgaphiprojvm_.set(iphivm, 3, true, __LINE__, __FILE__); + fpgazproj_.set(izproj, settings.nzbitsstub(5), false, __LINE__, __FILE__); + int izvm = izproj >> (8 - 7) & 0xf; + fpgazprojvm_.set(izvm, 4, true, __LINE__, __FILE__); + fpgaphiprojder_.set(iphider, settings.nbitsphiprojderL456(), false, __LINE__, __FILE__); + fpgazprojder_.set(izder, settings.nbitszprojderL456(), false, __LINE__, __FILE__); + } + + ////Separate the vm projections into zbins + ////This determines the central bin: + ////int zbin=4+(zproj.value()>>(zproj.nbits()-3)); + ////But we need some range (particularly for L5L6 seed projecting to L1-L3): + unsigned int zbin1 = (1 << (settings.MEBinsBits() - 1)) + + (((fpgazproj_.value() >> (fpgazproj_.nbits() - settings.MEBinsBits() - 2)) - 2) >> 2); + unsigned int zbin2 = (1 << (settings.MEBinsBits() - 1)) + + (((fpgazproj_.value() >> (fpgazproj_.nbits() - settings.MEBinsBits() - 2)) + 2) >> 2); + if (zbin1 >= settings.MEBins()) + zbin1 = 0; //note that zbin1 is unsigned + if (zbin2 >= settings.MEBins()) + zbin2 = settings.MEBins() - 1; + assert(zbin1 <= zbin2); + assert(zbin2 - zbin1 <= 1); + fpgazbin1projvm_.set(zbin1, settings.MEBinsBits(), true, __LINE__, __FILE__); // first z bin + if (zbin1 == zbin2) + fpgazbin2projvm_.set(0, 1, true, __LINE__, __FILE__); // don't need to check adjacent z bin + else + fpgazbin2projvm_.set(1, 1, true, __LINE__, __FILE__); // do need to check next z bin + + //fine vm z bits. Use 4 bits for fine position. starting at zbin 1 + int finez = ((1 << (settings.MEBinsBits() + 2)) + + (fpgazproj_.value() >> (fpgazproj_.nbits() - (settings.MEBinsBits() + 3)))) - + (zbin1 << 3); + + fpgafinezvm_.set(finez, 4, true, __LINE__, __FILE__); // fine z postions starting at zbin1 + + phiproj_ = phiproj; + zproj_ = zproj; + phiprojder_ = phiprojder; + zprojder_ = zprojder; + + phiprojapprox_ = phiprojapprox; + zprojapprox_ = zprojapprox; + phiprojderapprox_ = phiprojderapprox; + zprojderapprox_ = zprojderapprox; +} diff --git a/L1Trigger/TrackFindingTracklet/src/LayerResidual.cc b/L1Trigger/TrackFindingTracklet/src/LayerResidual.cc new file mode 100644 index 0000000000000..b9483e5135881 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/LayerResidual.cc @@ -0,0 +1,42 @@ +#include "L1Trigger/TrackFindingTracklet/interface/LayerResidual.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +using namespace std; +using namespace trklet; + +void LayerResidual::init(Settings const& settings, + int layer, + int iphiresid, + int izresid, + int istubid, + double phiresid, + double zresid, + double phiresidapprox, + double zresidapprox, + double rstub, + const Stub* stubptr) { + assert(layer > 0); + assert(layer <= N_LAYER); + + if (valid_ && (std::abs(iphiresid) > std::abs(fpgaphiresid_.value()))) + return; + + valid_ = true; + + layer_ = layer; + + fpgaphiresid_.set(iphiresid, settings.phiresidbits(), false, __LINE__, __FILE__); + fpgazresid_.set(izresid, settings.zresidbits(), false, __LINE__, __FILE__); + int nbitsid = 10; + fpgastubid_.set(istubid, nbitsid, true, __LINE__, __FILE__); + assert(!fpgaphiresid_.atExtreme()); + + phiresid_ = phiresid; + zresid_ = zresid; + + phiresidapprox_ = phiresidapprox; + zresidapprox_ = zresidapprox; + + rstub_ = rstub; + stubptr_ = stubptr; +} diff --git a/L1Trigger/TrackFindingTracklet/src/MatchCalculator.cc b/L1Trigger/TrackFindingTracklet/src/MatchCalculator.cc new file mode 100644 index 0000000000000..7e43c32886922 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/MatchCalculator.cc @@ -0,0 +1,572 @@ +#include "L1Trigger/TrackFindingTracklet/interface/MatchCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/HistBase.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +MatchCalculator::MatchCalculator(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + phioffset_ = phimin_; + + phiregion_ = name[8] - 'A'; + layerdisk_ = initLayerDisk(3); + + fullMatches_.resize(12, nullptr); + + //TODO - need to sort out constants here + icorrshift_ = 7; + + if (layerdisk_ < N_PSLAYER) { + icorzshift_ = -1 - settings_.PS_zderL_shift(); + } else { + icorzshift_ = -1 - settings_.SS_zderL_shift(); + } + phi0shift_ = 3; + fact_ = 1; + if (layerdisk_ >= N_PSLAYER && layerdisk_ < N_LAYER) { + fact_ = (1 << (settings_.nzbitsstub(0) - settings_.nzbitsstub(5))); + icorrshift_ -= (10 - settings_.nrbitsstub(layerdisk_)); + icorzshift_ += (settings_.nzbitsstub(0) - settings_.nzbitsstub(5) + settings_.nrbitsstub(layerdisk_) - + settings_.nrbitsstub(0)); + phi0shift_ = 0; + } + + for (unsigned int iSeed = 0; iSeed < N_SEED; iSeed++) { + if (layerdisk_ < N_LAYER) { + phimatchcut_[iSeed] = + settings_.rphimatchcut(iSeed, layerdisk_) / (settings_.kphi1() * settings_.rmean(layerdisk_)); + zmatchcut_[iSeed] = settings_.zmatchcut(iSeed, layerdisk_) / settings_.kz(); + } else { + rphicutPS_[iSeed] = settings_.rphicutPS(iSeed, layerdisk_ - N_LAYER) / (settings_.kphi() * settings_.kr()); + rphicut2S_[iSeed] = settings_.rphicut2S(iSeed, layerdisk_ - N_LAYER) / (settings_.kphi() * settings_.kr()); + rcut2S_[iSeed] = settings_.rcut2S(iSeed, layerdisk_ - N_LAYER) / settings_.krprojshiftdisk(); + rcutPS_[iSeed] = settings_.rcutPS(iSeed, layerdisk_ - N_LAYER) / settings_.krprojshiftdisk(); + } + } + + if (iSector_ == 0 && layerdisk_ < N_LAYER && settings_.writeTable()) { + ofstream outphicut; + outphicut.open(getName() + "_phicut.tab"); + outphicut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outphicut << "," << endl; + outphicut << phimatchcut_[seedindex]; + } + outphicut << endl << "};" << endl; + outphicut.close(); + + ofstream outzcut; + outzcut.open(getName() + "_zcut.tab"); + outzcut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outzcut << "," << endl; + outzcut << zmatchcut_[seedindex]; + } + outzcut << endl << "};" << endl; + outzcut.close(); + } + + if (iSector_ == 0 && layerdisk_ >= N_LAYER && settings_.writeTable()) { + ofstream outphicut; + outphicut.open(getName() + "_PSphicut.tab"); + outphicut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outphicut << "," << endl; + outphicut << rphicutPS_[seedindex]; + } + outphicut << endl << "};" << endl; + outphicut.close(); + + outphicut.open(getName() + "_2Sphicut.tab"); + outphicut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outphicut << "," << endl; + outphicut << rphicut2S_[seedindex]; + } + outphicut << endl << "};" << endl; + outphicut.close(); + + ofstream outzcut; + outzcut.open(getName() + "_PSrcut.tab"); + outzcut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outzcut << "," << endl; + outzcut << rcutPS_[seedindex]; + } + outzcut << endl << "};" << endl; + outzcut.close(); + + outzcut.open(getName() + "_2Srcut.tab"); + outzcut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outzcut << "," << endl; + outzcut << rcut2S_[seedindex]; + } + outzcut << endl << "};" << endl; + outzcut.close(); + } + + for (unsigned int i = 0; i < N_DSS_MOD * 2; i++) { + ialphafactinner_[i] = (1 << settings_.alphashift()) * settings_.krprojshiftdisk() * settings_.half2SmoduleWidth() / + (1 << (settings_.nbitsalpha() - 1)) / (settings_.rDSSinner(i) * settings_.rDSSinner(i)) / + settings_.kphi(); + ialphafactouter_[i] = (1 << settings_.alphashift()) * settings_.krprojshiftdisk() * settings_.half2SmoduleWidth() / + (1 << (settings_.nbitsalpha() - 1)) / (settings_.rDSSouter(i) * settings_.rDSSouter(i)) / + settings_.kphi(); + } +} + +void MatchCalculator::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output.substr(0, 8) == "matchout") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + unsigned int iSeed = getISeed(memory->getName()); + fullMatches_[iSeed] = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output " << output; +} + +void MatchCalculator::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "allstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + allstubs_ = tmp; + return; + } + if (input == "allprojin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + allprojs_ = tmp; + return; + } + if (input.substr(0, 5) == "match" && input.substr(input.size() - 2, 2) == "in") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + matches_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input " << input; +} + +void MatchCalculator::execute() { + unsigned int countall = 0; + unsigned int countsel = 0; + + Tracklet* oldTracklet = nullptr; + + std::vector, const Stub*> > mergedMatches = mergeMatches(matches_); + + for (unsigned int j = 0; j < mergedMatches.size(); j++) { + if (settings_.debugTracklet() && j == 0) { + edm::LogVerbatim("Tracklet") << getName() << " has " << mergedMatches.size() << " candidate matches"; + } + + countall++; + + const Stub* fpgastub = mergedMatches[j].second; + Tracklet* tracklet = mergedMatches[j].first.first; + const L1TStub* stub = fpgastub->l1tstub(); + + //check that the matches are orderd correctly + //allow equal here since we can have more than one cadidate match per tracklet projection + if (oldTracklet != nullptr) { + assert(oldTracklet->TCID() <= tracklet->TCID()); + } + oldTracklet = tracklet; + + if (layerdisk_ < N_LAYER) { + //Integer calculation + + int ir = fpgastub->r().value(); + int iphi = tracklet->fpgaphiproj(layerdisk_ + 1).value(); + int icorr = (ir * tracklet->fpgaphiprojder(layerdisk_ + 1).value()) >> icorrshift_; + iphi += icorr; + + int iz = tracklet->fpgazproj(layerdisk_ + 1).value(); + int izcor = (ir * tracklet->fpgazprojder(layerdisk_ + 1).value() + (1 << (icorzshift_ - 1))) >> icorzshift_; + iz += izcor; + + int ideltaz = fpgastub->z().value() - iz; + int ideltaphi = (fpgastub->phi().value() << phi0shift_) - (iphi << (settings_.phi0bitshift() - 1 + phi0shift_)); + + //Floating point calculations + + double phi = stub->phi() - phioffset_; + double r = stub->r(); + double z = stub->z(); + + if (settings_.useapprox()) { + double dphi = reco::reduceRange(phi - fpgastub->phiapprox(0.0, 0.0)); + assert(std::abs(dphi) < 0.001); + phi = fpgastub->phiapprox(0.0, 0.0); + z = fpgastub->zapprox(); + r = fpgastub->rapprox(); + } + + if (phi < 0) + phi += 2 * M_PI; + + double dr = r - tracklet->rproj(layerdisk_ + 1); + assert(std::abs(dr) < settings_.drmax()); + + double dphi = + reco::reduceRange(phi - (tracklet->phiproj(layerdisk_ + 1) + dr * tracklet->phiprojder(layerdisk_ + 1))); + + double dz = z - (tracklet->zproj(layerdisk_ + 1) + dr * tracklet->zprojder(layerdisk_ + 1)); + + double dphiapprox = reco::reduceRange( + phi - (tracklet->phiprojapprox(layerdisk_ + 1) + dr * tracklet->phiprojderapprox(layerdisk_ + 1))); + + double dzapprox = z - (tracklet->zprojapprox(layerdisk_ + 1) + dr * tracklet->zprojderapprox(layerdisk_ + 1)); + + int seedindex = tracklet->getISeed(); + + assert(phimatchcut_[seedindex] > 0); + assert(zmatchcut_[seedindex] > 0); + + if (settings_.bookHistos()) { + bool truthmatch = tracklet->stubtruthmatch(stub); + + HistBase* hists = globals_->histograms(); + hists->FillLayerResidual(layerdisk_ + 1, + seedindex, + dphiapprox * settings_.rmean(layerdisk_), + ideltaphi * settings_.kphi1() * settings_.rmean(layerdisk_), + ideltaz * fact_ * settings_.kz(), + dz, + truthmatch); + } + + if (std::abs(dphi) > 0.2 || std::abs(dphiapprox) > 0.2) { + edm::LogProblem("Tracklet") << "WARNING dphi and/or dphiapprox too large : " << dphi << " " << dphiapprox + << endl; + } + assert(std::abs(dphi) < 0.2); + assert(std::abs(dphiapprox) < 0.2); + + if (settings_.writeMonitorData("Residuals")) { + double pt = 0.01 * settings_.c() * settings_.bfield() / std::abs(tracklet->rinv()); + + globals_->ofstream("layerresiduals.txt") + << layerdisk_ + 1 << " " << seedindex << " " << pt << " " + << ideltaphi * settings_.kphi1() * settings_.rmean(layerdisk_) << " " + << dphiapprox * settings_.rmean(layerdisk_) << " " + << phimatchcut_[seedindex] * settings_.kphi1() * settings_.rmean(layerdisk_) << " " + << ideltaz * fact_ * settings_.kz() << " " << dz << " " << zmatchcut_[seedindex] * settings_.kz() << endl; + } + + bool imatch = (std::abs(ideltaphi) <= (int)phimatchcut_[seedindex]) && + (std::abs(ideltaz * fact_) <= (int)zmatchcut_[seedindex]); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " imatch = " << imatch << " ideltaphi cut " << ideltaphi << " " + << phimatchcut_[seedindex] << " ideltaz*fact cut " << ideltaz * fact_ << " " + << zmatchcut_[seedindex]; + } + + if (imatch) { + countsel++; + + tracklet->addMatch(layerdisk_ + 1, + ideltaphi, + ideltaz, + dphi, + dz, + dphiapprox, + dzapprox, + (phiregion_ << 7) + fpgastub->stubindex().value(), + stub->r(), + mergedMatches[j].second); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Accepted full match in layer " << getName() << " " << tracklet << " " + << iSector_; + } + + fullMatches_[seedindex]->addMatch(tracklet, mergedMatches[j].second); + } + } else { //disk matches + + //check that stubs and projections in same half of detector + assert(stub->z() * tracklet->t() > 0.0); + + int sign = (tracklet->t() > 0.0) ? 1 : -1; + int disk = sign * (layerdisk_ - (N_LAYER - 1)); + assert(disk != 0); + + //Perform integer calculations here + + int iz = fpgastub->z().value(); + int iphi = tracklet->fpgaphiprojdisk(disk).value(); + + //TODO - need to express interms of constants + int shifttmp = 6; + int iphicorr = (iz * tracklet->fpgaphiprojderdisk(disk).value()) >> shifttmp; + + iphi += iphicorr; + + int ir = tracklet->fpgarprojdisk(disk).value(); + + //TODO - need to express interms of constants + int shifttmp2 = 7; + int ircorr = (iz * tracklet->fpgarprojderdisk(disk).value()) >> shifttmp2; + + ir += ircorr; + + int ideltaphi = fpgastub->phi().value() * settings_.kphi() / settings_.kphi() - iphi; + + int irstub = fpgastub->r().value(); + int ialphafact = 0; + if (!stub->isPSmodule()) { + assert(irstub < (int)N_DSS_MOD * 2); + if (abs(disk) <= 2) { + ialphafact = ialphafactinner_[irstub]; + irstub = settings_.rDSSinner(irstub) / settings_.kr(); + } else { + ialphafact = ialphafactouter_[irstub]; + irstub = settings_.rDSSouter(irstub) / settings_.kr(); + } + } + + //TODO stub and projection r should not use different # bits... + int ideltar = (irstub >> 1) - ir; + + if (!stub->isPSmodule()) { + int ialphanew = fpgastub->alphanew().value(); + int iphialphacor = ((ideltar * ialphanew * ialphafact) >> settings_.alphashift()); + ideltaphi += iphialphacor; + } + + //Perform floating point calculations here + + double phi = stub->phi() - phioffset_; + double z = stub->z(); + double r = stub->r(); + + if (settings_.useapprox()) { + double dphi = reco::reduceRange(phi - fpgastub->phiapprox(0.0, 0.0)); + assert(std::abs(dphi) < 0.001); + phi = fpgastub->phiapprox(0.0, 0.0); + z = fpgastub->zapprox(); + r = fpgastub->rapprox(); + } + + if (phi < 0) + phi += 2 * M_PI; + + double dz = z - sign * settings_.zmean(layerdisk_ - N_LAYER); + + if (std::abs(dz) > settings_.dzmax()) { + throw cms::Exception("LogicError") + << __FILE__ << " " << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() + << "\n stub " << stub->z() << " disk " << disk << " " << dz; + } + + double phiproj = tracklet->phiprojdisk(disk) + dz * tracklet->phiprojderdisk(disk); + + double rproj = tracklet->rprojdisk(disk) + dz * tracklet->rprojderdisk(disk); + + double deltar = r - rproj; + + double dr = stub->r() - rproj; + + double dphi = reco::reduceRange(phi - phiproj); + + double dphiapprox = + reco::reduceRange(phi - (tracklet->phiprojapproxdisk(disk) + dz * tracklet->phiprojderapproxdisk(disk))); + + double drapprox = stub->r() - (tracklet->rprojapproxdisk(disk) + dz * tracklet->rprojderapproxdisk(disk)); + + double drphi = dphi * stub->r(); + double drphiapprox = dphiapprox * stub->r(); + + if (!stub->isPSmodule()) { + double alphanorm = stub->alphanorm(); + dphi += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r2(); + dphiapprox += drapprox * alphanorm * settings_.half2SmoduleWidth() / stub->r2(); + + drphi += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r(); + drphiapprox += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r(); + } + + int seedindex = tracklet->getISeed(); + + int idrphicut = rphicutPS_[seedindex]; + int idrcut = rcutPS_[seedindex]; + if (!stub->isPSmodule()) { + idrphicut = rphicut2S_[seedindex]; + idrcut = rcut2S_[seedindex]; + } + + double drphicut = idrphicut * settings_.kphi() * settings_.kr(); + double drcut = idrcut * settings_.krprojshiftdisk(); + + if (settings_.writeMonitorData("Residuals")) { + double pt = 0.01 * settings_.c() * settings_.bfield() / std::abs(tracklet->rinv()); + + globals_->ofstream("diskresiduals.txt") + << disk << " " << stub->isPSmodule() << " " << tracklet->layer() << " " << abs(tracklet->disk()) << " " + << pt << " " << ideltaphi * settings_.kphi() * stub->r() << " " << drphiapprox << " " << drphicut << " " + << ideltar * settings_.krprojshiftdisk() << " " << deltar << " " << drcut << " " << endl; + } + + bool match = (std::abs(drphi) < drphicut) && (std::abs(deltar) < drcut); + + bool imatch = (std::abs(ideltaphi * irstub) < idrphicut) && (std::abs(ideltar) < idrcut); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "imatch match disk: " << imatch << " " << match << " " << std::abs(ideltaphi) + << " " << drphicut / (settings_.kphi() * stub->r()) << " " << std::abs(ideltar) + << " " << drcut / settings_.krprojshiftdisk() << " r = " << stub->r(); + } + + if (imatch) { + countsel++; + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "MatchCalculator found match in disk " << getName(); + } + + if (std::abs(dphi) >= 0.25) { + edm::LogVerbatim("Tracklet") << "dphi " << dphi << " Seed / ISeed " << tracklet->getISeed(); + } + assert(std::abs(dphi) < 0.25); + assert(std::abs(dphiapprox) < 0.25); + + tracklet->addMatchDisk(disk, + ideltaphi, + ideltar, + drphi / stub->r(), + dr, + drphiapprox / stub->r(), + drapprox, + stub->alpha(settings_.stripPitch(stub->isPSmodule())), + (phiregion_ << 7) + fpgastub->stubindex().value(), + stub->z(), + fpgastub); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Accepted full match in disk " << getName() << " " << tracklet << " " + << iSector_; + } + + fullMatches_[seedindex]->addMatch(tracklet, mergedMatches[j].second); + } + } + if (countall >= settings_.maxStep("MC")) + break; + } + + if (settings_.writeMonitorData("MC")) { + globals_->ofstream("matchcalculator.txt") << getName() << " " << countall << " " << countsel << endl; + } +} + +std::vector, const Stub*> > MatchCalculator::mergeMatches( + vector& candmatch) { + std::vector, const Stub*> > tmp; + + std::vector indexArray; + indexArray.reserve(candmatch.size()); + for (unsigned int i = 0; i < candmatch.size(); i++) { + indexArray.push_back(0); + } + + int bestIndex = -1; + do { + int bestSector = 100; + int bestTCID = (1 << 16); + bestIndex = -1; + for (unsigned int i = 0; i < candmatch.size(); i++) { + if (indexArray[i] >= candmatch[i]->nMatches()) { + // skip as we were at the end + continue; + } + int TCID = candmatch[i]->getMatch(indexArray[i]).first.first->TCID(); + int dSector = 0; + if (dSector > 2) + dSector -= N_SECTOR; + if (dSector < -2) + dSector += N_SECTOR; + assert(abs(dSector) < 2); + if (dSector == -1) + dSector = 2; + if (dSector < bestSector) { + bestSector = dSector; + bestTCID = TCID; + bestIndex = i; + } + if (dSector == bestSector) { + if (TCID < bestTCID) { + bestTCID = TCID; + bestIndex = i; + } + } + } + if (bestIndex != -1) { + tmp.push_back(candmatch[bestIndex]->getMatch(indexArray[bestIndex])); + indexArray[bestIndex]++; + } + } while (bestIndex != -1); + + if (layerdisk_ < N_LAYER) { + int lastTCID = -1; + bool error = false; + + //Allow equal TCIDs since we can have multiple candidate matches + for (unsigned int i = 1; i < tmp.size(); i++) { + if (lastTCID > tmp[i].first.first->TCID()) { + edm::LogProblem("Tracklet") << "Wrong TCID ordering for projections in " << getName() << " last " << lastTCID + << " " << tmp[i].first.first->TCID(); + error = true; + } else { + lastTCID = tmp[i].first.first->TCID(); + } + } + + if (error) { + for (unsigned int i = 1; i < tmp.size(); i++) { + edm::LogProblem("Tracklet") << "Wrong order for in " << getName() << " " << i << " " << tmp[i].first.first + << " " << tmp[i].first.first->TCID(); + } + } + } + + for (unsigned int i = 0; i < tmp.size(); i++) { + if (i > 0) { + //This allows for equal TCIDs. This means that we can e.g. have a track seeded + //in L1L2 that projects to both L3 and D4. The algorithm will pick up the first hit and + //drop the second + + assert(tmp[i - 1].first.first->TCID() <= tmp[i].first.first->TCID()); + } + } + + return tmp; +} diff --git a/L1Trigger/TrackFindingTracklet/src/MatchEngine.cc b/L1Trigger/TrackFindingTracklet/src/MatchEngine.cc new file mode 100644 index 0000000000000..417e43c24f8f7 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/MatchEngine.cc @@ -0,0 +1,320 @@ +#include "L1Trigger/TrackFindingTracklet/interface/MatchEngine.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +MatchEngine::MatchEngine(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + layer_ = 0; + disk_ = 0; + string subname = name.substr(3, 2); + if (subname.substr(0, 1) == "L") + layer_ = stoi(subname.substr(1, 1)); + else if (subname.substr(0, 1) == "D") + disk_ = stoi(subname.substr(1, 1)); + else + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " " << name << " subname = " << subname << " " + << layer_ << " " << disk_; + + if (layer_ > 0) { + unsigned int nbits = 3; + if (layer_ >= 4) + nbits = 4; + + for (unsigned int irinv = 0; irinv < 32; irinv++) { + double rinv = (irinv - 15.5) * (1 << (settings_.nbitsrinv() - 5)) * settings_.krinvpars(); + + double stripPitch = + (settings_.rmean(layer_ - 1) < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double projbend = bend(settings_.rmean(layer_ - 1), rinv, stripPitch); + for (unsigned int ibend = 0; ibend < (unsigned int)(1 << nbits); ibend++) { + double stubbend = benddecode(ibend, layer_ <= 3); + bool pass = std::abs(stubbend - projbend) < settings_.bendcutme(layer_ - 1); + table_.push_back(pass); + } + } + + if (settings_.writeTable()) { + ofstream out; + char layer = '0' + layer_; + string fname = "METable_L"; + fname += layer; + fname += ".tab"; + out.open(fname.c_str()); + out << "{" << endl; + for (unsigned int i = 0; i < table_.size(); i++) { + if (i != 0) { + out << "," << endl; + } + out << table_[i]; + } + out << "};" << endl; + out.close(); + } + } + + if (disk_ > 0) { + for (unsigned int iprojbend = 0; iprojbend < 32; iprojbend++) { + double projbend = 0.5 * (iprojbend - 15.0); + for (unsigned int ibend = 0; ibend < 8; ibend++) { + double stubbend = benddecode(ibend, true); + bool pass = std::abs(stubbend - projbend) < settings_.bendcutme(disk_ + 5); + tablePS_.push_back(pass); + } + for (unsigned int ibend = 0; ibend < 16; ibend++) { + double stubbend = benddecode(ibend, false); + bool pass = std::abs(stubbend - projbend) < settings_.bendcutme(disk_ + 5); + table2S_.push_back(pass); + } + } + } +} + +void MatchEngine::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "matchout") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + candmatches_ = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output: " << output; +} + +void MatchEngine::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "vmstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + vmstubs_ = tmp; + return; + } + if (input == "vmprojin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + vmprojs_ = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input: " << input; +} + +void MatchEngine::execute() { + bool barrel = layer_ > 0; + + unsigned int countall = 0; + unsigned int countpass = 0; + + constexpr unsigned int kNBitsBuffer = 3; + + int writeindex = 0; + int readindex = 0; + std::pair projbuffer[1 << kNBitsBuffer]; //iproj zbin + + //The next projection to read, the number of projections and flag if we have more projections to read + int iproj = 0; + int nproj = vmprojs_->nTracklets(); + bool moreproj = iproj < nproj; + + //Projection that is read from the buffer and compared to stubs + int rzbin = 0; + int projfinerz = 0; + int projfinerzadj = 0; + + int projindex = 0; + int projrinv = 0; + bool isPSseed = false; + + //Number of stubs for current zbin and the stub being processed on this clock + int nstubs = 0; + int istub = 0; + + //Main processing loops starts here + for (unsigned int istep = 0; istep < settings_.maxStep("ME"); istep++) { + countall++; + + int writeindexplus = (writeindex + 1) % (1 << kNBitsBuffer); + int writeindexplusplus = (writeindex + 2) % (1 << kNBitsBuffer); + + //Determine if buffer is full - or near full as a projection + //can point to two z bins we might fill two slots in the buffer + bool bufferfull = (writeindexplus == readindex) || (writeindexplusplus == readindex); + + //Determin if buffer is empty + bool buffernotempty = (writeindex != readindex); + + //If we have more projections and the buffer is not full we read + //next projection and put in buffer if there are stubs in the + //memory the projection points to + + if ((!moreproj) && (!buffernotempty)) + break; + + if (moreproj && (!bufferfull)) { + Tracklet* proj = vmprojs_->getTracklet(iproj); + + int iprojtmp = iproj; + + iproj++; + moreproj = iproj < nproj; + + unsigned int rzfirst = barrel ? proj->zbin1projvm(layer_) : proj->rbin1projvm(disk_); + unsigned int rzlast = rzfirst; + bool second = (barrel ? proj->zbin2projvm(layer_) : proj->rbin2projvm(disk_)) == 1; + if (second) + rzlast += 1; + + //Check if there are stubs in the memory + int nstubfirst = vmstubs_->nStubsBin(rzfirst); + int nstublast = vmstubs_->nStubsBin(rzlast); + bool savefirst = nstubfirst != 0; + bool savelast = second && (nstublast != 0); + + int writeindextmp = writeindex; + int writeindextmpplus = (writeindex + 1) % (1 << kNBitsBuffer); + + if (savefirst && savelast) { + writeindex = writeindexplusplus; + } else if (savefirst || savelast) { + writeindex = writeindexplus; + } + + if (savefirst) { //TODO for HLS (make code logic simpler) + std::pair tmp(iprojtmp, rzfirst); + projbuffer[writeindextmp] = tmp; + } + if (savelast) { + std::pair tmp(iprojtmp, rzlast + 100); //TODO for HLS (fix flagging that this is second bin) + if (savefirst) { + projbuffer[writeindextmpplus] = tmp; + } else { + projbuffer[writeindextmp] = tmp; + } + } + } + + //If the buffer is not empty we have a projection that we need to process. + + if (buffernotempty) { + int istubtmp = istub; + + //New projection + if (istub == 0) { + projindex = projbuffer[readindex].first; + rzbin = projbuffer[readindex].second; + bool second = false; + if (rzbin >= 100) { + rzbin -= 100; + second = true; + } + + Tracklet* proj = vmprojs_->getTracklet(projindex); + + nstubs = vmstubs_->nStubsBin(rzbin); + + projfinerz = barrel ? proj->finezvm(layer_) : proj->finervm(disk_); + + projrinv = + barrel + ? (16 + (((-2) * proj->fpgaphiprojder(layer_).value()) >> (proj->fpgaphiprojder(layer_).nbits() - 4))) + : proj->getBendIndex(disk_).value(); + assert(projrinv >= 0); + if (settings_.extended() && projrinv == 32) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Extended tracking, projrinv:" << projrinv; + } + projrinv = 31; + } + assert(projrinv < 32); + + isPSseed = proj->PSseed() == 1; + + //Calculate fine z position + if (second) { + projfinerzadj = projfinerz - 8; + } else { + projfinerzadj = projfinerz; + } + if (nstubs == 1) { + istub = 0; + readindex = (readindex + 1) % (1 << kNBitsBuffer); + } else { + istub++; + } + } else { + //Check if last stub, if so, go to next buffer entry + if (istub + 1 >= nstubs) { + istub = 0; + readindex = (readindex + 1) % (1 << kNBitsBuffer); + } else { + istub++; + } + } + + //Read vmstub memory and extract data fields + const VMStubME& vmstub = vmstubs_->getVMStubMEBin(rzbin, istubtmp); + + bool isPSmodule = vmstub.isPSmodule(); + + int stubfinerz = vmstub.finerz().value(); + + int nbits = isPSmodule ? 3 : 4; + + //TODO - should use finephi information to reduce combinatorics + + unsigned int index = (projrinv << nbits) + vmstub.bend().value(); + + //Check if stub z position consistent + int idrz = stubfinerz - projfinerzadj; + bool pass; + + if (barrel) { + if (isPSseed) { + pass = idrz >= -2 && idrz <= 2; + } else { + pass = idrz >= -5 && idrz <= 5; + } + } else { + if (isPSmodule) { + pass = idrz >= -1 && idrz <= 1; + } else { + pass = idrz >= -5 && idrz <= 5; + } + } + + //Check if stub bend and proj rinv consistent + if (pass) { + if (barrel ? table_[index] : (isPSmodule ? tablePS_[index] : table2S_[index])) { + Tracklet* proj = vmprojs_->getTracklet(projindex); + std::pair tmp(proj, vmprojs_->getAllProjIndex(projindex)); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << proj->getISeed() << endl; + fout.close(); + } + candmatches_->addMatch(tmp, vmstub.stub()); + countpass++; + } + } + } + } + + if (settings_.writeMonitorData("ME")) { + globals_->ofstream("matchengine.txt") << getName() << " " << countall << " " << countpass << endl; + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/MatchEngineUnit.cc b/L1Trigger/TrackFindingTracklet/src/MatchEngineUnit.cc new file mode 100644 index 0000000000000..c4b9a1275e6f0 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/MatchEngineUnit.cc @@ -0,0 +1,83 @@ +#include "L1Trigger/TrackFindingTracklet/interface/MatchEngineUnit.h" + +using namespace std; +using namespace trklet; + +MatchEngineUnit::MatchEngineUnit(bool barrel, vector table, vector tablePS, vector table2S) + : candmatches_(5) { + idle_ = true; + barrel_ = barrel; + table_ = table; + tablePS_ = tablePS; + table2S_ = table2S; + slot_ = 1; //This makes it idle until initialized +} + +void MatchEngineUnit::init(VMStubsMEMemory* vmstubsmemory, + unsigned int slot, + int projrinv, + int projfinerz, + int projfinephi, + bool isPSseed, + Tracklet* proj) { + vmstubsmemory_ = vmstubsmemory; + idle_ = false; + slot_ = slot; + istub_ = 0; + projrinv_ = projrinv; + projfinerz_ = projfinerz; + projfinephi_ = projfinephi; + isPSseed_ = isPSseed; + proj_ = proj; +} + +void MatchEngineUnit::step() { + if (idle() || candmatches_.almostfull()) + return; + + const VMStubME& vmstub = vmstubsmemory_->getVMStubMEBin(slot_, istub_); + + istub_++; + if (istub_ >= vmstubsmemory_->nStubsBin(slot_)) + idle_ = true; + + bool isPSmodule = vmstub.isPSmodule(); + int stubfinerz = vmstub.finerz().value(); + int stubfinephi = vmstub.finephi().value(); + + int deltaphi = stubfinephi - projfinephi_; + + bool dphicut = (abs(deltaphi) < 3) || (abs(deltaphi) > 5); //TODO - need better implementations + dphicut = true; //Not used until cuts cleaned up + + if (!barrel_) + dphicut = true; + + int nbits = isPSmodule ? 3 : 4; + + unsigned int index = (projrinv_ << nbits) + vmstub.bend().value(); + + //Check if stub z position consistent + int idrz = stubfinerz - projfinerz_; + bool pass; + + if (barrel_) { + if (isPSseed_) { + pass = idrz >= -2 && idrz <= 2; + } else { + pass = idrz >= -5 && idrz <= 5; + } + } else { + if (isPSmodule) { + pass = idrz >= -1 && idrz <= 1; + } else { + pass = idrz >= -5 && idrz <= 5; + } + } + + //Check if stub bend and proj rinv consistent + if ((pass && dphicut) && (barrel_ ? table_[index] : (isPSmodule ? tablePS_[index] : table2S_[index]))) { + std::pair tmp(proj_, vmstub.stub()); + candmatches_.store(tmp); + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/MatchProcessor.cc b/L1Trigger/TrackFindingTracklet/src/MatchProcessor.cc new file mode 100644 index 0000000000000..ff57ae646421b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/MatchProcessor.cc @@ -0,0 +1,667 @@ +#include "L1Trigger/TrackFindingTracklet/interface/MatchProcessor.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionRouterBendTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/HistBase.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +MatchProcessor::MatchProcessor(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector), fullmatches_(12), inputProjBuffer_(3) { + phioffset_ = phimin_; + + phiregion_ = name[8] - 'A'; + + initLayerDisk(3, layer_, disk_); + + //TODO should sort out constants here + icorrshift_ = 7; + + if (layer_ <= 3) { + icorzshift_ = -1 - settings_.PS_zderL_shift(); + } else { + icorzshift_ = -1 - settings_.SS_zderL_shift(); + } + phi0shift_ = 3; + fact_ = 1; + if (layer_ >= 4) { + fact_ = (1 << (settings_.nzbitsstub(0) - settings_.nzbitsstub(5))); + icorrshift_ -= (10 - settings_.nrbitsstub(layer_ - 1)); + icorzshift_ += (settings_.nzbitsstub(0) - settings_.nzbitsstub(5) + settings_.nrbitsstub(layer_ - 1) - + settings_.nrbitsstub(0)); + phi0shift_ = 0; + } + + nrbits_ = 5; + nphiderbits_ = 6; + + //to adjust globaly the phi and rz matching cuts + phifact_ = 1.0; + rzfact_ = 1.0; + + for (unsigned int iSeed = 0; iSeed < 12; iSeed++) { + if (layer_ > 0) { + phimatchcut_[iSeed] = + settings_.rphimatchcut(iSeed, layer_ - 1) / (settings_.kphi1() * settings_.rmean(layer_ - 1)); + zmatchcut_[iSeed] = settings_.zmatchcut(iSeed, layer_ - 1) / settings_.kz(); + } + if (disk_ != 0) { + rphicutPS_[iSeed] = settings_.rphicutPS(iSeed, abs(disk_) - 1) / (settings_.kphi() * settings_.kr()); + rphicut2S_[iSeed] = settings_.rphicut2S(iSeed, abs(disk_) - 1) / (settings_.kphi() * settings_.kr()); + rcut2S_[iSeed] = settings_.rcut2S(iSeed, abs(disk_) - 1) / settings_.krprojshiftdisk(); + rcutPS_[iSeed] = settings_.rcutPS(iSeed, abs(disk_) - 1) / settings_.krprojshiftdisk(); + } + } + + if (iSector_ == 0 && layer_ > 0 && settings_.writeTable()) { + ofstream outphicut; + outphicut.open(getName() + "_phicut.tab"); + outphicut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < 12; seedindex++) { + if (seedindex != 0) + outphicut << "," << endl; + outphicut << phimatchcut_[seedindex]; + } + outphicut << endl << "};" << endl; + outphicut.close(); + + ofstream outzcut; + outzcut.open(getName() + "_zcut.tab"); + outzcut << "{" << endl; + for (unsigned int seedindex = 0; seedindex < N_SEED; seedindex++) { + if (seedindex != 0) + outzcut << "," << endl; + outzcut << zmatchcut_[seedindex]; + } + outzcut << endl << "};" << endl; + outzcut.close(); + } + + if (layer_ > 0) { + unsigned int nbits = 3; + if (layer_ >= 4) + nbits = 4; + + for (unsigned int irinv = 0; irinv < 32; irinv++) { + double rinv = (irinv - 15.5) * (1 << (settings_.nbitsrinv() - 5)) * settings_.krinvpars(); + double stripPitch = + (settings_.rmean(layer_ - 1) < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double projbend = bend(settings_.rmean(layer_ - 1), rinv, stripPitch); + for (unsigned int ibend = 0; ibend < (unsigned int)(1 << nbits); ibend++) { + double stubbend = benddecode(ibend, layer_ <= (int)N_PSLAYER); + bool pass = std::abs(stubbend - projbend) < settings_.bendcutme(layer_ - 1); + table_.push_back(pass); + } + } + + if (settings_.writeTable()) { + ofstream out; + char layer = '0' + layer_; + string fname = "METable_L"; + fname += layer; + fname += ".tab"; + out.open(fname.c_str()); + out << "{" << endl; + for (unsigned int i = 0; i < table_.size(); i++) { + if (i != 0) { + out << "," << endl; + } + out << table_[i]; + } + out << "};" << endl; + out.close(); + } + } + + if (disk_ > 0) { + for (unsigned int iprojbend = 0; iprojbend < 32; iprojbend++) { + double projbend = 0.5 * (iprojbend - 15.0); + for (unsigned int ibend = 0; ibend < 8; ibend++) { + double stubbend = benddecode(ibend, true); + bool pass = std::abs(stubbend - projbend) < settings_.bendcutme(disk_ + 5); + tablePS_.push_back(pass); + } + for (unsigned int ibend = 0; ibend < 16; ibend++) { + double stubbend = benddecode(ibend, false); + bool pass = std::abs(stubbend - projbend) < settings_.bendcutme(disk_ + 5); + table2S_.push_back(pass); + } + } + } + + for (unsigned int i = 0; i < N_DSS_MOD * 2; i++) { + ialphafactinner_[i] = (1 << settings_.alphashift()) * settings_.krprojshiftdisk() * settings_.half2SmoduleWidth() / + (1 << (settings_.nbitsalpha() - 1)) / (settings_.rDSSinner(i) * settings_.rDSSinner(i)) / + settings_.kphi(); + ialphafactouter_[i] = (1 << settings_.alphashift()) * settings_.krprojshiftdisk() * settings_.half2SmoduleWidth() / + (1 << (settings_.nbitsalpha() - 1)) / (settings_.rDSSouter(i) * settings_.rDSSouter(i)) / + settings_.kphi(); + } + + barrel_ = layer_ > 0; + + nvm_ = barrel_ ? settings_.nvmme(layer_ - 1) * settings_.nallstubs(layer_ - 1) + : settings_.nvmme(disk_ + 5) * settings_.nallstubs(disk_ + 5); + nvmbins_ = barrel_ ? settings_.nvmme(layer_ - 1) : settings_.nvmme(disk_ + 5); + + if (nvm_ == 32) + nvmbits_ = 5; + if (nvm_ == 16) + nvmbits_ = 4; + assert(nvmbits_ != -1); + + nMatchEngines_ = 4; + for (unsigned int iME = 0; iME < nMatchEngines_; iME++) { + MatchEngineUnit tmpME(barrel_, table_, tablePS_, table2S_); + matchengines_.push_back(tmpME); + } +} + +void MatchProcessor::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output.find("matchout") != std::string::npos) { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + unsigned int iSeed = getISeed(tmp->getName()); + assert(iSeed < fullmatches_.size()); + assert(fullmatches_[iSeed] == nullptr); + fullmatches_[iSeed] = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output: " << output; +} + +void MatchProcessor::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "allstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + allstubs_ = tmp; + return; + } + if (input == "vmstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + vmstubs_.push_back(tmp); //to allow more than one stub in? vmstubs_=tmp; + return; + } + if (input == "projin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + inputprojs_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input: " << input; +} + +void MatchProcessor::execute() { + if (globals_->projectionRouterBendTable() == nullptr) { // move to constructor?! + auto* bendTablePtr = new ProjectionRouterBendTable(); + bendTablePtr->init(settings_, globals_, nrbits_, nphiderbits_); + globals_->projectionRouterBendTable() = bendTablePtr; + } + + /* + The code is organized in three 'steps' corresponding to the PR, ME, and MC functions. The output from + the PR step is buffered in a 'circular' buffer, and similarly the ME output is put in a circular buffer. + + The implementation is done in steps, emulating what can be done in firmware. One each step we do: + + 1) A projection is read and if there is space it is insert into the inputProjBuffer_ + + 2) Process next match in the ME - if there is an idle ME the next projection is inserted + + 3) Readout match from ME and send to match calculator + + */ + + Tracklet* oldTracklet = nullptr; + + unsigned int countall = 0; + unsigned int countsel = 0; + + unsigned int iprojmem = 0; + unsigned int iproj = 0; + + inputProjBuffer_.reset(); + + for (unsigned int istep = 0; istep < settings_.maxStep("MP"); istep++) { + //Step 1 + //First step here checks if we have more input projections to put into + //the input puffer for projections + if (iprojmem < inputprojs_.size()) { + TrackletProjectionsMemory* projMem = inputprojs_[iprojmem]; + if (projMem->nTracklets() == 0) { + iprojmem++; + } else if (iproj < projMem->nTracklets()) { + if (!inputProjBuffer_.almostfull()) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " have projection in memory : " << projMem->getName(); + } + + Tracklet* proj = projMem->getTracklet(iproj); + FPGAWord fpgaphi = barrel_ ? proj->fpgaphiproj(layer_) : proj->fpgaphiprojdisk(disk_); + + int iphi = (fpgaphi.value() >> (fpgaphi.nbits() - nvmbits_)) & (nvmbins_ - 1); + + int projrinv = -1; + if (barrel_) { + projrinv = 16 + (proj->fpgarinv().value() >> (proj->fpgarinv().nbits() - 5)); + } else { + //The next lines looks up the predicted bend based on: + // 1 - r projections + // 2 - phi derivative + // 3 - the sign - i.e. if track is forward or backward + int rindex = (proj->fpgarprojdisk(disk_).value() >> (proj->fpgarprojdisk(disk_).nbits() - nrbits_)) & + ((1 << nrbits_) - 1); + + int phiderindex = + (proj->fpgaphiprojderdisk(disk_).value() >> (proj->fpgaphiprojderdisk(disk_).nbits() - nphiderbits_)) & + ((1 << nphiderbits_) - 1); + + int signindex = (proj->fpgarprojderdisk(disk_).value() < 0); + + int bendindex = (signindex << (nphiderbits_ + nrbits_)) + (rindex << (nphiderbits_)) + phiderindex; + + projrinv = globals_->projectionRouterBendTable()->bendLoookup(abs(disk_) - 1, bendindex); + + proj->setBendIndex(projrinv, disk_); + } + assert(projrinv >= 0); + + unsigned int slot = barrel_ ? proj->zbin1projvm(layer_) : proj->rbin1projvm(disk_); + bool second = (barrel_ ? proj->zbin2projvm(layer_) : proj->rbin2projvm(disk_)) == 1; + + unsigned int projfinephi = fpgaphi.value() >> (fpgaphi.nbits() - (nvmbits_ + 3)) & 7; + int projfinerz = barrel_ ? proj->finezvm(layer_) : proj->finervm(disk_); + + bool isPSseed = proj->PSseed() == 1; + + VMStubsMEMemory* stubmem = vmstubs_[iphi]; + if (stubmem->nStubsBin(slot) != 0) { + ProjectionTemp tmpProj(proj, slot, projrinv, projfinerz, projfinephi, iphi, isPSseed); + inputProjBuffer_.store(tmpProj); + } + if (second && (stubmem->nStubsBin(slot + 1) != 0)) { + ProjectionTemp tmpProj(proj, slot + 1, projrinv, projfinerz - 8, projfinephi, iphi, isPSseed); + inputProjBuffer_.store(tmpProj); + } + iproj++; + if (iproj == projMem->nTracklets()) { + iproj = 0; + iprojmem++; + } + } + } + } + + //Step 2 + //Check if we have ME that can process projection + + bool addedProjection = false; + for (unsigned int iME = 0; iME < nMatchEngines_; iME++) { + matchengines_[iME].step(); + //if match engine empty and we have queued projections add to match engine + if ((!addedProjection) && matchengines_[iME].idle() && (!inputProjBuffer_.empty())) { + ProjectionTemp tmpProj = inputProjBuffer_.read(); + VMStubsMEMemory* stubmem = vmstubs_[tmpProj.iphi()]; + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " adding projection to match engine"; + } + + matchengines_[iME].init(stubmem, + tmpProj.slot(), + tmpProj.projrinv(), + tmpProj.projfinerz(), + tmpProj.projfinephi(), + tmpProj.isPSseed(), + tmpProj.proj()); + addedProjection = true; + } + } + + //Step 3 + //Check if we have candidate match to process + + unsigned int iMEbest = nMatchEngines_; + int bestTCID = -1; + bool bestInPipeline = false; + for (unsigned int iME = 0; iME < nMatchEngines_; iME++) { + bool empty = matchengines_[iME].empty(); + if (empty && matchengines_[iME].idle()) + continue; + int currentTCID = empty ? matchengines_[iME].currentProj()->TCID() : matchengines_[iME].peek().first->TCID(); + if ((iMEbest == nMatchEngines_) || (currentTCID < bestTCID)) { + iMEbest = iME; + bestTCID = currentTCID; + bestInPipeline = empty; + } + } + + if (iMEbest != nMatchEngines_ && (!bestInPipeline)) { + std::pair candmatch = matchengines_[iMEbest].read(); + + const Stub* fpgastub = candmatch.second; + Tracklet* tracklet = candmatch.first; + + if (oldTracklet != nullptr) { + //allow equal here since we can have more than one cadidate match per tracklet projection + assert(oldTracklet->TCID() <= tracklet->TCID()); + } + oldTracklet = tracklet; + + bool match = matchCalculator(tracklet, fpgastub); + + if (settings_.debugTracklet() && match) { + edm::LogVerbatim("Tracklet") << getName() << " have match"; + } + + countall++; + if (match) + countsel++; + ; + } + } + + if (settings_.writeMonitorData("MC")) { + globals_->ofstream("matchcalculator.txt") << getName() << " " << countall << " " << countsel << endl; + } +} + +bool MatchProcessor::matchCalculator(Tracklet* tracklet, const Stub* fpgastub) { + const L1TStub* stub = fpgastub->l1tstub(); + + if (layer_ != 0) { + int ir = fpgastub->r().value(); + int iphi = tracklet->fpgaphiproj(layer_).value(); + int icorr = (ir * tracklet->fpgaphiprojder(layer_).value()) >> icorrshift_; + iphi += icorr; + + int iz = tracklet->fpgazproj(layer_).value(); + int izcor = (ir * tracklet->fpgazprojder(layer_).value() + (1 << (icorzshift_ - 1))) >> icorzshift_; + iz += izcor; + + int ideltaz = fpgastub->z().value() - iz; + int ideltaphi = (fpgastub->phi().value() << phi0shift_) - (iphi << (settings_.phi0bitshift() - 1 + phi0shift_)); + + //Floating point calculations + + double phi = stub->phi(); + double r = stub->r(); + double z = stub->z(); + + if (settings_.useapprox()) { + double dphi = reco::reduceRange(phi - fpgastub->phiapprox(phimin_, phimax_)); + assert(std::abs(dphi) < 0.001); + phi = fpgastub->phiapprox(phimin_, phimax_); + z = fpgastub->zapprox(); + r = fpgastub->rapprox(); + } + + if (phi < 0) + phi += 2 * M_PI; + phi -= phioffset_; + + double dr = r - tracklet->rproj(layer_); + assert(std::abs(dr) < settings_.drmax()); + + double dphi = reco::reduceRange(phi - (tracklet->phiproj(layer_) + dr * tracklet->phiprojder(layer_))); + + double dz = z - (tracklet->zproj(layer_) + dr * tracklet->zprojder(layer_)); + + double dphiapprox = + reco::reduceRange(phi - (tracklet->phiprojapprox(layer_) + dr * tracklet->phiprojderapprox(layer_))); + + double dzapprox = z - (tracklet->zprojapprox(layer_) + dr * tracklet->zprojderapprox(layer_)); + + int seedindex = tracklet->getISeed(); + + assert(phimatchcut_[seedindex] > 0); + assert(zmatchcut_[seedindex] > 0); + + if (settings_.bookHistos()) { + bool truthmatch = tracklet->stubtruthmatch(stub); + + HistBase* hists = globals_->histograms(); + hists->FillLayerResidual(layer_, + seedindex, + dphiapprox * settings_.rmean(layer_ - 1), + ideltaphi * settings_.kphi1() * settings_.rmean(layer_ - 1), + ideltaz * fact_ * settings_.kz(), + dz, + truthmatch); + } + + if (settings_.writeMonitorData("Residuals")) { + double pt = 0.01 * settings_.c() * settings_.bfield() / std::abs(tracklet->rinv()); + + globals_->ofstream("layerresiduals.txt") + << layer_ << " " << seedindex << " " << pt << " " + << ideltaphi * settings_.kphi1() * settings_.rmean(layer_ - 1) << " " + << dphiapprox * settings_.rmean(layer_ - 1) << " " + << phimatchcut_[seedindex] * settings_.kphi1() * settings_.rmean(layer_ - 1) << " " + << ideltaz * fact_ * settings_.kz() << " " << dz << " " << zmatchcut_[seedindex] * settings_.kz() << endl; + } + + bool imatch = (std::abs(ideltaphi) <= phifact_ * phimatchcut_[seedindex]) && + (std::abs(ideltaz * fact_) <= rzfact_ * zmatchcut_[seedindex]); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " imatch = " << imatch << " ideltaphi cut " << ideltaphi << " " + << phimatchcut_[seedindex] << " ideltaz*fact cut " << ideltaz * fact_ << " " + << zmatchcut_[seedindex]; + } + + if (std::abs(dphi) > 0.2 || std::abs(dphiapprox) > 0.2) { + edm::LogPrint("Tracklet") << "WARNING dphi and/or dphiapprox too large : " << dphi << " " << dphiapprox; + } + + assert(std::abs(dphi) < 0.2); + assert(std::abs(dphiapprox) < 0.2); + + if (imatch) { + tracklet->addMatch(layer_, + ideltaphi, + ideltaz, + dphi, + dz, + dphiapprox, + dzapprox, + (phiregion_ << 7) + fpgastub->stubindex().value(), + stub->r(), + fpgastub); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Accepted full match in layer " << getName() << " " << tracklet << " " + << iSector_; + } + + int iSeed = tracklet->getISeed(); + assert(fullmatches_[iSeed] != nullptr); + fullmatches_[iSeed]->addMatch(tracklet, fpgastub); + + return true; + } else { + return false; + } + } else { //disk matches + + //check that stubs and projections in same half of detector + assert(stub->z() * tracklet->t() > 0.0); + + int sign = (tracklet->t() > 0.0) ? 1 : -1; + int disk = sign * disk_; + assert(disk != 0); + + //Perform integer calculations here + + int iz = fpgastub->z().value(); + int iphi = tracklet->fpgaphiprojdisk(disk).value(); + + int shifttmp = 6; //TODO - express in terms of constants + assert(shifttmp >= 0); + int iphicorr = (iz * tracklet->fpgaphiprojderdisk(disk).value()) >> shifttmp; + + iphi += iphicorr; + + int ir = tracklet->fpgarprojdisk(disk).value(); + + int shifttmp2 = 7; //TODO - express in terms of constants + assert(shifttmp2 >= 0); + int ircorr = (iz * tracklet->fpgarprojderdisk(disk).value()) >> shifttmp2; + + ir += ircorr; + + int ideltaphi = fpgastub->phi().value() * settings_.kphi() / settings_.kphi() - iphi; + + int irstub = fpgastub->r().value(); + int ialphafact = 0; + if (!stub->isPSmodule()) { + assert(irstub < (int)N_DSS_MOD * 2); + if (disk_ <= 2) { + ialphafact = ialphafactinner_[irstub]; + irstub = settings_.rDSSinner(irstub) / settings_.kr(); + } else { + ialphafact = ialphafactouter_[irstub]; + irstub = settings_.rDSSouter(irstub) / settings_.kr(); + } + } + + int ideltar = (irstub * settings_.kr()) / settings_.krprojshiftdisk() - ir; + + if (!stub->isPSmodule()) { + int ialphanew = fpgastub->alphanew().value(); + int iphialphacor = ((ideltar * ialphanew * ialphafact) >> settings_.alphashift()); + ideltaphi += iphialphacor; + } + + //Perform floating point calculations here + + double phi = stub->phi(); + double z = stub->z(); + double r = stub->r(); + + if (settings_.useapprox()) { + double dphi = reco::reduceRange(phi - fpgastub->phiapprox(phimin_, phimax_)); + assert(std::abs(dphi) < 0.001); + phi = fpgastub->phiapprox(phimin_, phimax_); + z = fpgastub->zapprox(); + r = fpgastub->rapprox(); + } + + if (phi < 0) + phi += 2 * M_PI; + phi -= phioffset_; + + double dz = z - sign * settings_.zmean(disk_ - 1); + + if (std::abs(dz) > settings_.dzmax()) { + edm::LogProblem("Tracklet") << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " + << tracklet->getISeed(); + edm::LogProblem("Tracklet") << "stub " << stub->z() << " disk " << disk << " " << dz; + assert(std::abs(dz) < settings_.dzmax()); + } + + double phiproj = tracklet->phiprojdisk(disk) + dz * tracklet->phiprojderdisk(disk); + double rproj = tracklet->rprojdisk(disk) + dz * tracklet->rprojderdisk(disk); + double deltar = r - rproj; + + double dr = stub->r() - rproj; + double drapprox = stub->r() - (tracklet->rprojapproxdisk(disk) + dz * tracklet->rprojderapproxdisk(disk)); + + double dphi = reco::reduceRange(phi - phiproj); + double dphiapprox = + reco::reduceRange(phi - (tracklet->phiprojapproxdisk(disk) + dz * tracklet->phiprojderapproxdisk(disk))); + + double drphi = dphi * stub->r(); + double drphiapprox = dphiapprox * stub->r(); + + if (!stub->isPSmodule()) { + double alphanorm = stub->alphanorm(); + dphi += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r2(); + ; + dphiapprox += drapprox * alphanorm * settings_.half2SmoduleWidth() / stub->r2(); + + drphi += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r(); + drphiapprox += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r(); + } + + int seedindex = tracklet->getISeed(); + + int idrphicut = rphicutPS_[seedindex]; + int idrcut = rcutPS_[seedindex]; + if (!stub->isPSmodule()) { + idrphicut = rphicut2S_[seedindex]; + idrcut = rcut2S_[seedindex]; + } + + double drphicut = idrphicut * settings_.kphi() * settings_.kr(); + double drcut = idrcut * settings_.krprojshiftdisk(); + + if (settings_.writeMonitorData("Residuals")) { + double pt = 0.01 * settings_.c() * settings_.bfield() / std::abs(tracklet->rinv()); + + globals_->ofstream("diskresiduals.txt") + << disk_ << " " << stub->isPSmodule() << " " << tracklet->layer() << " " << abs(tracklet->disk()) << " " << pt + << " " << ideltaphi * settings_.kphi() * stub->r() << " " << drphiapprox << " " << drphicut << " " + << ideltar * settings_.krprojshiftdisk() << " " << deltar << " " << drcut << " " << endl; + } + + bool match = (std::abs(drphi) < drphicut) && (std::abs(deltar) < drcut); + bool imatch = (std::abs(ideltaphi * irstub) < idrphicut) && (std::abs(ideltar) < idrcut); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "imatch match disk: " << imatch << " " << match << " " << std::abs(ideltaphi) + << " " << drphicut / (settings_.kphi() * stub->r()) << " " << std::abs(ideltar) + << " " << drcut / settings_.krprojshiftdisk() << " r = " << stub->r(); + } + + if (imatch) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "MatchCalculator found match in disk " << getName(); + } + + if (std::abs(dphi) >= 0.25) { + edm::LogPrint("Tracklet") << "dphi " << dphi << " ISeed " << tracklet->getISeed(); + } + assert(std::abs(dphi) < 0.25); + assert(std::abs(dphiapprox) < 0.25); + + tracklet->addMatchDisk(disk, + ideltaphi, + ideltar, + drphi / stub->r(), + dr, + drphiapprox / stub->r(), + drapprox, + stub->alpha(settings_.stripPitch(stub->isPSmodule())), + (phiregion_ << 7) + fpgastub->stubindex().value(), + stub->z(), + fpgastub); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Accepted full match in disk " << getName() << " " << tracklet << " " + << iSector_; + } + + int iSeed = tracklet->getISeed(); + assert(fullmatches_[iSeed] != nullptr); + fullmatches_[iSeed]->addMatch(tracklet, fpgastub); + + return true; + } else { + return false; + } + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/MemoryBase.cc b/L1Trigger/TrackFindingTracklet/src/MemoryBase.cc new file mode 100644 index 0000000000000..6a6f167d66eea --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/MemoryBase.cc @@ -0,0 +1,113 @@ +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include + +using namespace trklet; +using namespace std; + +MemoryBase::MemoryBase(string name, Settings const& settings, unsigned int iSector) : name_(name), settings_(settings) { + iSector_ = iSector; + bx_ = 0; + event_ = 0; +} + +void MemoryBase::initLayerDisk(unsigned int pos, int& layer, int& disk) { + string subname = name_.substr(pos, 2); + layer = 0; + disk = 0; + + if (subname.substr(0, 1) == "L") + layer = stoi(subname.substr(1, 1)); + else if (subname.substr(0, 1) == "D") + disk = stoi(subname.substr(1, 1)); + else + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " name = " << name_ << " subname = " << subname + << " " << layer << " " << disk; +} + +unsigned int MemoryBase::initLayerDisk(unsigned int pos) { + int layer, disk; + initLayerDisk(pos, layer, disk); + + if (disk > 0) + return N_DISK + disk; + return layer - 1; +} + +void MemoryBase::initSpecialSeeding(unsigned int pos, bool& overlap, bool& extra, bool& extended) { + overlap = false; + extra = false; + extended = false; + + char subname = name_[pos]; + + static const std::set overlapset = { + 'X', 'Y', 'W', 'Q', 'R', 'S', 'T', 'Z', 'x', 'y', 'w', 'q', 'r', 's', 't', 'z'}; + overlap = overlapset.find(subname) != overlapset.end(); + + static const std::set extraset = {'I', 'J', 'K', 'L'}; + extra = extraset.find(subname) != extraset.end(); + + static const std::set extendedset = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'x', 'y', 'z', 'w', 'q', 'r', 's', 't'}; + extended = extendedset.find(subname) != extendedset.end(); +} + +void MemoryBase::findAndReplaceAll(std::string& data, std::string toSearch, std::string replaceStr) { + // Get the first occurrence + size_t pos = data.find(toSearch); + + // Repeat till end is reached + while (pos != std::string::npos) { + // Replace this occurrence of Sub String + data.replace(pos, toSearch.size(), replaceStr); + // Get the next occurrence from the current position + pos = data.find(toSearch, pos + replaceStr.size()); + } +} + +void MemoryBase::openFile(bool first, std::string filebase) { + std::string fname = filebase; + fname += getName(); + + findAndReplaceAll(fname, "PHIa", "PHIaa"); + findAndReplaceAll(fname, "PHIb", "PHIbb"); + findAndReplaceAll(fname, "PHIc", "PHIcc"); + findAndReplaceAll(fname, "PHId", "PHIdd"); + + findAndReplaceAll(fname, "PHIx", "PHIxx"); + findAndReplaceAll(fname, "PHIy", "PHIyy"); + findAndReplaceAll(fname, "PHIz", "PHIzz"); + findAndReplaceAll(fname, "PHIw", "PHIww"); + + fname += "_"; + if (iSector_ + 1 < 10) + fname += "0"; + fname += std::to_string(iSector_ + 1); + fname += ".dat"; + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else { + out_.open(fname.c_str(), std::ofstream::app); + } + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} + +size_t MemoryBase::find_nth(const string& haystack, size_t pos, const string& needle, size_t nth) { + size_t found_pos = haystack.find(needle, pos); + if (0 == nth || string::npos == found_pos) + return found_pos; + return find_nth(haystack, found_pos + 1, needle, nth - 1); +} diff --git a/L1Trigger/TrackFindingTracklet/src/ProcessBase.cc b/L1Trigger/TrackFindingTracklet/src/ProcessBase.cc new file mode 100644 index 0000000000000..43d90fa30d5a6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/ProcessBase.cc @@ -0,0 +1,148 @@ +#include "L1Trigger/TrackFindingTracklet/interface/ProcessBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include + +using namespace trklet; +using namespace std; + +ProcessBase::ProcessBase(string name, Settings const& settings, Globals* global, unsigned int iSector) + : name_(name), settings_(settings), globals_(global) { + iSector_ = iSector; + double dphi = 2 * M_PI / N_SECTOR; + double dphiHG = 0.5 * settings_.dphisectorHG() - M_PI / N_SECTOR; + phimin_ = iSector_ * dphi - dphiHG; + phimax_ = phimin_ + dphi + 2 * dphiHG; + phimin_ -= M_PI / N_SECTOR; + phimax_ -= M_PI / N_SECTOR; + if (phimin_ > M_PI) { + phimin_ -= 2 * M_PI; + phimax_ -= 2 * M_PI; + } +} + +unsigned int ProcessBase::nbits(unsigned int power) { + if (power == 2) + return 1; + if (power == 4) + return 2; + if (power == 8) + return 3; + if (power == 16) + return 4; + if (power == 32) + return 5; + + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << "nbits: power = " << power; + return 0; +} + +void ProcessBase::initLayerDisk(unsigned int pos, int& layer, int& disk) { + string subname = name_.substr(pos, 2); + layer = 0; + disk = 0; + if (subname.substr(0, 1) == "L") + layer = stoi(subname.substr(1, 1)); + else if (subname.substr(0, 1) == "D") + disk = stoi(subname.substr(1, 1)); + else + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " " << name_ << " subname = " << subname << " " + << layer << " " << disk; +} + +void ProcessBase::initLayerDisk(unsigned int pos, int& layer, int& disk, int& layerdisk) { + initLayerDisk(pos, layer, disk); + + layerdisk = layer - 1; + if (disk > 0) + layerdisk = N_DISK + disk; +} + +unsigned int ProcessBase::initLayerDisk(unsigned int pos) { + int layer, disk; + initLayerDisk(pos, layer, disk); + + if (disk > 0) + return N_DISK + disk; + return layer - 1; +} + +void ProcessBase::initLayerDisksandISeed(unsigned int& layerdisk1, unsigned int& layerdisk2, unsigned int& iSeed) { + layerdisk1 = 99; + layerdisk2 = 99; + + if (name_.substr(0, 3) == "TE_") { + if (name_[3] == 'L') { + layerdisk1 = name_[4] - '1'; + } else if (name_[3] == 'D') { + layerdisk1 = 6 + name_[4] - '1'; + } + if (name_[11] == 'L') { + layerdisk2 = name_[12] - '1'; + } else if (name_[11] == 'D') { + layerdisk2 = 6 + name_[12] - '1'; + } else if (name_[12] == 'L') { + layerdisk2 = name_[13] - '1'; + } else if (name_[12] == 'D') { + layerdisk2 = 6 + name_[13] - '1'; + } + } + + if ((name_.substr(0, 3) == "TC_") || (name_.substr(0, 3) == "TP_")) { + if (name_[3] == 'L') { + layerdisk1 = name_[4] - '1'; + } else if (name_[3] == 'D') { + layerdisk1 = 6 + name_[4] - '1'; + } + if (name_[5] == 'L') { + layerdisk2 = name_[6] - '1'; + } else if (name_[5] == 'D') { + layerdisk2 = 6 + name_[6] - '1'; + } + } + + if (layerdisk1 == 0 && layerdisk2 == 1) + iSeed = 0; + else if (layerdisk1 == 1 && layerdisk2 == 2) + iSeed = 1; + else if (layerdisk1 == 2 && layerdisk2 == 3) + iSeed = 2; + else if (layerdisk1 == 4 && layerdisk2 == 5) + iSeed = 3; + else if (layerdisk1 == 6 && layerdisk2 == 7) + iSeed = 4; + else if (layerdisk1 == 8 && layerdisk2 == 9) + iSeed = 5; + else if (layerdisk1 == 0 && layerdisk2 == 6) + iSeed = 6; + else if (layerdisk1 == 1 && layerdisk2 == 6) + iSeed = 7; + else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " layerdisk1 " << layerdisk1 << " layerdisk2 " + << layerdisk2; + } +} + +unsigned int ProcessBase::getISeed(std::string name) { + std::size_t pos = name.find("_"); + std::string name1 = name.substr(pos + 1); + pos = name1.find("_"); + std::string name2 = name1.substr(0, pos); + + unordered_map seedmap = { + {"L1L2", 0}, {"L2L3", 1}, {"L3L4", 2}, {"L5L6", 3}, {"D1D2", 4}, {"D3D4", 5}, {"L1D1", 6}, + {"L2D1", 7}, {"L1L2XX", 0}, {"L2L3XX", 1}, {"L3L4XX", 2}, {"L5L6XX", 3}, {"D1D2XX", 4}, {"D3D4XX", 5}, + {"L1D1XX", 6}, {"L2D1XX", 7}, {"L3L4L2", 8}, {"L5L6L4", 9}, {"L2L3D1", 10}, {"D1D2L2", 11}}; + auto found = seedmap.find(name2); + if (found != seedmap.end()) + return found->second; + + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " " << getName() << " name name1 name2 " << name + << " - " << name1 << " - " << name2; + return 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/ProjectionRouter.cc b/L1Trigger/TrackFindingTracklet/src/ProjectionRouter.cc new file mode 100644 index 0000000000000..06856031b1e1d --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/ProjectionRouter.cc @@ -0,0 +1,148 @@ +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionRouter.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +ProjectionRouter::ProjectionRouter(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + layerdisk_ = initLayerDisk(3); + + vmprojs_.resize(settings_.nvmme(layerdisk_), nullptr); + + nrbits_ = 5; + nphiderbits_ = 6; +} + +void ProjectionRouter::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "allprojout") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + allproj_ = tmp; + return; + } + + unsigned int nproj = settings_.nallstubs(layerdisk_); + unsigned int nprojvm = settings_.nvmme(layerdisk_); + + for (unsigned int iproj = 0; iproj < nproj; iproj++) { + for (unsigned int iprojvm = 0; iprojvm < nprojvm; iprojvm++) { + std::string name = "vmprojoutPHI"; + name += char(iproj + 'A'); + name += std::to_string(iproj * nprojvm + iprojvm + 1); + if (output == name) { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + vmprojs_[iprojvm] = tmp; + return; + } + } + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output: " << output; +} + +void ProjectionRouter::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input.substr(0, 4) == "proj" && input.substr(input.size() - 2, 2) == "in") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + inputproj_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input: " << input; +} + +void ProjectionRouter::execute() { + if (globals_->projectionRouterBendTable() == nullptr) { + auto* bendTablePtr = new ProjectionRouterBendTable(); + bendTablePtr->init(settings_, globals_, nrbits_, nphiderbits_); + globals_->projectionRouterBendTable() = bendTablePtr; + } + + unsigned int allprojcount = 0; + + //These are just here to test that the order is correct. Does not affect the actual execution + + int lastTCID = -1; + + for (auto& iproj : inputproj_) { + for (unsigned int i = 0; i < iproj->nTracklets(); i++) { + if (allprojcount > settings_.maxStep("PR")) + continue; + + Tracklet* tracklet = iproj->getTracklet(i); + + FPGAWord fpgaphi; + + if (layerdisk_ < N_LAYER) { + fpgaphi = tracklet->fpgaphiproj(layerdisk_ + 1); + } else { + int disk = layerdisk_ - (N_LAYER - 1); + fpgaphi = tracklet->fpgaphiprojdisk(disk); + + //The next lines looks up the predicted bend based on: + // 1 - r projections + // 2 - phi derivative + // 3 - the sign - i.e. if track is forward or backward + int rindex = (tracklet->fpgarprojdisk(disk).value() >> (tracklet->fpgarprojdisk(disk).nbits() - nrbits_)) & + ((1 << nrbits_) - 1); + + int phiderindex = (tracklet->fpgaphiprojderdisk(disk).value() >> + (tracklet->fpgaphiprojderdisk(disk).nbits() - nphiderbits_)) & + ((1 << nphiderbits_) - 1); + + int signindex = (tracklet->fpgarprojderdisk(disk).value() < 0); + + int bendindex = (signindex << (nphiderbits_ + nrbits_)) + (rindex << (nphiderbits_)) + phiderindex; + + int ibendproj = globals_->projectionRouterBendTable()->bendLoookup(disk - 1, bendindex); + + tracklet->setBendIndex(ibendproj, disk); + } + + unsigned int iphivm = + fpgaphi.bits(fpgaphi.nbits() - settings_.nbitsallstubs(layerdisk_) - settings_.nbitsvmme(layerdisk_), + settings_.nbitsvmme(layerdisk_)); + + //This block of code just checks that the configuration is consistent + if (lastTCID >= tracklet->TCID()) { + edm::LogPrint("Tracklet") << "Wrong TCID ordering for projections in " << getName(); + } else { + lastTCID = tracklet->TCID(); + } + + allproj_->addTracklet(tracklet); + + vmprojs_[iphivm]->addTracklet(tracklet, allprojcount); + + allprojcount++; + } + } + + if (settings_.writeMonitorData("AP")) { + globals_->ofstream("allprojections.txt") << getName() << " " << allproj_->nTracklets() << endl; + } + + if (settings_.writeMonitorData("VMP")) { + ofstream& out = globals_->ofstream("chisq.txt"); + for (unsigned int i = 0; i < 8; i++) { + if (vmprojs_[i] != nullptr) { + out << vmprojs_[i]->getName() << " " << vmprojs_[i]->nTracklets() << endl; + } + } + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/ProjectionRouterBendTable.cc b/L1Trigger/TrackFindingTracklet/src/ProjectionRouterBendTable.cc new file mode 100644 index 0000000000000..6ddbcc3628cf2 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/ProjectionRouterBendTable.cc @@ -0,0 +1,54 @@ +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionRouterBendTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" + +using namespace trklet; + +void ProjectionRouterBendTable::init(Settings const& settings, + Globals* globals, + unsigned int nrbits, + unsigned int nphiderbits) { + for (unsigned int idisk = 0; idisk < N_DISK; idisk++) { + unsigned int nsignbins = 2; + unsigned int nrbins = 1 << (nrbits); + unsigned int nphiderbins = 1 << (nphiderbits); + + for (unsigned int isignbin = 0; isignbin < nsignbins; isignbin++) { + for (unsigned int irbin = 0; irbin < nrbins; irbin++) { + int ir = irbin; + if (ir > (1 << (nrbits - 1))) + ir -= (1 << nrbits); + ir = ir << (settings.nrbitsstub(N_LAYER) - nrbits); + for (unsigned int iphiderbin = 0; iphiderbin < nphiderbins; iphiderbin++) { + int iphider = iphiderbin; + if (iphider > (1 << (nphiderbits - 1))) + iphider -= (1 << nphiderbits); + iphider = iphider << (settings.nbitsphiprojderL123() - nphiderbits); + + double rproj = ir * settings.krprojshiftdisk(); + double phider = iphider * globals->ITC_L1L2()->der_phiD_final.K(); + double t = settings.zmean(idisk) / rproj; + + if (isignbin) + t = -t; + + double rinv = -phider * (2.0 * t); + + double stripPitch = (rproj < settings.rcrit()) ? settings.stripPitch(true) : settings.stripPitch(false); + double bendproj = 0.5 * bend(rproj, rinv, stripPitch); + + int ibendproj = 2.0 * bendproj + 15.5; + if (ibendproj < 0) + ibendproj = 0; + if (ibendproj > 31) + ibendproj = 31; + + bendtable_[idisk].push_back(ibendproj); + } + } + } + } +} + +int ProjectionRouterBendTable::bendLoookup(int diskindex, int bendindex) { return bendtable_[diskindex][bendindex]; } diff --git a/L1Trigger/TrackFindingTracklet/src/ProjectionTemp.cc b/L1Trigger/TrackFindingTracklet/src/ProjectionTemp.cc new file mode 100644 index 0000000000000..5287ffacceb7b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/ProjectionTemp.cc @@ -0,0 +1,30 @@ +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionTemp.h" + +using namespace std; +using namespace trklet; + +ProjectionTemp::ProjectionTemp(Tracklet* proj, + unsigned int slot, + unsigned int projrinv, + int projfinerz, + unsigned int projfinephi, + unsigned int iphi, + bool isPSseed) { + proj_ = proj; + slot_ = slot; + projrinv_ = projrinv; + projfinerz_ = projfinerz; + projfinephi_ = projfinephi; + iphi_ = iphi; + isPSseed_ = isPSseed; +} + +ProjectionTemp::ProjectionTemp() { + proj_ = nullptr; + slot_ = 0; + projrinv_ = 0; + projfinerz_ = 0; + projfinephi_ = 0; + iphi_ = 0; + isPSseed_ = false; +} diff --git a/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc new file mode 100644 index 0000000000000..7f66f5d53329e --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc @@ -0,0 +1,513 @@ +#include "L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Track.h" + +#ifdef USEHYBRID +#include "DataFormats/L1TrackTrigger/interface/TTStub.h" +#include "L1Trigger/TrackFindingTMTT/interface/L1track3D.h" +#include "L1Trigger/TrackFindingTMTT/interface/KFParamsComb.h" +#include "L1Trigger/TrackFindingTracklet/interface/HybridFit.h" +#endif + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include +#include + +using namespace std; +using namespace trklet; + +PurgeDuplicate::PurgeDuplicate(std::string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector) {} + +void PurgeDuplicate::addOutput(MemoryBase* memory, std::string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + unordered_set outputs = {"trackout", + "trackout1", + "trackout2", + "trackout3", + "trackout4", + "trackout5", + "trackout6", + "trackout7", + "trackout8", + "trackout9", + "trackout10", + "trackout11"}; + if (outputs.find(output) != outputs.end()) { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + outputtracklets_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output: " << output; +} + +void PurgeDuplicate::addInput(MemoryBase* memory, std::string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + unordered_set inputs = {"trackin", + "trackin1", + "trackin2", + "trackin3", + "trackin4", + "trackin5", + "trackin6", + "trackin7", + "trackin8", + "trackin9", + "trackin10", + "trackin11", + "trackin12"}; + if (inputs.find(input) != inputs.end()) { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + inputtrackfits_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input: " << input; +} + +void PurgeDuplicate::execute(std::vector& outputtracks_) { + inputtracklets_.clear(); + inputtracks_.clear(); + + inputstubidslists_.clear(); + inputstublists_.clear(); + mergedstubidslists_.clear(); + + if (settings_.removalType() != "merge") { + for (auto& inputtrackfit : inputtrackfits_) { + if (inputtrackfit->nTracks() == 0) + continue; + for (unsigned int j = 0; j < inputtrackfit->nTracks(); j++) { + Track* aTrack = inputtrackfit->getTrack(j)->getTrack(); + aTrack->setSector(iSector_); + inputtracks_.push_back(aTrack); + } + } + if (inputtracks_.empty()) + return; + } + + unsigned int numTrk = inputtracks_.size(); + + //////////////////// + // Hybrid Removal // + //////////////////// +#ifdef USEHYBRID + + if (settings_.removalType() == "merge") { + std::vector> trackInfo; // Track seed & duplicate flag + // Vector to store the relative rank of the track candidate for merging, based on seed type + std::vector seedRank; + + // Get vectors from TrackFit and save them + // inputtracklets: Tracklet objects from the FitTrack (not actually fit yet) + // inputstublists: L1Stubs for that track + // inputstubidslists: Stub stubIDs for that 3rack + // mergedstubidslists: the same as inputstubidslists, but will be used during duplicate removal + for (unsigned int i = 0; i < inputtrackfits_.size(); i++) { + if (inputtrackfits_[i]->nStublists() == 0) + continue; + if (inputtrackfits_[i]->nStublists() != inputtrackfits_[i]->nTracks()) + throw "Number of stublists and tracks don't match up!"; + for (unsigned int j = 0; j < inputtrackfits_[i]->nStublists(); j++) { + Tracklet* aTrack = inputtrackfits_[i]->getTrack(j); + inputtracklets_.push_back(inputtrackfits_[i]->getTrack(j)); + + std::vector stublist = inputtrackfits_[i]->getStublist(j); + + inputstublists_.push_back(stublist); + + std::vector> stubidslist = inputtrackfits_[i]->getStubidslist(j); + inputstubidslists_.push_back(stubidslist); + mergedstubidslists_.push_back(stubidslist); + + // Encoding: L1L2=0, L2L3=1, L3L4=2, L5L6=3, D1D2=4, D3D4=5, L1D1=6, L2D1=7 + // Best Guess: L1L2 > L1D1 > L2L3 > L2D1 > D1D2 > L3L4 > L5L6 > D3D4 + // Best Rank: L1L2 > L3L4 > D3D4 > D1D2 > L2L3 > L2D1 > L5L6 > L1D1 + // Rank-Informed Guess: L1L2 > L3L4 > L1D1 > L2L3 > L2D1 > D1D2 > L5L6 > D3D4 + unsigned int curSeed = aTrack->seedIndex(); + if (curSeed == 0) { + seedRank.push_back(1); + } else if (curSeed == 2) { + seedRank.push_back(2); + } else if (curSeed == 5) { + seedRank.push_back(3); + } else if (curSeed == 4) { + seedRank.push_back(4); + } else if (curSeed == 1) { + seedRank.push_back(5); + } else if (curSeed == 7) { + seedRank.push_back(6); + } else if (curSeed == 3) { + seedRank.push_back(7); + } else if (curSeed == 6) { + seedRank.push_back(8); + } else if (settings_.extended()) { + seedRank.push_back(9); + } else { + throw cms::Exception("LogError") << __FILE__ << " " << __LINE__ << " Seed " << curSeed + << " not found in list, and settings->extended() not set."; + } + + if (stublist.size() != stubidslist.size()) + throw "Number of stubs and stubids don't match up!"; + + trackInfo.emplace_back(i, false); + } + } + + if (inputtracklets_.empty()) + return; + unsigned int numStublists = inputstublists_.size(); + + // Initialize all-false 2D array of tracks being duplicates to other tracks + bool dupMap[numStublists][numStublists]; // Ends up symmetric + for (unsigned int itrk = 0; itrk < numStublists; itrk++) { + for (unsigned int jtrk = 0; jtrk < numStublists; jtrk++) { + dupMap[itrk][jtrk] = false; + } + } + + // Find duplicates; Fill dupMap by looping over all pairs of "tracks" + // numStublists-1 since last track has no other to compare to + for (unsigned int itrk = 0; itrk < numStublists - 1; itrk++) { + for (unsigned int jtrk = itrk + 1; jtrk < numStublists; jtrk++) { + // Get primary track stubids + const std::vector>& stubsTrk1 = inputstubidslists_[itrk]; + + // Get and count secondary track stubids + const std::vector>& stubsTrk2 = inputstubidslists_[jtrk]; + + // Count number of Unique Regions (UR) that share stubs, and the number of UR that each track hits + unsigned int nShareUR = 0; + unsigned int nURStubTrk1 = 0; + unsigned int nURStubTrk2 = 0; + if (settings_.mergeComparison() == "CompareAll") { + bool URArray[16]; + for (auto& i : URArray) { + i = false; + }; + for (const auto& st1 : stubsTrk1) { + for (const auto& st2 : stubsTrk2) { + if (st1.first == st2.first && st1.second == st2.second) { + // Converts region encoded in st1->first to an index in the Unique Region (UR) array + int i = st1.first; + int reg = (i > 0 && i < 10) * (i - 1) + (i > 10) * (i - 5) - (i < 0) * i; + if (!URArray[reg]) { + nShareUR++; + URArray[reg] = true; + } + } + } + } + } else if (settings_.mergeComparison() == "CompareBest") { + std::vector fullStubslistsTrk1 = inputstublists_[itrk]; + std::vector fullStubslistsTrk2 = inputstublists_[jtrk]; + + // Arrays to store the index of the best stub in each region + int URStubidsTrk1[16]; + int URStubidsTrk2[16]; + for (int i = 0; i < 16; i++) { + URStubidsTrk1[i] = -1; + URStubidsTrk2[i] = -1; + } + // For each stub on the first track, find the stub with the best residual and store its index in the URStubidsTrk1 array + for (unsigned int stcount = 0; stcount < stubsTrk1.size(); stcount++) { + int i = stubsTrk1[stcount].first; + int reg = (i > 0 && i < 10) * (i - 1) + (i > 10) * (i - 5) - (i < 0) * i; + double nres = getPhiRes(inputtracklets_[itrk], fullStubslistsTrk1[stcount]); + double ores = 0; + if (URStubidsTrk1[reg] != -1) + ores = getPhiRes(inputtracklets_[itrk], fullStubslistsTrk1[URStubidsTrk1[reg]]); + if (URStubidsTrk1[reg] == -1 || nres < ores) { + URStubidsTrk1[reg] = stcount; + } + } + // For each stub on the second track, find the stub with the best residual and store its index in the URStubidsTrk1 array + for (unsigned int stcount = 0; stcount < stubsTrk2.size(); stcount++) { + int i = stubsTrk2[stcount].first; + int reg = (i > 0 && i < 10) * (i - 1) + (i > 10) * (i - 5) - (i < 0) * i; + double nres = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[stcount]); + double ores; + if (URStubidsTrk2[reg] != -1) + ores = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[URStubidsTrk2[reg]]); + if (URStubidsTrk2[reg] == -1 || nres < ores) { + URStubidsTrk2[reg] = stcount; + } + } + // For all 16 regions (6 layers and 10 disks), count the number of regions who's best stub on both tracks are the same + for (int i = 0; i < 16; i++) { + int t1i = URStubidsTrk1[i]; + int t2i = URStubidsTrk2[i]; + if (t1i != -1 && t2i != -1 && stubsTrk1[t1i].first == stubsTrk2[t2i].first && + stubsTrk1[t1i].second == stubsTrk2[t2i].second) + nShareUR++; + } + // Calculate the number of unique regions hit by each track, so that this number can be used in calculating the number of independent + // stubs on a track (not enabled/used by default) + for (int i = 0; i < 16; i++) { + if (URStubidsTrk1[i] != -1) + nURStubTrk1++; + if (URStubidsTrk2[i] != -1) + nURStubTrk2++; + } + } + + // Fill duplicate map + if (nShareUR >= settings_.minIndStubs()) { // For number of shared stub merge condition + dupMap[itrk][jtrk] = true; + dupMap[jtrk][itrk] = true; + } + } + } + + // Merge duplicate tracks + for (unsigned int itrk = 0; itrk < numStublists - 1; itrk++) { + for (unsigned int jtrk = itrk + 1; jtrk < numStublists; jtrk++) { + // Merge a track with its first duplicate found. + if (dupMap[itrk][jtrk]) { + // Set preferred track based on seed rank + int preftrk; + int rejetrk; + if (seedRank[itrk] < seedRank[jtrk]) { + preftrk = itrk; + rejetrk = jtrk; + } else { + preftrk = jtrk; + rejetrk = itrk; + } + + // Get a merged stub list + std::vector newStubList; + std::vector stubsTrk1 = inputstublists_[rejetrk]; + std::vector stubsTrk2 = inputstublists_[preftrk]; + newStubList = stubsTrk1; + for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) { + if (find(stubsTrk1.begin(), stubsTrk1.end(), stubsTrk2[stub2it]) == stubsTrk1.end()) { + newStubList.push_back(stubsTrk2[stub2it]); + } + } + // Overwrite stublist of preferred track with merged list + inputstublists_[preftrk] = newStubList; + + std::vector> newStubidsList; + std::vector> stubidsTrk1 = mergedstubidslists_[rejetrk]; + std::vector> stubidsTrk2 = mergedstubidslists_[preftrk]; + newStubidsList = stubidsTrk1; + for (unsigned int stub2it = 0; stub2it < stubidsTrk2.size(); stub2it++) { + if (find(stubidsTrk1.begin(), stubidsTrk1.end(), stubidsTrk2[stub2it]) == stubidsTrk1.end()) { + newStubidsList.push_back(stubidsTrk2[stub2it]); + } + } + // Overwrite stubidslist of preferred track with merged list + mergedstubidslists_[preftrk] = newStubidsList; + + // Mark that rejected track has been merged into another track + trackInfo[rejetrk].second = true; + } + } + } + + // Make the final track objects, fit with KF, and send to output + for (unsigned int itrk = 0; itrk < numStublists; itrk++) { + Tracklet* tracklet = inputtracklets_[itrk]; + std::vector trackstublist = inputstublists_[itrk]; + + HybridFit hybridFitter(iSector_, settings_, globals_); + hybridFitter.Fit(tracklet, trackstublist); + + // If the track was accepted (and thus fit), add to output + if (tracklet->fit()) { + // Add track to output if it wasn't merged into another + Track* outtrack = tracklet->getTrack(); + outtrack->setSector(iSector_); + if (trackInfo[itrk].second == true) + outtrack->setDuplicate(true); + else + outputtracklets_[trackInfo[itrk].first]->addTrack(tracklet); + + // Add all tracks to standalone root file output + outtrack->setStubIDpremerge(inputstubidslists_[itrk]); + outtrack->setStubIDprefit(mergedstubidslists_[itrk]); + outputtracks_.push_back(outtrack); + } + } + } +#endif + + ////////////////// + // Grid removal // + ////////////////// + if (settings_.removalType() == "grid") { + // Sort tracks by ichisq/DoF so that removal will keep the lower ichisq/DoF track + std::sort(inputtracks_.begin(), inputtracks_.end(), [](const Track* lhs, const Track* rhs) { + return lhs->ichisq() / lhs->stubID().size() < rhs->ichisq() / rhs->stubID().size(); + }); + bool grid[35][40] = {{false}}; + + for (unsigned int itrk = 0; itrk < numTrk; itrk++) { + if (inputtracks_[itrk]->duplicate()) + edm::LogPrint("Tracklet") << "WARNING: Track already tagged as duplicate!!"; + + double phiBin = (inputtracks_[itrk]->phi0(settings_) - 2 * M_PI / 27 * iSector_) / (2 * M_PI / 9 / 50) + 9; + phiBin = std::max(phiBin, 0.); + phiBin = std::min(phiBin, 34.); + + double ptBin = 1 / inputtracks_[itrk]->pt(settings_) * 40 + 20; + ptBin = std::max(ptBin, 0.); + ptBin = std::min(ptBin, 39.); + + if (grid[(int)phiBin][(int)ptBin]) + inputtracks_[itrk]->setDuplicate(true); + grid[(int)phiBin][(int)ptBin] = true; + + double phiTest = inputtracks_[itrk]->phi0(settings_) - 2 * M_PI / 27 * iSector_; + if (phiTest < -2 * M_PI / 27) + edm::LogVerbatim("Tracklet") << "track phi too small!"; + if (phiTest > 2 * 2 * M_PI / 27) + edm::LogVerbatim("Tracklet") << "track phi too big!"; + } + } // end grid removal + + ////////////////////////// + // ichi + nstub removal // + ////////////////////////// + if (settings_.removalType() == "ichi" || settings_.removalType() == "nstub") { + for (unsigned int itrk = 0; itrk < numTrk - 1; itrk++) { // numTrk-1 since last track has no other to compare to + + // If primary track is a duplicate, it cannot veto any...move on + if (inputtracks_[itrk]->duplicate() == 1) + continue; + + unsigned int nStubP = 0; + vector nStubS(numTrk); + vector nShare(numTrk); + // Get and count primary stubs + std::map stubsTrk1 = inputtracks_[itrk]->stubID(); + nStubP = stubsTrk1.size(); + + for (unsigned int jtrk = itrk + 1; jtrk < numTrk; jtrk++) { + // Skip duplicate tracks + if (inputtracks_[jtrk]->duplicate() == 1) + continue; + + // Get and count secondary stubs + std::map stubsTrk2 = inputtracks_[jtrk]->stubID(); + nStubS[jtrk] = stubsTrk2.size(); + + // Count shared stubs + for (auto& st : stubsTrk1) { + if (stubsTrk2.find(st.first) != stubsTrk2.end()) { + if (st.second == stubsTrk2[st.first]) + nShare[jtrk]++; + } + } + } + + // Tag duplicates + for (unsigned int jtrk = itrk + 1; jtrk < numTrk; jtrk++) { + // Skip duplicate tracks + if (inputtracks_[jtrk]->duplicate() == 1) + continue; + + // Chi2 duplicate removal + if (settings_.removalType() == "ichi") { + if ((nStubP - nShare[jtrk] < settings_.minIndStubs()) || + (nStubS[jtrk] - nShare[jtrk] < settings_.minIndStubs())) { + if ((int)inputtracks_[itrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4) > + (int)inputtracks_[jtrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4)) { + inputtracks_[itrk]->setDuplicate(true); + } else if ((int)inputtracks_[itrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4) <= + (int)inputtracks_[jtrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4)) { + inputtracks_[jtrk]->setDuplicate(true); + } else { + edm::LogVerbatim("Tracklet") << "Error: Didn't tag either track in duplicate pair."; + } + } + } // end ichi removal + + // nStub duplicate removal + if (settings_.removalType() == "nstub") { + if ((nStubP - nShare[jtrk] < settings_.minIndStubs()) && (nStubP < nStubS[jtrk])) { + inputtracks_[itrk]->setDuplicate(true); + } else if ((nStubS[jtrk] - nShare[jtrk] < settings_.minIndStubs()) && (nStubS[jtrk] <= nStubP)) { + inputtracks_[jtrk]->setDuplicate(true); + } else { + edm::LogVerbatim("Tracklet") << "Error: Didn't tag either track in duplicate pair."; + } + } // end nstub removal + + } // end tag duplicates + + } // end loop over primary track + + } // end ichi + nstub removal + + //Add tracks to output + if (settings_.removalType() != "merge") { + for (unsigned int i = 0; i < inputtrackfits_.size(); i++) { + for (unsigned int j = 0; j < inputtrackfits_[i]->nTracks(); j++) { + if (inputtrackfits_[i]->getTrack(j)->getTrack()->duplicate() == 0) { + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " + << inputtrackfits_[i]->getTrack(j)->getISeed() << endl; + fout.close(); + } + outputtracklets_[i]->addTrack(inputtrackfits_[i]->getTrack(j)); + } + //For root file: + outputtracks_.push_back(inputtrackfits_[i]->getTrack(j)->getTrack()); + } + } + } +} + +double PurgeDuplicate::getPhiRes(Tracklet* curTracklet, const Stub* curStub) { + double phiproj; + double stubphi; + double phires; + // Get phi position of stub + stubphi = curStub->l1tstub()->phi(); + // Get region that the stub is in (Layer 1->6, Disk 1->5) + int Layer = curStub->layer().value() + 1; + int Disk = curStub->disk().value(); + // Get phi projection of tracklet + int seedindex = curTracklet->seedIndex(); + // If this stub is a seed stub, set projection=phi, so that res=0 + if ((seedindex == 0 && (Layer == 1 || Layer == 2)) || (seedindex == 1 && (Layer == 2 || abs(Disk) == 0)) || + (seedindex == 2 && (Layer == 3 || Layer == 4)) || (seedindex == 3 && (Layer == 5 || Layer == 6)) || + (seedindex == 4 && (abs(Disk) == 1 || abs(Disk) == 2)) || + (seedindex == 5 && (abs(Disk) == 3 || abs(Disk) == 4)) || (seedindex == 6 && (Layer == 1 || abs(Disk) == 1)) || + (seedindex == 7 && (Layer == 2 || abs(Disk) == 1)) || + (seedindex == 8 && (Layer == 2 || Layer == 3 || Layer == 4)) || + (seedindex == 9 && (Layer == 4 || Layer == 5 || Layer == 6)) || + (seedindex == 10 && (Layer == 2 || Layer == 3 || abs(Disk) == 1)) || + (seedindex == 11 && (Layer == 2 || abs(Disk) == 1 || abs(Disk) == 2))) { + phiproj = stubphi; + // Otherwise, get projection of tracklet + } else if (Layer != 0) { + phiproj = curTracklet->phiproj(Layer); + } else if (Disk != 0) { + phiproj = curTracklet->phiprojdisk(Disk); + } else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Layer: " << Layer << " -- Disk: " << Disk + << " Stub is not layer or disk in getPhiRes"; + } + // Calculate residual + phires = std::abs(stubphi - phiproj); + return phires; +} diff --git a/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc b/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc new file mode 100644 index 0000000000000..966bc40bca0e6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/SLHCEvent.cc @@ -0,0 +1,293 @@ +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +L1SimTrack::L1SimTrack() { + eventid_ = -1; + trackid_ = -1; +} + +L1SimTrack::L1SimTrack( + int eventid, int trackid, int type, double pt, double eta, double phi, double vx, double vy, double vz) { + eventid_ = eventid; + trackid_ = trackid; + type_ = type; + pt_ = pt; + eta_ = eta; + phi_ = phi; + vx_ = vx; + vy_ = vy; + vz_ = vz; +} + +void L1SimTrack::write(ofstream& out) { + if (pt_ > -2.0) { + out << "SimTrack: " << eventid_ << "\t" << trackid_ << "\t" << type_ << "\t" << pt_ << "\t" << eta_ << "\t" << phi_ + << "\t" << vx_ << "\t" << vy_ << "\t" << vz_ << "\t" << endl; + } +} + +void L1SimTrack::write(ostream& out) { + if (pt_ > -2) { + out << "SimTrack: " << eventid_ << "\t" << trackid_ << "\t" << type_ << "\t" << pt_ << "\t" << eta_ << "\t" << phi_ + << "\t" << vx_ << "\t" << vy_ << "\t" << vz_ << "\t" << endl; + } +} + +void SLHCEvent::addL1SimTrack( + int eventid, int trackid, int type, double pt, double eta, double phi, double vx, double vy, double vz) { + vx -= x_offset_; + vy -= y_offset_; + L1SimTrack simtrack(eventid, trackid, type, pt, eta, phi, vx, vy, vz); + simtracks_.push_back(simtrack); +} + +bool SLHCEvent::addStub(int layer, + int ladder, + int module, + int strip, + int eventid, + vector tps, + double pt, + double bend, + double x, + double y, + double z, + int isPSmodule, + int isFlipped) { + if (layer > 999 && layer < 1999 && z < 0.0) { + layer += 1000; + } + + layer--; + x -= x_offset_; + y -= y_offset_; + + L1TStub stub( + eventid, tps, -1, -1, layer, ladder, module, strip, x, y, z, -1.0, -1.0, pt, bend, isPSmodule, isFlipped); + + stubs_.push_back(stub); + return true; +} + +SLHCEvent::SLHCEvent(istream& in) { + string tmp; + in >> tmp; + while (tmp == "Map:") { + in >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp; + in >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp >> tmp; + } + if (tmp == "EndMap") { + in >> tmp; + } + if (tmp != "Event:") { + edm::LogVerbatim("Tracklet") << "Expected to read 'Event:' but found:" << tmp; + if (tmp.empty()) { + edm::LogVerbatim("Tracklet") << "WARNING: fewer events to process than specified!"; + return; + } else { + edm::LogVerbatim("Tracklet") << "ERROR, aborting reading file"; + abort(); + } + } + in >> eventnum_; + + // read the SimTracks + in >> tmp; + while (tmp != "SimTrackEnd") { + if (!(tmp == "SimTrack:" || tmp == "SimTrackEnd")) { + edm::LogVerbatim("Tracklet") << "Expected to read 'SimTrack:' or 'SimTrackEnd' but found:" << tmp; + abort(); + } + int eventid; + int trackid; + int type; + string pt_str; + string eta_str; + string phi_str; + string vx_str; + string vy_str; + string vz_str; + double pt; + double eta; + double phi; + double vx; + double vy; + double vz; + in >> eventid >> trackid >> type >> pt_str >> eta_str >> phi_str >> vx_str >> vy_str >> vz_str; + pt = strtod(pt_str.c_str(), nullptr); + eta = strtod(eta_str.c_str(), nullptr); + phi = strtod(phi_str.c_str(), nullptr); + vx = strtod(vx_str.c_str(), nullptr); + vy = strtod(vy_str.c_str(), nullptr); + vz = strtod(vz_str.c_str(), nullptr); + vx -= x_offset_; + vy -= y_offset_; + L1SimTrack simtrack(eventid, trackid, type, pt, eta, phi, vx, vy, vz); + simtracks_.push_back(simtrack); + in >> tmp; + } + + int oldlayer = 0; + int oldladder = 0; + int oldmodule = 0; + int oldcbc = -1; + int count = 1; + double oldz = -1000.0; + + //read stubs + in >> tmp; + while (tmp != "StubEnd") { + if (!in.good()) { + edm::LogVerbatim("Tracklet") << "File not good"; + abort(); + }; + if (!(tmp == "Stub:" || tmp == "StubEnd")) { + edm::LogVerbatim("Tracklet") << "Expected to read 'Stub:' or 'StubEnd' but found:" << tmp; + abort(); + } + int layer; + int ladder; + int module; + int eventid; + vector tps; + int strip; + double pt; + double x; + double y; + double z; + double bend; + int isPSmodule; + int isFlipped; + + unsigned int ntps; + + in >> layer >> ladder >> module >> strip >> eventid >> pt >> x >> y >> z >> bend >> isPSmodule >> isFlipped >> ntps; + + for (unsigned int itps = 0; itps < ntps; itps++) { + int tp; + in >> tp; + tps.push_back(tp); + } + + if (layer > 999 && layer < 1999 && z < 0.0) { //negative disk + layer += 1000; + } + + int cbc = strip / 126; + if (layer > 3 && layer == oldlayer && ladder == oldladder && module == oldmodule && cbc == oldcbc && + std::abs(oldz - z) < 1.0) { + count++; + } else { + oldlayer = layer; + oldladder = ladder; + oldmodule = module; + oldcbc = cbc; + oldz = z; + count = 1; + } + + layer--; + x -= x_offset_; + y -= y_offset_; + + L1TStub stub( + eventid, tps, -1, -1, layer, ladder, module, strip, x, y, z, -1.0, -1.0, pt, bend, isPSmodule, isFlipped); + + in >> tmp; + + double t = std::abs(stub.z()) / stub.r(); + double eta = asinh(t); + + if (std::abs(eta) < 2.6 && count <= 100) { + stubs_.push_back(stub); + } + } +} + +void SLHCEvent::write(ofstream& out) { + out << "Event: " << eventnum_ << endl; + + for (auto& simtrack : simtracks_) { + simtrack.write(out); + } + out << "SimTrackEnd" << endl; + + for (auto& stub : stubs_) { + stub.write(out); + } + out << "StubEnd" << endl; +} + +void SLHCEvent::write(ostream& out) { + out << "Event: " << eventnum_ << endl; + + for (auto& simtrack : simtracks_) { + simtrack.write(out); + } + out << "SimTrackEnd" << endl; + + for (auto& stub : stubs_) { + stub.write(out); + } + out << "StubEnd" << endl; +} + +unsigned int SLHCEvent::layersHit(int tpid, int& nlayers, int& ndisks) { + int l1 = 0; + int l2 = 0; + int l3 = 0; + int l4 = 0; + int l5 = 0; + int l6 = 0; + + int d1 = 0; + int d2 = 0; + int d3 = 0; + int d4 = 0; + int d5 = 0; + + for (auto& stub : stubs_) { + if (stub.tpmatch(tpid)) { + if (stub.layer() == 0) + l1 = 1; + if (stub.layer() == 1) + l2 = 1; + if (stub.layer() == 2) + l3 = 1; + if (stub.layer() == 3) + l4 = 1; + if (stub.layer() == 4) + l5 = 1; + if (stub.layer() == 5) + l6 = 1; + + if (abs(stub.disk()) == 1) + d1 = 1; + if (abs(stub.disk()) == 2) + d2 = 1; + if (abs(stub.disk()) == 3) + d3 = 1; + if (abs(stub.disk()) == 4) + d4 = 1; + if (abs(stub.disk()) == 5) + d5 = 1; + } + } + + nlayers = l1 + l2 + l3 + l4 + l5 + l6; + ndisks = d1 + d2 + d3 + d4 + d5; + + return l1 + 2 * l2 + 4 * l3 + 8 * l4 + 16 * l5 + 32 * l6 + 64 * d1 + 128 * d2 + 256 * d3 + 512 * d4 + 1024 * d5; +} + +int SLHCEvent::getSimtrackFromSimtrackid(int simtrackid, int eventid) const { + for (unsigned int i = 0; i < simtracks_.size(); i++) { + if (simtracks_[i].trackid() == simtrackid && simtracks_[i].eventid() == eventid) + return i; + } + return -1; +} diff --git a/L1Trigger/TrackFindingTracklet/src/Sector.cc b/L1Trigger/TrackFindingTracklet/src/Sector.cc new file mode 100644 index 0000000000000..0c383ed147360 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Sector.cc @@ -0,0 +1,430 @@ +#include "L1Trigger/TrackFindingTracklet/interface/Sector.h" +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +#include "L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/CandidateMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/FullMatchMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/CleanTrackMemory.h" + +#include "L1Trigger/TrackFindingTracklet/interface/VMRouter.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletEngine.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletEngineDisplaced.h" +#include "L1Trigger/TrackFindingTracklet/interface/TripletEngine.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProcessor.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorDisplaced.h" +#include "L1Trigger/TrackFindingTracklet/interface/ProjectionRouter.h" +#include "L1Trigger/TrackFindingTracklet/interface/MatchEngine.h" +#include "L1Trigger/TrackFindingTracklet/interface/MatchCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/MatchProcessor.h" +#include "L1Trigger/TrackFindingTracklet/interface/FitTrack.h" +#include "L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +Sector::Sector(unsigned int i, Settings const& settings, Globals* globals) : settings_(settings), globals_(globals) { + isector_ = i; + double dphi = 2 * M_PI / N_SECTOR; + double dphiHG = 0.5 * settings_.dphisectorHG() - M_PI / N_SECTOR; + phimin_ = isector_ * dphi - dphiHG; + phimax_ = phimin_ + dphi + 2 * dphiHG; + phimin_ -= M_PI / N_SECTOR; + phimax_ -= M_PI / N_SECTOR; + phimin_ = reco::reduceRange(phimin_); + phimax_ = reco::reduceRange(phimax_); + if (phimin_ > phimax_) + phimin_ -= 2 * M_PI; +} + +Sector::~Sector() { + for (auto& mem : MemoriesV_) { + mem->clean(); + } +} + +bool Sector::addStub(L1TStub stub, string dtc) { + bool add = false; + + double phi = stub.phi(); + double dphi = 0.5 * settings_.dphisectorHG() - M_PI / N_SECTOR; + + std::map >& ILindex = globals_->ILindex(); + std::vector& tmp = ILindex[dtc]; + if (tmp.empty()) { + for (unsigned int i = 0; i < IL_.size(); i++) { + if (IL_[i]->getName().find("_" + dtc) != string::npos) { + tmp.push_back(i); + } + } + } + + if (((phi > phimin_ - dphi) && (phi < phimax_ + dphi)) || + ((phi > 2 * M_PI + phimin_ - dphi) && (phi < 2 * M_PI + phimax_ + dphi))) { + Stub fpgastub(stub, settings_, phimin_, phimax_); + std::vector& tmp = ILindex[dtc]; + assert(!tmp.empty()); + for (int i : tmp) { + if (IL_[i]->addStub(settings_, globals_, stub, fpgastub, dtc)) + add = true; + } + } + + return add; +} + +void Sector::addMem(string memType, string memName) { + if (memType == "InputLink:") { + addMemToVec(IL_, new InputLinkMemory(memName, settings_, isector_, phimin_, phimax_), memName); + } else if (memType == "AllStubs:") { + addMemToVec(AS_, new AllStubsMemory(memName, settings_, isector_), memName); + } else if (memType == "VMStubsTE:") { + addMemToVec(VMSTE_, new VMStubsTEMemory(memName, settings_, isector_), memName); + } else if (memType == "VMStubsME:") { + addMemToVec(VMSME_, new VMStubsMEMemory(memName, settings_, isector_), memName); + } else if (memType == "StubPairs:" || memType == "StubPairsDisplaced:") { + addMemToVec(SP_, new StubPairsMemory(memName, settings_, isector_), memName); + } else if (memType == "StubTriplets:") { + addMemToVec(ST_, new StubTripletsMemory(memName, settings_, isector_), memName); + } else if (memType == "TrackletParameters:") { + addMemToVec(TPAR_, new TrackletParametersMemory(memName, settings_, isector_), memName); + } else if (memType == "TrackletProjections:") { + addMemToVec(TPROJ_, new TrackletProjectionsMemory(memName, settings_, isector_), memName); + } else if (memType == "AllProj:") { + addMemToVec(AP_, new AllProjectionsMemory(memName, settings_, isector_), memName); + } else if (memType == "VMProjections:") { + addMemToVec(VMPROJ_, new VMProjectionsMemory(memName, settings_, isector_), memName); + } else if (memType == "CandidateMatch:") { + addMemToVec(CM_, new CandidateMatchMemory(memName, settings_, isector_), memName); + } else if (memType == "FullMatch:") { + addMemToVec(FM_, new FullMatchMemory(memName, settings_, isector_), memName); + } else if (memType == "TrackFit:") { + addMemToVec(TF_, new TrackFitMemory(memName, settings_, isector_, phimin_, phimax_), memName); + } else if (memType == "CleanTrack:") { + addMemToVec(CT_, new CleanTrackMemory(memName, settings_, isector_, phimin_, phimax_), memName); + } else { + edm::LogPrint("Tracklet") << "Don't know of memory type: " << memType; + exit(0); + } +} + +void Sector::addProc(string procType, string procName) { + if (procType == "VMRouter:") { + addProcToVec(VMR_, new VMRouter(procName, settings_, globals_, isector_), procName); + } else if (procType == "TrackletEngine:") { + addProcToVec(TE_, new TrackletEngine(procName, settings_, globals_, isector_), procName); + } else if (procType == "TrackletEngineDisplaced:") { + addProcToVec(TED_, new TrackletEngineDisplaced(procName, settings_, globals_, isector_), procName); + } else if (procType == "TripletEngine:") { + addProcToVec(TRE_, new TripletEngine(procName, settings_, globals_, isector_), procName); + } else if (procType == "TrackletCalculator:") { + addProcToVec(TC_, new TrackletCalculator(procName, settings_, globals_, isector_), procName); + } else if (procType == "TrackletProcessor:") { + addProcToVec(TP_, new TrackletProcessor(procName, settings_, globals_, isector_), procName); + } else if (procType == "TrackletCalculatorDisplaced:") { + addProcToVec(TCD_, new TrackletCalculatorDisplaced(procName, settings_, globals_, isector_), procName); + } else if (procType == "ProjectionRouter:") { + addProcToVec(PR_, new ProjectionRouter(procName, settings_, globals_, isector_), procName); + } else if (procType == "MatchEngine:") { + addProcToVec(ME_, new MatchEngine(procName, settings_, globals_, isector_), procName); + } else if (procType == "MatchCalculator:" || + procType == "DiskMatchCalculator:") { //TODO should not be used in configurations + addProcToVec(MC_, new MatchCalculator(procName, settings_, globals_, isector_), procName); + } else if (procType == "MatchProcessor:") { + addProcToVec(MP_, new MatchProcessor(procName, settings_, globals_, isector_), procName); + } else if (procType == "FitTrack:") { + addProcToVec(FT_, new FitTrack(procName, settings_, globals_, isector_), procName); + } else if (procType == "PurgeDuplicate:") { + addProcToVec(PD_, new PurgeDuplicate(procName, settings_, globals_, isector_), procName); + } else { + edm::LogPrint("Tracklet") << "Don't know of processing type: " << procType; + exit(0); + } +} + +void Sector::addWire(string mem, string procinfull, string procoutfull) { + stringstream ss1(procinfull); + string procin, output; + getline(ss1, procin, '.'); + getline(ss1, output); + + stringstream ss2(procoutfull); + string procout, input; + getline(ss2, procout, '.'); + getline(ss2, input); + + MemoryBase* memory = getMem(mem); + + if (!procin.empty()) { + ProcessBase* inProc = getProc(procin); + inProc->addOutput(memory, output); + } + + if (!procout.empty()) { + ProcessBase* outProc = getProc(procout); + outProc->addInput(memory, input); + } +} + +ProcessBase* Sector::getProc(string procName) { + auto it = Processes_.find(procName); + + if (it != Processes_.end()) { + return it->second.get(); + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find process : " << procName; + return nullptr; +} + +MemoryBase* Sector::getMem(string memName) { + auto it = Memories_.find(memName); + + if (it != Memories_.end()) { + return it->second.get(); + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find memory : " << memName; + return nullptr; +} + +void Sector::writeInputStubs(bool first) { + for (auto& i : IL_) { + i->writeStubs(first); + } +} + +void Sector::writeVMSTE(bool first) { + for (auto& i : VMSTE_) { + i->writeStubs(first); + } +} + +void Sector::writeVMSME(bool first) { + for (auto& i : VMSME_) { + i->writeStubs(first); + } +} + +void Sector::writeAS(bool first) { + for (auto& i : AS_) { + i->writeStubs(first); + } +} + +void Sector::writeSP(bool first) { + for (auto& i : SP_) { + i->writeSP(first); + } +} + +void Sector::writeST(bool first) { + for (auto& i : ST_) { + i->writeST(first); + } +} + +void Sector::writeTPAR(bool first) { + for (auto& i : TPAR_) { + i->writeTPAR(first); + } +} + +void Sector::writeTPROJ(bool first) { + for (auto& i : TPROJ_) { + i->writeTPROJ(first); + } +} + +void Sector::writeAP(bool first) { + for (auto& i : AP_) { + i->writeAP(first); + } +} + +void Sector::writeVMPROJ(bool first) { + for (auto& i : VMPROJ_) { + i->writeVMPROJ(first); + } +} + +void Sector::writeCM(bool first) { + for (auto& i : CM_) { + i->writeCM(first); + } +} + +void Sector::writeMC(bool first) { + for (auto& i : FM_) { + i->writeMC(first); + } +} + +void Sector::writeTF(bool first) { + for (auto& i : TF_) { + i->writeTF(first); + } +} + +void Sector::writeCT(bool first) { + for (auto& i : CT_) { + i->writeCT(first); + } +} + +void Sector::clean() { + if (settings_.writeMonitorData("NMatches")) { + int matchesL1 = 0; + int matchesL3 = 0; + int matchesL5 = 0; + for (auto& i : TPAR_) { + i->writeMatches(globals_, matchesL1, matchesL3, matchesL5); + } + globals_->ofstream("nmatchessector.txt") << matchesL1 << " " << matchesL3 << " " << matchesL5 << endl; + } + + for (auto& mem : MemoriesV_) { + mem->clean(); + } +} + +void Sector::executeVMR() { + if (settings_.writeMonitorData("IL")) { + ofstream& out = globals_->ofstream("inputlink.txt"); + for (auto& i : IL_) { + out << i->getName() << " " << i->nStubs() << endl; + } + } + for (auto& i : VMR_) { + i->execute(); + } +} + +void Sector::executeTE() { + for (auto& i : TE_) { + i->execute(); + } +} + +void Sector::executeTED() { + for (auto& i : TED_) { + i->execute(); + } +} + +void Sector::executeTRE() { + for (auto& i : TRE_) { + i->execute(); + } +} + +void Sector::executeTP() { + for (auto& i : TP_) { + i->execute(); + } +} + +void Sector::executeTC() { + for (auto& i : TC_) { + i->execute(); + } + + if (settings_.writeMonitorData("TrackProjOcc")) { + ofstream& out = globals_->ofstream("trackprojocc.txt"); + for (auto& i : TPROJ_) { + out << i->getName() << " " << i->nTracklets() << endl; + } + } +} + +void Sector::executeTCD() { + for (auto& i : TCD_) { + i->execute(); + } +} + +void Sector::executePR() { + for (auto& i : PR_) { + i->execute(); + } +} + +void Sector::executeME() { + for (auto& i : ME_) { + i->execute(); + } +} + +void Sector::executeMC() { + for (auto& i : MC_) { + i->execute(); + } +} + +void Sector::executeMP() { + for (auto& i : MP_) { + i->execute(); + } +} + +void Sector::executeFT() { + for (auto& i : FT_) { + i->execute(); + } +} + +void Sector::executePD(std::vector& tracks) { + for (auto& i : PD_) { + i->execute(tracks); + } +} + +std::vector Sector::getAllTracklets() const { + std::vector tmp; + for (auto tpar : TPAR_) { + for (unsigned int j = 0; j < tpar->nTracklets(); j++) { + tmp.push_back(tpar->getTracklet(j)); + } + } + return tmp; +} + +std::vector Sector::getStubs() const { + std::vector tmp; + + for (auto imem : IL_) { + for (unsigned int istub = 0; istub < imem->nStubs(); istub++) { + tmp.push_back(imem->getStub(istub)); + } + } + + return tmp; +} + +std::unordered_set Sector::seedMatch(int itp) const { + std::unordered_set tmpSeeds; + for (auto i : TPAR_) { + unsigned int nTracklet = i->nTracklets(); + for (unsigned int j = 0; j < nTracklet; j++) { + if (i->getTracklet(j)->tpseed() == itp) { + tmpSeeds.insert(i->getTracklet(j)->getISeed()); + } + } + } + return tmpSeeds; +} diff --git a/L1Trigger/TrackFindingTracklet/src/Stub.cc b/L1Trigger/TrackFindingTracklet/src/Stub.cc new file mode 100644 index 0000000000000..6fa8dc5b85753 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Stub.cc @@ -0,0 +1,248 @@ +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +#include + +using namespace std; +using namespace trklet; + +Stub::Stub(Settings const& settings) : settings_(settings) {} + +Stub::Stub(L1TStub& stub, Settings const& settings, double phiminsec, double phimaxsec) : settings_(settings) { + double r = stub.r(); + double z = stub.z(); + double sbend = stub.bend(); + + l1tstub_ = &stub; + + int bendbits = 4; + if (stub.isPSmodule()) + bendbits = 3; + + int ibend = bendencode(sbend, stub.isPSmodule()); + + bend_.set(ibend, bendbits, true, __LINE__, __FILE__); + + int layer = stub.layer() + 1; + + // hold the real values from L1Stub + double stubphi = stub.phi(); + + if (layer < 999) { + disk_.set(0, 4, false, __LINE__, __FILE__); + + assert(layer > 0 && layer <= N_LAYER); + double rmin = settings_.rmean(layer - 1) - settings_.drmax(); + double rmax = settings_.rmean(layer - 1) + settings_.drmax(); + + if (r < rmin || r > rmax) { + edm::LogProblem("Tracklet") << "Error r, rmin, rmeas, rmax :" << r << " " << rmin << " " << 0.5 * (rmin + rmax) + << " " << rmax; + } + + int irbits = settings_.nrbitsstub(layer - 1); + + int ir = lround((1 << irbits) * ((r - settings_.rmean(layer - 1)) / (rmax - rmin))); + + double zmin = -settings_.zlength(); + double zmax = settings_.zlength(); + + if (z < zmin || z > zmax) { + edm::LogProblem("Tracklet") << "Error z, zmin, zmax :" << z << " " << zmin << " " << zmax; + } + + int izbits = settings_.nzbitsstub(layer - 1); + + int iz = lround((1 << izbits) * z / (zmax - zmin)); + + if (z < zmin || z > zmax) { + edm::LogProblem("Tracklet") << "Error z, zmin, zmax :" << z << " " << zmin << " " << zmax; + } + + assert(phimaxsec - phiminsec > 0.0); + + if (stubphi < phiminsec - (phimaxsec - phiminsec) / 6.0) { + stubphi += 2 * M_PI; + } + assert((phimaxsec - phiminsec) > 0.0); + + int iphibits = settings_.nphibitsstub(layer - 1); + + double deltaphi = reco::reduceRange(stubphi - phiminsec); + + int iphi = (1 << iphibits) * deltaphi / (phimaxsec - phiminsec); + + layer_.set(layer - 1, 3, true, __LINE__, __FILE__); + r_.set(ir, irbits, false, __LINE__, __FILE__); + z_.set(iz, izbits, false, __LINE__, __FILE__); + phi_.set(iphi, iphibits, true, __LINE__, __FILE__); + + phicorr_.set(iphi, iphibits, true, __LINE__, __FILE__); + + } else { + // Here we handle the hits on disks. + + int disk = stub.module(); + assert(disk > 0 && disk <= N_DISK); + int sign = 1; + if (z < 0.0) + sign = -1; + + double zmin = sign * (settings_.zmean(disk - 1) - sign * settings_.dzmax()); + double zmax = sign * (settings_.zmean(disk - 1) + sign * settings_.dzmax()); + + if ((z > zmax) || (z < zmin)) { + edm::LogProblem("Tracklet") << "Error disk z, zmax, zmin: " << z << " " << zmax << " " << zmin; + } + + int iz = + (1 << settings.nzbitsstub(disk + N_DISK)) * ((z - sign * settings_.zmean(disk - 1)) / std::abs(zmax - zmin)); + + assert(phimaxsec - phiminsec > 0.0); + if (stubphi < phiminsec - (phimaxsec - phiminsec) / 6.0) { + stubphi += 2 * M_PI; + } + + assert(phimaxsec - phiminsec > 0.0); + if (stubphi < phiminsec - (phimaxsec - phiminsec) / 6.0) { + stubphi += 2 * M_PI; + } + + int iphibits = settings_.nphibitsstub(disk + 5); + + double deltaphi = reco::reduceRange(stubphi - phiminsec); + + int iphi = (1 << iphibits) * deltaphi / (phimaxsec - phiminsec); + + double rmin = 0; + double rmax = settings_.rmaxdisk(); + + if (r < rmin || r > rmax) { + edm::LogProblem("Tracklet") << "Error disk r, rmin, rmax :" << r << " " << rmin << " " << rmax; + } + + int ir = (1 << settings_.nrbitsstub(disk + 5)) * (r - rmin) / (rmax - rmin); + + int irSS = -1; + if (!stub.isPSmodule()) { + for (unsigned int i = 0; i < N_DSS_MOD * 2; ++i) { + if (disk <= 2) { + if (std::abs(r - settings_.rDSSinner(i)) < 0.2) { + irSS = i; + break; + } + } else { + if (std::abs(r - settings_.rDSSouter(i)) < 0.2) { + irSS = i; + break; + } + } + } + if (irSS < 0) { + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " didn't find rDSS value! r = " << r + << " Check that correct geometry is used!"; + } + } + if (irSS < 0) { + //PS modules + r_.set(ir, settings_.nrbitsstub(disk + N_DISK), true, __LINE__, __FILE__); + } else { + //SS modules + r_.set(irSS, 4, true, __LINE__, __FILE__); // in case of SS modules, store index, not r itself + } + + z_.set(iz, settings.nzbitsstub(disk + 5), false, __LINE__, __FILE__); + phi_.set(iphi, iphibits, true, __LINE__, __FILE__); + phicorr_.set(iphi, iphibits, true, __LINE__, __FILE__); + + disk_.set(sign * disk, 4, false, __LINE__, __FILE__); + + double alphanorm = stub.alphanorm(); + assert(std::abs(alphanorm) < 1.0); + int ialphanew = alphanorm * (1 << (settings.nbitsalpha() - 1)); + assert(ialphanew < (1 << (settings.nbitsalpha() - 1))); + assert(ialphanew >= -(1 << (settings.nbitsalpha() - 1))); + alphanew_.set(ialphanew, settings.nbitsalpha(), false, __LINE__, __FILE__); + } +} + +FPGAWord Stub::iphivmFineBins(int VMbits, int finebits) const { + unsigned int finephi = (phicorr_.value() >> (phicorr_.nbits() - VMbits - finebits)) & ((1 << finebits) - 1); + return FPGAWord(finephi, finebits, true, __LINE__, __FILE__); +} + +unsigned int Stub::phiregionaddress() const { + int iphi = (phicorr_.value() >> (phicorr_.nbits() - settings_.nbitsallstubs(layerdisk()))); + return (iphi << 7) + stubindex_.value(); +} + +std::string Stub::phiregionaddressstr() const { + int iphi = (phicorr_.value() >> (phicorr_.nbits() - settings_.nbitsallstubs(layerdisk()))); + FPGAWord phiregion(iphi, 3, true, __LINE__, __FILE__); + return phiregion.str() + stubindex_.str(); +} + +void Stub::setAllStubIndex(int nstub) { + if (nstub >= (1 << 7)) { + if (settings_.debugTracklet()) + edm::LogPrint("Tracklet") << "Warning too large stubindex!"; + nstub = (1 << 7) - 1; + } + + stubindex_.set(nstub, 7); +} + +void Stub::setPhiCorr(int phiCorr) { + int iphicorr = phi_.value() - phiCorr; + + if (iphicorr < 0) + iphicorr = 0; + if (iphicorr >= (1 << phi_.nbits())) + iphicorr = (1 << phi_.nbits()) - 1; + + phicorr_.set(iphicorr, phi_.nbits(), true, __LINE__, __FILE__); +} + +double Stub::rapprox() const { + if (disk_.value() == 0) { + int lr = 1 << (8 - settings_.nrbitsstub(layer_.value())); + return r_.value() * settings_.kr() * lr + settings_.rmean(layer_.value()); + } + return r_.value() * settings_.kr(); +} + +double Stub::zapprox() const { + if (disk_.value() == 0) { + int lz = 1; + if (layer_.value() >= 3) { + lz = 16; + } + return z_.value() * settings_.kz() * lz; + } + int sign = 1; + if (disk_.value() < 0) + sign = -1; + if (sign < 0) { + //Should understand why this is needed to get agreement with integer calculations + return (z_.value() + 1) * settings_.kz() + sign * settings_.zmean(abs(disk_.value()) - 1); + } else { + return z_.value() * settings_.kz() + sign * settings_.zmean(abs(disk_.value()) - 1); + } +} + +double Stub::phiapprox(double phimin, double) const { + int lphi = 1; + if (layer_.value() >= 3) { + lphi = 8; + } + return reco::reduceRange(phimin + phi_.value() * settings_.kphi() / lphi); +} + +unsigned int Stub::layerdisk() const { + if (layer_.value() == -1) + return 5 + abs(disk_.value()); + return layer_.value(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/StubPairsMemory.cc b/L1Trigger/TrackFindingTracklet/src/StubPairsMemory.cc new file mode 100644 index 0000000000000..4f5e496ee1b94 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/StubPairsMemory.cc @@ -0,0 +1,40 @@ +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubTE.h" +#include + +using namespace std; +using namespace trklet; + +StubPairsMemory::StubPairsMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) {} + +void StubPairsMemory::writeSP(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/StubPairs/StubPairs_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < stubs_.size(); j++) { + string stub1index = stubs_[j].first.stub()->stubindex().str(); + string stub2index = stubs_[j].second.stub()->stubindex().str(); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << stub1index << "|" << stub2index << " " << trklet::hexFormat(stub1index + stub2index) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/StubTripletsMemory.cc b/L1Trigger/TrackFindingTracklet/src/StubTripletsMemory.cc new file mode 100644 index 0000000000000..e9a03d0546e9c --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/StubTripletsMemory.cc @@ -0,0 +1,41 @@ +#include "L1Trigger/TrackFindingTracklet/interface/StubTripletsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include + +using namespace std; +using namespace trklet; + +StubTripletsMemory::StubTripletsMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) {} + +void StubTripletsMemory::writeST(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/StubPairs/StubTriplets_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < stubs1_.size(); j++) { + string stub1index = stubs1_[j]->stubindex().str(); + string stub2index = stubs2_[j]->stubindex().str(); + string stub3index = stubs3_[j]->stubindex().str(); + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << stub1index << "|" << stub2index << "|" << stub3index << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TETableBase.cc b/L1Trigger/TrackFindingTracklet/src/TETableBase.cc new file mode 100644 index 0000000000000..b28334bdf63ef --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TETableBase.cc @@ -0,0 +1,30 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TETableBase.h" + +using namespace std; +using namespace trklet; + +TETableBase::TETableBase(Settings const& settings) : settings_(settings) {} + +void TETableBase::writeVMTable(std::string name, bool positive) { + ofstream out; + out.open(name.c_str()); + out << "{" << endl; + for (unsigned int i = 0; i < table_.size(); i++) { + if (i != 0) { + out << "," << endl; + } + + assert(nbits_ > 0); + + int itable = table_[i]; + if (positive) { + if (table_[i] < 0) { + itable = (1 << nbits_) - 1; + } + } + + out << itable; + } + out << endl << "};" << endl; + out.close(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/Timer.cc b/L1Trigger/TrackFindingTracklet/src/Timer.cc new file mode 100644 index 0000000000000..a9924c7fd21e9 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Timer.cc @@ -0,0 +1,12 @@ +#include "L1Trigger/TrackFindingTracklet/interface/Timer.h" + +using namespace trklet; + +void Timer::start() { tstart_ = std::chrono::high_resolution_clock::now(); } +void Timer::stop() { + auto tstop = std::chrono::high_resolution_clock::now(); + double tmp = std::chrono::duration(tstop - tstart_).count(); + ttot_ += tmp; + ttotsq_ += tmp * tmp; + ntimes_++; +} diff --git a/L1Trigger/TrackFindingTracklet/src/Track.cc b/L1Trigger/TrackFindingTracklet/src/Track.cc new file mode 100644 index 0000000000000..58e1469936aae --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Track.cc @@ -0,0 +1,54 @@ +#include "L1Trigger/TrackFindingTracklet/interface/Track.h" + +#include "DataFormats/Math/interface/deltaPhi.h" + +#include + +using namespace std; +using namespace trklet; + +Track::Track(TrackPars ipars, + int ichisqrphi, + int ichisqrz, + double chisqrphi, + double chisqrz, + int hitpattern, + std::map stubID, + const std::vector& l1stub, + int seed) { + ipars_ = ipars; + ichisqrphi_ = ichisqrphi; + ichisqrz_ = ichisqrz; + + chisqrphi_ = chisqrphi; + chisqrz_ = chisqrz; + + hitpattern_ = hitpattern; + + nstubs_ = std::max((int)l1stub.size(), (int)N_FITSTUB); + + stubID_ = stubID; + l1stub_ = l1stub; + + seed_ = seed; + duplicate_ = false; + sector_ = -1; +} + +double Track::phi0(Settings const& settings) const { + double dphi = 2 * M_PI / N_SECTOR; + double dphiHG = 0.5 * settings.dphisectorHG() - M_PI / N_SECTOR; + double phimin = sector_ * dphi - dphiHG; + double phimax = phimin + dphi + 2 * dphiHG; + phimin -= M_PI / N_SECTOR; + phimax -= M_PI / N_SECTOR; + phimin = reco::reduceRange(phimin); + phimax = reco::reduceRange(phimax); + if (phimin > phimax) + phimin -= 2 * M_PI; + double phioffset = phimin; + + double phi0 = ipars_.phi0() * settings.kphi0pars() + phioffset; + phi0 = reco::reduceRange(phi0); + return phi0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackDer.cc b/L1Trigger/TrackFindingTracklet/src/TrackDer.cc new file mode 100644 index 0000000000000..2f8b02caba448 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackDer.cc @@ -0,0 +1,88 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackDer.h" + +using namespace std; +using namespace trklet; + +TrackDer::TrackDer() { + for (unsigned int i = 0; i < N_FITSTUB; i++) { + irinvdphi_[i] = 9999999; + irinvdzordr_[i] = 9999999; + iphi0dphi_[i] = 9999999; + iphi0dzordr_[i] = 9999999; + itdphi_[i] = 9999999; + itdzordr_[i] = 9999999; + iz0dphi_[i] = 9999999; + iz0dzordr_[i] = 9999999; + + rinvdphi_[i] = 0.0; + rinvdzordr_[i] = 0.0; + phi0dphi_[i] = 0.0; + phi0dzordr_[i] = 0.0; + tdphi_[i] = 0.0; + tdzordr_[i] = 0.0; + z0dphi_[i] = 0.0; + z0dzordr_[i] = 0.0; + } + + for (unsigned int i = 0; i < N_PSLAYER; i++) { + for (unsigned int j = 0; j < N_PSLAYER; j++) { + tdzcorr_[i][j] = 0.0; + z0dzcorr_[i][j] = 0.0; + } + } +} + +void TrackDer::setIndex(int layermask, int diskmask, int alphamask, int irinv) { + layermask_ = layermask; + diskmask_ = diskmask; + alphamask_ = alphamask; + irinv_ = irinv; +} + +void TrackDer::fill(int t, double MinvDt[N_FITPARAM][N_FITSTUB * 2], int iMinvDt[N_FITPARAM][N_FITSTUB * 2]) const { + unsigned int nlayer = 0; + if (layermask_ & 1) + nlayer++; + if (layermask_ & 2) + nlayer++; + if (layermask_ & 4) + nlayer++; + if (layermask_ & 8) + nlayer++; + if (layermask_ & 16) + nlayer++; + if (layermask_ & 32) + nlayer++; + int sign = 1; + if (t < 0) + sign = -1; + for (unsigned int i = 0; i < N_FITSTUB; i++) { + MinvDt[0][2 * i] = rinvdphi_[i]; + MinvDt[1][2 * i] = phi0dphi_[i]; + MinvDt[2][2 * i] = sign * tdphi_[i]; + MinvDt[3][2 * i] = sign * z0dphi_[i]; + MinvDt[0][2 * i + 1] = rinvdzordr_[i]; + MinvDt[1][2 * i + 1] = phi0dzordr_[i]; + MinvDt[2][2 * i + 1] = tdzordr_[i]; + MinvDt[3][2 * i + 1] = z0dzordr_[i]; + iMinvDt[0][2 * i] = irinvdphi_[i]; + iMinvDt[1][2 * i] = iphi0dphi_[i]; + iMinvDt[2][2 * i] = sign * itdphi_[i]; + iMinvDt[3][2 * i] = sign * iz0dphi_[i]; + iMinvDt[0][2 * i + 1] = irinvdzordr_[i]; + iMinvDt[1][2 * i + 1] = iphi0dzordr_[i]; + iMinvDt[2][2 * i + 1] = itdzordr_[i]; + iMinvDt[3][2 * i + 1] = iz0dzordr_[i]; + if (i < nlayer) { + MinvDt[0][2 * i + 1] *= sign; + MinvDt[1][2 * i + 1] *= sign; + iMinvDt[0][2 * i + 1] *= sign; + iMinvDt[1][2 * i + 1] *= sign; + } else { + MinvDt[2][2 * i + 1] *= sign; + MinvDt[3][2 * i + 1] *= sign; + iMinvDt[2][2 * i + 1] *= sign; + iMinvDt[3][2 * i + 1] *= sign; + } + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackDerTable.cc b/L1Trigger/TrackFindingTracklet/src/TrackDerTable.cc new file mode 100644 index 0000000000000..a5d6668de19c1 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackDerTable.cc @@ -0,0 +1,1048 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackDerTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +TrackDerTable::TrackDerTable(Settings const& settings) : settings_(settings) { + Nlay_ = N_LAYER; + Ndisk_ = N_DISK; + + LayerMemBits_ = 6; + DiskMemBits_ = 7; + LayerDiskMemBits_ = 18; + + alphaBits_ = settings_.alphaBitsTable(); + + nextLayerValue_ = 0; + nextDiskValue_ = 0; + nextLayerDiskValue_ = 0; + lastMultiplicity_ = (1 << (3 * alphaBits_)); + + for (int i = 0; i < (1 << Nlay_); i++) { + LayerMem_.push_back(-1); + } + + for (int i = 0; i < (1 << (2 * Ndisk_)); i++) { + DiskMem_.push_back(-1); + } + + for (int i = 0; i < (1 << (LayerMemBits_ + DiskMemBits_)); i++) { + LayerDiskMem_.push_back(-1); + } +} + +const TrackDer* TrackDerTable::getDerivatives(unsigned int layermask, + unsigned int diskmask, + unsigned int alphaindex, + unsigned int rinvindex) const { + int index = getIndex(layermask, diskmask); + if (index < 0) { + return nullptr; + } + return &derivatives_[index + alphaindex * (1 << settings_.nrinvBitsTable()) + rinvindex]; +} + +int TrackDerTable::getIndex(unsigned int layermask, unsigned int diskmask) const { + assert(layermask < LayerMem_.size()); + + assert(diskmask < DiskMem_.size()); + + int layercode = LayerMem_[layermask]; + int diskcode = DiskMem_[diskmask]; + + if (diskcode < 0 || layercode < 0) { + if (settings_.warnNoDer()) { + edm::LogPrint("Tracklet") << "layermask diskmask : " << layermask << " " << diskmask; + } + return -1; + } + + assert(layercode >= 0); + assert(layercode < (1 << LayerMemBits_)); + assert(diskcode >= 0); + assert(diskcode < (1 << DiskMemBits_)); + + int layerdiskaddress = layercode + (diskcode << LayerMemBits_); + + assert(layerdiskaddress >= 0); + assert(layerdiskaddress < (1 << (LayerMemBits_ + DiskMemBits_))); + + int address = LayerDiskMem_[layerdiskaddress]; + + if (address < 0) { + if (settings_.warnNoDer()) { + edm::LogVerbatim("Tracklet") << "layermask diskmask : " << layermask << " " << diskmask; + } + return -1; + } + + assert(address >= 0); + assert(address < (1 << LayerDiskMemBits_)); + + return address; +} + +void TrackDerTable::addEntry(unsigned int layermask, unsigned int diskmask, int multiplicity, int nrinv) { + assert(multiplicity <= (1 << (3 * alphaBits_))); + + assert(layermask < (unsigned int)(1 << Nlay_)); + + assert(diskmask < (unsigned int)(1 << (2 * Ndisk_))); + + if (LayerMem_[layermask] == -1) { + LayerMem_[layermask] = nextLayerValue_++; + } + if (DiskMem_[diskmask] == -1) { + DiskMem_[diskmask] = nextDiskValue_++; + } + + int layercode = LayerMem_[layermask]; + int diskcode = DiskMem_[diskmask]; + + assert(layercode >= 0); + assert(layercode < (1 << LayerMemBits_)); + assert(diskcode >= 0); + assert(diskcode < (1 << DiskMemBits_)); + + int layerdiskaddress = layercode + (diskcode << LayerMemBits_); + + assert(layerdiskaddress >= 0); + assert(layerdiskaddress < (1 << (LayerMemBits_ + DiskMemBits_))); + + int address = LayerDiskMem_[layerdiskaddress]; + + if (address != -1) { + edm::LogPrint("Tracklet") << "Duplicate entry: layermask=" << layermask << " diskmaks=" << diskmask; + } + + assert(address == -1); + + LayerDiskMem_[layerdiskaddress] = nextLayerDiskValue_; + + nextLayerDiskValue_ += multiplicity * nrinv; + + lastMultiplicity_ = multiplicity * nrinv; + + for (int i = 0; i < multiplicity; i++) { + for (int irinv = 0; irinv < nrinv; irinv++) { + TrackDer tmp; + tmp.setIndex(layermask, diskmask, i, irinv); + derivatives_.push_back(tmp); + } + } +} + +void TrackDerTable::readPatternFile(std::string fileName) { + ifstream in(fileName.c_str()); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "reading fit pattern file " << fileName; + edm::LogVerbatim("Tracklet") << " flags (good/eof/fail/bad): " << in.good() << " " << in.eof() << " " << in.fail() + << " " << in.bad(); + } + + while (in.good()) { + std::string layerstr, diskstr; + int multiplicity; + + in >> layerstr >> diskstr >> multiplicity; + + //correct multiplicity if you dont want 3 bits of alpha. + if (alphaBits_ == 2) { + if (multiplicity == 8) + multiplicity = 4; + if (multiplicity == 64) + multiplicity = 16; + if (multiplicity == 512) + multiplicity = 64; + } + + if (alphaBits_ == 1) { + if (multiplicity == 8) + multiplicity = 2; + if (multiplicity == 64) + multiplicity = 4; + if (multiplicity == 512) + multiplicity = 8; + } + + if (!in.good()) + continue; + + char** tmpptr = nullptr; + + int layers = strtol(layerstr.c_str(), tmpptr, 2); + int disks = strtol(diskstr.c_str(), tmpptr, 2); + + addEntry(layers, disks, multiplicity, (1 << settings_.nrinvBitsTable())); + } +} + +void TrackDerTable::fillTable() { + int nentries = getEntries(); + + for (int i = 0; i < nentries; i++) { + TrackDer& der = derivatives_[i]; + int layermask = der.layerMask(); + int diskmask = der.diskMask(); + int alphamask = der.alphaMask(); + int irinv = der.irinv(); + + double rinv = (irinv - ((1 << (settings_.nrinvBitsTable() - 1)) - 0.5)) * settings_.rinvmax() / + (1 << (settings_.nrinvBitsTable() - 1)); + + bool print = false; + + if (print) { + edm::LogVerbatim("Tracklet") << "PRINT i " << i << " " << layermask << " " << diskmask << " " << alphamask << " " + << print; + } + + int nlayers = 0; + double r[N_LAYER]; + + for (unsigned l = 0; l < N_LAYER; l++) { + if (layermask & (1 << (N_LAYER - 1 - l))) { + r[nlayers] = settings_.rmean(l); + nlayers++; + } + } + + int ndisks = 0; + double z[N_DISK]; + double alpha[N_DISK]; + + double t = tpar(settings_, diskmask, layermask); + + for (unsigned d = 0; d < N_DISK; d++) { + if (diskmask & (3 << (2 * (N_DISK - 1 - d)))) { + z[ndisks] = settings_.zmean(d); + alpha[ndisks] = 0.0; + double r = settings_.zmean(d) / t; + double r2 = r * r; + if (diskmask & (1 << (2 * (N_DISK - 1 - d)))) { + if (alphaBits_ == 3) { + int ialpha = alphamask & 7; + alphamask = alphamask >> 3; + alpha[ndisks] = settings_.half2SmoduleWidth() * (ialpha - 3.5) / 4.0 / r2; + if (print) + edm::LogVerbatim("Tracklet") << "PRINT 3 alpha ialpha : " << alpha[ndisks] << " " << ialpha; + } + if (alphaBits_ == 2) { + int ialpha = alphamask & 3; + alphamask = alphamask >> 2; + alpha[ndisks] = settings_.half2SmoduleWidth() * (ialpha - 1.5) / 2.0 / r2; + } + if (alphaBits_ == 1) { + int ialpha = alphamask & 1; + alphamask = alphamask >> 1; + alpha[ndisks] = settings_.half2SmoduleWidth() * (ialpha - 0.5) / r2; + if (print) + edm::LogVerbatim("Tracklet") << "PRINT 1 alpha ialpha : " << alpha[ndisks] << " " << ialpha; + } + } + ndisks++; + } + } + + double D[N_FITPARAM][N_FITSTUB * 2]; + int iD[N_FITPARAM][N_FITSTUB * 2]; + double MinvDt[N_FITPARAM][N_FITSTUB * 2]; + double MinvDtDelta[N_FITPARAM][N_FITSTUB * 2]; + int iMinvDt[N_FITPARAM][N_FITSTUB * 2]; + double sigma[N_FITSTUB * 2]; + double kfactor[N_FITSTUB * 2]; + + if (print) { + edm::LogVerbatim("Tracklet") << "PRINT ndisks alpha[0] z[0] t: " << ndisks << " " << alpha[0] << " " << z[0] + << " " << t; + for (int iii = 0; iii < nlayers; iii++) { + edm::LogVerbatim("Tracklet") << "PRINT iii r: " << iii << " " << r[iii]; + } + } + + calculateDerivatives(settings_, nlayers, r, ndisks, z, alpha, t, rinv, D, iD, MinvDt, iMinvDt, sigma, kfactor); + + double delta = 0.1; + + for (int i = 0; i < nlayers; i++) { + if (r[i] > settings_.rPS2S()) + continue; + + r[i] += delta; + + calculateDerivatives( + settings_, nlayers, r, ndisks, z, alpha, t, rinv, D, iD, MinvDtDelta, iMinvDt, sigma, kfactor); + + for (int ii = 0; ii < nlayers; ii++) { + if (r[ii] > settings_.rPS2S()) + continue; + double tder = (MinvDtDelta[2][2 * ii + 1] - MinvDt[2][2 * ii + 1]) / delta; + int itder = (1 << (settings_.fittbitshift() + settings_.rcorrbits())) * tder * settings_.kr() * settings_.kz() / + settings_.ktpars(); + double zder = (MinvDtDelta[3][2 * ii + 1] - MinvDt[3][2 * ii + 1]) / delta; + int izder = (1 << (settings_.fitz0bitshift() + settings_.rcorrbits())) * zder * settings_.kr() * + settings_.kz() / settings_.kz0pars(); + der.settdzcorr(i, ii, tder); + der.setz0dzcorr(i, ii, zder); + der.setitdzcorr(i, ii, itder); + der.setiz0dzcorr(i, ii, izder); + } + + r[i] -= delta; + } + + if (print) { + edm::LogVerbatim("Tracklet") << "iMinvDt table build : " << iMinvDt[0][10] << " " << iMinvDt[1][10] << " " + << iMinvDt[2][10] << " " << iMinvDt[3][10] << " " << t << " " << nlayers << " " + << ndisks; + + std::string oss = "alpha :"; + for (int iii = 0; iii < ndisks; iii++) { + oss += " "; + oss += std::to_string(alpha[iii]); + } + edm::LogVerbatim("Tracklet") << oss; + oss = "z :"; + for (int iii = 0; iii < ndisks; iii++) { + oss += " "; + oss += std::to_string(z[iii]); + } + edm::LogVerbatim("Tracklet") << oss; + } + + if (print) { + edm::LogVerbatim("Tracklet") << "PRINT nlayers ndisks : " << nlayers << " " << ndisks; + } + + for (int j = 0; j < nlayers + ndisks; j++) { + der.settpar(t); + + //integer + assert(std::abs(iMinvDt[0][2 * j]) < (1 << 23)); + assert(std::abs(iMinvDt[0][2 * j + 1]) < (1 << 23)); + assert(std::abs(iMinvDt[1][2 * j]) < (1 << 23)); + assert(std::abs(iMinvDt[1][2 * j + 1]) < (1 << 23)); + assert(std::abs(iMinvDt[2][2 * j]) < (1 << 19)); + assert(std::abs(iMinvDt[2][2 * j + 1]) < (1 << 19)); + assert(std::abs(iMinvDt[3][2 * j]) < (1 << 19)); + assert(std::abs(iMinvDt[3][2 * j + 1]) < (1 << 19)); + + if (print) { + edm::LogVerbatim("Tracklet") << "PRINT i " << i << " " << j << " " << iMinvDt[1][2 * j] << " " + << std::abs(iMinvDt[1][2 * j]); + } + + der.setirinvdphi(j, iMinvDt[0][2 * j]); + der.setirinvdzordr(j, iMinvDt[0][2 * j + 1]); + der.setiphi0dphi(j, iMinvDt[1][2 * j]); + der.setiphi0dzordr(j, iMinvDt[1][2 * j + 1]); + der.setitdphi(j, iMinvDt[2][2 * j]); + der.setitdzordr(j, iMinvDt[2][2 * j + 1]); + der.setiz0dphi(j, iMinvDt[3][2 * j]); + der.setiz0dzordr(j, iMinvDt[3][2 * j + 1]); + //floating point + der.setrinvdphi(j, MinvDt[0][2 * j]); + der.setrinvdzordr(j, MinvDt[0][2 * j + 1]); + der.setphi0dphi(j, MinvDt[1][2 * j]); + der.setphi0dzordr(j, MinvDt[1][2 * j + 1]); + der.settdphi(j, MinvDt[2][2 * j]); + der.settdzordr(j, MinvDt[2][2 * j + 1]); + der.setz0dphi(j, MinvDt[3][2 * j]); + der.setz0dzordr(j, MinvDt[3][2 * j + 1]); + } + } + + if (settings_.writeTable()) { + ofstream outL("FitDerTableNew_LayerMem.txt"); + for (unsigned int i = 0; i < LayerMem_.size(); i++) { + FPGAWord tmp; + int tmp1 = LayerMem_[i]; + if (tmp1 < 0) + tmp1 = (1 << 6) - 1; + edm::LogVerbatim("Tracklet") << "i LayerMem_ : " << i << " " << tmp1; + tmp.set(tmp1, 6, true, __LINE__, __FILE__); + outL << tmp.str() << endl; + } + outL.close(); + + ofstream outD("FitDerTableNew_DiskMem.txt"); + for (int tmp1 : DiskMem_) { + if (tmp1 < 0) + tmp1 = (1 << 7) - 1; + FPGAWord tmp; + tmp.set(tmp1, 7, true, __LINE__, __FILE__); + outD << tmp.str() << endl; + } + outD.close(); + + ofstream outLD("FitDerTableNew_LayerDiskMem.txt"); + for (int tmp1 : LayerDiskMem_) { + if (tmp1 < 0) + tmp1 = (1 << 10) - 1; + FPGAWord tmp; + tmp.set(tmp1, 10, true, __LINE__, __FILE__); + outLD << tmp.str() << endl; + } + outLD.close(); + + unsigned int nderivatives = derivatives_.size(); + edm::LogVerbatim("Tracklet") << "nderivatives = " << nderivatives; + + const std::array seedings = {{"L1L2", "L3L4", "L5L6", "D1D2", "D3D4", "D1L1", "D1L2"}}; + const string prefix = "FitDerTableNew_"; + + // open files for derivative tables + ofstream outrinvdphi[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Rinvdphi_" + seedings[i] + ".txt"; + outrinvdphi[i].open(fname.c_str()); + } + + ofstream outrinvdzordr[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Rinvdzordr_" + seedings[i] + ".txt"; + outrinvdzordr[i].open(fname.c_str()); + } + + ofstream outphi0dphi[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Phi0dphi_" + seedings[i] + ".txt"; + outphi0dphi[i].open(fname.c_str()); + } + + ofstream outphi0dzordr[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Phi0dzordr_" + seedings[i] + ".txt"; + outphi0dzordr[i].open(fname.c_str()); + } + + ofstream outtdphi[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Tdphi_" + seedings[i] + ".txt"; + outtdphi[i].open(fname.c_str()); + } + + ofstream outtdzordr[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Tdzordr_" + seedings[i] + ".txt"; + outtdzordr[i].open(fname.c_str()); + } + + ofstream outz0dphi[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + const string fname = prefix + "Z0dphi_" + seedings[i] + ".txt"; + outz0dphi[i].open(fname.c_str()); + } + + ofstream outz0dzordr[N_TRKLSEED]; + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + string fname = prefix + "Z0dzordr_" + seedings[i] + ".txt"; + outz0dzordr[i].open(fname.c_str()); + } + + for (auto& der : derivatives_) { + unsigned int layerhits = der.layerMask(); // 6 bits layer hit pattern + unsigned int diskmask = der.diskMask(); // 10 bits disk hit pattern + unsigned int diskhits = 0; + if (diskmask & (3 << 8)) + diskhits += 16; + if (diskmask & (3 << 6)) + diskhits += 8; + if (diskmask & (3 << 4)) + diskhits += 4; + if (diskmask & (3 << 2)) + diskhits += 2; + if (diskmask & (3 << 0)) + diskhits += 1; + assert(diskhits < 32); // 5 bits + unsigned int hits = (layerhits << 5) + diskhits; // 11 bits hit pattern + assert(hits < 4096); + + // loop over all seedings + int i = 0; // seeding index + for (const string& seed : seedings) { + unsigned int iseed1 = 0; + unsigned int iseed2 = 0; + // check if the seeding is good for the current hit pattern + if (seed == "L1L2") { + iseed1 = 1; + iseed2 = 2; + } + if (seed == "L3L4") { + iseed1 = 3; + iseed2 = 4; + } + if (seed == "L5L6") { + iseed1 = 5; + iseed2 = 6; + } + if (seed == "D1D2") { + iseed1 = 7; + iseed2 = 8; + } + if (seed == "D3D4") { + iseed1 = 9; + iseed2 = 10; + } + if (seed == "D1L1") { + iseed1 = 7; + iseed2 = 1; + } + if (seed == "D1L2") { + iseed1 = 7; + iseed2 = 2; + } + + bool goodseed = (hits & (1 << (11 - iseed1))) and (hits & (1 << (11 - iseed2))); + + int itmprinvdphi[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmprinvdzordr[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmpphi0dphi[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmpphi0dzordr[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmptdphi[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmptdzordr[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmpz0dphi[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + int itmpz0dzordr[N_PROJ] = {9999999, 9999999, 9999999, 9999999}; + + // loop over bits in hit pattern + int ider = 0; + if (goodseed) { + for (unsigned int ihit = 1; ihit < N_FITSTUB * 2; ++ihit) { + // skip seeding layers + if (ihit == iseed1 or ihit == iseed2) { + ider++; + continue; + } + // skip if no hit + if (not(hits & (1 << (11 - ihit)))) + continue; + + int inputI = -1; + if (seed == "L1L2") { + if (ihit == 3 or ihit == 10) + inputI = 0; // L3 or D4 + if (ihit == 4 or ihit == 9) + inputI = 1; // L4 or D3 + if (ihit == 5 or ihit == 8) + inputI = 2; // L5 or D2 + if (ihit == 6 or ihit == 7) + inputI = 3; // L6 or D1 + } else if (seed == "L3L4") { + if (ihit == 1) + inputI = 0; // L1 + if (ihit == 2) + inputI = 1; // L2 + if (ihit == 5 or ihit == 8) + inputI = 2; // L5 or D2 + if (ihit == 6 or ihit == 7) + inputI = 3; // L6 or D1 + } else if (seed == "L5L6") { + if (ihit == 1) + inputI = 0; // L1 + if (ihit == 2) + inputI = 1; // L2 + if (ihit == 3) + inputI = 2; // L3 + if (ihit == 4) + inputI = 3; // L4 + } else if (seed == "D1D2") { + if (ihit == 1) + inputI = 0; // L1 + if (ihit == 9) + inputI = 1; // D3 + if (ihit == 10) + inputI = 2; // D4 + if (ihit == 2 or ihit == 11) + inputI = 3; // L2 or D5 + } else if (seed == "D3D4") { + if (ihit == 1) + inputI = 0; // L1 + if (ihit == 7) + inputI = 1; // D1 + if (ihit == 8) + inputI = 2; // D2 + if (ihit == 2 or ihit == 11) + inputI = 3; // L2 or D5 + } else if (seed == "D1L1" or "D1L2") { + if (ihit == 8) + inputI = 0; // D2 + if (ihit == 9) + inputI = 1; // D3 + if (ihit == 10) + inputI = 2; // D4 + if (ihit == 11) + inputI = 3; // D5 + } + if (inputI >= 0 and inputI < (int)N_PROJ) { + itmprinvdphi[inputI] = der.irinvdphi(ider); + itmprinvdzordr[inputI] = der.irinvdzordr(ider); + itmpphi0dphi[inputI] = der.iphi0dphi(ider); + itmpphi0dzordr[inputI] = der.iphi0dzordr(ider); + itmptdphi[inputI] = der.itdphi(ider); + itmptdzordr[inputI] = der.itdzordr(ider); + itmpz0dphi[inputI] = der.iz0dphi(ider); + itmpz0dzordr[inputI] = der.iz0dzordr(ider); + } + + ider++; + + } // for (unsigned int ihit = 1; ihit < 12; ++ihit) + } // if (goodseed) + + FPGAWord tmprinvdphi[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmprinvdphi[j] > (1 << 13)) + itmprinvdphi[j] = (1 << 13) - 1; + tmprinvdphi[j].set(itmprinvdphi[j], 14, false, __LINE__, __FILE__); + } + outrinvdphi[i] << tmprinvdphi[0].str() << tmprinvdphi[1].str() << tmprinvdphi[2].str() << tmprinvdphi[3].str() + << endl; + + FPGAWord tmprinvdzordr[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmprinvdzordr[j] > (1 << 15)) + itmprinvdzordr[j] = (1 << 15) - 1; + tmprinvdzordr[j].set(itmprinvdzordr[j], 16, false, __LINE__, __FILE__); + } + outrinvdzordr[i] << tmprinvdzordr[0].str() << tmprinvdzordr[1].str() << tmprinvdzordr[2].str() + << tmprinvdzordr[3].str() << endl; + + FPGAWord tmpphi0dphi[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmpphi0dphi[j] > (1 << 13)) + itmpphi0dphi[j] = (1 << 13) - 1; + tmpphi0dphi[j].set(itmpphi0dphi[j], 14, false, __LINE__, __FILE__); + } + outphi0dphi[i] << tmpphi0dphi[0].str() << tmpphi0dphi[1].str() << tmpphi0dphi[2].str() << tmpphi0dphi[3].str() + << endl; + + FPGAWord tmpphi0dzordr[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmpphi0dzordr[j] > (1 << 15)) + itmpphi0dzordr[j] = (1 << 15) - 1; + tmpphi0dzordr[j].set(itmpphi0dzordr[j], 16, false, __LINE__, __FILE__); + } + outphi0dzordr[i] << tmpphi0dzordr[0].str() << tmpphi0dzordr[1].str() << tmpphi0dzordr[2].str() + << tmpphi0dzordr[3].str() << endl; + + FPGAWord tmptdphi[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmptdphi[j] > (1 << 13)) + itmptdphi[j] = (1 << 13) - 1; + tmptdphi[j].set(itmptdphi[j], 14, false, __LINE__, __FILE__); + } + outtdphi[i] << tmptdphi[0].str() << tmptdphi[1].str() << tmptdphi[2].str() << tmptdphi[3].str() << endl; + + FPGAWord tmptdzordr[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmptdzordr[j] > (1 << 15)) + itmptdzordr[j] = (1 << 15) - 1; + tmptdzordr[j].set(itmptdzordr[j], 16, false, __LINE__, __FILE__); + } + outtdzordr[i] << tmptdzordr[0].str() << tmptdzordr[1].str() << tmptdzordr[2].str() << tmptdzordr[3].str() + << endl; + + FPGAWord tmpz0dphi[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmpz0dphi[j] > (1 << 13)) + itmpz0dphi[j] = (1 << 13) - 1; + tmpz0dphi[j].set(itmpz0dphi[j], 14, false, __LINE__, __FILE__); + } + outz0dphi[i] << tmpz0dphi[0].str() << tmpz0dphi[1].str() << tmpz0dphi[2].str() << tmpz0dphi[3].str() << endl; + + FPGAWord tmpz0dzordr[N_PROJ]; + for (unsigned int j = 0; j < N_PROJ; ++j) { + if (itmpz0dzordr[j] > (1 << 15)) + itmpz0dzordr[j] = (1 << 15) - 1; + tmpz0dzordr[j].set(itmpz0dzordr[j], 16, false, __LINE__, __FILE__); + } + outz0dzordr[i] << tmpz0dzordr[0].str() << tmpz0dzordr[1].str() << tmpz0dzordr[2].str() << tmpz0dzordr[3].str() + << endl; + + i++; + } // for (const string & seed : seedings) + + } // for (auto & der : derivatives_) + + // close files + for (unsigned int i = 0; i < N_TRKLSEED; ++i) { + outrinvdphi[i].close(); + outrinvdzordr[i].close(); + outphi0dphi[i].close(); + outphi0dzordr[i].close(); + outtdphi[i].close(); + outtdzordr[i].close(); + outz0dphi[i].close(); + outz0dzordr[i].close(); + } + + } // if (writeFitDerTable) +} + +void TrackDerTable::invert(double M[4][8], unsigned int n) { + assert(n <= 4); + + unsigned int i, j, k; + double ratio, a; + + for (i = 0; i < n; i++) { + for (j = n; j < 2 * n; j++) { + if (i == (j - n)) + M[i][j] = 1.0; + else + M[i][j] = 0.0; + } + } + + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if (i != j) { + ratio = M[j][i] / M[i][i]; + for (k = 0; k < 2 * n; k++) { + M[j][k] -= ratio * M[i][k]; + } + } + } + } + + for (i = 0; i < n; i++) { + a = M[i][i]; + for (j = 0; j < 2 * n; j++) { + M[i][j] /= a; + } + } +} + +void TrackDerTable::invert(std::vector >& M, unsigned int n) { + assert(M.size() == n); + assert(M[0].size() == 2 * n); + + unsigned int i, j, k; + double ratio, a; + + for (i = 0; i < n; i++) { + for (j = n; j < 2 * n; j++) { + if (i == (j - n)) + M[i][j] = 1.0; + else + M[i][j] = 0.0; + } + } + + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if (i != j) { + ratio = M[j][i] / M[i][i]; + for (k = 0; k < 2 * n; k++) { + M[j][k] -= ratio * M[i][k]; + } + } + } + } + + for (i = 0; i < n; i++) { + a = M[i][i]; + for (j = 0; j < 2 * n; j++) { + M[i][j] /= a; + } + } +} + +void TrackDerTable::calculateDerivatives(Settings const& settings, + unsigned int nlayers, + double r[N_LAYER], + unsigned int ndisks, + double z[N_DISK], + double alpha[N_DISK], + double t, + double rinv, + double D[N_FITPARAM][N_FITSTUB * 2], + int iD[N_FITPARAM][N_FITSTUB * 2], + double MinvDt[N_FITPARAM][N_FITSTUB * 2], + int iMinvDt[N_FITPARAM][N_FITSTUB * 2], + double sigma[N_FITSTUB * 2], + double kfactor[N_FITSTUB * 2]) { + double sigmax = settings.stripPitch(true) / sqrt(12.0); + double sigmaz = settings.stripLength(true) / sqrt(12.0); + double sigmaz2 = settings.stripLength(false) / sqrt(12.0); + + double sigmazpsbarrel = sigmaz; //This is a bit of a hack - these weights should be properly determined + if (std::abs(t) > 2.0) + sigmazpsbarrel = sigmaz * std::abs(t) / 2.0; + if (std::abs(t) > 3.8) + sigmazpsbarrel = sigmaz * std::abs(t); + + double sigmax2sdisk = settings.stripPitch(false) / sqrt(12.0); + double sigmaz2sdisk = settings.stripLength(false) / sqrt(12.0); + + double sigmaxpsdisk = settings.stripPitch(true) / sqrt(12.0); + double sigmazpsdisk = settings.stripLength(true) / sqrt(12.0); + + unsigned int n = nlayers + ndisks; + + assert(n <= N_FITSTUB); + + double rnew[N_FITSTUB]; + + int j = 0; + + //here we handle a barrel hit + for (unsigned int i = 0; i < nlayers; i++) { + double ri = r[i]; + + rnew[i] = ri; + + //first we have the phi position + D[0][j] = -0.5 * ri * ri / sqrt(1 - 0.25 * ri * ri * rinv * rinv) / sigmax; + D[1][j] = ri / sigmax; + D[2][j] = 0.0; + D[3][j] = 0.0; + sigma[j] = sigmax; + kfactor[j] = settings.kphi1(); + j++; + //second the z position + D[0][j] = 0.0; + D[1][j] = 0.0; + if (ri < settings.rPS2S()) { + D[2][j] = (2 / rinv) * asin(0.5 * ri * rinv) / sigmazpsbarrel; + D[3][j] = 1.0 / sigmazpsbarrel; + sigma[j] = sigmazpsbarrel; + kfactor[j] = settings.kz(); + } else { + D[2][j] = (2 / rinv) * asin(0.5 * ri * rinv) / sigmaz2; + D[3][j] = 1.0 / sigmaz2; + sigma[j] = sigmaz2; + kfactor[j] = settings.kz(); + } + + j++; + } + + for (unsigned int i = 0; i < ndisks; i++) { + double zi = z[i]; + + double z0 = 0.0; + + double rmultiplier = alpha[i] * zi / t; + + double phimultiplier = zi / t; + + double drdrinv = -2.0 * sin(0.5 * rinv * (zi - z0) / t) / (rinv * rinv) + + (zi - z0) * cos(0.5 * rinv * (zi - z0) / t) / (rinv * t); + double drdphi0 = 0; + double drdt = -(zi - z0) * cos(0.5 * rinv * (zi - z0) / t) / (t * t); + double drdz0 = -cos(0.5 * rinv * (zi - z0) / t) / t; + + double dphidrinv = -0.5 * (zi - z0) / t; + double dphidphi0 = 1.0; + double dphidt = 0.5 * rinv * (zi - z0) / (t * t); + double dphidz0 = 0.5 * rinv / t; + + double r = (zi - z0) / t; + + rnew[i + nlayers] = r; + + sigma[j] = sigmax2sdisk; + if (std::abs(alpha[i]) < 1e-10) { + sigma[j] = sigmaxpsdisk; + } + + D[0][j] = (phimultiplier * dphidrinv + rmultiplier * drdrinv) / sigma[j]; + D[1][j] = (phimultiplier * dphidphi0 + rmultiplier * drdphi0) / sigma[j]; + D[2][j] = (phimultiplier * dphidt + rmultiplier * drdt) / sigma[j]; + D[3][j] = (phimultiplier * dphidz0 + rmultiplier * drdz0) / sigma[j]; + kfactor[j] = settings.kphi(); + + j++; + + if (std::abs(alpha[i]) < 1e-10) { + D[0][j] = drdrinv / sigmazpsdisk; + D[1][j] = drdphi0 / sigmazpsdisk; + D[2][j] = drdt / sigmazpsdisk; + D[3][j] = drdz0 / sigmazpsdisk; + sigma[j] = sigmazpsdisk; + kfactor[j] = settings.kr(); + } else { + D[0][j] = drdrinv / sigmaz2sdisk; + D[1][j] = drdphi0 / sigmaz2sdisk; + D[2][j] = drdt / sigmaz2sdisk; + D[3][j] = drdz0 / sigmaz2sdisk; + sigma[j] = sigmaz2sdisk; + kfactor[j] = settings.kr(); + } + + j++; + } + + double M[4][8]; + + for (unsigned int i1 = 0; i1 < 4; i1++) { + for (unsigned int i2 = 0; i2 < 4; i2++) { + M[i1][i2] = 0.0; + for (unsigned int j = 0; j < 2 * n; j++) { + M[i1][i2] += D[i1][j] * D[i2][j]; + } + } + } + + invert(M, 4); + + for (unsigned int j = 0; j < N_FITSTUB * 2; j++) { + for (unsigned int i1 = 0; i1 < N_FITPARAM; i1++) { + MinvDt[i1][j] = 0.0; + iMinvDt[i1][j] = 0; + } + } + + for (unsigned int j = 0; j < 2 * n; j++) { + for (unsigned int i1 = 0; i1 < 4; i1++) { + for (unsigned int i2 = 0; i2 < 4; i2++) { + MinvDt[i1][j] += M[i1][i2 + 4] * D[i2][j]; + } + } + } + + for (unsigned int i = 0; i < n; i++) { + iD[0][2 * i] = + D[0][2 * i] * (1 << settings.chisqphifactbits()) * settings.krinvpars() / (1 << settings.fitrinvbitshift()); + iD[1][2 * i] = + D[1][2 * i] * (1 << settings.chisqphifactbits()) * settings.kphi0pars() / (1 << settings.fitphi0bitshift()); + iD[2][2 * i] = + D[2][2 * i] * (1 << settings.chisqphifactbits()) * settings.ktpars() / (1 << settings.fittbitshift()); + iD[3][2 * i] = + D[3][2 * i] * (1 << settings.chisqphifactbits()) * settings.kz0pars() / (1 << settings.fitz0bitshift()); + + iD[0][2 * i + 1] = + D[0][2 * i + 1] * (1 << settings.chisqzfactbits()) * settings.krinvpars() / (1 << settings.fitrinvbitshift()); + iD[1][2 * i + 1] = + D[1][2 * i + 1] * (1 << settings.chisqzfactbits()) * settings.kphi0pars() / (1 << settings.fitphi0bitshift()); + iD[2][2 * i + 1] = + D[2][2 * i + 1] * (1 << settings.chisqzfactbits()) * settings.ktpars() / (1 << settings.fittbitshift()); + iD[3][2 * i + 1] = + D[3][2 * i + 1] * (1 << settings.chisqzfactbits()) * settings.kz0pars() / (1 << settings.fitz0bitshift()); + + //First the barrel + if (i < nlayers) { + MinvDt[0][2 * i] *= rnew[i] / sigmax; + MinvDt[1][2 * i] *= rnew[i] / sigmax; + MinvDt[2][2 * i] *= rnew[i] / sigmax; + MinvDt[3][2 * i] *= rnew[i] / sigmax; + + iMinvDt[0][2 * i] = + (1 << settings.fitrinvbitshift()) * MinvDt[0][2 * i] * settings.kphi1() / settings.krinvpars(); + iMinvDt[1][2 * i] = + (1 << settings.fitphi0bitshift()) * MinvDt[1][2 * i] * settings.kphi1() / settings.kphi0pars(); + iMinvDt[2][2 * i] = (1 << settings.fittbitshift()) * MinvDt[2][2 * i] * settings.kphi1() / settings.ktpars(); + iMinvDt[3][2 * i] = (1 << settings.fitz0bitshift()) * MinvDt[3][2 * i] * settings.kphi1() / settings.kz0pars(); + + if (rnew[i] < settings.rPS2S()) { + MinvDt[0][2 * i + 1] /= sigmazpsbarrel; + MinvDt[1][2 * i + 1] /= sigmazpsbarrel; + MinvDt[2][2 * i + 1] /= sigmazpsbarrel; + MinvDt[3][2 * i + 1] /= sigmazpsbarrel; + + iMinvDt[0][2 * i + 1] = + (1 << settings.fitrinvbitshift()) * MinvDt[0][2 * i + 1] * settings.kz() / settings.krinvpars(); + iMinvDt[1][2 * i + 1] = + (1 << settings.fitphi0bitshift()) * MinvDt[1][2 * i + 1] * settings.kz() / settings.kphi0pars(); + iMinvDt[2][2 * i + 1] = + (1 << settings.fittbitshift()) * MinvDt[2][2 * i + 1] * settings.kz() / settings.ktpars(); + iMinvDt[3][2 * i + 1] = + (1 << settings.fitz0bitshift()) * MinvDt[3][2 * i + 1] * settings.kz() / settings.kz0pars(); + } else { + MinvDt[0][2 * i + 1] /= sigmaz2; + MinvDt[1][2 * i + 1] /= sigmaz2; + MinvDt[2][2 * i + 1] /= sigmaz2; + MinvDt[3][2 * i + 1] /= sigmaz2; + + int fact = (1 << (settings.nzbitsstub(0) - settings.nzbitsstub(5))); + + iMinvDt[0][2 * i + 1] = + (1 << settings.fitrinvbitshift()) * MinvDt[0][2 * i + 1] * fact * settings.kz() / settings.krinvpars(); + iMinvDt[1][2 * i + 1] = + (1 << settings.fitphi0bitshift()) * MinvDt[1][2 * i + 1] * fact * settings.kz() / settings.kphi0pars(); + iMinvDt[2][2 * i + 1] = + (1 << settings.fittbitshift()) * MinvDt[2][2 * i + 1] * fact * settings.kz() / settings.ktpars(); + iMinvDt[3][2 * i + 1] = + (1 << settings.fitz0bitshift()) * MinvDt[3][2 * i + 1] * fact * settings.kz() / settings.kz0pars(); + } + } + + //Secondly the disks + else { + double denom = (std::abs(alpha[i - nlayers]) < 1e-10) ? sigmaxpsdisk : sigmax2sdisk; + + MinvDt[0][2 * i] *= (rnew[i] / denom); + MinvDt[1][2 * i] *= (rnew[i] / denom); + MinvDt[2][2 * i] *= (rnew[i] / denom); + MinvDt[3][2 * i] *= (rnew[i] / denom); + + assert(MinvDt[0][2 * i] == MinvDt[0][2 * i]); + + iMinvDt[0][2 * i] = (1 << settings.fitrinvbitshift()) * MinvDt[0][2 * i] * settings.kphi() / settings.krinvpars(); + iMinvDt[1][2 * i] = (1 << settings.fitphi0bitshift()) * MinvDt[1][2 * i] * settings.kphi() / settings.kphi0pars(); + iMinvDt[2][2 * i] = (1 << settings.fittbitshift()) * MinvDt[2][2 * i] * settings.kphi() / settings.ktpars(); + iMinvDt[3][2 * i] = (1 << settings.fitz0bitshift()) * MinvDt[3][2 * i] * settings.kphi() / settings.kz(); + + denom = (std::abs(alpha[i - nlayers]) < 1e-10) ? sigmazpsdisk : sigmaz2sdisk; + + MinvDt[0][2 * i + 1] /= denom; + MinvDt[1][2 * i + 1] /= denom; + MinvDt[2][2 * i + 1] /= denom; + MinvDt[3][2 * i + 1] /= denom; + + iMinvDt[0][2 * i + 1] = + (1 << settings.fitrinvbitshift()) * MinvDt[0][2 * i + 1] * settings.krprojshiftdisk() / settings.krinvpars(); + iMinvDt[1][2 * i + 1] = + (1 << settings.fitphi0bitshift()) * MinvDt[1][2 * i + 1] * settings.krprojshiftdisk() / settings.kphi0pars(); + iMinvDt[2][2 * i + 1] = + (1 << settings.fittbitshift()) * MinvDt[2][2 * i + 1] * settings.krprojshiftdisk() / settings.ktpars(); + iMinvDt[3][2 * i + 1] = + (1 << settings.fitz0bitshift()) * MinvDt[3][2 * i + 1] * settings.krprojshiftdisk() / settings.kz(); + } + } +} + +double TrackDerTable::tpar(Settings const& settings, int diskmask, int layermask) { + if (diskmask == 0) + return 0.0; + + double tmax = 1000.0; + double tmin = 0.0; + + for (int d = 1; d <= (int)N_DISK; d++) { + if (diskmask & (1 << (2 * (5 - d) + 1))) { //PS hit + double dmax = settings.zmean(d - 1) / 22.0; + if (dmax > sinh(2.4)) + dmax = sinh(2.4); + double dmin = settings.zmean(d - 1) / 65.0; + if (dmax < tmax) + tmax = dmax; + if (dmin > tmin) + tmin = dmin; + } + + if (diskmask & (1 << (2 * (5 - d)))) { //2S hit + double dmax = settings.zmean(d - 1) / 65.0; + double dmin = settings.zmean(d - 1) / 105.0; + if (dmax < tmax) + tmax = dmax; + if (dmin > tmin) + tmin = dmin; + } + } + + for (int l = 1; l <= (int)N_LAYER; l++) { + if (layermask & (1 << (6 - l))) { + double lmax = settings.zlength() / settings.rmean(l - 1); + if (lmax < tmax) + tmax = lmax; + } + } + + return 0.5 * (tmax + tmin) * 1.07; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackFitMemory.cc b/L1Trigger/TrackFindingTracklet/src/TrackFitMemory.cc new file mode 100644 index 0000000000000..83f046180274d --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackFitMemory.cc @@ -0,0 +1,43 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackFitMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include + +using namespace std; +using namespace trklet; + +TrackFitMemory::TrackFitMemory(string name, Settings const& settings, unsigned int iSector, double phimin, double phimax) + : MemoryBase(name, settings, iSector) { + phimin_ = phimin; + phimax_ = phimax; +} + +void TrackFitMemory::writeTF(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/FitTrack/TrackFit_" << getName() << "_" << std::setfill('0') << std::setw(2) + << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < tracks_.size(); j++) { + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec << " "; + out_ << tracks_[j]->trackfitstr() << " " << trklet::hexFormat(tracks_[j]->trackfitstr()); + out_ << "\n"; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/Tracklet.cc b/L1Trigger/TrackFindingTracklet/src/Tracklet.cc new file mode 100644 index 0000000000000..addae6dc69618 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/Tracklet.cc @@ -0,0 +1,903 @@ +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Track.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include + +using namespace std; +using namespace trklet; + +Tracklet::Tracklet(Settings const& settings, + const L1TStub* innerStub, + const L1TStub* middleStub, + const L1TStub* outerStub, + const Stub* innerFPGAStub, + const Stub* middleFPGAStub, + const Stub* outerFPGAStub, + double rinv, + double phi0, + double d0, + double z0, + double t, + double rinvapprox, + double phi0approx, + double d0approx, + double z0approx, + double tapprox, + int irinv, + int iphi0, + int id0, + int iz0, + int it, + LayerProjection layerprojs[N_PROJ], + DiskProjection diskprojs[N_PROJ], + bool disk, + bool overlap) + : settings_(settings) { + overlap_ = overlap; + disk_ = disk; + assert(!(disk && overlap)); + barrel_ = (!disk) && (!overlap); + triplet_ = false; + + trackletIndex_ = -1; + TCIndex_ = -1; + + assert(disk_ || barrel_ || overlap_); + + if (barrel_ && middleStub == nullptr) + assert(innerStub->layer() < N_LAYER); + + innerStub_ = innerStub; + middleStub_ = middleStub; + outerStub_ = outerStub; + innerFPGAStub_ = innerFPGAStub; + middleFPGAStub_ = middleFPGAStub; + outerFPGAStub_ = outerFPGAStub; + + trackpars_.init(rinv, phi0, d0, t, z0); + + trackparsapprox_.init(rinvapprox, phi0approx, d0approx, tapprox, z0approx); + + fpgapars_.rinv().set(irinv, settings_.nbitsrinv(), false, __LINE__, __FILE__); + fpgapars_.phi0().set(iphi0, settings_.nbitsphi0(), false, __LINE__, __FILE__); + fpgapars_.d0().set(id0, settings_.nbitsd0(), false, __LINE__, __FILE__); + fpgapars_.z0().set(iz0, settings_.nbitsz0(), false, __LINE__, __FILE__); + fpgapars_.t().set(it, settings_.nbitst(), false, __LINE__, __FILE__); + + fpgatrack_ = nullptr; + + if (innerStub_) + assert(innerStub_->layer() < N_LAYER || innerStub_->disk() < N_DISK); + if (middleStub_) + assert(middleStub_->layer() < N_LAYER || middleStub_->disk() < N_DISK); + if (outerStub_) + assert(outerStub_->layer() < N_LAYER || outerStub_->disk() < N_DISK); + + seedIndex_ = calcSeedIndex(); + + triplet_ = (seedIndex_ >= 8); + + //fill projection layers + for (unsigned int i = 0; i < N_LAYER - 2; i++) { + projlayer_[i] = settings.projlayers(seedIndex_, i); + } + + //fill projection disks + for (unsigned int i = 0; i < N_DISK; i++) { + projdisk_[i] = settings.projdisks(seedIndex_, i); + } + + //Handle projections to the layers + for (unsigned int i = 0; i < N_LAYER - 2; i++) { + if (projlayer_[i] == 0) + continue; + if (!layerprojs[i].valid()) + continue; + + layerproj_[projlayer_[i] - 1] = layerprojs[i]; + } + //Now handle projections to the disks + for (unsigned int i = 0; i < N_DISK; i++) { + if (projdisk_[i] == 0) + continue; + if (!diskprojs[i].valid()) + continue; + + diskproj_[projdisk_[i] - 1] = diskprojs[i]; + } + + ichisqrphifit_.set(-1, 8, false); + ichisqrzfit_.set(-1, 8, false); +} + +int Tracklet::tpseed() { + set tpset; + + set tpsetstubinner; + set tpsetstubouter; + + vector tps = innerStub_->tps(); + for (auto tp : tps) { + if (tp != 0) { + tpsetstubinner.insert(tp); + tpset.insert(abs(tp)); + } + } + + tps = outerStub_->tps(); + for (auto tp : tps) { + if (tp != 0) { + tpsetstubouter.insert(tp); + tpset.insert(abs(tp)); + } + } + + for (auto& tp : tpset) { + if (tpsetstubinner.find(tp) != tpsetstubinner.end() && tpsetstubinner.find(-tp) != tpsetstubinner.end() && + tpsetstubouter.find(tp) != tpsetstubouter.end() && tpsetstubouter.find(-tp) != tpsetstubouter.end()) { + return tp; + } + } + return 0; +} + +bool Tracklet::stubtruthmatch(const L1TStub* stub) { + set tpset; + set tpsetstub; + set tpsetstubinner; + set tpsetstubouter; + + vector tps = stub->tps(); + for (auto tp : tps) { + if (tp != 0) { + tpsetstub.insert(tp); + tpset.insert(abs(tp)); + } + } + tps = innerStub_->tps(); + for (auto tp : tps) { + if (tp != 0) { + tpsetstubinner.insert(tp); + tpset.insert(abs(tp)); + } + } + tps = outerStub_->tps(); + for (auto tp : tps) { + if (tp != 0) { + tpsetstubouter.insert(tp); + tpset.insert(abs(tp)); + } + } + + for (auto tp : tpset) { + if (tpsetstub.find(tp) != tpsetstub.end() && tpsetstub.find(-tp) != tpsetstub.end() && + tpsetstubinner.find(tp) != tpsetstubinner.end() && tpsetstubinner.find(-tp) != tpsetstubinner.end() && + tpsetstubouter.find(tp) != tpsetstubouter.end() && tpsetstubouter.find(-tp) != tpsetstubouter.end()) { + return true; + } + } + + return false; +} + +std::string Tracklet::addressstr() { + std::string str; + str = innerFPGAStub_->phiregionaddressstr() + "|"; + if (middleFPGAStub_) { + str += middleFPGAStub_->phiregionaddressstr() + "|"; + } + str += outerFPGAStub_->phiregionaddressstr(); + + return str; +} + +std::string Tracklet::trackletparstr() { + if (settings_.writeoutReal()) { + std::string oss = std::to_string(fpgapars_.rinv().value() * settings_.krinvpars()) + " " + + std::to_string(fpgapars_.phi0().value() * settings_.kphi0pars()) + " " + + std::to_string(fpgapars_.d0().value() * settings_.kd0pars()) + " " + + std::to_string(fpgapars_.z0().value() * settings_.kz()) + " " + + std::to_string(fpgapars_.t().value() * settings_.ktpars()); + return oss; + } else { + std::string str = innerFPGAStub_->stubindex().str() + "|"; + if (middleFPGAStub_) { + str += middleFPGAStub_->stubindex().str() + "|"; + } + str += outerFPGAStub_->stubindex().str() + "|" + fpgapars_.rinv().str() + "|" + fpgapars_.phi0().str() + "|"; + if (middleFPGAStub_) + str += fpgapars_.d0().str() + "|"; + str += fpgapars_.z0().str() + "|" + fpgapars_.t().str(); + return str; + } +} + +std::string Tracklet::vmstrlayer(int layer, unsigned int allstubindex) { + FPGAWord index; + if (allstubindex >= (1 << 7)) { + edm::LogPrint("Tracklet") << "Warning projection number too large!"; + index.set((1 << 7) - 1, 7, true, __LINE__, __FILE__); + } else { + index.set(allstubindex, 7, true, __LINE__, __FILE__); + } + + // This is a shortcut. + //int irinvvm=16+(fpgarinv().value()>>(fpgarinv().nbits()-5)); + // rinv is not directly available in the TrackletProjection. + // can be inferred from phi derivative: rinv = - phider * 2 + int tmp_irinv = layerproj_[layer - 1].fpgaphiprojder().value() * (-2); + int nbits_irinv = layerproj_[layer - 1].fpgaphiprojder().nbits() + 1; + + // irinv in VMProjection: + // top 5 bits of rinv and shifted to be positive + int irinvvm = 16 + (tmp_irinv >> (nbits_irinv - 5)); + + if (settings_.extended() && (irinvvm > 31)) { //TODO - displaced tracking should protect against this + edm::LogPrint("Tracklet") << "Warning irinvvm too large:" << irinvvm; + irinvvm = 31; + } + + assert(irinvvm >= 0); + assert(irinvvm < 32); + FPGAWord tmp; + tmp.set(irinvvm, 5, true, __LINE__, __FILE__); + std::string oss = index.str() + "|" + layerproj_[layer - 1].fpgazbin1projvm().str() + "|" + + layerproj_[layer - 1].fpgazbin2projvm().str() + "|" + layerproj_[layer - 1].fpgafinezvm().str() + + "|" + tmp.str() + "|" + std::to_string(PSseed()); + return oss; +} + +std::string Tracklet::vmstrdisk(int disk, unsigned int allstubindex) { + FPGAWord index; + if (allstubindex >= (1 << 7)) { + edm::LogPrint("Tracklet") << "Warning projection number too large!"; + index.set((1 << 7) - 1, 7, true, __LINE__, __FILE__); + } else { + index.set(allstubindex, 7, true, __LINE__, __FILE__); + } + std::string oss = index.str() + "|" + diskproj_[disk - 1].fpgarbin1projvm().str() + "|" + + diskproj_[disk - 1].fpgarbin2projvm().str() + "|" + diskproj_[disk - 1].fpgafinervm().str() + "|" + + diskproj_[disk - 1].getBendIndex().str(); + return oss; +} + +std::string Tracklet::trackletprojstr(int layer) const { + assert(layer > 0 && layer <= N_LAYER); + FPGAWord tmp; + if (trackletIndex_ < 0 || trackletIndex_ > (int)settings_.ntrackletmax()) { + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " trackletIndex_ = " << trackletIndex_; + } + tmp.set(trackletIndex_, 7, true, __LINE__, __FILE__); + FPGAWord tcid; + if (settings_.extended()) { + tcid.set(TCIndex_, 8, true, __LINE__, __FILE__); + } else { + tcid.set(TCIndex_, 7, true, __LINE__, __FILE__); + } + + std::string oss = tcid.str() + "|" + tmp.str() + "|" + layerproj_[layer - 1].fpgaphiproj().str() + "|" + + layerproj_[layer - 1].fpgazproj().str() + "|" + layerproj_[layer - 1].fpgaphiprojder().str() + "|" + + layerproj_[layer - 1].fpgazprojder().str(); + return oss; +} + +std::string Tracklet::trackletprojstrD(int disk) const { + assert(abs(disk) <= N_DISK); + FPGAWord tmp; + if (trackletIndex_ < 0 || trackletIndex_ > (int)settings_.ntrackletmax()) { + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " trackletIndex_ = " << trackletIndex_; + } + tmp.set(trackletIndex_, 7, true, __LINE__, __FILE__); + FPGAWord tcid; + if (settings_.extended()) { + tcid.set(TCIndex_, 8, true, __LINE__, __FILE__); + } else { + tcid.set(TCIndex_, 7, true, __LINE__, __FILE__); + } + std::string oss = tcid.str() + "|" + tmp.str() + "|" + diskproj_[abs(disk) - 1].fpgaphiproj().str() + "|" + + diskproj_[abs(disk) - 1].fpgarproj().str() + "|" + diskproj_[abs(disk) - 1].fpgaphiprojder().str() + + "|" + diskproj_[abs(disk) - 1].fpgarprojder().str(); + return oss; +} + +void Tracklet::addMatch(int layer, + int ideltaphi, + int ideltaz, + double dphi, + double dz, + double dphiapprox, + double dzapprox, + int stubid, + double rstub, + const trklet::Stub* stubptr) { + assert(layer > 0 && layer <= N_LAYER); + layerresid_[layer - 1].init( + settings_, layer, ideltaphi, ideltaz, stubid, dphi, dz, dphiapprox, dzapprox, rstub, stubptr); +} + +void Tracklet::addMatchDisk(int disk, + int ideltaphi, + int ideltar, + double dphi, + double dr, + double dphiapprox, + double drapprox, + double alpha, + int stubid, + double zstub, + const trklet::Stub* stubptr) { + assert(abs(disk) <= N_DISK); + diskresid_[abs(disk) - 1].init(settings_, + disk, + ideltaphi, + ideltar, + stubid, + dphi, + dr, + dphiapprox, + drapprox, + zstub, + alpha, + stubptr->alphanew(), + stubptr); +} + +int Tracklet::nMatches() { + int nmatches = 0; + + for (const auto& ilayerresid : layerresid_) { + if (ilayerresid.valid()) { + nmatches++; + } + } + + return nmatches; +} + +int Tracklet::nMatchesDisk() { + int nmatches = 0; + + for (const auto& idiskresid : diskresid_) { + if (idiskresid.valid()) { + nmatches++; + } + } + return nmatches; +} + +std::string Tracklet::fullmatchstr(int layer) { + assert(layer > 0 && layer <= N_LAYER); + + FPGAWord tmp; + if (trackletIndex_ < 0 || trackletIndex_ > (int)settings_.ntrackletmax()) { + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " trackletIndex_ = " << trackletIndex_; + } + tmp.set(trackletIndex_, 7, true, __LINE__, __FILE__); + FPGAWord tcid; + if (settings_.extended()) { + tcid.set(TCIndex_, 8, true, __LINE__, __FILE__); + } else { + tcid.set(TCIndex_, 7, true, __LINE__, __FILE__); + } + std::string oss = tcid.str() + "|" + tmp.str() + "|" + layerresid_[layer - 1].fpgastubid().str() + "|" + + layerresid_[layer - 1].fpgaphiresid().str() + "|" + layerresid_[layer - 1].fpgazresid().str(); + return oss; +} + +std::string Tracklet::fullmatchdiskstr(int disk) { + assert(disk > 0 && disk <= N_DISK); + + FPGAWord tmp; + if (trackletIndex_ < 0 || trackletIndex_ > (int)settings_.ntrackletmax()) { + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " trackletIndex_ = " << trackletIndex_; + } + tmp.set(trackletIndex_, 7, true, __LINE__, __FILE__); + FPGAWord tcid; + if (settings_.extended()) { + tcid.set(TCIndex_, 8, true, __LINE__, __FILE__); + } else { + tcid.set(TCIndex_, 7, true, __LINE__, __FILE__); + } + std::string oss = tcid.str() + "|" + tmp.str() + "|" + diskresid_[disk - 1].fpgastubid().str() + "|" + + diskresid_[disk - 1].fpgaphiresid().str() + "|" + diskresid_[disk - 1].fpgarresid().str(); + return oss; +} + +std::vector Tracklet::getL1Stubs() { + std::vector tmp; + + if (innerStub_) + tmp.push_back(innerStub_); + if (middleStub_) + tmp.push_back(middleStub_); + if (outerStub_) + tmp.push_back(outerStub_); + + for (const auto& ilayerresid : layerresid_) { + if (ilayerresid.valid()) + tmp.push_back(ilayerresid.stubptr()->l1tstub()); + } + + for (const auto& idiskresid : diskresid_) { + if (idiskresid.valid()) + tmp.push_back(idiskresid.stubptr()->l1tstub()); + } + + return tmp; +} + +std::map Tracklet::getStubIDs() { + std::map stubIDs; + + // For future reference, *resid_[i] uses i as the absolute stub index. (0-5 for barrel, 0-4 for disk) + // On the other hand, proj*_[i] uses i almost like *resid_[i], except the *seeding* layer indices are removed entirely. + // E.g. An L3L4 track has 0=L1, 1=L2, 2=L4, 3=L5 for the barrels (for proj*_[i]) + + if (innerFPGAStub_) + assert(innerFPGAStub_->stubindex().nbits() == 7); + if (middleFPGAStub_) + assert(middleFPGAStub_->stubindex().nbits() == 7); + if (outerFPGAStub_) + assert(outerFPGAStub_->stubindex().nbits() == 7); + + if (barrel_) { + for (int i = 0; i < N_LAYER; i++) { + //check barrel + if (layerresid_[i].valid()) { + // two extra bits to indicate if the matched stub is local or from neighbor + int location = 1; // local + location <<= layerresid_[i].fpgastubid().nbits(); + + stubIDs[1 + i] = layerresid_[i].fpgastubid().value() + location; + } + + //check disk + if (i >= N_DISK) + continue; //i=[0..4] for disks + if (diskresid_[i].valid()) { + if (i == 3 && layerresid_[0].valid() && innerFPGAStub_->layer().value() == 1) + continue; // Don't add D4 if track has L1 stub + // two extra bits to indicate if the matched stub is local or from neighbor + int location = 1; // local + location <<= diskresid_[i].fpgastubid().nbits(); + + if (itfit().value() < 0) { + stubIDs[-11 - i] = diskresid_[i].fpgastubid().value() + location; + } else { + stubIDs[11 + i] = diskresid_[i].fpgastubid().value() + location; + } + } + } + + //get stubs making up tracklet + if (innerFPGAStub_) + stubIDs[innerFPGAStub_->layer().value() + 1] = innerFPGAStub_->phiregionaddress() + (1 << 10); + if (middleFPGAStub_) + stubIDs[middleFPGAStub_->layer().value() + 1] = middleFPGAStub_->phiregionaddress() + (1 << 10); + if (outerFPGAStub_) + stubIDs[outerFPGAStub_->layer().value() + 1] = outerFPGAStub_->phiregionaddress() + (1 << 10); + + } else if (disk_) { + for (int i = 0; i < N_DISK; i++) { + //check barrel + if (layerresid_[i].valid()) { + // two extra bits to indicate if the matched stub is local or from neighbor + int location = 1; // local + location <<= layerresid_[i].fpgastubid().nbits(); + + stubIDs[1 + i] = layerresid_[i].fpgastubid().value() + location; + } + + //check disks + if (i == 4 && layerresid_[1].valid()) + continue; // Don't add D5 if track has L2 stub + if (diskresid_[i].valid()) { + // two extra bits to indicate if the matched stub is local or from neighbor + int location = 1; // local + location <<= diskresid_[i].fpgastubid().nbits(); + + if (innerStub_->disk() < 0) { + stubIDs[-11 - i] = diskresid_[i].fpgastubid().value() + location; + } else { + stubIDs[11 + i] = diskresid_[i].fpgastubid().value() + location; + } + } + } + + //get stubs making up tracklet + if (innerFPGAStub_->disk().value() < 0) { //negative side runs 6-10 + if (innerFPGAStub_) + stubIDs[innerFPGAStub_->disk().value() - 10] = innerFPGAStub_->phiregionaddress() + (1 << 10); + if (middleFPGAStub_) + stubIDs[middleFPGAStub_->disk().value() - 10] = middleFPGAStub_->phiregionaddress() + (1 << 10); + if (outerFPGAStub_) + stubIDs[outerFPGAStub_->disk().value() - 10] = outerFPGAStub_->phiregionaddress() + (1 << 10); + } else { // positive side runs 11-15] + if (innerFPGAStub_) + stubIDs[innerFPGAStub_->disk().value() + 10] = innerFPGAStub_->phiregionaddress() + (1 << 10); + if (middleFPGAStub_) + stubIDs[middleFPGAStub_->disk().value() + 10] = middleFPGAStub_->phiregionaddress() + (1 << 10); + if (outerFPGAStub_) + stubIDs[outerFPGAStub_->disk().value() + 10] = outerFPGAStub_->phiregionaddress() + (1 << 10); + } + + } else if (overlap_) { + for (int i = 0; i < N_DISK; i++) { + //check barrel + if (layerresid_[i].valid()) { + // two extra bits to indicate if the matched stub is local or from neighbor + int location = 1; // local + location <<= layerresid_[i].fpgastubid().nbits(); + + stubIDs[1 + i] = layerresid_[i].fpgastubid().value() + location; + } + + //check disks + if (diskresid_[i].valid()) { + // two extra bits to indicate if the matched stub is local or from neighbor + int location = 1; // local + location <<= diskresid_[i].fpgastubid().nbits(); + + if (innerStub_->disk() < 0) { // if negative overlap + if (innerFPGAStub_->layer().value() != 2 || !layerresid_[0].valid() || + i != 3) { // Don't add D4 if this is an L3L2 track with an L1 stub + stubIDs[-11 - i] = diskresid_[i].fpgastubid().value() + location; + } + } else { + if (innerFPGAStub_->layer().value() != 2 || !layerresid_[0].valid() || i != 3) { + stubIDs[11 + i] = diskresid_[i].fpgastubid().value() + location; + } + } + } + } + + //get stubs making up tracklet + + if (innerFPGAStub_->layer().value() == 2) { // L3L2 track + if (innerFPGAStub_) + stubIDs[innerFPGAStub_->layer().value() + 1] = innerFPGAStub_->phiregionaddress() + (1 << 10); + if (middleFPGAStub_) + stubIDs[middleFPGAStub_->layer().value() + 1] = middleFPGAStub_->phiregionaddress() + (1 << 10); + if (outerFPGAStub_) + stubIDs[outerFPGAStub_->layer().value() + 1] = outerFPGAStub_->phiregionaddress() + (1 << 10); + } else if (innerFPGAStub_->disk().value() < 0) { //negative side runs -11 - -15 + if (innerFPGAStub_) + stubIDs[innerFPGAStub_->disk().value() - 10] = innerFPGAStub_->phiregionaddress() + (1 << 10); + if (middleFPGAStub_) + stubIDs[middleFPGAStub_->layer().value() + 1] = middleFPGAStub_->phiregionaddress() + (1 << 10); + if (outerFPGAStub_) + stubIDs[outerFPGAStub_->layer().value() + 1] = outerFPGAStub_->phiregionaddress() + (1 << 10); + } else { // positive side runs 11-15] + if (innerFPGAStub_) + stubIDs[innerFPGAStub_->disk().value() + 10] = innerFPGAStub_->phiregionaddress() + (1 << 10); + if (middleFPGAStub_) + stubIDs[middleFPGAStub_->layer().value() + 1] = middleFPGAStub_->phiregionaddress() + (1 << 10); + if (outerFPGAStub_) + stubIDs[outerFPGAStub_->layer().value() + 1] = outerFPGAStub_->phiregionaddress() + (1 << 10); + } + } + + return stubIDs; +} + +void Tracklet::setFitPars(double rinvfit, + double phi0fit, + double d0fit, + double tfit, + double z0fit, + double chisqrphifit, + double chisqrzfit, + double rinvfitexact, + double phi0fitexact, + double d0fitexact, + double tfitexact, + double z0fitexact, + double chisqrphifitexact, + double chisqrzfitexact, + int irinvfit, + int iphi0fit, + int id0fit, + int itfit, + int iz0fit, + int ichisqrphifit, + int ichisqrzfit, + int hitpattern, + const vector& l1stubs) { + fitpars_.init(rinvfit, phi0fit, d0fit, tfit, z0fit); + chisqrphifit_ = chisqrphifit; + chisqrzfit_ = chisqrzfit; + + fitparsexact_.init(rinvfitexact, phi0fitexact, d0fitexact, tfitexact, z0fitexact); + chisqrphifitexact_ = chisqrphifitexact; + chisqrzfitexact_ = chisqrzfitexact; + + if (irinvfit > (1 << 14)) + irinvfit = (1 << 14); + if (irinvfit <= -(1 << 14)) + irinvfit = -(1 << 14) + 1; + fpgafitpars_.rinv().set(irinvfit, 15, false, __LINE__, __FILE__); + fpgafitpars_.phi0().set(iphi0fit, 19, false, __LINE__, __FILE__); + fpgafitpars_.d0().set(id0fit, 19, false, __LINE__, __FILE__); + fpgafitpars_.t().set(itfit, 14, false, __LINE__, __FILE__); + + if (iz0fit >= (1 << (settings_.nbitsz0() - 1))) { + iz0fit = (1 << (settings_.nbitsz0() - 1)) - 1; + } + + if (iz0fit <= -(1 << (settings_.nbitsz0() - 1))) { + iz0fit = 1 - (1 << (settings_.nbitsz0() - 1)); + } + + fpgafitpars_.z0().set(iz0fit, settings_.nbitsz0(), false, __LINE__, __FILE__); + ichisqrphifit_.set(ichisqrphifit, 8, true, __LINE__, __FILE__); + ichisqrzfit_.set(ichisqrzfit, 8, true, __LINE__, __FILE__); + + hitpattern_ = hitpattern; + + fpgatrack_.reset(new Track(makeTrack(l1stubs))); +} + +std::string Tracklet::trackfitstr() { + string stubid0 = "111111111"; + string stubid1 = "111111111"; + string stubid2 = "111111111"; + string stubid3 = "111111111"; + + if (isBarrel()) { + if (layer() == 1) { + if (layerresid_[2].valid()) { + stubid0 = layerresid_[2].fpgastubid().str(); + } + if (layerresid_[3].valid()) { + stubid1 = layerresid_[3].fpgastubid().str(); + } + if (layerresid_[4].valid()) { + stubid2 = layerresid_[4].fpgastubid().str(); + } + if (layerresid_[5].valid()) { + stubid3 = layerresid_[5].fpgastubid().str(); + } + if (diskresid_[0].valid()) { + stubid3 = diskresid_[0].fpgastubid().str(); + } + if (diskresid_[1].valid()) { + stubid2 = diskresid_[1].fpgastubid().str(); + } + if (diskresid_[2].valid()) { + stubid1 = diskresid_[2].fpgastubid().str(); + } + if (diskresid_[3].valid()) { + stubid0 = diskresid_[3].fpgastubid().str(); + } + } + + if (layer() == 3) { + if (layerresid_[0].valid()) { + stubid0 = layerresid_[0].fpgastubid().str(); + } + if (layerresid_[1].valid()) { + stubid1 = layerresid_[1].fpgastubid().str(); + } + if (layerresid_[4].valid()) { + stubid2 = layerresid_[4].fpgastubid().str(); + } + if (layerresid_[5].valid()) { + stubid3 = layerresid_[5].fpgastubid().str(); + } + if (diskresid_[0].valid()) { + stubid3 = diskresid_[0].fpgastubid().str(); + } + if (diskresid_[1].valid()) { + stubid2 = diskresid_[1].fpgastubid().str(); + } + } + + if (layer() == 5) { + if (layerresid_[0].valid()) { + stubid0 = layerresid_[0].fpgastubid().str(); + } + if (layerresid_[1].valid()) { + stubid1 = layerresid_[1].fpgastubid().str(); + } + if (layerresid_[2].valid()) { + stubid2 = layerresid_[2].fpgastubid().str(); + } + if (layerresid_[3].valid()) { + stubid3 = layerresid_[3].fpgastubid().str(); + } + } + } + + if (isDisk()) { + if (disk() == 1) { + if (layerresid_[0].valid()) { + stubid0 = layerresid_[0].fpgastubid().str(); + } + if (diskresid_[2].valid()) { + stubid1 = diskresid_[2].fpgastubid().str(); + } + if (diskresid_[3].valid()) { + stubid2 = diskresid_[3].fpgastubid().str(); + } + if (diskresid_[4].valid()) { + stubid3 = diskresid_[4].fpgastubid().str(); + } else if (layerresid_[1].valid()) { + stubid3 = layerresid_[1].fpgastubid().str(); + } + } + + if (disk() == 3) { + if (layerresid_[0].valid()) { + stubid0 = layerresid_[0].fpgastubid().str(); + } + if (diskresid_[0].valid()) { + stubid1 = diskresid_[0].fpgastubid().str(); + } + if (diskresid_[1].valid()) { + stubid2 = diskresid_[1].fpgastubid().str(); + } + if (diskresid_[4].valid()) { + stubid3 = diskresid_[4].fpgastubid().str(); + } else if (layerresid_[1].valid()) { + stubid3 = layerresid_[1].fpgastubid().str(); + } + } + } + + if (isOverlap()) { + if (layer() == 1) { + if (diskresid_[1].valid()) { + stubid0 = diskresid_[1].fpgastubid().str(); + } + if (diskresid_[2].valid()) { + stubid1 = diskresid_[2].fpgastubid().str(); + } + if (diskresid_[3].valid()) { + stubid2 = diskresid_[3].fpgastubid().str(); + } + if (diskresid_[4].valid()) { + stubid3 = diskresid_[4].fpgastubid().str(); + } + } + } + + std::string oss; + // real Q print out for fitted tracks + if (settings_.writeoutReal()) { + oss = std::to_string((fpgafitpars_.rinv().value()) * settings_.krinvpars()) + " " + + std::to_string((fpgafitpars_.phi0().value()) * settings_.kphi0pars()) + " " + + std::to_string((fpgafitpars_.d0().value()) * settings_.kd0pars()) + " " + + std::to_string((fpgafitpars_.t().value()) * settings_.ktpars()) + " " + + std::to_string((fpgafitpars_.z0().value()) * settings_.kz()) + " " + innerFPGAStub_->phiregionaddressstr() + + " "; + } + //Binary print out + if (!settings_.writeoutReal()) { + oss = fpgafitpars_.rinv().str() + "|" + fpgafitpars_.phi0().str() + "|" + fpgafitpars_.d0().str() + "|" + + fpgafitpars_.t().str() + "|" + fpgafitpars_.z0().str() + "|" + innerFPGAStub_->phiregionaddressstr() + "|"; + } + if (middleFPGAStub_) { + oss += middleFPGAStub_->phiregionaddressstr() + " "; + } + oss += outerFPGAStub_->phiregionaddressstr() + " " + stubid0 + "|" + stubid1 + "|" + stubid2 + "|" + stubid3; + + return oss; +} + +Track Tracklet::makeTrack(const vector& l1stubs) { + assert(fit()); + + TrackPars ipars(fpgafitpars_.rinv().value(), + fpgafitpars_.phi0().value(), + fpgafitpars_.d0().value(), + fpgafitpars_.t().value(), + fpgafitpars_.z0().value()); + + Track tmpTrack( + ipars, + ichisqrphifit_.value(), + ichisqrzfit_.value(), + chisqrphifit_, + chisqrzfit_, + hitpattern_, + getStubIDs(), + (l1stubs.empty()) ? getL1Stubs() : l1stubs, // If fitter produced no stub list, take it from original tracklet. + getISeed()); + + return tmpTrack; +} + +int Tracklet::layer() const { + int l1 = (innerFPGAStub_ && innerFPGAStub_->isBarrel()) ? innerStub_->layer() + 1 : 999, + l2 = (middleFPGAStub_ && middleFPGAStub_->isBarrel()) ? middleStub_->layer() + 1 : 999, + l3 = (outerFPGAStub_ && outerFPGAStub_->isBarrel()) ? outerStub_->layer() + 1 : 999, l = min(min(l1, l2), l3); + return (l < 999 ? l : 0); +} + +int Tracklet::disk() const { + int d1 = (innerFPGAStub_ && innerFPGAStub_->isDisk()) ? innerStub_->disk() : 999, + d2 = (middleFPGAStub_ && middleFPGAStub_->isDisk()) ? middleStub_->disk() : 999, + d3 = (outerFPGAStub_ && outerFPGAStub_->isDisk()) ? outerStub_->disk() : 999, d = 999; + if (abs(d1) < min(abs(d2), abs(d3))) + d = d1; + if (abs(d2) < min(abs(d1), abs(d3))) + d = d2; + if (abs(d3) < min(abs(d1), abs(d2))) + d = d3; + return (d < 999 ? d : 0); +} + +int Tracklet::disk2() const { + if (innerStub_->disk() > 0) { + return innerStub_->disk() + 1; + } + return innerStub_->disk() - 1; +} + +void Tracklet::setTrackletIndex(int index) { + trackletIndex_ = index; + assert(index < 128); +} + +int Tracklet::getISeed() const { + int iSeed = TCIndex_ >> 4; + assert(iSeed >= 0 && iSeed <= (int)N_SEED); + return iSeed; +} + +int Tracklet::getITC() const { + int iSeed = getISeed(), iTC = TCIndex_ - (iSeed << 4); + assert(iTC >= 0 && iTC <= 14); + return iTC; +} + +unsigned int Tracklet::calcSeedIndex() const { + int seedindex = -1; + int seedlayer = layer(); + int seeddisk = disk(); + + if (seedlayer == 1 && seeddisk == 0) + seedindex = 0; //L1L2 + if (seedlayer == 3 && seeddisk == 0) + seedindex = 2; //L3L4 + if (seedlayer == 5 && seeddisk == 0) + seedindex = 3; //L5L6 + if (seedlayer == 0 && abs(seeddisk) == 1) + seedindex = 4; //D1D2 + if (seedlayer == 0 && abs(seeddisk) == 3) + seedindex = 5; //D3D4 + if (seedlayer == 1 && abs(seeddisk) == 1) + seedindex = 6; //L1D1 + if (seedlayer == 2 && abs(seeddisk) == 1) + seedindex = 7; //L2D1 + if (seedlayer == 2 && abs(seeddisk) == 0) + seedindex = 1; //L2L3 + if (middleFPGAStub_ && seedlayer == 2 && seeddisk == 0) + seedindex = 8; // L3L4L2 + if (middleFPGAStub_ && seedlayer == 4 && seeddisk == 0) + seedindex = 9; // L5L6L4 + assert(innerFPGAStub_ != nullptr); + assert(outerFPGAStub_ != nullptr); + if (middleFPGAStub_ && seedlayer == 2 && abs(seeddisk) == 1) { + int l1 = (innerFPGAStub_ && innerFPGAStub_->isBarrel()) ? innerStub_->layer() + 1 : 999, + l2 = (middleFPGAStub_ && middleFPGAStub_->isBarrel()) ? middleStub_->layer() + 1 : 999, + l3 = (outerFPGAStub_ && outerFPGAStub_->isBarrel()) ? outerStub_->layer() + 1 : 999; + if (l1 + l2 + l3 < 1998) { // If two stubs are layer stubs + seedindex = 10; // L2L3D1 + } else { + seedindex = 11; // D1D2L2 + } + } + + if (seedindex < 0) { + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " seedlayer abs(seeddisk) : " << seedlayer + << " " << abs(seeddisk); + } + + return seedindex; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletCalculator.cc b/L1Trigger/TrackFindingTracklet/src/TrackletCalculator.cc new file mode 100644 index 0000000000000..c7946901b6e2a --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletCalculator.cc @@ -0,0 +1,192 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +TrackletCalculator::TrackletCalculator(string name, Settings const& settings, Globals* globals, unsigned int iSector) + : TrackletCalculatorBase(name, settings, globals, iSector) { + phioffset_ = phimin_; + + for (unsigned int ilayer = 0; ilayer < N_LAYER; ilayer++) { + vector tmp(settings.nallstubs(ilayer), nullptr); + trackletprojlayers_.push_back(tmp); + } + + for (unsigned int idisk = 0; idisk < N_DISK; idisk++) { + vector tmp(settings.nallstubs(idisk + N_LAYER), nullptr); + trackletprojdisks_.push_back(tmp); + } + + initLayerDisksandISeed(layerdisk1_, layerdisk2_, iSeed_); + + // set TC index + iTC_ = name_[7] - 'A'; + + TCIndex_ = (iSeed_ << 4) + iTC_; + assert(TCIndex_ >= 0 && TCIndex_ <= (int)settings_.ntrackletmax()); + + if (settings_.usephicritapprox()) { + double phicritFactor = + 0.5 * settings_.rcrit() * globals_->ITC_L1L2()->rinv_final.K() / globals_->ITC_L1L2()->phi0_final.K(); + if (std::abs(phicritFactor - 2.) > 0.25) + edm::LogPrint("Tracklet") + << "TrackletCalculator::TrackletCalculator phicrit approximation may be invalid! Please check."; + } +} + +void TrackletCalculator::addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory) { + outputProj = dynamic_cast(memory); + assert(outputProj != nullptr); +} + +void TrackletCalculator::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "trackpar") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + trackletpars_ = tmp; + return; + } + + if (output.substr(0, 7) == "projout") { + //output is on the form 'projoutL2PHIC' or 'projoutD3PHIB' + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + + unsigned int layerdisk = output[8] - '1'; //layer or disk counting from 0 + unsigned int phiregion = output[12] - 'A'; //phiregion counting from 0 + + if (output[7] == 'L') { + assert(layerdisk < N_LAYER); + assert(phiregion < trackletprojlayers_[layerdisk].size()); + //check that phiregion not already initialized + assert(trackletprojlayers_[layerdisk][phiregion] == nullptr); + trackletprojlayers_[layerdisk][phiregion] = tmp; + return; + } + + if (output[7] == 'D') { + assert(layerdisk < N_DISK); + assert(phiregion < trackletprojdisks_[layerdisk].size()); + //check that phiregion not already initialized + assert(trackletprojdisks_[layerdisk][phiregion] == nullptr); + trackletprojdisks_[layerdisk][phiregion] = tmp; + return; + } + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void TrackletCalculator::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "innerallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + innerallstubs_.push_back(tmp); + return; + } + if (input == "outerallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + outerallstubs_.push_back(tmp); + return; + } + if (input.substr(0, 8) == "stubpair") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + stubpairs_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find intput : " << input; +} + +void TrackletCalculator::execute() { + unsigned int countall = 0; + unsigned int countsel = 0; + + for (auto& stubpair : stubpairs_) { + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on too many tracklets in " << getName(); + break; + } + for (unsigned int i = 0; i < stubpair->nStubPairs(); i++) { + countall++; + const Stub* innerFPGAStub = stubpair->getVMStub1(i).stub(); + const L1TStub* innerStub = innerFPGAStub->l1tstub(); + + const Stub* outerFPGAStub = stubpair->getVMStub2(i).stub(); + const L1TStub* outerStub = outerFPGAStub->l1tstub(); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculator execute " << getName() << "[" << iSector_ << "]"; + } + + if (innerFPGAStub->isBarrel() && (getName() != "TC_D1L2A" && getName() != "TC_D1L2B")) { + if (outerFPGAStub->isDisk()) { + //overlap seeding + bool accept = overlapSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub); + if (accept) + countsel++; + } else { + //barrel+barrel seeding + bool accept = barrelSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub); + if (accept) + countsel++; + } + } else { + if (outerFPGAStub->isDisk()) { + //disk+disk seeding + bool accept = diskSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub); + if (accept) + countsel++; + } else if (innerFPGAStub->isDisk()) { + //layer+disk seeding + bool accept = overlapSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub); + if (accept) + countsel++; + } else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " invalid seeding"; + } + } + + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on number of tracklets in " << getName(); + break; + } + + if (countall >= settings_.maxStep("TC")) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Will break on MAXTC 1"; + break; + } + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculator execute done"; + } + } + if (countall >= settings_.maxStep("TC")) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Will break on MAXTC 2"; + break; + } + } + + if (settings_.writeMonitorData("TC")) { + globals_->ofstream("trackletcalculator.txt") << getName() << " " << countall << " " << countsel << endl; + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletCalculatorBase.cc b/L1Trigger/TrackFindingTracklet/src/TrackletCalculatorBase.cc new file mode 100644 index 0000000000000..687ff3fdfac82 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletCalculatorBase.cc @@ -0,0 +1,1473 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/HistBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorDisk.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculatorOverlap.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +TrackletCalculatorBase::TrackletCalculatorBase(string name, + Settings const& settings, + Globals* global, + unsigned int iSector) + : ProcessBase(name, settings, global, iSector) {} + +void TrackletCalculatorBase::exacttracklet(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double, + double& rinv, + double& phi0, + double& t, + double& z0, + double phiproj[N_LAYER - 2], + double zproj[N_LAYER - 2], + double phider[N_LAYER - 2], + double zder[N_LAYER - 2], + double phiprojdisk[N_DISK], + double rprojdisk[N_DISK], + double phiderdisk[N_DISK], + double rderdisk[N_DISK]) { + double deltaphi = reco::reduceRange(phi1 - phi2); + + double dist = sqrt(r2 * r2 + r1 * r1 - 2 * r1 * r2 * cos(deltaphi)); + + rinv = 2 * sin(deltaphi) / dist; + + double phi1tmp = phi1 - phimin_; + + phi0 = reco::reduceRange(phi1tmp + asin(0.5 * r1 * rinv)); + + double rhopsi1 = 2 * asin(0.5 * r1 * rinv) / rinv; + double rhopsi2 = 2 * asin(0.5 * r2 * rinv) / rinv; + + t = (z1 - z2) / (rhopsi1 - rhopsi2); + + z0 = z1 - t * rhopsi1; + + for (unsigned int i = 0; i < N_LAYER - 2; i++) { + exactproj(settings_.rmean(settings_.projlayers(iSeed_, i) - 1), + rinv, + phi0, + t, + z0, + phiproj[i], + zproj[i], + phider[i], + zder[i]); + } + + for (unsigned int i = 0; i < N_DISK; i++) { + exactprojdisk(settings_.zmean(i), rinv, phi0, t, z0, phiprojdisk[i], rprojdisk[i], phiderdisk[i], rderdisk[i]); + } +} + +void TrackletCalculatorBase::exacttrackletdisk(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double, + double& rinv, + double& phi0, + double& t, + double& z0, + double phiprojLayer[N_PSLAYER], //=3 (project to PS barrel layers only) + double zprojLayer[N_PSLAYER], + double phiderLayer[N_PSLAYER], + double zderLayer[N_PSLAYER], + double phiproj[N_DISK - 2], //=3 (max project to 3 other disks) + double rproj[N_DISK - 2], + double phider[N_DISK - 2], + double rder[N_DISK - 2]) { + double deltaphi = reco::reduceRange(phi1 - phi2); + + double dist = sqrt(r2 * r2 + r1 * r1 - 2 * r1 * r2 * cos(deltaphi)); + + rinv = 2 * sin(deltaphi) / dist; + + double phi1tmp = phi1 - phimin_; + + phi0 = reco::reduceRange(phi1tmp + asin(0.5 * r1 * rinv)); + + double rhopsi1 = 2 * asin(0.5 * r1 * rinv) / rinv; + double rhopsi2 = 2 * asin(0.5 * r2 * rinv) / rinv; + + t = (z1 - z2) / (rhopsi1 - rhopsi2); + + z0 = z1 - t * rhopsi1; + + for (unsigned int i = 0; i < N_DISK - 2; i++) { + exactprojdisk(settings_.zmean(settings_.projdisks(iSeed_, i) - 1), + rinv, + phi0, + t, + z0, + phiproj[i], + rproj[i], + phider[i], + rder[i]); + } + + for (unsigned int i = 0; i < N_DISK - 2; i++) { + exactproj(settings_.rmean(i), rinv, phi0, t, z0, phiprojLayer[i], zprojLayer[i], phiderLayer[i], zderLayer[i]); + } +} + +void TrackletCalculatorBase::exacttrackletOverlap(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double, + double& rinv, + double& phi0, + double& t, + double& z0, + double phiprojLayer[N_PSLAYER], + double zprojLayer[N_PSLAYER], + double phiderLayer[N_PSLAYER], + double zderLayer[N_PSLAYER], + double phiproj[N_DISK - 2], + double rproj[N_DISK - 2], + double phider[N_DISK - 2], + double rder[N_DISK - 2]) { + double deltaphi = reco::reduceRange(phi1 - phi2); + + double dist = sqrt(r2 * r2 + r1 * r1 - 2 * r1 * r2 * cos(deltaphi)); + + rinv = 2 * sin(deltaphi) / dist; + + if (r1 > r2) + rinv = -rinv; + + double phi1tmp = phi1 - phimin_; + + phi0 = reco::reduceRange(phi1tmp + asin(0.5 * r1 * rinv)); + + double rhopsi1 = 2 * asin(0.5 * r1 * rinv) / rinv; + double rhopsi2 = 2 * asin(0.5 * r2 * rinv) / rinv; + + t = (z1 - z2) / (rhopsi1 - rhopsi2); + + z0 = z1 - t * rhopsi1; + + for (int i = 0; i < 4; i++) { + exactprojdisk(settings_.zmean(i + 1), rinv, phi0, t, z0, phiproj[i], rproj[i], phider[i], rder[i]); + } + + for (int i = 0; i < 1; i++) { + exactproj(settings_.rmean(i), rinv, phi0, t, z0, phiprojLayer[i], zprojLayer[i], phiderLayer[i], zderLayer[i]); + } +} + +void TrackletCalculatorBase::exactproj(double rproj, + double rinv, + double phi0, + double t, + double z0, + double& phiproj, + double& zproj, + double& phider, + double& zder) { + phiproj = phi0 - asin(0.5 * rproj * rinv); + zproj = z0 + (2 * t / rinv) * asin(0.5 * rproj * rinv); + + phider = -0.5 * rinv / sqrt(1 - pow(0.5 * rproj * rinv, 2)); + zder = t / sqrt(1 - pow(0.5 * rproj * rinv, 2)); +} + +void TrackletCalculatorBase::exactprojdisk(double zproj, + double rinv, + double phi0, + double t, + double z0, + double& phiproj, + double& rproj, + double& phider, + double& rder) { + if (t < 0) + zproj = -zproj; + + double tmp = rinv * (zproj - z0) / (2.0 * t); + rproj = (2.0 / rinv) * sin(tmp); + phiproj = phi0 - tmp; + + phider = -rinv / (2 * t); + rder = cos(tmp) / t; +} + +void TrackletCalculatorBase::addDiskProj(Tracklet* tracklet, int disk) { + FPGAWord fpgar = tracklet->fpgarprojdisk(disk); + + if (fpgar.value() * settings_.krprojshiftdisk() < settings_.rmindiskvm()) + return; + if (fpgar.value() * settings_.krprojshiftdisk() > settings_.rmaxdisk()) + return; + + FPGAWord fpgaphi = tracklet->fpgaphiprojdisk(disk); + + int iphivmRaw = fpgaphi.value() >> (fpgaphi.nbits() - 5); + + int iphi = iphivmRaw / (32 / settings_.nallstubs(abs(disk) + N_DISK)); + + addProjectionDisk(disk, iphi, trackletprojdisks_[abs(disk) - 1][iphi], tracklet); +} + +bool TrackletCalculatorBase::addLayerProj(Tracklet* tracklet, int layer) { + assert(layer > 0); + + FPGAWord fpgaz = tracklet->fpgazproj(layer); + FPGAWord fpgaphi = tracklet->fpgaphiproj(layer); + + if (fpgaphi.atExtreme()) + edm::LogProblem("Tracklet") << "at extreme! " << fpgaphi.value(); + + assert(!fpgaphi.atExtreme()); + + if (fpgaz.atExtreme()) + return false; + + if (std::abs(fpgaz.value() * settings_.kz()) > settings_.zlength()) + return false; + + int iphivmRaw = fpgaphi.value() >> (fpgaphi.nbits() - 5); + int iphi = iphivmRaw / (32 / settings_.nallstubs(layer - 1)); + + addProjection(layer, iphi, trackletprojlayers_[layer - 1][iphi], tracklet); + + return true; +} + +void TrackletCalculatorBase::addProjection(int layer, + int iphi, + TrackletProjectionsMemory* trackletprojs, + Tracklet* tracklet) { + if (trackletprojs == nullptr) { + if (settings_.warnNoMem()) { + edm::LogVerbatim("Tracklet") << "No projection memory exists in " << getName() << " for layer = " << layer + << " iphi = " << iphi + 1; + } + return; + } + assert(trackletprojs != nullptr); + trackletprojs->addProj(tracklet); +} + +void TrackletCalculatorBase::addProjectionDisk(int disk, + int iphi, + TrackletProjectionsMemory* trackletprojs, + Tracklet* tracklet) { + if (iSeed_ == 2 && abs(disk) == 4) + return; //L3L4 projections to D3 are not used. Should be in configuration + if (trackletprojs == nullptr) { + if (iSeed_ == 2 && abs(disk) == 3) + return; //L3L4 projections to D3 are not used. + if (settings_.warnNoMem()) { + edm::LogVerbatim("Tracklet") << "No projection memory exists in " << getName() << " for disk = " << abs(disk) + << " iphi = " << iphi + 1; + } + return; + } + assert(trackletprojs != nullptr); + trackletprojs->addProj(tracklet); +} + +bool TrackletCalculatorBase::goodTrackPars(bool goodrinv, bool goodz0) { + bool success = true; + if (!goodrinv) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " TrackletCalculatorBase irinv too large"; + } + success = false; + } + if (!goodz0) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " TrackletCalculatorBase z0 cut to large"; + } + success = false; + } + return success; +} + +bool TrackletCalculatorBase::inSector(int iphi0, int irinv, double phi0approx, double rinvapprox) { + double phicritapprox = phi0approx - asin(0.5 * settings_.rcrit() * rinvapprox); + + int ifactor = 0.5 * settings_.rcrit() * settings_.krinvpars() / settings_.kphi0pars() * (1 << 8); + int iphicrit = iphi0 - (irinv >> 8) * ifactor; + + int iphicritmincut = settings_.phicritminmc() / globals_->ITC_L1L2()->phi0_final.K(); + int iphicritmaxcut = settings_.phicritmaxmc() / globals_->ITC_L1L2()->phi0_final.K(); + + bool keepapprox = (phicritapprox > settings_.phicritminmc()) && (phicritapprox < settings_.phicritmaxmc()), + keep = (iphicrit > iphicritmincut) && (iphicrit < iphicritmaxcut); + if (settings_.debugTracklet()) + if (keepapprox && !keep) + edm::LogVerbatim("Tracklet") << getName() + << " Tracklet kept with exact phicrit cut but not approximate, phicritapprox: " + << phicritapprox; + if (settings_.usephicritapprox()) { + return keepapprox; + } else { + return keep; + } + + return true; +} + +bool TrackletCalculatorBase::barrelSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculator " << getName() + << " trying stub pair in layer (inner outer): " << innerFPGAStub->layer().value() + << " " << outerFPGAStub->layer().value(); + } + + assert(outerFPGAStub->isBarrel()); + assert(layerdisk1_ == (unsigned int)innerFPGAStub->layer().value()); + assert(layerdisk1_ < N_LAYER && layerdisk2_ < N_LAYER); + + double r1 = innerStub->r(); + double z1 = innerStub->z(); + double phi1 = innerStub->phi(); + + double r2 = outerStub->r(); + double z2 = outerStub->z(); + double phi2 = outerStub->phi(); + + double rinv, phi0, t, z0; + + double phiproj[N_LAYER - 2], zproj[N_LAYER - 2], phider[N_LAYER - 2], zder[N_LAYER - 2]; + double phiprojdisk[N_DISK], rprojdisk[N_DISK], phiderdisk[N_DISK], rderdisk[N_DISK]; + + exacttracklet(r1, + z1, + phi1, + r2, + z2, + phi2, + outerStub->sigmaz(), + rinv, + phi0, + t, + z0, + phiproj, + zproj, + phider, + zder, + phiprojdisk, + rprojdisk, + phiderdisk, + rderdisk); + + if (settings_.useapprox()) { + phi1 = innerFPGAStub->phiapprox(phimin_, phimax_); + z1 = innerFPGAStub->zapprox(); + r1 = innerFPGAStub->rapprox(); + + phi2 = outerFPGAStub->phiapprox(phimin_, phimax_); + z2 = outerFPGAStub->zapprox(); + r2 = outerFPGAStub->rapprox(); + } + + double rinvapprox, phi0approx, tapprox, z0approx; + double phiprojapprox[N_LAYER - 2], zprojapprox[N_LAYER - 2]; + double phiprojdiskapprox[N_DISK], rprojdiskapprox[N_DISK]; + + IMATH_TrackletCalculator* ITC; + if (iSeed_ == 0) + ITC = globals_->ITC_L1L2(); + else if (iSeed_ == 1) + ITC = globals_->ITC_L2L3(); + else if (iSeed_ == 2) + ITC = globals_->ITC_L3L4(); + else + ITC = globals_->ITC_L5L6(); + + ITC->r1.set_fval(r1 - settings_.rmean(layerdisk1_)); + ITC->r2.set_fval(r2 - settings_.rmean(layerdisk2_)); + ITC->z1.set_fval(z1); + ITC->z2.set_fval(z2); + double sphi1 = angle0to2pi::make0To2pi(phi1 - phioffset_); + double sphi2 = angle0to2pi::make0To2pi(phi2 - phioffset_); + + ITC->phi1.set_fval(sphi1); + ITC->phi2.set_fval(sphi2); + + ITC->rproj0.set_fval(settings_.rmean(settings_.projlayers(iSeed_, 0) - 1)); + ITC->rproj1.set_fval(settings_.rmean(settings_.projlayers(iSeed_, 1) - 1)); + ITC->rproj2.set_fval(settings_.rmean(settings_.projlayers(iSeed_, 2) - 1)); + ITC->rproj3.set_fval(settings_.rmean(settings_.projlayers(iSeed_, 3) - 1)); + + ITC->zproj0.set_fval(t > 0 ? settings_.zmean(0) : -settings_.zmean(0)); + ITC->zproj1.set_fval(t > 0 ? settings_.zmean(1) : -settings_.zmean(1)); + ITC->zproj2.set_fval(t > 0 ? settings_.zmean(2) : -settings_.zmean(2)); + ITC->zproj3.set_fval(t > 0 ? settings_.zmean(3) : -settings_.zmean(3)); + ITC->zproj4.set_fval(t > 0 ? settings_.zmean(4) : -settings_.zmean(4)); + + ITC->rinv_final.calculate(); + ITC->phi0_final.calculate(); + ITC->t_final.calculate(); + ITC->z0_final.calculate(); + + ITC->phiL_0_final.calculate(); + ITC->phiL_1_final.calculate(); + ITC->phiL_2_final.calculate(); + ITC->phiL_3_final.calculate(); + + ITC->zL_0_final.calculate(); + ITC->zL_1_final.calculate(); + ITC->zL_2_final.calculate(); + ITC->zL_3_final.calculate(); + + ITC->phiD_0_final.calculate(); + ITC->phiD_1_final.calculate(); + ITC->phiD_2_final.calculate(); + ITC->phiD_3_final.calculate(); + ITC->phiD_4_final.calculate(); + + ITC->rD_0_final.calculate(); + ITC->rD_1_final.calculate(); + ITC->rD_2_final.calculate(); + ITC->rD_3_final.calculate(); + ITC->rD_4_final.calculate(); + + ITC->der_phiL_final.calculate(); + ITC->der_zL_final.calculate(); + ITC->der_phiD_final.calculate(); + ITC->der_rD_final.calculate(); + + //store the approximate results + rinvapprox = ITC->rinv_final.fval(); + phi0approx = ITC->phi0_final.fval(); + tapprox = ITC->t_final.fval(); + z0approx = ITC->z0_final.fval(); + + phiprojapprox[0] = ITC->phiL_0_final.fval(); + phiprojapprox[1] = ITC->phiL_1_final.fval(); + phiprojapprox[2] = ITC->phiL_2_final.fval(); + phiprojapprox[3] = ITC->phiL_3_final.fval(); + + zprojapprox[0] = ITC->zL_0_final.fval(); + zprojapprox[1] = ITC->zL_1_final.fval(); + zprojapprox[2] = ITC->zL_2_final.fval(); + zprojapprox[3] = ITC->zL_3_final.fval(); + + phiprojdiskapprox[0] = ITC->phiD_0_final.fval(); + phiprojdiskapprox[1] = ITC->phiD_1_final.fval(); + phiprojdiskapprox[2] = ITC->phiD_2_final.fval(); + phiprojdiskapprox[3] = ITC->phiD_3_final.fval(); + phiprojdiskapprox[4] = ITC->phiD_4_final.fval(); + + rprojdiskapprox[0] = ITC->rD_0_final.fval(); + rprojdiskapprox[1] = ITC->rD_1_final.fval(); + rprojdiskapprox[2] = ITC->rD_2_final.fval(); + rprojdiskapprox[3] = ITC->rD_3_final.fval(); + rprojdiskapprox[4] = ITC->rD_4_final.fval(); + + //now binary + + int irinv, iphi0, it, iz0; + LayerProjection layerprojs[N_LAYER - 2]; + DiskProjection diskprojs[N_DISK]; + + int iphiproj[N_LAYER - 2], izproj[N_LAYER - 2]; + int iphiprojdisk[N_DISK], irprojdisk[N_DISK]; + + int ir1 = innerFPGAStub->r().value(); + int iphi1 = innerFPGAStub->phi().value(); + int iz1 = innerFPGAStub->z().value(); + + int ir2 = outerFPGAStub->r().value(); + int iphi2 = outerFPGAStub->phi().value(); + int iz2 = outerFPGAStub->z().value(); + + iphi1 <<= (settings_.nphibitsstub(5) - settings_.nphibitsstub(layerdisk1_)); + iphi2 <<= (settings_.nphibitsstub(5) - settings_.nphibitsstub(layerdisk2_)); + ir1 <<= (8 - settings_.nrbitsstub(layerdisk1_)); + ir2 <<= (8 - settings_.nrbitsstub(layerdisk2_)); + + iz1 <<= (settings_.nzbitsstub(0) - settings_.nzbitsstub(layerdisk1_)); + iz2 <<= (settings_.nzbitsstub(0) - settings_.nzbitsstub(layerdisk2_)); + + ITC->r1.set_ival(ir1); + ITC->r2.set_ival(ir2); + ITC->z1.set_ival(iz1); + ITC->z2.set_ival(iz2); + ITC->phi1.set_ival(iphi1); + ITC->phi2.set_ival(iphi2); + + ITC->rinv_final.calculate(); + ITC->phi0_final.calculate(); + ITC->t_final.calculate(); + ITC->z0_final.calculate(); + + ITC->phiL_0_final.calculate(); + ITC->phiL_1_final.calculate(); + ITC->phiL_2_final.calculate(); + ITC->phiL_3_final.calculate(); + + ITC->zL_0_final.calculate(); + ITC->zL_1_final.calculate(); + ITC->zL_2_final.calculate(); + ITC->zL_3_final.calculate(); + + ITC->phiD_0_final.calculate(); + ITC->phiD_1_final.calculate(); + ITC->phiD_2_final.calculate(); + ITC->phiD_3_final.calculate(); + ITC->phiD_4_final.calculate(); + + ITC->rD_0_final.calculate(); + ITC->rD_1_final.calculate(); + ITC->rD_2_final.calculate(); + ITC->rD_3_final.calculate(); + ITC->rD_4_final.calculate(); + + ITC->der_phiL_final.calculate(); + ITC->der_zL_final.calculate(); + ITC->der_phiD_final.calculate(); + ITC->der_rD_final.calculate(); + + //store the binary results + irinv = ITC->rinv_final.ival(); + iphi0 = ITC->phi0_final.ival(); + it = ITC->t_final.ival(); + iz0 = ITC->z0_final.ival(); + + iphiproj[0] = ITC->phiL_0_final.ival(); + iphiproj[1] = ITC->phiL_1_final.ival(); + iphiproj[2] = ITC->phiL_2_final.ival(); + iphiproj[3] = ITC->phiL_3_final.ival(); + + izproj[0] = ITC->zL_0_final.ival(); + izproj[1] = ITC->zL_1_final.ival(); + izproj[2] = ITC->zL_2_final.ival(); + izproj[3] = ITC->zL_3_final.ival(); + + if (!goodTrackPars(ITC->rinv_final.local_passes(), ITC->z0_final.local_passes())) + return false; + + if (!inSector(iphi0, irinv, phi0approx, rinvapprox)) + return false; + + for (unsigned int i = 0; i < N_LAYER - 2; ++i) { + //reject projection if z is out of range + if (izproj[i] < -(1 << (settings_.nzbitsstub(0) - 1))) + continue; + if (izproj[i] >= (1 << (settings_.nzbitsstub(0) - 1))) + continue; + + //reject projection if phi is out of range + if (iphiproj[i] >= (1 << settings_.nphibitsstub(5)) - 1) + continue; + if (iphiproj[i] <= 0) + continue; + + //Adjust bits for r and z projection depending on layer + if (settings_.projlayers(iSeed_, i) <= 3) { //TODO clean up logic + iphiproj[i] >>= (settings_.nphibitsstub(5) - settings_.nphibitsstub(settings_.projlayers(iSeed_, i) - 1)); + } else { + izproj[i] >>= (settings_.nzbitsstub(0) - settings_.nzbitsstub(5)); + } + + layerprojs[i].init(settings_, + settings_.projlayers(iSeed_, i), + settings_.rmean(settings_.projlayers(iSeed_, i) - 1), + iphiproj[i], + izproj[i], + ITC->der_phiL_final.ival(), + ITC->der_zL_final.ival(), + phiproj[i], + zproj[i], + phider[i], + zder[i], + phiprojapprox[i], + zprojapprox[i], + ITC->der_phiL_final.fval(), + ITC->der_zL_final.fval()); + } + + iphiprojdisk[0] = ITC->phiD_0_final.ival(); + iphiprojdisk[1] = ITC->phiD_1_final.ival(); + iphiprojdisk[2] = ITC->phiD_2_final.ival(); + iphiprojdisk[3] = ITC->phiD_3_final.ival(); + iphiprojdisk[4] = ITC->phiD_4_final.ival(); + + irprojdisk[0] = ITC->rD_0_final.ival(); + irprojdisk[1] = ITC->rD_1_final.ival(); + irprojdisk[2] = ITC->rD_2_final.ival(); + irprojdisk[3] = ITC->rD_3_final.ival(); + irprojdisk[4] = ITC->rD_4_final.ival(); + + if (std::abs(it * ITC->t_final.K()) > 1.0) { + for (unsigned int i = 0; i < N_DISK; ++i) { + if (iphiprojdisk[i] <= 0) + continue; + if (iphiprojdisk[i] >= (1 << settings_.nphibitsstub(0)) - 1) + continue; + + if (irprojdisk[i] < settings_.rmindisk() / ITC->rD_0_final.K() || + irprojdisk[i] > settings_.rmaxdisk() / ITC->rD_0_final.K()) + continue; + + diskprojs[i].init(settings_, + i + 1, + settings_.zmean(i), + iphiprojdisk[i], + irprojdisk[i], + ITC->der_phiD_final.ival(), + ITC->der_rD_final.ival(), + phiprojdisk[i], + rprojdisk[i], + phiderdisk[i], + rderdisk[i], + phiprojdiskapprox[i], + rprojdiskapprox[i], + ITC->der_phiD_final.fval(), + ITC->der_rD_final.fval()); + } + } + + if (settings_.writeMonitorData("TPars")) { + globals_->ofstream("trackletpars.txt") + << "Trackpars " << layerdisk1_ + 1 << " " << rinv << " " << rinvapprox << " " << ITC->rinv_final.fval() + << " " << phi0 << " " << phi0approx << " " << ITC->phi0_final.fval() << " " << t << " " << tapprox << " " + << ITC->t_final.fval() << " " << z0 << " " << z0approx << " " << ITC->z0_final.fval() << endl; + } + + Tracklet* tracklet = new Tracklet(settings_, + innerStub, + nullptr, + outerStub, + innerFPGAStub, + nullptr, + outerFPGAStub, + rinv, + phi0, + 0.0, + z0, + t, + rinvapprox, + phi0approx, + 0.0, + z0approx, + tapprox, + irinv, + iphi0, + 0, + iz0, + it, + layerprojs, + diskprojs, + false); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculator " << getName() << " Found tracklet for seed = " << iSeed_ << " " + << iSector_ << " phi0 = " << phi0; + } + + tracklet->setTrackletIndex(trackletpars_->nTracklets()); + tracklet->setTCIndex(TCIndex_); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() << endl; + fout.close(); + } + trackletpars_->addTracklet(tracklet); + + if (settings_.bookHistos()) { + HistBase* hists = globals_->histograms(); + int tp = tracklet->tpseed(); + hists->fillTrackletParams(settings_, + globals_, + iSeed_, + iSector_, + rinvapprox, + irinv * ITC->rinv_final.K(), + phi0approx, + iphi0 * ITC->phi0_final.K(), + asinh(tapprox), + asinh(it * ITC->t_final.K()), + z0approx, + iz0 * ITC->z0_final.K(), + tp); + } + + bool addL3 = false; + bool addL4 = false; + bool addL5 = false; + bool addL6 = false; + for (unsigned int j = 0; j < N_LAYER - 2; j++) { + int lproj = settings_.projlayers(iSeed_, j); + bool added = false; + if (tracklet->validProj(lproj)) { + added = addLayerProj(tracklet, lproj); + if (added && lproj == 3) + addL3 = true; + if (added && lproj == 4) + addL4 = true; + if (added && lproj == 5) + addL5 = true; + if (added && lproj == 6) + addL6 = true; + } + } + + for (unsigned int j = 0; j < N_DISK - 1; j++) { //no projections to 5th disk!! + int disk = j + 1; + if (disk == 4 && addL3) + continue; + if (disk == 3 && addL4) + continue; + if (disk == 2 && addL5) + continue; + if (disk == 1 && addL6) + continue; + if (it < 0) + disk = -disk; + if (tracklet->validProjDisk(abs(disk))) { + addDiskProj(tracklet, disk); + } + } + + return true; +} + +bool TrackletCalculatorBase::diskSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculator::execute calculate disk seeds"; + } + + int sign = 1; + if (innerFPGAStub->disk().value() < 0) + sign = -1; + + int disk = innerFPGAStub->disk().value(); + assert(abs(disk) == 1 || abs(disk) == 3); + + assert(innerStub->isPSmodule()); + assert(outerStub->isPSmodule()); + + double r1 = innerStub->r(); + double z1 = innerStub->z(); + double phi1 = innerStub->phi(); + + double r2 = outerStub->r(); + double z2 = outerStub->z(); + double phi2 = outerStub->phi(); + + if (r2 < r1 + 2.0) { + return false; //Protection... Should be handled cleaner to avoid problem with floating point calculation + } + + double rinv, phi0, t, z0; + + double phiproj[N_PSLAYER], zproj[N_PSLAYER], phider[N_PSLAYER], zder[N_PSLAYER]; + double phiprojdisk[N_DISK - 2], rprojdisk[N_DISK - 2], phiderdisk[N_DISK - 2], rderdisk[N_DISK - 2]; + + exacttrackletdisk(r1, + z1, + phi1, + r2, + z2, + phi2, + outerStub->sigmaz(), + rinv, + phi0, + t, + z0, + phiproj, + zproj, + phider, + zder, + phiprojdisk, + rprojdisk, + phiderdisk, + rderdisk); + + //Truncates floating point positions to integer representation precision + if (settings_.useapprox()) { + phi1 = innerFPGAStub->phiapprox(phimin_, phimax_); + z1 = innerFPGAStub->zapprox(); + r1 = innerFPGAStub->rapprox(); + + phi2 = outerFPGAStub->phiapprox(phimin_, phimax_); + z2 = outerFPGAStub->zapprox(); + r2 = outerFPGAStub->rapprox(); + } + + double rinvapprox, phi0approx, tapprox, z0approx; + double phiprojapprox[N_PSLAYER], zprojapprox[N_PSLAYER]; + double phiprojdiskapprox[N_DISK - 2], rprojdiskapprox[N_DISK - 2]; + + IMATH_TrackletCalculatorDisk* ITC; + if (disk == 1) + ITC = globals_->ITC_F1F2(); + else if (disk == 3) + ITC = globals_->ITC_F3F4(); + else if (disk == -1) + ITC = globals_->ITC_B1B2(); + else + ITC = globals_->ITC_B3B4(); + + ITC->r1.set_fval(r1); + ITC->r2.set_fval(r2); + int signt = t > 0 ? 1 : -1; + ITC->z1.set_fval(z1 - signt * settings_.zmean(layerdisk1_ - N_LAYER)); + ITC->z2.set_fval(z2 - signt * settings_.zmean(layerdisk2_ - N_LAYER)); + double sphi1 = angle0to2pi::make0To2pi(phi1 - phioffset_); + double sphi2 = angle0to2pi::make0To2pi(phi2 - phioffset_); + ITC->phi1.set_fval(sphi1); + ITC->phi2.set_fval(sphi2); + + ITC->rproj0.set_fval(settings_.rmean(0)); + ITC->rproj1.set_fval(settings_.rmean(1)); + ITC->rproj2.set_fval(settings_.rmean(2)); + + ITC->zproj0.set_fval(signt * settings_.zmean(settings_.projdisks(iSeed_, 0) - 1)); + ITC->zproj1.set_fval(signt * settings_.zmean(settings_.projdisks(iSeed_, 1) - 1)); + ITC->zproj2.set_fval(signt * settings_.zmean(settings_.projdisks(iSeed_, 2) - 1)); + + ITC->rinv_final.calculate(); + ITC->phi0_final.calculate(); + ITC->t_final.calculate(); + ITC->z0_final.calculate(); + + ITC->phiL_0_final.calculate(); + ITC->phiL_1_final.calculate(); + ITC->phiL_2_final.calculate(); + + ITC->zL_0_final.calculate(); + ITC->zL_1_final.calculate(); + ITC->zL_2_final.calculate(); + + ITC->phiD_0_final.calculate(); + ITC->phiD_1_final.calculate(); + ITC->phiD_2_final.calculate(); + + ITC->rD_0_final.calculate(); + ITC->rD_1_final.calculate(); + ITC->rD_2_final.calculate(); + + ITC->der_phiL_final.calculate(); + ITC->der_zL_final.calculate(); + ITC->der_phiD_final.calculate(); + ITC->der_rD_final.calculate(); + + //store the approximate results + rinvapprox = ITC->rinv_final.fval(); + phi0approx = ITC->phi0_final.fval(); + tapprox = ITC->t_final.fval(); + z0approx = ITC->z0_final.fval(); + + phiprojapprox[0] = ITC->phiL_0_final.fval(); + phiprojapprox[1] = ITC->phiL_1_final.fval(); + phiprojapprox[2] = ITC->phiL_2_final.fval(); + + zprojapprox[0] = ITC->zL_0_final.fval(); + zprojapprox[1] = ITC->zL_1_final.fval(); + zprojapprox[2] = ITC->zL_2_final.fval(); + + phiprojdiskapprox[0] = ITC->phiD_0_final.fval(); + phiprojdiskapprox[1] = ITC->phiD_1_final.fval(); + phiprojdiskapprox[2] = ITC->phiD_2_final.fval(); + + rprojdiskapprox[0] = ITC->rD_0_final.fval(); + rprojdiskapprox[1] = ITC->rD_1_final.fval(); + rprojdiskapprox[2] = ITC->rD_2_final.fval(); + + //now binary + + int irinv, iphi0, it, iz0; + int iphiproj[N_PSLAYER], izproj[N_PSLAYER]; + + int iphiprojdisk[N_DISK - 2], irprojdisk[N_DISK - 2]; + + int ir1 = innerFPGAStub->r().value(); + int iphi1 = innerFPGAStub->phi().value(); + int iz1 = innerFPGAStub->z().value(); + + int ir2 = outerFPGAStub->r().value(); + int iphi2 = outerFPGAStub->phi().value(); + int iz2 = outerFPGAStub->z().value(); + + //To get same precission as for layers. + iphi1 <<= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + iphi2 <<= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + + ITC->r1.set_ival(ir1); + ITC->r2.set_ival(ir2); + ITC->z1.set_ival(iz1); + ITC->z2.set_ival(iz2); + ITC->phi1.set_ival(iphi1); + ITC->phi2.set_ival(iphi2); + + ITC->rinv_final.calculate(); + ITC->phi0_final.calculate(); + ITC->t_final.calculate(); + ITC->z0_final.calculate(); + + ITC->phiL_0_final.calculate(); + ITC->phiL_1_final.calculate(); + ITC->phiL_2_final.calculate(); + + ITC->zL_0_final.calculate(); + ITC->zL_1_final.calculate(); + ITC->zL_2_final.calculate(); + + ITC->phiD_0_final.calculate(); + ITC->phiD_1_final.calculate(); + ITC->phiD_2_final.calculate(); + + ITC->rD_0_final.calculate(); + ITC->rD_1_final.calculate(); + ITC->rD_2_final.calculate(); + + ITC->der_phiL_final.calculate(); + ITC->der_zL_final.calculate(); + ITC->der_phiD_final.calculate(); + ITC->der_rD_final.calculate(); + + //store the binary results + irinv = ITC->rinv_final.ival(); + iphi0 = ITC->phi0_final.ival(); + it = ITC->t_final.ival(); + iz0 = ITC->z0_final.ival(); + + iphiproj[0] = ITC->phiL_0_final.ival(); + iphiproj[1] = ITC->phiL_1_final.ival(); + iphiproj[2] = ITC->phiL_2_final.ival(); + + izproj[0] = ITC->zL_0_final.ival(); + izproj[1] = ITC->zL_1_final.ival(); + izproj[2] = ITC->zL_2_final.ival(); + + if (!goodTrackPars(ITC->rinv_final.local_passes(), ITC->z0_final.local_passes())) + return false; + + if (!inSector(iphi0, irinv, phi0approx, rinvapprox)) + return false; + + LayerProjection layerprojs[N_LAYER - 2]; + DiskProjection diskprojs[N_DISK - 2]; + + for (unsigned int i = 0; i < N_DISK - 2; ++i) { + //Check is outside z range + if (izproj[i] < -(1 << (settings_.nzbitsstub(0) - 1))) + continue; + if (izproj[i] >= (1 << (settings_.nzbitsstub(0) - 1))) + continue; + + //Check if outside phi range + if (iphiproj[i] >= (1 << settings_.nphibitsstub(5)) - 1) + continue; + if (iphiproj[i] <= 0) + continue; + + //shift bits - allways in PS modules for disk seeding + iphiproj[i] >>= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + + layerprojs[i].init(settings_, + i + 1, + settings_.rmean(i), + iphiproj[i], + izproj[i], + ITC->der_phiL_final.ival(), + ITC->der_zL_final.ival(), + phiproj[i], + zproj[i], + phider[i], + zder[i], + phiprojapprox[i], + zprojapprox[i], + ITC->der_phiL_final.fval(), + ITC->der_zL_final.fval()); + } + + iphiprojdisk[0] = ITC->phiD_0_final.ival(); + iphiprojdisk[1] = ITC->phiD_1_final.ival(); + iphiprojdisk[2] = ITC->phiD_2_final.ival(); + + irprojdisk[0] = ITC->rD_0_final.ival(); + irprojdisk[1] = ITC->rD_1_final.ival(); + irprojdisk[2] = ITC->rD_2_final.ival(); + + for (unsigned int i = 0; i < N_DISK - 2; ++i) { + //check that phi projection in range + if (iphiprojdisk[i] <= 0) + continue; + if (iphiprojdisk[i] >= (1 << settings_.nphibitsstub(0)) - 1) + continue; + + //check that r projection in range + if (irprojdisk[i] <= 0 || irprojdisk[i] > settings_.rmaxdisk() / ITC->rD_0_final.K()) + continue; + + diskprojs[i].init(settings_, + i + 1, + settings_.zmean(settings_.projdisks(iSeed_, i) - 1), + iphiprojdisk[i], + irprojdisk[i], + ITC->der_phiD_final.ival(), + ITC->der_rD_final.ival(), + phiprojdisk[i], + rprojdisk[i], + phiderdisk[i], + rderdisk[i], + phiprojdiskapprox[i], + rprojdiskapprox[i], + ITC->der_phiD_final.fval(), + ITC->der_rD_final.fval()); + } + + if (settings_.writeMonitorData("TPars")) { + globals_->ofstream("trackletparsdisk.txt") + << "Trackpars " << layerdisk1_ - 5 << " " << rinv << " " << rinvapprox << " " + << ITC->rinv_final.fval() << " " << phi0 << " " << phi0approx << " " << ITC->phi0_final.fval() << " " << t + << " " << tapprox << " " << ITC->t_final.fval() << " " << z0 << " " << z0approx << " " << ITC->z0_final.fval() + << endl; + } + + Tracklet* tracklet = new Tracklet(settings_, + innerStub, + nullptr, + outerStub, + innerFPGAStub, + nullptr, + outerFPGAStub, + rinv, + phi0, + 0.0, + z0, + t, + rinvapprox, + phi0approx, + 0.0, + z0approx, + tapprox, + irinv, + iphi0, + 0, + iz0, + it, + layerprojs, + diskprojs, + true); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Found tracklet for disk seed = " << iSeed_ << " " << tracklet << " " << iSector_; + } + + tracklet->setTrackletIndex(trackletpars_->nTracklets()); + tracklet->setTCIndex(TCIndex_); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() << endl; + fout.close(); + } + trackletpars_->addTracklet(tracklet); + + if (tracklet->validProj(1)) { + addLayerProj(tracklet, 1); + } + + if (tracklet->validProj(2)) { + addLayerProj(tracklet, 2); + } + + for (unsigned int j = 0; j < N_DISK - 2; j++) { + if (tracklet->validProjDisk(sign * settings_.projdisks(iSeed_, j))) { + addDiskProj(tracklet, sign * settings_.projdisks(iSeed_, j)); + } + } + + return true; +} + +bool TrackletCalculatorBase::overlapSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub) { + //Deal with overlap stubs here + assert(outerFPGAStub->isBarrel()); + + assert(innerFPGAStub->isDisk()); + + int disk = innerFPGAStub->disk().value(); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "trying to make overlap tracklet for seed = " << iSeed_ << " " << getName(); + } + + double r1 = innerStub->r(); + double z1 = innerStub->z(); + double phi1 = innerStub->phi(); + + double r2 = outerStub->r(); + double z2 = outerStub->z(); + double phi2 = outerStub->phi(); + + //Protection for wrong radii. Could be handled cleaner to avoid problem with floating point calculation and with overflows in the integer calculation. + if (r1 < r2 + 1.5) { + return false; + } + + double rinv, phi0, t, z0; + + double phiproj[N_PSLAYER], zproj[N_PSLAYER], phider[N_PSLAYER], zder[N_PSLAYER]; + double phiprojdisk[N_DISK - 1], rprojdisk[N_DISK - 1], phiderdisk[N_DISK - 1], rderdisk[N_DISK - 1]; + + exacttrackletOverlap(r1, + z1, + phi1, + r2, + z2, + phi2, + outerStub->sigmaz(), + rinv, + phi0, + t, + z0, + phiproj, + zproj, + phider, + zder, + phiprojdisk, + rprojdisk, + phiderdisk, + rderdisk); + + //Truncates floating point positions to integer representation precision + if (settings_.useapprox()) { + phi1 = innerFPGAStub->phiapprox(phimin_, phimax_); + z1 = innerFPGAStub->zapprox(); + r1 = innerFPGAStub->rapprox(); + + phi2 = outerFPGAStub->phiapprox(phimin_, phimax_); + z2 = outerFPGAStub->zapprox(); + r2 = outerFPGAStub->rapprox(); + } + + double rinvapprox, phi0approx, tapprox, z0approx; + double phiprojapprox[N_PSLAYER], zprojapprox[N_PSLAYER]; + double phiprojdiskapprox[N_DISK - 1], rprojdiskapprox[N_DISK - 1]; + + IMATH_TrackletCalculatorOverlap* ITC; + int ll = outerFPGAStub->layer().value() + 1; + if (ll == 1 && disk == 1) + ITC = globals_->ITC_L1F1(); + else if (ll == 2 && disk == 1) + ITC = globals_->ITC_L2F1(); + else if (ll == 1 && disk == -1) + ITC = globals_->ITC_L1B1(); + else if (ll == 2 && disk == -1) + ITC = globals_->ITC_L2B1(); + else + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!"; + + ITC->r1.set_fval(r2 - settings_.rmean(ll - 1)); + ITC->r2.set_fval(r1); + int signt = t > 0 ? 1 : -1; + ITC->z1.set_fval(z2); + ITC->z2.set_fval(z1 - signt * settings_.zmean(layerdisk2_ - N_LAYER)); + double sphi1 = angle0to2pi::make0To2pi(phi1 - phioffset_); + double sphi2 = angle0to2pi::make0To2pi(phi2 - phioffset_); + ITC->phi1.set_fval(sphi2); + ITC->phi2.set_fval(sphi1); + + ITC->rproj0.set_fval(settings_.rmean(0)); + ITC->rproj1.set_fval(settings_.rmean(1)); + ITC->rproj2.set_fval(settings_.rmean(2)); + + ITC->zproj0.set_fval(signt * settings_.zmean(1)); + ITC->zproj1.set_fval(signt * settings_.zmean(2)); + ITC->zproj2.set_fval(signt * settings_.zmean(3)); + ITC->zproj3.set_fval(signt * settings_.zmean(4)); + + ITC->rinv_final.calculate(); + ITC->phi0_final.calculate(); + ITC->t_final.calculate(); + ITC->z0_final.calculate(); + + ITC->phiL_0_final.calculate(); + ITC->phiL_1_final.calculate(); + ITC->phiL_2_final.calculate(); + + ITC->zL_0_final.calculate(); + ITC->zL_1_final.calculate(); + ITC->zL_2_final.calculate(); + + ITC->phiD_0_final.calculate(); + ITC->phiD_1_final.calculate(); + ITC->phiD_2_final.calculate(); + ITC->phiD_3_final.calculate(); + + ITC->rD_0_final.calculate(); + ITC->rD_1_final.calculate(); + ITC->rD_2_final.calculate(); + ITC->rD_3_final.calculate(); + + ITC->der_phiL_final.calculate(); + ITC->der_zL_final.calculate(); + ITC->der_phiD_final.calculate(); + ITC->der_rD_final.calculate(); + + //store the approximate results + rinvapprox = ITC->rinv_final.fval(); + phi0approx = ITC->phi0_final.fval(); + tapprox = ITC->t_final.fval(); + z0approx = ITC->z0_final.fval(); + + phiprojapprox[0] = ITC->phiL_0_final.fval(); + phiprojapprox[1] = ITC->phiL_1_final.fval(); + phiprojapprox[2] = ITC->phiL_2_final.fval(); + + zprojapprox[0] = ITC->zL_0_final.fval(); + zprojapprox[1] = ITC->zL_1_final.fval(); + zprojapprox[2] = ITC->zL_2_final.fval(); + + phiprojdiskapprox[0] = ITC->phiD_0_final.fval(); + phiprojdiskapprox[1] = ITC->phiD_1_final.fval(); + phiprojdiskapprox[2] = ITC->phiD_2_final.fval(); + phiprojdiskapprox[3] = ITC->phiD_3_final.fval(); + + rprojdiskapprox[0] = ITC->rD_0_final.fval(); + rprojdiskapprox[1] = ITC->rD_1_final.fval(); + rprojdiskapprox[2] = ITC->rD_2_final.fval(); + rprojdiskapprox[3] = ITC->rD_3_final.fval(); + + //now binary + + int irinv, iphi0, it, iz0; + int iphiproj[N_LAYER - 2], izproj[N_LAYER - 2]; + int iphiprojdisk[N_DISK], irprojdisk[N_DISK]; + + int ir2 = innerFPGAStub->r().value(); + int iphi2 = innerFPGAStub->phi().value(); + int iz2 = innerFPGAStub->z().value(); + + int ir1 = outerFPGAStub->r().value(); + int iphi1 = outerFPGAStub->phi().value(); + int iz1 = outerFPGAStub->z().value(); + + //To get global precission + ir1 <<= (8 - settings_.nrbitsstub(ll - 1)); + iphi1 <<= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + iphi2 <<= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + + ITC->r1.set_ival(ir1); + ITC->r2.set_ival(ir2); + ITC->z1.set_ival(iz1); + ITC->z2.set_ival(iz2); + ITC->phi1.set_ival(iphi1); + ITC->phi2.set_ival(iphi2); + + ITC->rinv_final.calculate(); + ITC->phi0_final.calculate(); + ITC->t_final.calculate(); + ITC->z0_final.calculate(); + + ITC->phiL_0_final.calculate(); + ITC->phiL_1_final.calculate(); + ITC->phiL_2_final.calculate(); + + ITC->zL_0_final.calculate(); + ITC->zL_1_final.calculate(); + ITC->zL_2_final.calculate(); + + ITC->phiD_0_final.calculate(); + ITC->phiD_1_final.calculate(); + ITC->phiD_2_final.calculate(); + ITC->phiD_3_final.calculate(); + + ITC->rD_0_final.calculate(); + ITC->rD_1_final.calculate(); + ITC->rD_2_final.calculate(); + ITC->rD_3_final.calculate(); + + ITC->der_phiL_final.calculate(); + ITC->der_zL_final.calculate(); + ITC->der_phiD_final.calculate(); + ITC->der_rD_final.calculate(); + + //store the binary results + irinv = ITC->rinv_final.ival(); + iphi0 = ITC->phi0_final.ival(); + it = ITC->t_final.ival(); + iz0 = ITC->z0_final.ival(); + + iphiproj[0] = ITC->phiL_0_final.ival(); + iphiproj[1] = ITC->phiL_1_final.ival(); + iphiproj[2] = ITC->phiL_2_final.ival(); + + izproj[0] = ITC->zL_0_final.ival(); + izproj[1] = ITC->zL_1_final.ival(); + izproj[2] = ITC->zL_2_final.ival(); + + iphiprojdisk[0] = ITC->phiD_0_final.ival(); + iphiprojdisk[1] = ITC->phiD_1_final.ival(); + iphiprojdisk[2] = ITC->phiD_2_final.ival(); + iphiprojdisk[3] = ITC->phiD_3_final.ival(); + + irprojdisk[0] = ITC->rD_0_final.ival(); + irprojdisk[1] = ITC->rD_1_final.ival(); + irprojdisk[2] = ITC->rD_2_final.ival(); + irprojdisk[3] = ITC->rD_3_final.ival(); + + if (!goodTrackPars(ITC->rinv_final.local_passes(), ITC->z0_final.local_passes())) + return false; + + if (!inSector(iphi0, irinv, phi0approx, rinvapprox)) + return false; + + LayerProjection layerprojs[N_LAYER - 2]; + DiskProjection diskprojs[N_DISK]; + + for (unsigned int i = 0; i < N_DISK - 2; ++i) { + //check that zproj is in range + if (izproj[i] < -(1 << (settings_.nzbitsstub(0) - 1))) + continue; + if (izproj[i] >= (1 << (settings_.nzbitsstub(0) - 1))) + continue; + + //check that phiproj is in range + if (iphiproj[i] >= (1 << settings_.nphibitsstub(5)) - 1) + continue; + if (iphiproj[i] <= 0) + continue; + + //adjust bits for PS modules (no 2S modules in overlap seeds) + iphiproj[i] >>= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + + layerprojs[i].init(settings_, + i + 1, + settings_.rmean(i), + iphiproj[i], + izproj[i], + ITC->der_phiL_final.ival(), + ITC->der_zL_final.ival(), + phiproj[i], + zproj[i], + phider[i], + zder[i], + phiprojapprox[i], + zprojapprox[i], + ITC->der_phiL_final.fval(), + ITC->der_zL_final.fval()); + } + + for (int i = 0; i < 4; ++i) { + //check that phi projection in range + if (iphiprojdisk[i] <= 0) + continue; + if (iphiprojdisk[i] >= (1 << settings_.nphibitsstub(0)) - 1) + continue; + + //check that r projection in range + if (irprojdisk[i] <= 0 || irprojdisk[i] > settings_.rmaxdisk() / ITC->rD_0_final.K()) + continue; + + diskprojs[i].init(settings_, + i + 1, + settings_.zmean(i), + iphiprojdisk[i], + irprojdisk[i], + ITC->der_phiD_final.ival(), + ITC->der_rD_final.ival(), + phiprojdisk[i], + rprojdisk[i], + phiderdisk[i], + rderdisk[i], + phiprojdiskapprox[i], + rprojdiskapprox[i], + ITC->der_phiD_final.fval(), + ITC->der_rD_final.fval()); + } + + if (settings_.writeMonitorData("TPars")) { + globals_->ofstream("trackletparsoverlap.txt") + << "Trackpars " << layerdisk1_ - 5 << " " << rinv << " " << irinv << " " << ITC->rinv_final.fval() << " " + << phi0 << " " << iphi0 << " " << ITC->phi0_final.fval() << " " << t << " " << it << " " + << ITC->t_final.fval() << " " << z0 << " " << iz0 << " " << ITC->z0_final.fval() << endl; + } + + Tracklet* tracklet = new Tracklet(settings_, + innerStub, + nullptr, + outerStub, + innerFPGAStub, + nullptr, + outerFPGAStub, + rinv, + phi0, + 0.0, + z0, + t, + rinvapprox, + phi0approx, + 0.0, + z0approx, + tapprox, + irinv, + iphi0, + 0, + iz0, + it, + layerprojs, + diskprojs, + false, + true); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Found tracklet in overlap seed = " << iSeed_ << " " << tracklet << " " << iSector_; + } + + tracklet->setTrackletIndex(trackletpars_->nTracklets()); + tracklet->setTCIndex(TCIndex_); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() << endl; + fout.close(); + } + trackletpars_->addTracklet(tracklet); + + int layer = outerFPGAStub->layer().value() + 1; + + if (layer == 2) { + if (tracklet->validProj(1)) { + addLayerProj(tracklet, 1); + } + } + + for (unsigned int disk = 2; disk < 6; disk++) { + if (layer == 2 && disk == 5) + continue; + if (tracklet->validProjDisk(disk)) { + addDiskProj(tracklet, disk); + } + } + + return true; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletCalculatorDisplaced.cc b/L1Trigger/TrackFindingTracklet/src/TrackletCalculatorDisplaced.cc new file mode 100644 index 0000000000000..de2f0910c6697 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletCalculatorDisplaced.cc @@ -0,0 +1,1513 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletCalculatorDisplaced.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include "L1Trigger/TrackFindingTracklet/interface/Stub.h" +#include "L1Trigger/TrackFindingTracklet/interface/L1TStub.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +TrackletCalculatorDisplaced::TrackletCalculatorDisplaced(string name, + Settings const& settings, + Globals* global, + unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + for (unsigned int ilayer = 0; ilayer < N_LAYER; ilayer++) { + vector tmp(settings.nallstubs(ilayer), nullptr); + trackletprojlayers_.push_back(tmp); + } + + for (unsigned int idisk = 0; idisk < N_DISK; idisk++) { + vector tmp(settings.nallstubs(idisk + N_LAYER), nullptr); + trackletprojdisks_.push_back(tmp); + } + + layer_ = 0; + disk_ = 0; + + string name1 = name.substr(1); //this is to correct for "TCD" having one more letter then "TC" + if (name1[3] == 'L') + layer_ = name1[4] - '0'; + if (name1[3] == 'D') + disk_ = name1[4] - '0'; + + // set TC index + int iSeed = -1; + + int iTC = name1[9] - 'A'; + + if (name1.substr(3, 6) == "L3L4L2") + iSeed = 8; + else if (name1.substr(3, 6) == "L5L6L4") + iSeed = 9; + else if (name1.substr(3, 6) == "L2L3D1") + iSeed = 10; + else if (name1.substr(3, 6) == "D1D2L2") + iSeed = 11; + + assert(iSeed != -1); + + TCIndex_ = (iSeed << 4) + iTC; + assert(TCIndex_ >= 128 && TCIndex_ < 191); + + assert((layer_ != 0) || (disk_ != 0)); + + toR_.clear(); + toZ_.clear(); + + if (iSeed == 8 || iSeed == 9) { + if (layer_ == 3) { + rproj_[0] = settings_.rmean(0); + rproj_[1] = settings_.rmean(4); + rproj_[2] = settings_.rmean(5); + lproj_[0] = 1; + lproj_[1] = 5; + lproj_[2] = 6; + + dproj_[0] = 1; + dproj_[1] = 2; + dproj_[2] = 0; + toZ_.push_back(settings_.zmean(0)); + toZ_.push_back(settings_.zmean(1)); + } + if (layer_ == 5) { + rproj_[0] = settings_.rmean(0); + rproj_[1] = settings_.rmean(1); + rproj_[2] = settings_.rmean(2); + lproj_[0] = 1; + lproj_[1] = 2; + lproj_[2] = 3; + + dproj_[0] = 0; + dproj_[1] = 0; + dproj_[2] = 0; + } + for (unsigned int i = 0; i < N_LAYER - 3; ++i) + toR_.push_back(rproj_[i]); + } + + if (iSeed == 10 || iSeed == 11) { + if (layer_ == 2) { + rproj_[0] = settings_.rmean(0); + lproj_[0] = 1; + lproj_[1] = -1; + lproj_[2] = -1; + + zproj_[0] = settings_.zmean(1); + zproj_[1] = settings_.zmean(2); + zproj_[2] = settings_.zmean(3); + dproj_[0] = 2; + dproj_[1] = 3; + dproj_[2] = 4; + } + if (disk_ == 1) { + rproj_[0] = settings_.rmean(0); + lproj_[0] = 1; + lproj_[1] = -1; + lproj_[2] = -1; + + zproj_[0] = settings_.zmean(2); + zproj_[1] = settings_.zmean(3); + zproj_[2] = settings_.zmean(4); + dproj_[0] = 3; + dproj_[1] = 4; + dproj_[2] = 5; + } + toR_.push_back(settings_.rmean(0)); + for (unsigned int i = 0; i < N_DISK - 2; ++i) + toZ_.push_back(zproj_[i]); + } +} + +void TrackletCalculatorDisplaced::addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory) { + outputProj = dynamic_cast(memory); + assert(outputProj != nullptr); +} + +void TrackletCalculatorDisplaced::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "trackpar") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + trackletpars_ = tmp; + return; + } + + if (output.substr(0, 7) == "projout") { + //output is on the form 'projoutL2PHIC' or 'projoutD3PHIB' + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + + unsigned int layerdisk = output[8] - '1'; //layer or disk counting from 0 + unsigned int phiregion = output[12] - 'A'; //phiregion counting from 0 + + if (output[7] == 'L') { + assert(layerdisk < N_LAYER); + assert(phiregion < trackletprojlayers_[layerdisk].size()); + //check that phiregion not already initialized + assert(trackletprojlayers_[layerdisk][phiregion] == nullptr); + trackletprojlayers_[layerdisk][phiregion] = tmp; + return; + } + + if (output[7] == 'D') { + assert(layerdisk < N_DISK); + assert(phiregion < trackletprojdisks_[layerdisk].size()); + //check that phiregion not already initialized + assert(trackletprojdisks_[layerdisk][phiregion] == nullptr); + trackletprojdisks_[layerdisk][phiregion] = tmp; + return; + } + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void TrackletCalculatorDisplaced::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "thirdallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + innerallstubs_.push_back(tmp); + return; + } + if (input == "firstallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + middleallstubs_.push_back(tmp); + return; + } + if (input == "secondallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + outerallstubs_.push_back(tmp); + return; + } + if (input.find("stubtriplet") == 0) { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + stubtriplets_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input; +} + +void TrackletCalculatorDisplaced::execute() { + unsigned int countall = 0; + unsigned int countsel = 0; + + for (auto& stubtriplet : stubtriplets_) { + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on too many tracklets in " << getName(); + break; + } + for (unsigned int i = 0; i < stubtriplet->nStubTriplets(); i++) { + countall++; + + const Stub* innerFPGAStub = stubtriplet->getFPGAStub1(i); + const L1TStub* innerStub = innerFPGAStub->l1tstub(); + + const Stub* middleFPGAStub = stubtriplet->getFPGAStub2(i); + const L1TStub* middleStub = middleFPGAStub->l1tstub(); + + const Stub* outerFPGAStub = stubtriplet->getFPGAStub3(i); + const L1TStub* outerStub = outerFPGAStub->l1tstub(); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced execute " << getName() << "[" << iSector_ << "]"; + } + + if (innerFPGAStub->isBarrel() && middleFPGAStub->isBarrel() && outerFPGAStub->isBarrel()) { + //barrel+barrel seeding + bool accept = LLLSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); + if (accept) + countsel++; + } else if (innerFPGAStub->isDisk() && middleFPGAStub->isDisk() && outerFPGAStub->isDisk()) { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!"; + } else { + //layer+disk seeding + if (innerFPGAStub->isBarrel() && middleFPGAStub->isDisk() && outerFPGAStub->isDisk()) { //D1D2L2 + bool accept = DDLSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); + if (accept) + countsel++; + } else if (innerFPGAStub->isDisk() && middleFPGAStub->isBarrel() && outerFPGAStub->isBarrel()) { //L2L3D1 + bool accept = LLDSeeding(innerFPGAStub, innerStub, middleFPGAStub, middleStub, outerFPGAStub, outerStub); + if (accept) + countsel++; + } else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!"; + } + } + + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on number of tracklets in " << getName(); + break; + } + + if (countall >= settings_.maxStep("TC")) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Will break on MAXTC 1"; + break; + } + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced execute done"; + } + } + if (countall >= settings_.maxStep("TC")) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Will break on MAXTC 2"; + break; + } + } + + if (settings_.writeMonitorData("TPD")) { + globals_->ofstream("trackletcalculatordisplaced.txt") << getName() << " " << countall << " " << countsel << endl; + } +} + +void TrackletCalculatorDisplaced::addDiskProj(Tracklet* tracklet, int disk) { + FPGAWord fpgar = tracklet->fpgarprojdisk(disk); + + if (fpgar.value() * settings_.krprojshiftdisk() < settings_.rmindiskvm()) + return; + if (fpgar.value() * settings_.krprojshiftdisk() > settings_.rmaxdisk()) + return; + + FPGAWord fpgaphi = tracklet->fpgaphiprojdisk(disk); + + int iphivmRaw = fpgaphi.value() >> (fpgaphi.nbits() - 5); + int iphi = iphivmRaw / (32 / settings_.nallstubs(abs(disk) + N_DISK)); + + addProjectionDisk(disk, iphi, trackletprojdisks_[abs(disk) - 1][iphi], tracklet); +} + +bool TrackletCalculatorDisplaced::addLayerProj(Tracklet* tracklet, int layer) { + assert(layer > 0); + + FPGAWord fpgaz = tracklet->fpgazproj(layer); + FPGAWord fpgaphi = tracklet->fpgaphiproj(layer); + + if (fpgaz.atExtreme()) + return false; + + if (std::abs(fpgaz.value() * settings_.kz()) > settings_.zlength()) + return false; + + int iphivmRaw = fpgaphi.value() >> (fpgaphi.nbits() - 5); + int iphi = iphivmRaw / (32 / settings_.nallstubs(layer - 1)); + + addProjection(layer, iphi, trackletprojlayers_[layer - 1][iphi], tracklet); + + return true; +} + +void TrackletCalculatorDisplaced::addProjection(int layer, + int iphi, + TrackletProjectionsMemory* trackletprojs, + Tracklet* tracklet) { + if (trackletprojs == nullptr) { + if (settings_.warnNoMem()) { + edm::LogVerbatim("Tracklet") << "No projection memory exists in " << getName() << " for layer = " << layer + << " iphi = " << iphi + 1; + } + return; + } + assert(trackletprojs != nullptr); + trackletprojs->addProj(tracklet); +} + +void TrackletCalculatorDisplaced::addProjectionDisk(int disk, + int iphi, + TrackletProjectionsMemory* trackletprojs, + Tracklet* tracklet) { + if (trackletprojs == nullptr) { + if (layer_ == 3 && abs(disk) == 3) + return; //L3L4 projections to D3 are not used. + if (settings_.warnNoMem()) { + edm::LogVerbatim("Tracklet") << "No projection memory exists in " << getName() << " for disk = " << abs(disk) + << " iphi = " << iphi + 1; + } + return; + } + assert(trackletprojs != nullptr); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " adding projection to " << trackletprojs->getName(); + } + trackletprojs->addProj(tracklet); +} + +bool TrackletCalculatorDisplaced::LLLSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* middleFPGAStub, + const L1TStub* middleStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced " << getName() << " " << layer_ + << " trying stub triplet in layer (L L L): " << innerFPGAStub->layer().value() << " " + << middleFPGAStub->layer().value() << " " << outerFPGAStub->layer().value(); + } + + assert(outerFPGAStub->isBarrel()); + + double r1 = innerStub->r(); + double z1 = innerStub->z(); + double phi1 = innerStub->phi(); + + double r2 = middleStub->r(); + double z2 = middleStub->z(); + double phi2 = middleStub->phi(); + + double r3 = outerStub->r(); + double z3 = outerStub->z(); + double phi3 = outerStub->phi(); + + int take3 = 0; + if (layer_ == 5) + take3 = 1; + + double rinv, phi0, d0, t, z0; + + LayerProjection layerprojs[N_LAYER - 2]; + DiskProjection diskprojs[N_DISK]; + + double phiproj[N_LAYER - 2], zproj[N_LAYER - 2], phider[N_LAYER - 2], zder[N_LAYER - 2]; + double phiprojdisk[N_DISK], rprojdisk[N_DISK], phiderdisk[N_DISK], rderdisk[N_DISK]; + + exacttracklet(r1, + z1, + phi1, + r2, + z2, + phi2, + r3, + z3, + phi3, + take3, + rinv, + phi0, + d0, + t, + z0, + phiproj, + zproj, + phiprojdisk, + rprojdisk, + phider, + zder, + phiderdisk, + rderdisk); + + if (settings_.useapprox()) { + phi1 = innerFPGAStub->phiapprox(phimin_, phimax_); + z1 = innerFPGAStub->zapprox(); + r1 = innerFPGAStub->rapprox(); + + phi2 = outerFPGAStub->phiapprox(phimin_, phimax_); + z2 = outerFPGAStub->zapprox(); + r2 = outerFPGAStub->rapprox(); + } + + double rinvapprox, phi0approx, d0approx, tapprox, z0approx; + double phiprojapprox[N_LAYER - 2], zprojapprox[N_LAYER - 2], phiderapprox[N_LAYER - 2], zderapprox[N_LAYER - 2]; + double phiprojdiskapprox[N_DISK], rprojdiskapprox[N_DISK]; + double phiderdiskapprox[N_DISK], rderdiskapprox[N_DISK]; + + //TODO: implement the actual integer calculation + + //store the approcximate results + rinvapprox = rinv; + phi0approx = phi0; + d0approx = d0; + tapprox = t; + z0approx = z0; + + for (unsigned int i = 0; i < toR_.size(); ++i) { + phiprojapprox[i] = phiproj[i]; + zprojapprox[i] = zproj[i]; + phiderapprox[i] = phider[i]; + zderapprox[i] = zder[i]; + } + + for (unsigned int i = 0; i < toZ_.size(); ++i) { + phiprojdiskapprox[i] = phiprojdisk[i]; + rprojdiskapprox[i] = rprojdisk[i]; + phiderdiskapprox[i] = phiderdisk[i]; + rderdiskapprox[i] = rderdisk[i]; + } + + //now binary + double krinv = settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()), + kphi0 = settings_.kphi1() * pow(2, settings_.phi0_shift()), + kt = settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()), + kz0 = settings_.kz() * pow(2, settings_.z0_shift()), + kphiproj = settings_.kphi1() * pow(2, settings_.SS_phiL_shift()), + kphider = settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift()), + kzproj = settings_.kz() * pow(2, settings_.PS_zL_shift()), + kzder = settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift()), + kphiprojdisk = settings_.kphi1() * pow(2, settings_.SS_phiD_shift()), + kphiderdisk = settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift()), + krprojdisk = settings_.kr() * pow(2, settings_.PS_rD_shift()), + krderdisk = settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift()); + + int irinv, iphi0, id0, it, iz0; + int iphiproj[N_LAYER - 2], izproj[N_LAYER - 2], iphider[N_LAYER - 2], izder[N_LAYER - 2]; + int iphiprojdisk[N_DISK], irprojdisk[N_DISK], iphiderdisk[N_DISK], irderdisk[N_DISK]; + + //store the binary results + irinv = rinvapprox / krinv; + iphi0 = phi0approx / kphi0; + id0 = d0approx / settings_.kd0(); + it = tapprox / kt; + iz0 = z0approx / kz0; + + bool success = true; + if (std::abs(rinvapprox) > settings_.rinvcut()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "TrackletCalculator::LLL Seeding irinv too large: " << rinvapprox << "(" << irinv + << ")"; + success = false; + } + if (std::abs(z0approx) > 1.8 * settings_.z0cut()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Failed tracklet z0 cut " << z0approx << " in layer " << layer_; + success = false; + } + if (std::abs(d0approx) > settings_.maxd0()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Failed tracklet d0 cut " << d0approx; + success = false; + } + + if (!success) + return false; + + double phicritapprox = phi0approx - asin(0.5 * settings_.rcrit() * rinvapprox); + int phicrit = iphi0 - 2 * irinv; + + int iphicritmincut = settings_.phicritminmc() / globals_->ITC_L1L2()->phi0_final.K(); + int iphicritmaxcut = settings_.phicritmaxmc() / globals_->ITC_L1L2()->phi0_final.K(); + + bool keepapprox = (phicritapprox > settings_.phicritminmc()) && (phicritapprox < settings_.phicritmaxmc()), + keep = (phicrit > iphicritmincut) && (phicrit < iphicritmaxcut); + + if (settings_.debugTracklet()) + if (keep && !keepapprox) + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced::LLLSeeding tracklet kept with exact phicrit cut " + "but not approximate, phicritapprox: " + << phicritapprox; + if (settings_.usephicritapprox()) { + if (!keepapprox) + return false; + } else { + if (!keep) + return false; + } + + for (unsigned int i = 0; i < toR_.size(); ++i) { + iphiproj[i] = phiprojapprox[i] / kphiproj; + izproj[i] = zprojapprox[i] / kzproj; + + iphider[i] = phiderapprox[i] / kphider; + izder[i] = zderapprox[i] / kzder; + + //check that z projection is in range + if (izproj[i] < -(1 << (settings_.nzbitsstub(0) - 1))) + continue; + if (izproj[i] >= (1 << (settings_.nzbitsstub(0) - 1))) + continue; + + //check that phi projection is in range + if (iphiproj[i] >= (1 << settings_.nphibitsstub(N_LAYER - 1)) - 1) + continue; + if (iphiproj[i] <= 0) + continue; + + //adjust number of bits for phi and z projection + if (rproj_[i] < settings_.rPS2S()) { + iphiproj[i] >>= (settings_.nphibitsstub(N_LAYER - 1) - settings_.nphibitsstub(0)); + if (iphiproj[i] >= (1 << settings_.nphibitsstub(0)) - 1) + iphiproj[i] = (1 << settings_.nphibitsstub(0)) - 2; //-2 not to hit atExtreme + } else { + izproj[i] >>= (settings_.nzbitsstub(0) - settings_.nzbitsstub(N_LAYER - 1)); + } + + if (rproj_[i] < settings_.rPS2S()) { + if (iphider[i] < -(1 << (settings_.nbitsphiprojderL123() - 1))) { + iphider[i] = -(1 << (settings_.nbitsphiprojderL123() - 1)); + } + if (iphider[i] >= (1 << (settings_.nbitsphiprojderL123() - 1))) { + iphider[i] = (1 << (settings_.nbitsphiprojderL123() - 1)) - 1; + } + } else { + if (iphider[i] < -(1 << (settings_.nbitsphiprojderL456() - 1))) { + iphider[i] = -(1 << (settings_.nbitsphiprojderL456() - 1)); + } + if (iphider[i] >= (1 << (settings_.nbitsphiprojderL456() - 1))) { + iphider[i] = (1 << (settings_.nbitsphiprojderL456() - 1)) - 1; + } + } + + layerprojs[i].init(settings_, + lproj_[i], + rproj_[i], + iphiproj[i], + izproj[i], + iphider[i], + izder[i], + phiproj[i], + zproj[i], + phider[i], + zder[i], + phiprojapprox[i], + zprojapprox[i], + phiderapprox[i], + zderapprox[i]); + } + + if (std::abs(it * kt) > 1.0) { + for (unsigned int i = 0; i < toZ_.size(); ++i) { + iphiprojdisk[i] = phiprojdiskapprox[i] / kphiprojdisk; + irprojdisk[i] = rprojdiskapprox[i] / krprojdisk; + + iphiderdisk[i] = phiderdiskapprox[i] / kphiderdisk; + irderdisk[i] = rderdiskapprox[i] / krderdisk; + + //check phi projection in range + if (iphiprojdisk[i] <= 0) + continue; + if (iphiprojdisk[i] >= (1 << settings_.nphibitsstub(0)) - 1) + continue; + + //check r projection in range + if (rprojdiskapprox[i] < settings_.rmindisk() || rprojdiskapprox[i] > settings_.rmaxdisk()) + continue; + + diskprojs[i].init(settings_, + i + 1, + rproj_[i], + iphiprojdisk[i], + irprojdisk[i], + iphiderdisk[i], + irderdisk[i], + phiprojdisk[i], + rprojdisk[i], + phiderdisk[i], + rderdisk[i], + phiprojdiskapprox[i], + rprojdiskapprox[i], + phiderdisk[i], + rderdisk[i]); + } + } + + if (settings_.writeMonitorData("TrackletPars")) { + globals_->ofstream("trackletpars.txt") + << "Trackpars " << layer_ << " " << rinv << " " << rinvapprox << " " << rinvapprox << " " << phi0 << " " + << phi0approx << " " << phi0approx << " " << t << " " << tapprox << " " << tapprox << " " << z0 << " " + << z0approx << " " << z0approx << endl; + } + + Tracklet* tracklet = new Tracklet(settings_, + innerStub, + middleStub, + outerStub, + innerFPGAStub, + middleFPGAStub, + outerFPGAStub, + rinv, + phi0, + d0, + z0, + t, + rinvapprox, + phi0approx, + d0approx, + z0approx, + tapprox, + irinv, + iphi0, + id0, + iz0, + it, + layerprojs, + diskprojs, + false); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced " << getName() + << " Found LLL tracklet in sector = " << iSector_ << " phi0 = " << phi0; + } + + tracklet->setTrackletIndex(trackletpars_->nTracklets()); + tracklet->setTCIndex(TCIndex_); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() << endl; + fout.close(); + } + trackletpars_->addTracklet(tracklet); + + bool addL5 = false; + bool addL6 = false; + for (unsigned int j = 0; j < toR_.size(); j++) { + bool added = false; + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "adding layer projection " << j << "/" << toR_.size() << " " << lproj_[j]; + if (tracklet->validProj(lproj_[j])) { + added = addLayerProj(tracklet, lproj_[j]); + if (added && lproj_[j] == 5) + addL5 = true; + if (added && lproj_[j] == 6) + addL6 = true; + } + } + + for (unsigned int j = 0; j < toZ_.size(); j++) { + int disk = dproj_[j]; + if (disk == 0) + continue; + if (disk == 2 && addL5) + continue; + if (disk == 1 && addL6) + continue; + if (it < 0) + disk = -disk; + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "adding disk projection " << j << "/" << toZ_.size() << " " << disk; + if (tracklet->validProjDisk(abs(disk))) { + addDiskProj(tracklet, disk); + } + } + + return true; +} + +bool TrackletCalculatorDisplaced::DDLSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* middleFPGAStub, + const L1TStub* middleStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced " << getName() << " " << layer_ + << " trying stub triplet in (L2 D1 D2): " << innerFPGAStub->layer().value() << " " + << middleFPGAStub->disk().value() << " " << outerFPGAStub->disk().value(); + } + + int take3 = 1; //D1D2L2 + + double r1 = innerStub->r(); + double z1 = innerStub->z(); + double phi1 = innerStub->phi(); + + double r2 = middleStub->r(); + double z2 = middleStub->z(); + double phi2 = middleStub->phi(); + + double r3 = outerStub->r(); + double z3 = outerStub->z(); + double phi3 = outerStub->phi(); + + double rinv, phi0, d0, t, z0; + + double phiproj[N_LAYER - 2], zproj[N_LAYER - 2], phider[N_LAYER - 2], zder[N_LAYER - 2]; + double phiprojdisk[N_DISK], rprojdisk[N_DISK], phiderdisk[N_DISK], rderdisk[N_DISK]; + + exacttracklet(r1, + z1, + phi1, + r2, + z2, + phi2, + r3, + z3, + phi3, + take3, + rinv, + phi0, + d0, + t, + z0, + phiproj, + zproj, + phiprojdisk, + rprojdisk, + phider, + zder, + phiderdisk, + rderdisk); + + if (settings_.useapprox()) { + phi1 = innerFPGAStub->phiapprox(phimin_, phimax_); + z1 = innerFPGAStub->zapprox(); + r1 = innerFPGAStub->rapprox(); + + phi2 = outerFPGAStub->phiapprox(phimin_, phimax_); + z2 = outerFPGAStub->zapprox(); + r2 = outerFPGAStub->rapprox(); + } + + double rinvapprox, phi0approx, d0approx, tapprox, z0approx; + double phiprojapprox[N_LAYER - 2], zprojapprox[N_LAYER - 2], phiderapprox[N_LAYER - 2], zderapprox[N_LAYER - 2]; + double phiprojdiskapprox[N_DISK], rprojdiskapprox[N_DISK]; + double phiderdiskapprox[N_DISK], rderdiskapprox[N_DISK]; + + //TODO: implement the actual integer calculation + + //store the approcximate results + rinvapprox = rinv; + phi0approx = phi0; + d0approx = d0; + tapprox = t; + z0approx = z0; + + for (unsigned int i = 0; i < toR_.size(); ++i) { + phiprojapprox[i] = phiproj[i]; + zprojapprox[i] = zproj[i]; + phiderapprox[i] = phider[i]; + zderapprox[i] = zder[i]; + } + + for (unsigned int i = 0; i < toZ_.size(); ++i) { + phiprojdiskapprox[i] = phiprojdisk[i]; + rprojdiskapprox[i] = rprojdisk[i]; + phiderdiskapprox[i] = phiderdisk[i]; + rderdiskapprox[i] = rderdisk[i]; + } + + //now binary + double krinv = settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()), + kphi0 = settings_.kphi1() * pow(2, settings_.phi0_shift()), + kt = settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()), + kz0 = settings_.kz() * pow(2, settings_.z0_shift()), + kphiproj = settings_.kphi1() * pow(2, settings_.SS_phiL_shift()), + kphider = settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift()), + kzproj = settings_.kz() * pow(2, settings_.PS_zL_shift()), + kzder = settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift()), + kphiprojdisk = settings_.kphi1() * pow(2, settings_.SS_phiD_shift()), + kphiderdisk = settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift()), + krprojdisk = settings_.kr() * pow(2, settings_.PS_rD_shift()), + krderdisk = settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift()); + + int irinv, iphi0, id0, it, iz0; + int iphiproj[N_LAYER - 2], izproj[N_LAYER - 2], iphider[N_LAYER - 2], izder[N_LAYER - 2]; + int iphiprojdisk[N_DISK], irprojdisk[N_DISK], iphiderdisk[N_DISK], irderdisk[N_DISK]; + + //store the binary results + irinv = rinvapprox / krinv; + iphi0 = phi0approx / kphi0; + id0 = d0approx / settings_.kd0(); + it = tapprox / kt; + iz0 = z0approx / kz0; + + bool success = true; + if (std::abs(rinvapprox) > settings_.rinvcut()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "TrackletCalculator::DDL Seeding irinv too large: " << rinvapprox << "(" << irinv + << ")"; + success = false; + } + if (std::abs(z0approx) > 1.8 * settings_.z0cut()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Failed tracklet z0 cut " << z0approx; + success = false; + } + if (std::abs(d0approx) > settings_.maxd0()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Failed tracklet d0 cut " << d0approx; + success = false; + } + + if (!success) + return false; + + double phicritapprox = phi0approx - asin(0.5 * settings_.rcrit() * rinvapprox); + int phicrit = iphi0 - 2 * irinv; + + int iphicritmincut = settings_.phicritminmc() / globals_->ITC_L1L2()->phi0_final.K(); + int iphicritmaxcut = settings_.phicritmaxmc() / globals_->ITC_L1L2()->phi0_final.K(); + + bool keepapprox = (phicritapprox > settings_.phicritminmc()) && (phicritapprox < settings_.phicritmaxmc()), + keep = (phicrit > iphicritmincut) && (phicrit < iphicritmaxcut); + + if (settings_.debugTracklet()) + if (keep && !keepapprox) + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced::DDLSeeding tracklet kept with exact phicrit cut " + "but not approximate, phicritapprox: " + << phicritapprox; + if (settings_.usephicritapprox()) { + if (!keepapprox) + return false; + } else { + if (!keep) + return false; + } + + LayerProjection layerprojs[N_LAYER - 2]; + DiskProjection diskprojs[N_DISK]; + + for (unsigned int i = 0; i < toR_.size(); ++i) { + iphiproj[i] = phiprojapprox[i] / kphiproj; + izproj[i] = zprojapprox[i] / kzproj; + + iphider[i] = phiderapprox[i] / kphider; + izder[i] = zderapprox[i] / kzder; + + //check that z projection in range + if (izproj[i] < -(1 << (settings_.nzbitsstub(0) - 1))) + continue; + if (izproj[i] >= (1 << (settings_.nzbitsstub(0) - 1))) + continue; + + //check that phi projection in range + if (iphiproj[i] >= (1 << settings_.nphibitsstub(5)) - 1) + continue; + if (iphiproj[i] <= 0) + continue; + + if (rproj_[i] < settings_.rPS2S()) { + iphiproj[i] >>= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + } else { + izproj[i] >>= (settings_.nzbitsstub(0) - settings_.nzbitsstub(5)); + } + + if (rproj_[i] < settings_.rPS2S()) { + if (iphider[i] < -(1 << (settings_.nbitsphiprojderL123() - 1))) + iphider[i] = -(1 << (settings_.nbitsphiprojderL123() - 1)); + if (iphider[i] >= (1 << (settings_.nbitsphiprojderL123() - 1))) + iphider[i] = (1 << (settings_.nbitsphiprojderL123() - 1)) - 1; + } else { + if (iphider[i] < -(1 << (settings_.nbitsphiprojderL456() - 1))) + iphider[i] = -(1 << (settings_.nbitsphiprojderL456() - 1)); + if (iphider[i] >= (1 << (settings_.nbitsphiprojderL456() - 1))) + iphider[i] = (1 << (settings_.nbitsphiprojderL456() - 1)) - 1; + } + + layerprojs[i].init(settings_, + lproj_[i], + rproj_[i], + iphiproj[i], + izproj[i], + iphider[i], + izder[i], + phiproj[i], + zproj[i], + phider[i], + zder[i], + phiprojapprox[i], + zprojapprox[i], + phiderapprox[i], + zderapprox[i]); + } + + if (std::abs(it * kt) > 1.0) { + for (unsigned int i = 0; i < toZ_.size(); ++i) { + iphiprojdisk[i] = phiprojdiskapprox[i] / kphiprojdisk; + irprojdisk[i] = rprojdiskapprox[i] / krprojdisk; + + iphiderdisk[i] = phiderdiskapprox[i] / kphiderdisk; + irderdisk[i] = rderdiskapprox[i] / krderdisk; + + if (iphiprojdisk[i] <= 0) + continue; + if (iphiprojdisk[i] >= (1 << settings_.nphibitsstub(0)) - 1) + continue; + + if (irprojdisk[i] < settings_.rmindisk() / krprojdisk || irprojdisk[i] > settings_.rmaxdisk() / krprojdisk) + continue; + + diskprojs[i].init(settings_, + i + 1, + rproj_[i], + iphiprojdisk[i], + irprojdisk[i], + iphiderdisk[i], + irderdisk[i], + phiprojdisk[i], + rprojdisk[i], + phiderdisk[i], + rderdisk[i], + phiprojdiskapprox[i], + rprojdiskapprox[i], + phiderdisk[i], + rderdisk[i]); + } + } + + if (settings_.writeMonitorData("TrackletPars")) { + globals_->ofstream("trackletpars.txt") + << "Trackpars " << layer_ << " " << rinv << " " << rinvapprox << " " << rinvapprox << " " << phi0 << " " + << phi0approx << " " << phi0approx << " " << t << " " << tapprox << " " << tapprox << " " << z0 << " " + << z0approx << " " << z0approx << endl; + } + + Tracklet* tracklet = new Tracklet(settings_, + innerStub, + middleStub, + outerStub, + innerFPGAStub, + middleFPGAStub, + outerFPGAStub, + rinv, + phi0, + d0, + z0, + t, + rinvapprox, + phi0approx, + d0approx, + z0approx, + tapprox, + irinv, + iphi0, + id0, + iz0, + it, + layerprojs, + diskprojs, + true); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced " << getName() + << " Found DDL tracklet in sector = " << iSector_ << " phi0 = " << phi0; + } + + tracklet->setTrackletIndex(trackletpars_->nTracklets()); + tracklet->setTCIndex(TCIndex_); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() << endl; + fout.close(); + } + trackletpars_->addTracklet(tracklet); + + for (unsigned int j = 0; j < toR_.size(); j++) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "adding layer projection " << j << "/" << toR_.size() << " " << lproj_[j] << " " + << tracklet->validProj(lproj_[j]); + if (tracklet->validProj(lproj_[j])) { + addLayerProj(tracklet, lproj_[j]); + } + } + + for (unsigned int j = 0; j < toZ_.size(); j++) { + int disk = dproj_[j]; + if (disk == 0) + continue; + if (it < 0) + disk = -disk; + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "adding disk projection " << j << "/" << toZ_.size() << " " << disk << " " + << tracklet->validProjDisk(abs(disk)); + if (tracklet->validProjDisk(abs(disk))) { + addDiskProj(tracklet, disk); + } + } + + return true; +} + +bool TrackletCalculatorDisplaced::LLDSeeding(const Stub* innerFPGAStub, + const L1TStub* innerStub, + const Stub* middleFPGAStub, + const L1TStub* middleStub, + const Stub* outerFPGAStub, + const L1TStub* outerStub) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced " << getName() << " " << layer_ + << " trying stub triplet in (L2L3D1): " << middleFPGAStub->layer().value() << " " + << outerFPGAStub->layer().value() << " " << innerFPGAStub->disk().value(); + } + + int take3 = 0; //L2L3D1 + + double r3 = innerStub->r(); + double z3 = innerStub->z(); + double phi3 = innerStub->phi(); + + double r1 = middleStub->r(); + double z1 = middleStub->z(); + double phi1 = middleStub->phi(); + + double r2 = outerStub->r(); + double z2 = outerStub->z(); + double phi2 = outerStub->phi(); + + double rinv, phi0, d0, t, z0; + + double phiproj[N_LAYER - 2], zproj[N_LAYER - 2], phider[N_LAYER - 2], zder[N_LAYER - 2]; + double phiprojdisk[N_DISK], rprojdisk[N_DISK], phiderdisk[N_DISK], rderdisk[N_DISK]; + + exacttracklet(r1, + z1, + phi1, + r2, + z2, + phi2, + r3, + z3, + phi3, + take3, + rinv, + phi0, + d0, + t, + z0, + phiproj, + zproj, + phiprojdisk, + rprojdisk, + phider, + zder, + phiderdisk, + rderdisk); + + if (settings_.useapprox()) { + phi1 = innerFPGAStub->phiapprox(phimin_, phimax_); + z1 = innerFPGAStub->zapprox(); + r1 = innerFPGAStub->rapprox(); + + phi2 = outerFPGAStub->phiapprox(phimin_, phimax_); + z2 = outerFPGAStub->zapprox(); + r2 = outerFPGAStub->rapprox(); + } + + double rinvapprox, phi0approx, d0approx, tapprox, z0approx; + double phiprojapprox[N_LAYER - 2], zprojapprox[N_LAYER - 2], phiderapprox[N_LAYER - 2], zderapprox[N_LAYER - 2]; + double phiprojdiskapprox[N_DISK], rprojdiskapprox[N_DISK]; + double phiderdiskapprox[N_DISK], rderdiskapprox[N_DISK]; + + //TODO: implement the actual integer calculation + + //store the approcximate results + rinvapprox = rinv; + phi0approx = phi0; + d0approx = d0; + tapprox = t; + z0approx = z0; + + for (unsigned int i = 0; i < toR_.size(); ++i) { + phiprojapprox[i] = phiproj[i]; + zprojapprox[i] = zproj[i]; + phiderapprox[i] = phider[i]; + zderapprox[i] = zder[i]; + } + + for (unsigned int i = 0; i < toZ_.size(); ++i) { + phiprojdiskapprox[i] = phiprojdisk[i]; + rprojdiskapprox[i] = rprojdisk[i]; + phiderdiskapprox[i] = phiderdisk[i]; + rderdiskapprox[i] = rderdisk[i]; + } + + //now binary + double krinv = settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()), + kphi0 = settings_.kphi1() * pow(2, settings_.phi0_shift()), + kt = settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()), + kz0 = settings_.kz() * pow(2, settings_.z0_shift()), + kphiproj = settings_.kphi1() * pow(2, settings_.SS_phiL_shift()), + kphider = settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderL_shift()), + kzproj = settings_.kz() * pow(2, settings_.PS_zL_shift()), + kzder = settings_.kz() / settings_.kr() * pow(2, settings_.PS_zderL_shift()), + kphiprojdisk = settings_.kphi1() * pow(2, settings_.SS_phiD_shift()), + kphiderdisk = settings_.kphi1() / settings_.kr() * pow(2, settings_.SS_phiderD_shift()), + krprojdisk = settings_.kr() * pow(2, settings_.PS_rD_shift()), + krderdisk = settings_.kr() / settings_.kz() * pow(2, settings_.PS_rderD_shift()); + + int irinv, iphi0, id0, it, iz0; + int iphiproj[N_LAYER - 2], izproj[N_LAYER - 2], iphider[N_LAYER - 2], izder[N_LAYER - 2]; + int iphiprojdisk[N_DISK], irprojdisk[N_DISK], iphiderdisk[N_DISK], irderdisk[N_DISK]; + + //store the binary results + irinv = rinvapprox / krinv; + iphi0 = phi0approx / kphi0; + id0 = d0approx / settings_.kd0(); + it = tapprox / kt; + iz0 = z0approx / kz0; + + bool success = true; + if (std::abs(rinvapprox) > settings_.rinvcut()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "TrackletCalculator:: LLD Seeding irinv too large: " << rinvapprox << "(" << irinv + << ")"; + success = false; + } + if (std::abs(z0approx) > 1.8 * settings_.z0cut()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Failed tracklet z0 cut " << z0approx; + success = false; + } + if (std::abs(d0approx) > settings_.maxd0()) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Failed tracklet d0 cut " << d0approx; + success = false; + } + + if (!success) + return false; + + double phicritapprox = phi0approx - asin(0.5 * settings_.rcrit() * rinvapprox); + int phicrit = iphi0 - 2 * irinv; + + int iphicritmincut = settings_.phicritminmc() / globals_->ITC_L1L2()->phi0_final.K(); + int iphicritmaxcut = settings_.phicritmaxmc() / globals_->ITC_L1L2()->phi0_final.K(); + + bool keepapprox = (phicritapprox > settings_.phicritminmc()) && (phicritapprox < settings_.phicritmaxmc()), + keep = (phicrit > iphicritmincut) && (phicrit < iphicritmaxcut); + + if (settings_.debugTracklet()) + if (keep && !keepapprox) + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced::LLDSeeding tracklet kept with exact phicrit cut " + "but not approximate, phicritapprox: " + << phicritapprox; + if (settings_.usephicritapprox()) { + if (!keepapprox) + return false; + } else { + if (!keep) + return false; + } + + LayerProjection layerprojs[N_LAYER - 2]; + DiskProjection diskprojs[N_DISK]; + + for (unsigned int i = 0; i < toR_.size(); ++i) { + iphiproj[i] = phiprojapprox[i] / kphiproj; + izproj[i] = zprojapprox[i] / kzproj; + + iphider[i] = phiderapprox[i] / kphider; + izder[i] = zderapprox[i] / kzder; + + if (izproj[i] < -(1 << (settings_.nzbitsstub(0) - 1))) + continue; + if (izproj[i] >= (1 << (settings_.nzbitsstub(0) - 1))) + continue; + + //this is left from the original.... + if (iphiproj[i] >= (1 << settings_.nphibitsstub(5)) - 1) + continue; + if (iphiproj[i] <= 0) + continue; + + if (rproj_[i] < settings_.rPS2S()) { + iphiproj[i] >>= (settings_.nphibitsstub(5) - settings_.nphibitsstub(0)); + } else { + izproj[i] >>= (settings_.nzbitsstub(0) - settings_.nzbitsstub(5)); + } + + if (rproj_[i] < settings_.rPS2S()) { + if (iphider[i] < -(1 << (settings_.nbitsphiprojderL123() - 1))) + iphider[i] = -(1 << (settings_.nbitsphiprojderL123() - 1)); + if (iphider[i] >= (1 << (settings_.nbitsphiprojderL123() - 1))) + iphider[i] = (1 << (settings_.nbitsphiprojderL123() - 1)) - 1; + } else { + if (iphider[i] < -(1 << (settings_.nbitsphiprojderL456() - 1))) + iphider[i] = -(1 << (settings_.nbitsphiprojderL456() - 1)); + if (iphider[i] >= (1 << (settings_.nbitsphiprojderL456() - 1))) + iphider[i] = (1 << (settings_.nbitsphiprojderL456() - 1)) - 1; + } + + layerprojs[i].init(settings_, + lproj_[i], + rproj_[i], + iphiproj[i], + izproj[i], + iphider[i], + izder[i], + phiproj[i], + zproj[i], + phider[i], + zder[i], + phiprojapprox[i], + zprojapprox[i], + phiderapprox[i], + zderapprox[i]); + } + + if (std::abs(it * kt) > 1.0) { + for (unsigned int i = 0; i < toZ_.size(); ++i) { + iphiprojdisk[i] = phiprojdiskapprox[i] / kphiprojdisk; + irprojdisk[i] = rprojdiskapprox[i] / krprojdisk; + + iphiderdisk[i] = phiderdiskapprox[i] / kphiderdisk; + irderdisk[i] = rderdiskapprox[i] / krderdisk; + + //Check phi range of projection + if (iphiprojdisk[i] <= 0) + continue; + if (iphiprojdisk[i] >= (1 << settings_.nphibitsstub(0)) - 1) + continue; + + //Check r range of projection + if (irprojdisk[i] < settings_.rmindisk() / krprojdisk || irprojdisk[i] > settings_.rmaxdisk() / krprojdisk) + continue; + + diskprojs[i].init(settings_, + i + 1, + rproj_[i], + iphiprojdisk[i], + irprojdisk[i], + iphiderdisk[i], + irderdisk[i], + phiprojdisk[i], + rprojdisk[i], + phiderdisk[i], + rderdisk[i], + phiprojdiskapprox[i], + rprojdiskapprox[i], + phiderdisk[i], + rderdisk[i]); + } + } + + if (settings_.writeMonitorData("TrackletPars")) { + globals_->ofstream("trackletpars.txt") + << "Trackpars " << layer_ << " " << rinv << " " << rinvapprox << " " << rinvapprox << " " << phi0 << " " + << phi0approx << " " << phi0approx << " " << t << " " << tapprox << " " << tapprox << " " << z0 << " " + << z0approx << " " << z0approx << endl; + } + + Tracklet* tracklet = new Tracklet(settings_, + innerStub, + middleStub, + outerStub, + innerFPGAStub, + middleFPGAStub, + outerFPGAStub, + rinv, + phi0, + d0, + z0, + t, + rinvapprox, + phi0approx, + d0approx, + z0approx, + tapprox, + irinv, + iphi0, + id0, + iz0, + it, + layerprojs, + diskprojs, + false); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced " << getName() + << " Found LLD tracklet in sector = " << iSector_ << " phi0 = " << phi0; + } + + tracklet->setTrackletIndex(trackletpars_->nTracklets()); + tracklet->setTCIndex(TCIndex_); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << tracklet->getISeed() << endl; + fout.close(); + } + trackletpars_->addTracklet(tracklet); + + for (unsigned int j = 0; j < toR_.size(); j++) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "adding layer projection " << j << "/" << toR_.size() << " " << lproj_[j]; + if (tracklet->validProj(lproj_[j])) { + addLayerProj(tracklet, lproj_[j]); + } + } + + for (unsigned int j = 0; j < toZ_.size(); j++) { + int disk = dproj_[j]; + if (disk == 0) + continue; + if (it < 0) + disk = -disk; + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "adding disk projection " << j << "/" << toZ_.size() << " " << disk; + if (tracklet->validProjDisk(abs(disk))) { + addDiskProj(tracklet, disk); + } + } + + return true; +} + +void TrackletCalculatorDisplaced::exactproj(double rproj, + double rinv, + double phi0, + double d0, + double t, + double z0, + double r0, + double& phiproj, + double& zproj, + double& phider, + double& zder) { + double rho = 1 / rinv; + if (rho < 0) { + r0 = -r0; + } + phiproj = phi0 - asin((rproj * rproj + r0 * r0 - rho * rho) / (2 * rproj * r0)); + double beta = acos((rho * rho + r0 * r0 - rproj * rproj) / (2 * r0 * rho)); + zproj = z0 + t * std::abs(rho * beta); + + //not exact, but close + phider = -0.5 * rinv / sqrt(1 - pow(0.5 * rproj * rinv, 2)) + d0 / (rproj * rproj); + zder = t / sqrt(1 - pow(0.5 * rproj * rinv, 2)); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "exact proj layer at " << rproj << " : " << phiproj << " " << zproj; + } +} + +void TrackletCalculatorDisplaced::exactprojdisk(double zproj, + double rinv, + double, + double, //phi0 and d0 are not used. + double t, + double z0, + double x0, + double y0, + double& phiproj, + double& rproj, + double& phider, + double& rder) { + //protect against t=0 + if (std::abs(t) < 0.1) + t = 0.1; + if (t < 0) + zproj = -zproj; + double rho = std::abs(1 / rinv); + double beta = (zproj - z0) / (t * rho); + double phiV = atan2(-y0, -x0); + double c = rinv > 0 ? -1 : 1; + + double x = x0 + rho * cos(phiV + c * beta); + double y = y0 + rho * sin(phiV + c * beta); + + phiproj = atan2(y, x); + + phiproj = reco::reduceRange(phiproj - phimin_); + + rproj = sqrt(x * x + y * y); + + phider = c / t / (x * x + y * y) * (rho + x0 * cos(phiV + c * beta) + y0 * sin(phiV + c * beta)); + rder = c / t / rproj * (y0 * cos(phiV + c * beta) - x0 * sin(phiV + c * beta)); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "exact proj disk at" << zproj << " : " << phiproj << " " << rproj; + } +} + +void TrackletCalculatorDisplaced::exacttracklet(double r1, + double z1, + double phi1, + double r2, + double z2, + double phi2, + double r3, + double z3, + double phi3, + int take3, + double& rinv, + double& phi0, + double& d0, + double& t, + double& z0, + double phiproj[N_DISK], + double zproj[N_DISK], + double phiprojdisk[N_DISK], + double rprojdisk[N_DISK], + double phider[N_DISK], + double zder[N_DISK], + double phiderdisk[N_DISK], + double rderdisk[N_DISK]) { + //two lines perpendicular to the 1->2 and 2->3 + double x1 = r1 * cos(phi1); + double x2 = r2 * cos(phi2); + double x3 = r3 * cos(phi3); + + double y1 = r1 * sin(phi1); + double y2 = r2 * sin(phi2); + double y3 = r3 * sin(phi3); + + double k1 = -(x2 - x1) / (y2 - y1); + double k2 = -(x3 - x2) / (y3 - y2); + double b1 = 0.5 * (y2 + y1) - 0.5 * (x1 + x2) * k1; + double b2 = 0.5 * (y3 + y2) - 0.5 * (x2 + x3) * k2; + //their intersection gives the center of the circle + double y0 = (b1 * k2 - b2 * k1) / (k2 - k1); + double x0 = (b1 - b2) / (k2 - k1); + //get the radius three ways: + double R1 = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2)); + double R2 = sqrt(pow(x2 - x0, 2) + pow(y2 - y0, 2)); + double R3 = sqrt(pow(x3 - x0, 2) + pow(y3 - y0, 2)); + //check if the same + double eps1 = std::abs(R1 / R2 - 1); + double eps2 = std::abs(R3 / R2 - 1); + if (eps1 > 1e-10 || eps2 > 1e-10) + edm::LogVerbatim("Tracklet") << "&&&&&&&&&&&& bad circle! " << R1 << "\t" << R2 << "\t" << R3; + + //results + rinv = 1. / R1; + phi0 = 0.5 * M_PI + atan2(y0, x0); + + phi0 -= phimin_; + + d0 = -R1 + sqrt(x0 * x0 + y0 * y0); + //sign of rinv: + double dphi = reco::reduceRange(phi3 - atan2(y0, x0)); + if (dphi < 0) { + rinv = -rinv; + d0 = -d0; + phi0 = phi0 + M_PI; + } + phi0 = angle0to2pi::make0To2pi(phi0); + + //now in RZ: + //turning angle + double beta1 = reco::reduceRange(atan2(y1 - y0, x1 - x0) - atan2(-y0, -x0)); + double beta2 = reco::reduceRange(atan2(y2 - y0, x2 - x0) - atan2(-y0, -x0)); + double beta3 = reco::reduceRange(atan2(y3 - y0, x3 - x0) - atan2(-y0, -x0)); + + double t12 = (z2 - z1) / std::abs(beta2 - beta1) / R1; + double z12 = (z1 * beta2 - z2 * beta1) / (beta2 - beta1); + double t13 = (z3 - z1) / std::abs(beta3 - beta1) / R1; + double z13 = (z1 * beta3 - z3 * beta1) / (beta3 - beta1); + + if (take3 > 0) { + //take 13 (large lever arm) + t = t13; + z0 = z13; + } else { + //take 12 (pixel layers) + t = t12; + z0 = z12; + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "exact tracklet: " << rinv << " " << phi0 << " " << d0 << " " << t << " " << z0; + + for (unsigned int i = 0; i < toR_.size(); i++) { + exactproj(toR_[i], rinv, phi0, d0, t, z0, sqrt(x0 * x0 + y0 * y0), phiproj[i], zproj[i], phider[i], zder[i]); + } + + for (unsigned int i = 0; i < toZ_.size(); i++) { + exactprojdisk(toZ_[i], rinv, phi0, d0, t, z0, x0, y0, phiprojdisk[i], rprojdisk[i], phiderdisk[i], rderdisk[i]); + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletEngine.cc b/L1Trigger/TrackFindingTracklet/src/TrackletEngine.cc new file mode 100644 index 0000000000000..dbc5bb62835f3 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletEngine.cc @@ -0,0 +1,289 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletEngine.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace trklet; +using namespace std; + +TrackletEngine::TrackletEngine(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + stubpairs_ = nullptr; + innervmstubs_ = nullptr; + outervmstubs_ = nullptr; + + initLayerDisksandISeed(layerdisk1_, layerdisk2_, iSeed_); + + innerphibits_ = settings.nfinephi(0, iSeed_); + outerphibits_ = settings.nfinephi(1, iSeed_); +} + +void TrackletEngine::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "stubpairout") { + StubPairsMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + stubpairs_ = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void TrackletEngine::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "innervmstubin") { + VMStubsTEMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + innervmstubs_ = tmp; + setVMPhiBin(); + return; + } + if (input == "outervmstubin") { + VMStubsTEMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + outervmstubs_ = tmp; + setVMPhiBin(); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input; +} + +void TrackletEngine::execute() { + if (!settings_.useSeed(iSeed_)) + return; + + unsigned int countall = 0; + unsigned int countpass = 0; + + assert(innervmstubs_ != nullptr); + assert(outervmstubs_ != nullptr); + + for (unsigned int i = 0; i < innervmstubs_->nVMStubs(); i++) { + const VMStubTE& innervmstub = innervmstubs_->getVMStubTE(i); + FPGAWord lookupbits = innervmstub.vmbits(); + + unsigned int nbits = 7; + if (iSeed_ == 4 || iSeed_ == 5) + nbits = 6; + int rzdiffmax = lookupbits.bits(nbits, lookupbits.nbits() - nbits); + int rzbinfirst = lookupbits.bits(0, 3); + int start = lookupbits.bits(4, nbits - 4); + int next = lookupbits.bits(3, 1); + + if ((iSeed_ == 4 || iSeed_ == 5) && innervmstub.stub()->disk().value() < 0) { //TODO - need to store negative disk + start += 4; + } + int last = start + next; + + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int j = 0; j < outervmstubs_->nVMStubsBinned(ibin); j++) { + if (countall >= settings_.maxStep("TE")) + break; + countall++; + const VMStubTE& outervmstub = outervmstubs_->getVMStubTEBinned(ibin, j); + + int rzbin = outervmstub.vmbits().bits(0, 3); + + FPGAWord iphiinnerbin = innervmstub.finephi(); + FPGAWord iphiouterbin = outervmstub.finephi(); + + unsigned int index = (iphiinnerbin.value() << outerphibits_) + iphiouterbin.value(); + + if (iSeed_ >= 4) { //Also use r-position + int ir = ((ibin & 3) << 1) + (rzbin >> 2); + index = (index << 3) + ir; + } + + if (start != ibin) + rzbin += 8; + if ((rzbin < rzbinfirst) || (rzbin - rzbinfirst > rzdiffmax)) { + continue; + } + + FPGAWord innerbend = innervmstub.bend(); + FPGAWord outerbend = outervmstub.bend(); + + int ptinnerindex = (index << innerbend.nbits()) + innerbend.value(); + int ptouterindex = (index << outerbend.nbits()) + outerbend.value(); + + if (!(pttableinner_[ptinnerindex] && pttableouter_[ptouterindex])) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of stub pt cut bends : " + << benddecode(innervmstub.bend().value(), innervmstub.isPSmodule()) << " " + << benddecode(outervmstub.bend().value(), outervmstub.isPSmodule()); + } + continue; + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding stub pair in " << getName(); + + stubpairs_->addStubPair(innervmstub, outervmstub); + countpass++; + } + } + } + + if (settings_.writeMonitorData("TE")) { + globals_->ofstream("trackletengine.txt") << getName() << " " << countall << " " << countpass << endl; + } +} + +void TrackletEngine::setVMPhiBin() { + if (innervmstubs_ == nullptr || outervmstubs_ == nullptr) + return; + + innervmstubs_->setother(outervmstubs_); + outervmstubs_->setother(innervmstubs_); + + int outerrbits = 3; + if (iSeed_ < 4) { + outerrbits = 0; + } + + int outerrbins = (1 << outerrbits); + int innerphibins = (1 << innerphibits_); + int outerphibins = (1 << outerphibits_); + + double innerphimin, innerphimax; + innervmstubs_->getPhiRange(innerphimin, innerphimax, iSeed_, 0); + + double outerphimin, outerphimax; + outervmstubs_->getPhiRange(outerphimin, outerphimax, iSeed_, 1); + + double phiinner[2]; + double phiouter[2]; + double router[2]; + + unsigned int nbendbitsinner = 3; + unsigned int nbendbitsouter = 3; + if (iSeed_ == 2) { + nbendbitsouter = 4; + } + if (iSeed_ == 3) { + nbendbitsinner = 4; + nbendbitsouter = 4; + } + + std::vector vmbendinner((1 << nbendbitsinner), false); + std::vector vmbendouter((1 << nbendbitsouter), false); + + for (int iphiinnerbin = 0; iphiinnerbin < innerphibins; iphiinnerbin++) { + phiinner[0] = innerphimin + iphiinnerbin * (innerphimax - innerphimin) / innerphibins; + phiinner[1] = innerphimin + (iphiinnerbin + 1) * (innerphimax - innerphimin) / innerphibins; + for (int iphiouterbin = 0; iphiouterbin < outerphibins; iphiouterbin++) { + phiouter[0] = outerphimin + iphiouterbin * (outerphimax - outerphimin) / outerphibins; + phiouter[1] = outerphimin + (iphiouterbin + 1) * (outerphimax - outerphimin) / outerphibins; + for (int irouterbin = 0; irouterbin < outerrbins; irouterbin++) { + if (iSeed_ >= 4) { + router[0] = + settings_.rmindiskvm() + irouterbin * (settings_.rmaxdiskvm() - settings_.rmindiskvm()) / outerrbins; + router[1] = settings_.rmindiskvm() + + (irouterbin + 1) * (settings_.rmaxdiskvm() - settings_.rmindiskvm()) / outerrbins; + } else { + router[0] = settings_.rmean(layerdisk2_); + router[1] = settings_.rmean(layerdisk2_); + } + + double bendinnermin = 20.0; + double bendinnermax = -20.0; + double bendoutermin = 20.0; + double bendoutermax = -20.0; + double rinvmin = 1.0; + for (int i1 = 0; i1 < 2; i1++) { + for (int i2 = 0; i2 < 2; i2++) { + for (int i3 = 0; i3 < 2; i3++) { + double rinner = 0.0; + if (iSeed_ == 4 || iSeed_ == 5) { + rinner = router[i3] * settings_.zmean(layerdisk1_ - N_LAYER) / settings_.zmean(layerdisk2_ - N_LAYER); + } else { + rinner = settings_.rmean(layerdisk1_); + } + double rinv1 = rinv(phiinner[i1], phiouter[i2], rinner, router[i3]); + double pitchinner = + (rinner < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double pitchouter = + (router[i3] < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double abendinner = -bend(rinner, rinv1, pitchinner); + double abendouter = -bend(router[i3], rinv1, pitchouter); + if (abendinner < bendinnermin) + bendinnermin = abendinner; + if (abendinner > bendinnermax) + bendinnermax = abendinner; + if (abendouter < bendoutermin) + bendoutermin = abendouter; + if (abendouter > bendoutermax) + bendoutermax = abendouter; + if (std::abs(rinv1) < rinvmin) { + rinvmin = std::abs(rinv1); + } + } + } + } + + bool passptcut = rinvmin < settings_.rinvcutte(); + + for (int ibend = 0; ibend < (1 << nbendbitsinner); ibend++) { + double bend = benddecode(ibend, nbendbitsinner == 3); + + bool passinner = bend - bendinnermin > -settings_.bendcutte(0, iSeed_) && + bend - bendinnermax < settings_.bendcutte(0, iSeed_); + if (passinner) + vmbendinner[ibend] = true; + pttableinner_.push_back(passinner && passptcut); + } + + for (int ibend = 0; ibend < (1 << nbendbitsouter); ibend++) { + double bend = benddecode(ibend, nbendbitsouter == 3); + + bool passouter = bend - bendoutermin > -settings_.bendcutte(1, iSeed_) && + bend - bendoutermax < settings_.bendcutte(1, iSeed_); + if (passouter) + vmbendouter[ibend] = true; + pttableouter_.push_back(passouter && passptcut); + } + } + } + } + + innervmstubs_->setbendtable(vmbendinner); + outervmstubs_->setbendtable(vmbendouter); + + if (iSector_ == 0 && settings_.writeTable()) + writeTETable(); +} + +void TrackletEngine::writeTETable() { + ofstream outstubptinnercut; + outstubptinnercut.open(getName() + "_stubptinnercut.tab"); + outstubptinnercut << "{" << endl; + for (unsigned int i = 0; i < pttableinner_.size(); i++) { + if (i != 0) + outstubptinnercut << "," << endl; + outstubptinnercut << pttableinner_[i]; + } + outstubptinnercut << endl << "};" << endl; + outstubptinnercut.close(); + + ofstream outstubptoutercut; + outstubptoutercut.open(getName() + "_stubptoutercut.tab"); + outstubptoutercut << "{" << endl; + for (unsigned int i = 0; i < pttableouter_.size(); i++) { + if (i != 0) + outstubptoutercut << "," << endl; + outstubptoutercut << pttableouter_[i]; + } + outstubptoutercut << endl << "};" << endl; + outstubptoutercut.close(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletEngineDisplaced.cc b/L1Trigger/TrackFindingTracklet/src/TrackletEngineDisplaced.cc new file mode 100644 index 0000000000000..145e84cb06164 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletEngineDisplaced.cc @@ -0,0 +1,414 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletEngineDisplaced.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/MemoryBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/FPGAWord.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +TrackletEngineDisplaced::TrackletEngineDisplaced(string name, + Settings const& settings, + Globals* global, + unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + stubpairs_.clear(); + firstvmstubs_.clear(); + secondvmstubs_ = nullptr; + layer1_ = 0; + layer2_ = 0; + disk1_ = 0; + disk2_ = 0; + string name1 = name.substr(1); //this is to correct for "TED" having one more letter then "TE" + if (name1[3] == 'L') { + layer1_ = name1[4] - '0'; + } + if (name1[3] == 'D') { + disk1_ = name1[4] - '0'; + } + if (name1[11] == 'L') { + layer2_ = name1[12] - '0'; + } + if (name1[11] == 'D') { + disk2_ = name1[12] - '0'; + } + if (name1[12] == 'L') { + layer2_ = name1[13] - '0'; + } + if (name1[12] == 'D') { + disk2_ = name1[13] - '0'; + } + + iSeed_ = -1; + if (layer1_ == 3 && layer2_ == 4) + iSeed_ = 8; + if (layer1_ == 5 && layer2_ == 6) + iSeed_ = 9; + if (layer1_ == 2 && layer2_ == 3) + iSeed_ = 10; + if (disk1_ == 1 && disk2_ == 2) + iSeed_ = 11; + + firstphibits_ = settings_.nfinephi(0, iSeed_); + secondphibits_ = settings_.nfinephi(1, iSeed_); + + readTables(); +} + +TrackletEngineDisplaced::~TrackletEngineDisplaced() { table_.clear(); } + +void TrackletEngineDisplaced::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "stubpairout") { + StubPairsMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + stubpairs_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void TrackletEngineDisplaced::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "firstvmstubin") { + VMStubsTEMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + firstvmstubs_.push_back(tmp); + return; + } + if (input == "secondvmstubin") { + VMStubsTEMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + secondvmstubs_ = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input; +} + +void TrackletEngineDisplaced::execute() { + if (!settings_.useSeed(iSeed_)) + return; + + unsigned int countall = 0; + unsigned int countpass = 0; + unsigned int nInnerStubs = 0; + + for (unsigned int iInnerMem = 0; iInnerMem < firstvmstubs_.size(); + nInnerStubs += firstvmstubs_.at(iInnerMem)->nVMStubs(), iInnerMem++) + ; + + assert(!firstvmstubs_.empty()); + assert(secondvmstubs_ != nullptr); + + for (auto& iInnerMem : firstvmstubs_) { + assert(iInnerMem->nVMStubs() == iInnerMem->nVMStubs()); + for (unsigned int i = 0; i < iInnerMem->nVMStubs(); i++) { + const VMStubTE& firstvmstub = iInnerMem->getVMStubTE(i); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "In " << getName() << " have first stub"; + } + + if ((layer1_ == 3 && layer2_ == 4) || (layer1_ == 5 && layer2_ == 6)) { + int lookupbits = firstvmstub.vmbits().value() & 1023; + int zdiffmax = (lookupbits >> 7); + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int zbinfirst = newbin & 7; + + int start = (bin >> 1); + int last = start + (bin & 1); + + assert(last < 8); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will look in zbins " << start << " to " << last; + } + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int j = 0; j < secondvmstubs_->nVMStubsBinned(ibin); j++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "In " << getName() << " have second stub(1) " << ibin << " " << j; + } + + if (countall >= settings_.maxStep("TE")) + break; + countall++; + const VMStubTE& secondvmstub = secondvmstubs_->getVMStubTEBinned(ibin, j); + + int zbin = (secondvmstub.vmbits().value() & 7); + if (start != ibin) + zbin += 8; + if (zbin < zbinfirst || zbin - zbinfirst > zdiffmax) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stubpair rejected because of wrong zbin"; + } + continue; + } + + assert(firstphibits_ != -1); + assert(secondphibits_ != -1); + + FPGAWord iphifirstbin = firstvmstub.finephi(); + FPGAWord iphisecondbin = secondvmstub.finephi(); + + unsigned int index = (iphifirstbin.value() << secondphibits_) + iphisecondbin.value(); + + FPGAWord firstbend = firstvmstub.bend(); + FPGAWord secondbend = secondvmstub.bend(); + + index = (index << firstbend.nbits()) + firstbend.value(); + index = (index << secondbend.nbits()) + secondbend.value(); + + if (index >= table_.size()) + table_.resize(index + 1); + + if (table_.at(index).empty()) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of stub pt cut bends : " + << benddecode(firstvmstub.bend().value(), firstvmstub.isPSmodule()) << " " + << benddecode(secondvmstub.bend().value(), secondvmstub.isPSmodule()); + } + if (!settings_.writeTripletTables()) + continue; + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-layer pair in " << getName(); + for (unsigned int isp = 0; isp < stubpairs_.size(); ++isp) { + if (settings_.writeTripletTables() || table_.at(index).count(stubpairs_.at(isp)->getName())) { + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubpairs_.at(isp)->addStubPair(firstvmstub, secondvmstub, index, getName()); + } + } + + countpass++; + } + } + + } else if (layer1_ == 2 && layer2_ == 3) { + int lookupbits = firstvmstub.vmbits().value() & 1023; + int zdiffmax = (lookupbits >> 7); + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int zbinfirst = newbin & 7; + + int start = (bin >> 1); + int last = start + (bin & 1); + + assert(last < 8); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will look in zbins " << start << " to " << last; + } + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int j = 0; j < secondvmstubs_->nVMStubsBinned(ibin); j++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "In " << getName() << " have second stub(2) "; + } + + if (countall >= settings_.maxStep("TE")) + break; + countall++; + + const VMStubTE& secondvmstub = secondvmstubs_->getVMStubTEBinned(ibin, j); + + int zbin = (secondvmstub.vmbits().value() & 7); + if (start != ibin) + zbin += 8; + if (zbin < zbinfirst || zbin - zbinfirst > zdiffmax) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stubpair rejected because of wrong zbin"; + } + continue; + } + + assert(firstphibits_ != -1); + assert(secondphibits_ != -1); + + FPGAWord iphifirstbin = firstvmstub.finephi(); + FPGAWord iphisecondbin = secondvmstub.finephi(); + + unsigned int index = (iphifirstbin.value() << secondphibits_) + iphisecondbin.value(); + + FPGAWord firstbend = firstvmstub.bend(); + FPGAWord secondbend = secondvmstub.bend(); + + index = (index << firstbend.nbits()) + firstbend.value(); + index = (index << secondbend.nbits()) + secondbend.value(); + + if (index >= table_.size()) + table_.resize(index + 1); + + if (table_.at(index).empty()) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of stub pt cut bends : " + << benddecode(firstvmstub.bend().value(), firstvmstub.isPSmodule()) << " " + << benddecode(secondvmstub.bend().value(), secondvmstub.isPSmodule()); + } + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-layer pair in " << getName(); + for (unsigned int isp = 0; isp < stubpairs_.size(); ++isp) { + if (settings_.writeTripletTables() || table_.at(index).count(stubpairs_.at(isp)->getName()) || true) { + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubpairs_.at(isp)->addStubPair(firstvmstub, secondvmstub, index, getName()); + } + } + + countpass++; + } + } + + } else if (disk1_ == 1 && disk2_ == 2) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << getName() << "[" << iSector_ << "] Disk-disk pair"; + + int lookupbits = firstvmstub.vmbits().value() & 511; + bool negdisk = firstvmstub.stub()->disk().value() < 0; + int rdiffmax = (lookupbits >> 6); + int newbin = (lookupbits & 63); + int bin = newbin / 8; + + int rbinfirst = newbin & 7; + + int start = (bin >> 1); + if (negdisk) + start += 4; + int last = start + (bin & 1); + assert(last < 8); + for (int ibin = start; ibin <= last; ibin++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " looking for matching stub in " << secondvmstubs_->getName() + << " in bin = " << ibin << " with " << secondvmstubs_->nVMStubsBinned(ibin) + << " stubs"; + } + for (unsigned int j = 0; j < secondvmstubs_->nVMStubsBinned(ibin); j++) { + if (countall >= settings_.maxStep("TE")) + break; + countall++; + + const VMStubTE& secondvmstub = secondvmstubs_->getVMStubTEBinned(ibin, j); + + int rbin = (secondvmstub.vmbits().value() & 7); + if (start != ibin) + rbin += 8; + if (rbin < rbinfirst) + continue; + if (rbin - rbinfirst > rdiffmax) + continue; + + unsigned int irsecondbin = secondvmstub.vmbits().value() >> 2; + + FPGAWord iphifirstbin = firstvmstub.finephi(); + FPGAWord iphisecondbin = secondvmstub.finephi(); + + unsigned int index = (irsecondbin << (secondphibits_ + firstphibits_)) + + (iphifirstbin.value() << secondphibits_) + iphisecondbin.value(); + + FPGAWord firstbend = firstvmstub.bend(); + FPGAWord secondbend = secondvmstub.bend(); + + index = (index << firstbend.nbits()) + firstbend.value(); + index = (index << secondbend.nbits()) + secondbend.value(); + + if (index >= table_.size()) + table_.resize(index + 1); + + if (table_.at(index).empty()) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of stub pt cut bends : " + << benddecode(firstvmstub.bend().value(), firstvmstub.isPSmodule()) << " " + << benddecode(secondvmstub.bend().value(), secondvmstub.isPSmodule()); + } + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding disk-disk pair in " << getName(); + + for (unsigned int isp = 0; isp < stubpairs_.size(); ++isp) { + if (settings_.writeTripletTables() || table_.at(index).count(stubpairs_.at(isp)->getName()) || true) { + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubpairs_.at(isp)->addStubPair(firstvmstub, secondvmstub, index, getName()); + } + } + countpass++; + } + } + } + } + } + if (countall > 5000) { + edm::LogVerbatim("Tracklet") << "In TrackletEngineDisplaced::execute : " << getName() << " " << nInnerStubs << " " + << secondvmstubs_->nVMStubs() << " " << countall << " " << countpass; + for (auto& iInnerMem : firstvmstubs_) { + for (unsigned int i = 0; i < iInnerMem->nVMStubs(); i++) { + const VMStubTE& firstvmstub = iInnerMem->getVMStubTE(i); + edm::LogVerbatim("Tracklet") << "In TrackletEngineDisplaced::execute first stub : " + << firstvmstub.stub()->l1tstub()->r() << " " + << firstvmstub.stub()->l1tstub()->phi() << " " + << firstvmstub.stub()->l1tstub()->r() * firstvmstub.stub()->l1tstub()->phi() << " " + << firstvmstub.stub()->l1tstub()->z(); + } + } + for (unsigned int i = 0; i < secondvmstubs_->nVMStubs(); i++) { + const VMStubTE& secondvmstub = secondvmstubs_->getVMStubTE(i); + edm::LogVerbatim("Tracklet") << "In TrackletEngineDisplaced::execute second stub : " + << secondvmstub.stub()->l1tstub()->r() << " " + << secondvmstub.stub()->l1tstub()->phi() << " " + << secondvmstub.stub()->l1tstub()->r() * secondvmstub.stub()->l1tstub()->phi() << " " + << secondvmstub.stub()->l1tstub()->z(); + } + } + + if (settings_.writeMonitorData("TED")) { + globals_->ofstream("trackletenginedisplaces.txt") << getName() << " " << countall << " " << countpass << endl; + } +} + +void TrackletEngineDisplaced::readTables() { + ifstream fin; + string tableName, line, word; + + string tablePath = settings_.tableTEDFile(); + unsigned int finddir = tablePath.find("table_TED_"); + tableName = tablePath.substr(0, finddir) + "table_" + name_ + ".txt"; + + fin.open(tableName, ifstream::in); + if (!fin) { + throw cms::Exception("BadConfig") << "TripletEngine::readTables, file " << tableName << " not known"; + } + + while (getline(fin, line)) { + istringstream iss(line); + table_.resize(table_.size() + 1); + + while (iss >> word) + table_[table_.size() - 1].insert(word); + } + fin.close(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc b/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc new file mode 100644 index 0000000000000..8cbd7db3408ca --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletEventProcessor.cc @@ -0,0 +1,540 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletEventProcessor.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/SLHCEvent.h" +#include "L1Trigger/TrackFindingTracklet/interface/Sector.h" +#include "L1Trigger/TrackFindingTracklet/interface/HistBase.h" +#include "L1Trigger/TrackFindingTracklet/interface/Track.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" +#include "L1Trigger/TrackFindingTracklet/interface/Cabling.h" + +#include "DataFormats/Math/interface/deltaPhi.h" + +#include + +using namespace trklet; +using namespace std; + +TrackletEventProcessor::TrackletEventProcessor() : settings_(nullptr) {} + +TrackletEventProcessor::~TrackletEventProcessor() { + if (settings_ && settings_->bookHistos()) { + histbase_->close(); + } +} + +void TrackletEventProcessor::init(Settings const& theSettings) { + settings_ = &theSettings; + + globals_ = make_unique(*settings_); + + //Verify consistency + if (settings_->kphi0pars() != globals_->ITC_L1L2()->phi0_final.K()) { + throw cms::Exception("Inconsistency") << "phi0 conversion parameter inconsistency\n"; + } + + if (settings_->krinvpars() != globals_->ITC_L1L2()->rinv_final.K()) { + throw cms::Exception("Inconsistency") << "ring conversion parameter inconsistency\n"; + } + + if (settings_->ktpars() != globals_->ITC_L1L2()->t_final.K()) { + throw cms::Exception("Inconsistency") << "t conversion parameter inconsistency\n"; + } + + if (settings_->debugTracklet()) { + edm::LogVerbatim("Tracklet") << "========================================================= \n" + << "Conversion factors for global coordinates: \n" + << "z kz = " << settings_->kz() << "\n" + << "r kr = " << settings_->kr() << "\n" + << "phi kphi1 = " << settings_->kphi1() << "\n" + << "========================================================= \n" + << "Conversion factors for track(let) parameters: \n" + << "rinv krinvpars = " << settings_->krinvpars() << "\n" + << "phi0 kphi0pars = " << settings_->kphi0pars() << "\n" + << "d0 kd0pars = " << settings_->kd0pars() << "\n" + << "t ktpars = " << settings_->ktpars() << "\n" + << "z0 kz0pars = " << settings_->kz0pars() << "\n" + << "========================================================= \n" + << "phi0bitshift = " << settings_->phi0bitshift() << "\n" + << "d0bitshift = ??? \n" + << "========================================================="; + } + + //option to write out tables for HLS code, not used in production + /* + const Settings& settings = *settings_; + Globals* globals = globals_; + + if (settings_->writeVerilog() || settings_->writeHLS()) { +#include "../test/WriteInvTables.icc" +#include "../test/WriteDesign.icc" + } + */ + + if (settings_->bookHistos()) { + histbase_ = new HistBase; + histbase_->open(); + histbase_->bookLayerResidual(); + histbase_->bookDiskResidual(); + histbase_->bookTrackletParams(); + histbase_->bookSeedEff(); + + globals_->histograms() = histbase_; + } + + // create the sector processors (1 sector processor = 1 board) + sectors_.resize(N_SECTOR); + + for (unsigned int i = 0; i < N_SECTOR; i++) { + sectors_[i] = make_unique(i, *settings_, globals_.get()); + } + + // get the memory modules + if (settings_->debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will read memory modules file"; + } + + ifstream inmem(settings_->memoryModulesFile().c_str()); + assert(inmem.good()); + + while (inmem.good()) { + string memType, memName, size; + inmem >> memType >> memName >> size; + if (!inmem.good()) + continue; + if (settings_->writetrace()) { + edm::LogVerbatim("Tracklet") << "Read memory: " << memType << " " << memName; + } + for (auto& sector : sectors_) { + sector->addMem(memType, memName); + } + } + + // get the processing modules + if (settings_->debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will read processing modules file"; + } + + ifstream inproc(settings_->processingModulesFile().c_str()); + assert(inproc.good()); + + while (inproc.good()) { + string procType, procName; + inproc >> procType >> procName; + if (!inproc.good()) + continue; + if (settings_->writetrace()) { + edm::LogVerbatim("Tracklet") << "Read process: " << procType << " " << procName; + } + for (auto& sector : sectors_) { + sector->addProc(procType, procName); + } + } + + // get the wiring information + if (settings_->debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will read wiring information"; + } + + ifstream inwire(settings_->wiresFile().c_str()); + assert(inwire.good()); + + while (inwire.good()) { + string line; + getline(inwire, line); + if (!inwire.good()) + continue; + if (settings_->writetrace()) { + edm::LogVerbatim("Tracklet") << "Line : " << line; + } + stringstream ss(line); + string mem, tmp1, procin, tmp2, procout; + ss >> mem >> tmp1 >> procin; + if (procin == "output=>") { + procin = ""; + ss >> procout; + } else { + ss >> tmp2 >> procout; + } + + for (auto& sector : sectors_) { + sector->addWire(mem, procin, procout); + } + } + + // get the DTC/cabling information + ifstream indtc(settings_->DTCLinkLayerDiskFile()); + assert(indtc.good()); + string dtc; + indtc >> dtc; + while (indtc.good()) { + vector tmp; + dtclayerdisk_[dtc] = tmp; + int layerdisk; + indtc >> layerdisk; + while (layerdisk > 0) { + dtclayerdisk_[dtc].push_back(layerdisk); + indtc >> layerdisk; + } + indtc >> dtc; + } + + cabling_ = make_unique(settings_->DTCLinkFile(), settings_->moduleCablingFile(), *settings_); +} + +void TrackletEventProcessor::event(SLHCEvent& ev) { + globals_->event() = &ev; + + tracks_.clear(); + + eventnum_++; + bool first = (eventnum_ == 1); + + cleanTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->clean(); + } + cleanTimer_.stop(); + + addStubTimer_.start(); + + for (int j = 0; j < ev.nstubs(); j++) { + L1TStub stub = ev.stub(j); + + int layer = stub.layer() + 1; + int ladder = stub.ladder(); + int module = stub.module(); + + string dtc = cabling_->dtc(layer, ladder, module); + string dtcbase = dtc.substr(2, dtc.size() - 2); + if (dtc[0] == 'n') { + dtcbase = dtc.substr(0, 4) + dtc.substr(6, dtc.size() - 6); + } + + cabling_->addphi(dtc, stub.phi(), layer, module); + + double phi = angle0to2pi::make0To2pi(stub.phi() + 0.5 * settings_->dphisectorHG()); + + unsigned int isector = N_SECTOR * phi / (2 * M_PI); + + for (unsigned int k = 0; k < N_SECTOR; k++) { + int diff = k - isector; + if (diff > (int)N_SECTOR / 2) + diff -= (int)N_SECTOR; + if (diff < (-1) * (int)N_SECTOR / 2) + diff += (int)N_SECTOR; + if (abs(diff) > 1) + continue; + double phiminsect = + k * 2 * M_PI / N_SECTOR - 0.5 * (settings_->dphisectorHG() - 2 * M_PI / N_SECTOR) - M_PI / N_SECTOR; + double dphi = stub.phi() - phiminsect; + if (dphi > M_PI) + dphi -= 2 * M_PI; + while (dphi < 0.0) + dphi += 2 * M_PI; + if (dphi > settings_->dphisectorHG()) + continue; + bool add = sectors_[k]->addStub(stub, dtcbase); + + static std::map dtcstubs; + + if (settings_->writeMem()) { + vector dtcs = cabling_->DTCs(); + for (const auto& dtc : dtcs) { + string dtcbase = dtc.substr(2, dtc.size() - 2); + if (dtc[0] == 'n') { + dtcbase = dtc.substr(0, 4) + dtc.substr(6, dtc.size() - 6); + } + + string fname = "../data/MemPrints/InputStubs/Link_"; + fname += dtcbase; + if (dtcstubs.find(dtcbase + "A") != dtcstubs.end()) + continue; + fname += "_A.dat"; + ofstream* out = new ofstream; + out->open(fname.c_str()); + dtcstubs[dtcbase + "A"] = out; + + fname = "../data/MemPrints/InputStubs/Link_"; + fname += dtcbase; + if (dtcstubs.find(dtcbase + "B") != dtcstubs.end()) + continue; + fname += "_B.dat"; + out = new ofstream; + out->open(fname.c_str()); + dtcstubs[dtcbase + "B"] = out; + } + + static int oldevent = -1; + if (eventnum_ != oldevent) { + oldevent = eventnum_; + for (auto& dtcstub : dtcstubs) { + FPGAWord tmp; + tmp.set(eventnum_ % 8, 3); + (*(dtcstub.second)) << "BX " << tmp.str() << " Event : " << eventnum_ + 1 << endl; + } + } + } + + if (add && settings_->writeMem() && k == settings_->writememsect()) { + Stub fpgastub(stub, *settings_, sectors_[k]->phimin(), sectors_[k]->phimax()); + FPGAWord phi = fpgastub.phi(); + int topbit = phi.value() >> (phi.nbits() - 1); + std::vector tmp = dtclayerdisk_[dtcbase]; + int layerdisk = stub.layer() + 1; + if (layerdisk > 999) { + layerdisk = 10 + abs(stub.disk()); + } + int layerdiskcode = -1; + for (unsigned int i = 0; i < tmp.size(); i++) { + if (tmp[i] == layerdisk) + layerdiskcode = i; + } + if (layerdiskcode == -1) { + edm::LogVerbatim("Tracklet") << "dtcbase layerdisk layer disk : " << dtcbase << " " << layerdisk << " " + << stub.layer() + 1 << " " << stub.disk(); + } + assert(layerdiskcode >= 0); + assert(layerdiskcode < 4); + FPGAWord ldcode; + ldcode.set(layerdiskcode, 2); + string dataword = "1|" + ldcode.str() + "|" + fpgastub.str(); + if (topbit == 0) { + (*dtcstubs[dtcbase + "A"]) << dataword << " " << trklet::hexFormat(dataword) << endl; + } else { + (*dtcstubs[dtcbase + "B"]) << dataword << " " << trklet::hexFormat(dataword) << endl; + } + } + } + } + + if (settings_->writeMem()) { + for (unsigned int k = 0; k < N_SECTOR; k++) { + if (k == settings_->writememsect()) + sectors_[k]->writeInputStubs(first); + } + } + + addStubTimer_.stop(); + + // ---------------------------------------------------------------------------------------- + // Now start the tracklet processing + + // VM router + VMRouterTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeVMR(); + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeInputStubs(first); + sectors_[k]->writeVMSTE(first); + sectors_[k]->writeVMSME(first); + sectors_[k]->writeAS(first); + } + } + VMRouterTimer_.stop(); + + // tracklet engine + TETimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeTE(); + } + TETimer_.stop(); + + // tracklet engine displaced + TEDTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeTED(); + } + TEDTimer_.stop(); + + // triplet engine + TRETimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeTRE(); + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeST(first); + } + } + TRETimer_.stop(); + + // tracklet processor (alternative implementation to TE+TC) + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeTP(); + } + + for (unsigned int k = 0; k < N_SECTOR; k++) { + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeSP(first); + } + } + + // tracklet calculator + TCTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeTC(); + } + TCTimer_.stop(); + + int nTP = globals_->event()->nsimtracks(); + for (int iTP = 0; iTP < nTP; iTP++) { + L1SimTrack simtrk = globals_->event()->simtrack(iTP); + if (simtrk.pt() < 2.0) + continue; + if (std::abs(simtrk.vz()) > 15.0) + continue; + if (hypot(simtrk.vx(), simtrk.vy()) > 0.1) + continue; + bool electron = (abs(simtrk.type()) == 11); + bool muon = (abs(simtrk.type()) == 13); + bool pion = (abs(simtrk.type()) == 211); + bool kaon = (abs(simtrk.type()) == 321); + bool proton = (abs(simtrk.type()) == 2212); + if (!(electron || muon || pion || kaon || proton)) + continue; + int nlayers = 0; + int ndisks = 0; + int simtrackid = simtrk.trackid(); + unsigned int hitmask = ev.layersHit(simtrackid, nlayers, ndisks); + if (nlayers + ndisks < 4) + continue; + + if (settings_->writeMonitorData("HitEff")) { + static ofstream outhit("hiteff.txt"); + outhit << simtrk.eta() << " " << (hitmask & 1) << " " << (hitmask & 2) << " " << (hitmask & 4) << " " + << (hitmask & 8) << " " << (hitmask & 16) << " " << (hitmask & 32) << " " << (hitmask & 64) << " " + << (hitmask & 128) << " " << (hitmask & 256) << " " << (hitmask & 512) << " " << (hitmask & 1024) << endl; + } + + std::unordered_set matchseed; + for (unsigned int k = 0; k < N_SECTOR; k++) { + std::unordered_set matchseedtmp = sectors_[k]->seedMatch(iTP); + matchseed.insert(matchseedtmp.begin(), matchseedtmp.end()); + } + if (settings_->bookHistos()) { + for (int iseed = 0; iseed < 8; iseed++) { + bool eff = matchseed.find(iseed) != matchseed.end(); + globals_->histograms()->fillSeedEff(iseed, simtrk.eta(), eff); + } + } + } + + // tracklet calculator displaced + TCDTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeTCD(); + } + TCDTimer_.stop(); + + for (unsigned int k = 0; k < N_SECTOR; k++) { + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeTPAR(first); + sectors_[k]->writeTPROJ(first); + } + } + + // projection router + PRTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executePR(); + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeVMPROJ(first); + sectors_[k]->writeAP(first); + } + } + PRTimer_.stop(); + + // match engine + METimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeME(); + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeCM(first); + } + } + METimer_.stop(); + + // match calculator + MCTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeMC(); + } + MCTimer_.stop(); + + // match processor (alternative to ME+MC) + MPTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeMP(); + } + MPTimer_.stop(); + + for (unsigned int k = 0; k < N_SECTOR; k++) { + if (settings_->writeMem() && k == settings_->writememsect()) { + sectors_[k]->writeMC(first); + } + } + + // fit track + FTTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executeFT(); +#ifndef USEHYBRID //don't try to print these memories if running hybrid + if ((settings_->writeMem() || settings_->writeMonitorData("IFit")) && k == settings_->writememsect()) { + sectors_[k]->writeTF(first); + } +#endif + } + FTTimer_.stop(); + + // purge duplicate + PDTimer_.start(); + for (unsigned int k = 0; k < N_SECTOR; k++) { + sectors_[k]->executePD(tracks_); +#ifndef USEHYBRID //don't try to print these memories if running hybrid + if (((settings_->writeMem() || settings_->writeMonitorData("IFit")) && k == settings_->writememsect()) || + settings_->writeMonitorData("CT")) { + sectors_[k]->writeCT(first); + } +#endif + } + PDTimer_.stop(); +} + +void TrackletEventProcessor::printSummary() { + if (settings_->writeMonitorData("Cabling")) { + cabling_->writephirange(); + } + + if (settings_->bookHistos()) { + globals_->histograms()->close(); + } + + edm::LogVerbatim("Tracklet") + << "Process Times called Average time (ms) Total time (s) \n" + << "Cleaning " << setw(10) << cleanTimer_.ntimes() << setw(20) << setprecision(3) + << cleanTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << cleanTimer_.tottime() << "\n" + << "Add Stubs " << setw(10) << addStubTimer_.ntimes() << setw(20) << setprecision(3) + << addStubTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << addStubTimer_.tottime() << "\n" + << "VMRouter " << setw(10) << VMRouterTimer_.ntimes() << setw(20) << setprecision(3) + << VMRouterTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << VMRouterTimer_.tottime() << "\n" + << "TrackletEngine " << setw(10) << TETimer_.ntimes() << setw(20) << setprecision(3) + << TETimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << TETimer_.tottime() << "\n" + << "TrackletEngineDisplaced" << setw(10) << TEDTimer_.ntimes() << setw(20) << setprecision(3) + << TEDTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << TEDTimer_.tottime() << "\n" + << "TripletEngine " << setw(10) << TRETimer_.ntimes() << setw(20) << setprecision(3) + << TRETimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << TRETimer_.tottime() << "\n" + << "TrackletCalculator " << setw(10) << TCTimer_.ntimes() << setw(20) << setprecision(3) + << TCTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << TCTimer_.tottime() << "\n" + << "TrackletCalculatorDisplaced" << setw(10) << TCDTimer_.ntimes() << setw(20) << setprecision(3) + << TCDTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << TCDTimer_.tottime() << "\n" + << "ProjectionRouter " << setw(10) << PRTimer_.ntimes() << setw(20) << setprecision(3) + << PRTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << PRTimer_.tottime() << "\n" + << "MatchEngine " << setw(10) << METimer_.ntimes() << setw(20) << setprecision(3) + << METimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << METimer_.tottime() << "\n" + << "MatchCalculator " << setw(10) << MCTimer_.ntimes() << setw(20) << setprecision(3) + << MCTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << MCTimer_.tottime() << "\n" + << "MatchProcessor " << setw(10) << MPTimer_.ntimes() << setw(20) << setprecision(3) + << MPTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << MPTimer_.tottime() << "\n" + << "FitTrack " << setw(10) << FTTimer_.ntimes() << setw(20) << setprecision(3) + << FTTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << FTTimer_.tottime() << "\n" + << "PurgeDuplicate " << setw(10) << PDTimer_.ntimes() << setw(20) << setprecision(3) + << PDTimer_.avgtime() * 1000.0 << setw(20) << setprecision(3) << PDTimer_.tottime(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletParametersMemory.cc b/L1Trigger/TrackFindingTracklet/src/TrackletParametersMemory.cc new file mode 100644 index 0000000000000..ff2e3eea03c40 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletParametersMemory.cc @@ -0,0 +1,64 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletParametersMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include + +using namespace std; +using namespace trklet; + +TrackletParametersMemory::TrackletParametersMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) {} + +void TrackletParametersMemory::clean() { + for (auto& tracklet : tracklets_) { + delete tracklet; + } + tracklets_.clear(); +} + +void TrackletParametersMemory::writeMatches(Globals* globals, int& matchesL1, int& matchesL3, int& matchesL5) { + ofstream& out = globals->ofstream("nmatches.txt"); + for (auto& tracklet : tracklets_) { + if ((tracklet->nMatches() + tracklet->nMatchesDisk()) > 0) { + if (tracklet->layer() == 1) + matchesL1++; + if (tracklet->layer() == 3) + matchesL3++; + if (tracklet->layer() == 5) + matchesL5++; + } + out << tracklet->layer() << " " << tracklet->disk() << " " << tracklet->nMatches() << " " + << tracklet->nMatchesDisk() << endl; + } +} + +void TrackletParametersMemory::writeTPAR(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/TrackletParameters/TrackletParameters_" << getName() << "_" << std::setfill('0') + << std::setw(2) << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < tracklets_.size(); j++) { + string tpar = tracklets_[j]->trackletparstr(); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << tpar << " " << trklet::hexFormat(tpar) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletProcessor.cc b/L1Trigger/TrackFindingTracklet/src/TrackletProcessor.cc new file mode 100644 index 0000000000000..17525fe60f085 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TrackletProcessor.cc @@ -0,0 +1,947 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TrackletProcessor.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" +#include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +using namespace std; +using namespace trklet; + +TrackletProcessor::TrackletProcessor(string name, Settings const& settings, Globals* globals, unsigned int iSector) + : TrackletCalculatorBase(name, settings, globals, iSector) { + double dphi = 2 * M_PI / N_SECTOR; + double dphiHG = 0.5 * settings_.dphisectorHG() - M_PI / N_SECTOR; + phimin_ = iSector_ * dphi - dphiHG; + phimax_ = phimin_ + dphi + 2 * dphiHG; + phimin_ -= M_PI / N_SECTOR; + phimax_ -= M_PI / N_SECTOR; + phimin_ = reco::reduceRange(phimin_); + phimax_ = reco::reduceRange(phimax_); + if (phimin_ > phimax_) + phimin_ -= 2 * M_PI; + phioffset_ = phimin_; + + for (unsigned int ilayer = 0; ilayer < N_LAYER; ilayer++) { + vector tmp(settings_.nallstubs(ilayer), nullptr); + trackletprojlayers_.push_back(tmp); + } + + for (unsigned int idisk = 0; idisk < N_DISK; idisk++) { + vector tmp(settings_.nallstubs(idisk + N_LAYER), nullptr); + trackletprojdisks_.push_back(tmp); + } + + initLayerDisksandISeed(layerdisk1_, layerdisk2_, iSeed_); + + layer_ = 0; + disk_ = 0; + + if (name_[3] == 'L') { + layer_ = name_[4] - '0'; + if (name_[5] == 'D') + disk_ = name_[6] - '0'; + } + if (name_[3] == 'D') + disk_ = name_[4] - '0'; + + extra_ = (layer_ == 2 && disk_ == 0); + + // set TC index + if (name_[7] == 'A') + iTC_ = 0; + else if (name_[7] == 'B') + iTC_ = 1; + else if (name_[7] == 'C') + iTC_ = 2; + else if (name_[7] == 'D') + iTC_ = 3; + else if (name_[7] == 'E') + iTC_ = 4; + else if (name_[7] == 'F') + iTC_ = 5; + else if (name_[7] == 'G') + iTC_ = 6; + else if (name_[7] == 'H') + iTC_ = 7; + else if (name_[7] == 'I') + iTC_ = 8; + else if (name_[7] == 'J') + iTC_ = 9; + else if (name_[7] == 'K') + iTC_ = 10; + else if (name_[7] == 'L') + iTC_ = 11; + else if (name_[7] == 'M') + iTC_ = 12; + else if (name_[7] == 'N') + iTC_ = 13; + else if (name_[7] == 'O') + iTC_ = 14; + + assert(iTC_ != -1); + + iSeed_ = 99; + if (name_.substr(3, 4) == "L1L2") + iSeed_ = 0; + else if (name_.substr(3, 4) == "L3L4") + iSeed_ = 2; + else if (name_.substr(3, 4) == "L5L6") + iSeed_ = 3; + else if (name_.substr(3, 4) == "D1D2") + iSeed_ = 4; + else if (name_.substr(3, 4) == "D3D4") + iSeed_ = 5; + else if (name_.substr(3, 4) == "D1L1") + iSeed_ = 6; + else if (name_.substr(3, 4) == "D1L2") + iSeed_ = 7; + else if (name_.substr(3, 4) == "L1D1") + iSeed_ = 6; + else if (name_.substr(3, 4) == "L2D1") + iSeed_ = 7; + else if (name_.substr(3, 4) == "L2L3") + iSeed_ = 1; + + assert(iSeed_ != 99); + + TCIndex_ = (iSeed_ << 4) + iTC_; + assert(TCIndex_ >= 0 && TCIndex_ <= (int)settings_.ntrackletmax()); + + assert((layer_ != 0) || (disk_ != 0)); + + if (settings_.usephicritapprox()) { + double phicritFactor = + 0.5 * settings_.rcrit() * globals_->ITC_L1L2()->rinv_final.K() / globals_->ITC_L1L2()->phi0_final.K(); + if (std::abs(phicritFactor - 2.) > 0.25) + edm::LogPrint("Tracklet") + << "TrackletProcessor::TrackletProcessor phicrit approximation may be invalid! Please check."; + } +} + +void TrackletProcessor::addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory) { + outputProj = dynamic_cast(memory); + assert(outputProj != nullptr); +} + +void TrackletProcessor::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "trackpar") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + trackletpars_ = tmp; + return; + } + + if (output.substr(0, 7) == "projout") { + //output is on the form 'projoutL2PHIC' or 'projoutD3PHIB' + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + + unsigned int layerdisk = output[8] - '1'; //layer or disk counting from 0 + unsigned int phiregion = output[12] - 'A'; //phiregion counting from 0 + + if (output[7] == 'L') { + assert(layerdisk < N_LAYER); + assert(phiregion < trackletprojlayers_[layerdisk].size()); + //check that phiregion not already initialized + assert(trackletprojlayers_[layerdisk][phiregion] == nullptr); + trackletprojlayers_[layerdisk][phiregion] = tmp; + return; + } + + if (output[7] == 'D') { + assert(layerdisk < N_DISK); + assert(phiregion < trackletprojdisks_[layerdisk].size()); + //check that phiregion not already initialized + assert(trackletprojdisks_[layerdisk][phiregion] == nullptr); + trackletprojdisks_[layerdisk][phiregion] = tmp; + return; + } + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void TrackletProcessor::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + + if (input == "innervmstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + innervmstubs_.push_back(tmp); + setVMPhiBin(); + return; + } + if (input == "outervmstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + outervmstubs_.push_back(tmp); + setVMPhiBin(); + return; + } + if (input == "innerallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + innerallstubs_.push_back(tmp); + return; + } + if (input == "outerallstubin") { + auto* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + outerallstubs_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input; +} + +void TrackletProcessor::execute() { + unsigned int countall = 0; + unsigned int countsel = 0; + + unsigned int countteall = 0; + unsigned int counttepass = 0; + + StubPairsMemory stubpairs("tmp", settings_, iSector_); //dummy arguments for now + + bool print = false; + + assert(innervmstubs_.size() == outervmstubs_.size()); + + if (!settings_.useSeed(iSeed_)) + return; + + for (unsigned int ivmmem = 0; ivmmem < innervmstubs_.size(); ivmmem++) { + unsigned int innerphibin = innervmstubs_[ivmmem]->phibin(); + unsigned int outerphibin = outervmstubs_[ivmmem]->phibin(); + + unsigned phiindex = 32 * innerphibin + outerphibin; + + //overlap seeding + if (disk_ == 1 && (layer_ == 1 || layer_ == 2)) { + for (unsigned int i = 0; i < innervmstubs_[ivmmem]->nVMStubs(); i++) { + const VMStubTE& innervmstub = innervmstubs_[ivmmem]->getVMStubTE(i); + + int lookupbits = innervmstub.vmbits().value(); + + int rdiffmax = (lookupbits >> 7); + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int rbinfirst = newbin & 7; + + int start = (bin >> 1); + int last = start + (bin & 1); + + for (int ibin = start; ibin <= last; ibin++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " looking for matching stub in bin " << ibin << " with " + << outervmstubs_[ivmmem]->nVMStubsBinned(ibin) << " stubs"; + } + for (unsigned int j = 0; j < outervmstubs_[ivmmem]->nVMStubsBinned(ibin); j++) { + countall++; + countteall++; + + const VMStubTE& outervmstub = outervmstubs_[ivmmem]->getVMStubTEBinned(ibin, j); + int rbin = (outervmstub.vmbits().value() & 7); + if (start != ibin) + rbin += 8; + if ((rbin < rbinfirst) || (rbin - rbinfirst > rdiffmax)) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") + << getName() << " layer-disk stub pair rejected because rbin cut : " << rbin << " " << rbinfirst + << " " << rdiffmax; + } + continue; + } + + int ir = ((start & 3) << 3) + rbinfirst; + + assert(innerphibits_ != -1); + assert(outerphibits_ != -1); + + FPGAWord iphiinnerbin = innervmstub.finephi(); + FPGAWord iphiouterbin = outervmstub.finephi(); + + assert(iphiouterbin == outervmstub.finephi()); + + unsigned int index = (((iphiinnerbin.value() << outerphibits_) + iphiouterbin.value()) << 5) + ir; + + assert(index < phitable_[phiindex].size()); + + if (!phitable_[phiindex][index]) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of tracklet pt cut"; + } + continue; + } + + FPGAWord innerbend = innervmstub.bend(); + FPGAWord outerbend = outervmstub.bend(); + + int ptinnerindex = (index << innerbend.nbits()) + innerbend.value(); + int ptouterindex = (index << outerbend.nbits()) + outerbend.value(); + + if (!(pttableinner_[phiindex][ptinnerindex] && pttableouter_[phiindex][ptouterindex])) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of stub pt cut bends : " + << benddecode(innervmstub.bend().value(), innervmstub.isPSmodule()) << " " + << benddecode(outervmstub.bend().value(), outervmstub.isPSmodule()); + } + continue; + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-disk pair in " << getName(); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubpairs.addStubPair( + innervmstub, outervmstub, 0, innervmstubs_[ivmmem]->getName() + " " + outervmstubs_[ivmmem]->getName()); + counttepass++; + countall++; + } + } + } + + } else { + for (unsigned int i = 0; i < innervmstubs_[ivmmem]->nVMStubs(); i++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "In " << getName() << " have inner stub"; + } + + if ((layer_ == 1 && disk_ == 0) || (layer_ == 2 && disk_ == 0) || (layer_ == 3 && disk_ == 0) || + (layer_ == 5 && disk_ == 0)) { + const VMStubTE& innervmstub = innervmstubs_[ivmmem]->getVMStubTE(i); + + int lookupbits = (int)innervmstub.vmbits().value(); + int zdiffmax = (lookupbits >> 7); + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int zbinfirst = newbin & 7; + + int start = (bin >> 1); + int last = start + (bin & 1); + + if (print) { + edm::LogVerbatim("Tracklet") << "start last : " << start << " " << last; + } + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Will look in zbins " << start << " to " << last; + } + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int j = 0; j < outervmstubs_[ivmmem]->nVMStubsBinned(ibin); j++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "In " << getName() << " have outer stub"; + } + + countteall++; + countall++; + + const VMStubTE& outervmstub = outervmstubs_[ivmmem]->getVMStubTEBinned(ibin, j); + + int zbin = (outervmstub.vmbits().value() & 7); + + if (start != ibin) + zbin += 8; + + if (zbin < zbinfirst || zbin - zbinfirst > zdiffmax) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stubpair rejected because of wrong fine z"; + } + continue; + } + + if (print) { + edm::LogVerbatim("Tracklet") << "ibin j " << ibin << " " << j; + } + + assert(innerphibits_ != -1); + assert(outerphibits_ != -1); + + FPGAWord iphiinnerbin = innervmstub.finephi(); + FPGAWord iphiouterbin = outervmstub.finephi(); + + int index = (iphiinnerbin.value() << outerphibits_) + iphiouterbin.value(); + + assert(index < (int)phitable_[phiindex].size()); + + if (!phitable_[phiindex][index]) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "Stub pair rejected because of tracklet pt cut"; + } + continue; + } + + FPGAWord innerbend = innervmstub.bend(); + FPGAWord outerbend = outervmstub.bend(); + + int ptinnerindex = (index << innerbend.nbits()) + innerbend.value(); + int ptouterindex = (index << outerbend.nbits()) + outerbend.value(); + + if (!(pttableinner_[phiindex][ptinnerindex] && pttableouter_[phiindex][ptouterindex])) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") + << "Stub pair rejected because of stub pt cut bends : " + << benddecode(innervmstub.bend().value(), innervmstub.isPSmodule()) << " " + << benddecode(outervmstub.bend().value(), outervmstub.isPSmodule()); + } + continue; + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-layer pair in " << getName(); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubpairs.addStubPair(innervmstub, + outervmstub, + 0, + innervmstubs_[ivmmem]->getName() + " " + outervmstubs_[ivmmem]->getName()); + counttepass++; + countall++; + } + } + + } else if ((disk_ == 1 && layer_ == 0) || (disk_ == 3 && layer_ == 0)) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << getName() << "[" << iSector_ << "] Disk-disk pair"; + + const VMStubTE& innervmstub = innervmstubs_[ivmmem]->getVMStubTE(i); + + int lookupbits = (int)innervmstub.vmbits().value(); + bool negdisk = innervmstub.stub()->disk().value() < 0; //TODO - need to store negative disk + int rdiffmax = (lookupbits >> 6); + int newbin = (lookupbits & 63); + int bin = newbin / 8; + + int rbinfirst = newbin & 7; + + int start = (bin >> 1); + if (negdisk) + start += 4; + int last = start + (bin & 1); + for (int ibin = start; ibin <= last; ibin++) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << getName() << " looking for matching stub in bin " << ibin << " with " + << outervmstubs_[ivmmem]->nVMStubsBinned(ibin) << " stubs"; + for (unsigned int j = 0; j < outervmstubs_[ivmmem]->nVMStubsBinned(ibin); j++) { + countall++; + countteall++; + + const VMStubTE& outervmstub = outervmstubs_[ivmmem]->getVMStubTEBinned(ibin, j); + + int vmbits = (int)outervmstub.vmbits().value(); + int rbin = (vmbits & 7); + if (start != ibin) + rbin += 8; + if (rbin < rbinfirst) + continue; + if (rbin - rbinfirst > rdiffmax) + continue; + + int rzbin = outervmstub.vmbits().bits(0, 3); + + FPGAWord iphiinnerbin = innervmstub.finephi(); + FPGAWord iphiouterbin = outervmstub.finephi(); + + unsigned int index = (iphiinnerbin.value() << outerphibits_) + iphiouterbin.value(); + + constexpr unsigned int n_barrelseed = 3; + if (iSeed_ > n_barrelseed) { //Also use r-position for disk/overlap seeds + int ir = ((ibin & n_barrelseed) << 1) + (rzbin >> 2); + index = (index << n_barrelseed) + ir; + } + + FPGAWord innerbend = innervmstub.bend(); + FPGAWord outerbend = outervmstub.bend(); + + unsigned int ptinnerindex = (index << innerbend.nbits()) + innerbend.value(); + unsigned int ptouterindex = (index << outerbend.nbits()) + outerbend.value(); + + assert(ptinnerindex < pttableinner_[phiindex].size()); + assert(ptouterindex < pttableouter_[phiindex].size()); + + if (!(pttableinner_[phiindex][ptinnerindex] && pttableouter_[phiindex][ptouterindex])) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") + << "Stub pair rejected because of stub pt cut bends : " + << benddecode(innervmstub.bend().value(), innervmstub.isPSmodule()) << " " + << benddecode(outervmstub.bend().value(), outervmstub.isPSmodule()) + << " pass : " << pttableinner_[phiindex][ptinnerindex] << " " + << pttableouter_[phiindex][ptouterindex]; + } + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding disk-disk pair in " << getName(); + + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubpairs.addStubPair(innervmstub, + outervmstub, + 0, + innervmstubs_[ivmmem]->getName() + " " + outervmstubs_[ivmmem]->getName()); + countall++; + counttepass++; + } + } + } + } + } + } + + if (settings_.writeMonitorData("TE")) { + globals_->ofstream("trackletprocessor.txt") << getName() << " " << countteall << " " << counttepass << endl; + } + + for (unsigned int i = 0; i < stubpairs.nStubPairs(); i++) { + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on too many tracklets in " << getName(); + break; + } + countall++; + const Stub* innerFPGAStub = stubpairs.getVMStub1(i).stub(); + const L1TStub* innerStub = innerFPGAStub->l1tstub(); + + const Stub* outerFPGAStub = stubpairs.getVMStub2(i).stub(); + const L1TStub* outerStub = outerFPGAStub->l1tstub(); + + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletProcessor execute " << getName() << "[" << iSector_ << "]"; + } + + bool accept = false; + + if (innerFPGAStub->isBarrel() && (getName() != "TC_D1L2A" && getName() != "TC_D1L2B")) { + if (outerFPGAStub->isDisk()) { + //overlap seeding + accept = overlapSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub); + } else { + //barrel+barrel seeding + accept = barrelSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub); + } + } else { + if (outerFPGAStub->isDisk()) { + //disk+disk seeding + accept = diskSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub); + } else if (innerFPGAStub->isDisk()) { + //layer+disk seeding + accept = overlapSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub); + } else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!"; + } + } + + if (accept) + countsel++; + + if (settings_.writeMonitorData("TP")) { + globals_->ofstream("tc_seedpairs.txt") << stubpairs.getTEDName(i) << " " << accept << endl; + } + + if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) { + edm::LogVerbatim("Tracklet") << "Will break on number of tracklets in " << getName(); + break; + } + + if (countall >= settings_.maxStep("TP")) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Will break on MAXTC 1"; + break; + } + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "TrackletProcessor execute done"; + } + } + if (countall >= settings_.maxStep("TP")) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Will break on MAXTC 2"; + //break; + } + + if (settings_.writeMonitorData("TP")) { + globals_->ofstream("trackletcalculator.txt") << getName() << " " << countall << " " << countsel << endl; + } +} + +void TrackletProcessor::setVMPhiBin() { + if (innervmstubs_.size() != outervmstubs_.size()) + return; + + for (unsigned int ivmmem = 0; ivmmem < innervmstubs_.size(); ivmmem++) { + unsigned int innerphibin = innervmstubs_[ivmmem]->phibin(); + unsigned int outerphibin = outervmstubs_[ivmmem]->phibin(); + + unsigned phiindex = 32 * innerphibin + outerphibin; + + if (phitable_.find(phiindex) != phitable_.end()) + continue; + + innervmstubs_[ivmmem]->setother(outervmstubs_[ivmmem]); + outervmstubs_[ivmmem]->setother(innervmstubs_[ivmmem]); + + if ((layer_ == 1 && disk_ == 0) || (layer_ == 2 && disk_ == 0) || (layer_ == 3 && disk_ == 0) || + (layer_ == 5 && disk_ == 0)) { + innerphibits_ = settings_.nfinephi(0, iSeed_); + outerphibits_ = settings_.nfinephi(1, iSeed_); + + int innerphibins = (1 << innerphibits_); + int outerphibins = (1 << outerphibits_); + + double innerphimin, innerphimax; + innervmstubs_[ivmmem]->getPhiRange(innerphimin, innerphimax, iSeed_, 0); + double rinner = settings_.rmean(layer_ - 1); + + double outerphimin, outerphimax; + outervmstubs_[ivmmem]->getPhiRange(outerphimin, outerphimax, iSeed_, 1); + double router = settings_.rmean(layer_); + + double phiinner[2]; + double phiouter[2]; + + std::vector vmbendinner; + std::vector vmbendouter; + unsigned int nbins1 = 8; + if (layer_ >= 4) + nbins1 = 16; + for (unsigned int i = 0; i < nbins1; i++) { + vmbendinner.push_back(false); + } + + unsigned int nbins2 = 8; + if (layer_ >= 3) + nbins2 = 16; + for (unsigned int i = 0; i < nbins2; i++) { + vmbendouter.push_back(false); + } + + for (int iphiinnerbin = 0; iphiinnerbin < innerphibins; iphiinnerbin++) { + phiinner[0] = innerphimin + iphiinnerbin * (innerphimax - innerphimin) / innerphibins; + phiinner[1] = innerphimin + (iphiinnerbin + 1) * (innerphimax - innerphimin) / innerphibins; + for (int iphiouterbin = 0; iphiouterbin < outerphibins; iphiouterbin++) { + phiouter[0] = outerphimin + iphiouterbin * (outerphimax - outerphimin) / outerphibins; + phiouter[1] = outerphimin + (iphiouterbin + 1) * (outerphimax - outerphimin) / outerphibins; + + double bendinnermin = 20.0; + double bendinnermax = -20.0; + double bendoutermin = 20.0; + double bendoutermax = -20.0; + double rinvmin = 1.0; + for (int i1 = 0; i1 < 2; i1++) { + for (int i2 = 0; i2 < 2; i2++) { + double rinv1 = rinv(phiinner[i1], phiouter[i2], rinner, router); + double pitchinner = + (rinner < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double pitchouter = + (router < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double abendinner = -bend(rinner, rinv1, pitchinner); + double abendouter = -bend(router, rinv1, pitchouter); + if (abendinner < bendinnermin) + bendinnermin = abendinner; + if (abendinner > bendinnermax) + bendinnermax = abendinner; + if (abendouter < bendoutermin) + bendoutermin = abendouter; + if (abendouter > bendoutermax) + bendoutermax = abendouter; + if (std::abs(rinv1) < rinvmin) { + rinvmin = std::abs(rinv1); + } + } + } + + phitable_[phiindex].push_back(rinvmin < settings_.rinvcutte()); + + int nbins1 = 8; + if (layer_ >= 4) + nbins1 = 16; + for (int ibend = 0; ibend < nbins1; ibend++) { + double bend = benddecode(ibend, layer_ <= 3); + + bool passinner = bend - bendinnermin > -settings_.bendcutte(0, iSeed_) && + bend - bendinnermax < settings_.bendcutte(0, iSeed_); + if (passinner) + vmbendinner[ibend] = true; + pttableinner_[phiindex].push_back(passinner); + } + + int nbins2 = 8; + if (layer_ >= 3) + nbins2 = 16; + for (int ibend = 0; ibend < nbins2; ibend++) { + double bend = benddecode(ibend, layer_ <= 2); + + bool passouter = bend - bendoutermin > -settings_.bendcutte(1, iSeed_) && + bend - bendoutermax < settings_.bendcutte(1, iSeed_); + if (passouter) + vmbendouter[ibend] = true; + pttableouter_[phiindex].push_back(passouter); + } + } + } + + innervmstubs_[ivmmem]->setbendtable(vmbendinner); + outervmstubs_[ivmmem]->setbendtable(vmbendouter); + + if (iSector_ == 0 && settings_.writeTable()) + writeTETable(); + } + + if ((disk_ == 1 && layer_ == 0) || (disk_ == 3 && layer_ == 0)) { + innerphibits_ = settings_.nfinephi(0, iSeed_); + outerphibits_ = settings_.nfinephi(1, iSeed_); + + int outerrbits = 3; + + int outerrbins = (1 << outerrbits); + int innerphibins = (1 << innerphibits_); + int outerphibins = (1 << outerphibits_); + + double innerphimin, innerphimax; + innervmstubs_[ivmmem]->getPhiRange(innerphimin, innerphimax, iSeed_, 0); + + double outerphimin, outerphimax; + outervmstubs_[ivmmem]->getPhiRange(outerphimin, outerphimax, iSeed_, 1); + + double phiinner[2]; + double phiouter[2]; + double router[2]; + + std::vector vmbendinner; + std::vector vmbendouter; + + for (unsigned int i = 0; i < 8; i++) { + vmbendinner.push_back(false); + vmbendouter.push_back(false); + } + + for (int irouterbin = 0; irouterbin < outerrbins; irouterbin++) { + router[0] = + settings_.rmindiskvm() + irouterbin * (settings_.rmaxdiskvm() - settings_.rmindiskvm()) / outerrbins; + router[1] = + settings_.rmindiskvm() + (irouterbin + 1) * (settings_.rmaxdiskvm() - settings_.rmindiskvm()) / outerrbins; + for (int iphiinnerbin = 0; iphiinnerbin < innerphibins; iphiinnerbin++) { + phiinner[0] = innerphimin + iphiinnerbin * (innerphimax - innerphimin) / innerphibins; + phiinner[1] = innerphimin + (iphiinnerbin + 1) * (innerphimax - innerphimin) / innerphibins; + for (int iphiouterbin = 0; iphiouterbin < outerphibins; iphiouterbin++) { + phiouter[0] = outerphimin + iphiouterbin * (outerphimax - outerphimin) / outerphibins; + phiouter[1] = outerphimin + (iphiouterbin + 1) * (outerphimax - outerphimin) / outerphibins; + + double bendinnermin = 20.0; + double bendinnermax = -20.0; + double bendoutermin = 20.0; + double bendoutermax = -20.0; + double rinvmin = 1.0; + double rinvmax = -1.0; + for (int i1 = 0; i1 < 2; i1++) { + for (int i2 = 0; i2 < 2; i2++) { + for (int i3 = 0; i3 < 2; i3++) { + double rinner = router[i3] * settings_.zmean(disk_ - 1) / settings_.zmean(disk_); + double rinv1 = rinv(phiinner[i1], phiouter[i2], rinner, router[i3]); + double pitchinner = + (rinner < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double pitchouter = + (router[i3] < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double abendinner = bend(rinner, rinv1, pitchinner); + double abendouter = bend(router[i3], rinv1, pitchouter); + if (abendinner < bendinnermin) + bendinnermin = abendinner; + if (abendinner > bendinnermax) + bendinnermax = abendinner; + if (abendouter < bendoutermin) + bendoutermin = abendouter; + if (abendouter > bendoutermax) + bendoutermax = abendouter; + if (std::abs(rinv1) < rinvmin) { + rinvmin = std::abs(rinv1); + } + if (std::abs(rinv1) > rinvmax) { + rinvmax = std::abs(rinv1); + } + } + } + } + + phitable_[phiindex].push_back(rinvmin < settings_.rinvcutte()); + + for (int ibend = 0; ibend < 8; ibend++) { + double bend = benddecode(ibend, true); + + bool passinner = bend - bendinnermin > -settings_.bendcutte(0, iSeed_) && + bend - bendinnermax < settings_.bendcutte(0, iSeed_); + if (passinner) + vmbendinner[ibend] = true; + pttableinner_[phiindex].push_back(passinner); + } + + for (int ibend = 0; ibend < 8; ibend++) { + double bend = benddecode(ibend, true); + + bool passouter = bend - bendoutermin > -settings_.bendcutte(1, iSeed_) && + bend - bendoutermax < settings_.bendcutte(1, iSeed_); + if (passouter) + vmbendouter[ibend] = true; + pttableouter_[phiindex].push_back(passouter); + } + } + } + } + + innervmstubs_[ivmmem]->setbendtable(vmbendinner); + outervmstubs_[ivmmem]->setbendtable(vmbendouter); + + if (iSector_ == 0 && settings_.writeTable()) + writeTETable(); + + } else if (disk_ == 1 && (layer_ == 1 || layer_ == 2)) { + innerphibits_ = settings_.nfinephi(0, iSeed_); + outerphibits_ = settings_.nfinephi(1, iSeed_); + unsigned int nrbits = 5; + + int innerphibins = (1 << innerphibits_); + int outerphibins = (1 << outerphibits_); + + double innerphimin, innerphimax; + innervmstubs_[ivmmem]->getPhiRange(innerphimin, innerphimax, iSeed_, 0); + + double outerphimin, outerphimax; + outervmstubs_[ivmmem]->getPhiRange(outerphimin, outerphimax, iSeed_, 1); + + double phiinner[2]; + double phiouter[2]; + double router[2]; + + std::vector vmbendinner; + std::vector vmbendouter; + + for (unsigned int i = 0; i < 8; i++) { + vmbendinner.push_back(false); + vmbendouter.push_back(false); + } + + double dr = (settings_.rmaxdiskvm() - settings_.rmindiskvm()) / (1 << nrbits); + + for (int iphiinnerbin = 0; iphiinnerbin < innerphibins; iphiinnerbin++) { + phiinner[0] = innerphimin + iphiinnerbin * (innerphimax - innerphimin) / innerphibins; + phiinner[1] = innerphimin + (iphiinnerbin + 1) * (innerphimax - innerphimin) / innerphibins; + for (int iphiouterbin = 0; iphiouterbin < outerphibins; iphiouterbin++) { + phiouter[0] = outerphimin + iphiouterbin * (outerphimax - outerphimin) / outerphibins; + phiouter[1] = outerphimin + (iphiouterbin + 1) * (outerphimax - outerphimin) / outerphibins; + for (int irbin = 0; irbin < (1 << nrbits); irbin++) { + router[0] = settings_.rmindiskvm() + dr * irbin; + router[1] = router[0] + dr; + double bendinnermin = 20.0; + double bendinnermax = -20.0; + double bendoutermin = 20.0; + double bendoutermax = -20.0; + double rinvmin = 1.0; + for (int i1 = 0; i1 < 2; i1++) { + for (int i2 = 0; i2 < 2; i2++) { + for (int i3 = 0; i3 < 2; i3++) { + double rinner = settings_.rmean(layer_ - 1); + double rinv1 = rinv(phiinner[i1], phiouter[i2], rinner, router[i3]); + double pitchinner = + (rinner < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double pitchouter = + (router[i3] < settings_.rcrit()) ? settings_.stripPitch(true) : settings_.stripPitch(false); + double abendinner = bend(rinner, rinv1, pitchinner); + double abendouter = bend(router[i3], rinv1, pitchouter); + if (abendinner < bendinnermin) + bendinnermin = abendinner; + if (abendinner > bendinnermax) + bendinnermax = abendinner; + if (abendouter < bendoutermin) + bendoutermin = abendouter; + if (abendouter > bendoutermax) + bendoutermax = abendouter; + if (std::abs(rinv1) < rinvmin) { + rinvmin = std::abs(rinv1); + } + } + } + } + + phitable_[phiindex].push_back(rinvmin < settings_.rinvcutte()); + + for (int ibend = 0; ibend < 8; ibend++) { + double bend = benddecode(ibend, true); + + bool passinner = bend - bendinnermin > -settings_.bendcutte(0, iSeed_) && + bend - bendinnermax < settings_.bendcutte(0, iSeed_); + if (passinner) + vmbendinner[ibend] = true; + pttableinner_[phiindex].push_back(passinner); + } + + for (int ibend = 0; ibend < 8; ibend++) { + double bend = benddecode(ibend, true); + + bool passouter = bend - bendoutermin > -settings_.bendcutte(1, iSeed_) && + bend - bendoutermax < settings_.bendcutte(1, iSeed_); + if (passouter) + vmbendouter[ibend] = true; + pttableouter_[phiindex].push_back(passouter); + } + } + } + } + + innervmstubs_[ivmmem]->setbendtable(vmbendinner); + outervmstubs_[ivmmem]->setbendtable(vmbendouter); + + if (iSector_ == 0 && settings_.writeTable()) + writeTETable(); + } + } +} + +void TrackletProcessor::writeTETable() { + ofstream outptcut; + outptcut.open(getName() + "_ptcut.tab"); + outptcut << "{" << endl; + //for(unsigned int i=0;i +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +TrackletProjectionsMemory::TrackletProjectionsMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) { + size_t pos = find_nth(name, 0, "_", 1); + assert(pos != string::npos); + initLayerDisk(pos + 1, layer_, disk_); +} + +void TrackletProjectionsMemory::addProj(Tracklet* tracklet) { + if (layer_ != 0 && disk_ == 0) + assert(tracklet->validProj(layer_)); + if (layer_ == 0 && disk_ != 0) + assert(tracklet->validProjDisk(disk_)); + if (layer_ != 0 && disk_ != 0) + assert(tracklet->validProj(layer_) || tracklet->validProjDisk(disk_)); + + for (auto& itracklet : tracklets_) { + if (itracklet == tracklet) { + edm::LogPrint("Tracklet") << "Adding same tracklet " << tracklet << " twice in " << getName(); + } + assert(itracklet != tracklet); + } + + tracklets_.push_back(tracklet); +} + +void TrackletProjectionsMemory::clean() { tracklets_.clear(); } + +void TrackletProjectionsMemory::writeTPROJ(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/TrackletProjections/TrackletProjections_" << getName() << "_" << std::setfill('0') + << std::setw(2) << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < tracklets_.size(); j++) { + string proj = (layer_ > 0 && tracklets_[j]->validProj(layer_)) ? tracklets_[j]->trackletprojstrlayer(layer_) + : tracklets_[j]->trackletprojstrdisk(disk_); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << proj << " " << trklet::hexFormat(proj) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/TripletEngine.cc b/L1Trigger/TrackFindingTracklet/src/TripletEngine.cc new file mode 100644 index 0000000000000..403bf8f02ef48 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/TripletEngine.cc @@ -0,0 +1,477 @@ +#include "L1Trigger/TrackFindingTracklet/interface/TripletEngine.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +#include + +using namespace std; +using namespace trklet; + +TripletEngine::TripletEngine(string name, Settings const &settings, Globals *global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector) { + stubpairs_.clear(); + thirdvmstubs_.clear(); + layer1_ = 0; + layer2_ = 0; + layer3_ = 0; + disk1_ = 0; + disk2_ = 0; + disk3_ = 0; + dct1_ = 0; + dct2_ = 0; + dct3_ = 0; + phi1_ = 0; + phi2_ = 0; + phi3_ = 0; + z1_ = 0; + z2_ = 0; + z3_ = 0; + r1_ = 0; + r2_ = 0; + r3_ = 0; + + if (name_[4] == 'L') + layer1_ = name_[5] - '0'; + if (name_[4] == 'D') + disk1_ = name_[5] - '0'; + if (name_[7] == 'L') + layer2_ = name_[8] - '0'; + if (name_[7] == 'D') + disk2_ = name_[8] - '0'; + + if (layer1_ == 3 && layer2_ == 4) { + layer3_ = 2; + iSeed_ = 8; + } else if (layer1_ == 5 && layer2_ == 6) { + layer3_ = 4; + iSeed_ = 9; + } else if (layer1_ == 2 && layer2_ == 3) { + disk3_ = 1; + iSeed_ = 10; + } else if (disk1_ == 1 && disk2_ == 2) { + layer3_ = 2; + iSeed_ = 11; + } else + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!"; + + if ((layer2_ == 4 && layer3_ == 2) || (layer2_ == 6 && layer3_ == 4)) { + secondphibits_ = settings_.nfinephi(1, iSeed_); + thirdphibits_ = settings_.nfinephi(2, iSeed_); + } + if ((layer2_ == 3 && disk3_ == 1) || (disk2_ == 2 && layer3_ == 2)) { + secondphibits_ = settings_.nfinephi(1, iSeed_); + thirdphibits_ = settings_.nfinephi(2, iSeed_); + } + readTables(); +} + +TripletEngine::~TripletEngine() { + if (settings_.writeTripletTables()) + writeTables(); +} + +void TripletEngine::addOutput(MemoryBase *memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + if (output == "stubtripout") { + auto *tmp = dynamic_cast(memory); + assert(tmp != nullptr); + stubtriplets_ = tmp; + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void TripletEngine::addInput(MemoryBase *memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "thirdvmstubin") { + auto *tmp = dynamic_cast(memory); + assert(tmp != nullptr); + thirdvmstubs_.push_back(tmp); + return; + } + if (input.substr(0, 8) == "stubpair") { + auto *tmp = dynamic_cast(memory); + assert(tmp != nullptr); + stubpairs_.push_back(tmp); + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input; +} + +void TripletEngine::execute() { + unsigned int countall = 0; + unsigned int countpass = 0; + unsigned int nThirdStubs = 0; + count_ = 0; + + for (unsigned int iThirdMem = 0; iThirdMem < thirdvmstubs_.size(); + nThirdStubs += thirdvmstubs_.at(iThirdMem)->nVMStubs(), iThirdMem++) + ; + + assert(!thirdvmstubs_.empty()); + assert(!stubpairs_.empty()); + + bool print = false && (getName().substr(0, 10) == "TRE_L2cL3c"); + + print = print && nThirdStubs > 0; + + int hacksum = 0; + if (print) { + edm::LogVerbatim("Tracklet") << "In TripletEngine::execute : " << getName() << " " << nThirdStubs << ":"; + for (unsigned int i = 0; i < thirdvmstubs_.size(); ++i) { + edm::LogVerbatim("Tracklet") << thirdvmstubs_.at(i)->getName() << " " << thirdvmstubs_.at(i)->nVMStubs(); + } + int s = 0; + std::string oss = ""; + for (unsigned int i = 0; i < stubpairs_.size(); ++i) { + oss += std::to_string(stubpairs_.at(i)->nStubPairs()); + oss += " "; + s += stubpairs_.at(i)->nStubPairs(); + } + hacksum += nThirdStubs * s; + edm::LogVerbatim("Tracklet") << oss; + for (unsigned int i = 0; i < stubpairs_.size(); ++i) { + edm::LogVerbatim("Tracklet") << " " << stubpairs_.at(i)->getName(); + } + } + + tmpSPTable_.clear(); + + for (unsigned int i = 0; i < stubpairs_.size(); ++i) { + for (unsigned int j = 0; j < stubpairs_.at(i)->nStubPairs(); ++j) { + if (print) + edm::LogVerbatim("Tracklet") << " ***** " << stubpairs_.at(i)->getName() << " " + << stubpairs_.at(i)->nStubPairs(); + + auto firstvmstub = stubpairs_.at(i)->getVMStub1(j); + auto secondvmstub = stubpairs_.at(i)->getVMStub2(j); + + if ((layer2_ == 4 && layer3_ == 2) || (layer2_ == 6 && layer3_ == 4)) { + constexpr unsigned int vmbitshift = 10; + int lookupbits = (int)((firstvmstub.vmbits().value() >> vmbitshift) & 1023); //1023=2^vmbitshift-1 + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int start = (bin >> 1); + int last = start + (bin & 1); + + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int k = 0; k < thirdvmstubs_.size(); k++) { + string vmsteSuffix = thirdvmstubs_.at(k)->getLastPartOfName(); + vmsteSuffix = vmsteSuffix.substr(0, vmsteSuffix.find_last_of('n')); + if (stubpairs_.at(i)->getLastPartOfName() != vmsteSuffix) + continue; + for (unsigned int l = 0; l < thirdvmstubs_.at(k)->nVMStubsBinned(ibin); l++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << "In " << getName() << " have third stub"; + } + + if (countall >= settings_.maxStep("TRE")) + break; + countall++; + + const VMStubTE &thirdvmstub = thirdvmstubs_.at(k)->getVMStubTEBinned(ibin, l); + + assert(secondphibits_ != -1); + assert(thirdphibits_ != -1); + + unsigned int nvmsecond = settings_.nallstubs(layer2_ - 1) * settings_.nvmte(1, iSeed_); + unsigned int nvmbitssecond = nbits(nvmsecond); + + FPGAWord iphisecondbin = secondvmstub.stub()->iphivmFineBins(nvmbitssecond, secondphibits_); + + //currently not using same number of bits as in the TED + //assert(iphisecondbin==(int)secondvmstub.finephi()); + FPGAWord iphithirdbin = thirdvmstub.finephi(); + + unsigned int index = (iphisecondbin.value() << thirdphibits_) + iphithirdbin.value(); + + FPGAWord secondbend = secondvmstub.bend(); + FPGAWord thirdbend = thirdvmstub.bend(); + + index = (index << secondbend.nbits()) + secondbend.value(); + index = (index << thirdbend.nbits()) + thirdbend.value(); + + if (index >= table_.size()) + table_.resize(index + 1, false); + + if (!table_[index]) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") + << "Stub pair rejected because of stub pt cut bends : " + << benddecode(secondvmstub.bend().value(), secondvmstub.isPSmodule()) << " " + << benddecode(thirdvmstub.bend().value(), thirdvmstub.isPSmodule()); + } + if (!settings_.writeTripletTables()) + continue; + } + if (settings_.writeTripletTables()) + table_[index] = true; + + const unsigned spIndex = stubpairs_.at(i)->getIndex(j); + const string &tedName = stubpairs_.at(i)->getTEDName(j); + if (!tmpSPTable_.count(tedName)) + tmpSPTable_[tedName]; + if (spIndex >= tmpSPTable_.at(tedName).size()) + tmpSPTable_.at(tedName).resize(spIndex + 1); + tmpSPTable_.at(tedName).at(spIndex).push_back(stubpairs_.at(i)->getName()); + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-layer pair in " << getName(); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubtriplets_->addStubs(thirdvmstub.stub(), + (stubpairs_.at(i))->getVMStub1(j).stub(), + (stubpairs_.at(i))->getVMStub2(j).stub()); + + countpass++; + } + } + } + + } + + else if (disk2_ == 2 && layer3_ == 2) { + int lookupbits = (int)((firstvmstub.vmbits().value() >> 10) & 1023); + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int start = (bin >> 1); + int last = start + (bin & 1); + + if (firstvmstub.stub()->disk().value() < 0) { //TODO - negative disk should come from memory + start = settings_.NLONGVMBINS() - last - 1; + last = settings_.NLONGVMBINS() - start - 1; + } + + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int k = 0; k < thirdvmstubs_.size(); k++) { + string vmsteSuffix = thirdvmstubs_.at(k)->getLastPartOfName(); + vmsteSuffix = vmsteSuffix.substr(0, vmsteSuffix.find_last_of('n')); + if (stubpairs_.at(i)->getLastPartOfName() != vmsteSuffix) + continue; + + for (unsigned int l = 0; l < thirdvmstubs_.at(k)->nVMStubsBinned(ibin); l++) { + if (countall >= settings_.maxStep("TRE")) + break; + countall++; + + const VMStubTE &thirdvmstub = thirdvmstubs_.at(k)->getVMStubTEBinned(ibin, l); + + assert(secondphibits_ != -1); + assert(thirdphibits_ != -1); + + FPGAWord iphisecondbin = secondvmstub.finephi(); + FPGAWord iphithirdbin = thirdvmstub.finephi(); + + unsigned int index = (iphisecondbin.value() << thirdphibits_) + iphithirdbin.value(); + + FPGAWord secondbend = secondvmstub.bend(); + FPGAWord thirdbend = thirdvmstub.bend(); + + index = (index << secondbend.nbits()) + secondbend.value(); + index = (index << thirdbend.nbits()) + thirdbend.value(); + + if (index >= table_.size()) + table_.resize(index + 1, false); + + if (!table_[index]) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") + << "Stub triplet rejected because of stub pt cut bends : " + << benddecode(secondvmstub.bend().value(), secondvmstub.isPSmodule()) << " " + << benddecode(thirdvmstub.bend().value(), thirdvmstub.isPSmodule()); + } + } + if (settings_.writeTripletTables()) + table_[index] = true; + + const unsigned spIndex = stubpairs_.at(i)->getIndex(j); + const string &tedName = stubpairs_.at(i)->getTEDName(j); + if (!tmpSPTable_.count(tedName)) + tmpSPTable_[tedName]; + if (spIndex >= tmpSPTable_.at(tedName).size()) + tmpSPTable_.at(tedName).resize(spIndex + 1); + tmpSPTable_.at(tedName).at(spIndex).push_back(stubpairs_.at(i)->getName()); + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-disk pair in " << getName(); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubtriplets_->addStubs(thirdvmstub.stub(), + (stubpairs_.at(i))->getVMStub1(j).stub(), + (stubpairs_.at(i))->getVMStub2(j).stub()); + countpass++; + } + } + } + } + + else if (layer2_ == 3 && disk3_ == 1) { + int lookupbits = (int)((firstvmstub.vmbits().value() >> 10) & 1023); + + int newbin = (lookupbits & 127); + int bin = newbin / 8; + + int start = (bin >> 1); + int last = start + (bin & 1); + + for (int ibin = start; ibin <= last; ibin++) { + for (unsigned int k = 0; k < thirdvmstubs_.size(); k++) { + string vmsteSuffix = thirdvmstubs_.at(k)->getLastPartOfName(); + vmsteSuffix = vmsteSuffix.substr(0, vmsteSuffix.find_last_of('n')); + if (stubpairs_.at(i)->getLastPartOfName() != vmsteSuffix) + continue; + for (unsigned int l = 0; l < thirdvmstubs_.at(k)->nVMStubsBinned(ibin); l++) { + if (countall >= settings_.maxStep("TRE")) + break; + countall++; + + const VMStubTE &thirdvmstub = thirdvmstubs_.at(k)->getVMStubTEBinned(ibin, l); + + assert(secondphibits_ != -1); + assert(thirdphibits_ != -1); + + unsigned int nvmsecond; + + nvmsecond = settings_.nallstubs(layer2_ - 1) * settings_.nvmte(1, iSeed_); + unsigned int nvmbitssecond = nbits(nvmsecond); + + FPGAWord iphisecondbin = secondvmstub.stub()->iphivmFineBins(nvmbitssecond, secondphibits_); + + //currentlty not using same number of bits as in the TED + //assert(iphisecondbin==(int)secondvmstub.finephi()); + FPGAWord iphithirdbin = thirdvmstub.finephi(); + + unsigned int index = (iphisecondbin.value() << thirdphibits_) + iphithirdbin.value(); + + FPGAWord secondbend = secondvmstub.bend(); + FPGAWord thirdbend = thirdvmstub.bend(); + + index = (index << secondbend.nbits()) + secondbend.value(); + index = (index << thirdbend.nbits()) + thirdbend.value(); + + if (index >= table_.size()) + table_.resize(index + 1, false); + + if (!table_[index]) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") + << "Stub pair rejected because of stub pt cut bends : " + << benddecode(secondvmstub.bend().value(), secondvmstub.isPSmodule()) << " " + << benddecode(thirdvmstub.bend().value(), thirdvmstub.isPSmodule()); + } + } + if (settings_.writeTripletTables()) + table_[index] = true; + + const unsigned spIndex = stubpairs_.at(i)->getIndex(j); + const string &tedName = stubpairs_.at(i)->getTEDName(j); + if (!tmpSPTable_.count(tedName)) + tmpSPTable_[tedName]; + if (spIndex >= tmpSPTable_.at(tedName).size()) + tmpSPTable_.at(tedName).resize(spIndex + 1); + tmpSPTable_.at(tedName).at(spIndex).push_back(stubpairs_.at(i)->getName()); + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding layer-disk pair in " << getName(); + if (settings_.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector_ << " " << iSeed_ << endl; + fout.close(); + } + stubtriplets_->addStubs(thirdvmstub.stub(), + (stubpairs_.at(i))->getVMStub1(j).stub(), + (stubpairs_.at(i))->getVMStub2(j).stub()); + countpass++; + } + } + } + } + } + } + + for (const auto &tedName : tmpSPTable_) { + for (unsigned spIndex = 0; spIndex < tedName.second.size(); spIndex++) { + if (tedName.second.at(spIndex).empty()) + continue; + vector entry(tedName.second.at(spIndex)); + sort(entry.begin(), entry.end()); + entry.erase(unique(entry.begin(), entry.end()), entry.end()); + const string &spName = entry.at(0); + + if (!spTable_.count(tedName.first)) + spTable_[tedName.first]; + if (spIndex >= spTable_.at(tedName.first).size()) + spTable_.at(tedName.first).resize(spIndex + 1); + if (!spTable_.at(tedName.first).at(spIndex).count(spName)) + spTable_.at(tedName.first).at(spIndex)[spName] = 0; + spTable_.at(tedName.first).at(spIndex)[spName]++; + } + } + + if (settings_.writeMonitorData("TRE")) { + globals_->ofstream("tripletengine.txt") << getName() << " " << countall << " " << countpass << endl; + } +} + +void TripletEngine::readTables() { + ifstream fin; + string tableName, word; + unsigned num; + + string tablePath = settings_.tableTREFile(); + unsigned int finddir = tablePath.find("table_TRE_"); + tableName = tablePath.substr(0, finddir) + "table_" + name_ + ".txt"; + + fin.open(tableName, ifstream::in); + if (!fin) { + throw cms::Exception("BadConfig") << "TripletEngine::readTables, file " << tableName << " not known"; + } + while (!fin.eof()) { + fin >> word; + num = atoi(word.c_str()); + table_.push_back(num > 0 ? true : false); + } + fin.close(); +} + +void TripletEngine::writeTables() { + ofstream fout; + stringstream tableName; + + tableName << "table/table_" << name_ << "_" << iSector_ << ".txt"; + + fout.open(tableName.str(), ofstream::out); + for (const auto &entry : table_) + fout << entry << endl; + fout.close(); + + for (const auto &tedName : spTable_) { + tableName.str(""); + tableName << "table/table_" << tedName.first << "_" << name_ << "_" << iSector_ << ".txt"; + + fout.open(tableName.str(), ofstream::out); + for (const auto &entry : tedName.second) { + for (const auto &spName : entry) + fout << spName.first << ":" << spName.second << " "; + fout << endl; + } + fout.close(); + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMProjectionsMemory.cc b/L1Trigger/TrackFindingTracklet/src/VMProjectionsMemory.cc new file mode 100644 index 0000000000000..ff4c8f2be7191 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMProjectionsMemory.cc @@ -0,0 +1,57 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMProjectionsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h" +#include +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +VMProjectionsMemory::VMProjectionsMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) { + initLayerDisk(7, layer_, disk_); +} + +void VMProjectionsMemory::addTracklet(Tracklet* tracklet, unsigned int allprojindex) { + std::pair tmp(tracklet, allprojindex); + //Check that order of TCID is correct + if (!tracklets_.empty()) { + assert(tracklets_[tracklets_.size() - 1].first->TCID() <= tracklet->TCID()); + } + tracklets_.push_back(tmp); +} + +void VMProjectionsMemory::writeVMPROJ(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/VMProjections/VMProjections_" << getName(); + //get rid of duplicates + auto const& tmp = oss.str(); + int len = tmp.size(); + if (tmp[len - 2] == 'n' && tmp[len - 1] > '1' && tmp[len - 1] <= '9') + return; + oss << "_" << std::setfill('0') << std::setw(2) << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int j = 0; j < tracklets_.size(); j++) { + string vmproj = (layer_ > 0) ? tracklets_[j].first->vmstrlayer(layer_, tracklets_[j].second) + : tracklets_[j].first->vmstrdisk(disk_, tracklets_[j].second); + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + out_ << " " << vmproj << " " << trklet::hexFormat(vmproj) << endl; + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMRouter.cc b/L1Trigger/TrackFindingTracklet/src/VMRouter.cc new file mode 100644 index 0000000000000..52aa1d099a32b --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMRouter.cc @@ -0,0 +1,337 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMRouter.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubTE.h" +#include "L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Exception.h" + +using namespace std; +using namespace trklet; + +VMRouter::VMRouter(string name, Settings const& settings, Globals* global, unsigned int iSector) + : ProcessBase(name, settings, global, iSector), vmrtable_(settings) { + layerdisk_ = initLayerDisk(4); + + vmstubsMEPHI_.resize(settings_.nvmme(layerdisk_), nullptr); + + overlapbits_ = 7; + nextrabits_ = overlapbits_ - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_)); + + vmrtable_.init(layerdisk_); + + nbitszfinebintable_ = settings_.vmrlutzbits(layerdisk_); + nbitsrfinebintable_ = settings_.vmrlutrbits(layerdisk_); +} + +void VMRouter::addOutput(MemoryBase* memory, string output) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output " + << output; + } + + if (output.substr(0, 10) == "allstubout") { + AllStubsMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + allstubs_.push_back(tmp); + return; + } + + if (output.substr(0, 12) == "vmstuboutPHI") { + char seedtype = memory->getName().substr(11, 1)[0]; + unsigned int pos = 12; + int vmbin = memory->getName().substr(pos, 1)[0] - '0'; + pos++; + if (pos < memory->getName().size()) { + if (memory->getName().substr(pos, 1)[0] != 'n') { + vmbin = vmbin * 10 + memory->getName().substr(pos, 1)[0] - '0'; + pos++; + } + } + + int iseed = -1; + unsigned int inner = 1; + if (memory->getName().substr(3, 2) == "TE") { + VMStubsTEMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + if (seedtype < 'I') { + if (layerdisk_ == 0 || layerdisk_ == 1) + iseed = 0; + if (layerdisk_ == 2 || layerdisk_ == 3) + iseed = 2; + if (layerdisk_ == 4 || layerdisk_ == 5) + iseed = 3; + if (layerdisk_ == 6 || layerdisk_ == 7) + iseed = 4; + if (layerdisk_ == 8 || layerdisk_ == 9) + iseed = 5; + if (layerdisk_ == 0 || layerdisk_ == 2 || layerdisk_ == 4 || layerdisk_ == 6 || layerdisk_ == 8) + inner = 0; + } else if (seedtype < 'M') { + if (layerdisk_ == 1 || layerdisk_ == 2) + iseed = 1; + if (layerdisk_ == 1) + inner = 0; + } else if (seedtype <= 'Z') { + if (layerdisk_ == 0 || layerdisk_ == 6) + iseed = 6; + if (layerdisk_ == 1 || layerdisk_ == 6) + iseed = 7; + if (layerdisk_ == 0 || layerdisk_ == 1) + inner = 0; + } else if (seedtype < 'o' && seedtype >= 'a') { + if (layerdisk_ == 1 || layerdisk_ == 2) + iseed = 10; + if (layerdisk_ == 1) + inner = 0; + } else if (seedtype > 'o' && seedtype <= 'z') { + if (layerdisk_ == 1) + iseed = 11; + if (layerdisk_ == 6) + iseed = 10; + inner = 2; + } else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!"; + } + assert(iseed != -1); + int seedindex = -1; + for (unsigned int k = 0; k < vmstubsTEPHI_.size(); k++) { + if (vmstubsTEPHI_[k].seednumber == (unsigned int)iseed) { + seedindex = k; + } + } + if (seedindex == -1) { + seedindex = vmstubsTEPHI_.size(); + vector avectmp; + vector > vectmp(settings_.nvmte(inner, iseed), avectmp); + VMStubsTEPHI atmp(iseed, inner, vectmp); + vmstubsTEPHI_.push_back(atmp); + } + vmstubsTEPHI_[seedindex].vmstubmem[(vmbin - 1) & (settings_.nvmte(inner, iseed) - 1)].push_back(tmp); + + } else if (memory->getName().substr(3, 2) == "ME") { + VMStubsMEMemory* tmp = dynamic_cast(memory); + assert(tmp != nullptr); + vmstubsMEPHI_[(vmbin - 1) & (settings_.nvmme(layerdisk_) - 1)] = tmp; + } else { + throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " should never get here!"; + } + + return; + } + + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output; +} + +void VMRouter::addInput(MemoryBase* memory, string input) { + if (settings_.writetrace()) { + edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input " + << input; + } + if (input == "stubin") { + InputLinkMemory* tmp1 = dynamic_cast(memory); + assert(tmp1 != nullptr); + if (tmp1 != nullptr) { + stubinputs_.push_back(tmp1); + } + return; + } + throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input; +} + +void VMRouter::execute() { + unsigned int allStubCounter = 0; + + //Loop over the input stubs + for (auto& stubinput : stubinputs_) { + for (unsigned int i = 0; i < stubinput->nStubs(); i++) { + if (allStubCounter > settings_.maxStep("VMR")) + continue; + if (allStubCounter > 127) + continue; + Stub* stub = stubinput->getStub(i); + + //Note - below information is not part of the stub, but rather from which input memory we are reading + bool negdisk = (stub->disk().value() < 0); + + //use &127 to make sure we fit into the number of bits - + //though we should have protected against overflows above + FPGAWord allStubIndex(allStubCounter & 127, 7, true, __LINE__, __FILE__); + + //TODO - should not be needed - but need to migrate some other pieces of code before removing + stub->setAllStubIndex(allStubCounter); + //TODO - should not be needed - but need to migrate some other pieces of code before removing + stub->l1tstub()->setAllStubIndex(allStubCounter); + + allStubCounter++; + + //Fill allstubs memories - in HLS this is the same write to multiple memories + for (auto& allstub : allstubs_) { + allstub->addStub(stub); + } + + //Fill all the ME VM memories + + FPGAWord iphi = stub->phicorr(); + unsigned int ivm = + iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_)), + settings_.nbitsvmme(layerdisk_)); + unsigned int extrabits = iphi.bits(iphi.nbits() - overlapbits_, nextrabits_); + + unsigned int ivmPlus = ivm; + + if (extrabits == ((1U << nextrabits_) - 1) && ivm != ((1U << settings_.nbitsvmme(layerdisk_)) - 1)) + ivmPlus++; + unsigned int ivmMinus = ivm; + if (extrabits == 0 && ivm != 0) + ivmMinus--; + + //Calculate the z and r position for the vmstub + + //Take the top nbitszfinebintable_ bits of the z coordinate + int indexz = (((1 << (stub->z().nbits() - 1)) + stub->z().value()) >> (stub->z().nbits() - nbitszfinebintable_)); + int indexr = -1; + if (layerdisk_ > (N_LAYER - 1)) { + if (negdisk) { + indexz = (1 << nbitszfinebintable_) - indexz; + } + indexr = stub->r().value(); + if (stub->isPSmodule()) { + indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_); + } + } else { + //Take the top nbitsfinebintable_ bits of the z coordinate. The & is to handle the negative z values. + indexr = (((1 << (stub->r().nbits() - 1)) + stub->r().value()) >> (stub->r().nbits() - nbitsrfinebintable_)); + } + + assert(indexz >= 0); + assert(indexr >= 0); + assert(indexz < (1 << nbitszfinebintable_)); + assert(indexr < (1 << nbitsrfinebintable_)); + + int melut = vmrtable_.lookup(indexz, indexr); + + assert(melut >= 0); + + int vmbin = melut >> 3; + if (negdisk) + vmbin += 8; + int rzfine = melut & 7; + + // pad disk PS bend word with a '0' in MSB so that all disk bends have 4 bits (for HLS compatibility) + int nbendbits = stub->bend().nbits(); + if (layerdisk_ >= N_LAYER) + nbendbits = settings_.nbendbitsmedisk(); + + VMStubME vmstub( + stub, + stub->iphivmFineBins(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_)), + settings_.nbitsvmme(layerdisk_)), + FPGAWord(rzfine, 3, true, __LINE__, __FILE__), + FPGAWord(stub->bend().value(), nbendbits, true, __LINE__, __FILE__), + allStubIndex); + + assert(vmstubsMEPHI_[ivmPlus] != nullptr); + vmstubsMEPHI_[ivmPlus]->addStub(vmstub, vmbin); + + if (ivmMinus != ivmPlus) { + assert(vmstubsMEPHI_[ivmMinus] != nullptr); + vmstubsMEPHI_[ivmMinus]->addStub(vmstub, vmbin); + } + + //Fill the TE VM memories + + for (auto& ivmstubTEPHI : vmstubsTEPHI_) { + unsigned int iseed = ivmstubTEPHI.seednumber; + unsigned int inner = ivmstubTEPHI.stubposition; + if ((iseed == 4 || iseed == 5 || iseed == 6 || iseed == 7) && (!stub->isPSmodule())) + continue; + + unsigned int lutwidth = settings_.lutwidthtab(inner, iseed); + if (settings_.extended()) { + lutwidth = settings_.lutwidthtabextended(inner, iseed); + } + + int lutval = -999; + + if (inner > 0) { + if (layerdisk_ < N_LAYER) { + lutval = melut; + } else { + if (inner == 2 && iseed == 10) { + lutval = 0; + if (stub->r().value() < 10) { + lutval = 8 * (1 + (stub->r().value() >> 2)); + } else { + if (stub->r().value() < settings_.rmindiskl3overlapvm() / settings_.kr()) { + lutval = -1; + } + } + } else { + lutval = vmrtable_.lookupdisk(indexz, indexr); + } + } + if (lutval == -1) + continue; + } else { + if (iseed < 6 || iseed > 7) { + lutval = vmrtable_.lookupinner(indexz, indexr); + } else { + lutval = vmrtable_.lookupinneroverlap(indexz, indexr); + } + if (lutval == -1) + continue; + if (settings_.extended() && (iseed == 2 || iseed == 3 || iseed == 10 || iseed == 4)) { + int lutval2 = vmrtable_.lookupinnerThird(indexz, indexr); + if (lutval2 == -1) + continue; + lutval += (lutval2 << 10); + } + } + + assert(lutval >= 0); + + FPGAWord binlookup(lutval, lutwidth, true, __LINE__, __FILE__); + + if (binlookup.value() < 0) + continue; + + unsigned int ivmte = + iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmte(inner, iseed)), + settings_.nbitsvmte(inner, iseed)); + + int bin = -1; + if (inner != 0) { + bin = binlookup.value() / 8; + unsigned int tmp = binlookup.value() & 7; //three bits in outer layers - this could be coded cleaner... + binlookup.set(tmp, 3, true, __LINE__, __FILE__); + } + + FPGAWord finephi = stub->iphivmFineBins(settings_.nphireg(inner, iseed), settings_.nfinephi(inner, iseed)); + + VMStubTE tmpstub(stub, finephi, stub->bend(), binlookup, allStubIndex); + + unsigned int nmem = ivmstubTEPHI.vmstubmem[ivmte].size(); + + assert(nmem > 0); + + for (unsigned int l = 0; l < nmem; l++) { + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " try adding stub to " + << ivmstubTEPHI.vmstubmem[ivmte][l]->getName() << " inner=" << inner + << " bin=" << bin; + } + if (inner == 0) { + ivmstubTEPHI.vmstubmem[ivmte][l]->addVMStub(tmpstub); + } else { + ivmstubTEPHI.vmstubmem[ivmte][l]->addVMStub(tmpstub, bin); + } + } + } + } + } +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMRouterPhiCorrTable.cc b/L1Trigger/TrackFindingTracklet/src/VMRouterPhiCorrTable.cc new file mode 100644 index 0000000000000..3ec4838e0adb0 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMRouterPhiCorrTable.cc @@ -0,0 +1,62 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMRouterPhiCorrTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include "L1Trigger/TrackFindingTracklet/interface/Util.h" + +using namespace std; +using namespace trklet; + +VMRouterPhiCorrTable::VMRouterPhiCorrTable(Settings const& settings) : TETableBase(settings) { nbits_ = 14; } + +void VMRouterPhiCorrTable::init(int layer, int bendbits, int rbits) { + assert(bendbits == 3 || bendbits == 4); + + layer_ = layer; + bendbits_ = bendbits; + rbits_ = rbits; + + rbins_ = (1 << rbits); + rmin_ = settings_.rmean(layer - 1) - settings_.drmax(); + rmax_ = settings_.rmean(layer - 1) + settings_.drmax(); + dr_ = 2 * settings_.drmax() / rbins_; + + bendbins_ = (1 << bendbits); + + rmean_ = settings_.rmean(layer - 1); + + for (int ibend = 0; ibend < bendbins_; ibend++) { + for (int irbin = 0; irbin < rbins_; irbin++) { + int value = getphiCorrValue(ibend, irbin); + table_.push_back(value); + } + } + + if (settings_.writeTable()) { + writeVMTable("VMPhiCorrL" + std::to_string(layer_) + ".txt", false); + } +} + +int VMRouterPhiCorrTable::getphiCorrValue(int ibend, int irbin) const { + double bend = trklet::benddecode(ibend, layer_ <= (int)N_PSLAYER); + + //for the rbin - calculate the distance to the nominal layer radius + double Delta = (irbin + 0.5) * dr_ - settings_.drmax(); + + //calculate the phi correction - this is a somewhat approximate formula + double dphi = (Delta / 0.18) * (bend * settings_.stripPitch(false)) / rmean_; + + int idphi = 0; + + if (layer_ <= (int)N_PSLAYER) { + idphi = dphi / settings_.kphi(); + } else { + idphi = dphi / settings_.kphi1(); + } + + return idphi; +} + +int VMRouterPhiCorrTable::lookupPhiCorr(int ibend, int rbin) { + int index = ibend * rbins_ + rbin; + assert(index < (int)table_.size()); + return table_[index]; +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMRouterTable.cc b/L1Trigger/TrackFindingTracklet/src/VMRouterTable.cc new file mode 100644 index 0000000000000..f1bcab0a26469 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMRouterTable.cc @@ -0,0 +1,288 @@ +// VMRouterTable: Lookup table used by the VMRouter to route stubs and provide information about which VMStubs are needed by the TrackletEngine +#include "L1Trigger/TrackFindingTracklet/interface/VMRouterTable.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include + +using namespace std; +using namespace trklet; + +VMRouterTable::VMRouterTable(Settings const& settings) : settings_(settings) {} + +VMRouterTable::VMRouterTable(Settings const& settings, unsigned int layerdisk) : settings_(settings) { + init(layerdisk); +} + +void VMRouterTable::init(unsigned int layerdisk) { + zbits_ = settings_.vmrlutzbits(layerdisk); + rbits_ = settings_.vmrlutrbits(layerdisk); + + rbins_ = (1 << rbits_); + zbins_ = (1 << zbits_); + + if (layerdisk < N_LAYER) { + zmin_ = -settings_.zlength(); + zmax_ = settings_.zlength(); + rmin_ = settings_.rmean(layerdisk) - settings_.drmax(); + rmax_ = settings_.rmean(layerdisk) + settings_.drmax(); + } else { + rmin_ = 0; + rmax_ = settings_.rmaxdisk(); + zmin_ = settings_.zmean(layerdisk - N_LAYER) - settings_.dzmax(); + zmax_ = settings_.zmean(layerdisk - N_LAYER) + settings_.dzmax(); + } + + dr_ = (rmax_ - rmin_) / rbins_; + dz_ = (zmax_ - zmin_) / zbins_; + + int NBINS = settings_.NLONGVMBINS() * settings_.NLONGVMBINS(); + + for (int izbin = 0; izbin < zbins_; izbin++) { + for (int irbin = 0; irbin < rbins_; irbin++) { + double r = rmin_ + (irbin + 0.5) * dr_; + double z = zmin_ + (izbin + 0.5) * dz_; + + if (layerdisk > (N_LAYER - 1) && irbin < 10) //special case for the tabulated radii in 2S disks + r = (layerdisk <= 7) ? settings_.rDSSinner(irbin) : settings_.rDSSouter(irbin); + + int bin; + if (layerdisk < N_LAYER) { + double zproj = z * settings_.rmean(layerdisk) / r; + bin = NBINS * (zproj + settings_.zlength()) / (2 * settings_.zlength()); + } else { + double rproj = r * settings_.zmean(layerdisk - N_LAYER) / z; + bin = NBINS * (rproj - settings_.rmindiskvm()) / (settings_.rmaxdisk() - settings_.rmindiskvm()); + } + if (bin < 0) + bin = 0; + if (bin >= NBINS) + bin = NBINS - 1; + vmrtable_.push_back(bin); + + if (layerdisk >= N_LAYER) { + double rproj = r * settings_.zmean(layerdisk - N_LAYER) / z; + bin = 0.5 * NBINS * (rproj - settings_.rmindiskvm()) / (settings_.rmaxdiskvm() - settings_.rmindiskvm()); + if (bin < 0) + bin = 0; + if (bin >= NBINS / 2) + bin = NBINS / 2 - 1; + vmrtabletedisk_.push_back(bin); + } + + if (layerdisk == 0 || layerdisk == 2 || layerdisk == 4 || layerdisk == 6 || layerdisk == 8) { + vmrtableteinner_.push_back(getLookup(layerdisk + 1, z, r)); + } + + if (layerdisk == 1) { + vmrtableteinner_.push_back(getLookup(layerdisk + 1, z, r, 1)); + } + + if (layerdisk == 1) { //projection from L2 to D1 for L2L3D1 seeding + vmrtableteinnerThird_.push_back(getLookup(6, z, r, 10)); + } + + if (layerdisk == 4) { //projection from L5 to L4 for L5L6L4 seeding + vmrtableteinnerThird_.push_back(getLookup(3, z, r)); + } + + if (layerdisk == 2) { //projection from L3 to L5 for L3L4L2 seeding + vmrtableteinnerThird_.push_back(getLookup(1, z, r)); + } + + if (layerdisk == 6) { //projection from D1 to L2 for D1D2L2 seeding + vmrtableteinnerThird_.push_back(getLookup(1, z, r)); + } + + if (layerdisk == 0 || layerdisk == 1) { + vmrtableteinneroverlap_.push_back(getLookup(6, z, r, layerdisk + 6)); + } + } + } +} + +int VMRouterTable::getLookup(unsigned int layerdisk, double z, double r, int iseed) { + double z0cut = settings_.z0cut(); + + if (layerdisk < N_LAYER) { + if (iseed == 1 && std::abs(z) < 52.0) + return -1; + + double rmean = settings_.rmean(layerdisk); + + double rratio1 = rmean / (r + 0.5 * dr_); + double rratio2 = rmean / (r - 0.5 * dr_); + + double z1 = (z - 0.5 * dz_) * rratio1 + z0cut * (rratio1 - 1.0); + double z2 = (z + 0.5 * dz_) * rratio1 + z0cut * (rratio1 - 1.0); + double z3 = (z - 0.5 * dz_) * rratio2 + z0cut * (rratio2 - 1.0); + double z4 = (z + 0.5 * dz_) * rratio2 + z0cut * (rratio2 - 1.0); + double z5 = (z - 0.5 * dz_) * rratio1 - z0cut * (rratio1 - 1.0); + double z6 = (z + 0.5 * dz_) * rratio1 - z0cut * (rratio1 - 1.0); + double z7 = (z - 0.5 * dz_) * rratio2 - z0cut * (rratio2 - 1.0); + double z8 = (z + 0.5 * dz_) * rratio2 - z0cut * (rratio2 - 1.0); + + double zmin = std::min({z1, z2, z3, z4, z5, z6, z7, z8}); + double zmax = std::max({z1, z2, z3, z4, z5, z6, z7, z8}); + + int NBINS = settings_.NLONGVMBINS() * settings_.NLONGVMBINS(); + + int zbin1 = NBINS * (zmin + settings_.zlength()) / (2 * settings_.zlength()); + int zbin2 = NBINS * (zmax + settings_.zlength()) / (2 * settings_.zlength()); + + if (zbin1 >= NBINS) + return -1; + if (zbin2 < 0) + return -1; + + if (zbin2 >= NBINS) + zbin2 = NBINS - 1; + if (zbin1 < 0) + zbin1 = 0; + + // This is a 10 bit word: + // xxx|yyy|z|rrr + // xxx is the delta z window + // yyy is the z bin + // z is flag to look in next bin + // rrr first fine z bin + // NOTE : this encoding is not efficient z is one if xxx+rrr is greater than 8 + // and xxx is only 1,2, or 3 + // should also reject xxx=0 as this means projection is outside range + + int value = zbin1 / 8; + value *= 2; + if (zbin2 / 8 - zbin1 / 8 > 0) + value += 1; + value *= 8; + value += (zbin1 & 7); + assert(value / 8 < 15); + int deltaz = zbin2 - zbin1; + if (deltaz > 7) { + deltaz = 7; + } + assert(deltaz < 8); + value += (deltaz << 7); + + return value; + + } else { + if (std::abs(z) < 2.0 * z0cut) + return -1; + + double zmean = settings_.zmean(layerdisk - N_LAYER); + if (z < 0.0) + zmean = -zmean; + + double r1 = (r + 0.5 * dr_) * (zmean + z0cut) / (z + 0.5 * dz_ + z0cut); + double r2 = (r - 0.5 * dr_) * (zmean - z0cut) / (z + 0.5 * dz_ - z0cut); + double r3 = (r + 0.5 * dr_) * (zmean + z0cut) / (z - 0.5 * dz_ + z0cut); + double r4 = (r - 0.5 * dr_) * (zmean - z0cut) / (z - 0.5 * dz_ - z0cut); + double r5 = (r + 0.5 * dr_) * (zmean - z0cut) / (z + 0.5 * dz_ - z0cut); + double r6 = (r - 0.5 * dr_) * (zmean + z0cut) / (z + 0.5 * dz_ + z0cut); + double r7 = (r + 0.5 * dr_) * (zmean - z0cut) / (z - 0.5 * dz_ - z0cut); + double r8 = (r - 0.5 * dr_) * (zmean + z0cut) / (z - 0.5 * dz_ + z0cut); + + double rmin = std::min({r1, r2, r3, r4, r5, r6, r7, r8}); + double rmax = std::max({r1, r2, r3, r4, r5, r6, r7, r8}); + + int NBINS = settings_.NLONGVMBINS() * settings_.NLONGVMBINS() / 2; + + double rmindisk = settings_.rmindiskvm(); + double rmaxdisk = settings_.rmaxdiskvm(); + + if (iseed == 6) + rmaxdisk = settings_.rmaxdiskl1overlapvm(); + if (iseed == 7) + rmindisk = settings_.rmindiskl2overlapvm(); + if (iseed == 10) + rmaxdisk = settings_.rmaxdisk(); + + if (rmin > rmaxdisk) + return -1; + if (rmax > rmaxdisk) + rmax = rmaxdisk; + + if (rmax < rmindisk) + return -1; + if (rmin < rmindisk) + rmin = rmindisk; + + int rbin1 = NBINS * (rmin - settings_.rmindiskvm()) / (settings_.rmaxdiskvm() - settings_.rmindiskvm()); + int rbin2 = NBINS * (rmax - settings_.rmindiskvm()) / (settings_.rmaxdiskvm() - settings_.rmindiskvm()); + + if (iseed == 10) { + constexpr double rminspec = 40.0; + rbin1 = NBINS * (rmin - rminspec) / (settings_.rmaxdisk() - rminspec); + rbin2 = NBINS * (rmax - rminspec) / (settings_.rmaxdisk() - rminspec); + } + + if (rbin2 >= NBINS) + rbin2 = NBINS - 1; + if (rbin1 < 0) + rbin1 = 0; + + // This is a 9 bit word: + // xxx|yy|z|rrr + // xxx is the delta r window + // yy is the r bin yy is three bits for overlaps + // z is flag to look in next bin + // rrr fine r bin + // NOTE : this encoding is not efficient z is one if xxx+rrr is greater than 8 + // and xxx is only 1,2, or 3 + // should also reject xxx=0 as this means projection is outside range + + bool overlap = iseed == 6 || iseed == 7 || iseed == 10; + + int value = rbin1 / 8; + if (overlap) { + if (z < 0.0) + value += 4; + } + value *= 2; + if (rbin2 / 8 - rbin1 / 8 > 0) + value += 1; + value *= 8; + value += (rbin1 & 7); + assert(value / 8 < 15); + int deltar = rbin2 - rbin1; + if (deltar > 7) + deltar = 7; + if (overlap) { + value += (deltar << 7); + } else { + value += (deltar << 6); + } + + return value; + } +} + +int VMRouterTable::lookup(int zbin, int rbin) { + int index = zbin * rbins_ + rbin; + assert(index >= 0 && index < (int)vmrtable_.size()); + return vmrtable_[index]; +} + +int VMRouterTable::lookupdisk(int zbin, int rbin) { + int index = zbin * rbins_ + rbin; + assert(index >= 0 && index < (int)vmrtabletedisk_.size()); + return vmrtabletedisk_[index]; +} + +int VMRouterTable::lookupinner(int zbin, int rbin) { + int index = zbin * rbins_ + rbin; + assert(index >= 0 && index < (int)vmrtableteinner_.size()); + return vmrtableteinner_[index]; +} + +int VMRouterTable::lookupinneroverlap(int zbin, int rbin) { + int index = zbin * rbins_ + rbin; + assert(index >= 0 && index < (int)vmrtableteinneroverlap_.size()); + return vmrtableteinneroverlap_[index]; +} + +int VMRouterTable::lookupinnerThird(int zbin, int rbin) { + int index = zbin * rbins_ + rbin; + assert(index >= 0 && index < (int)vmrtableteinnerThird_.size()); + return vmrtableteinnerThird_[index]; +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMStubME.cc b/L1Trigger/TrackFindingTracklet/src/VMStubME.cc new file mode 100644 index 0000000000000..d7e63bccc2002 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMStubME.cc @@ -0,0 +1,24 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMStubME.h" + +using namespace std; +using namespace trklet; + +VMStubME::VMStubME(const Stub* stub, FPGAWord finephi, FPGAWord finerz, FPGAWord bend, FPGAWord allstubindex) { + stub_ = stub; + finephi_ = finephi; + finerz_ = finerz; + bend_ = bend; + allStubIndex_ = allstubindex; +} + +std::string VMStubME::str() const { + string stub = allStubIndex_.str(); + stub += "|"; + stub += bend_.str(); + stub += "|"; + stub += finephi_.str(); + stub += "|"; + stub += finerz_.str(); + + return stub; +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMStubTE.cc b/L1Trigger/TrackFindingTracklet/src/VMStubTE.cc new file mode 100644 index 0000000000000..a7eb85cb17408 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMStubTE.cc @@ -0,0 +1,24 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMStubTE.h" + +using namespace std; +using namespace trklet; + +VMStubTE::VMStubTE(const Stub* stub, FPGAWord finephi, FPGAWord bend, FPGAWord vmbits, FPGAWord allstubindex) { + stub_ = stub; + finephi_ = finephi; + bend_ = bend; + vmbits_ = vmbits; + allStubIndex_ = allstubindex; +} + +std::string VMStubTE::str() const { + string stub = allStubIndex_.str(); + stub += "|"; + stub += bend_.str(); + stub += "|"; + stub += finephi_.str(); + stub += "|"; + stub += vmbits_.str(); + + return stub; +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMStubsMEMemory.cc b/L1Trigger/TrackFindingTracklet/src/VMStubsMEMemory.cc new file mode 100644 index 0000000000000..59418f445c5f5 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMStubsMEMemory.cc @@ -0,0 +1,55 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" +#include + +using namespace std; +using namespace trklet; + +VMStubsMEMemory::VMStubsMEMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) { + unsigned int layerdisk = initLayerDisk(6); + if (layerdisk < N_LAYER) { + binnedstubs_.resize(settings_.NLONGVMBINS()); + } else { + //For disks we have NLONGVMBITS on each disk + binnedstubs_.resize(2 * settings_.NLONGVMBINS()); + } +} + +void VMStubsMEMemory::writeStubs(bool first) { + std::ostringstream oss; + oss << "../data/MemPrints/VMStubsME/VMStubs_" << getName(); + //get rid of duplicates + auto const& tmp = oss.str(); + int len = tmp.size(); + if (tmp[len - 2] == 'n' && tmp[len - 1] > '1' && tmp[len - 1] <= '9') + return; + oss << "_" << std::setfill('0') << std::setw(2) << (iSector_ + 1) << ".dat"; + auto const& fname = oss.str(); + + if (first) { + bx_ = 0; + event_ = 1; + out_.open(fname.c_str()); + } else + out_.open(fname.c_str(), std::ofstream::app); + + out_ << "BX = " << (bitset<3>)bx_ << " Event : " << event_ << endl; + + for (unsigned int i = 0; i < binnedstubs_.size(); i++) { + for (unsigned int j = 0; j < binnedstubs_[i].size(); j++) { + string stub = binnedstubs_[i][j].stubindex().str(); + stub += "|" + binnedstubs_[i][j].bend().str(); + + FPGAWord finepos = binnedstubs_[i][j].finerz(); + stub += "|" + finepos.str(); + out_ << hex << i << " " << j << dec << " " << stub << " " << trklet::hexFormat(stub) << endl; + } + } + out_.close(); + + bx_++; + event_++; + if (bx_ > 7) + bx_ = 0; +} diff --git a/L1Trigger/TrackFindingTracklet/src/VMStubsTEMemory.cc b/L1Trigger/TrackFindingTracklet/src/VMStubsTEMemory.cc new file mode 100644 index 0000000000000..523af7ebdc242 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/VMStubsTEMemory.cc @@ -0,0 +1,277 @@ +#include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h" +#include +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace std; +using namespace trklet; + +VMStubsTEMemory::VMStubsTEMemory(string name, Settings const& settings, unsigned int iSector) + : MemoryBase(name, settings, iSector) { + //set the layer or disk that the memory is in + initLayerDisk(6, layer_, disk_); + + //Pointer to other VMStub memory for creating stub pairs + other_ = nullptr; + + //What type of seeding is this memory used for + initSpecialSeeding(11, overlap_, extra_, extended_); + + string subname = name.substr(12, 2); + phibin_ = subname[0] - '0'; + if (subname[1] != 'n') { + phibin_ = 10 * phibin_ + (subname[1] - '0'); + } + + //set the bins used in the bend tabele + unsigned int nbins = 8; + if (layer_ >= 4) + nbins = 16; + if (disk_ == 1 && extended_ && overlap_) + nbins = 16; + for (unsigned int i = 0; i < nbins; i++) { + vmbendtable_.push_back(true); + } + + isinner_ = (layer_ % 2 == 1 or disk_ % 2 == 1); + // special cases with overlap seeding + if (overlap_ and layer_ == 2) + isinner_ = true; + if (overlap_ and layer_ == 3) + isinner_ = false; + if (overlap_ and disk_ == 1) + isinner_ = false; + + if (extra_ and layer_ == 2) + isinner_ = true; + if (extra_ and layer_ == 3) + isinner_ = false; + // more special cases for triplets + if (!overlap_ and extended_ and layer_ == 2) + isinner_ = true; + if (!overlap_ and extended_ and layer_ == 3) + isinner_ = false; + if (overlap_ and extended_ and layer_ == 2) + isinner_ = false; + if (overlap_ and extended_ and disk_ == 1) + isinner_ = false; + + stubsbinnedvm_.resize(settings_.NLONGVMBINS()); +} + +bool VMStubsTEMemory::addVMStub(VMStubTE vmstub, int bin) { + //If the pt of the stub is consistent with the allowed pt of tracklets + //in that can be formed in this VM and the other VM used in the TE. + bool pass = passbend(vmstub.bend().value()); + + if (!pass) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << getName() << " Stub failed bend cut. bend = " + << benddecode(vmstub.bend().value(), vmstub.isPSmodule()); + return false; + } + + bool negdisk = vmstub.stub()->disk().value() < 0.0; + + if (overlap_) { + if (disk_ == 1) { + assert(bin < 4); + if (negdisk) + bin += 4; + if (stubsbinnedvm_[bin].size() >= settings_.maxStubsPerBin()) + return false; + stubsbinnedvm_[bin].push_back(vmstub); + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << getName() << " Stub in disk = " << disk_ << " in bin = " << bin; + } else if (layer_ == 2) { + if (stubsbinnedvm_[bin].size() >= settings_.maxStubsPerBin()) + return false; + stubsbinnedvm_[bin].push_back(vmstub); + } + } else { + if (vmstub.stub()->isBarrel()) { + if (!isinner_) { + if (stubsbinnedvm_[bin].size() >= settings_.maxStubsPerBin()) + return false; + stubsbinnedvm_[bin].push_back(vmstub); + } + + } else { + if (disk_ % 2 == 0) { + assert(bin < 4); + if (negdisk) + bin += 4; + if (stubsbinnedvm_[bin].size() >= settings_.maxStubsPerBin()) + return false; + stubsbinnedvm_[bin].push_back(vmstub); + } + } + } + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding stubs to " << getName(); + if (stubsbinnedvm_[bin].size() >= settings_.maxStubsPerBin()) + return false; + stubsvm_.push_back(vmstub); + return true; +} + +// TODO - should migrate away from using this method for any binned memory +bool VMStubsTEMemory::addVMStub(VMStubTE vmstub) { + FPGAWord binlookup = vmstub.vmbits(); + + assert(binlookup.value() >= 0); + int bin = (binlookup.value() / 8); + + //If the pt of the stub is consistent with the allowed pt of tracklets + //in that can be formed in this VM and the other VM used in the TE. + bool pass = passbend(vmstub.bend().value()); + + if (!pass) { + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << getName() << " Stub failed bend cut. bend = " + << benddecode(vmstub.bend().value(), vmstub.isPSmodule()); + return false; + } + + bool negdisk = vmstub.stub()->disk().value() < 0.0; + + if (!extended_) { + if (overlap_) { + if (disk_ == 1) { + assert(bin < 4); + if (negdisk) + bin += 4; + stubsbinnedvm_[bin].push_back(vmstub); + if (settings_.debugTracklet()) { + edm::LogVerbatim("Tracklet") << getName() << " Stub with lookup = " << binlookup.value() + << " in disk = " << disk_ << " in bin = " << bin; + } + } + } else { + if (vmstub.stub()->isBarrel()) { + if (!isinner_) { + stubsbinnedvm_[bin].push_back(vmstub); + } + + } else { + if (disk_ % 2 == 0) { + assert(bin < 4); + if (negdisk) + bin += 4; + stubsbinnedvm_[bin].push_back(vmstub); + } + } + } + } else { //extended + if (!isinner_) { + if (layer_ > 0) { + stubsbinnedvm_[bin].push_back(vmstub); + } else { + if (overlap_) { + assert(disk_ == 1); // D1 from L2L3D1 + + //bin 0 is PS, 1 through 3 is 2S + if (vmstub.stub()->isPSmodule()) { + bin = 0; + } else { + bin = vmstub.stub()->r().value(); // 0 to 9 + bin = bin >> 2; // 0 to 2 + bin += 1; + } + } + assert(bin < 4); + if (negdisk) + bin += 4; + stubsbinnedvm_[bin].push_back(vmstub); + } + } + } + + if (settings_.debugTracklet()) + edm::LogVerbatim("Tracklet") << "Adding stubs to " << getName(); + stubsvm_.push_back(vmstub); + return true; +} + +void VMStubsTEMemory::clean() { + stubsvm_.clear(); + for (unsigned int i = 0; i < settings_.NLONGVMBINS(); i++) { + stubsbinnedvm_[i].clear(); + } +} + +void VMStubsTEMemory::writeStubs(bool first) { + openFile(first, "../data/MemPrints/VMStubsTE/VMStubs_"); + + if (isinner_) { // inner VM for TE purpose + for (unsigned int j = 0; j < stubsvm_.size(); j++) { + out_ << "0x"; + out_ << std::setfill('0') << std::setw(2); + out_ << hex << j << dec; + string stub = stubsvm_[j].str(); + out_ << " " << stub << " " << trklet::hexFormat(stub) << endl; + } + } else { // outer VM for TE purpose + for (unsigned int i = 0; i < settings_.NLONGVMBINS(); i++) { + for (unsigned int j = 0; j < stubsbinnedvm_[i].size(); j++) { + string stub = stubsbinnedvm_[i][j].str(); + out_ << hex << i << " " << j << dec << " " << stub << " " << trklet::hexFormat(stub) << endl; + } + } + } + + out_.close(); +} + +void VMStubsTEMemory::getPhiRange(double& phimin, double& phimax, unsigned int iSeed, unsigned int inner) { + int nvm = -1; + if (overlap_) { + if (layer_ > 0) { + nvm = settings_.nallstubs(layer_ - 1) * settings_.nvmte(inner, iSeed); + } + if (disk_ > 0) { + nvm = settings_.nallstubs(disk_ + N_DISK) * settings_.nvmte(inner, iSeed); + } + } else { + if (layer_ > 0) { + nvm = settings_.nallstubs(layer_ - 1) * settings_.nvmte(inner, iSeed); + if (extra_) { + nvm = settings_.nallstubs(layer_ - 1) * settings_.nvmte(inner, iSeed); + } + } + if (disk_ > 0) { + nvm = settings_.nallstubs(disk_ + N_DISK) * settings_.nvmte(inner, iSeed); + } + } + assert(nvm > 0); + assert(nvm <= 32); + double dphi = settings_.dphisectorHG() / nvm; + phimax = phibin() * dphi; + phimin = phimax - dphi; + + return; +} + +void VMStubsTEMemory::setbendtable(std::vector vmbendtable) { + assert(vmbendtable_.size() == vmbendtable.size()); + for (unsigned int i = 0; i < vmbendtable.size(); i++) { + vmbendtable_[i] = vmbendtable[i]; + } + + if (iSector_ == 0 && settings_.writeTable()) + writeVMBendTable(); +} + +void VMStubsTEMemory::writeVMBendTable() { + ofstream outvmbendcut; + outvmbendcut.open(getName() + "_vmbendcut.tab"); + outvmbendcut << "{" << endl; + unsigned int vmbendtableSize = vmbendtable_.size(); + assert(vmbendtableSize == 16 || vmbendtableSize == 8); + for (unsigned int i = 0; i < vmbendtableSize; i++) { + if (i != 0) + outvmbendcut << "," << endl; + outvmbendcut << vmbendtable_[i]; + } + outvmbendcut << endl << "};" << endl; + outvmbendcut.close(); +} diff --git a/L1Trigger/TrackFindingTracklet/src/imath.cc b/L1Trigger/TrackFindingTracklet/src/imath.cc new file mode 100644 index 0000000000000..a5498f6fa3959 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/imath.cc @@ -0,0 +1,439 @@ +// +// Integer representation of floating point arithmetic suitable for FPGA designs +// +// Author: Yuri Gershtein +// Date: March 2018 +// + +#include "L1Trigger/TrackFindingTracklet/interface/imath.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include + +using namespace trklet; + +std::string VarBase::itos(int i) { return std::to_string(i); } + +std::string VarBase::kstring() const { + char s[1024]; + std::string t = ""; + for (const auto &Kmap : Kmap_) { + sprintf(s, "^(%i)", Kmap.second); + std::string t0(s); + t = t + Kmap.first + t0; + } + return t; +} + +void VarBase::analyze() { + if (!readytoanalyze_) + return; + + double u = maxval_; + if (u < -minval_) + u = -minval_; + + int iu = log2(range() / u); + if (iu > 1) { + char slog[1024]; + sprintf(slog, + "analyzing %s: range %g is much larger then %g. suggest cutting by a factor of 2^%i", + name_.c_str(), + range(), + u, + iu); + edm::LogVerbatim("Tracklet") << slog; + } +#ifdef IMATH_ROOT + char slog[100]; + if (h_) { + double eff = h_->Integral() / h_->GetEntries(); + if (eff < 0.99) { + sprintf(slog, "analyzing %s: range is too small, contains %f", name_.c_str(), eff); + edm::LogVerbatim("Tracklet") << slog; + h_->Print(); + } + globals_->h_file_->cd(); + TCanvas *c = new TCanvas(); + c->cd(); + h_->Draw("colz"); + h_->Write(); + } else { + if (globals_->use_root) { + sprintf(slog, "analyzing %s: no histogram!\n", name_.c_str()); + edm::LogVerbatim("Tracklet") << slog; + } + } +#endif + + if (p1_) + p1_->analyze(); + if (p2_) + p2_->analyze(); + + readytoanalyze_ = false; +} + +std::string VarBase::dump() { + char s[1024]; + std::string u = kstring(); + sprintf( + s, + "Name = %s \t Op = %s \t nbits = %i \n ival = %li \t fval = %g \t K = %g Range = %f\n units = %s\n", + name_.c_str(), + op_.c_str(), + nbits_, + ival_, + fval_, + K_, + range(), + u.c_str()); + std::string t(s); + return t; +} + +void VarBase::dump_msg() { + char s[2048]; + std::string u = kstring(); + sprintf(s, + "Name = %s \t Op = %s \t nbits = %i \n ival = %li \t fval = %g \t K = %g Range = %f\n units = " + "%s\n step = %i, latency = %i\n", + name_.c_str(), + op_.c_str(), + nbits_, + ival_, + fval_, + K_, + range(), + u.c_str(), + step_, + latency_); + std::string t(s); + edm::LogVerbatim("Tracklet") << t; + if (p1_) + p1_->dump_msg(); + if (p2_) + p2_->dump_msg(); +} + +void VarAdjustK::adjust(double Knew, double epsilon, bool do_assert, int nbits) { + //WARNING!!! + //THIS METHID CAN BE USED ONLY FOR THE FINAL ANSWER + //THE CHANGE IN CONSTANT CAN NOT BE PROPAGATED UP THE CALCULATION TREE + + K_ = p1_->K(); + Kmap_ = p1_->Kmap(); + double r = Knew / K_; + + lr_ = (r > 1) ? log2(r) + epsilon : log2(r); + K_ = K_ * pow(2, lr_); + if (do_assert) + assert(std::abs(Knew / K_ - 1) < epsilon); + + if (nbits > 0) + nbits_ = nbits; + else + nbits_ = p1_->nbits() - lr_; + + Kmap_["2"] = Kmap_["2"] + lr_; +} + +void VarInv::initLUT(double offset) { + offset_ = offset; + double offsetI = lround(offset_ / p1_->K()); + for (int i = 0; i < Nelements_; ++i) { + int i1 = addr_to_ival(i); + LUT[i] = gen_inv(offsetI + i1); + } +} + +void VarBase::makeready() { + pipe_counter_ = 0; + pipe_delays_.clear(); + readytoprint_ = true; + readytoanalyze_ = true; + usedasinput_ = false; + if (p1_) + p1_->makeready(); + if (p2_) + p2_->makeready(); + if (p3_) + p3_->makeready(); +} + +bool VarBase::has_delay(int i) { + //dumb sequential search + for (int pipe_delay : pipe_delays_) + if (pipe_delay == i) + return true; + return false; +} + +std::string VarBase::pipe_delay(VarBase *v, int nbits, int delay) { + //have we been delayed by this much already? + if (v->has_delay(delay)) + return ""; + v->add_delay(delay); + std::string name = v->name(); + std::string name_delayed = name + "_delay" + itos(delay); + std::string out = "wire signed [" + itos(nbits - 1) + ":0] " + name_delayed + ";\n"; + out = out + pipe_delay_wire(v, name_delayed, nbits, delay); + return out; +} +std::string VarBase::pipe_delays(const int step) { + std::string out = ""; + if (p1_) + out += p1_->pipe_delays(step); + if (p2_) + out += p2_->pipe_delays(step); + if (p3_) + out += p3_->pipe_delays(step); + + int l = step - latency_ - step_; + return (out + pipe_delay(this, nbits(), l)); +} +std::string VarBase::pipe_delay_wire(VarBase *v, std::string name_delayed, int nbits, int delay) { + std::string name = v->name(); + std::string name_pipe = name + "_pipe" + itos(v->pipe_counter()); + v->pipe_increment(); + std::string out = "pipe_delay #(.STAGES(" + itos(delay) + "), .WIDTH(" + itos(nbits) + ")) " + name_pipe + + "(.clk(clk), .val_in(" + name + "), .val_out(" + name_delayed + "));\n"; + return out; +} + +void VarBase::inputs(std::vector *vd) { + if (op_ == "def" && !usedasinput_) { + usedasinput_ = true; + vd->push_back(this); + } else { + if (p1_) + p1_->inputs(vd); + if (p2_) + p2_->inputs(vd); + if (p3_) + p3_->inputs(vd); + } +} + +#ifdef IMATH_ROOT +TTree *VarBase::addToTree(imathGlobals *globals, VarBase *v, char *s) { + if (globals->h_file_ == 0) { + globals->h_file_ = new TFile("imath.root", "RECREATE"); + edm::LogVerbatim("Tracklet") << "recreating file imath.root"; + } + globals->h_file_->cd(); + TTree *tt = (TTree *)globals->h_file_->Get("tt"); + if (tt == 0) { + tt = new TTree("tt", ""); + edm::LogVerbatim("Tracklet") << "creating TTree tt"; + } + std::string si = v->name() + "_i"; + std::string sf = v->name() + "_f"; + std::string sv = v->name(); + if (s != 0) { + std::string prefix(s); + si = prefix + si; + sf = prefix + sf; + sv = prefix + sv; + } + if (!tt->GetBranchStatus(si.c_str())) { + tt->Branch(si.c_str(), (Long64_t *)&(v->ival_)); + tt->Branch(sf.c_str(), &(v->fval_)); + tt->Branch(sv.c_str(), &(v->val_)); + } + + if (v->p1_) + addToTree(globals, v->p1_, s); + if (v->p2_) + addToTree(globals, v->p2_, s); + if (v->p3_) + addToTree(globals, v->p3_, s); + + return tt; +} +TTree *VarBase::addToTree(imathGlobals *globals, double *v, char *s) { + if (globals->h_file_ == 0) { + globals->h_file_ = new TFile("imath.root", "RECREATE"); + edm::LogVerbatim("Tracklet") << "recreating file imath.root"; + } + globals->h_file_->cd(); + TTree *tt = (TTree *)globals->h_file_->Get("tt"); + if (tt == 0) { + tt = new TTree("tt", ""); + edm::LogVerbatim("Tracklet") << "creating TTree tt"; + } + tt->Branch(s, v); + return tt; +} +TTree *VarBase::addToTree(imathGlobals *globals, int *v, char *s) { + if (globals->h_file_ == 0) { + globals->h_file_ = new TFile("imath.root", "RECREATE"); + edm::LogVerbatim("Tracklet") << "recreating file imath.root"; + } + globals->h_file_->cd(); + TTree *tt = (TTree *)globals->h_file_->Get("tt"); + if (tt == 0) { + tt = new TTree("tt", ""); + edm::LogVerbatim("Tracklet") << "creating TTree tt"; + } + tt->Branch(s, v); + return tt; +} +void VarBase::fillTree(imathGlobals *globals) { + if (globals->h_file_ == 0) + return; + globals->h_file_->cd(); + TTree *tt = (TTree *)globals->h_file_->Get("tt"); + if (tt == 0) + return; + tt->Fill(); +} +void VarBase::writeTree(imathGlobals *globals) { + if (globals->h_file_ == 0) + return; + globals->h_file_->cd(); + TTree *tt = (TTree *)globals->h_file_->Get("tt"); + if (tt == 0) + return; + tt->Write(); +} + +#endif + +void VarCut::local_passes(std::map > &passes, + const std::map > *const previous_passes) const { + const int lower_cut = lower_cut_ / cut_var_->K(); + const int upper_cut = upper_cut_ / cut_var_->K(); + if (!previous_passes || (previous_passes && !previous_passes->count(cut_var_))) { + if (!passes.count(cut_var_)) + passes[cut_var_]; + passes.at(cut_var_).push_back(cut_var_->ival() > lower_cut && cut_var_->ival() < upper_cut); + } +} + +bool VarBase::local_passes() const { + bool passes = false; + for (const auto &cut : cuts_) { + const VarCut *const cast_cut = (VarCut *)cut; + const int lower_cut = cast_cut->lower_cut() / K_; + const int upper_cut = cast_cut->upper_cut() / K_; + passes = passes || (ival_ > lower_cut && ival_ < upper_cut); + if (globals_->printCutInfo_) { + edm::LogVerbatim("Tracklet") << " " << name_ << " " + << ((ival_ > lower_cut && ival_ < upper_cut) ? "PASSES" : "FAILS") + << " (required: " << lower_cut * K_ << " < " << ival_ * K_ << " < " << upper_cut * K_ + << ")"; + } + } + return passes; +} + +void VarBase::passes(std::map > &passes, + const std::map > *const previous_passes) const { + if (p1_) + p1_->passes(passes, previous_passes); + if (p2_) + p2_->passes(passes, previous_passes); + if (p3_) + p3_->passes(passes, previous_passes); + + for (const auto &cut : cuts_) { + const VarCut *const cast_cut = (VarCut *)cut; + const int lower_cut = cast_cut->lower_cut() / K_; + const int upper_cut = cast_cut->upper_cut() / K_; + if (!previous_passes || (previous_passes && !previous_passes->count(this))) { + if (!passes.count(this)) + passes[this]; + passes.at(this).push_back(ival_ > lower_cut && ival_ < upper_cut); + if (globals_->printCutInfo_) { + edm::LogVerbatim("Tracklet") << " " << name_ << " " + << ((ival_ > lower_cut && ival_ < upper_cut) ? "PASSES" : "FAILS") + << " (required: " << lower_cut * K_ << " < " << ival_ * K_ << " < " + << upper_cut * K_ << ")"; + } + } + } +} + +void VarBase::add_cut(VarCut *cut, const bool call_set_cut_var) { + cuts_.push_back(cut); + if (call_set_cut_var) + cut->set_cut_var(this, false); +} + +void VarCut::set_cut_var(VarBase *cut_var, const bool call_add_cut) { + cut_var_ = cut_var; + if (call_add_cut) + cut_var->add_cut(this, false); + if (parent_flag_) + parent_flag_->calculate_step(); +} + +void VarFlag::add_cut(VarBase *cut, const bool call_set_parent_flag) { + cuts_.push_back(cut); + if (cut->op() == "cut" && call_set_parent_flag) { + VarCut *const cast_cut = (VarCut *)cut; + cast_cut->set_parent_flag(this, false); + } + calculate_step(); +} + +void VarCut::set_parent_flag(VarFlag *parent_flag, const bool call_add_cut) { + parent_flag_ = parent_flag; + if (call_add_cut) + parent_flag->add_cut(this, false); +} + +VarBase *VarBase::cut_var() { + if (op_ == "cut") + return cut_var_; + else + return this; +} + +bool VarFlag::passes() { + if (globals_->printCutInfo_) { + edm::LogVerbatim("Tracklet") << "Checking if " << name_ << " passes..."; + } + + std::map > passes0, passes1; + for (const auto &cut : cuts_) { + if (cut->op() != "cut") + continue; + const VarCut *const cast_cut = (VarCut *)cut; + cast_cut->local_passes(passes0); + } + for (const auto &cut : cuts_) { + if (cut->op() != "cut") + cut->passes(passes1, &passes0); + else { + if (cut->cut_var()->p1()) + cut->cut_var()->p1()->passes(passes1, &passes0); + if (cut->cut_var()->p2()) + cut->cut_var()->p2()->passes(passes1, &passes0); + if (cut->cut_var()->p3()) + cut->cut_var()->p3()->passes(passes1, &passes0); + } + } + + bool passes = true; + for (const auto &cut_var : passes0) { + bool local_passes = false; + for (const auto &pass : cut_var.second) + local_passes = local_passes || pass; + passes = passes && local_passes; + } + for (const auto &cut_var : passes1) { + bool local_passes = false; + for (const auto &pass : cut_var.second) + local_passes = local_passes || pass; + passes = passes && local_passes; + } + + if (globals_->printCutInfo_) { + edm::LogVerbatim("Tracklet") << name_ << " " << (passes ? "PASSES" : "FAILS"); + } + + return passes; +} diff --git a/L1Trigger/TrackFindingTracklet/src/imath_HLS.cc b/L1Trigger/TrackFindingTracklet/src/imath_HLS.cc new file mode 100644 index 0000000000000..48cd864389a43 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/imath_HLS.cc @@ -0,0 +1,404 @@ +#include "L1Trigger/TrackFindingTracklet/interface/imath.h" + +using namespace trklet; + +void VarInv::writeLUT(std::ofstream& fs, HLS) const { + for (int i = 0; i < Nelements_ - 1; ++i) + fs << "0x" << std::hex << (LUT[i] & ((1 << nbits_) - 1)) << std::dec << ",\n"; + fs << "0x" << std::hex << (LUT[Nelements_ - 1] & ((1 << nbits_) - 1)) << std::dec << "\n"; +} + +void VarBase::print_truncation(std::string& t, const std::string& o1, const int ps, HLS) const { + if (ps > 0) { + t += "const ap_int<" + itos(nbits_ + ps) + "> " + name_ + "_tmp = " + o1 + ";\n"; + t += "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + name_ + "_tmp >> " + itos(ps) + ";\n"; + } else + t += "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + o1 + ";\n"; +} + +// +// print functions +// + +void VarCut::print(std::map >& cut_strings, + const int step, + HLS, + const std::map >* const previous_cut_strings) const { + assert(step > -1); + std::string name = cut_var_->name(); + + const int lower_cut = lower_cut_ / cut_var_->K(); + const int upper_cut = upper_cut_ / cut_var_->K(); + if (!previous_cut_strings || (previous_cut_strings && !previous_cut_strings->count(cut_var_))) { + if (!cut_strings.count(cut_var_)) + cut_strings[cut_var_]; + cut_strings.at(cut_var_).insert(name + " > " + itos(lower_cut) + " && " + name + " < " + itos(upper_cut)); + } +} + +void VarBase::print_cuts(std::map >& cut_strings, + const int step, + HLS, + const std::map >* const previous_cut_strings) const { + if (p1_) + p1_->print_cuts(cut_strings, step, hls, previous_cut_strings); + if (p2_) + p2_->print_cuts(cut_strings, step, hls, previous_cut_strings); + if (p3_) + p3_->print_cuts(cut_strings, step, hls, previous_cut_strings); + + std::string name = name_; + + for (const auto& cut : cuts_) { + const VarCut* const cast_cut = (VarCut*)cut; + const int lower_cut = cast_cut->lower_cut() / K_; + const int upper_cut = cast_cut->upper_cut() / K_; + if (!previous_cut_strings || (previous_cut_strings && !previous_cut_strings->count(this))) { + if (!cut_strings.count(this)) + cut_strings[this]; + cut_strings.at(this).insert(name + " > " + itos(lower_cut) + " && " + name + " < " + itos(upper_cut)); + } + } +} + +void VarAdjustK::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + std::string shift = ""; + if (lr_ > 0) + shift = " >> " + itos(lr_); + else if (lr_ < 0) + shift = " << " + itos(-lr_); + + std::string n1 = p1_->name(); + + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n"; + fs << "const ap_int<" << nbits_ << "> " << name_ << " = " << n1 << shift << ";\n"; +} + +void VarAdjustKR::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + std::string n1 = p1_->name(); + + std::string o1 = n1; + if (lr_ == 1) + o1 = "(" + o1 + "+1)>>1"; + if (lr_ > 1) + o1 = "( (" + o1 + ">>" + itos(lr_ - 1) + ")+1)>>1"; + if (lr_ < 0) + o1 = "ap_int<" + itos(nbits_) + ">(" + o1 + ")<<" + itos(-lr_); + + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n"; + fs << "const ap_int<" << nbits_ << "> " << name_ << " = " << o1 << ";\n"; +} + +void VarDef::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + fs << "// units " << kstring() << "\t" << K_ << "\n"; + fs << "const ap_int<" << nbits_ << "> " << name_ << " = " << name_ << "_wire;\n"; +} + +void VarParam::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n"; + fs << "static const ap_int<" << nbits_ << "> " << name_ << " = " << ival_ << ";\n"; +} + +void VarAdd::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(p2_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string o1 = p1_->name(); + if (shift1 > 0) { + o1 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o1 + ")"; + o1 += "<<" + itos(shift1); + o1 = "(" + o1 + ")"; + } + + std::string o2 = p2_->name(); + if (shift2 > 0) { + o2 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o2 + ")"; + o2 += "<<" + itos(shift2); + o2 = "(" + o2 + ")"; + } + + o1 = o1 + " + " + o2; + + std::string t = ""; + print_truncation(t, o1, ps_, hls); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarSubtract::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(p2_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string o1 = p1_->name(); + if (shift1 > 0) { + o1 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o1 + ")"; + o1 += "<<" + itos(shift1); + o1 = "(" + o1 + ")"; + } + + std::string o2 = p2_->name(); + if (shift2 > 0) { + o2 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o2 + ")"; + o2 += "<<" + itos(shift2); + o2 = "(" + o2 + ")"; + } + + o1 = o1 + " - " + o2; + + std::string t = ""; + print_truncation(t, o1, ps_, hls); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarNounits::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + std::string o1 = "(" + n1 + " * " + itos(cI_) + ")"; + + std::string t = ""; + print_truncation(t, o1, ps_, hls); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarTimesC::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + std::string o1 = "(" + n1 + " * " + itos(cI_) + ")"; + + std::string t = ""; + print_truncation(t, o1, ps_, hls); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarNeg::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + + std::string t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = -" + n1 + ";\n"; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarShiftround::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + std::string o1 = n1; + if (shift_ == 1) + o1 = "(" + o1 + "+1)>>1"; + if (shift_ > 1) + o1 = "( (" + o1 + ">>" + itos(shift_ - 1) + ")+1)>>1"; + if (shift_ < 0) + o1 = "ap_int<" + itos(nbits_) + ">(" + o1 + ")<<" + itos(-shift_); + + std::string t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + o1 + ";\n"; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarShift::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + std::string o1 = n1; + if (shift_ > 0) + o1 = o1 + ">>" + itos(shift_); + if (shift_ < 0) + o1 = "ap_int<" + itos(nbits_) + ">(" + o1 + ")<<" + itos(-shift_); + + std::string t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + o1 + ";\n"; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarMult::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + assert(p1_); + std::string n1 = p1_->name(); + assert(p2_); + std::string n2 = p2_->name(); + std::string o1 = n1 + " * " + n2; + + std::string t = ""; + print_truncation(t, o1, ps_, hls); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarInv::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(p1_); + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + fs << "static const ap_int<" << itos(nbits_) << "> LUT_" << name_ << "[" << Nelements_ << "] = {\n"; + fs << "#include \"LUT_" << name_ << ".h\"\n"; + fs << "};\n"; + + std::string n1 = p1_->name(); + //first calculate address + std::string t1 = "addr_" + name_; + std::string t = "const ap_uint<" + itos(nbaddr_) + "> " + t1 + " = "; + if (shift_ > 0) + t = t + "(" + n1 + ">>" + itos(shift_) + ") & " + itos(mask_); + else + t = t + n1 + " & " + itos(mask_); + fs << t << "; // address for the LUT\n"; + + t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = LUT_" + name_ + "[addr_" + name_ + "];\n"; + fs << t; +} + +void VarFlag::print(std::ofstream& fs, HLS, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + fs << "const ap_int<1> " << name_ << " = ("; + std::map > cut_strings0, cut_strings1; + for (const auto& cut : cuts_) { + if (cut->op() != "cut") + continue; + const VarCut* const cast_cut = (VarCut*)cut; + cast_cut->print(cut_strings0, step_, hls); + } + for (const auto& cut : cuts_) { + if (cut->op() != "cut") + cut->print_cuts(cut_strings1, step_, hls, &cut_strings0); + else { + if (cut->cut_var()->p1()) + cut->cut_var()->p1()->print_cuts(cut_strings1, step_, hls, &cut_strings1); + if (cut->cut_var()->p2()) + cut->cut_var()->p2()->print_cuts(cut_strings1, step_, hls, &cut_strings1); + if (cut->cut_var()->p3()) + cut->cut_var()->p3()->print_cuts(cut_strings1, step_, hls, &cut_strings1); + } + } + + std::string separator = ""; + for (const auto& cut_var : cut_strings0) { + separator += "(("; + for (const auto& cut_string : cut_var.second) { + fs << separator << cut_string; + separator = ") || ("; + } + separator = ")) && "; + } + for (const auto& cut_var : cut_strings1) { + separator += "(("; + for (const auto& cut_string : cut_var.second) { + fs << separator << cut_string; + separator = ") || ("; + } + separator = ")) && "; + } + + fs << ")));"; +} + +void VarBase::print_step(int step, std::ofstream& fs, HLS) { + if (!readytoprint_) + return; + if (step > step_) + return; + if (p1_) + p1_->print_step(step, fs, hls); + if (p2_) + p2_->print_step(step, fs, hls); + if (p3_) + p3_->print_step(step, fs, hls); + if (step == step_) { + print(fs, hls, 0, 0, 0); + readytoprint_ = false; + } +} + +void VarBase::print_all(std::ofstream& fs, HLS) { + for (int i = 0; i <= step_; ++i) { + fs << "//\n// STEP " << i << "\n\n"; + print_step(i, fs, hls); + } +} + +void VarBase::design_print(std::vector v, std::ofstream& fs, HLS) { + //header of the module + + //inputs + std::vector vd; + vd.clear(); + int imax = v.size(); + for (int i = 0; i < imax; ++i) + (v[i])->inputs(&vd); + + //print header + fs << "#include \"ap_int.h\"\n\n"; + fs << "void XXX (\n"; + + imax = vd.size(); + for (int i = 0; i < imax; ++i) + fs << " const ap_int<" << (vd[i])->nbits() << "> " << (vd[i])->name() << "_wire,\n"; + fs << "\n"; + + imax = v.size() - 1; + for (int i = 0; i < imax; ++i) + fs << " ap_int<" << (v[i])->nbits() << "> * const " << (v[i])->name() << "_wire,\n"; + if (imax >= 0) + fs << " ap_int<" << (v[imax])->nbits() << "> * const " << (v[imax])->name() << "_wire\n"; + fs << ")\n{\n"; + fs << "#pragma HLS pipeline II=1\n"; + fs << "#pragma HLS latency max=25\n"; + + //body of the module + imax = v.size(); + for (int i = 0; i < imax; ++i) { + fs << "\n//\n"; + fs << "// calculating " << (v[i])->name() << "\n"; + fs << "//\n"; + (v[i])->print_all(fs, hls); + } + fs << "\n"; + + //trailer + fs << "\n"; + fs << "\n//\n"; + fs << "// wiring the outputs \n"; + fs << "//\n"; + for (int i = 0; i < imax; ++i) { + std::string n = v[i]->name() + "_wire"; + fs << "*" << n << " = " << (v[i])->name() << ";\n"; + } + + fs << "}\n"; +} diff --git a/L1Trigger/TrackFindingTracklet/src/imath_Verilog.cc b/L1Trigger/TrackFindingTracklet/src/imath_Verilog.cc new file mode 100644 index 0000000000000..e2e4d77463d4e --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/imath_Verilog.cc @@ -0,0 +1,534 @@ +#include "L1Trigger/TrackFindingTracklet/interface/imath.h" + +using namespace trklet; + +void VarInv::writeLUT(std::ofstream& fs, Verilog) const { + for (int i = 0; i < Nelements_; ++i) + fs << std::hex << (LUT[i] & ((1 << nbits_) - 1)) << std::dec << "\n"; +} + +void VarBase::print_truncation(std::string& t, const std::string& o1, const int ps, Verilog) const { + if (ps > 0) { + t += "wire signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "reg signed [" + itos(nbits_ + ps - 1) + ":0]" + name_ + "_tmp;\n"; + t += "always @(posedge clk) " + name_ + "_tmp <= " + o1 + ";\n"; + t += "assign " + name_ + " = " + name_ + "_tmp[" + itos(nbits_ + ps - 1) + ":" + itos(ps) + "];\n"; + } else { + t += "reg signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "always @(posedge clk) " + name_ + " <= " + o1 + ";\n"; + } +} + +// +// print functions +// + +void VarCut::print(std::map >& cut_strings, + const int step, + Verilog, + const std::map >* const previous_cut_strings) const { + int l = step - cut_var_->latency() - cut_var_->step(); + std::string name = cut_var_->name(); + if (l > 0) + name += "_delay" + itos(l); + + const int lower_cut = lower_cut_ / cut_var_->K(); + const int upper_cut = upper_cut_ / cut_var_->K(); + if (!previous_cut_strings || (previous_cut_strings && !previous_cut_strings->count(cut_var_))) { + if (!cut_strings.count(cut_var_)) + cut_strings[cut_var_]; + cut_strings.at(cut_var_).insert(name + " > " + itos(lower_cut) + " && " + name + " < " + itos(upper_cut)); + } +} + +void VarBase::print_cuts(std::map >& cut_strings, + const int step, + Verilog, + const std::map >* const previous_cut_strings) const { + if (p1_) + p1_->print_cuts(cut_strings, step, verilog, previous_cut_strings); + if (p2_) + p2_->print_cuts(cut_strings, step, verilog, previous_cut_strings); + if (p3_) + p3_->print_cuts(cut_strings, step, verilog, previous_cut_strings); + + int l = step - latency_ - step_; + std::string name = name_; + if (l > 0) + name += "_delay" + itos(l); + + for (const auto& cut : cuts_) { + const VarCut* const cast_cut = (VarCut*)cut; + const int lower_cut = cast_cut->lower_cut() / K_; + const int upper_cut = cast_cut->upper_cut() / K_; + if (!previous_cut_strings || (previous_cut_strings && !previous_cut_strings->count(this))) { + if (!cut_strings.count(this)) + cut_strings[this]; + cut_strings.at(this).insert(name + " > " + itos(lower_cut) + " && " + name + " < " + itos(upper_cut)); + } + } +} + +void VarAdjustK::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + + std::string shift = ""; + if (lr_ > 0) + shift = " >>> " + itos(lr_); + else if (lr_ < 0) + shift = " << " + itos(-lr_); + + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n"; + std::string t = "wire signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "assign " + name_ + " = " + n1 + shift; + fs << t << "; \n"; +} + +void VarAdjustKR::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + + std::string o1 = n1; + if (lr_ == 1) + o1 = "(" + o1 + "+1)>>>1"; + if (lr_ > 1) + o1 = "( (" + o1 + ">>>" + itos(lr_ - 1) + ")+1)>>>1"; + if (lr_ < 0) + o1 = o1 + "<<" + itos(-lr_); + + std::string t = "reg signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "always @(posedge clk) " + name_ + " <= " + o1; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarDef::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + std::string t = "reg signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t = t + "always @(posedge clk) " + name_ + " <= " + name_ + "_wire;\n"; + fs << "// units " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarParam::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + std::string t = "parameter " + name_ + " = "; + if (ival_ < 0) + t = t + "- " + itos(nbits_) + "\'sd" + itos(-ival_); + else + t = t + itos(nbits_) + "\'sd" + itos(ival_); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarAdd::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(p2_); + assert(l3 == 0); + std::string o1 = p1_->name(); + if (l1 > 0) + o1 += "_delay" + itos(l1); + if (shift1 > 0) { + o1 += "<<" + itos(shift1); + o1 = "(" + o1 + ")"; + } + + std::string o2 = p2_->name(); + if (l2 > 0) + o2 += "_delay" + itos(l2); + if (shift2 > 0) { + o2 += "<<" + itos(shift2); + o2 = "(" + o2 + ")"; + } + + o1 = o1 + " + " + o2; + + std::string t = ""; + print_truncation(t, o1, ps_, verilog); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarSubtract::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(p2_); + assert(l3 == 0); + std::string o1 = p1_->name(); + if (l1 > 0) + o1 += "_delay" + itos(l1); + if (shift1 > 0) { + o1 += "<<" + itos(shift1); + o1 = "(" + o1 + ")"; + } + + std::string o2 = p2_->name(); + if (l2 > 0) + o2 += "_delay" + itos(l2); + if (shift2 > 0) { + o2 += "<<" + itos(shift2); + o2 = "(" + o2 + ")"; + } + + o1 = o1 + " - " + o2; + + std::string t = ""; + print_truncation(t, o1, ps_, verilog); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarNounits::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + std::string o1 = "(" + n1 + " * " + itos(cI_) + ")"; + + std::string t = ""; + print_truncation(t, o1, ps_, verilog); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarTimesC::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + std::string o1 = "(" + n1 + " * " + itos(cI_) + ")"; + + std::string t = ""; + print_truncation(t, o1, ps_, verilog); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarNeg::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + + std::string t = "reg signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "always @(posedge clk) " + name_ + " <= - " + n1; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarShiftround::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + std::string o1 = n1; + if (shift_ == 1) + o1 = "(" + o1 + "+1)>>>1"; + if (shift_ > 1) + o1 = "( (" + o1 + ">>>" + itos(shift_ - 1) + ")+1)>>>1"; + if (shift_ < 0) + o1 = o1 + "<<" + itos(-shift_); + + std::string t = "reg signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "always @(posedge clk) " + name_ + " <= " + o1; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarShift::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + std::string o1 = n1; + if (shift_ > 0) + o1 = o1 + ">>>" + itos(shift_); + if (shift_ < 0) + o1 = o1 + "<<" + itos(-shift_); + + std::string t = "wire signed [" + itos(nbits_ - 1) + ":0]" + name_ + ";\n"; + t += "assign " + name_ + " = " + o1; + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n"; +} + +void VarMult::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(l3 == 0); + assert(p1_); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + assert(p2_); + std::string n2 = p2_->name(); + if (l2 > 0) + n2 = n2 + "_delay" + itos(l2); + std::string o1 = n1 + " * " + n2; + + std::string t = ""; + print_truncation(t, o1, ps_, verilog); + fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t; +} + +void VarInv::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(l2 == 0); + assert(l3 == 0); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + //first calculate address + std::string t1 = "addr_" + name_; + std::string t = "wire [" + itos(nbaddr_ - 1) + ":0] " + t1 + ";\n"; + t = t + "assign " + t1 + " = "; + if (shift_ > 0) + t = t + "(" + n1 + ">>>" + itos(shift_) + ") & " + itos(mask_); + else + t = t + n1 + " & " + itos(mask_); + fs << t << "; // address for the LUT\n"; + + t = "wire signed [" + itos(nbits_ - 1) + ":0] " + name_ + ";\n"; + fs << t; + + std::string t2 = "LUT_" + name_; + + fs << "Memory #( \n"; + fs << " .RAM_WIDTH(" << nbits_ << "), // Specify RAM data width \n"; + fs << " .RAM_DEPTH(" << Nelements_ << "), // Specify RAM depth (number of entries) \n"; + fs << " .RAM_PERFORMANCE(\"HIGH_PERFORMANCE\"), // \"HIGH_PERFORMANCE\" = 2 clks latency \n"; + fs << " .INIT_FILE() \n"; + fs << " ) " << t2 << " ( \n"; + fs << " .addra(" << itos(nbaddr_) << "\'b0), // Write address bus, width determined from RAM_DEPTH \n"; + fs << " .addrb(" << t1 << " ), // Read address bus, width determined from RAM_DEPTH \n"; + fs << " .dina(" << itos(nbits_) << "\'b0), // RAM input data, width determined from RAM_WIDTH \n"; + fs << " .clka(clk), // Write clock \n"; + fs << " .clkb(clk), // Read clock \n"; + fs << " .wea(1\'b0), // Write enable \n"; + fs << " .enb(1\'b1), // Read Enable, for additional power savings, disable when not in use \n"; + fs << " .rstb(reset), // Output reset (does not affect memory contents) \n"; + fs << " .regceb(1\'b1), // Output register enable \n"; + fs << " .doutb(" << name_ << ") // RAM output data, \n"; + fs << " ); \n"; +} + +void VarDSPPostadd::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(p1_); + assert(p2_); + assert(p3_); + std::string n1 = p1_->name(); + if (l1 > 0) + n1 = n1 + "_delay" + itos(l1); + std::string n2 = p2_->name(); + if (l2 > 0) + n2 = n2 + "_delay" + itos(l2); + std::string n3 = p3_->name(); + if (l3 > 0) + n3 = n3 + "_delay" + itos(l3); + + if (shift3_ > 0) + n3 = n3 + "<<" + itos(shift3_); + if (shift3_ < 0) + n3 = n3 + ">>>" + itos(-shift3_); + + std::string n4 = ""; + if (ps_ > 0) + n4 = ">>>" + itos(ps_); + + fs << name_ + " = DSP_postadd(" + n1 + ", " + n2 + ", " + n3 + ")" + n4 + ";"; +} + +void VarFlag::print(std::ofstream& fs, Verilog, int l1, int l2, int l3) { + assert(l1 == 0); + assert(l2 == 0); + assert(l3 == 0); + + fs << "wire " << name_ << ";" << std::endl; + fs << "assign " << name_ << " = ("; + std::map > cut_strings0, cut_strings1; + for (const auto& cut : cuts_) { + if (cut->op() != "cut") + continue; + const VarCut* const cast_cut = (VarCut*)cut; + cast_cut->print(cut_strings0, step_, verilog); + } + for (const auto& cut : cuts_) { + if (cut->op() != "cut") + cut->print_cuts(cut_strings1, step_, verilog, &cut_strings0); + else { + if (cut->cut_var()->p1()) + cut->cut_var()->p1()->print_cuts(cut_strings1, step_, verilog, &cut_strings1); + if (cut->cut_var()->p2()) + cut->cut_var()->p2()->print_cuts(cut_strings1, step_, verilog, &cut_strings1); + if (cut->cut_var()->p3()) + cut->cut_var()->p3()->print_cuts(cut_strings1, step_, verilog, &cut_strings1); + } + } + + std::string separator = ""; + for (const auto& cut_var : cut_strings0) { + separator += "(("; + for (const auto& cut_string : cut_var.second) { + fs << separator << cut_string; + separator = ") || ("; + } + separator = ")) && "; + } + for (const auto& cut_var : cut_strings1) { + separator += "(("; + for (const auto& cut_string : cut_var.second) { + fs << separator << cut_string; + separator = ") || ("; + } + separator = ")) && "; + } + + fs << ")));"; +} + +void VarBase::print_step(int step, std::ofstream& fs, Verilog) { + if (!readytoprint_) + return; + if (step > step_) + return; + int l1 = 0; + int l2 = 0; + int l3 = 0; + if (p1_) { + p1_->print_step(step, fs, verilog); + l1 = step_ - p1_->latency() - p1_->step(); + } + if (p2_) { + p2_->print_step(step, fs, verilog); + l2 = step_ - p2_->latency() - p2_->step(); + } + if (p3_) { + p3_->print_step(step, fs, verilog); + l3 = step_ - p3_->latency() - p3_->step(); + } + if (step == step_) { + if (l1 < 0 || l2 < 0 || l3 < 0 || (l1 > 0 && l2 > 0 && l3 > 0)) { + char slog[100]; + sprintf(slog, "%s::print_step(%i): something wrong with latencies! %i %i %i\n", name_.c_str(), step, l1, l2, l3); + edm::LogVerbatim("Tracklet") << slog; + dump_msg(); + assert(0); + } + if (l1 > 0) { + if (p1_->op() != "const") + fs << pipe_delay(p1_, p1_->nbits(), l1); + else + l1 = 0; + } + if (l2 > 0) { + if (p2_->op() != "const") + fs << pipe_delay(p2_, p2_->nbits(), l2); + else + l2 = 0; + } + if (l3 > 0) { + if (p3_->op() != "const") + fs << pipe_delay(p3_, p3_->nbits(), l3); + else + l3 = 0; + } + + if (op_ == "flag") { + for (const auto& cut : cuts_) + fs << cut->cut_var()->pipe_delays(step_); + } + + print(fs, verilog, l1, l2, l3); + readytoprint_ = false; + } +} + +void VarBase::print_all(std::ofstream& fs, Verilog) { + for (int i = 0; i <= step_; ++i) { + fs << "//\n// STEP " << i << "\n\n"; + print_step(i, fs, verilog); + } +} + +void VarBase::design_print(std::vector v, std::ofstream& fs, Verilog) { + //step at which all the outputs should be valid + int maxstep = 0; + + //header of the module + + //inputs + std::vector vd; + vd.clear(); + int imax = v.size(); + for (int i = 0; i < imax; ++i) { + (v[i])->inputs(&vd); + int step = v[i]->step() + v[i]->latency(); + if (step > maxstep) + maxstep = step; + } + + //print header + fs << "module \n"; + fs << "(\n"; + fs << " input clk,\n"; + fs << " input reset,\n\n"; + + imax = vd.size(); + for (int i = 0; i < imax; ++i) + fs << " input [" << (vd[i])->nbits() - 1 << ":0] " << (vd[i])->name() << "_wire,\n"; + fs << "\n"; + + imax = v.size() - 1; + for (int i = 0; i < imax; ++i) + if (v[i]->nbits() > 1) + fs << " output [" << (v[i])->nbits() - 1 << ":0] " << (v[i])->name() << "_wire,\n"; + else + fs << " output " << (v[i])->name() << "_wire,\n"; + if (imax >= 0) { + if (v[imax]->nbits() > 1) + fs << " output [" << (v[imax])->nbits() - 1 << ":0] " << (v[imax])->name() << "_wire\n"; + else + fs << " output " << (v[imax])->name() << "_wire\n"; + } + fs << ");\n\n"; + + //body of the module + imax = v.size(); + for (int i = 0; i < imax; ++i) { + fs << "\n//\n"; + fs << "// calculating " << (v[i])->name() << "\n"; + fs << "//\n"; + (v[i])->print_all(fs, verilog); + } + fs << "\n"; + + //trailer + fs << "\n"; + fs << "\n//\n"; + fs << "// wiring the outputs \n"; + fs << "// latency = " << maxstep << "\n"; + fs << "//\n"; + for (int i = 0; i < imax; ++i) { + std::string n = v[i]->name() + "_wire"; + int delay = maxstep - v[i]->step() - v[i]->latency(); + if (delay == 0) + fs << "assign " << n << " = " << (v[i])->name() << ";\n"; + else + fs << pipe_delay_wire(v[i], n, v[i]->nbits(), delay); + } + + fs << "endmodule\n"; +} diff --git a/L1Trigger/TrackFindingTracklet/src/imath_calculate.cc b/L1Trigger/TrackFindingTracklet/src/imath_calculate.cc new file mode 100644 index 0000000000000..0aa2f7b77c045 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/src/imath_calculate.cc @@ -0,0 +1,192 @@ +#include "L1Trigger/TrackFindingTracklet/interface/imath.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace trklet; + +bool VarBase::calculate(int debug_level) { + bool ok1 = true; + bool ok2 = true; + bool ok3 = true; + + if (p1_) + ok1 = p1_->calculate(debug_level); + if (p2_) + ok2 = p2_->calculate(debug_level); + if (p3_) + ok3 = p3_->calculate(debug_level); + + long int ival_prev = ival_; + local_calculate(); + + bool all_ok = ok1 && ok2 && ok3 && debug_level; + + if (fval_ > maxval_) + maxval_ = fval_; + if (fval_ < minval_) + minval_ = fval_; +#ifdef IMATH_ROOT + if (globals_->use_root) { + if (h_ == 0) { + globals_->h_file_->cd(); + std::string hname = "h_" + name_; + h_ = (TH2F *)globals_->h_file_->Get(hname.c_str()); + if (h_ == 0) { + h_precision_ = 0.5 * h_nbins_ * K_; + std::string st = name_ + ";fval;fval-ival*K"; + h_ = new TH2F(hname.c_str(), name_.c_str(), h_nbins_, -range(), range(), h_nbins_, -h_precision_, h_precision_); + if (debug_level == 3) + edm::LogVerbatim("Tracklet") << " booking histogram " << hname; + } + } + if (ival_ != ival_prev || op_ == "def" || op_ == "const") + h_->Fill(fval_, K_ * ival_ - fval_); + } +#endif + + bool todump = false; + int nmax = sizeof(long int) * 8; + int ns = nmax - nbits_; + long int itest = ival_; + itest = itest << ns; + itest = itest >> ns; + if (itest != ival_) { + if (debug_level == 3 || (ival_ != ival_prev && all_ok)) { + edm::LogVerbatim("Tracklet") << "imath: truncated value mismatch!! " << ival_ << " != " << itest; + todump = true; + } + all_ok = false; + } + + val_ = ival_ * K_; + float ftest = val_; + float tolerance = 0.1 * std::abs(fval_); + if (tolerance < 2 * K_) + tolerance = 2 * K_; + if (std::abs(ftest - fval_) > tolerance) { + if (debug_level == 3 || (ival_ != ival_prev && (all_ok && (op_ != "inv" || debug_level >= 2)))) { + edm::LogVerbatim("Tracklet") << "imath: **GROSS** value mismatch!! " << fval_ << " != " << ftest; + if (op_ == "inv") + edm::LogVerbatim("Tracklet") << p1_->dump() << "\n-----------------------------------"; + todump = true; + } + all_ok = false; + } + + if (todump) + edm::LogVerbatim("Tracklet") << dump(); + + return all_ok; +} + +void VarFlag::calculate_step() { + int max_step = 0; + for (const auto &cut : cuts_) { + if (!cut->cut_var()) + continue; + if (cut->cut_var()->latency() + cut->cut_var()->step() > max_step) + max_step = cut->cut_var()->latency() + cut->cut_var()->step(); + } + step_ = max_step; +} + +// +// local calculations +// + +void VarAdjustK::local_calculate() { + fval_ = p1_->fval(); + ival_ = p1_->ival(); + if (lr_ > 0) + ival_ = ival_ >> lr_; + else if (lr_ < 0) + ival_ = ival_ << (-lr_); +} + +void VarAdjustKR::local_calculate() { + fval_ = p1_->fval(); + ival_ = p1_->ival(); + if (lr_ > 0) + ival_ = ((ival_ >> (lr_ - 1)) + 1) >> 1; //rounding + else if (lr_ < 0) + ival_ = ival_ << (-lr_); +} + +void VarAdd::local_calculate() { + fval_ = p1_->fval() + p2_->fval(); + long int i1 = p1_->ival(); + long int i2 = p2_->ival(); + if (shift1 > 0) + i1 = i1 << shift1; + if (shift2 > 0) + i2 = i2 << shift2; + ival_ = i1 + i2; + if (ps_ > 0) + ival_ = ival_ >> ps_; +} + +void VarSubtract::local_calculate() { + fval_ = p1_->fval() - p2_->fval(); + long int i1 = p1_->ival(); + long int i2 = p2_->ival(); + if (shift1 > 0) + i1 = i1 << shift1; + if (shift2 > 0) + i2 = i2 << shift2; + ival_ = i1 - i2; + if (ps_ > 0) + ival_ = ival_ >> ps_; +} + +void VarNounits::local_calculate() { + fval_ = p1_->fval(); + ival_ = (p1_->ival() * cI_) >> ps_; +} + +void VarTimesC::local_calculate() { + fval_ = p1_->fval() * cF_; + ival_ = (p1_->ival() * cI_) >> ps_; +} + +void VarNeg::local_calculate() { + fval_ = -p1_->fval(); + ival_ = -p1_->ival(); +} + +void VarShift::local_calculate() { + fval_ = p1_->fval() * pow(2, -shift_); + ival_ = p1_->ival(); + if (shift_ > 0) + ival_ = ival_ >> shift_; + if (shift_ < 0) + ival_ = ival_ << (-shift_); +} + +void VarShiftround::local_calculate() { + fval_ = p1_->fval() * pow(2, -shift_); + ival_ = p1_->ival(); + if (shift_ > 0) + ival_ = ((ival_ >> (shift_ - 1)) + 1) >> 1; + if (shift_ < 0) + ival_ = ival_ << (-shift_); +} + +void VarMult::local_calculate() { + fval_ = p1_->fval() * p2_->fval(); + ival_ = (p1_->ival() * p2_->ival()) >> ps_; +} + +void VarDSPPostadd::local_calculate() { + fval_ = p1_->fval() * p2_->fval() + p3_->fval(); + ival_ = p3_->ival(); + if (shift3_ > 0) + ival_ = ival_ << shift3_; + if (shift3_ < 0) + ival_ = ival_ >> (-shift3_); + ival_ += p1_->ival() * p2_->ival(); + ival_ = ival_ >> ps_; +} + +void VarInv::local_calculate() { + fval_ = 1. / (offset_ + p1_->fval()); + ival_ = LUT[ival_to_addr(p1_->ival())]; +} diff --git a/L1Trigger/TrackFindingTracklet/test/BuildFile.xml b/L1Trigger/TrackFindingTracklet/test/BuildFile.xml new file mode 100644 index 0000000000000..aee5c63f06ded --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/BuildFile.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py b/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py new file mode 100644 index 0000000000000..7ef38f91d0194 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/HybridTracks_cfg.py @@ -0,0 +1,62 @@ +# define basic process +import FWCore.ParameterSet.Config as cms +import FWCore.Utilities.FileUtils as FileUtils +process = cms.Process("L1HybridTrack") + +# ---------------------------------------------------------------------------------- +# import standard configurations +process.load('Configuration.StandardSequences.Services_cff') +process.load('FWCore.MessageService.MessageLogger_cfi') +process.load('Configuration.EventContent.EventContent_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_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', '') + + +# ---------------------------------------------------------------------------------- +# input +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) +Source_Files = cms.untracked.vstring( + "/store/relval/CMSSW_11_0_0/RelValSingleMuFlatPt2To100/GEN-SIM-DIGI-RAW/110X_mcRun4_realistic_v2_2026D49noPU-v1/20000/F5E783E4-CF4A-4745-B4ED-6F1AA5E5C16F.root" +) +process.source = cms.Source("PoolSource", fileNames = Source_Files) + + +# ---------------------------------------------------------------------------------- +# L1 tracking => hybrid emulation +process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") + +# prompt tracking only +process.TTTracksEmulation = cms.Path(process.L1HybridTracks) +process.TTTracksEmulationWithTruth = cms.Path(process.L1HybridTracksWithAssociators) + +# extended tracking only +#process.TTTracksEmulation = cms.Path(process.L1ExtendedHybridTracks) +#process.TTTracksEmulationWithTruth = cms.Path(process.L1ExtendedHybridTracksWithAssociators) + +# both prompt+extended hybrid tracking +#process.TTTracksEmulation = cms.Path(process.L1PromptExtendedHybridTracks) +#process.TTTracksEmulationWithTruth = cms.Path(process.L1PromptExtendedHybridTracksWithAssociators) + + +# ---------------------------------------------------------------------------------- +# output module +process.out = cms.OutputModule( "PoolOutputModule", + fileName = cms.untracked.string("L1Tracks.root"), + fastCloning = cms.untracked.bool( False ), + outputCommands = cms.untracked.vstring('drop *', + 'keep *_TTTrack*_Level1TTTracks_*', +) +) +process.FEVToutput_step = cms.EndPath(process.out) + + +#process.schedule = cms.Schedule(process.TTTracksEmulation,process.FEVToutput_step) +process.schedule = cms.Schedule(process.TTTracksEmulationWithTruth,process.FEVToutput_step) + diff --git a/L1Trigger/TrackFindingTracklet/test/INTERNAL/HistImp.cc b/L1Trigger/TrackFindingTracklet/test/INTERNAL/HistImp.cc new file mode 100644 index 0000000000000..c2ddd60745a4f --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/INTERNAL/HistImp.cc @@ -0,0 +1,280 @@ +#include "L1Trigger/TrackFindingTracklet/interface/HistImp.h" +#include "L1Trigger/TrackFindingTracklet/interface/slhcevent.h" +#include "L1Trigger/TrackFindingTracklet/interface/Globals.h" + +using namespace std; +using namespace trklet; + +HistImp::HistImp() { + h_file_ = 0; + h_layerresid_phi_L3_L1L2_ = 0; + h_layerresid_phi_L3_L1L2_match_ = 0; + h_layerresid_phif_L3_L1L2_ = 0; + h_layerresid_phif_L3_L1L2_match_ = 0; + h_layerresid_z_L3_L1L2_ = 0; + h_layerresid_z_L3_L1L2_match_ = 0; + h_layerresid_zf_L3_L1L2_ = 0; + h_layerresid_zf_L3_L1L2_match_ = 0; + + h_diskresid_phi_D1_L1L2_ = 0; + h_diskresid_phi_D1_L1L2_match_ = 0; + h_diskresid_phif_D1_L1L2_ = 0; + h_diskresid_phif_D1_L1L2_match_ = 0; + h_diskresid_r_D1_L1L2_ = 0; + h_diskresid_r_D1_L1L2_match_ = 0; + h_diskresid_rf_D1_L1L2_ = 0; + h_diskresid_rf_D1_L1L2_match_ = 0; + + h_rinv_L1L2_ = 0; + h_irinv_L1L2_ = 0; + h_rinvres_L1L2_ = 0; + h_irinvres_L1L2_ = 0; +} + +void HistImp::open() { h_file_ = new TFile("fpgahist.root", "RECREATE"); } + +void HistImp::close() { + if (h_file_) { + h_file_->Write(); + h_file_->Close(); + h_file_ = 0; + } +} + +void HistImp::bookLayerResidual() { + TH1::AddDirectory(kTRUE); + + assert(h_file_ != 0); + h_file_->cd(); + + h_layerresid_phi_L3_L1L2_ = new TH1F("L3 phiresid L1L2", "L3 phiresid L1L2", 100, -0.5, 0.5); + h_layerresid_phi_L3_L1L2_match_ = new TH1F("L3 phiresid L1L2 Match", "L3 phiresid L1L2 Match", 100, -0.5, 0.5); + h_layerresid_phif_L3_L1L2_ = new TH1F("L3 phiresid float L1L2", "L3 phiresid float L1L2", 100, -0.5, 0.5); + h_layerresid_phif_L3_L1L2_match_ = + new TH1F("L3 phiresid float L1L2 Match", "L3 phiresid float L1L2 Match", 100, -0.5, 0.5); + + h_layerresid_z_L3_L1L2_ = new TH1F("L3 zresid L1L2", "L3 zresid L1L2", 100, -5.0, 5.0); + h_layerresid_z_L3_L1L2_match_ = new TH1F("L3 zresid L1L2 Match", "L3 zresid L1L2 Match", 100, -5.0, 5.0); + h_layerresid_zf_L3_L1L2_ = new TH1F("L3 zresid float L1L2", "L3 zresid float L1L2", 100, -5.0, 5.0); + h_layerresid_zf_L3_L1L2_match_ = new TH1F("L3 zresid float L1L2 Match", "L3 zresid float L1L2 Match", 100, -5.0, 5.0); +} + +void HistImp::bookDiskResidual() { + TH1::AddDirectory(kTRUE); + + assert(h_file_ != 0); + h_file_->cd(); + + h_diskresid_phi_D1_L1L2_ = new TH1F("D1 phiresid L1L2", "D1 phiresid L1L2", 100, -0.5, 0.5); + h_diskresid_phi_D1_L1L2_match_ = new TH1F("D1 phiresid L1L2 Match", "D1 phiresid L1L2 Match", 100, -0.5, 0.5); + h_diskresid_phif_D1_L1L2_ = new TH1F("D1 phiresid float L1L2", "D1 phiresid float L1L2", 100, -0.5, 0.5); + h_diskresid_phif_D1_L1L2_match_ = + new TH1F("D1 phiresid float L1L2 Match", "D1 phiresid float L1L2 Match", 100, -0.5, 0.5); + + h_diskresid_r_D1_L1L2_ = new TH1F("D1 rresid L1L2", "D1 rresid L1L2", 100, -5.0, 5.0); + h_diskresid_r_D1_L1L2_match_ = new TH1F("D1 rresid L1L2 Match", "D1 rresid L1L2 Match", 100, -5.0, 5.0); + h_diskresid_rf_D1_L1L2_ = new TH1F("D1 rresid float L1L2", "D1 rresid float L1L2", 100, -5.0, 5.0); + h_diskresid_rf_D1_L1L2_match_ = new TH1F("D1 rresid float L1L2 Match", "D1 rresid float L1L2 Match", 100, -5.0, 5.0); +} + +void HistImp::bookTrackletParams() { + TH1::AddDirectory(kTRUE); + + assert(h_file_ != 0); + h_file_->cd(); + + h_rinv_L1L2_ = new TH1F("Tracklet rinv in L1L2", "Tracklet rinv in L1L2", 140, -0.007, 0.007); + h_irinv_L1L2_ = new TH1F("Tracklet irinv in L1L2", "Tracklet irinv in L1L2", 140, -0.007, 0.007); + h_rinv_matched_L1L2_ = new TH1F("Tracklet rinv in matched L1L2", "Tracklet rinv in matched L1L2", 140, -0.007, 0.007); + h_irinv_matched_L1L2_ = + new TH1F("Tracklet irinv in matched L1L2", "Tracklet irinv in matched L1L2", 140, -0.007, 0.007); + h_rinvres_L1L2_ = new TH1F("Tracklet rinv res in L1L2", "Tracklet rinv res in L1L2", 100, -0.0005, 0.0005); + h_irinvres_L1L2_ = new TH1F("Tracklet irinv res in L1L2", "Tracklet irinv res in L1L2", 100, -0.0005, 0.0005); + + h_phi0_L1L2_ = new TH1F("Tracklet phi0 in L1L2", "Tracklet phi0 in L1L2", 100, 0.0, 1.0); + h_iphi0_L1L2_ = new TH1F("Tracklet iphi0 in L1L2", "Tracklet iphi0 in L1L2", 100, 0.0, 1.0); + h_phi0_matched_L1L2_ = new TH1F("Tracklet phi0 in matched L1L2", "Tracklet phi0 in matched L1L2", 100, 0.0, 1.0); + h_iphi0_matched_L1L2_ = new TH1F("Tracklet iphi0 in matched L1L2", "Tracklet iphi0 in matched L1L2", 100, 0.0, 1.0); + h_phi0global_L1L2_ = new TH1F("Tracklet phi0 global in L1L2", "Tracklet phi0 global in L1L2", 99, -M_PI, M_PI); + h_iphi0global_L1L2_ = new TH1F("Tracklet iphi0 global in L1L2", "Tracklet iphi0 global in L1L2", 99, -M_PI, M_PI); + h_phi0global_matched_L1L2_ = + new TH1F("Tracklet phi0 global in matched L1L2", "Tracklet phi0 global in matched L1L2", 99, -M_PI, M_PI); + h_iphi0global_matched_L1L2_ = + new TH1F("Tracklet iphi0 global in matched L1L2", "Tracklet iphi0 global in matched L1L2", 99, -M_PI, M_PI); + h_phi0res_L1L2_ = new TH1F("Tracklet phi0 res in L1L2", "Tracklet phi0 res in L1L2", 100, -0.5, 0.5); + h_iphi0res_L1L2_ = new TH1F("Tracklet iphi0 res in L1L2", "Tracklet iphi0 res in L1L2", 100, -0.5, 0.5); + + h_eta_L1L2_ = new TH1F("Tracklet eta in L1L2", "Tracklet eta in L1L2", 100, -2.5, 2.5); + h_ieta_L1L2_ = new TH1F("Tracklet ieta in L1L2", "Tracklet ieta in L1L2", 100, -2.5, 2.5); + h_eta_matched_L1L2_ = new TH1F("Tracklet eta in matched L1L2", "Tracklet eta in matched L1L2", 100, -2.5, 2.5); + h_ieta_matched_L1L2_ = new TH1F("Tracklet ieta in matched L1L2", "Tracklet ieta in matched L1L2", 100, -2.5, 2.5); + h_etares_L1L2_ = new TH1F("Tracklet eta res in L1L2", "Tracklet eta res in L1L2", 100, -0.05, 0.05); + h_ietares_L1L2_ = new TH1F("Tracklet ieta res in L1L2", "Tracklet ieta res in L1L2", 100, -0.05, 0.05); + + h_z0_L1L2_ = new TH1F("Tracklet z0 in L1L2", "Tracklet z0 in L1L2", 100, -25.0, 25.0); + h_iz0_L1L2_ = new TH1F("Tracklet iz0 in L1L2", "Tracklet iz0 in L1L2", 100, -25.0, 25.0); + h_z0_matched_L1L2_ = new TH1F("Tracklet z0 in matched L1L2", "Tracklet z0 in matched L1L2", 100, -25.0, 25.0); + h_iz0_matched_L1L2_ = new TH1F("Tracklet iz0 in matched L1L2", "Tracklet iz0 in matched L1L2", 100, -25.0, 25.0); + h_z0res_L1L2_ = new TH1F("Tracklet z0 res in L1L2", "Tracklet z0 res in L1L2", 100, -5.0, 5.0); + h_iz0res_L1L2_ = new TH1F("Tracklet iz0 res in L1L2", "Tracklet iz0 res in L1L2", 100, -5.0, 5.0); +} + +void HistImp::fillTrackletParams(const Settings* settings, + Globals* globals, + int seedIndex, + int iSector, + double rinv, + double irinv, + double phi0, + double iphi0, + double eta, + double ieta, + double z0, + double iz0, + int tp) { + if (seedIndex == 0) { + h_rinv_L1L2_->Fill(rinv); + h_irinv_L1L2_->Fill(irinv); + h_phi0_L1L2_->Fill(phi0); + h_iphi0_L1L2_->Fill(iphi0); + double phi0global = phi0 + iSector * 2 * M_PI / N_SECTOR; + if (phi0global > M_PI) + phi0global -= 2 * M_PI; + if (phi0global < -M_PI) + phi0global += 2 * M_PI; + double iphi0global = iphi0 + iSector * 2 * M_PI / N_SECTOR; + if (iphi0global > M_PI) + iphi0global -= 2 * M_PI; + if (iphi0global < -M_PI) + iphi0global += 2 * M_PI; + h_phi0global_L1L2_->Fill(phi0global); + h_iphi0global_L1L2_->Fill(iphi0global); + h_eta_L1L2_->Fill(eta); + h_ieta_L1L2_->Fill(ieta); + h_z0_L1L2_->Fill(z0); + h_iz0_L1L2_->Fill(iz0); + if (tp != 0) { + h_rinv_matched_L1L2_->Fill(rinv); + h_irinv_matched_L1L2_->Fill(irinv); + h_phi0_matched_L1L2_->Fill(phi0); + h_iphi0_matched_L1L2_->Fill(iphi0); + h_phi0global_matched_L1L2_->Fill(phi0global); + h_iphi0global_matched_L1L2_->Fill(iphi0global); + h_eta_matched_L1L2_->Fill(eta); + h_ieta_matched_L1L2_->Fill(ieta); + h_z0_matched_L1L2_->Fill(z0); + h_iz0_matched_L1L2_->Fill(iz0); + L1SimTrack simtrk = globals->event()->simtrack(tp - 1); + h_rinvres_L1L2_->Fill(rinv - (simtrk.charge() * 0.01 * 0.3 * 3.8 / simtrk.pt())); + h_irinvres_L1L2_->Fill(irinv - (simtrk.charge() * 0.01 * 0.3 * 3.8 / simtrk.pt())); + double simtrkphi0 = simtrk.phi(); + double dphiHG = 0.5 * settings->dphisectorHG() - M_PI / N_SECTOR; + double phimin = +dphiHG - M_PI / N_SECTOR; + double phioffset = phimin; + while (iphi0 - phioffset - simtrkphi0 > M_PI / N_SECTOR) + simtrkphi0 += 2 * M_PI / N_SECTOR; + while (iphi0 - phioffset - simtrkphi0 < -M_PI / N_SECTOR) + simtrkphi0 -= 2 * M_PI / N_SECTOR; + h_phi0res_L1L2_->Fill(phi0 - phioffset - simtrkphi0); + h_iphi0res_L1L2_->Fill(iphi0 - phioffset - simtrkphi0); + h_etares_L1L2_->Fill(eta - simtrk.eta()); + h_ietares_L1L2_->Fill(ieta - simtrk.eta()); + h_z0res_L1L2_->Fill(z0 - simtrk.vz()); + h_iz0res_L1L2_->Fill(iz0 - simtrk.vz()); + } + } + + return; +} + +void HistImp::FillLayerResidual( + int layer, int seed, double phiresid, double iphiresid, double zresid, double izresid, bool match) { + if (layer == 3) { + if (seed == 0) { + h_layerresid_phi_L3_L1L2_->Fill(iphiresid); + h_layerresid_phif_L3_L1L2_->Fill(phiresid); + h_layerresid_z_L3_L1L2_->Fill(izresid); + h_layerresid_zf_L3_L1L2_->Fill(zresid); + if (match) { + h_layerresid_phi_L3_L1L2_match_->Fill(iphiresid); + h_layerresid_phif_L3_L1L2_match_->Fill(phiresid); + h_layerresid_z_L3_L1L2_match_->Fill(izresid); + h_layerresid_zf_L3_L1L2_match_->Fill(zresid); + } + } + } + return; +} + +void HistImp::FillDiskResidual( + int disk, int seed, double phiresid, double iphiresid, double rresid, double irresid, bool match) { + if (disk == 1) { + if (seed == 0) { + h_diskresid_phi_D1_L1L2_->Fill(iphiresid); + h_diskresid_phif_D1_L1L2_->Fill(phiresid); + h_diskresid_r_D1_L1L2_->Fill(irresid); + h_diskresid_rf_D1_L1L2_->Fill(rresid); + if (match) { + h_diskresid_phi_D1_L1L2_match_->Fill(iphiresid); + h_diskresid_phif_D1_L1L2_match_->Fill(phiresid); + h_diskresid_r_D1_L1L2_match_->Fill(irresid); + h_diskresid_rf_D1_L1L2_match_->Fill(rresid); + } + } + } + + return; +} + +void HistImp::bookSeedEff() { + TH1::AddDirectory(kTRUE); + + assert(h_file_ != 0); + h_file_->cd(); + + h_eff_eta_L1L2seed_ = + new TEfficiency("Efficincy for L1L2 seeding vs eta", "Efficiency for L1L2 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_L2L3seed_ = + new TEfficiency("Efficincy for L2L3 seeding vs eta", "Efficiency for L2L3 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_L3L4seed_ = + new TEfficiency("Efficincy for L3L4 seeding vs eta", "Efficiency for L3L4 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_L5L6seed_ = + new TEfficiency("Efficincy for L5L6 seeding vs eta", "Efficiency for L5L6 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_D1D2seed_ = + new TEfficiency("Efficincy for D1D2 seeding vs eta", "Efficiency for D1D2 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_D3D4seed_ = + new TEfficiency("Efficincy for D3D4 seeding vs eta", "Efficiency for D3D4 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_D1L1seed_ = + new TEfficiency("Efficincy for D1L1 seeding vs eta", "Efficiency for D1L1 seeding vs eta", 50, -2.5, 2.5); + h_eff_eta_D1L2seed_ = + new TEfficiency("Efficincy for D1L2 seeding vs eta", "Efficiency for D1L2 seeding vs eta", 50, -2.5, 2.5); +} + +void HistImp::fillSeedEff(int seedIndex, double etaTP, bool eff) { + if (seedIndex == 0) { + h_eff_eta_L1L2seed_->Fill(eff, etaTP); + } + if (seedIndex == 1) { + h_eff_eta_L2L3seed_->Fill(eff, etaTP); + } + if (seedIndex == 2) { + h_eff_eta_L3L4seed_->Fill(eff, etaTP); + } + if (seedIndex == 3) { + h_eff_eta_L5L6seed_->Fill(eff, etaTP); + } + if (seedIndex == 4) { + h_eff_eta_D1D2seed_->Fill(eff, etaTP); + } + if (seedIndex == 5) { + h_eff_eta_D3D4seed_->Fill(eff, etaTP); + } + if (seedIndex == 6) { + h_eff_eta_D1L1seed_->Fill(eff, etaTP); + } + if (seedIndex == 7) { + h_eff_eta_D1L2seed_->Fill(eff, etaTP); + } + + return; +} diff --git a/L1Trigger/TrackFindingTracklet/test/INTERNAL/HistImp.h b/L1Trigger/TrackFindingTracklet/test/INTERNAL/HistImp.h new file mode 100644 index 0000000000000..25957724a05db --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/INTERNAL/HistImp.h @@ -0,0 +1,117 @@ +#ifndef L1Trigger_TrackFindingTracklet_interface_HistImp_h +#define L1Trigger_TrackFindingTracklet_interface_HistImp_h + +#include +#include +#include + +#include "L1Trigger/TrackFindingTracklet/interface/HistBase.h" + +namespace trklet { + + class Settings; + class Globals; + + class HistImp : public HistBase { + public: + HistImp(); + + ~HistImp() = default; + + void open() override; + void close() override; + + void bookLayerResidual() override; + void bookDiskResidual() override; + void bookTrackletParams() override; + void bookSeedEff() override; + + void fillTrackletParams(const Settings *settings, + Globals *globals, + int seedIndex, + int iSector, + double rinv, + double irinv, + double phi0, + double iphi0, + double eta, + double ieta, + double z0, + double iz0, + int tp) override; + + void FillLayerResidual( + int layer, int seed, double phiresid, double iphiresid, double zresid, double izresid, bool match) override; + + void FillDiskResidual( + int disk, int seed, double phiresid, double iphiresid, double rresid, double irresid, bool match) override; + + //Efficiency for finding seed + void fillSeedEff(int seedIndex, double etaTP, bool eff) override; + + private: + TFile *h_file_; + + //Layer residuales + TH1F *h_layerresid_phi_L3_L1L2_; + TH1F *h_layerresid_phi_L3_L1L2_match_; + TH1F *h_layerresid_phif_L3_L1L2_; + TH1F *h_layerresid_phif_L3_L1L2_match_; + TH1F *h_layerresid_z_L3_L1L2_; + TH1F *h_layerresid_z_L3_L1L2_match_; + TH1F *h_layerresid_zf_L3_L1L2_; + TH1F *h_layerresid_zf_L3_L1L2_match_; + + //Disk residuals + TH1F *h_diskresid_phi_D1_L1L2_; + TH1F *h_diskresid_phi_D1_L1L2_match_; + TH1F *h_diskresid_phif_D1_L1L2_; + TH1F *h_diskresid_phif_D1_L1L2_match_; + TH1F *h_diskresid_r_D1_L1L2_; + TH1F *h_diskresid_r_D1_L1L2_match_; + TH1F *h_diskresid_rf_D1_L1L2_; + TH1F *h_diskresid_rf_D1_L1L2_match_; + + //Tracklet parameters + TH1F *h_rinv_L1L2_; + TH1F *h_irinv_L1L2_; + TH1F *h_rinv_matched_L1L2_; + TH1F *h_irinv_matched_L1L2_; + TH1F *h_rinvres_L1L2_; + TH1F *h_irinvres_L1L2_; + TH1F *h_phi0_L1L2_; + TH1F *h_iphi0_L1L2_; + TH1F *h_phi0_matched_L1L2_; + TH1F *h_iphi0_matched_L1L2_; + TH1F *h_phi0global_L1L2_; + TH1F *h_iphi0global_L1L2_; + TH1F *h_phi0global_matched_L1L2_; + TH1F *h_iphi0global_matched_L1L2_; + TH1F *h_phi0res_L1L2_; + TH1F *h_iphi0res_L1L2_; + TH1F *h_eta_L1L2_; + TH1F *h_ieta_L1L2_; + TH1F *h_eta_matched_L1L2_; + TH1F *h_ieta_matched_L1L2_; + TH1F *h_etares_L1L2_; + TH1F *h_ietares_L1L2_; + TH1F *h_z0_L1L2_; + TH1F *h_iz0_L1L2_; + TH1F *h_z0_matched_L1L2_; + TH1F *h_iz0_matched_L1L2_; + TH1F *h_z0res_L1L2_; + TH1F *h_iz0res_L1L2_; + + //seeding efficiency + TEfficiency *h_eff_eta_L1L2seed_; + TEfficiency *h_eff_eta_L2L3seed_; + TEfficiency *h_eff_eta_L3L4seed_; + TEfficiency *h_eff_eta_L5L6seed_; + TEfficiency *h_eff_eta_D1D2seed_; + TEfficiency *h_eff_eta_D3D4seed_; + TEfficiency *h_eff_eta_D1L1seed_; + TEfficiency *h_eff_eta_D1L2seed_; + }; + +}; // namespace trklet +#endif diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc new file mode 100644 index 0000000000000..d86c90494b1e6 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker.cc @@ -0,0 +1,1492 @@ +////////////////////////////////////////////////////////////////////// +// // +// Analyzer for making mini-ntuple for L1 track performance plots // +// // +////////////////////////////////////////////////////////////////////// + +//////////////////// +// FRAMEWORK HEADERS +#include "FWCore/PluginManager/interface/ModuleDef.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" + +/////////////////////// +// DATA FORMATS HEADERS +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/Ref.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TrackTrigger/interface/TTCluster.h" +#include "DataFormats/L1TrackTrigger/interface/TTStub.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" +#include "SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h" +#include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTClusterAssociationMap.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTStubAssociationMap.h" +#include "SimTracker/TrackTriggerAssociation/interface/TTTrackAssociationMap.h" +#include "Geometry/Records/interface/StackedTrackerGeometryRecord.h" + +#include "DataFormats/JetReco/interface/GenJetCollection.h" +#include "DataFormats/JetReco/interface/GenJet.h" + +//////////////////////////// +// DETECTOR GEOMETRY HEADERS +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "Geometry/TrackerGeometryBuilder/interface/RectangularPixelTopology.h" +#include "Geometry/CommonDetUnit/interface/GeomDetType.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" + +#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" +#include "Geometry/CommonTopologies/interface/PixelGeomDetType.h" +#include "Geometry/TrackerGeometryBuilder/interface/PixelTopologyBuilder.h" +#include "Geometry/Records/interface/StackedTrackerGeometryRecord.h" + +//////////////// +// PHYSICS TOOLS +#include "CommonTools/UtilAlgos/interface/TFileService.h" + +/////////////// +// ROOT HEADERS +#include +#include +#include +#include +#include +#include +#include + +////////////// +// STD HEADERS +#include +#include +#include + +////////////// +// NAMESPACES +using namespace std; +using namespace edm; + +////////////////////////////// +// // +// CLASS DEFINITION // +// // +////////////////////////////// + +class L1TrackNtupleMaker : public edm::EDAnalyzer { +public: + // Constructor/destructor + explicit L1TrackNtupleMaker(const edm::ParameterSet& iConfig); + ~L1TrackNtupleMaker() override; + + // Mandatory methods + void beginJob() override; + void endJob() override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + +protected: +private: + //----------------------------------------------------------------------------------------------- + // Containers of parameters passed by python configuration file + edm::ParameterSet config; + + int MyProcess; // 11/13/211 for single electrons/muons/pions, 6/15 for pions from ttbar/taus, 1 for inclusive + bool DebugMode; // lots of debug printout statements + bool SaveAllTracks; // store in ntuples not only truth-matched tracks but ALL tracks + bool SaveStubs; // option to save also stubs in the ntuples (makes them large...) + int L1Tk_nPar; // use 4 or 5 parameter track fit? + int TP_minNStub; // require TPs to have >= minNStub (defining efficiency denominator) (==0 means to only require >= 1 cluster) + int TP_minNStubLayer; // require TPs to have stubs in >= minNStubLayer layers/disks (defining efficiency denominator) + double TP_minPt; // save TPs with pt > minPt + double TP_maxEta; // save TPs with |eta| < maxEta + double TP_maxZ0; // save TPs with |z0| < maxZ0 + int L1Tk_minNStub; // require L1 tracks to have >= minNStub (this is mostly for tracklet purposes) + + bool TrackingInJets; // do tracking in jets? + + edm::InputTag L1TrackInputTag; // L1 track collection + edm::InputTag MCTruthTrackInputTag; // MC truth collection + edm::InputTag MCTruthClusterInputTag; + edm::InputTag L1StubInputTag; + edm::InputTag MCTruthStubInputTag; + edm::InputTag TrackingParticleInputTag; + edm::InputTag TrackingVertexInputTag; + edm::InputTag GenJetInputTag; + + edm::EDGetTokenT > > ttClusterToken_; + edm::EDGetTokenT > > ttStubToken_; + edm::EDGetTokenT > ttClusterMCTruthToken_; + edm::EDGetTokenT > ttStubMCTruthToken_; + + edm::EDGetTokenT > > ttTrackToken_; + edm::EDGetTokenT > ttTrackMCTruthToken_; + + edm::EDGetTokenT > TrackingParticleToken_; + edm::EDGetTokenT > TrackingVertexToken_; + + edm::EDGetTokenT > GenJetToken_; + + //----------------------------------------------------------------------------------------------- + // tree & branches for mini-ntuple + + bool available_; // ROOT file for histograms is open. + + TTree* eventTree; + + // all L1 tracks + std::vector* m_trk_pt; + std::vector* m_trk_eta; + std::vector* m_trk_phi; + std::vector* m_trk_d0; // (filled if L1Tk_nPar==5, else 999) + std::vector* m_trk_z0; + std::vector* m_trk_chi2; + std::vector* m_trk_chi2rphi; + std::vector* m_trk_chi2rz; + std::vector* m_trk_bendchi2; + std::vector* m_trk_nstub; + std::vector* m_trk_lhits; + std::vector* m_trk_dhits; + std::vector* m_trk_seed; + std::vector* m_trk_hitpattern; + std::vector* m_trk_phiSector; + std::vector* m_trk_genuine; + std::vector* m_trk_loose; + std::vector* m_trk_unknown; + std::vector* m_trk_combinatoric; + std::vector* m_trk_fake; //0 fake, 1 track from primary interaction, 2 secondary track + std::vector* m_trk_matchtp_pdgid; + std::vector* m_trk_matchtp_pt; + std::vector* m_trk_matchtp_eta; + std::vector* m_trk_matchtp_phi; + std::vector* m_trk_matchtp_z0; + std::vector* m_trk_matchtp_dxy; + std::vector* m_trk_injet; //is the track within dR<0.4 of a genjet with pt > 30 GeV? + std::vector* m_trk_injet_highpt; //is the track within dR<0.4 of a genjet with pt > 100 GeV? + std::vector* m_trk_injet_vhighpt; //is the track within dR<0.4 of a genjet with pt > 200 GeV? + + // all tracking particles + std::vector* m_tp_pt; + std::vector* m_tp_eta; + std::vector* m_tp_phi; + std::vector* m_tp_dxy; + std::vector* m_tp_d0; + std::vector* m_tp_z0; + std::vector* m_tp_d0_prod; + std::vector* m_tp_z0_prod; + std::vector* m_tp_pdgid; + std::vector* m_tp_nmatch; + std::vector* m_tp_nstub; + std::vector* m_tp_eventid; + std::vector* m_tp_charge; + std::vector* m_tp_injet; + std::vector* m_tp_injet_highpt; + std::vector* m_tp_injet_vhighpt; + + // *L1 track* properties if m_tp_nmatch > 0 + std::vector* m_matchtrk_pt; + std::vector* m_matchtrk_eta; + std::vector* m_matchtrk_phi; + std::vector* m_matchtrk_d0; //this variable is only filled if L1Tk_nPar==5 + std::vector* m_matchtrk_z0; + std::vector* m_matchtrk_chi2; + std::vector* m_matchtrk_chi2rphi; + std::vector* m_matchtrk_chi2rz; + std::vector* m_matchtrk_bendchi2; + std::vector* m_matchtrk_nstub; + std::vector* m_matchtrk_lhits; + std::vector* m_matchtrk_dhits; + std::vector* m_matchtrk_seed; + std::vector* m_matchtrk_hitpattern; + std::vector* m_matchtrk_injet; + std::vector* m_matchtrk_injet_highpt; + std::vector* m_matchtrk_injet_vhighpt; + + // ALL stubs + std::vector* m_allstub_x; + std::vector* m_allstub_y; + std::vector* m_allstub_z; + + std::vector* m_allstub_isBarrel; // stub is in barrel (1) or in disk (0) + std::vector* m_allstub_layer; + std::vector* m_allstub_isPSmodule; + + std::vector* m_allstub_trigDisplace; + std::vector* m_allstub_trigOffset; + std::vector* m_allstub_trigPos; + std::vector* m_allstub_trigBend; + + // stub associated with tracking particle ? + std::vector* m_allstub_matchTP_pdgid; // -999 if not matched + std::vector* m_allstub_matchTP_pt; // -999 if not matched + std::vector* m_allstub_matchTP_eta; // -999 if not matched + std::vector* m_allstub_matchTP_phi; // -999 if not matched + + std::vector* m_allstub_genuine; + + // track jet variables (for each gen jet, store the sum of pt of TPs / tracks inside jet cone) + std::vector* m_jet_eta; + std::vector* m_jet_phi; + std::vector* m_jet_pt; + std::vector* m_jet_tp_sumpt; + std::vector* m_jet_trk_sumpt; + std::vector* m_jet_matchtrk_sumpt; +}; + +////////////////////////////////// +// // +// CLASS IMPLEMENTATION // +// // +////////////////////////////////// + +////////////// +// CONSTRUCTOR +L1TrackNtupleMaker::L1TrackNtupleMaker(edm::ParameterSet const& iConfig) : config(iConfig) { + MyProcess = iConfig.getParameter("MyProcess"); + DebugMode = iConfig.getParameter("DebugMode"); + SaveAllTracks = iConfig.getParameter("SaveAllTracks"); + SaveStubs = iConfig.getParameter("SaveStubs"); + L1Tk_nPar = iConfig.getParameter("L1Tk_nPar"); + TP_minNStub = iConfig.getParameter("TP_minNStub"); + TP_minNStubLayer = iConfig.getParameter("TP_minNStubLayer"); + TP_minPt = iConfig.getParameter("TP_minPt"); + TP_maxEta = iConfig.getParameter("TP_maxEta"); + TP_maxZ0 = iConfig.getParameter("TP_maxZ0"); + L1TrackInputTag = iConfig.getParameter("L1TrackInputTag"); + MCTruthTrackInputTag = iConfig.getParameter("MCTruthTrackInputTag"); + L1Tk_minNStub = iConfig.getParameter("L1Tk_minNStub"); + + TrackingInJets = iConfig.getParameter("TrackingInJets"); + + L1StubInputTag = iConfig.getParameter("L1StubInputTag"); + MCTruthClusterInputTag = iConfig.getParameter("MCTruthClusterInputTag"); + MCTruthStubInputTag = iConfig.getParameter("MCTruthStubInputTag"); + TrackingParticleInputTag = iConfig.getParameter("TrackingParticleInputTag"); + TrackingVertexInputTag = iConfig.getParameter("TrackingVertexInputTag"); + GenJetInputTag = iConfig.getParameter("GenJetInputTag"); + + ttTrackToken_ = consumes > >(L1TrackInputTag); + ttTrackMCTruthToken_ = consumes >(MCTruthTrackInputTag); + ttStubToken_ = consumes > >(L1StubInputTag); + ttClusterMCTruthToken_ = consumes >(MCTruthClusterInputTag); + ttStubMCTruthToken_ = consumes >(MCTruthStubInputTag); + + TrackingParticleToken_ = consumes >(TrackingParticleInputTag); + TrackingVertexToken_ = consumes >(TrackingVertexInputTag); + GenJetToken_ = consumes >(GenJetInputTag); +} + +///////////// +// DESTRUCTOR +L1TrackNtupleMaker::~L1TrackNtupleMaker() {} + +////////// +// END JOB +void L1TrackNtupleMaker::endJob() { + // things to be done at the exit of the event Loop + edm::LogVerbatim("Tracklet") << "L1TrackNtupleMaker::endJob"; +} + +//////////// +// BEGIN JOB +void L1TrackNtupleMaker::beginJob() { + // things to be done before entering the event Loop + edm::LogVerbatim("Tracklet") << "L1TrackNtupleMaker::beginJob"; + + //----------------------------------------------------------------------------------------------- + // book histograms / make ntuple + edm::Service fs; + available_ = fs.isAvailable(); + if (not available_) + return; // No ROOT file open. + + // initilize + m_trk_pt = new std::vector; + m_trk_eta = new std::vector; + m_trk_phi = new std::vector; + m_trk_z0 = new std::vector; + m_trk_d0 = new std::vector; + m_trk_chi2 = new std::vector; + m_trk_chi2rphi = new std::vector; + m_trk_chi2rz = new std::vector; + m_trk_bendchi2 = new std::vector; + m_trk_nstub = new std::vector; + m_trk_lhits = new std::vector; + m_trk_dhits = new std::vector; + m_trk_seed = new std::vector; + m_trk_hitpattern = new std::vector; + m_trk_phiSector = new std::vector; + m_trk_genuine = new std::vector; + m_trk_loose = new std::vector; + m_trk_unknown = new std::vector; + m_trk_combinatoric = new std::vector; + m_trk_fake = new std::vector; + m_trk_matchtp_pdgid = new std::vector; + m_trk_matchtp_pt = new std::vector; + m_trk_matchtp_eta = new std::vector; + m_trk_matchtp_phi = new std::vector; + m_trk_matchtp_z0 = new std::vector; + m_trk_matchtp_dxy = new std::vector; + m_trk_injet = new std::vector; + m_trk_injet_highpt = new std::vector; + m_trk_injet_vhighpt = new std::vector; + + m_tp_pt = new std::vector; + m_tp_eta = new std::vector; + m_tp_phi = new std::vector; + m_tp_dxy = new std::vector; + m_tp_d0 = new std::vector; + m_tp_z0 = new std::vector; + m_tp_d0_prod = new std::vector; + m_tp_z0_prod = new std::vector; + m_tp_pdgid = new std::vector; + m_tp_nmatch = new std::vector; + m_tp_nstub = new std::vector; + m_tp_eventid = new std::vector; + m_tp_charge = new std::vector; + m_tp_injet = new std::vector; + m_tp_injet_highpt = new std::vector; + m_tp_injet_vhighpt = new std::vector; + + m_matchtrk_pt = new std::vector; + m_matchtrk_eta = new std::vector; + m_matchtrk_phi = new std::vector; + m_matchtrk_z0 = new std::vector; + m_matchtrk_d0 = new std::vector; + m_matchtrk_chi2 = new std::vector; + m_matchtrk_chi2rphi = new std::vector; + m_matchtrk_chi2rz = new std::vector; + m_matchtrk_bendchi2 = new std::vector; + m_matchtrk_nstub = new std::vector; + m_matchtrk_dhits = new std::vector; + m_matchtrk_lhits = new std::vector; + m_matchtrk_seed = new std::vector; + m_matchtrk_hitpattern = new std::vector; + m_matchtrk_injet = new std::vector; + m_matchtrk_injet_highpt = new std::vector; + m_matchtrk_injet_vhighpt = new std::vector; + + m_allstub_x = new std::vector; + m_allstub_y = new std::vector; + m_allstub_z = new std::vector; + + m_allstub_isBarrel = new std::vector; + m_allstub_layer = new std::vector; + m_allstub_isPSmodule = new std::vector; + m_allstub_trigDisplace = new std::vector; + m_allstub_trigOffset = new std::vector; + m_allstub_trigPos = new std::vector; + m_allstub_trigBend = new std::vector; + + m_allstub_matchTP_pdgid = new std::vector; + m_allstub_matchTP_pt = new std::vector; + m_allstub_matchTP_eta = new std::vector; + m_allstub_matchTP_phi = new std::vector; + + m_allstub_genuine = new std::vector; + + m_jet_eta = new std::vector; + m_jet_phi = new std::vector; + m_jet_pt = new std::vector; + m_jet_tp_sumpt = new std::vector; + m_jet_trk_sumpt = new std::vector; + m_jet_matchtrk_sumpt = new std::vector; + + // ntuple + eventTree = fs->make("eventTree", "Event tree"); + + if (SaveAllTracks) { + eventTree->Branch("trk_pt", &m_trk_pt); + eventTree->Branch("trk_eta", &m_trk_eta); + eventTree->Branch("trk_phi", &m_trk_phi); + eventTree->Branch("trk_d0", &m_trk_d0); + eventTree->Branch("trk_z0", &m_trk_z0); + eventTree->Branch("trk_chi2", &m_trk_chi2); + eventTree->Branch("trk_chi2rphi", &m_trk_chi2rphi); + eventTree->Branch("trk_chi2rz", &m_trk_chi2rz); + eventTree->Branch("trk_bendchi2", &m_trk_bendchi2); + eventTree->Branch("trk_nstub", &m_trk_nstub); + eventTree->Branch("trk_lhits", &m_trk_lhits); + eventTree->Branch("trk_dhits", &m_trk_dhits); + eventTree->Branch("trk_seed", &m_trk_seed); + eventTree->Branch("trk_hitpattern", &m_trk_hitpattern); + eventTree->Branch("trk_phiSector", &m_trk_phiSector); + eventTree->Branch("trk_genuine", &m_trk_genuine); + eventTree->Branch("trk_loose", &m_trk_loose); + eventTree->Branch("trk_unknown", &m_trk_unknown); + eventTree->Branch("trk_combinatoric", &m_trk_combinatoric); + eventTree->Branch("trk_fake", &m_trk_fake); + eventTree->Branch("trk_matchtp_pdgid", &m_trk_matchtp_pdgid); + eventTree->Branch("trk_matchtp_pt", &m_trk_matchtp_pt); + eventTree->Branch("trk_matchtp_eta", &m_trk_matchtp_eta); + eventTree->Branch("trk_matchtp_phi", &m_trk_matchtp_phi); + eventTree->Branch("trk_matchtp_z0", &m_trk_matchtp_z0); + eventTree->Branch("trk_matchtp_dxy", &m_trk_matchtp_dxy); + if (TrackingInJets) { + eventTree->Branch("trk_injet", &m_trk_injet); + eventTree->Branch("trk_injet_highpt", &m_trk_injet_highpt); + eventTree->Branch("trk_injet_vhighpt", &m_trk_injet_vhighpt); + } + } + + eventTree->Branch("tp_pt", &m_tp_pt); + eventTree->Branch("tp_eta", &m_tp_eta); + eventTree->Branch("tp_phi", &m_tp_phi); + eventTree->Branch("tp_dxy", &m_tp_dxy); + eventTree->Branch("tp_d0", &m_tp_d0); + eventTree->Branch("tp_z0", &m_tp_z0); + eventTree->Branch("tp_d0_prod", &m_tp_d0_prod); + eventTree->Branch("tp_z0_prod", &m_tp_z0_prod); + eventTree->Branch("tp_pdgid", &m_tp_pdgid); + eventTree->Branch("tp_nmatch", &m_tp_nmatch); + eventTree->Branch("tp_nstub", &m_tp_nstub); + eventTree->Branch("tp_eventid", &m_tp_eventid); + eventTree->Branch("tp_charge", &m_tp_charge); + if (TrackingInJets) { + eventTree->Branch("tp_injet", &m_tp_injet); + eventTree->Branch("tp_injet_highpt", &m_tp_injet_highpt); + eventTree->Branch("tp_injet_vhighpt", &m_tp_injet_vhighpt); + } + + eventTree->Branch("matchtrk_pt", &m_matchtrk_pt); + eventTree->Branch("matchtrk_eta", &m_matchtrk_eta); + eventTree->Branch("matchtrk_phi", &m_matchtrk_phi); + eventTree->Branch("matchtrk_z0", &m_matchtrk_z0); + eventTree->Branch("matchtrk_d0", &m_matchtrk_d0); + eventTree->Branch("matchtrk_chi2", &m_matchtrk_chi2); + eventTree->Branch("matchtrk_chi2rphi", &m_matchtrk_chi2rphi); + eventTree->Branch("matchtrk_chi2rz", &m_matchtrk_chi2rz); + eventTree->Branch("matchtrk_bendchi2", &m_matchtrk_bendchi2); + eventTree->Branch("matchtrk_nstub", &m_matchtrk_nstub); + eventTree->Branch("matchtrk_lhits", &m_matchtrk_lhits); + eventTree->Branch("matchtrk_dhits", &m_matchtrk_dhits); + eventTree->Branch("matchtrk_seed", &m_matchtrk_seed); + eventTree->Branch("matchtrk_hitpattern", &m_matchtrk_hitpattern); + if (TrackingInJets) { + eventTree->Branch("matchtrk_injet", &m_matchtrk_injet); + eventTree->Branch("matchtrk_injet_highpt", &m_matchtrk_injet_highpt); + eventTree->Branch("matchtrk_injet_vhighpt", &m_matchtrk_injet_vhighpt); + } + + if (SaveStubs) { + eventTree->Branch("allstub_x", &m_allstub_x); + eventTree->Branch("allstub_y", &m_allstub_y); + eventTree->Branch("allstub_z", &m_allstub_z); + + eventTree->Branch("allstub_isBarrel", &m_allstub_isBarrel); + eventTree->Branch("allstub_layer", &m_allstub_layer); + eventTree->Branch("allstub_isPSmodule", &m_allstub_isPSmodule); + + eventTree->Branch("allstub_trigDisplace", &m_allstub_trigDisplace); + eventTree->Branch("allstub_trigOffset", &m_allstub_trigOffset); + eventTree->Branch("allstub_trigPos", &m_allstub_trigPos); + eventTree->Branch("allstub_trigBend", &m_allstub_trigBend); + + eventTree->Branch("allstub_matchTP_pdgid", &m_allstub_matchTP_pdgid); + eventTree->Branch("allstub_matchTP_pt", &m_allstub_matchTP_pt); + eventTree->Branch("allstub_matchTP_eta", &m_allstub_matchTP_eta); + eventTree->Branch("allstub_matchTP_phi", &m_allstub_matchTP_phi); + + eventTree->Branch("allstub_genuine", &m_allstub_genuine); + } + + if (TrackingInJets) { + eventTree->Branch("jet_eta", &m_jet_eta); + eventTree->Branch("jet_phi", &m_jet_phi); + eventTree->Branch("jet_pt", &m_jet_pt); + eventTree->Branch("jet_tp_sumpt", &m_jet_tp_sumpt); + eventTree->Branch("jet_trk_sumpt", &m_jet_trk_sumpt); + eventTree->Branch("jet_matchtrk_sumpt", &m_jet_matchtrk_sumpt); + } +} + +////////// +// ANALYZE +void L1TrackNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + if (not available_) + return; // No ROOT file open. + + if (!(MyProcess == 13 || MyProcess == 11 || MyProcess == 211 || MyProcess == 6 || MyProcess == 15 || + MyProcess == 1)) { + edm::LogVerbatim("Tracklet") << "The specified MyProcess is invalid! Exiting..."; + return; + } + + if (!(L1Tk_nPar == 4 || L1Tk_nPar == 5)) { + edm::LogVerbatim("Tracklet") << "Invalid number of track parameters, specified L1Tk_nPar == " << L1Tk_nPar + << " but only 4/5 are valid options! Exiting..."; + return; + } + + // clear variables + if (SaveAllTracks) { + m_trk_pt->clear(); + m_trk_eta->clear(); + m_trk_phi->clear(); + m_trk_d0->clear(); + m_trk_z0->clear(); + m_trk_chi2->clear(); + m_trk_chi2rphi->clear(); + m_trk_chi2rz->clear(); + m_trk_bendchi2->clear(); + m_trk_nstub->clear(); + m_trk_lhits->clear(); + m_trk_dhits->clear(); + m_trk_seed->clear(); + m_trk_hitpattern->clear(); + m_trk_phiSector->clear(); + m_trk_genuine->clear(); + m_trk_loose->clear(); + m_trk_unknown->clear(); + m_trk_combinatoric->clear(); + m_trk_fake->clear(); + m_trk_matchtp_pdgid->clear(); + m_trk_matchtp_pt->clear(); + m_trk_matchtp_eta->clear(); + m_trk_matchtp_phi->clear(); + m_trk_matchtp_z0->clear(); + m_trk_matchtp_dxy->clear(); + m_trk_injet->clear(); + m_trk_injet_highpt->clear(); + m_trk_injet_vhighpt->clear(); + } + + m_tp_pt->clear(); + m_tp_eta->clear(); + m_tp_phi->clear(); + m_tp_dxy->clear(); + m_tp_d0->clear(); + m_tp_z0->clear(); + m_tp_d0_prod->clear(); + m_tp_z0_prod->clear(); + m_tp_pdgid->clear(); + m_tp_nmatch->clear(); + m_tp_nstub->clear(); + m_tp_eventid->clear(); + m_tp_charge->clear(); + m_tp_injet->clear(); + m_tp_injet_highpt->clear(); + m_tp_injet_vhighpt->clear(); + + m_matchtrk_pt->clear(); + m_matchtrk_eta->clear(); + m_matchtrk_phi->clear(); + m_matchtrk_z0->clear(); + m_matchtrk_d0->clear(); + m_matchtrk_chi2->clear(); + m_matchtrk_chi2rphi->clear(); + m_matchtrk_chi2rz->clear(); + m_matchtrk_bendchi2->clear(); + m_matchtrk_nstub->clear(); + m_matchtrk_lhits->clear(); + m_matchtrk_dhits->clear(); + m_matchtrk_seed->clear(); + m_matchtrk_hitpattern->clear(); + m_matchtrk_injet->clear(); + m_matchtrk_injet_highpt->clear(); + m_matchtrk_injet_vhighpt->clear(); + + if (SaveStubs) { + m_allstub_x->clear(); + m_allstub_y->clear(); + m_allstub_z->clear(); + + m_allstub_isBarrel->clear(); + m_allstub_layer->clear(); + m_allstub_isPSmodule->clear(); + + m_allstub_trigDisplace->clear(); + m_allstub_trigOffset->clear(); + m_allstub_trigPos->clear(); + m_allstub_trigBend->clear(); + + m_allstub_matchTP_pdgid->clear(); + m_allstub_matchTP_pt->clear(); + m_allstub_matchTP_eta->clear(); + m_allstub_matchTP_phi->clear(); + + m_allstub_genuine->clear(); + } + + m_jet_eta->clear(); + m_jet_phi->clear(); + m_jet_pt->clear(); + m_jet_tp_sumpt->clear(); + m_jet_trk_sumpt->clear(); + m_jet_matchtrk_sumpt->clear(); + + // ----------------------------------------------------------------------------------------------- + // retrieve various containers + // ----------------------------------------------------------------------------------------------- + + // L1 tracks + edm::Handle > > TTTrackHandle; + iEvent.getByToken(ttTrackToken_, TTTrackHandle); + + // L1 stubs + edm::Handle > > TTStubHandle; + if (SaveStubs) + iEvent.getByToken(ttStubToken_, TTStubHandle); + + // MC truth association maps + edm::Handle > MCTruthTTClusterHandle; + iEvent.getByToken(ttClusterMCTruthToken_, MCTruthTTClusterHandle); + edm::Handle > MCTruthTTStubHandle; + iEvent.getByToken(ttStubMCTruthToken_, MCTruthTTStubHandle); + edm::Handle > MCTruthTTTrackHandle; + iEvent.getByToken(ttTrackMCTruthToken_, MCTruthTTTrackHandle); + + // tracking particles + edm::Handle > TrackingParticleHandle; + edm::Handle > TrackingVertexHandle; + iEvent.getByToken(TrackingParticleToken_, TrackingParticleHandle); + iEvent.getByToken(TrackingVertexToken_, TrackingVertexHandle); + + // ----------------------------------------------------------------------------------------------- + // more for TTStubs + edm::ESHandle geometryHandle; + iSetup.get().get(geometryHandle); + + edm::ESHandle tTopoHandle; + iSetup.get().get(tTopoHandle); + + edm::ESHandle tGeomHandle; + iSetup.get().get(tGeomHandle); + + const TrackerTopology* const tTopo = tTopoHandle.product(); + const TrackerGeometry* const theTrackerGeom = tGeomHandle.product(); + + // ---------------------------------------------------------------------------------------------- + // loop over L1 stubs + // ---------------------------------------------------------------------------------------------- + + if (SaveStubs) { + for (auto gd = theTrackerGeom->dets().begin(); gd != theTrackerGeom->dets().end(); gd++) { + DetId detid = (*gd)->geographicalId(); + if (detid.subdetId() != StripSubdetector::TOB && detid.subdetId() != StripSubdetector::TID) + continue; + if (!tTopo->isLower(detid)) + continue; // loop on the stacks: choose the lower arbitrarily + DetId stackDetid = tTopo->stack(detid); // Stub module detid + + if (TTStubHandle->find(stackDetid) == TTStubHandle->end()) + continue; + + // Get the DetSets of the Clusters + edmNew::DetSet > stubs = (*TTStubHandle)[stackDetid]; + const GeomDetUnit* det0 = theTrackerGeom->idToDetUnit(detid); + const auto* theGeomDet = dynamic_cast(det0); + const PixelTopology* topol = dynamic_cast(&(theGeomDet->specificTopology())); + + // loop over stubs + for (auto stubIter = stubs.begin(); stubIter != stubs.end(); ++stubIter) { + edm::Ref >, TTStub > tempStubPtr = + edmNew::makeRefTo(TTStubHandle, stubIter); + + int isBarrel = 0; + int layer = -999999; + if (detid.subdetId() == StripSubdetector::TOB) { + isBarrel = 1; + layer = static_cast(tTopo->layer(detid)); + } else if (detid.subdetId() == StripSubdetector::TID) { + isBarrel = 0; + layer = static_cast(tTopo->layer(detid)); + } else { + edm::LogVerbatim("Tracklet") << "WARNING -- neither TOB or TID stub, shouldn't happen..."; + layer = -1; + } + + int isPSmodule = 0; + if (topol->nrows() == 960) + isPSmodule = 1; + + MeasurementPoint coords = tempStubPtr->clusterRef(0)->findAverageLocalCoordinatesCentered(); + LocalPoint clustlp = topol->localPosition(coords); + GlobalPoint posStub = theGeomDet->surface().toGlobal(clustlp); + + double tmp_stub_x = posStub.x(); + double tmp_stub_y = posStub.y(); + double tmp_stub_z = posStub.z(); + + float trigDisplace = tempStubPtr->rawBend(); + float trigOffset = tempStubPtr->bendOffset(); + float trigPos = tempStubPtr->innerClusterPosition(); + float trigBend = tempStubPtr->bendFE(); + + m_allstub_x->push_back(tmp_stub_x); + m_allstub_y->push_back(tmp_stub_y); + m_allstub_z->push_back(tmp_stub_z); + + m_allstub_isBarrel->push_back(isBarrel); + m_allstub_layer->push_back(layer); + m_allstub_isPSmodule->push_back(isPSmodule); + + m_allstub_trigDisplace->push_back(trigDisplace); + m_allstub_trigOffset->push_back(trigOffset); + m_allstub_trigPos->push_back(trigPos); + m_allstub_trigBend->push_back(trigBend); + + // matched to tracking particle? + edm::Ptr my_tp = MCTruthTTStubHandle->findTrackingParticlePtr(tempStubPtr); + + int myTP_pdgid = -999; + float myTP_pt = -999; + float myTP_eta = -999; + float myTP_phi = -999; + + if (my_tp.isNull() == false) { + int tmp_eventid = my_tp->eventId().event(); + + if (tmp_eventid > 0) + continue; // this means stub from pileup track + + myTP_pdgid = my_tp->pdgId(); + myTP_pt = my_tp->p4().pt(); + myTP_eta = my_tp->p4().eta(); + myTP_phi = my_tp->p4().phi(); + } + + m_allstub_matchTP_pdgid->push_back(myTP_pdgid); + m_allstub_matchTP_pt->push_back(myTP_pt); + m_allstub_matchTP_eta->push_back(myTP_eta); + m_allstub_matchTP_phi->push_back(myTP_phi); + + int tmp_stub_genuine = 0; + if (MCTruthTTStubHandle->isGenuine(tempStubPtr)) + tmp_stub_genuine = 1; + + m_allstub_genuine->push_back(tmp_stub_genuine); + } + } + } + + // ---------------------------------------------------------------------------------------------- + // tracking in jets + // ---------------------------------------------------------------------------------------------- + + std::vector v_jets; + std::vector v_jets_highpt; + std::vector v_jets_vhighpt; + + if (TrackingInJets) { + // gen jets + if (DebugMode) + edm::LogVerbatim("Tracklet") << "get genjets"; + edm::Handle > GenJetHandle; + iEvent.getByToken(GenJetToken_, GenJetHandle); + + if (GenJetHandle.isValid()) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "loop over genjets"; + std::vector::const_iterator iterGenJet; + for (iterGenJet = GenJetHandle->begin(); iterGenJet != GenJetHandle->end(); ++iterGenJet) { + reco::GenJet myJet = reco::GenJet(*iterGenJet); + + if (myJet.pt() < 30.0) + continue; + if (std::abs(myJet.eta()) > 2.5) + continue; + + if (DebugMode) + edm::LogVerbatim("Tracklet") << "genjet pt = " << myJet.pt() << ", eta = " << myJet.eta(); + + bool ishighpt = false; + bool isveryhighpt = false; + if (myJet.pt() > 100.0) + ishighpt = true; + if (myJet.pt() > 200.0) + isveryhighpt = true; + + const math::XYZTLorentzVector& jetP4 = myJet.p4(); + v_jets.push_back(jetP4); + if (ishighpt) + v_jets_highpt.push_back(1); + else + v_jets_highpt.push_back(0); + if (isveryhighpt) + v_jets_vhighpt.push_back(1); + else + v_jets_vhighpt.push_back(0); + + } // end loop over genjets + } // end isValid + + } // end TrackingInJets + + const int NJETS = 10; + float jets_tp_sumpt[NJETS] = {0}; //sum pt of TPs with dR<0.4 of jet + float jets_matchtrk_sumpt[NJETS] = {0}; //sum pt of tracks matched to TP with dR<0.4 of jet + float jets_trk_sumpt[NJETS] = {0}; //sum pt of all tracks with dR<0.4 of jet + + // ---------------------------------------------------------------------------------------------- + // loop over L1 tracks + // ---------------------------------------------------------------------------------------------- + + if (SaveAllTracks) { + if (DebugMode) { + edm::LogVerbatim("Tracklet") << "\n Loop over L1 tracks!"; + edm::LogVerbatim("Tracklet") << "\n Looking at " << L1Tk_nPar << "-parameter tracks!"; + } + + int this_l1track = 0; + std::vector >::const_iterator iterL1Track; + for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { + edm::Ptr > l1track_ptr(TTTrackHandle, this_l1track); + this_l1track++; + + float tmp_trk_pt = iterL1Track->momentum().perp(); + float tmp_trk_eta = iterL1Track->momentum().eta(); + float tmp_trk_phi = iterL1Track->momentum().phi(); + float tmp_trk_z0 = iterL1Track->z0(); //cm + + float tmp_trk_d0 = -999; + if (L1Tk_nPar == 5) { + float tmp_trk_x0 = iterL1Track->POCA().x(); + float tmp_trk_y0 = iterL1Track->POCA().y(); + tmp_trk_d0 = -tmp_trk_x0 * sin(tmp_trk_phi) + tmp_trk_y0 * cos(tmp_trk_phi); + } + + float tmp_trk_chi2 = iterL1Track->chi2(); + float tmp_trk_chi2rphi = iterL1Track->chi2XY(); + float tmp_trk_chi2rz = iterL1Track->chi2Z(); + float tmp_trk_bendchi2 = iterL1Track->stubPtConsistency(); + + std::vector >, TTStub > > + stubRefs = iterL1Track->getStubRefs(); + int tmp_trk_nstub = (int)stubRefs.size(); + + int tmp_trk_seed = 0; + tmp_trk_seed = (int)iterL1Track->trackSeedType(); + + int tmp_trk_hitpattern = 0; + tmp_trk_hitpattern = (int)iterL1Track->hitPattern(); + + unsigned int tmp_trk_phiSector = iterL1Track->phiSector(); + + // ---------------------------------------------------------------------------------------------- + // loop over stubs on tracks + + //float tmp_trk_bend_chi2 = 0; + int tmp_trk_dhits = 0; + int tmp_trk_lhits = 0; + + if (true) { + // loop over stubs + for (int is = 0; is < tmp_trk_nstub; is++) { + //detID of stub + DetId detIdStub = theTrackerGeom->idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); + + MeasurementPoint coords = stubRefs.at(is)->clusterRef(0)->findAverageLocalCoordinatesCentered(); + const GeomDet* theGeomDet = theTrackerGeom->idToDet(detIdStub); + Global3DPoint posStub = theGeomDet->surface().toGlobal(theGeomDet->topology().localPosition(coords)); + + double x = posStub.x(); + double y = posStub.y(); + double z = posStub.z(); + + int layer = -999999; + if (detIdStub.subdetId() == StripSubdetector::TOB) { + layer = static_cast(tTopo->layer(detIdStub)); + if (DebugMode) + edm::LogVerbatim("Tracklet") + << " stub in layer " << layer << " at position x y z = " << x << " " << y << " " << z; + tmp_trk_lhits += pow(10, layer - 1); + } else if (detIdStub.subdetId() == StripSubdetector::TID) { + layer = static_cast(tTopo->layer(detIdStub)); + if (DebugMode) + edm::LogVerbatim("Tracklet") + << " stub in disk " << layer << " at position x y z = " << x << " " << y << " " << z; + tmp_trk_dhits += pow(10, layer - 1); + } + + } //end loop over stubs + } + // ---------------------------------------------------------------------------------------------- + + int tmp_trk_genuine = 0; + int tmp_trk_loose = 0; + int tmp_trk_unknown = 0; + int tmp_trk_combinatoric = 0; + if (MCTruthTTTrackHandle->isLooselyGenuine(l1track_ptr)) + tmp_trk_loose = 1; + if (MCTruthTTTrackHandle->isGenuine(l1track_ptr)) + tmp_trk_genuine = 1; + if (MCTruthTTTrackHandle->isUnknown(l1track_ptr)) + tmp_trk_unknown = 1; + if (MCTruthTTTrackHandle->isCombinatoric(l1track_ptr)) + tmp_trk_combinatoric = 1; + + if (DebugMode) { + edm::LogVerbatim("Tracklet") << "L1 track," + << " pt: " << tmp_trk_pt << " eta: " << tmp_trk_eta << " phi: " << tmp_trk_phi + << " z0: " << tmp_trk_z0 << " chi2: " << tmp_trk_chi2 + << " chi2rphi: " << tmp_trk_chi2rphi << " chi2rz: " << tmp_trk_chi2rz + << " nstub: " << tmp_trk_nstub; + if (tmp_trk_genuine) + edm::LogVerbatim("Tracklet") << " (is genuine)"; + if (tmp_trk_unknown) + edm::LogVerbatim("Tracklet") << " (is unknown)"; + if (tmp_trk_combinatoric) + edm::LogVerbatim("Tracklet") << " (is combinatoric)"; + } + + m_trk_pt->push_back(tmp_trk_pt); + m_trk_eta->push_back(tmp_trk_eta); + m_trk_phi->push_back(tmp_trk_phi); + m_trk_z0->push_back(tmp_trk_z0); + if (L1Tk_nPar == 5) + m_trk_d0->push_back(tmp_trk_d0); + else + m_trk_d0->push_back(999.); + m_trk_chi2->push_back(tmp_trk_chi2); + m_trk_chi2rphi->push_back(tmp_trk_chi2rphi); + m_trk_chi2rz->push_back(tmp_trk_chi2rz); + m_trk_bendchi2->push_back(tmp_trk_bendchi2); + m_trk_nstub->push_back(tmp_trk_nstub); + m_trk_dhits->push_back(tmp_trk_dhits); + m_trk_lhits->push_back(tmp_trk_lhits); + m_trk_seed->push_back(tmp_trk_seed); + m_trk_hitpattern->push_back(tmp_trk_hitpattern); + m_trk_phiSector->push_back(tmp_trk_phiSector); + m_trk_genuine->push_back(tmp_trk_genuine); + m_trk_loose->push_back(tmp_trk_loose); + m_trk_unknown->push_back(tmp_trk_unknown); + m_trk_combinatoric->push_back(tmp_trk_combinatoric); + + // ---------------------------------------------------------------------------------------------- + // for studying the fake rate + // ---------------------------------------------------------------------------------------------- + + edm::Ptr my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(l1track_ptr); + + int myFake = 0; + + int myTP_pdgid = -999; + float myTP_pt = -999; + float myTP_eta = -999; + float myTP_phi = -999; + float myTP_z0 = -999; + float myTP_dxy = -999; + + if (my_tp.isNull()) + myFake = 0; + else { + int tmp_eventid = my_tp->eventId().event(); + + if (tmp_eventid > 0) + myFake = 2; + else + myFake = 1; + + myTP_pdgid = my_tp->pdgId(); + myTP_pt = my_tp->p4().pt(); + myTP_eta = my_tp->p4().eta(); + myTP_phi = my_tp->p4().phi(); + myTP_z0 = my_tp->vertex().z(); + + float myTP_x0 = my_tp->vertex().x(); + float myTP_y0 = my_tp->vertex().y(); + myTP_dxy = sqrt(myTP_x0 * myTP_x0 + myTP_y0 * myTP_y0); + + if (DebugMode) { + edm::LogVerbatim("Tracklet") << "TP matched to track has pt = " << my_tp->p4().pt() + << " eta = " << my_tp->momentum().eta() << " phi = " << my_tp->momentum().phi() + << " z0 = " << my_tp->vertex().z() << " pdgid = " << my_tp->pdgId() + << " dxy = " << myTP_dxy; + } + } + + m_trk_fake->push_back(myFake); + + m_trk_matchtp_pdgid->push_back(myTP_pdgid); + m_trk_matchtp_pt->push_back(myTP_pt); + m_trk_matchtp_eta->push_back(myTP_eta); + m_trk_matchtp_phi->push_back(myTP_phi); + m_trk_matchtp_z0->push_back(myTP_z0); + m_trk_matchtp_dxy->push_back(myTP_dxy); + + // ---------------------------------------------------------------------------------------------- + // for tracking in jets + // ---------------------------------------------------------------------------------------------- + + if (TrackingInJets) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "doing tracking in jets now"; + + int InJet = 0; + int InJetHighpt = 0; + int InJetVeryHighpt = 0; + + for (int ij = 0; ij < (int)v_jets.size(); ij++) { + float deta = tmp_trk_eta - (v_jets.at(ij)).eta(); + float dphi = tmp_trk_phi - (v_jets.at(ij)).phi(); + while (dphi > 3.14159) + dphi = std::abs(2 * 3.14159 - dphi); + float dR = sqrt(deta * deta + dphi * dphi); + + if (dR < 0.4) { + InJet = 1; + if (v_jets_highpt.at(ij) == 1) + InJetHighpt = 1; + if (v_jets_vhighpt.at(ij) == 1) + InJetVeryHighpt = 1; + if (ij < NJETS) + jets_trk_sumpt[ij] += tmp_trk_pt; + } + } + + m_trk_injet->push_back(InJet); + m_trk_injet_highpt->push_back(InJetHighpt); + m_trk_injet_vhighpt->push_back(InJetVeryHighpt); + + } //end tracking in jets + + } //end track loop + + } //end if SaveAllTracks + + // ---------------------------------------------------------------------------------------------- + // loop over tracking particles + // ---------------------------------------------------------------------------------------------- + + if (DebugMode) + edm::LogVerbatim("Tracklet") << "\n Loop over tracking particles!"; + + int this_tp = 0; + std::vector::const_iterator iterTP; + for (iterTP = TrackingParticleHandle->begin(); iterTP != TrackingParticleHandle->end(); ++iterTP) { + edm::Ptr tp_ptr(TrackingParticleHandle, this_tp); + this_tp++; + + int tmp_eventid = iterTP->eventId().event(); + if (MyProcess != 1 && tmp_eventid > 0) + continue; //only care about tracking particles from the primary interaction (except for MyProcess==1, i.e. looking at all TPs) + + float tmp_tp_pt = iterTP->pt(); + float tmp_tp_eta = iterTP->eta(); + float tmp_tp_phi = iterTP->phi(); + float tmp_tp_vz = iterTP->vz(); + float tmp_tp_vx = iterTP->vx(); + float tmp_tp_vy = iterTP->vy(); + int tmp_tp_pdgid = iterTP->pdgId(); + float tmp_tp_z0_prod = tmp_tp_vz; + float tmp_tp_d0_prod = tmp_tp_vx * sin(tmp_tp_phi) - tmp_tp_vy * cos(tmp_tp_phi); + + if (MyProcess == 13 && abs(tmp_tp_pdgid) != 13) + continue; + if (MyProcess == 11 && abs(tmp_tp_pdgid) != 11) + continue; + if ((MyProcess == 6 || MyProcess == 15 || MyProcess == 211) && abs(tmp_tp_pdgid) != 211) + continue; + + if (tmp_tp_pt < TP_minPt) + continue; + if (std::abs(tmp_tp_eta) > TP_maxEta) + continue; + + // ---------------------------------------------------------------------------------------------- + // get d0/z0 propagated back to the IP + + float tmp_tp_t = tan(2.0 * atan(1.0) - 2.0 * atan(exp(-tmp_tp_eta))); + + float delx = -tmp_tp_vx; + float dely = -tmp_tp_vy; + + float A = 0.01 * 0.5696; + float Kmagnitude = A / tmp_tp_pt; + + float tmp_tp_charge = tp_ptr->charge(); + float K = Kmagnitude * tmp_tp_charge; + float d = 0; + + float tmp_tp_x0p = delx - (d + 1. / (2. * K) * sin(tmp_tp_phi)); + float tmp_tp_y0p = dely + (d + 1. / (2. * K) * cos(tmp_tp_phi)); + float tmp_tp_rp = sqrt(tmp_tp_x0p * tmp_tp_x0p + tmp_tp_y0p * tmp_tp_y0p); + float tmp_tp_d0 = tmp_tp_charge * tmp_tp_rp - (1. / (2. * K)); + + tmp_tp_d0 = tmp_tp_d0 * (-1); //fix d0 sign + + static double pi = 4.0 * atan(1.0); + float delphi = tmp_tp_phi - atan2(-K * tmp_tp_x0p, K * tmp_tp_y0p); + if (delphi < -pi) + delphi += 2.0 * pi; + if (delphi > pi) + delphi -= 2.0 * pi; + float tmp_tp_z0 = tmp_tp_vz + tmp_tp_t * delphi / (2.0 * K); + // ---------------------------------------------------------------------------------------------- + + if (std::abs(tmp_tp_z0) > TP_maxZ0) + continue; + + // for pions in ttbar, only consider TPs coming from near the IP! + float dxy = sqrt(tmp_tp_vx * tmp_tp_vx + tmp_tp_vy * tmp_tp_vy); + float tmp_tp_dxy = dxy; + if (MyProcess == 6 && (dxy > 1.0)) + continue; + + if (DebugMode) + edm::LogVerbatim("Tracklet") << "Tracking particle, pt: " << tmp_tp_pt << " eta: " << tmp_tp_eta + << " phi: " << tmp_tp_phi << " z0: " << tmp_tp_z0 << " d0: " << tmp_tp_d0 + << " z_prod: " << tmp_tp_z0_prod << " d_prod: " << tmp_tp_d0_prod + << " pdgid: " << tmp_tp_pdgid << " eventID: " << iterTP->eventId().event() + << " ttclusters " << MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr).size() + << " ttstubs " << MCTruthTTStubHandle->findTTStubRefs(tp_ptr).size() << " tttracks " + << MCTruthTTTrackHandle->findTTTrackPtrs(tp_ptr).size(); + + // ---------------------------------------------------------------------------------------------- + // only consider TPs associated with >= 1 cluster, or >= X stubs, or have stubs in >= X layers (configurable options) + + if (MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr).empty()) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "No matching TTClusters for TP, continuing..."; + continue; + } + + std::vector >, TTStub > > + theStubRefs = MCTruthTTStubHandle->findTTStubRefs(tp_ptr); + int nStubTP = (int)theStubRefs.size(); + + // how many layers/disks have stubs? + int hasStubInLayer[11] = {0}; + for (auto& theStubRef : theStubRefs) { + DetId detid(theStubRef->getDetId()); + + int layer = -1; + if (detid.subdetId() == StripSubdetector::TOB) { + layer = static_cast(tTopo->layer(detid)) - 1; //fill in array as entries 0-5 + } else if (detid.subdetId() == StripSubdetector::TID) { + layer = static_cast(tTopo->layer(detid)) + 5; //fill in array as entries 6-10 + } + + //bool isPS = (theTrackerGeom->getDetectorType(detid)==TrackerGeometry::ModuleType::Ph2PSP); + + //treat genuine stubs separately (==2 is genuine, ==1 is not) + if (MCTruthTTStubHandle->findTrackingParticlePtr(theStubRef).isNull() && hasStubInLayer[layer] < 2) + hasStubInLayer[layer] = 1; + else + hasStubInLayer[layer] = 2; + } + + int nStubLayerTP = 0; + int nStubLayerTP_g = 0; + for (int isum : hasStubInLayer) { + if (isum >= 1) + nStubLayerTP += 1; + if (isum == 2) + nStubLayerTP_g += 1; + } + + if (DebugMode) + edm::LogVerbatim("Tracklet") << "TP is associated with " << nStubTP << " stubs, and has stubs in " << nStubLayerTP + << " different layers/disks, and has GENUINE stubs in " << nStubLayerTP_g + << " layers "; + + if (TP_minNStub > 0) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "Only consider TPs with >= " << TP_minNStub << " stubs"; + if (nStubTP < TP_minNStub) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "TP fails minimum nbr stubs requirement! Continuing..."; + continue; + } + } + if (TP_minNStubLayer > 0) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "Only consider TPs with stubs in >= " << TP_minNStubLayer << " layers/disks"; + if (nStubLayerTP < TP_minNStubLayer) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "TP fails stubs in minimum nbr of layers/disks requirement! Continuing..."; + continue; + } + } + + // ---------------------------------------------------------------------------------------------- + // look for L1 tracks matched to the tracking particle + + std::vector > > matchedTracks = + MCTruthTTTrackHandle->findTTTrackPtrs(tp_ptr); + + int nMatch = 0; + int i_track = -1; + float i_chi2dof = 99999; + + if (!matchedTracks.empty()) { + if (DebugMode && (matchedTracks.size() > 1)) + edm::LogVerbatim("Tracklet") << "TrackingParticle has more than one matched L1 track!"; + + // ---------------------------------------------------------------------------------------------- + // loop over matched L1 tracks + // here, "match" means tracks that can be associated to a TrackingParticle with at least one hit of at least one of its clusters + // https://twiki.cern.ch/twiki/bin/viewauth/CMS/SLHCTrackerTriggerSWTools#MC_truth_for_TTTrack + + for (int it = 0; it < (int)matchedTracks.size(); it++) { + bool tmp_trk_genuine = false; + bool tmp_trk_loosegenuine = false; + if (MCTruthTTTrackHandle->isGenuine(matchedTracks.at(it))) + tmp_trk_genuine = true; + if (MCTruthTTTrackHandle->isLooselyGenuine(matchedTracks.at(it))) + tmp_trk_loosegenuine = true; + if (!tmp_trk_loosegenuine) + continue; + + if (DebugMode) { + if (MCTruthTTTrackHandle->findTrackingParticlePtr(matchedTracks.at(it)).isNull()) { + edm::LogVerbatim("Tracklet") << "track matched to TP is NOT uniquely matched to a TP"; + } else { + edm::Ptr my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(matchedTracks.at(it)); + edm::LogVerbatim("Tracklet") << "TP matched to track matched to TP ... tp pt = " << my_tp->p4().pt() + << " eta = " << my_tp->momentum().eta() << " phi = " << my_tp->momentum().phi() + << " z0 = " << my_tp->vertex().z(); + } + edm::LogVerbatim("Tracklet") << " ... matched L1 track has pt = " << matchedTracks.at(it)->momentum().perp() + << " eta = " << matchedTracks.at(it)->momentum().eta() + << " phi = " << matchedTracks.at(it)->momentum().phi() + << " chi2 = " << matchedTracks.at(it)->chi2() + << " consistency = " << matchedTracks.at(it)->stubPtConsistency() + << " z0 = " << matchedTracks.at(it)->z0() + << " nstub = " << matchedTracks.at(it)->getStubRefs().size(); + if (tmp_trk_genuine) + edm::LogVerbatim("Tracklet") << " (genuine!) "; + if (tmp_trk_loosegenuine) + edm::LogVerbatim("Tracklet") << " (loose genuine!) "; + } + + // ---------------------------------------------------------------------------------------------- + // further require L1 track to be (loosely) genuine, that there is only one TP matched to the track + // + have >= L1Tk_minNStub stubs for it to be a valid match (only relevant is your track collection + // e.g. stores 3-stub tracks but at plot level you require >= 4 stubs (--> tracklet case) + + std::vector >, TTStub > > + stubRefs = matchedTracks.at(it)->getStubRefs(); + int tmp_trk_nstub = stubRefs.size(); + + if (tmp_trk_nstub < L1Tk_minNStub) + continue; + + /* + // PS stubs + int tmp_trk_nPSstub = 0; + for (int is=0; isidToDet( (stubRefs.at(is)->clusterRef(0))->getDetId() )->geographicalId(); + DetId stackDetid = tTopo->stack(detIdStub); + bool isPS = (theTrackerGeom->getDetectorType(stackDetid)==TrackerGeometry::ModuleType::Ph2PSP); + if (isPS) tmp_trk_nPSstub++; + } + */ + + float dmatch_pt = 999; + float dmatch_eta = 999; + float dmatch_phi = 999; + int match_id = 999; + + edm::Ptr my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(matchedTracks.at(it)); + dmatch_pt = std::abs(my_tp->p4().pt() - tmp_tp_pt); + dmatch_eta = std::abs(my_tp->p4().eta() - tmp_tp_eta); + dmatch_phi = std::abs(my_tp->p4().phi() - tmp_tp_phi); + match_id = my_tp->pdgId(); + + float tmp_trk_chi2dof = (matchedTracks.at(it)->chi2()) / (2 * tmp_trk_nstub - L1Tk_nPar); + + // ensure that track is uniquely matched to the TP we are looking at! + if (dmatch_pt < 0.1 && dmatch_eta < 0.1 && dmatch_phi < 0.1 && tmp_tp_pdgid == match_id && tmp_trk_genuine) { + nMatch++; + if (i_track < 0 || tmp_trk_chi2dof < i_chi2dof) { + i_track = it; + i_chi2dof = tmp_trk_chi2dof; + } + } + + } // end loop over matched L1 tracks + + } // end has at least 1 matched L1 track + // ---------------------------------------------------------------------------------------------- + + float tmp_matchtrk_pt = -999; + float tmp_matchtrk_eta = -999; + float tmp_matchtrk_phi = -999; + float tmp_matchtrk_z0 = -999; + float tmp_matchtrk_d0 = -999; + float tmp_matchtrk_chi2 = -999; + float tmp_matchtrk_chi2rphi = -999; + float tmp_matchtrk_chi2rz = -999; + float tmp_matchtrk_bendchi2 = -999; + int tmp_matchtrk_nstub = -999; + int tmp_matchtrk_dhits = -999; + int tmp_matchtrk_lhits = -999; + int tmp_matchtrk_seed = -999; + int tmp_matchtrk_hitpattern = -999; + + if (nMatch > 1 && DebugMode) + edm::LogVerbatim("Tracklet") << "WARNING *** 2 or more matches to genuine L1 tracks ***"; + + if (nMatch > 0) { + tmp_matchtrk_pt = matchedTracks.at(i_track)->momentum().perp(); + tmp_matchtrk_eta = matchedTracks.at(i_track)->momentum().eta(); + tmp_matchtrk_phi = matchedTracks.at(i_track)->momentum().phi(); + tmp_matchtrk_z0 = matchedTracks.at(i_track)->z0(); + + if (L1Tk_nPar == 5) { + float tmp_matchtrk_x0 = matchedTracks.at(i_track)->POCA().x(); + float tmp_matchtrk_y0 = matchedTracks.at(i_track)->POCA().y(); + tmp_matchtrk_d0 = -tmp_matchtrk_x0 * sin(tmp_matchtrk_phi) + tmp_matchtrk_y0 * cos(tmp_matchtrk_phi); + } + + tmp_matchtrk_chi2 = matchedTracks.at(i_track)->chi2(); + tmp_matchtrk_chi2rphi = matchedTracks.at(i_track)->chi2XY(); + tmp_matchtrk_chi2rz = matchedTracks.at(i_track)->chi2Z(); + tmp_matchtrk_bendchi2 = matchedTracks.at(i_track)->stubPtConsistency(); + tmp_matchtrk_nstub = (int)matchedTracks.at(i_track)->getStubRefs().size(); + tmp_matchtrk_seed = (int)matchedTracks.at(i_track)->trackSeedType(); + tmp_matchtrk_hitpattern = (int)matchedTracks.at(i_track)->hitPattern(); + + // ------------------------------------------------------------------------------------------ + + //float tmp_matchtrk_bend_chi2 = 0; + + tmp_matchtrk_dhits = 0; + tmp_matchtrk_lhits = 0; + + std::vector >, TTStub > > + stubRefs = matchedTracks.at(i_track)->getStubRefs(); + int tmp_nstub = stubRefs.size(); + + for (int is = 0; is < tmp_nstub; is++) { + DetId detIdStub = theTrackerGeom->idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); + /* + MeasurementPoint coords = stubRefs.at(is)->clusterRef(0)->findAverageLocalCoordinatesCentered(); + const GeomDet* theGeomDet = theTrackerGeom->idToDet(detIdStub); + Global3DPoint posStub = theGeomDet->surface().toGlobal( theGeomDet->topology().localPosition(coords) ); + */ + + int layer = -999999; + if (detIdStub.subdetId() == StripSubdetector::TOB) { + layer = static_cast(tTopo->layer(detIdStub)); + tmp_matchtrk_lhits += pow(10, layer - 1); + } else if (detIdStub.subdetId() == StripSubdetector::TID) { + layer = static_cast(tTopo->layer(detIdStub)); + tmp_matchtrk_dhits += pow(10, layer - 1); + } + + // ------------------------------------------------------------------------------------------ + } + } + + m_tp_pt->push_back(tmp_tp_pt); + m_tp_eta->push_back(tmp_tp_eta); + m_tp_phi->push_back(tmp_tp_phi); + m_tp_dxy->push_back(tmp_tp_dxy); + m_tp_z0->push_back(tmp_tp_z0); + m_tp_d0->push_back(tmp_tp_d0); + m_tp_z0_prod->push_back(tmp_tp_z0_prod); + m_tp_d0_prod->push_back(tmp_tp_d0_prod); + m_tp_pdgid->push_back(tmp_tp_pdgid); + m_tp_nmatch->push_back(nMatch); + m_tp_nstub->push_back(nStubTP); + m_tp_eventid->push_back(tmp_eventid); + m_tp_charge->push_back(tmp_tp_charge); + + m_matchtrk_pt->push_back(tmp_matchtrk_pt); + m_matchtrk_eta->push_back(tmp_matchtrk_eta); + m_matchtrk_phi->push_back(tmp_matchtrk_phi); + m_matchtrk_z0->push_back(tmp_matchtrk_z0); + m_matchtrk_d0->push_back(tmp_matchtrk_d0); + m_matchtrk_chi2->push_back(tmp_matchtrk_chi2); + m_matchtrk_chi2rphi->push_back(tmp_matchtrk_chi2rphi); + m_matchtrk_chi2rz->push_back(tmp_matchtrk_chi2rz); + m_matchtrk_bendchi2->push_back(tmp_matchtrk_bendchi2); + m_matchtrk_nstub->push_back(tmp_matchtrk_nstub); + m_matchtrk_dhits->push_back(tmp_matchtrk_dhits); + m_matchtrk_lhits->push_back(tmp_matchtrk_lhits); + m_matchtrk_seed->push_back(tmp_matchtrk_seed); + m_matchtrk_hitpattern->push_back(tmp_matchtrk_hitpattern); + + // ---------------------------------------------------------------------------------------------- + // for tracking in jets + // ---------------------------------------------------------------------------------------------- + + if (TrackingInJets) { + if (DebugMode) + edm::LogVerbatim("Tracklet") << "check if TP/matched track is within jet"; + + int tp_InJet = 0; + int matchtrk_InJet = 0; + int tp_InJetHighpt = 0; + int matchtrk_InJetHighpt = 0; + int tp_InJetVeryHighpt = 0; + int matchtrk_InJetVeryHighpt = 0; + + for (int ij = 0; ij < (int)v_jets.size(); ij++) { + float deta = tmp_tp_eta - (v_jets.at(ij)).eta(); + float dphi = tmp_tp_phi - (v_jets.at(ij)).phi(); + while (dphi > 3.14159) + dphi = std::abs(2 * 3.14159 - dphi); + float dR = sqrt(deta * deta + dphi * dphi); + if (dR < 0.4) { + tp_InJet = 1; + if (v_jets_highpt.at(ij) == 1) + tp_InJetHighpt = 1; + if (v_jets_vhighpt.at(ij) == 1) + tp_InJetVeryHighpt = 1; + if (ij < NJETS) + jets_tp_sumpt[ij] += tmp_tp_pt; + } + + if (nMatch > 0) { + deta = tmp_matchtrk_eta - (v_jets.at(ij)).eta(); + dphi = tmp_matchtrk_phi - (v_jets.at(ij)).phi(); + while (dphi > 3.14159) + dphi = std::abs(2 * 3.14159 - dphi); + dR = sqrt(deta * deta + dphi * dphi); + if (dR < 0.4) { + matchtrk_InJet = 1; + if (v_jets_highpt.at(ij) == 1) + matchtrk_InJetHighpt = 1; + if (v_jets_vhighpt.at(ij) == 1) + matchtrk_InJetVeryHighpt = 1; + if (ij < NJETS) + jets_matchtrk_sumpt[ij] += tmp_matchtrk_pt; + } + } + } + + m_tp_injet->push_back(tp_InJet); + m_tp_injet_highpt->push_back(tp_InJetHighpt); + m_tp_injet_vhighpt->push_back(tp_InJetVeryHighpt); + m_matchtrk_injet->push_back(matchtrk_InJet); + m_matchtrk_injet_highpt->push_back(matchtrk_InJetHighpt); + m_matchtrk_injet_vhighpt->push_back(matchtrk_InJetVeryHighpt); + + } //end TrackingInJets + + } //end loop tracking particles + + if (TrackingInJets) { + for (int ij = 0; ij < (int)v_jets.size(); ij++) { + if (ij < NJETS) { + m_jet_eta->push_back((v_jets.at(ij)).eta()); + m_jet_phi->push_back((v_jets.at(ij)).phi()); + m_jet_pt->push_back((v_jets.at(ij)).pt()); + m_jet_tp_sumpt->push_back(jets_tp_sumpt[ij]); + m_jet_trk_sumpt->push_back(jets_trk_sumpt[ij]); + m_jet_matchtrk_sumpt->push_back(jets_matchtrk_sumpt[ij]); + } + } + } + + eventTree->Fill(); + +} // end of analyze() + +/////////////////////////// +// DEFINE THIS AS A PLUG-IN +DEFINE_FWK_MODULE(L1TrackNtupleMaker); diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py new file mode 100644 index 0000000000000..c7f6f3786a354 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtupleMaker_cfg.py @@ -0,0 +1,206 @@ +############################################################ +# define basic process +############################################################ + +import FWCore.ParameterSet.Config as cms +import FWCore.Utilities.FileUtils as FileUtils +import os +process = cms.Process("L1TrackNtuple") + +############################################################ +# edit options here +############################################################ + +GEOMETRY = "D49" +L1TRKALGO = 'HYBRID' # L1 tracking algorithm: 'HYBRID' (baseline, 4par fit) or 'HYBRID_DISPLACED' (extended, 5par fit) + +WRITE_DATA = False + +############################################################ +# import standard configurations +############################################################ + +process.load('Configuration.StandardSequences.Services_cff') +process.load('Configuration.EventContent.EventContent_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') + +process.load('FWCore.MessageService.MessageLogger_cfi') +process.MessageLogger.categories.append('Tracklet') +process.MessageLogger.categories.append('L1track') +process.MessageLogger.Tracklet = cms.untracked.PSet(limit = cms.untracked.int32(-1)) + +if GEOMETRY == "D49": + print "using geometry " + GEOMETRY + " (tilted)" + process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') + process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +else: + print "this is not a valid geometry!!!" + +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', '') + + +############################################################ +# input and output +############################################################ + +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) + +# Get list of MC datasets from repo, or specify yourself. + +def getTxtFile(txtFileName): + return FileUtils.loadListFromFile(os.environ['CMSSW_BASE']+'/src/'+txtFileName) + +if GEOMETRY == "D49": + inputMC = ["/store/relval/CMSSW_11_1_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU25ns_110X_mcRun4_realistic_v2_2026D49PU200-v1/20000/F7BF4AED-51F1-9D47-B86D-6C3DDA134AB9.root"] + +else: + print "this is not a valid geometry!!!" + +process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring(*inputMC)) + +process.TFileService = cms.Service("TFileService", fileName = cms.string('TTbar_PU200_'+GEOMETRY+'.root'), closeFileFast = cms.untracked.bool(True)) +process.Timing = cms.Service("Timing", summaryOnly = cms.untracked.bool(True)) + + +############################################################ +# L1 tracking: remake stubs? +############################################################ + +#process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') +#from L1Trigger.TrackTrigger.TTStubAlgorithmRegister_cfi import * +#process.load("SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff") + +#from SimTracker.TrackTriggerAssociation.TTClusterAssociation_cfi import * +#TTClusterAssociatorFromPixelDigis.digiSimLinks = cms.InputTag("simSiPixelDigis","Tracker") + +#process.TTClusterStub = cms.Path(process.TrackTriggerClustersStubs) +#process.TTClusterStubTruth = cms.Path(process.TrackTriggerAssociatorClustersStubs) + +############################################################ +# L1 tracking +############################################################ + +process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") + +# HYBRID: prompt tracking +if (L1TRKALGO == 'HYBRID'): + process.TTTracksEmulation = cms.Path(process.L1HybridTracks) + process.TTTracksEmulationWithTruth = cms.Path(process.L1HybridTracksWithAssociators) + NHELIXPAR = 4 + L1TRK_NAME = "TTTracksFromTrackletEmulation" + L1TRK_LABEL = "Level1TTTracks" + L1TRUTH_NAME = "TTTrackAssociatorFromPixelDigis" + +# HYBRID: extended tracking +elif (L1TRKALGO == 'HYBRID_DISPLACED'): + process.TTTracksEmulation = cms.Path(process.L1ExtendedHybridTracks) + process.TTTracksEmulationWithTruth = cms.Path(process.L1ExtendedHybridTracksWithAssociators) + NHELIXPAR = 5 + L1TRK_NAME = "TTTracksFromExtendedTrackletEmulation" + L1TRK_LABEL = "Level1TTTracks" + L1TRUTH_NAME = "TTTrackAssociatorFromPixelDigisExtended" + +# LEGACY ALGORITHM (EXPERTS ONLY): TRACKLET +elif (L1TRKALGO == 'TRACKLET'): + print "\n WARNING - this is not a recommended algorithm! Please use HYBRID (HYBRID_DISPLACED)!" + print "\n To run the tracklet-only algorithm, please ensure you have commented out #define USEHYBRID in interface/Settings.h + recompiled! \n" + process.TTTracksEmulation = cms.Path(process.L1HybridTracks) + process.TTTracksEmulationWithTruth = cms.Path(process.L1HybridTracksWithAssociators) + NHELIXPAR = 4 + L1TRK_NAME = "TTTracksFromTrackletEmulation" + L1TRK_LABEL = "Level1TTTracks" + L1TRUTH_NAME = "TTTrackAssociatorFromPixelDigis" + +# LEGACY ALGORITHM (EXPERTS ONLY): TMTT +elif (L1TRKALGO == 'TMTT'): + print "\n WARNING - this is not a recommended algorithm! Please use HYBRID (HYBRID_DISPLACED)! \n" + process.load("L1Trigger.TrackFindingTMTT.TMTrackProducer_Ultimate_cff") + L1TRK_PROC = process.TMTrackProducer + L1TRK_NAME = "TMTrackProducer" + L1TRK_LABEL = "TML1TracksKF4ParamsComb" + L1TRUTH_NAME = "TTTrackAssociatorFromPixelDigis" + NHELIXPAR = 4 + L1TRK_PROC.EnableMCtruth = cms.bool(False) # Reduce CPU use by disabling internal histos. + L1TRK_PROC.EnableHistos = cms.bool(False) + process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") + process.load("SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff") + process.TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag(L1TRK_NAME, L1TRK_LABEL) ) + process.TTTracksEmulation = cms.Path(process.offlineBeamSpot*L1TRK_PROC) + process.TTTracksEmulationWithTruth = cms.Path(process.offlineBeamSpot*L1TRK_PROC*process.TrackTriggerAssociatorTracks) + +else: + print "ERROR: Unknown L1TRKALGO option" + exit(1) + +############################################################ +# Define the track ntuple process, MyProcess is the (unsigned) PDGID corresponding to the process which is run +# e.g. single electron/positron = 11 +# single pion+/pion- = 211 +# single muon+/muon- = 13 +# pions in jets = 6 +# taus = 15 +# all TPs = 1 +############################################################ + +process.L1TrackNtuple = cms.EDAnalyzer('L1TrackNtupleMaker', + MyProcess = cms.int32(1), + DebugMode = cms.bool(False), # printout lots of debug statements + SaveAllTracks = cms.bool(True), # save *all* L1 tracks, not just truth matched to primary particle + SaveStubs = cms.bool(False), # save some info for *all* stubs + L1Tk_nPar = cms.int32(NHELIXPAR), # use 4 or 5-parameter L1 tracking? + L1Tk_minNStub = cms.int32(4), # L1 tracks with >= 4 stubs + TP_minNStub = cms.int32(4), # require TP to have >= X number of stubs associated with it + TP_minNStubLayer = cms.int32(4), # require TP to have stubs in >= X layers/disks + TP_minPt = cms.double(2.0), # only save TPs with pt > X GeV + TP_maxEta = cms.double(2.5), # only save TPs with |eta| < X + TP_maxZ0 = cms.double(30.0), # only save TPs with |z0| < X cm + L1TrackInputTag = cms.InputTag(L1TRK_NAME, L1TRK_LABEL), # TTTrack input + MCTruthTrackInputTag = cms.InputTag(L1TRUTH_NAME, L1TRK_LABEL), # MCTruth input + # other input collections + L1StubInputTag = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), + MCTruthClusterInputTag = cms.InputTag("TTClusterAssociatorFromPixelDigis", "ClusterAccepted"), + MCTruthStubInputTag = cms.InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted"), + TrackingParticleInputTag = cms.InputTag("mix", "MergedTrackTruth"), + TrackingVertexInputTag = cms.InputTag("mix", "MergedTrackTruth"), + # tracking in jets (--> requires AK4 genjet collection present!) + TrackingInJets = cms.bool(False), + GenJetInputTag = cms.InputTag("ak4GenJets", ""), + ) + +process.ana = cms.Path(process.L1TrackNtuple) + +# use this if you want to re-run the stub making +# process.schedule = cms.Schedule(process.TTClusterStub,process.TTClusterStubTruth,process.TTTracksEmulationWithTruth,process.ana) + +# use this if cluster/stub associators not available +# process.schedule = cms.Schedule(process.TTClusterStubTruth,process.TTTracksEmulationWithTruth,process.ana) + +# use this to only run tracking + track associator +process.schedule = cms.Schedule(process.TTTracksEmulationWithTruth,process.ana) + + +############################################################ +# write output dataset? +############################################################ + +if (WRITE_DATA): + process.writeDataset = cms.OutputModule("PoolOutputModule", + splitLevel = cms.untracked.int32(0), + eventAutoFlushCompressedSize = cms.untracked.int32(5242880), + outputCommands = process.RAWSIMEventContent.outputCommands, + fileName = cms.untracked.string('output_dataset.root'), ## ADAPT IT ## + dataset = cms.untracked.PSet( + filterName = cms.untracked.string(''), + dataTier = cms.untracked.string('GEN-SIM') + ) + ) + process.writeDataset.outputCommands.append('keep *TTTrack*_*_*_*') + process.writeDataset.outputCommands.append('keep *TTStub*_*_*_*') + + process.pd = cms.EndPath(process.writeDataset) + process.schedule.append(process.pd) + diff --git a/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C b/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C new file mode 100644 index 0000000000000..b3ab4660b0bd4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/L1TrackNtuplePlot.C @@ -0,0 +1,3747 @@ +// ---------------------------------------------------------------------------------------------------------------- +// Basic example ROOT script for making tracking performance plots using the ntuples produced by L1TrackNtupleMaker.cc +// +// e.g. in ROOT do: .L L1TrackNtuplePlot.C++, L1TrackNtuplePlot("TTbar_PU200_hybrid") +// +// By Louise Skinnari, June 2013 +// ---------------------------------------------------------------------------------------------------------------- + +#include "TROOT.h" +#include "TStyle.h" +#include "TLatex.h" +#include "TFile.h" +#include "TTree.h" +#include "TChain.h" +#include "TBranch.h" +#include "TLeaf.h" +#include "TCanvas.h" +#include "TLegend.h" +#include "TH1.h" +#include "TH2.h" +#include "TF1.h" +#include "TProfile.h" +#include "TProfile2D.h" +#include "TMath.h" +#include + +#include +#include +#include +#include + +using namespace std; + +void SetPlotStyle(); +void mySmallText(Double_t x, Double_t y, Color_t color, char* text); + +double getIntervalContainingFractionOfEntries(TH1* histogram, double interval, int minEntries = 5); +void makeResidualIntervalPlot( + TString type, TString dir, TString variable, TH1F* h_68, TH1F* h_90, TH1F* h_99, double minY, double maxY); + +// ---------------------------------------------------------------------------------------------------------------- +// Main script +// ---------------------------------------------------------------------------------------------------------------- + +void L1TrackNtuplePlot(TString type, + TString type_dir = "", + TString treeName = "", + int TP_select_injet = 0, + int TP_select_pdgid = 0, + int TP_select_eventid = 0, + bool useTightCuts = false, + bool useDeadRegion = false, + float TP_minPt = 2.0, + float TP_maxPt = 100.0, + float TP_maxEta = 2.4, + float TP_maxDxy = 1.0, + float TP_maxD0 = 1.0, + bool doDetailedPlots = false) { + // type: this is the name of the input file you want to process (minus ".root" extension) + // type_dir: this is the directory containing the input file you want to process. Note that this must end with a "/", as in "EventSets/" + // TP_select_pdgid: if non-zero, only select TPs with a given PDG ID + // TP_select_eventid: if zero, only look at TPs from primary interaction, else, include TPs from pileup + // TP_minPt: only look at TPs with pt > X GeV + // TP_maxPt: only look at TPs with pt < X GeV + // TP_maxEta: only look at TPs with |eta| < X + // doDetailedPlots: includes extra plots, such as performance vs d0. + + // TP_select_injet: only look at TPs that are within a jet with pt > 30 GeV (==1) or within a jet with pt > 100 GeV (==2), >200 GeV (==3) or all TPs (==0) + + //-- N.B. For standard displaced tracking plots, set TP_minPt=3.0, TP_maxEta=2.0, TP_maxDxy=10.0, + //-- TO_maxD0=10.0, doDetailedPlots=true. (Efficiency plots vs eta also usually made for d0 < 5). + + gROOT->SetBatch(); + gErrorIgnoreLevel = kWarning; + + SetPlotStyle(); + + // ---------------------------------------------------------------------------------------------------------------- + // define input options + + // these are the LOOSE cuts, baseline scenario for efficiency and rate plots ==> configure as appropriate + int L1Tk_minNstub = 4; + float L1Tk_maxChi2 = 999999; + float L1Tk_maxChi2dof = 999999.; + + // TIGHT cuts (separate plots / rates) ==> configure as appropriate + // this is currently set up as an either or for performance plots, to not duplicate a ton of code. + int L1Tk_TIGHT_minNstub = 4; + float L1Tk_TIGHT_maxChi2 = 999999; + float L1Tk_TIGHT_maxChi2dof = 999999.; + if (useTightCuts) { + L1Tk_minNstub = L1Tk_TIGHT_minNstub; + L1Tk_maxChi2 = L1Tk_TIGHT_maxChi2; + L1Tk_maxChi2dof = L1Tk_TIGHT_maxChi2dof; + } + + bool doGausFit = false; //do gaussian fit for resolution vs eta/pt plots + bool doLooseMatch = false; //looser MC truth matching + + // tracklet variables + int L1Tk_seed = 0; + + //some counters for integrated efficiencies + int n_all_eta2p5 = 0; + int n_all_eta1p75 = 0; + int n_all_eta1p0 = 0; + int n_match_eta2p5 = 0; + int n_match_eta1p75 = 0; + int n_match_eta1p0 = 0; + int n_all_ptg2 = 0; + int n_all_ptg8 = 0; + int n_all_pt2to8 = 0; + int n_all_ptg40 = 0; + int n_match_ptg2 = 0; + int n_match_ptg8 = 0; + int n_match_pt2to8 = 0; + int n_match_ptg40 = 0; + + // counters for total track rates + int ntrk_pt2 = 0; + int ntrk_pt3 = 0; + int ntrk_pt10 = 0; + int ntp_pt2 = 0; + int ntp_pt3 = 0; + int ntp_pt10 = 0; + + // ---------------------------------------------------------------------------------------------------------------- + // read ntuples + TChain* tree = new TChain("L1TrackNtuple" + treeName + "/eventTree"); + tree->Add(type_dir + type + ".root"); + + if (tree->GetEntries() == 0) { + cout << "File doesn't exist or is empty, returning..." + << endl; //cout's kept in this file as it is an example standalone plotting script, not running in central CMSSW + return; + } + + // ---------------------------------------------------------------------------------------------------------------- + // define leafs & branches + + // tracking particles + vector* tp_pt; + vector* tp_eta; + vector* tp_phi; + vector* tp_dxy; + vector* tp_z0; + vector* tp_d0; + vector* tp_pdgid; + vector* tp_nmatch; + vector* tp_nstub; + vector* tp_eventid; + vector* tp_injet; + vector* tp_injet_highpt; + vector* tp_injet_vhighpt; + + // *L1 track* properties, for tracking particles matched to a L1 track + vector* matchtrk_pt; + vector* matchtrk_eta; + vector* matchtrk_phi; + vector* matchtrk_d0; + vector* matchtrk_z0; + vector* matchtrk_chi2; + vector* matchtrk_chi2rphi; + vector* matchtrk_chi2rz; + vector* matchtrk_nstub; + vector* matchtrk_lhits; + vector* matchtrk_dhits; + vector* matchtrk_seed; + vector* matchtrk_hitpattern; + vector* matchtrk_injet; + vector* matchtrk_injet_highpt; + vector* matchtrk_injet_vhighpt; + + // all L1 tracks + vector* trk_pt; + vector* trk_eta; + vector* trk_phi; + vector* trk_chi2; + vector* trk_chi2rphi; + vector* trk_chi2rz; + vector* trk_nstub; + vector* trk_lhits; + vector* trk_dhits; + vector* trk_seed; + vector* trk_hitpattern; + vector* trk_phiSector; + vector* trk_injet; + vector* trk_injet_highpt; + vector* trk_injet_vhighpt; + vector* trk_fake; + vector* trk_genuine; + vector* trk_loose; + + TBranch* b_tp_pt; + TBranch* b_tp_eta; + TBranch* b_tp_phi; + TBranch* b_tp_dxy; + TBranch* b_tp_z0; + TBranch* b_tp_d0; + TBranch* b_tp_pdgid; + TBranch* b_tp_nmatch; + TBranch* b_tp_nstub; + TBranch* b_tp_eventid; + TBranch* b_tp_injet; + TBranch* b_tp_injet_highpt; + TBranch* b_tp_injet_vhighpt; + + TBranch* b_matchtrk_pt; + TBranch* b_matchtrk_eta; + TBranch* b_matchtrk_phi; + TBranch* b_matchtrk_d0; + TBranch* b_matchtrk_z0; + TBranch* b_matchtrk_chi2; + TBranch* b_matchtrk_chi2rphi; + TBranch* b_matchtrk_chi2rz; + TBranch* b_matchtrk_nstub; + TBranch* b_matchtrk_lhits; + TBranch* b_matchtrk_dhits; + TBranch* b_matchtrk_seed; + TBranch* b_matchtrk_hitpattern; + TBranch* b_matchtrk_injet; + TBranch* b_matchtrk_injet_highpt; + TBranch* b_matchtrk_injet_vhighpt; + + TBranch* b_trk_pt; + TBranch* b_trk_eta; + TBranch* b_trk_phi; + TBranch* b_trk_chi2; + TBranch* b_trk_chi2rphi; + TBranch* b_trk_chi2rz; + TBranch* b_trk_nstub; + TBranch* b_trk_lhits; + TBranch* b_trk_dhits; + TBranch* b_trk_phiSector; + TBranch* b_trk_seed; + TBranch* b_trk_hitpattern; + TBranch* b_trk_injet; + TBranch* b_trk_injet_highpt; + TBranch* b_trk_injet_vhighpt; + TBranch* b_trk_fake; + TBranch* b_trk_genuine; + TBranch* b_trk_loose; + + tp_pt = 0; + tp_eta = 0; + tp_phi = 0; + tp_dxy = 0; + tp_z0 = 0; + tp_d0 = 0; + tp_pdgid = 0; + tp_nmatch = 0; + tp_nstub = 0; + tp_eventid = 0; + tp_injet = 0; + tp_injet_highpt = 0; + tp_injet_vhighpt = 0; + + matchtrk_pt = 0; + matchtrk_eta = 0; + matchtrk_phi = 0; + matchtrk_d0 = 0; + matchtrk_z0 = 0; + matchtrk_chi2 = 0; + matchtrk_chi2rphi = 0; + matchtrk_chi2rz = 0; + matchtrk_nstub = 0; + matchtrk_lhits = 0; + matchtrk_dhits = 0; + matchtrk_seed = 0; + matchtrk_hitpattern = 0; + matchtrk_injet = 0; + matchtrk_injet_highpt = 0; + matchtrk_injet_vhighpt = 0; + + trk_pt = 0; + trk_eta = 0; + trk_phi = 0; + trk_chi2 = 0; + trk_chi2rphi = 0; + trk_chi2rz = 0; + trk_nstub = 0; + trk_lhits = 0; + trk_dhits = 0; + trk_phiSector = 0; + trk_seed = 0; + trk_hitpattern = 0; + trk_injet = 0; + trk_injet_highpt = 0; + trk_injet_vhighpt = 0; + trk_fake = 0; + trk_genuine = 0; + trk_loose = 0; + + tree->SetBranchAddress("tp_pt", &tp_pt, &b_tp_pt); + tree->SetBranchAddress("tp_eta", &tp_eta, &b_tp_eta); + tree->SetBranchAddress("tp_phi", &tp_phi, &b_tp_phi); + tree->SetBranchAddress("tp_dxy", &tp_dxy, &b_tp_dxy); + tree->SetBranchAddress("tp_z0", &tp_z0, &b_tp_z0); + tree->SetBranchAddress("tp_d0", &tp_d0, &b_tp_d0); + tree->SetBranchAddress("tp_pdgid", &tp_pdgid, &b_tp_pdgid); + if (doLooseMatch) + tree->SetBranchAddress("tp_nloosematch", &tp_nmatch, &b_tp_nmatch); + else + tree->SetBranchAddress("tp_nmatch", &tp_nmatch, &b_tp_nmatch); + tree->SetBranchAddress("tp_nstub", &tp_nstub, &b_tp_nstub); + tree->SetBranchAddress("tp_eventid", &tp_eventid, &b_tp_eventid); + if (TP_select_injet > 0) { + tree->SetBranchAddress("tp_injet", &tp_injet, &b_tp_injet); + tree->SetBranchAddress("tp_injet_highpt", &tp_injet_highpt, &b_tp_injet_highpt); + tree->SetBranchAddress("tp_injet_vhighpt", &tp_injet_vhighpt, &b_tp_injet_vhighpt); + } + + if (doLooseMatch) { + tree->SetBranchAddress("loosematchtrk_pt", &matchtrk_pt, &b_matchtrk_pt); + tree->SetBranchAddress("loosematchtrk_eta", &matchtrk_eta, &b_matchtrk_eta); + tree->SetBranchAddress("loosematchtrk_phi", &matchtrk_phi, &b_matchtrk_phi); + tree->SetBranchAddress("loosematchtrk_d0", &matchtrk_d0, &b_matchtrk_d0); + tree->SetBranchAddress("loosematchtrk_z0", &matchtrk_z0, &b_matchtrk_z0); + tree->SetBranchAddress("loosematchtrk_chi2", &matchtrk_chi2, &b_matchtrk_chi2); + tree->SetBranchAddress("loosematchtrk_chi2rphi", &matchtrk_chi2rphi, &b_matchtrk_chi2rphi); + tree->SetBranchAddress("loosematchtrk_chi2rz", &matchtrk_chi2rz, &b_matchtrk_chi2rz); + tree->SetBranchAddress("loosematchtrk_nstub", &matchtrk_nstub, &b_matchtrk_nstub); + tree->SetBranchAddress("loosematchtrk_seed", &matchtrk_seed, &b_matchtrk_seed); + tree->SetBranchAddress("loosematchtrk_hitpattern", &matchtrk_hitpattern, &b_matchtrk_hitpattern); + if (TP_select_injet > 0) { + tree->SetBranchAddress("loosematchtrk_injet", &matchtrk_injet, &b_matchtrk_injet); + tree->SetBranchAddress("loosematchtrk_injet_highpt", &matchtrk_injet_highpt, &b_matchtrk_injet_highpt); + tree->SetBranchAddress("loosematchtrk_injet_vhighpt", &matchtrk_injet_vhighpt, &b_matchtrk_injet_vhighpt); + } + } else { + tree->SetBranchAddress("matchtrk_pt", &matchtrk_pt, &b_matchtrk_pt); + tree->SetBranchAddress("matchtrk_eta", &matchtrk_eta, &b_matchtrk_eta); + tree->SetBranchAddress("matchtrk_phi", &matchtrk_phi, &b_matchtrk_phi); + tree->SetBranchAddress("matchtrk_d0", &matchtrk_d0, &b_matchtrk_d0); + tree->SetBranchAddress("matchtrk_z0", &matchtrk_z0, &b_matchtrk_z0); + tree->SetBranchAddress("matchtrk_chi2", &matchtrk_chi2, &b_matchtrk_chi2); + tree->SetBranchAddress("matchtrk_chi2rphi", &matchtrk_chi2rphi, &b_matchtrk_chi2rphi); + tree->SetBranchAddress("matchtrk_chi2rz", &matchtrk_chi2rz, &b_matchtrk_chi2rz); + tree->SetBranchAddress("matchtrk_nstub", &matchtrk_nstub, &b_matchtrk_nstub); + tree->SetBranchAddress("matchtrk_lhits", &matchtrk_lhits, &b_matchtrk_lhits); + tree->SetBranchAddress("matchtrk_dhits", &matchtrk_dhits, &b_matchtrk_dhits); + tree->SetBranchAddress("matchtrk_seed", &matchtrk_seed, &b_matchtrk_seed); + tree->SetBranchAddress("matchtrk_hitpattern", &matchtrk_hitpattern, &b_matchtrk_hitpattern); + if (TP_select_injet > 0) { + tree->SetBranchAddress("matchtrk_injet", &matchtrk_injet, &b_matchtrk_injet); + tree->SetBranchAddress("matchtrk_injet_highpt", &matchtrk_injet_highpt, &b_matchtrk_injet_highpt); + tree->SetBranchAddress("matchtrk_injet_vhighpt", &matchtrk_injet_vhighpt, &b_matchtrk_injet_vhighpt); + } + } + + tree->SetBranchAddress("trk_pt", &trk_pt, &b_trk_pt); + tree->SetBranchAddress("trk_eta", &trk_eta, &b_trk_eta); + tree->SetBranchAddress("trk_phi", &trk_phi, &b_trk_phi); + tree->SetBranchAddress("trk_chi2", &trk_chi2, &b_trk_chi2); + tree->SetBranchAddress("trk_chi2rphi", &trk_chi2rphi, &b_trk_chi2rphi); + tree->SetBranchAddress("trk_chi2rz", &trk_chi2rz, &b_trk_chi2rz); + tree->SetBranchAddress("trk_nstub", &trk_nstub, &b_trk_nstub); + tree->SetBranchAddress("trk_lhits", &trk_lhits, &b_trk_lhits); + tree->SetBranchAddress("trk_dhits", &trk_dhits, &b_trk_dhits); + tree->SetBranchAddress("trk_phiSector", &trk_phiSector, &b_trk_phiSector); + tree->SetBranchAddress("trk_seed", &trk_seed, &b_trk_seed); + tree->SetBranchAddress("trk_hitpattern", &trk_hitpattern, &b_trk_hitpattern); + tree->SetBranchAddress("trk_fake", &trk_fake, &b_trk_fake); + tree->SetBranchAddress("trk_genuine", &trk_genuine, &b_trk_genuine); + tree->SetBranchAddress("trk_loose", &trk_loose, &b_trk_loose); + if (TP_select_injet > 0) { + tree->SetBranchAddress("trk_injet", &trk_injet, &b_trk_injet); + tree->SetBranchAddress("trk_injet_highpt", &trk_injet_highpt, &b_trk_injet_highpt); + tree->SetBranchAddress("trk_injet_vhighpt", &trk_injet_vhighpt, &b_trk_injet_vhighpt); + } + + // ---------------------------------------------------------------------------------------------------------------- + // histograms + // ---------------------------------------------------------------------------------------------------------------- + + ///////////////////////////////////////////////// + // NOTATION: // + // 'C' - Central eta range, |eta|<0.8 // + // 'I' - Intermediate eta range, 0.8<|eta|<1.6 // + // 'F' - Forward eta range, |eta|>1.6 // + // // + // 'L' - Low pt range, pt<8 GeV // + // 'H' - High pt range, pt>8 GeV // + ///////////////////////////////////////////////// + + // ---------------------------------------------------------------------------------------------------------------- + // for efficiencies + + TH1F* h_tp_pt = new TH1F("tp_pt", ";Tracking particle p_{T} [GeV]; Tracking particles / 1.0 GeV", 100, 0, 100.0); + TH1F* h_tp_pt_L = new TH1F("tp_pt_L", ";Tracking particle p_{T} [GeV]; Tracking particles / 0.1 GeV", 80, 0, 8.0); + TH1F* h_tp_pt_LC = new TH1F("tp_pt_LC", ";Tracking particle p_{T} [GeV]; Tracking particles / 0.1 GeV", 80, 0, 8.0); + TH1F* h_tp_pt_H = new TH1F("tp_pt_H", ";Tracking particle p_{T} [GeV]; Tracking particles / 1.0 GeV", 92, 8.0, 100.0); + TH1F* h_tp_eta = new TH1F("tp_eta", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_tp_eta_L = new TH1F("tp_eta_L", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_tp_eta_H = new TH1F("tp_eta_H", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_tp_eta_23 = new TH1F("tp_eta_23", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_tp_eta_35 = new TH1F("tp_eta_35", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_tp_eta_5 = new TH1F("tp_eta_5", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + + TH1F* h_match_tp_pt = + new TH1F("match_tp_pt", ";Tracking particle p_{T} [GeV]; Tracking particles / 1.0 GeV", 100, 0, 100.0); + TH1F* h_match_tp_pt_L = + new TH1F("match_tp_pt_L", ";Tracking particle p_{T} [GeV]; Tracking particles / 0.1 GeV", 80, 0, 8.0); + TH1F* h_match_tp_pt_LC = + new TH1F("match_tp_pt_LC", ";Tracking particle p_{T} [GeV]; Tracking particles / 0.1 GeV", 80, 0, 8.0); + TH1F* h_match_tp_pt_H = + new TH1F("match_tp_pt_H", ";Tracking particle p_{T} [GeV]; Tracking particles / 0.1 GeV", 92, 8.0, 100.0); + TH1F* h_match_tp_eta = new TH1F("match_tp_eta", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_match_tp_eta_L = + new TH1F("match_tp_eta_L", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_match_tp_eta_H = + new TH1F("match_tp_eta_H", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_match_tp_eta_23 = + new TH1F("match_tp_eta_23", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_match_tp_eta_35 = + new TH1F("match_tp_eta_35", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + TH1F* h_match_tp_eta_5 = + new TH1F("match_tp_eta_5", ";Tracking particle #eta; Tracking particles / 0.1", 50, -2.5, 2.5); + + // ---------------------------------------------------------------------------------------------------------------- + // Tracklet propogation efficiencies vs. eta for seeding layers + + int trackletEffEtaBins = 24; + double trackletEffMaxEta = 2.4; + int numLayers = 11; + TH2F* h_trk_tracklet_hits = new TH2F("trk_tracklet_hits", + ";Track |#eta|; Layer index (0-5 = L1-6, 6-10 = D1-5)", + trackletEffEtaBins, + 0, + trackletEffMaxEta, + 11, + 0, + 11); //used to create below hist + TH2F* h_trk_tracklet_eff = new TH2F("trk_tracklet_eff", + ";Track |#eta|; Layer index (0-5 = L1-6, 6-10 = D1-5)", + trackletEffEtaBins, + 0, + trackletEffMaxEta, + 11, + 0, + 11); + + // ---------------------------------------------------------------------------------------------------------------- + // resolution vs. pt histograms + + // ---------------------------------------------- + // for new versions of resolution vs pt/eta plots + unsigned int nBinsPtRes = 500; + double maxPtRes = 30.; + + unsigned int nBinsPtRelRes = 1000; + double maxPtRelRes = 10.; + + unsigned int nBinsEtaRes = 500; + double maxEtaRes = 0.1; + + unsigned int nBinsPhiRes = 500; + double maxPhiRes = 0.2; + + unsigned int nBinsZ0Res = 100; + double maxZ0Res = 4.0; + // ---------------------------------------------- + + const int nRANGE = 20; + TString ptrange[nRANGE] = {"0-5", "5-10", "10-15", "15-20", "20-25", "25-30", "30-35", "35-40", "40-45", "45-50", + "50-55", "55-60", "60-65", "65-70", "70-75", "75-80", "80-85", "85-90", "90-95", "95-100"}; + + const int nRANGE_L = 12; + TString ptrange_L[nRANGE] = { + "2-2.5", "2.5-3", "3-3.5", "3.5-4", "4-4.5", "4.5-5", "5-5.5", "5.5-6", "6-6.5", "6.5-7", "7-7.5", "7.5-8"}; + + TH1F* h_absResVsPt_pt[nRANGE]; + TH1F* h_absResVsPt_ptRel[nRANGE]; + TH1F* h_absResVsPt_z0[nRANGE]; + TH1F* h_absResVsPt_phi[nRANGE]; + TH1F* h_absResVsPt_eta[nRANGE]; + TH1F* h_absResVsPt_d0[nRANGE]; + + TH1F* h_absResVsPt_pt_L[nRANGE_L]; + TH1F* h_absResVsPt_ptRel_L[nRANGE_L]; + TH1F* h_absResVsPt_z0_L[nRANGE_L]; + TH1F* h_absResVsPt_phi_L[nRANGE_L]; + TH1F* h_absResVsPt_eta_L[nRANGE_L]; + TH1F* h_absResVsPt_d0_L[nRANGE_L]; + + for (int i = 0; i < nRANGE; i++) { + h_absResVsPt_pt[i] = new TH1F( + "absResVsPt_pt_" + ptrange[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsPtRes, 0, maxPtRes); + h_absResVsPt_ptRel[i] = new TH1F("absResVsPt_ptRel_" + ptrange[i], + ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", + nBinsPtRelRes, + 0, + maxPtRelRes); + h_absResVsPt_z0[i] = new TH1F( + "absResVsPt_z0_" + ptrange[i], ";z_{0} residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsZ0Res, 0, maxZ0Res); + h_absResVsPt_phi[i] = new TH1F( + "absResVsPt_phi_" + ptrange[i], ";#phi residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsPhiRes, 0, maxPhiRes); + h_absResVsPt_eta[i] = new TH1F( + "absResVsPt_eta_" + ptrange[i], ";#eta residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsEtaRes, 0, maxEtaRes); + h_absResVsPt_d0[i] = + new TH1F("absResVsPt_d0_" + ptrange[i], ";d_{0}residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, 0, 0.02); + } + + for (int i = 0; i < nRANGE_L; i++) { + h_absResVsPt_pt_L[i] = new TH1F( + "absResVsPt_L_pt_" + ptrange_L[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsPtRes, 0, maxPtRes); + h_absResVsPt_ptRel_L[i] = new TH1F("absResVsPt_L_ptRel_" + ptrange_L[i], + ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", + nBinsPtRelRes, + 0, + maxPtRelRes); + h_absResVsPt_z0_L[i] = new TH1F( + "absResVsPt_L_z0_" + ptrange_L[i], ";z_{0} residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsZ0Res, 0, maxZ0Res); + h_absResVsPt_phi_L[i] = new TH1F("absResVsPt_L_phi_" + ptrange_L[i], + ";#phi residual (L1 - sim) [GeV]; L1 tracks / 0.1", + nBinsPhiRes, + 0, + maxPhiRes); + h_absResVsPt_eta_L[i] = new TH1F("absResVsPt_L_eta_" + ptrange_L[i], + ";#eta residual (L1 - sim) [GeV]; L1 tracks / 0.1", + nBinsEtaRes, + 0, + maxEtaRes); + h_absResVsPt_d0_L[i] = + new TH1F("absResVsPt_L_d0_" + ptrange_L[i], ";d_{0}residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, 0, 0.02); + } + + // resolution vs. eta histograms + + const int nETARANGE = 24; + TString etarange[nETARANGE] = {"0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0", "1.1", "1.2", + "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2.0", "2.1", "2.2", "2.3", "2.4"}; + /* + const int nETARANGE = 12; + TString etarange[nETARANGE] = {"0.2","0.4","0.6","0.8","1.0", + "1.2","1.4","1.6","1.8","2.0", + "2.2","2.4"}; + */ + + TH1F* h_absResVsEta_eta[nETARANGE]; + TH1F* h_absResVsEta_z0[nETARANGE]; + TH1F* h_absResVsEta_phi[nETARANGE]; + TH1F* h_absResVsEta_ptRel[nETARANGE]; + TH1F* h_absResVsEta_d0[nETARANGE]; + + TH1F* h_absResVsEta_eta_L[nETARANGE]; + TH1F* h_absResVsEta_z0_L[nETARANGE]; + TH1F* h_absResVsEta_phi_L[nETARANGE]; + TH1F* h_absResVsEta_ptRel_L[nETARANGE]; + TH1F* h_absResVsEta_d0_L[nETARANGE]; + + TH1F* h_absResVsEta_eta_H[nETARANGE]; + TH1F* h_absResVsEta_z0_H[nETARANGE]; + TH1F* h_absResVsEta_phi_H[nETARANGE]; + TH1F* h_absResVsEta_ptRel_H[nETARANGE]; + TH1F* h_absResVsEta_d0_H[nETARANGE]; + + for (int i = 0; i < nETARANGE; i++) { + h_absResVsEta_eta[i] = new TH1F( + "absResVsEta_eta_" + etarange[i], ";#eta residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsEtaRes, 0, maxEtaRes); + h_absResVsEta_z0[i] = new TH1F( + "absResVsEta_z0_" + etarange[i], ";|z_{0} residual (L1 - sim)| [cm]; L1 tracks / 0.01", nBinsZ0Res, 0, maxZ0Res); + h_absResVsEta_phi[i] = new TH1F( + "absResVsEta_phi_" + etarange[i], ";#phi residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsPhiRes, 0, maxPhiRes); + h_absResVsEta_ptRel[i] = new TH1F("absResVsEta_ptRel_" + etarange[i], + ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", + nBinsPtRelRes, + 0, + maxPtRelRes); + h_absResVsEta_d0[i] = + new TH1F("absResVsEta_d0_" + etarange[i], ";d_{0}residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, 0, 0.02); + + h_absResVsEta_eta_L[i] = new TH1F("absResVsEta_eta_L_" + etarange[i], + ";#eta residual (L1 - sim) [GeV]; L1 tracks / 0.1", + nBinsEtaRes, + 0, + maxEtaRes); + h_absResVsEta_z0_L[i] = new TH1F("absResVsEta_z0_L_" + etarange[i], + ";|z_{0} residual (L1 - sim)| [cm]; L1 tracks / 0.01", + nBinsZ0Res, + 0, + maxZ0Res); + h_absResVsEta_phi_L[i] = new TH1F("absResVsEta_phi_L_" + etarange[i], + ";#phi residual (L1 - sim) [GeV]; L1 tracks / 0.1", + nBinsPhiRes, + 0, + maxPhiRes); + h_absResVsEta_ptRel_L[i] = new TH1F("absResVsEta_ptRel_L_" + etarange[i], + ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", + nBinsPtRelRes, + 0, + maxPtRelRes); + h_absResVsEta_d0_L[i] = + new TH1F("absResVsEta_d0_L_" + etarange[i], ";d_{0}residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, 0, 0.02); + + h_absResVsEta_eta_H[i] = new TH1F("absResVsEta_eta_H_" + etarange[i], + ";#eta residual (L1 - sim) [GeV]; L1 tracks / 0.1", + nBinsEtaRes, + 0, + maxEtaRes); + h_absResVsEta_z0_H[i] = new TH1F("absResVsEta_z0_H_" + etarange[i], + ";|z_{0} residual (L1 - sim)| [cm]; L1 tracks / 0.01", + nBinsZ0Res, + 0, + maxZ0Res); + h_absResVsEta_phi_H[i] = new TH1F("absResVsEta_phi_H_" + etarange[i], + ";#phi residual (L1 - sim) [GeV]; L1 tracks / 0.1", + nBinsPhiRes, + 0, + maxPhiRes); + h_absResVsEta_ptRel_H[i] = new TH1F("absResVsEta_ptRel_H_" + etarange[i], + ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", + nBinsPtRelRes, + 0, + maxPtRelRes); + h_absResVsEta_d0_H[i] = + new TH1F("absResVsEta_d0_H_" + etarange[i], ";d_{0}residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, 0, 0.02); + } + + // resolution vs phi + + const int nPHIRANGE = 32; + TString phirange[nPHIRANGE] = {"-3.0", "-2.8", "-2.6", "-2.4", "-2.2", "-2.0", "-1.8", "-1.6", "-1.4", "-1.2", "-1.0", + "-0.8", "-0.6", "-0.4", "-0.2", "0.0", "0.2", "0.4", "0.6", "0.8", "1.0", "1.2", + "1.4", "1.6", "1.8", "2.0", "2.2", "2.4", "2.6", "2.8", "3.0", "3.2"}; + + TH1F* h_absResVsPhi_pt[nPHIRANGE]; + TH1F* h_absResVsPhi_ptRel[nPHIRANGE]; + + for (int i = 0; i < nPHIRANGE; i++) { + h_absResVsPhi_pt[i] = new TH1F( + "absResVsPt_pt_" + phirange[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", nBinsPtRes, 0, maxPtRes); + h_absResVsPhi_ptRel[i] = new TH1F("absResVsPt_ptRel_" + phirange[i], + ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", + nBinsPtRelRes, + 0, + maxPtRelRes); + } + + // ---------------------------------------------------------------------------------------------------------------- + // chi2 histograms (last bin is an overflow bin) + + TH1F* h_trk_chi2 = new TH1F("trk_chi2", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_trk_chi2_dof = new TH1F("trk_chi2_dof", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2 = new TH1F("match_trk_chi2", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2_dof = new TH1F("match_trk_chi2_dof", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + + TH1F* h_trk_chi2rphi = new TH1F("trk_chi2rphi", ";#chi^{2}_{r-#phi}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_trk_chi2rphi_dof = new TH1F("trk_chi2rphi_dof", ";#chi^{2}_{r-#phi} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2rphi = new TH1F("match_trk_chi2rphi", ";#chi^{2}_{r-#phi}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2rphi_dof = + new TH1F("match_trk_chi2rphi_dof", ";#chi^{2}_{r-#phi} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + + TH1F* h_trk_chi2rz = new TH1F("trk_chi2rz", ";#chi^{2}_{r-z}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_trk_chi2rz_dof = new TH1F("trk_chi2rz_dof", ";#chi^{2}_{r-z} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2rz = new TH1F("match_trk_chi2rz", ";#chi^{2}_{r-z}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2rz_dof = + new TH1F("match_trk_chi2rz_dof", ";#chi^{2}_{r-z} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + + // ---------------------------------------------------------------------------------------------------------------- + // total track rates + + TH1F* h_trk_all_vspt = new TH1F("trk_all_vspt", ";Track p_{T} [GeV]; ", 50, 0, 25); + TH1F* h_trk_loose_vspt = new TH1F("trk_loose_vspt", ";Track p_{T} [GeV]; ", 50, 0, 25); + TH1F* h_trk_genuine_vspt = new TH1F("trk_genuine_vspt", ";Track p_{T} [GeV]; ", 50, 0, 25); + TH1F* h_trk_notloose_vspt = new TH1F( + "trk_notloose_vspt", ";Track p_{T} [GeV]; ", 50, 0, 25); //(same as "fake" according to the trk_fake labeling) + TH1F* h_trk_notgenuine_vspt = new TH1F("trk_notgenuine_vspt", ";Track p_{T} [GeV]; ", 50, 0, 25); + TH1F* h_trk_duplicate_vspt = new TH1F("trk_duplicate_vspt", + ";Track p_{T} [GeV]; ", + 50, + 0, + 25); //where a TP is genuinely matched to more than one L1 track + TH1F* h_tp_vspt = new TH1F("tp_vspt", ";TP p_{T} [GeV]; ", 50, 0, 25); + + // ---------------------------------------------------------------------------------------------------------------- + + TH1F* h_tp_z0 = new TH1F("tp_z0", ";Tracking particle z_{0} [cm]; Tracking particles / 1.0 cm", 50, -25.0, 25.0); + TH1F* h_tp_z0_L = new TH1F("tp_z0_L", ";Tracking particle z_{0} [cm]; Tracking particles / 1.0 cm", 50, -25.0, 25.0); + TH1F* h_tp_z0_H = new TH1F("tp_z0_H", ";Tracking particle z_{0} [cm]; Tracking particles / 1.0 cm", 50, -25.0, 25.0); + + TH1F* h_match_tp_z0 = + new TH1F("match_tp_z0", ";Tracking particle z_{0} [cm]; Tracking particles / 1.0 cm", 50, -25.0, 25.0); + TH1F* h_match_tp_z0_L = + new TH1F("match_tp_z0_L", ";Tracking particle z_{0} [cm]; Tracking particles / 1.0 cm", 50, -25.0, 25.0); + TH1F* h_match_tp_z0_H = + new TH1F("match_tp_z0_H", ";Tracking particle z_{0} [cm]; Tracking particles / 1.0 cm", 50, -25.0, 25.0); + + // ---------------------------------------------------------------------------------------------------------------- + // + // ****************** additional histograms drawn if using 'detailed' option ****************** + // + // ---------------------------------------------------------------------------------------------------------------- + + const float maxD0plot = TP_maxD0; + + TH1F* h_tp_phi = new TH1F("tp_phi", ";Tracking particle #phi [rad]; Tracking particles / 0.1", 64, -3.2, 3.2); + TH1F* h_tp_d0 = + new TH1F("tp_d0", ";Tracking particle d_{0} [cm]; Tracking particles / 0.01 cm", 50, -maxD0plot, maxD0plot); + TH1F* h_tp_absd0 = + new TH1F("tp_absd0", ";Tracking particle |d_{0}| [cm]; Tracking particles / 0.04 cm", 50, 0, maxD0plot); + TH1F* h_tp_absd0_eta2 = + new TH1F("tp_absd0_eta2", ";Tracking particle |d_{0}| [cm]; Tracking particles / 0.04 cm", 50, 0, maxD0plot); + TH1F* h_tp_absd0_eta2_pt3 = + new TH1F("tp_absd0_eta2_pt3", ";Tracking particle |d_{0}| [cm]; Tracking particles / 0.04 cm", 50, 0, maxD0plot); + + TH1F* h_match_tp_phi = + new TH1F("match_tp_phi", ";Tracking particle #phi [rad]; Tracking particles / 0.1", 64, -3.2, 3.2); + TH1F* h_match_tp_d0 = + new TH1F("match_tp_d0", ";Tracking particle d_{0} [cm]; Tracking particles / 0.01 cm", 50, -maxD0plot, maxD0plot); + TH1F* h_match_tp_absd0 = + new TH1F("match_tp_absd0", ";Tracking particle d_{0} [cm]; Tracking particles / 0.04 cm", 50, 0, maxD0plot); + TH1F* h_match_tp_absd0_eta2 = + new TH1F("match_tp_absd0_eta2", ";Tracking particle d_{0} [cm]; Tracking particles / 0.04 cm", 50, 0, maxD0plot); + TH1F* h_match_tp_absd0_eta2_pt3 = new TH1F( + "match_tp_absd0_eta2_pt3", ";Tracking particle d_{0} [cm]; Tracking particles / 0.04 cm", 50, 0, maxD0plot); + + TH1F* h_match_trk_nstub = new TH1F("match_trk_nstub", ";Number of stubs; L1 tracks / 1.0", 15, 0, 15); + TH1F* h_match_trk_nstub_C = new TH1F("match_trk_nstub_C", ";Number of stubs; L1 tracks / 1.0", 15, 0, 15); + TH1F* h_match_trk_nstub_I = new TH1F("match_trk_nstub_I", ";Number of stubs; L1 tracks / 1.0", 15, 0, 15); + TH1F* h_match_trk_nstub_F = new TH1F("match_trk_nstub_F", ";Number of stubs; L1 tracks / 1.0", 15, 0, 15); + + // note that we are only making the below chi2 histograms using the joint chi2, not the separate chi2rphi and chi2rz + + // chi2 histograms + // note: last bin is an overflow bin + TH1F* h_match_trk_chi2_C_L = new TH1F("match_trk_chi2_C_L", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2_I_L = new TH1F("match_trk_chi2_I_L", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2_F_L = new TH1F("match_trk_chi2_F_L", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2_C_H = new TH1F("match_trk_chi2_C_H", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2_I_H = new TH1F("match_trk_chi2_I_H", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + TH1F* h_match_trk_chi2_F_H = new TH1F("match_trk_chi2_F_H", ";#chi^{2}; L1 tracks / 1.0", 100, 0, 100); + + // chi2/dof histograms + // note: lastbin is an overflow bin + TH1F* h_match_trk_chi2_dof_C_L = + new TH1F("match_trk_chi2_dof_C_L", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2_dof_I_L = + new TH1F("match_trk_chi2_dof_I_L", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2_dof_F_L = + new TH1F("match_trk_chi2_dof_F_L", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2_dof_C_H = + new TH1F("match_trk_chi2_dof_C_H", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2_dof_I_H = + new TH1F("match_trk_chi2_dof_I_H", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + TH1F* h_match_trk_chi2_dof_F_H = + new TH1F("match_trk_chi2_dof_F_H", ";#chi^{2} / D.O.F.; L1 tracks / 0.2", 100, 0, 20); + + // ---------------------------------------------------------------------------------------------------------------- + // resolution histograms + TH1F* h_res_pt = new TH1F("res_pt", ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.05", 200, -5.0, 5.0); + TH1F* h_res_ptRel = new TH1F("res_ptRel", ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.01", 200, -1.0, 1.0); + TH1F* h_res_eta = new TH1F("res_eta", ";#eta residual (L1 - sim); L1 tracks / 0.0002", 100, -0.01, 0.01); + TH1F* h_res_phi = new TH1F("res_phi", ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + + TH1F* h_res_z0 = new TH1F("res_z0", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1.0, 1.0); + TH1F* h_res_z0_C = new TH1F("res_z0_C", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1.0, 1.0); + TH1F* h_res_z0_I = new TH1F("res_z0_I", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1.0, 1.0); + TH1F* h_res_z0_F = new TH1F("res_z0_F", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1.0, 1.0); + TH1F* h_res_z0_L = new TH1F("res_z0_L", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1.0, 1.0); + TH1F* h_res_z0_H = new TH1F("res_z0_H", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1.0, 1.0); + + TH1F* h_res_z0_C_L = + new TH1F("res_z0_C_L", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, (-1) * 1.0, 1.0); + TH1F* h_res_z0_I_L = + new TH1F("res_z0_I_L", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, (-1) * 1.0, 1.0); + TH1F* h_res_z0_F_L = + new TH1F("res_z0_F_L", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, (-1) * 1.0, 1.0); + TH1F* h_res_z0_C_H = + new TH1F("res_z0_C_H", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, (-1) * 1.0, 1.0); + TH1F* h_res_z0_I_H = + new TH1F("res_z0_I_H", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, (-1) * 1.0, 1.0); + TH1F* h_res_z0_F_H = + new TH1F("res_z0_F_H", ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, (-1) * 1.0, 1.0); + + TH1F* h_res_d0 = new TH1F("res_d0", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0002 cm", 200, -0.02, 0.02); + TH1F* h_res_d0_C = new TH1F("res_d0_C", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_I = new TH1F("res_d0_I", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_F = new TH1F("res_d0_F", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_L = new TH1F("res_d0_L", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_H = new TH1F("res_d0_H", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + + TH1F* h_res_d0_C_L = + new TH1F("res_d0_C_L", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_I_L = + new TH1F("res_d0_I_L", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_F_L = + new TH1F("res_d0_F_L", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_C_H = + new TH1F("res_d0_C_H", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_I_H = + new TH1F("res_d0_I_H", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + TH1F* h_res_d0_F_H = + new TH1F("res_d0_F_H", ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0001 cm", 200, -0.05, 0.05); + + // ---------------------------------------------------------------------------------------------------------------- + // more resolution vs pt + + TH1F* h_resVsPt_pt[nRANGE]; + TH1F* h_resVsPt_pt_C[nRANGE]; + TH1F* h_resVsPt_pt_I[nRANGE]; + TH1F* h_resVsPt_pt_F[nRANGE]; + + TH1F* h_resVsPt_ptRel[nRANGE]; + TH1F* h_resVsPt_ptRel_C[nRANGE]; + TH1F* h_resVsPt_ptRel_I[nRANGE]; + TH1F* h_resVsPt_ptRel_F[nRANGE]; + + TH1F* h_resVsPt_z0[nRANGE]; + TH1F* h_resVsPt_z0_C[nRANGE]; + TH1F* h_resVsPt_z0_I[nRANGE]; + TH1F* h_resVsPt_z0_F[nRANGE]; + + TH1F* h_resVsPt_phi[nRANGE]; + TH1F* h_resVsPt_phi_C[nRANGE]; + TH1F* h_resVsPt_phi_I[nRANGE]; + TH1F* h_resVsPt_phi_F[nRANGE]; + + TH1F* h_resVsPt_eta[nRANGE]; + TH1F* h_resVsPt_d0[nRANGE]; + + for (int i = 0; i < nRANGE; i++) { + h_resVsPt_pt[i] = + new TH1F("resVsPt_pt_" + ptrange[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, -5.0, 5.0); + h_resVsPt_pt_C[i] = + new TH1F("resVsPt_pt_C_" + ptrange[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, -5.0, 5.0); + h_resVsPt_pt_I[i] = + new TH1F("resVsPt_pt_I_" + ptrange[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, -5.0, 5.0); + h_resVsPt_pt_F[i] = + new TH1F("resVsPt_pt_F_" + ptrange[i], ";p_{T} residual (L1 - sim) [GeV]; L1 tracks / 0.1", 100, -5.0, 5.0); + + h_resVsPt_ptRel[i] = new TH1F( + "resVsPt_ptRel_" + ptrange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", 300, -0.15, 0.15); + h_resVsPt_ptRel_C[i] = new TH1F( + "resVsPt_ptRel_c_" + ptrange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", 300, -0.15, 0.15); + h_resVsPt_ptRel_I[i] = new TH1F( + "resVsPt_ptRel_I_" + ptrange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", 300, -0.15, 0.15); + h_resVsPt_ptRel_F[i] = new TH1F( + "resVsPt_ptRel_F_" + ptrange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", 300, -0.15, 0.15); + + h_resVsPt_z0[i] = + new TH1F("resVsPt_z0_" + ptrange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1, 1); + h_resVsPt_z0_C[i] = + new TH1F("resVsPt_z0_C_" + ptrange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1, 1); + h_resVsPt_z0_I[i] = + new TH1F("resVsPt_z0_I_" + ptrange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1, 1); + h_resVsPt_z0_F[i] = + new TH1F("resVsPt_z0_F_" + ptrange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.02", 100, -1, 1); + + h_resVsPt_phi[i] = new TH1F( + "resVsPt_phi_" + ptrange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + h_resVsPt_phi_C[i] = new TH1F( + "resVsPt_phi_C_" + ptrange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + h_resVsPt_phi_I[i] = new TH1F( + "resVsPt_phi_I_" + ptrange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + h_resVsPt_phi_F[i] = new TH1F( + "resVsPt_phi_F_" + ptrange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + + h_resVsPt_eta[i] = + new TH1F("resVsPt_eta_" + ptrange[i], ";#eta residual (L1 - sim); L1 tracks / 0.0002", 100, -0.01, 0.01); + + h_resVsPt_d0[i] = + new TH1F("resVsPt_d0_" + ptrange[i], ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.0004", 100, -0.02, 0.02); + } + + // ---------------------------------------------------------------------------------------------------------------- + // more resolution vs eta + + TH1F* h_resVsEta_eta[nETARANGE]; + TH1F* h_resVsEta_eta_L[nETARANGE]; + TH1F* h_resVsEta_eta_H[nETARANGE]; + + TH1F* h_resVsEta_z0[nETARANGE]; + TH1F* h_resVsEta_z0_L[nETARANGE]; + TH1F* h_resVsEta_z0_H[nETARANGE]; + + TH1F* h_resVsEta_phi[nETARANGE]; + TH1F* h_resVsEta_phi_L[nETARANGE]; + TH1F* h_resVsEta_phi_H[nETARANGE]; + + TH1F* h_resVsEta_ptRel[nETARANGE]; + TH1F* h_resVsEta_ptRel_L[nETARANGE]; + TH1F* h_resVsEta_ptRel_H[nETARANGE]; + + TH1F* h_resVsEta_d0[nETARANGE]; + TH1F* h_resVsEta_d0_L[nETARANGE]; + TH1F* h_resVsEta_d0_H[nETARANGE]; + + for (int i = 0; i < nETARANGE; i++) { + h_resVsEta_eta[i] = + new TH1F("resVsEta2_eta_" + etarange[i], ";#eta residual (L1 - sim); L1 tracks / 0.0002", 100, -0.01, 0.01); + h_resVsEta_eta_L[i] = + new TH1F("resVsEta2_eta_L_" + etarange[i], ";#eta residual (L1 - sim); L1 tracks / 0.0002", 100, -0.01, 0.01); + h_resVsEta_eta_H[i] = + new TH1F("resVsEta2_eta_H_" + etarange[i], ";#eta residual (L1 - sim); L1 tracks / 0.0002", 100, -0.01, 0.01); + + h_resVsEta_z0[i] = + new TH1F("resVsEta2_z0_" + etarange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.01", 100, -1, 1); + h_resVsEta_z0_L[i] = + new TH1F("resVsEta2_z0_L_" + etarange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.01", 100, -1, 1); + h_resVsEta_z0_H[i] = + new TH1F("resVsEta2_z0_H_" + etarange[i], ";z_{0} residual (L1 - sim) [cm]; L1 tracks / 0.01", 100, -1, 1); + + h_resVsEta_phi[i] = new TH1F( + "resVsEta2_phi_" + etarange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + h_resVsEta_phi_L[i] = new TH1F( + "resVsEta2_phi_L_" + etarange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + h_resVsEta_phi_H[i] = new TH1F( + "resVsEta2_phi_H_" + etarange[i], ";#phi residual (L1 - sim) [rad]; L1 tracks / 0.0001", 100, -0.005, 0.005); + + h_resVsEta_ptRel[i] = new TH1F( + "resVsEta2_ptRel_" + etarange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.01", 100, -0.5, 0.5); + h_resVsEta_ptRel_L[i] = new TH1F( + "resVsEta2_ptRel_L_" + etarange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", 100, -0.1, 0.1); + h_resVsEta_ptRel_H[i] = new TH1F( + "resVsEta2_ptRel_H_" + etarange[i], ";p_{T} residual (L1 - sim) / p_{T}; L1 tracks / 0.02", 100, -0.25, 0.25); + + h_resVsEta_d0[i] = + new TH1F("resVsEta2_d0_" + etarange[i], ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.004", 100, -0.02, 0.02); + h_resVsEta_d0_L[i] = new TH1F( + "resVsEta2_d0_L_" + etarange[i], ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.004", 100, -0.02, 0.02); + h_resVsEta_d0_H[i] = new TH1F( + "resVsEta2_d0_H_" + etarange[i], ";d_{0} residual (L1 - sim) [cm]; L1 tracks / 0.004", 100, -0.02, 0.02); + } + // ---------------------------------------------------------------------------------------------------------------- + + // ---------------------------------------------------------------------------------------------------------------- + // additional ones for sum pt in jets + /* + TH1F* h_jet_tp_sumpt_vspt = new TH1F("jet_tp_sumpt_vspt", ";sum(TP p_{T}) [GeV]; Gen jets / 5.0 GeV", 20, 0, 200.0); + TH1F* h_jet_trk_sumpt_vspt = new TH1F("jet_trk_sumpt_vspt", ";sum(TP p_{T}) [GeV]; Gen jets / 5.0 GeV", 20, 0, 200.0); + TH1F* h_jet_matchtrk_sumpt_vspt = new TH1F("jet_matchtrk_sumpt_vspt", ";sum(TP p_{T}) [GeV]; Gen jets / 5.0 GeV", 20, 0, 200.0); + + TH1F* h_jet_tp_sumpt_vseta = new TH1F("jet_tp_sumpt_vseta", ";Gen jet #eta; Gen jets / 0.2", 24, -2.4, 2.4); + TH1F* h_jet_trk_sumpt_vseta = new TH1F("jet_trk_sumpt_vseta", ";Gen jet #eta; Gen jets / 0.2", 24, -2.4, 2.4); + TH1F* h_jet_matchtrk_sumpt_vseta = new TH1F("jet_matchtrk_sumpt_vseta", ";Gen jet #eta; Gen jets / 0.2", 24, -2.4, 2.4); + + h_jet_tp_sumpt_vseta->Sumw2(); + h_jet_tp_sumpt_vspt->Sumw2(); + h_jet_trk_sumpt_vseta->Sumw2(); + h_jet_trk_sumpt_vspt->Sumw2(); + h_jet_matchtrk_sumpt_vseta->Sumw2(); + h_jet_matchtrk_sumpt_vspt->Sumw2(); + */ + + // ---------------------------------------------------------------------------------------------------------------- + // number of tracks per event + + // all tracks + TH1F* h_ntrk_pt2 = new TH1F("ntrk_pt2", ";# tracks (p_{T} > 2 GeV) / event; Events", 400, 0, 400.0); + TH1F* h_ntrk_pt3 = new TH1F("ntrk_pt3", ";# tracks (p_{T} > 3 GeV) / event; Events", 300, 0, 300.0); + TH1F* h_ntrk_pt10 = new TH1F("ntrk_pt10", ";# tracks (p_{T} > 10 GeV) / event; Events", 100, 0, 100.0); + + // tracks flagged as genuine (this would include duplicates (?)) + TH1F* h_ntrk_genuine_pt2 = + new TH1F("ntrk_genuine_pt2", ";# genuine tracks (p_{T} > 2 GeV) / event; Events", 400, 0, 400.0); + TH1F* h_ntrk_genuine_pt3 = + new TH1F("ntrk_genuine_pt3", ";# genuine tracks (p_{T} > 3 GeV) / event; Events", 300, 0, 300.0); + TH1F* h_ntrk_genuine_pt10 = + new TH1F("ntrk_genuine_pt10", ";# genuine tracks (p_{T} > 10 GeV) / event; Events", 100, 0, 100.0); + + // Max N tracks from a sector per event + TH1F* h_ntrkPerSector_pt2 = + new TH1F("ntrkPerSector_pt2", ";Max. # tracks from a sector (p_{T} > 2 GeV) / event; Events", 50, 0, 100.0); + TH1F* h_ntrkPerSector_pt3 = + new TH1F("ntrkPerSector_pt3", ";Max. # tracks from a sector (p_{T} > 3 GeV) / event; Events", 50, 0, 100.0); + TH1F* h_ntrkPerSector_pt4 = + new TH1F("ntrkPerSector_pt4", ";Max. # tracks from a sector (p_{T} > 10 GeV) / event; Events", 50, 0, 100.0); + + // ---------------------------------------------------------------------------------------------------------------- + // * * * * * S T A R T O F A C T U A L R U N N I N G O N E V E N T S * * * * * + // ---------------------------------------------------------------------------------------------------------------- + + int nevt = tree->GetEntries(); + cout << "number of events = " << nevt << endl; + + // ---------------------------------------------------------------------------------------------------------------- + // event loop + for (int i = 0; i < nevt; i++) { + tree->GetEntry(i, 0); + + /* + // ---------------------------------------------------------------------------------------------------------------- + // sumpt in jets + if (TP_select_injet > 0) { + for (int ij=0; ij<(int)jet_tp_sumpt->size(); ij++) { + + float fraction = 0; + float fractionMatch = 0; + if (jet_tp_sumpt->at(ij) > 0) { + fraction = jet_trk_sumpt->at(ij)/jet_tp_sumpt->at(ij); + fractionMatch = jet_matchtrk_sumpt->at(ij)/jet_tp_sumpt->at(ij); + } + + h_jet_tp_sumpt_vspt->Fill(jet_tp_sumpt->at(ij),1.0); + h_jet_trk_sumpt_vspt->Fill(jet_tp_sumpt->at(ij),fraction); + h_jet_matchtrk_sumpt_vspt->Fill(jet_tp_sumpt->at(ij),fractionMatch); + + h_jet_tp_sumpt_vseta->Fill(jet_eta->at(ij),1.0); + h_jet_trk_sumpt_vseta->Fill(jet_eta->at(ij),fraction); + h_jet_matchtrk_sumpt_vseta->Fill(jet_eta->at(ij),fractionMatch); + } + } + */ + + // ---------------------------------------------------------------------------------------------------------------- + // track loop for total rates & fake rates. + + int ntrkevt_pt2 = 0; + int ntrkevt_pt3 = 0; + int ntrkevt_pt10 = 0; + + int ntrkevt_genuine_pt2 = 0; + int ntrkevt_genuine_pt3 = 0; + int ntrkevt_genuine_pt10 = 0; + + vector nTrksPerSector_pt2(9, 0); + vector nTrksPerSector_pt3(9, 0); + vector nTrksPerSector_pt4(9, 0); + + for (int it = 0; it < (int)trk_pt->size(); it++) { + // ---------------------------------------------------------------------------------------------------------------- + // track properties + + // fill all trk chi2 & chi2/dof histograms, including for chi2 r-phi and chi2 r-z + int ndof = 2 * trk_nstub->at(it) - 4; + float chi2 = trk_chi2->at(it); + float chi2dof = (float)chi2 / ndof; + float chi2rphi = trk_chi2rphi->at(it); + float chi2rphidof = (float)chi2rphi / ndof; + float chi2rz = trk_chi2rz->at(it); + float chi2rzdof = (float)chi2rz / ndof; + + // create overflow bins by restricting range of chi2 + int chi2Overflow = 100; + int chi2DOFOverflow = 20; //apprx chi2Overflow / avg. nstubs + double buffer = 0.1; + + if (chi2 > chi2Overflow) + chi2 = chi2Overflow - buffer; + if (chi2dof > chi2DOFOverflow) + chi2dof = chi2DOFOverflow - buffer; + if (chi2rphi > chi2Overflow) + chi2rphi = chi2Overflow - buffer; + if (chi2rphidof > chi2DOFOverflow) + chi2rphidof = chi2DOFOverflow - buffer; + if (chi2rz > chi2Overflow) + chi2rz = chi2Overflow - buffer; + if (chi2rzdof > chi2DOFOverflow) + chi2rzdof = chi2DOFOverflow - buffer; + + if (trk_pt->at(it) > TP_minPt) { //TRK pt > TP_minPt + + h_trk_chi2->Fill(chi2); + h_trk_chi2_dof->Fill(chi2dof); + + h_trk_chi2rphi->Fill(chi2rphi); + h_trk_chi2rphi_dof->Fill(chi2rphidof); + + h_trk_chi2rz->Fill(chi2rz); + h_trk_chi2rz_dof->Fill(chi2rzdof); + + } //end TRK pt > TP_minPt + + // ---------------------------------------------------------------------------------------------------------------- + // look at track rate and fake rate, etc. + + // only look at tracks in (ttbar) jets ? + if (TP_select_injet > 0) { + if (TP_select_injet == 1 && trk_injet->at(it) == 0) + continue; + if (TP_select_injet == 2 && trk_injet_highpt->at(it) == 0) + continue; + if (TP_select_injet == 3 && trk_injet_vhighpt->at(it) == 0) + continue; + } + + if (std::abs(trk_eta->at(it)) > TP_maxEta) + continue; + if (trk_pt->at(it) < TP_minPt) + continue; + + // Uncomment these cuts to see effect on rate & fake rate. + //int ndof = 2*trk_nstub->at(it)-4; + //if (trk_chi2->at(it) > L1Tk_maxChi2) continue; + //if (trk_chi2->at(it)/ndof > L1Tk_maxChi2dof) continue; + //if (trk_nstub->at(it) < L1Tk_minNstub) continue; + + // Tracklet & Hybrid have 9 sectors, but TMTT has 18 (with sectors 0 & 1 in nonant 0 etc). + // As don't know here with algo used, "% 9" added to prevent crash, but not correct for TMTT. + if (trk_pt->at(it) > 2.0) + ++nTrksPerSector_pt2.at(trk_phiSector->at(it) % 9); + if (trk_pt->at(it) > 3.0) + ++nTrksPerSector_pt3.at(trk_phiSector->at(it) % 9); + if (trk_pt->at(it) > 4.0) + ++nTrksPerSector_pt4.at(trk_phiSector->at(it) % 9); + + if (trk_pt->at(it) > 2.0) { + ntrk_pt2++; + ntrkevt_pt2++; + h_trk_all_vspt->Fill(trk_pt->at(it)); + if (trk_genuine->at(it) == 1) { + ntrkevt_genuine_pt2++; + h_trk_genuine_vspt->Fill(trk_pt->at(it)); + } else + h_trk_notgenuine_vspt->Fill(trk_pt->at(it)); + if (trk_loose->at(it) == 1) + h_trk_loose_vspt->Fill(trk_pt->at(it)); + else + h_trk_notloose_vspt->Fill(trk_pt->at(it)); + } + if (trk_pt->at(it) > 3.0) { + ntrk_pt3++; + ntrkevt_pt3++; + if (trk_genuine->at(it) == 1) + ntrkevt_genuine_pt3++; + } + if (trk_pt->at(it) > 10.0) { + ntrk_pt10++; + ntrkevt_pt10++; + if (trk_genuine->at(it) == 1) + ntrkevt_genuine_pt10++; + } + + // ---------------------------------------------------------------------------------------------------------------- + // Fill tracklet propogation efficiency histo + + // create an 11-bit long iterable from lhits and dhits + int num_layers = 6; + int num_discs = 5; + int lhits = trk_lhits->at(it); + int dhits = trk_dhits->at(it); + std::vector layers = {}; + for (int layer_index = 0; layer_index < num_layers + num_discs; layer_index++) { + if (layer_index < num_layers) { + layers.push_back(lhits % 10); + lhits /= 10; + } else { + layers.push_back(dhits % 10); + dhits /= 10; + } + } + + for (unsigned int layer = 0; layer < layers.size(); layer++) { + if (layers.at(layer)) { // if there was a hit at this layer... + h_trk_tracklet_hits->Fill(std::abs(trk_eta->at(it)), layer); // ...fill this bin with the layer of the track. + } + } + } + + h_ntrk_pt2->Fill(ntrkevt_pt2); + h_ntrk_pt3->Fill(ntrkevt_pt3); + h_ntrk_pt10->Fill(ntrkevt_pt10); + + h_ntrk_genuine_pt2->Fill(ntrkevt_genuine_pt2); + h_ntrk_genuine_pt3->Fill(ntrkevt_genuine_pt3); + h_ntrk_genuine_pt10->Fill(ntrkevt_genuine_pt10); + + h_ntrkPerSector_pt2->Fill(*std::max_element(nTrksPerSector_pt2.begin(), nTrksPerSector_pt2.end())); + h_ntrkPerSector_pt3->Fill(*std::max_element(nTrksPerSector_pt3.begin(), nTrksPerSector_pt3.end())); + h_ntrkPerSector_pt4->Fill(*std::max_element(nTrksPerSector_pt4.begin(), nTrksPerSector_pt4.end())); + + // ---------------------------------------------------------------------------------------------------------------- + // tracking particle loop + for (int it = 0; it < (int)tp_pt->size(); it++) { + // only look at TPs in (ttbar) jets ? + if (TP_select_injet > 0) { + if (TP_select_injet == 1 && tp_injet->at(it) == 0) + continue; + if (TP_select_injet == 2 && tp_injet_highpt->at(it) == 0) + continue; + if (TP_select_injet == 3 && tp_injet_vhighpt->at(it) == 0) + continue; + } + + // cut on PDG ID at plot stage? + if (TP_select_pdgid != 0) { + if (abs(tp_pdgid->at(it)) != abs(TP_select_pdgid)) + continue; + } + + // kinematic cuts + if (std::abs(tp_dxy->at(it)) > TP_maxDxy) + continue; + if (std::abs(tp_d0->at(it)) > TP_maxD0) + continue; + if (tp_pt->at(it) < 0.2) + continue; + if (tp_pt->at(it) > TP_maxPt) + continue; + if (std::abs(tp_eta->at(it)) > TP_maxEta) + continue; + + // total track rates + if (tp_pt->at(it) > TP_minPt) { + if (tp_pt->at(it) > 2.0) { + ntp_pt2++; + h_tp_vspt->Fill(tp_pt->at(it)); + // duplicate rate + if (tp_nmatch->at(it) > 1) { + for (int inm = 1; inm < tp_nmatch->at(it); inm++) + h_trk_duplicate_vspt->Fill(matchtrk_pt->at(it)); + } + } + if (tp_pt->at(it) > 3.0) + ntp_pt3++; + if (tp_pt->at(it) > 10.0) + ntp_pt10++; + } + + // cut on event ID (eventid=0 means the TP is from the primary interaction, so *not* selecting only eventid=0 means including stuff from pileup) + if (TP_select_eventid == 0 && tp_eventid->at(it) != 0) + continue; + + // look at failure scenarios? + if (useDeadRegion) { + if (tp_phi->at(it) < 0 || tp_phi->at(it) > 1) + continue; + } + + h_tp_pt->Fill(tp_pt->at(it)); + if (tp_pt->at(it) < 8.0) + h_tp_pt_L->Fill(tp_pt->at(it)); + else + h_tp_pt_H->Fill(tp_pt->at(it)); + if (tp_pt->at(it) < 8.0 && std::abs(tp_eta->at(it)) < 1.0) + h_tp_pt_LC->Fill(tp_pt->at(it)); + + if (tp_pt->at(it) > TP_minPt) { + if (std::abs(tp_eta->at(it)) < 1.0) + n_all_eta1p0++; + else if (std::abs(tp_eta->at(it)) < 1.75) + n_all_eta1p75++; + else + n_all_eta2p5++; + + if (std::abs(tp_pt->at(it)) > 2.0) + n_all_ptg2++; + if (std::abs(tp_pt->at(it)) > 2.0 && std::abs(tp_pt->at(it)) < 8.0) + n_all_pt2to8++; + if (std::abs(tp_pt->at(it)) > 8.0) + n_all_ptg8++; + if (std::abs(tp_pt->at(it)) > 40.0) + n_all_ptg40++; + + h_tp_eta->Fill(tp_eta->at(it)); + h_tp_phi->Fill(tp_phi->at(it)); + h_tp_z0->Fill(tp_z0->at(it)); + h_tp_d0->Fill(tp_d0->at(it)); + h_tp_absd0->Fill(std::abs(tp_d0->at(it))); + if (std::abs(tp_eta->at(it)) < 2.0) + h_tp_absd0_eta2->Fill(std::abs(tp_d0->at(it))); + if (std::abs(tp_eta->at(it)) < 2.0 && tp_pt->at(it) > 3.0) + h_tp_absd0_eta2_pt3->Fill(std::abs(tp_d0->at(it))); + + if (tp_pt->at(it) < 3.0) + h_tp_eta_23->Fill(tp_eta->at(it)); + else if (tp_pt->at(it) < 5.0) + h_tp_eta_35->Fill(tp_eta->at(it)); + else + h_tp_eta_5->Fill(tp_eta->at(it)); + + if (tp_pt->at(it) < 8.0) { + h_tp_eta_L->Fill(tp_eta->at(it)); + h_tp_z0_L->Fill(tp_z0->at(it)); + } else { + h_tp_eta_H->Fill(tp_eta->at(it)); + h_tp_z0_H->Fill(tp_z0->at(it)); + } + } + + // ---------------------------------------------------------------------------------------------------------------- + // was the tracking particle matched to a L1 track? + if (tp_nmatch->at(it) < 1) + continue; + + // ---------------------------------------------------------------------------------------------------------------- + // use only tracks with min X stubs + if (matchtrk_nstub->at(it) < L1Tk_minNstub) + continue; + + int thisseed = matchtrk_seed->at(it); + if (thisseed > 25) + thisseed = thisseed - 20; + if ((L1Tk_seed != 0) && (thisseed != L1Tk_seed)) + continue; + + // ---------------------------------------------------------------------------------------------------------------- + // fill matchtrk chi2 & chi2/dof histograms before making chi2 cut + + int ndof = 2 * matchtrk_nstub->at(it) - 4; + float chi2 = matchtrk_chi2->at(it); + float chi2dof = (float)chi2 / ndof; + float chi2rphi = matchtrk_chi2rphi->at(it); + float chi2rphidof = (float)chi2rphi / ndof; + float chi2rz = matchtrk_chi2rz->at(it); + float chi2rzdof = (float)chi2rz / ndof; + + // create overflow bins by restricting range of chi2 + int chi2Overflow = 100; + int chi2DOFOverflow = 20; //apprx chi2Overflow / avg. nstubs + double buffer = 0.1; + + if (chi2 > chi2Overflow) + chi2 = chi2Overflow - buffer; + if (chi2dof > chi2DOFOverflow) + chi2dof = chi2DOFOverflow - buffer; + if (chi2rphi > chi2Overflow) + chi2rphi = chi2Overflow - buffer; + if (chi2rphidof > chi2DOFOverflow) + chi2rphidof = chi2DOFOverflow - buffer; + if (chi2rz > chi2Overflow) + chi2rz = chi2Overflow - buffer; + if (chi2rzdof > chi2DOFOverflow) + chi2rzdof = chi2DOFOverflow - buffer; + + if (tp_pt->at(it) > TP_minPt) { //TP pt > TP_minPt + + h_match_trk_chi2->Fill(chi2); + h_match_trk_chi2_dof->Fill(chi2dof); + + h_match_trk_chi2rphi->Fill(chi2rphi); + h_match_trk_chi2rphi_dof->Fill(chi2rphidof); + + h_match_trk_chi2rz->Fill(chi2rz); + h_match_trk_chi2rz_dof->Fill(chi2rzdof); + + // central eta + if (std::abs(tp_eta->at(it)) < 0.8) { + if (tp_pt->at(it) < 8.0) { + h_match_trk_chi2_C_L->Fill(chi2); + h_match_trk_chi2_dof_C_L->Fill(chi2dof); + } else { + h_match_trk_chi2_C_H->Fill(chi2); + h_match_trk_chi2_dof_C_H->Fill(chi2dof); + } + } + // intermediate eta + else if (std::abs(tp_eta->at(it)) < 1.6 && std::abs(tp_eta->at(it)) >= 0.8) { + if (tp_pt->at(it) < 8.0) { + h_match_trk_chi2_I_L->Fill(chi2); + h_match_trk_chi2_dof_I_L->Fill(chi2dof); + } else { + h_match_trk_chi2_I_H->Fill(chi2); + h_match_trk_chi2_dof_I_H->Fill(chi2dof); + } + } + // forward eta + else if (std::abs(tp_eta->at(it)) >= 1.6) { + if (tp_pt->at(it) < 8.0) { + h_match_trk_chi2_F_L->Fill(chi2); + h_match_trk_chi2_dof_F_L->Fill(chi2dof); + } else { + h_match_trk_chi2_F_H->Fill(chi2); + h_match_trk_chi2_dof_F_H->Fill(chi2dof); + } + } + } //end TP pt > TP_minPt + + // ---------------------------------------------------------------------------------------------------------------- + // cut on chi2? + if (matchtrk_chi2->at(it) > L1Tk_maxChi2) + continue; + if (matchtrk_chi2->at(it) / ndof > L1Tk_maxChi2dof) + continue; + + // use tight quality cut selection? + /* + if (matchtrk_nstub->at(it)==4) { + if (std::abs(matchtrk_eta->at(it))<2.2 && matchtrk_consistency->at(it)>10) continue; + else if (std::abs(matchtrk_eta->at(it))>2.2 && chi2dof>5.0) continue; + } + if (matchtrk_pt->at(it)>10.0 && chi2dof>5.0) continue; + */ + + // ---------------------------------------------------------------------------------------------------------------- + // more plots + + // fill matched track histograms + h_match_tp_pt->Fill(tp_pt->at(it)); + if (tp_pt->at(it) < 8.0) + h_match_tp_pt_L->Fill(tp_pt->at(it)); + else + h_match_tp_pt_H->Fill(tp_pt->at(it)); + if (tp_pt->at(it) < 8.0 && std::abs(tp_eta->at(it)) < 1.0) + h_match_tp_pt_LC->Fill(tp_pt->at(it)); + + if (tp_pt->at(it) > TP_minPt) { + h_match_tp_eta->Fill(tp_eta->at(it)); + h_match_tp_phi->Fill(tp_phi->at(it)); + h_match_tp_z0->Fill(tp_z0->at(it)); + h_match_tp_d0->Fill(tp_d0->at(it)); + h_match_tp_absd0->Fill(std::abs(tp_d0->at(it))); + if (std::abs(tp_eta->at(it)) < 2.0) + h_match_tp_absd0_eta2->Fill(std::abs(tp_d0->at(it))); + if (std::abs(tp_eta->at(it)) < 2.0 && tp_pt->at(it) > 3.0) + h_match_tp_absd0_eta2_pt3->Fill(std::abs(tp_d0->at(it))); + + if (std::abs(tp_eta->at(it)) < 1.0) + n_match_eta1p0++; + else if (std::abs(tp_eta->at(it)) < 1.75) + n_match_eta1p75++; + else + n_match_eta2p5++; + + if (std::abs(tp_pt->at(it)) > 2.0) + n_match_ptg2++; + if (std::abs(tp_pt->at(it)) > 2.0 && std::abs(tp_pt->at(it)) < 8.0) + n_match_pt2to8++; + if (std::abs(tp_pt->at(it)) > 8.0) + n_match_ptg8++; + if (std::abs(tp_pt->at(it)) > 40.0) + n_match_ptg40++; + + if (tp_pt->at(it) < 3.0) + h_match_tp_eta_23->Fill(tp_eta->at(it)); + else if (tp_pt->at(it) < 5.0) + h_match_tp_eta_35->Fill(tp_eta->at(it)); + else + h_match_tp_eta_5->Fill(tp_eta->at(it)); + + if (tp_pt->at(it) < 8.0) { + h_match_tp_eta_L->Fill(tp_eta->at(it)); + h_match_tp_z0_L->Fill(tp_z0->at(it)); + } else { + h_match_tp_z0_H->Fill(tp_z0->at(it)); + h_match_tp_eta_H->Fill(tp_eta->at(it)); + } + } + + // for the following, only consider TPs with pt > TP_minPt + if (tp_pt->at(it) < TP_minPt) + continue; + + // fill nstub histograms + h_match_trk_nstub->Fill(matchtrk_nstub->at(it)); + if (std::abs(tp_eta->at(it)) < 0.8) + h_match_trk_nstub_C->Fill(matchtrk_nstub->at(it)); + else if (std::abs(tp_eta->at(it)) < 1.6 && std::abs(tp_eta->at(it)) >= 0.8) + h_match_trk_nstub_I->Fill(matchtrk_nstub->at(it)); + else if (std::abs(tp_eta->at(it)) >= 1.6) + h_match_trk_nstub_F->Fill(matchtrk_nstub->at(it)); + + // ---------------------------------------------------------------------------------------------------------------- + // fill resolution histograms + + h_res_pt->Fill(matchtrk_pt->at(it) - tp_pt->at(it)); + h_res_ptRel->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_res_eta->Fill(matchtrk_eta->at(it) - tp_eta->at(it)); + h_res_phi->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + h_res_z0->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + if (matchtrk_d0->at(it) < 999.) + h_res_d0->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + + if (std::abs(tp_eta->at(it)) < 0.8) + h_res_z0_C->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + else if (std::abs(tp_eta->at(it)) < 1.6 && std::abs(tp_eta->at(it)) >= 0.8) + h_res_z0_I->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + else if (std::abs(tp_eta->at(it)) >= 1.6) + h_res_z0_F->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + + if (tp_pt->at(it) < 8.0) { + h_res_z0_L->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + if (std::abs(tp_eta->at(it)) < 1.0) + h_res_z0_C_L->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + else + h_res_z0_F_L->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + } else { + h_res_z0_H->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + if (std::abs(tp_eta->at(it)) < 1.0) + h_res_z0_C_H->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + else + h_res_z0_F_H->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + } + + if (matchtrk_d0->at(it) < 999.) { + if (std::abs(tp_eta->at(it)) < 0.8) + h_res_d0_C->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + else if (std::abs(tp_eta->at(it)) < 1.6 && std::abs(tp_eta->at(it)) >= 0.8) + h_res_d0_I->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + else if (std::abs(tp_eta->at(it)) >= 1.6) + h_res_d0_F->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + + if (tp_pt->at(it) < 8.0) { + h_res_d0_L->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + if (std::abs(tp_eta->at(it)) < 1.0) + h_res_d0_C_L->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + else + h_res_d0_F_L->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + } else { + h_res_d0_H->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + if (std::abs(tp_eta->at(it)) < 1.0) + h_res_d0_C_H->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + else + h_res_d0_F_H->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + } + } + + // ---------------------------------------------------------------------------------------------------------------- + // fill resolution vs. pt histograms + for (int im = 0; im < nRANGE; im++) { + if ((tp_pt->at(it) > (float)im * 5.0) && (tp_pt->at(it) < (float)(im + 1) * 5.0)) { + h_resVsPt_pt[im]->Fill(matchtrk_pt->at(it) - tp_pt->at(it)); + h_resVsPt_ptRel[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsPt_eta[im]->Fill(matchtrk_eta->at(it) - tp_eta->at(it)); + h_resVsPt_phi[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + h_resVsPt_z0[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + + h_absResVsPt_pt[im]->Fill(std::abs(matchtrk_pt->at(it) - tp_pt->at(it))); + h_absResVsPt_ptRel[im]->Fill(std::abs((matchtrk_pt->at(it) - tp_pt->at(it))) / tp_pt->at(it)); + h_absResVsPt_z0[im]->Fill(std::abs(matchtrk_z0->at(it) - tp_z0->at(it))); + h_absResVsPt_phi[im]->Fill(std::abs(matchtrk_phi->at(it) - tp_phi->at(it))); + h_absResVsPt_eta[im]->Fill(std::abs(matchtrk_eta->at(it) - tp_eta->at(it))); + + if (std::abs(tp_eta->at(it)) < 0.8) { + h_resVsPt_pt_C[im]->Fill(matchtrk_pt->at(it) - tp_pt->at(it)); + h_resVsPt_ptRel_C[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsPt_z0_C[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + h_resVsPt_phi_C[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + } else if (std::abs(tp_eta->at(it)) < 1.6 && std::abs(tp_eta->at(it)) >= 0.8) { + h_resVsPt_pt_I[im]->Fill(matchtrk_pt->at(it) - tp_pt->at(it)); + h_resVsPt_ptRel_I[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsPt_z0_I[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + h_resVsPt_phi_I[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + } else if (std::abs(tp_eta->at(it)) >= 1.6) { + h_resVsPt_pt_F[im]->Fill(matchtrk_pt->at(it) - tp_pt->at(it)); + h_resVsPt_ptRel_F[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsPt_z0_F[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + h_resVsPt_phi_F[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + } + + if (matchtrk_d0->at(it) < 999) { + h_resVsPt_d0[im]->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + h_absResVsPt_d0[im]->Fill(std::abs(matchtrk_d0->at(it) - tp_d0->at(it))); + } + } + } + + for (int im = 4; im < nRANGE_L + 4; im++) { + if ((tp_pt->at(it) > (float)im * 0.5) && (tp_pt->at(it) <= (float)(im + 1) * 0.5)) { + h_absResVsPt_pt_L[im - 4]->Fill(std::abs(matchtrk_pt->at(it) - tp_pt->at(it))); + h_absResVsPt_ptRel_L[im - 4]->Fill(std::abs((matchtrk_pt->at(it) - tp_pt->at(it))) / tp_pt->at(it)); + h_absResVsPt_z0_L[im - 4]->Fill(std::abs(matchtrk_z0->at(it) - tp_z0->at(it))); + h_absResVsPt_phi_L[im - 4]->Fill(std::abs(matchtrk_phi->at(it) - tp_phi->at(it))); + h_absResVsPt_eta_L[im - 4]->Fill(std::abs(matchtrk_eta->at(it) - tp_eta->at(it))); + h_absResVsPt_d0_L[im - 4]->Fill(std::abs(matchtrk_d0->at(it) - tp_d0->at(it))); + } + } + + // ---------------------------------------------------------------------------------------------------------------- + // fill resolution vs. eta histograms + for (int im = 0; im < nETARANGE; im++) { + if ((std::abs(tp_eta->at(it)) > (float)im * 0.1) && (std::abs(tp_eta->at(it)) < (float)(im + 1) * 0.1)) { + h_resVsEta_ptRel[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsEta_eta[im]->Fill(matchtrk_eta->at(it) - tp_eta->at(it)); + h_resVsEta_phi[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + h_resVsEta_z0[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + + h_absResVsEta_ptRel[im]->Fill(std::abs((matchtrk_pt->at(it) - tp_pt->at(it))) / tp_pt->at(it)); + h_absResVsEta_eta[im]->Fill(std::abs(matchtrk_eta->at(it) - tp_eta->at(it))); + h_absResVsEta_phi[im]->Fill(std::abs(matchtrk_phi->at(it) - tp_phi->at(it))); + h_absResVsEta_z0[im]->Fill(std::abs(matchtrk_z0->at(it) - tp_z0->at(it))); + + if (tp_pt->at(it) < 8.0) { + h_resVsEta_ptRel_L[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsEta_eta_L[im]->Fill(matchtrk_eta->at(it) - tp_eta->at(it)); + h_resVsEta_z0_L[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + h_resVsEta_phi_L[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + + h_absResVsEta_ptRel_L[im]->Fill(std::abs((matchtrk_pt->at(it) - tp_pt->at(it))) / tp_pt->at(it)); + h_absResVsEta_eta_L[im]->Fill(std::abs(matchtrk_eta->at(it) - tp_eta->at(it))); + h_absResVsEta_phi_L[im]->Fill(std::abs(matchtrk_phi->at(it) - tp_phi->at(it))); + h_absResVsEta_z0_L[im]->Fill(std::abs(matchtrk_z0->at(it) - tp_z0->at(it))); + + if (matchtrk_d0->at(it) < 999) { + h_resVsEta_d0_L[im]->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + h_absResVsEta_d0_L[im]->Fill(std::abs(matchtrk_d0->at(it) - tp_d0->at(it))); + } + } else { + h_resVsEta_ptRel_H[im]->Fill((matchtrk_pt->at(it) - tp_pt->at(it)) / tp_pt->at(it)); + h_resVsEta_eta_H[im]->Fill(matchtrk_eta->at(it) - tp_eta->at(it)); + h_resVsEta_z0_H[im]->Fill(matchtrk_z0->at(it) - tp_z0->at(it)); + h_resVsEta_phi_H[im]->Fill(matchtrk_phi->at(it) - tp_phi->at(it)); + + h_absResVsEta_ptRel_H[im]->Fill(std::abs((matchtrk_pt->at(it) - tp_pt->at(it))) / tp_pt->at(it)); + h_absResVsEta_eta_H[im]->Fill(std::abs(matchtrk_eta->at(it) - tp_eta->at(it))); + h_absResVsEta_phi_H[im]->Fill(std::abs(matchtrk_phi->at(it) - tp_phi->at(it))); + h_absResVsEta_z0_H[im]->Fill(std::abs(matchtrk_z0->at(it) - tp_z0->at(it))); + + if (matchtrk_d0->at(it) < 999) { + h_resVsEta_d0_H[im]->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + h_absResVsEta_d0_H[im]->Fill(std::abs(matchtrk_d0->at(it) - tp_d0->at(it))); + } + } + + if (matchtrk_d0->at(it) < 999) { + h_resVsEta_d0[im]->Fill(matchtrk_d0->at(it) - tp_d0->at(it)); + h_absResVsEta_d0[im]->Fill(std::abs(matchtrk_d0->at(it) - tp_d0->at(it))); + } + } + } + + // ---------------------------------------------------------------------------------------------------------------- + // fill resolution vs. phi histograms + for (int im = 0; im < nPHIRANGE; im++) { + if ((tp_phi->at(it) > (float)im * 0.2 - 3.2) && (tp_phi->at(it) < (float)(im + 1) * 0.2 - 3.2)) { + h_absResVsPhi_pt[im]->Fill(std::abs(matchtrk_pt->at(it) - tp_pt->at(it))); + h_absResVsPhi_ptRel[im]->Fill(std::abs((matchtrk_pt->at(it) - tp_pt->at(it))) / tp_pt->at(it)); + } + } + + } // end of matched track loop + + } // end of event loop + // ---------------------------------------------------------------------------------------------------------------- + + // ---------------------------------------------------------------------------------------------------------------- + // Post-event-loop histogram normalization(s) + + // Normalize tracklet efficiency by each eta slice + double maxBinContents; + double etaRes = trackletEffMaxEta / trackletEffEtaBins; + for (double etaBin = 0; etaBin < trackletEffEtaBins; + etaBin++) { //loop through eta bin values (constants defined with relevant hist defs) + maxBinContents = 0; + std::vector binContents = {}; + for (int layer = 0; layer < numLayers; layer++) { + binContents.push_back(h_trk_tracklet_hits->GetBinContent(etaBin + 1, layer + 1)); + maxBinContents = std::max(maxBinContents, binContents.back()); + } + float binWeight; + for (int layer = 0; layer < numLayers; layer++) { + binWeight = (maxBinContents == 0) ? 0 : binContents.at(layer) / maxBinContents; + h_trk_tracklet_eff->Fill((etaBin + 0.5) * etaRes, layer, binWeight); + } + } + + // Adjust tracklet hits and efficiency histograms for aesthetics + + // ---------------------------------------------------------------------------------------------------------------- + // 2D plots + // ---------------------------------------------------------------------------------------------------------------- + + TH1F* h2_resVsPt_pt = new TH1F("resVsPt2_pt", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + TH1F* h2_resVsPt_pt_C = + new TH1F("resVsPt2_pt_C", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + TH1F* h2_resVsPt_pt_I = + new TH1F("resVsPt2_pt_I", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + TH1F* h2_resVsPt_pt_F = + new TH1F("resVsPt2_pt_F", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + + TH1F* h2_resVsPt_ptRel = + new TH1F("resVsPt2_ptRel", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + TH1F* h2_resVsPt_ptRel_C = + new TH1F("resVsPt2_ptRel_C", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + TH1F* h2_resVsPt_ptRel_I = + new TH1F("resVsPt2_ptRel_I", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + TH1F* h2_resVsPt_ptRel_F = + new TH1F("resVsPt2_ptRel_F", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + + TH1F* h2_mresVsPt_pt = + new TH1F("mresVsPt2_pt", ";Tracking particle p_{T} [GeV]; Mean(p_{T} residual) [GeV]", 20, 0, 100); + TH1F* h2_mresVsPt_pt_C = + new TH1F("mresVsPt2_pt_C", ";Tracking particle p_{T} [GeV]; Mean(p_{T} residual) [GeV]", 20, 0, 100); + TH1F* h2_mresVsPt_pt_I = + new TH1F("mresVsPt2_pt_I", ";Tracking particle p_{T} [GeV]; Mean(p_{T} residual) [GeV]", 20, 0, 100); + TH1F* h2_mresVsPt_pt_F = + new TH1F("mresVsPt2_pt_F", ";Tracking particle p_{T} [GeV]; Mean(p_{T} residual) [GeV]", 20, 0, 100); + + TH1F* h2_resVsPt_z0 = new TH1F("resVsPt2_z0", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + TH1F* h2_resVsPt_z0_C = + new TH1F("resVsPt2_z0_C", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + TH1F* h2_resVsPt_z0_I = + new TH1F("resVsPt2_z0_I", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + TH1F* h2_resVsPt_z0_F = + new TH1F("resVsPt2_z0_F", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + + TH1F* h2_resVsPt_phi = new TH1F("resVsPt2_phi", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + TH1F* h2_resVsPt_phi_C = + new TH1F("resVsPt2_phi_C", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + TH1F* h2_resVsPt_phi_I = + new TH1F("resVsPt2_phi_I", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + TH1F* h2_resVsPt_phi_F = + new TH1F("resVsPt2_phi_F", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + + TH1F* h2_resVsPt_eta = new TH1F("resVsPt2_eta", ";Tracking particle p_{T} [GeV]; #eta resolution", 20, 0, 100); + + TH1F* h2_resVsPt_d0 = new TH1F("resVsPt2_d0", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", 20, 0, 100); + + TH1F* h2_resVsPt_pt_68 = + new TH1F("resVsPt2_pt_68", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + TH1F* h2_resVsPt_ptRel_68 = + new TH1F("resVsPt2_ptRel_68", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + TH1F* h2_resVsPt_z0_68 = + new TH1F("resVsPt2_z0_68", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + TH1F* h2_resVsPt_phi_68 = + new TH1F("resVsPt2_phi_68", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + TH1F* h2_resVsPt_eta_68 = new TH1F("resVsPt2_eta_68", ";Tracking particle p_{T} [GeV]; #eta resolution", 20, 0, 100); + TH1F* h2_resVsPt_d0_68 = + new TH1F("resVsPt2_d0_68", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", 20, 0, 100); + + TH1F* h2_resVsPt_pt_90 = + new TH1F("resVsPt2_pt_90", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + TH1F* h2_resVsPt_ptRel_90 = + new TH1F("resVsPt2_ptRel_90", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + TH1F* h2_resVsPt_z0_90 = + new TH1F("resVsPt2_z0_90", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + TH1F* h2_resVsPt_phi_90 = + new TH1F("resVsPt2_phi_90", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + TH1F* h2_resVsPt_eta_90 = new TH1F("resVsPt2_eta_90", ";Tracking particle p_{T} [GeV]; #eta resolution", 20, 0, 100); + TH1F* h2_resVsPt_d0_90 = + new TH1F("resVsPt2_d0_90", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", 20, 0, 100); + + TH1F* h2_resVsPt_pt_99 = + new TH1F("resVsPt2_pt_99", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", 20, 0, 100); + TH1F* h2_resVsPt_ptRel_99 = + new TH1F("resVsPt2_ptRel_99", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", 20, 0, 100); + TH1F* h2_resVsPt_z0_99 = + new TH1F("resVsPt2_z0_99", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", 20, 0, 100); + TH1F* h2_resVsPt_phi_99 = + new TH1F("resVsPt2_phi_99", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", 20, 0, 100); + TH1F* h2_resVsPt_eta_99 = new TH1F("resVsPt2_eta_99", ";Tracking particle p_{T} [GeV]; #eta resolution", 20, 0, 100); + TH1F* h2_resVsPt_d0_99 = + new TH1F("resVsPt2_d0_99", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", 20, 0, 100); + + TH1F* h2_resVsPt_pt_L_68 = + new TH1F("resVsPt2_pt_L_68", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_ptRel_L_68 = + new TH1F("resVsPt2_ptRel_L_68", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_z0_L_68 = + new TH1F("resVsPt2_z0_L_68", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_phi_L_68 = + new TH1F("resVsPt2_phi_L_68", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_eta_L_68 = + new TH1F("resVsPt2_eta_L_68", ";Tracking particle p_{T} [GeV]; #eta resolution", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_d0_L_68 = + new TH1F("resVsPt2_d0_L_68", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", nRANGE_L, 2, 8); + + TH1F* h2_resVsPt_pt_L_90 = + new TH1F("resVsPt2_pt_L_90", ";Tracking particle p_{T} [GeV]; p_{T} resolution [GeV]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_ptRel_L_90 = + new TH1F("resVsPt2_ptRel_L_90", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_z0_L_90 = + new TH1F("resVsPt2_z0_L_90", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_phi_L_90 = + new TH1F("resVsPt2_phi_L_90", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_eta_L_90 = + new TH1F("resVsPt2_eta_L_90", ";Tracking particle p_{T} [GeV]; #eta resolution", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_d0_L_90 = + new TH1F("resVsPt2_d0_L_90", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", nRANGE_L, 2, 8); + + TH1F* h2_resVsPt_pt_L_99 = + new TH1F("resVsPt2_pt_L_99", ";Tracking particle p_{T} [GeV]; p_{T} resolution [cm]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_ptRel_L_99 = + new TH1F("resVsPt2_ptRel_L_99", ";Tracking particle p_{T} [GeV]; p_{T} resolution / p_{T}", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_z0_L_99 = + new TH1F("resVsPt2_z0_L_99", ";Tracking particle p_{T} [GeV]; z_{0} resolution [cm]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_phi_L_99 = + new TH1F("resVsPt2_phi_L_99", ";Tracking particle p_{T} [GeV]; #phi resolution [rad]", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_eta_L_99 = + new TH1F("resVsPt2_eta_L_99", ";Tracking particle p_{T} [GeV]; #eta resolution", nRANGE_L, 2, 8); + TH1F* h2_resVsPt_d0_L_99 = + new TH1F("resVsPt2_d0_L_99", ";Tracking particle p_{T} [GeV]; d_{0} resolution [cm]", nRANGE_L, 2, 8); + + for (int i = 0; i < nRANGE; i++) { + // set bin content and error + h2_resVsPt_pt->SetBinContent(i + 1, h_resVsPt_pt[i]->GetRMS()); + h2_resVsPt_pt->SetBinError(i + 1, h_resVsPt_pt[i]->GetRMSError()); + h2_resVsPt_pt_C->SetBinContent(i + 1, h_resVsPt_pt_C[i]->GetRMS()); + h2_resVsPt_pt_C->SetBinError(i + 1, h_resVsPt_pt_C[i]->GetRMSError()); + h2_resVsPt_pt_I->SetBinContent(i + 1, h_resVsPt_pt_I[i]->GetRMS()); + h2_resVsPt_pt_I->SetBinError(i + 1, h_resVsPt_pt_I[i]->GetRMSError()); + h2_resVsPt_pt_F->SetBinContent(i + 1, h_resVsPt_pt_F[i]->GetRMS()); + h2_resVsPt_pt_F->SetBinError(i + 1, h_resVsPt_pt_F[i]->GetRMSError()); + + h2_resVsPt_ptRel->SetBinContent(i + 1, h_resVsPt_ptRel[i]->GetRMS()); + h2_resVsPt_ptRel->SetBinError(i + 1, h_resVsPt_ptRel[i]->GetRMSError()); + h2_resVsPt_ptRel_C->SetBinContent(i + 1, h_resVsPt_ptRel_C[i]->GetRMS()); + h2_resVsPt_ptRel_C->SetBinError(i + 1, h_resVsPt_ptRel_C[i]->GetRMSError()); + h2_resVsPt_ptRel_I->SetBinContent(i + 1, h_resVsPt_ptRel_I[i]->GetRMS()); + h2_resVsPt_ptRel_I->SetBinError(i + 1, h_resVsPt_ptRel_I[i]->GetRMSError()); + h2_resVsPt_ptRel_F->SetBinContent(i + 1, h_resVsPt_ptRel_F[i]->GetRMS()); + h2_resVsPt_ptRel_F->SetBinError(i + 1, h_resVsPt_ptRel_F[i]->GetRMSError()); + + h2_mresVsPt_pt->SetBinContent(i + 1, h_resVsPt_pt[i]->GetMean()); + h2_mresVsPt_pt->SetBinError(i + 1, h_resVsPt_pt[i]->GetMeanError()); + h2_mresVsPt_pt_C->SetBinContent(i + 1, h_resVsPt_pt_C[i]->GetMean()); + h2_mresVsPt_pt_C->SetBinError(i + 1, h_resVsPt_pt_C[i]->GetMeanError()); + h2_mresVsPt_pt_I->SetBinContent(i + 1, h_resVsPt_pt_I[i]->GetMean()); + h2_mresVsPt_pt_I->SetBinError(i + 1, h_resVsPt_pt_I[i]->GetMeanError()); + h2_mresVsPt_pt_F->SetBinContent(i + 1, h_resVsPt_pt_F[i]->GetMean()); + h2_mresVsPt_pt_F->SetBinError(i + 1, h_resVsPt_pt_F[i]->GetMeanError()); + + h2_resVsPt_z0->SetBinContent(i + 1, h_resVsPt_z0[i]->GetRMS()); + h2_resVsPt_z0->SetBinError(i + 1, h_resVsPt_z0[i]->GetRMSError()); + h2_resVsPt_z0_C->SetBinContent(i + 1, h_resVsPt_z0_C[i]->GetRMS()); + h2_resVsPt_z0_C->SetBinError(i + 1, h_resVsPt_z0_C[i]->GetRMSError()); + h2_resVsPt_z0_I->SetBinContent(i + 1, h_resVsPt_z0_I[i]->GetRMS()); + h2_resVsPt_z0_I->SetBinError(i + 1, h_resVsPt_z0_I[i]->GetRMSError()); + h2_resVsPt_z0_F->SetBinContent(i + 1, h_resVsPt_z0_F[i]->GetRMS()); + h2_resVsPt_z0_F->SetBinError(i + 1, h_resVsPt_z0_F[i]->GetRMSError()); + + h2_resVsPt_phi->SetBinContent(i + 1, h_resVsPt_phi[i]->GetRMS()); + h2_resVsPt_phi->SetBinError(i + 1, h_resVsPt_phi[i]->GetRMSError()); + h2_resVsPt_phi_C->SetBinContent(i + 1, h_resVsPt_phi_C[i]->GetRMS()); + h2_resVsPt_phi_C->SetBinError(i + 1, h_resVsPt_phi_C[i]->GetRMSError()); + h2_resVsPt_phi_I->SetBinContent(i + 1, h_resVsPt_phi_I[i]->GetRMS()); + h2_resVsPt_phi_I->SetBinError(i + 1, h_resVsPt_phi_I[i]->GetRMSError()); + h2_resVsPt_phi_F->SetBinContent(i + 1, h_resVsPt_phi_F[i]->GetRMS()); + h2_resVsPt_phi_F->SetBinError(i + 1, h_resVsPt_phi_F[i]->GetRMSError()); + + h2_resVsPt_eta->SetBinContent(i + 1, h_resVsPt_eta[i]->GetRMS()); + h2_resVsPt_eta->SetBinError(i + 1, h_resVsPt_eta[i]->GetRMSError()); + + h2_resVsPt_d0->SetBinContent(i + 1, h_resVsPt_d0[i]->GetRMS()); + h2_resVsPt_d0->SetBinError(i + 1, h_resVsPt_d0[i]->GetRMSError()); + + h2_resVsPt_pt_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_pt[i], 0.68)); + h2_resVsPt_pt_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_pt[i], 0.90)); + h2_resVsPt_pt_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_pt[i], 0.99)); + + h2_resVsPt_ptRel_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_ptRel[i], 0.68)); + h2_resVsPt_ptRel_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_ptRel[i], 0.90)); + h2_resVsPt_ptRel_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_ptRel[i], 0.99)); + + h2_resVsPt_eta_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_eta[i], 0.68)); + h2_resVsPt_eta_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_eta[i], 0.90)); + h2_resVsPt_eta_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_eta[i], 0.99)); + + h2_resVsPt_z0_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_z0[i], 0.68)); + h2_resVsPt_z0_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_z0[i], 0.90)); + h2_resVsPt_z0_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_z0[i], 0.99)); + + h2_resVsPt_phi_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_phi[i], 0.68)); + h2_resVsPt_phi_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_phi[i], 0.90)); + h2_resVsPt_phi_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_phi[i], 0.99)); + + h2_resVsPt_d0_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_d0[i], 0.68)); + h2_resVsPt_d0_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_d0[i], 0.90)); + h2_resVsPt_d0_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_d0[i], 0.99)); + } + + for (int i = 0; i < nRANGE_L; i++) { + h2_resVsPt_pt_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_pt_L[i], 0.68)); + h2_resVsPt_pt_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_pt_L[i], 0.90)); + h2_resVsPt_pt_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_pt_L[i], 0.99)); + + h2_resVsPt_ptRel_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_ptRel_L[i], 0.68)); + h2_resVsPt_ptRel_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_ptRel_L[i], 0.90)); + h2_resVsPt_ptRel_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_ptRel_L[i], 0.99)); + + h2_resVsPt_eta_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_eta_L[i], 0.68)); + h2_resVsPt_eta_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_eta_L[i], 0.90)); + h2_resVsPt_eta_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_eta_L[i], 0.99)); + + h2_resVsPt_z0_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_z0_L[i], 0.68)); + h2_resVsPt_z0_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_z0_L[i], 0.90)); + h2_resVsPt_z0_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_z0_L[i], 0.99)); + + h2_resVsPt_phi_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_phi_L[i], 0.68)); + h2_resVsPt_phi_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_phi_L[i], 0.90)); + h2_resVsPt_phi_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_phi_L[i], 0.99)); + + h2_resVsPt_d0_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_d0_L[i], 0.68)); + h2_resVsPt_d0_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_d0_L[i], 0.90)); + h2_resVsPt_d0_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPt_d0_L[i], 0.99)); + } + + // resolution vs. eta histograms + TH1F* h2_resVsEta_eta = new TH1F("resVsEta_eta", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_eta_L = new TH1F("resVsEta_eta_L", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_eta_H = new TH1F("resVsEta_eta_H", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_z0 = new TH1F("resVsEta_z0", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_L = + new TH1F("resVsEta_z0_L", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_H = + new TH1F("resVsEta_z0_H", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_phi = + new TH1F("resVsEta_phi", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_L = + new TH1F("resVsEta_phi_L", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_H = + new TH1F("resVsEta_phi_H", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_ptRel = + new TH1F("resVsEta_ptRel", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_L = + new TH1F("resVsEta_ptRel_L", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_H = + new TH1F("resVsEta_ptRel_H", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_d0 = new TH1F("resVsEta_d0", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_L = + new TH1F("resVsEta_d0_L", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_H = + new TH1F("resVsEta_d0_H", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + // mean of residuals + TH1F* h2_mresVsEta_eta = + new TH1F("mresVsEta_eta", ";Tracking particle |#eta|; Mean(#eta residual)", nETARANGE, 0, 2.4); + TH1F* h2_mresVsEta_z0 = + new TH1F("mresVsEta_z0", ";Tracking particle |#eta|; Mean(z_{0} residual) [cm]", nETARANGE, 0, 2.4); + TH1F* h2_mresVsEta_phi = + new TH1F("mresVsEta_phi", ";Tracking particle |#eta|; Mean(phi residual) [rad]", nETARANGE, 0, 2.4); + TH1F* h2_mresVsEta_ptRel = + new TH1F("mresVsEta_ptRel", ";Tracking particle |#eta|; Mean(ptrel residual)", nETARANGE, 0, 2.4); + + // 68 / 90 / 99% residuals + TH1F* h2_resVsEta_eta_68 = + new TH1F("resVsEta_eta_68", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_eta_90 = + new TH1F("resVsEta_eta_90", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_eta_99 = + new TH1F("resVsEta_eta_99", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_z0_68 = + new TH1F("resVsEta_z0_68", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_90 = + new TH1F("resVsEta_z0_90", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_99 = + new TH1F("resVsEta_z0_99", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_phi_68 = + new TH1F("resVsEta_phi_68", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_90 = + new TH1F("resVsEta_phi_90", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_99 = + new TH1F("resVsEta_phi_99", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_ptRel_68 = + new TH1F("resVsEta_ptRel_68", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_90 = + new TH1F("resVsEta_ptRel_90", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_99 = + new TH1F("resVsEta_ptRel_99", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_d0_68 = + new TH1F("resVsEta_d0_68", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_90 = + new TH1F("resVsEta_d0_90", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_99 = + new TH1F("resVsEta_d0_99", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_eta_L_68 = + new TH1F("resVsEta_eta_L_68", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_L_68 = + new TH1F("resVsEta_z0_L_68", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_L_68 = + new TH1F("resVsEta_phi_L_68", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_L_68 = + new TH1F("resVsEta_ptRel_L_68", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_L_68 = + new TH1F("resVsEta_d0_L_68", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_eta_L_90 = + new TH1F("resVsEta_eta_L_90", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_L_90 = + new TH1F("resVsEta_z0_L_90", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_L_90 = + new TH1F("resVsEta_phi_L_90", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_L_90 = + new TH1F("resVsEta_ptRel_L_90", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_L_90 = + new TH1F("resVsEta_d0_L_90", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_eta_L_99 = + new TH1F("resVsEta_eta_L_99", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_L_99 = + new TH1F("resVsEta_z0_L_99", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_L_99 = + new TH1F("resVsEta_phi_L_99", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_L_99 = + new TH1F("resVsEta_ptRel_L_99", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_L_99 = + new TH1F("resVsEta_d0_L_99", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_eta_H_68 = + new TH1F("resVsEta_eta_H_68", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_H_68 = + new TH1F("resVsEta_z0_H_68", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_H_68 = + new TH1F("resVsEta_phi_H_68", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_H_68 = + new TH1F("resVsEta_ptRel_H_68", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_H_68 = + new TH1F("resVsEta_d0_H_68", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_eta_H_90 = + new TH1F("resVsEta_eta_H_90", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_H_90 = + new TH1F("resVsEta_z0_H_90", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_H_90 = + new TH1F("resVsEta_phi_H_90", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_H_90 = + new TH1F("resVsEta_ptRel_H_90", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_H_90 = + new TH1F("resVsEta_d0_H_90", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + TH1F* h2_resVsEta_eta_H_99 = + new TH1F("resVsEta_eta_H_99", ";Tracking particle |#eta|; #eta resolution", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_z0_H_99 = + new TH1F("resVsEta_z0_H_99", ";Tracking particle |#eta|; z_{0} resolution [cm]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_phi_H_99 = + new TH1F("resVsEta_phi_H_99", ";Tracking particle |#eta|; #phi resolution [rad]", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_ptRel_H_99 = + new TH1F("resVsEta_ptRel_H_99", ";Tracking particle |#eta|; p_{T} resolution / p_{T}", nETARANGE, 0, 2.4); + TH1F* h2_resVsEta_d0_H_99 = + new TH1F("resVsEta_d0_H_99", ";Tracking particle |#eta|; d_{0} resolution [cm]", nETARANGE, 0, 2.4); + + // resolution vs. eta histograms (gaussian fit) + TH1F* h3_resVsEta_eta_L = new TH1F("resVsEta_eta_L_gaus", ";|#eta|; #sigma(#eta)", nETARANGE, 0, 2.4); + TH1F* h3_resVsEta_eta_H = new TH1F("resVsEta_eta_H_gaus", ";|#eta|; #sigma(#eta)", nETARANGE, 0, 2.4); + + TH1F* h3_resVsEta_z0_L = new TH1F("resVsEta_z0_L_gaus", ";|#eta|; #sigma(z_{0}) [cm]", nETARANGE, 0, 2.4); + TH1F* h3_resVsEta_z0_H = new TH1F("resVsEta_z0_H_gaus", ";|#eta|; #sigma(z_{0}) [cm]", nETARANGE, 0, 2.4); + + TH1F* h3_resVsEta_phi_L = new TH1F("resVsEta_phi_L_gaus", ";|#eta|; #sigma(#phi) [rad]", nETARANGE, 0, 2.4); + TH1F* h3_resVsEta_phi_H = new TH1F("resVsEta_phi_H_gaus", ";|#eta|; #sigma(#phi) [rad]", nETARANGE, 0, 2.4); + + TH1F* h3_resVsEta_ptRel_L = new TH1F("resVsEta_ptRel_L_gaus", ";|#eta|; #sigma(p_{T}) / p_{T}", nETARANGE, 0, 2.4); + TH1F* h3_resVsEta_ptRel_H = new TH1F("resVsEta_ptRel_H_gaus", ";|#eta|; #sigma(p_{T}) / p_{T}", nETARANGE, 0, 2.4); + + TString fitdir = "FitResults/"; + + for (int i = 0; i < nETARANGE; i++) { + // set bin content and error + h2_resVsEta_eta->SetBinContent(i + 1, h_resVsEta_eta[i]->GetRMS()); + h2_resVsEta_eta->SetBinError(i + 1, h_resVsEta_eta[i]->GetRMSError()); + h2_resVsEta_eta_L->SetBinContent(i + 1, h_resVsEta_eta_L[i]->GetRMS()); + h2_resVsEta_eta_L->SetBinError(i + 1, h_resVsEta_eta_L[i]->GetRMSError()); + h2_resVsEta_eta_H->SetBinContent(i + 1, h_resVsEta_eta_H[i]->GetRMS()); + h2_resVsEta_eta_H->SetBinError(i + 1, h_resVsEta_eta_H[i]->GetRMSError()); + + h2_resVsEta_z0->SetBinContent(i + 1, h_resVsEta_z0[i]->GetRMS()); + h2_resVsEta_z0->SetBinError(i + 1, h_resVsEta_z0[i]->GetRMSError()); + h2_resVsEta_z0_L->SetBinContent(i + 1, h_resVsEta_z0_L[i]->GetRMS()); + h2_resVsEta_z0_L->SetBinError(i + 1, h_resVsEta_z0_L[i]->GetRMSError()); + h2_resVsEta_z0_H->SetBinContent(i + 1, h_resVsEta_z0_H[i]->GetRMS()); + h2_resVsEta_z0_H->SetBinError(i + 1, h_resVsEta_z0_H[i]->GetRMSError()); + + h2_resVsEta_phi->SetBinContent(i + 1, h_resVsEta_phi[i]->GetRMS()); + h2_resVsEta_phi->SetBinError(i + 1, h_resVsEta_phi[i]->GetRMSError()); + h2_resVsEta_phi_L->SetBinContent(i + 1, h_resVsEta_phi_L[i]->GetRMS()); + h2_resVsEta_phi_L->SetBinError(i + 1, h_resVsEta_phi_L[i]->GetRMSError()); + h2_resVsEta_phi_H->SetBinContent(i + 1, h_resVsEta_phi_H[i]->GetRMS()); + h2_resVsEta_phi_H->SetBinError(i + 1, h_resVsEta_phi_H[i]->GetRMSError()); + + h2_resVsEta_ptRel->SetBinContent(i + 1, h_resVsEta_ptRel[i]->GetRMS()); + h2_resVsEta_ptRel->SetBinError(i + 1, h_resVsEta_ptRel[i]->GetRMSError()); + h2_resVsEta_ptRel_L->SetBinContent(i + 1, h_resVsEta_ptRel_L[i]->GetRMS()); + h2_resVsEta_ptRel_L->SetBinError(i + 1, h_resVsEta_ptRel_L[i]->GetRMSError()); + h2_resVsEta_ptRel_H->SetBinContent(i + 1, h_resVsEta_ptRel_H[i]->GetRMS()); + h2_resVsEta_ptRel_H->SetBinError(i + 1, h_resVsEta_ptRel_H[i]->GetRMSError()); + + h2_mresVsEta_eta->SetBinContent(i + 1, h_resVsEta_eta[i]->GetMean()); + h2_mresVsEta_eta->SetBinError(i + 1, h_resVsEta_eta[i]->GetMeanError()); + h2_mresVsEta_z0->SetBinContent(i + 1, h_resVsEta_z0[i]->GetMean()); + h2_mresVsEta_z0->SetBinError(i + 1, h_resVsEta_z0[i]->GetMeanError()); + h2_mresVsEta_phi->SetBinContent(i + 1, h_resVsEta_phi[i]->GetMean()); + h2_mresVsEta_phi->SetBinError(i + 1, h_resVsEta_phi[i]->GetMeanError()); + h2_mresVsEta_ptRel->SetBinContent(i + 1, h_resVsEta_ptRel[i]->GetMean()); + h2_mresVsEta_ptRel->SetBinError(i + 1, h_resVsEta_ptRel[i]->GetMeanError()); + + h2_resVsEta_d0->SetBinContent(i + 1, h_resVsEta_d0[i]->GetRMS()); + h2_resVsEta_d0->SetBinError(i + 1, h_resVsEta_d0[i]->GetRMSError()); + h2_resVsEta_d0_L->SetBinContent(i + 1, h_resVsEta_d0_L[i]->GetRMS()); + h2_resVsEta_d0_L->SetBinError(i + 1, h_resVsEta_d0_L[i]->GetRMSError()); + h2_resVsEta_d0_H->SetBinContent(i + 1, h_resVsEta_d0_H[i]->GetRMS()); + h2_resVsEta_d0_H->SetBinError(i + 1, h_resVsEta_d0_H[i]->GetRMSError()); + + h2_resVsEta_eta_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta[i], 0.68)); + h2_resVsEta_eta_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta[i], 0.90)); + h2_resVsEta_eta_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta[i], 0.99)); + + h2_resVsEta_z0_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0[i], 0.68)); + h2_resVsEta_z0_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0[i], 0.90)); + h2_resVsEta_z0_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0[i], 0.99)); + + h2_resVsEta_phi_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi[i], 0.68)); + h2_resVsEta_phi_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi[i], 0.90)); + h2_resVsEta_phi_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi[i], 0.99)); + + h2_resVsEta_ptRel_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel[i], 0.68)); + h2_resVsEta_ptRel_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel[i], 0.90)); + h2_resVsEta_ptRel_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel[i], 0.99)); + + h2_resVsEta_d0_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0[i], 0.68)); + h2_resVsEta_d0_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0[i], 0.90)); + h2_resVsEta_d0_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0[i], 0.99)); + + h2_resVsEta_eta_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta_L[i], 0.68)); + h2_resVsEta_z0_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0_L[i], 0.68)); + h2_resVsEta_phi_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi_L[i], 0.68)); + h2_resVsEta_ptRel_L_68->SetBinContent(i + 1, + getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel_L[i], 0.68)); + h2_resVsEta_d0_L_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0_L[i], 0.68)); + + h2_resVsEta_eta_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta_L[i], 0.90)); + h2_resVsEta_z0_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0_L[i], 0.90)); + h2_resVsEta_phi_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi_L[i], 0.90)); + h2_resVsEta_ptRel_L_90->SetBinContent(i + 1, + getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel_L[i], 0.90)); + h2_resVsEta_d0_L_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0_L[i], 0.90)); + + h2_resVsEta_eta_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta_L[i], 0.99)); + h2_resVsEta_z0_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0_L[i], 0.99)); + h2_resVsEta_phi_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi_L[i], 0.99)); + h2_resVsEta_ptRel_L_99->SetBinContent(i + 1, + getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel_L[i], 0.99)); + h2_resVsEta_d0_L_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0_L[i], 0.99)); + + h2_resVsEta_eta_H_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta_H[i], 0.68)); + h2_resVsEta_z0_H_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0_H[i], 0.68)); + h2_resVsEta_phi_H_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi_H[i], 0.68)); + h2_resVsEta_ptRel_H_68->SetBinContent(i + 1, + getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel_H[i], 0.68)); + h2_resVsEta_d0_H_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0_H[i], 0.68)); + + h2_resVsEta_eta_H_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta_H[i], 0.90)); + h2_resVsEta_z0_H_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0_H[i], 0.90)); + h2_resVsEta_phi_H_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi_H[i], 0.90)); + h2_resVsEta_ptRel_H_90->SetBinContent(i + 1, + getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel_H[i], 0.90)); + h2_resVsEta_d0_H_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0_H[i], 0.90)); + + h2_resVsEta_eta_H_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_eta_H[i], 0.99)); + h2_resVsEta_z0_H_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_z0_H[i], 0.99)); + h2_resVsEta_phi_H_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_phi_H[i], 0.99)); + h2_resVsEta_ptRel_H_99->SetBinContent(i + 1, + getIntervalContainingFractionOfEntries(h_absResVsEta_ptRel_H[i], 0.99)); + h2_resVsEta_d0_H_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsEta_d0_H[i], 0.99)); + + // --------------------------------------------------------------------------------------------------- + // gaussian fit instead + // --------------------------------------------------------------------------------------------------- + + if (doGausFit) { + TCanvas cfit; + char text[500]; + + float sigma = 0; + float esigma = 0; + TF1* fit; + + float rms = 0; + float erms = 0; + + fit = new TF1("fit", "gaus", -0.01, 0.01); + h_resVsEta_eta_L[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_eta_L[i]->GetRMS(); + erms = h_resVsEta_eta_L[i]->GetRMSError(); + h3_resVsEta_eta_L->SetBinContent(i + 1, sigma); + h3_resVsEta_eta_L->SetBinError(i + 1, esigma); + h_resVsEta_eta_L[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} < 5 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_eta_L_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -0.01, 0.01); + h_resVsEta_eta_H[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_eta_H[i]->GetRMS(); + erms = h_resVsEta_eta_H[i]->GetRMSError(); + h3_resVsEta_eta_H->SetBinContent(i + 1, sigma); + h3_resVsEta_eta_H->SetBinError(i + 1, esigma); + h_resVsEta_eta_H[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} > 15 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_eta_H_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -1, 1); + h_resVsEta_z0_L[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_z0_L[i]->GetRMS(); + erms = h_resVsEta_z0_L[i]->GetRMSError(); + h3_resVsEta_z0_L->SetBinContent(i + 1, sigma); + h3_resVsEta_z0_L->SetBinError(i + 1, esigma); + h_resVsEta_z0_L[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} < 5 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_z0_L_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -1, 1); + h_resVsEta_z0_H[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_z0_H[i]->GetRMS(); + erms = h_resVsEta_z0_H[i]->GetRMSError(); + h3_resVsEta_z0_H->SetBinContent(i + 1, sigma); + h3_resVsEta_z0_H->SetBinError(i + 1, esigma); + h_resVsEta_z0_H[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} > 15 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_z0_H_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -0.005, 0.005); + h_resVsEta_phi_L[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_phi_L[i]->GetRMS(); + erms = h_resVsEta_phi_L[i]->GetRMSError(); + h3_resVsEta_phi_L->SetBinContent(i + 1, sigma); + h3_resVsEta_phi_L->SetBinError(i + 1, esigma); + h_resVsEta_phi_L[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} < 5 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_phi_L_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -0.005, 0.005); + h_resVsEta_phi_H[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_phi_H[i]->GetRMS(); + erms = h_resVsEta_phi_H[i]->GetRMSError(); + h3_resVsEta_phi_H->SetBinContent(i + 1, sigma); + h3_resVsEta_phi_H->SetBinError(i + 1, esigma); + h_resVsEta_phi_H[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} > 15 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_phi_H_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -0.5, 0.5); + h_resVsEta_ptRel_L[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_ptRel_L[i]->GetRMS(); + erms = h_resVsEta_ptRel_L[i]->GetRMSError(); + h3_resVsEta_ptRel_L->SetBinContent(i + 1, sigma); + h3_resVsEta_ptRel_L->SetBinError(i + 1, esigma); + h_resVsEta_ptRel_L[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} < 5 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_ptRel_L_" + etarange[i] + ".pdf"); + delete fit; + + fit = new TF1("fit", "gaus", -0.5, 0.5); + h_resVsEta_ptRel_H[i]->Fit("fit", "R"); + sigma = fit->GetParameter(2); + esigma = fit->GetParError(2); + rms = h_resVsEta_ptRel_H[i]->GetRMS(); + erms = h_resVsEta_ptRel_H[i]->GetRMSError(); + h3_resVsEta_ptRel_H->SetBinContent(i + 1, sigma); + h3_resVsEta_ptRel_H->SetBinError(i + 1, esigma); + h_resVsEta_ptRel_H[i]->Draw(); + sprintf(text, "RMS: %.4f +/- %.4f", rms, erms); + mySmallText(0.2, 0.86, 1, text); + sprintf(text, "Fit: %.4f +/- %.4f", sigma, esigma); + mySmallText(0.2, 0.8, 2, text); + sprintf(text, "p_{T} > 15 GeV"); + mySmallText(0.2, 0.7, 1, text); + cfit.SaveAs(fitdir + "resVsEta_ptRel_H_" + etarange[i] + ".pdf"); + delete fit; + + } //end doGausFit + } + + TH1F* h2_resVsPhi_pt_68 = + new TH1F("resVsPhi2_pt_68", ";Tracking particle #phi; p_{T} resolution [GeV]", 32, -3.2, 3.2); + TH1F* h2_resVsPhi_pt_90 = + new TH1F("resVsPhi2_pt_90", ";Tracking particle #phi; p_{T} resolution [GeV]", 32, -3.2, 3.2); + TH1F* h2_resVsPhi_pt_99 = + new TH1F("resVsPhi2_pt_99", ";Tracking particle #phi; p_{T} resolution [GeV]", 32, -3.2, 3.2); + TH1F* h2_resVsPhi_ptRel_68 = + new TH1F("resVsPhi2_ptRel_68", ";Tracking particle #phi; p_{T} resolution / p_{T}", 32, -3.2, 3.2); + TH1F* h2_resVsPhi_ptRel_90 = + new TH1F("resVsPhi2_ptRel_90", ";Tracking particle #phi; p_{T} resolution / p_{T}", 32, -3.2, 3.2); + TH1F* h2_resVsPhi_ptRel_99 = + new TH1F("resVsPhi2_ptRel_99", ";Tracking particle #phi; p_{T} resolution / p_{T}", 32, -3.2, 3.2); + + for (int i = 0; i < nPHIRANGE; i++) { + h2_resVsPhi_pt_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPhi_pt[i], 0.68)); + h2_resVsPhi_pt_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPhi_pt[i], 0.90)); + h2_resVsPhi_pt_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPhi_pt[i], 0.99)); + + h2_resVsPhi_ptRel_68->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPhi_ptRel[i], 0.68)); + h2_resVsPhi_ptRel_90->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPhi_ptRel[i], 0.90)); + h2_resVsPhi_ptRel_99->SetBinContent(i + 1, getIntervalContainingFractionOfEntries(h_absResVsPhi_ptRel[i], 0.99)); + } + + // set minimum to zero + h2_resVsPt_pt->SetMinimum(0); + h2_resVsPt_pt_C->SetMinimum(0); + h2_resVsPt_pt_I->SetMinimum(0); + h2_resVsPt_pt_F->SetMinimum(0); + + h2_resVsPt_ptRel->SetMinimum(0); + h2_resVsPt_ptRel_C->SetMinimum(0); + h2_resVsPt_ptRel_I->SetMinimum(0); + h2_resVsPt_ptRel_F->SetMinimum(0); + + h2_resVsPt_z0->SetMinimum(0); + h2_resVsPt_z0_C->SetMinimum(0); + h2_resVsPt_z0_I->SetMinimum(0); + h2_resVsPt_z0_F->SetMinimum(0); + + h2_resVsPt_phi->SetMinimum(0); + h2_resVsPt_phi_C->SetMinimum(0); + h2_resVsPt_phi_I->SetMinimum(0); + h2_resVsPt_phi_F->SetMinimum(0); + + h2_resVsPt_eta->SetMinimum(0); + + h2_resVsEta_eta->SetMinimum(0); + h2_resVsEta_eta_L->SetMinimum(0); + h2_resVsEta_eta_H->SetMinimum(0); + + h2_resVsEta_z0->SetMinimum(0); + h2_resVsEta_z0_L->SetMinimum(0); + h2_resVsEta_z0_H->SetMinimum(0); + + h2_resVsEta_phi->SetMinimum(0); + h2_resVsEta_phi_L->SetMinimum(0); + h2_resVsEta_phi_H->SetMinimum(0); + + h2_resVsEta_ptRel->SetMinimum(0); + h2_resVsEta_ptRel_L->SetMinimum(0); + h2_resVsEta_ptRel_H->SetMinimum(0); + + h2_resVsPt_d0->SetMinimum(0); + h2_resVsEta_d0->SetMinimum(0); + h2_resVsEta_d0_L->SetMinimum(0); + h2_resVsEta_d0_H->SetMinimum(0); + + // ------------------------------------------------------------------------------------------- + // output file for histograms + // ------------------------------------------------------------------------------------------- + + if (TP_select_pdgid != 0) { + char pdgidtxt[500]; + sprintf(pdgidtxt, "_pdgid%i", TP_select_pdgid); + type = type + pdgidtxt; + } else if (TP_select_injet == 1) + type = type + "_injet"; + else if (TP_select_injet == 2) + type = type + "_injet_highpt"; + else if (TP_select_injet == 3) + type = type + "_injet_vhighpt"; + + if (TP_select_eventid != 0) + type = type + "_wpu"; + + if (useTightCuts) + type = type + "_tight"; + if (useDeadRegion) + type = type + "_dead"; + + if (L1Tk_seed != 0) { + char seedtxt[500]; + sprintf(seedtxt, "_seed%i", L1Tk_seed); + type = type + seedtxt; + } + + if (TP_minPt > 2.0) { + char pttxt[500]; + sprintf(pttxt, "_pt%.0f", TP_minPt); + type = type + pttxt; + } + + TFile* fout; + if (doLooseMatch) + fout = new TFile("output_looseMatch_" + type + treeName + ".root", "recreate"); + else + fout = new TFile(type_dir + "output_" + type + treeName + ".root", "recreate"); + + // ------------------------------------------------------------------------------------------- + // draw and save plots + // ------------------------------------------------------------------------------------------- + + char ctxt[500]; + TCanvas c; + + TString DIR = "TrkPlots/"; + + // plots overlaying 68, 90, 99% confidence levels] + + float max_eta_ptRel = 0.2; + float max_pt_ptRel = 0.2; + float max_pt_pt = 20; + float max_z0 = 2.0; + float max_phi = 0.01; + float max_eta = 0.03; + + if (type.Contains("El")) { + max_pt_ptRel = 1.0; + max_eta_ptRel = 1.0; + max_phi = 0.1; + } + + // makeResidualIntervalPlot will save the individual plots to the root file + makeResidualIntervalPlot( + type, DIR, "resVsPt_ptRel", h2_resVsPt_ptRel_68, h2_resVsPt_ptRel_90, h2_resVsPt_ptRel_99, 0, max_pt_ptRel); + makeResidualIntervalPlot(type, DIR, "resVsPt_pt", h2_resVsPt_pt_68, h2_resVsPt_pt_90, h2_resVsPt_pt_99, 0, max_pt_pt); + makeResidualIntervalPlot(type, DIR, "resVsPt_z0", h2_resVsPt_z0_68, h2_resVsPt_z0_90, h2_resVsPt_z0_99, 0, max_z0); + makeResidualIntervalPlot( + type, DIR, "resVsPt_phi", h2_resVsPt_phi_68, h2_resVsPt_phi_90, h2_resVsPt_phi_99, 0, max_phi); + makeResidualIntervalPlot( + type, DIR, "resVsPt_eta", h2_resVsPt_eta_68, h2_resVsPt_eta_90, h2_resVsPt_eta_99, 0, max_eta); + //makeResidualIntervalPlot( type, DIR, "resVsPt_d0", h2_resVsPt_d0_68, h2_resVsPt_d0_90, h2_resVsPt_d0_99, 0, 0.02 ); + + makeResidualIntervalPlot(type, + DIR, + "resVsPt_L_ptRel", + h2_resVsPt_ptRel_L_68, + h2_resVsPt_ptRel_L_90, + h2_resVsPt_ptRel_L_99, + 0, + max_pt_ptRel); + makeResidualIntervalPlot( + type, DIR, "resVsPt_L_pt", h2_resVsPt_pt_L_68, h2_resVsPt_pt_L_90, h2_resVsPt_pt_L_99, 0, max_pt_pt); + makeResidualIntervalPlot( + type, DIR, "resVsPt_L_z0", h2_resVsPt_z0_L_68, h2_resVsPt_z0_L_90, h2_resVsPt_z0_L_99, 0, max_z0); + makeResidualIntervalPlot( + type, DIR, "resVsPt_L_phi", h2_resVsPt_phi_L_68, h2_resVsPt_phi_L_90, h2_resVsPt_phi_L_99, 0, max_phi); + makeResidualIntervalPlot( + type, DIR, "resVsPt_L_eta", h2_resVsPt_eta_L_68, h2_resVsPt_eta_L_90, h2_resVsPt_eta_L_99, 0, max_eta); + //makeResidualIntervalPlot( type, DIR, "resVsPt_L_d0", h2_resVsPt_d0_L_68, h2_resVsPt_d0_L_90, h2_resVsPt_d0_L_99, 0, 0.02 ); + + makeResidualIntervalPlot( + type, DIR, "resVsEta_eta", h2_resVsEta_eta_68, h2_resVsEta_eta_90, h2_resVsEta_eta_99, 0, max_eta); + makeResidualIntervalPlot( + type, DIR, "resVsEta_z0", h2_resVsEta_z0_68, h2_resVsEta_z0_90, h2_resVsEta_z0_99, 0, max_z0); + makeResidualIntervalPlot( + type, DIR, "resVsEta_phi", h2_resVsEta_phi_68, h2_resVsEta_phi_90, h2_resVsEta_phi_99, 0, max_phi); + makeResidualIntervalPlot( + type, DIR, "resVsEta_ptRel", h2_resVsEta_ptRel_68, h2_resVsEta_ptRel_90, h2_resVsEta_ptRel_99, 0, max_eta_ptRel); + //makeResidualIntervalPlot( type, DIR, "resVsEta_d0", h2_resVsEta_d0_68, h2_resVsEta_d0_90, h2_resVsEta_d0_99, 0, 0.02 ); + + makeResidualIntervalPlot( + type, DIR, "resVsEta_L_eta", h2_resVsEta_eta_L_68, h2_resVsEta_eta_L_90, h2_resVsEta_eta_L_99, 0, max_eta); + makeResidualIntervalPlot( + type, DIR, "resVsEta_L_z0", h2_resVsEta_z0_L_68, h2_resVsEta_z0_L_90, h2_resVsEta_z0_L_99, 0, max_z0); + makeResidualIntervalPlot( + type, DIR, "resVsEta_L_phi", h2_resVsEta_phi_L_68, h2_resVsEta_phi_L_90, h2_resVsEta_phi_L_99, 0, max_phi); + makeResidualIntervalPlot(type, + DIR, + "resVsEta_L_ptRel", + h2_resVsEta_ptRel_L_68, + h2_resVsEta_ptRel_L_90, + h2_resVsEta_ptRel_L_99, + 0, + max_eta_ptRel); + //makeResidualIntervalPlot( type, DIR, "resVsEta_L_d0", h2_resVsEta_d0_L_68, h2_resVsEta_d0_L_90, h2_resVsEta_d0_L_99, 0, 0.02 ); + + makeResidualIntervalPlot( + type, DIR, "resVsEta_H_eta", h2_resVsEta_eta_H_68, h2_resVsEta_eta_H_90, h2_resVsEta_eta_H_99, 0, max_eta); + makeResidualIntervalPlot( + type, DIR, "resVsEta_H_z0", h2_resVsEta_z0_H_68, h2_resVsEta_z0_H_90, h2_resVsEta_z0_H_99, 0, max_z0); + makeResidualIntervalPlot( + type, DIR, "resVsEta_H_phi", h2_resVsEta_phi_H_68, h2_resVsEta_phi_H_90, h2_resVsEta_phi_H_99, 0, max_phi); + makeResidualIntervalPlot(type, + DIR, + "resVsEta_H_ptRel", + h2_resVsEta_ptRel_H_68, + h2_resVsEta_ptRel_H_90, + h2_resVsEta_ptRel_H_99, + 0, + max_eta_ptRel); + //makeResidualIntervalPlot( type, DIR, "resVsEta_H_d0", h2_resVsEta_d0_H_68, h2_resVsEta_d0_H_90, h2_resVsEta_d0_H_99, 0, 0.02 ); + + if (doDetailedPlots) { + makeResidualIntervalPlot( + type, DIR, "resVsPhi_ptRel", h2_resVsPhi_ptRel_68, h2_resVsPhi_ptRel_90, h2_resVsPhi_ptRel_99, 0, 0.5); + makeResidualIntervalPlot(type, DIR, "resVsPhi_pt", h2_resVsPhi_pt_68, h2_resVsPhi_pt_90, h2_resVsPhi_pt_99, 0, 20); + } + + // ---------------------------------------------------------------------------------------------------------- + // resoultion vs pt + // ---------------------------------------------------------------------------------------------------------- + + h2_resVsPt_pt_90->SetMinimum(0); + h2_resVsPt_pt_90->SetMarkerStyle(20); + h2_resVsPt_pt_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPt_pt_90.pdf"); + + h2_resVsPt_ptRel_90->SetMinimum(0); + h2_resVsPt_ptRel_90->SetMarkerStyle(20); + h2_resVsPt_ptRel_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPt_ptRel_90.pdf"); + + h2_resVsPt_z0_90->SetMinimum(0); + h2_resVsPt_z0_90->SetMarkerStyle(20); + h2_resVsPt_z0_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPt_z0_90.pdf"); + + h2_resVsPt_phi_90->SetMinimum(0); + h2_resVsPt_phi_90->SetMarkerStyle(20); + h2_resVsPt_phi_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPt_phi_90.pdf"); + + h2_resVsPt_eta_90->SetMinimum(0); + h2_resVsPt_eta_90->SetMarkerStyle(20); + h2_resVsPt_eta_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPt_eta_90.pdf"); + + /* + h2_resVsPt_phi_90->SetMinimum(0); + h2_resVsPt_d0_90->SetMarkerStyle(20); + h2_resVsPt_d0_90->Draw("p"); + c.SaveAs(DIR+type+"_resVsPt_d0_90.pdf"); + */ + + // Limit decimal places for doubles in normalized tracklet eff. graphs + gStyle->SetPaintTextFormat("4.2f"); + + h_trk_tracklet_eff->SetMinimum(0); + h_trk_tracklet_eff->Draw("col text"); + c.SaveAs(DIR + type + "_trk_tracklet_eff.pdf"); + + // Remove decimal places for ints in in tracklet hits graphs + gStyle->SetPaintTextFormat("4.0f"); + + h_trk_tracklet_hits->SetMinimum(0); + h_trk_tracklet_hits->Draw("col text"); + c.SaveAs(DIR + type + "_trk_tracklet_hits.pdf"); + + if (doDetailedPlots) { + h2_resVsPt_eta->Write(); + + h2_resVsPt_pt->Write(); + h2_resVsPt_pt_C->Write(); + h2_resVsPt_pt_I->Write(); + h2_resVsPt_pt_F->Write(); + + h2_resVsPt_ptRel->Write(); + h2_resVsPt_ptRel_C->Write(); + h2_resVsPt_ptRel_I->Write(); + h2_resVsPt_ptRel_F->Write(); + + h2_mresVsPt_pt->Write(); + h2_mresVsPt_pt_C->Write(); + h2_mresVsPt_pt_I->Write(); + h2_mresVsPt_pt_F->Write(); + + h2_resVsPt_d0->Write(); + + h2_resVsPt_z0_C->Write(); + h2_resVsPt_z0_I->Write(); + h2_resVsPt_z0_F->Write(); + + h2_resVsPt_phi->Write(); + h2_resVsPt_phi_C->Write(); + h2_resVsPt_phi_I->Write(); + h2_resVsPt_phi_F->Write(); + } + + // ---------------------------------------------------------------------------------------------------------- + // resolution vs eta + // ---------------------------------------------------------------------------------------------------------- + + h2_resVsEta_eta_90->SetMinimum(0); + h2_resVsEta_eta_90->SetMarkerStyle(20); + h2_resVsEta_eta_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_eta_90.pdf"); + + h2_resVsEta_eta_68->SetMinimum(0); + h2_resVsEta_eta_68->SetMarkerStyle(20); + h2_resVsEta_eta_68->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_eta_68.pdf"); + + if (doDetailedPlots) { + h2_resVsEta_eta_L_90->Draw("p"); + sprintf(ctxt, "p_{T} < 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_eta_L_90.pdf"); + + h2_resVsEta_eta_H_90->Draw("p"); + sprintf(ctxt, "p_{T} > 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_eta_H_90.pdf"); + } + + h2_resVsEta_z0_90->SetMinimum(0); + h2_resVsEta_z0_90->SetMarkerStyle(20); + h2_resVsEta_z0_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_z0_90.pdf"); + + h2_resVsEta_z0_68->SetMinimum(0); + h2_resVsEta_z0_68->SetMarkerStyle(20); + h2_resVsEta_z0_68->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_z0_68.pdf"); + + if (doDetailedPlots) { + h2_resVsEta_z0_L_90->Draw(); + sprintf(ctxt, "p_{T} < 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_z0_L_90.pdf"); + + h2_resVsEta_z0_H_90->Draw(); + sprintf(ctxt, "p_{T} > 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_z0_H_90.pdf"); + } + + /* + h2_resVsEta_d0_90->Draw(); + c.SaveAs(DIR+type+"_resVsEta_d0_90.pdf"); + + h2_resVsEta_d0_L_90->Draw(); + sprintf(ctxt,"p_{T} < 8 GeV"); + mySmallText(0.22,0.82,1,ctxt); + c.SaveAs(DIR+type+"_resVsEta_d0_L_90.pdf"); + + h2_resVsEta_d0_H_90->Draw(); + sprintf(ctxt,"p_{T} > 8 GeV"); + mySmallText(0.22,0.82,1,ctxt); + c.SaveAs(DIR+type+"_resVsEta_d0_H_90.pdf"); + */ + + h2_resVsEta_phi_90->SetMinimum(0); + h2_resVsEta_phi_90->SetMarkerStyle(20); + h2_resVsEta_phi_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_phi_90.pdf"); + + h2_resVsEta_phi_68->SetMinimum(0); + h2_resVsEta_phi_68->SetMarkerStyle(20); + h2_resVsEta_phi_68->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_phi_68.pdf"); + + if (doDetailedPlots) { + h2_resVsEta_phi_L_90->Draw(); + sprintf(ctxt, "p_{T} < 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_phi_L_90.pdf"); + + h2_resVsEta_phi_H_90->Draw(); + sprintf(ctxt, "p_{T} > 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_phi_H_90.pdf"); + } + + h2_resVsEta_ptRel_90->SetMinimum(0); + h2_resVsEta_ptRel_90->SetMarkerStyle(20); + h2_resVsEta_ptRel_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_ptRel_90.pdf"); + + h2_resVsEta_ptRel_68->SetMinimum(0); + h2_resVsEta_ptRel_68->SetMarkerStyle(20); + h2_resVsEta_ptRel_68->Draw("p"); + c.SaveAs(DIR + type + "_resVsEta_ptRel_68.pdf"); + + if (doDetailedPlots) { + h2_resVsEta_ptRel_L_90->Draw(); + sprintf(ctxt, "p_{T} < 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_ptRel_L_90.pdf"); + + h2_resVsEta_ptRel_H_90->Draw(); + sprintf(ctxt, "p_{T} > 8 GeV"); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_resVsEta_ptRel_H_90.pdf"); + + h2_resVsEta_eta->Write(); + h2_resVsEta_eta_L->Write(); + h2_resVsEta_eta_H->Write(); + + h2_resVsEta_z0->Draw(); + c.SaveAs(DIR + type + "_resVsEta_z0_rms.pdf"); + h2_resVsEta_eta->Draw(); + c.SaveAs(DIR + type + "_resVsEta_eta_rms.pdf"); + h2_resVsEta_ptRel->Draw(); + c.SaveAs(DIR + type + "_resVsEta_ptRel_rms.pdf"); + h2_resVsEta_phi->Draw(); + c.SaveAs(DIR + type + "_resVsEta_phi_rms.pdf"); + + // check residuals + h2_mresVsEta_z0->Draw(); + h2_mresVsEta_z0->Write(); + c.SaveAs(DIR + type + "_mean-resVsEta_z0.pdf"); + + h2_mresVsEta_eta->Draw(); + h2_mresVsEta_eta->Write(); + c.SaveAs(DIR + type + "_mean-resVsEta_eta.pdf"); + + h2_mresVsEta_ptRel->Draw(); + h2_mresVsEta_ptRel->Write(); + c.SaveAs(DIR + type + "_mean-resVsEta_ptRel.pdf"); + + h2_mresVsEta_phi->Draw(); + h2_mresVsEta_phi->Write(); + c.SaveAs(DIR + type + "_mean-resVsEta_phi.pdf"); + + h2_resVsEta_z0->Write(); + h2_resVsEta_z0_L->Write(); + h2_resVsEta_z0_H->Write(); + + h2_resVsEta_d0->Write(); + h2_resVsEta_d0_L->Write(); + h2_resVsEta_d0_H->Write(); + + h2_resVsEta_phi->Write(); + h2_resVsEta_phi_L->Write(); + h2_resVsEta_phi_H->Write(); + + h2_resVsEta_ptRel->Write(); + h2_resVsEta_ptRel_L->Write(); + h2_resVsEta_ptRel_H->Write(); + } + + if (doGausFit) { + h3_resVsEta_eta_L->Write(); + h3_resVsEta_z0_L->Write(); + h3_resVsEta_phi_L->Write(); + h3_resVsEta_ptRel_L->Write(); + + h3_resVsEta_eta_H->Write(); + h3_resVsEta_z0_H->Write(); + h3_resVsEta_phi_H->Write(); + h3_resVsEta_ptRel_H->Write(); + } + + // resolution vs phi + if (doDetailedPlots) { + h2_resVsPhi_pt_90->SetMinimum(0); + h2_resVsPhi_pt_90->SetMarkerStyle(20); + h2_resVsPhi_pt_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPhi_pt_90.pdf"); + + h2_resVsPhi_ptRel_90->SetMinimum(0); + h2_resVsPhi_ptRel_90->SetMarkerStyle(20); + h2_resVsPhi_ptRel_90->Draw("p"); + c.SaveAs(DIR + type + "_resVsPhi_ptRel_90.pdf"); + } + + // ---------------------------------------------------------------------------------------------------------------- + // track quality plots + // ---------------------------------------------------------------------------------------------------------------- + + if (doDetailedPlots) { + h_match_trk_nstub->Write(); + h_match_trk_nstub_C->Write(); + h_match_trk_nstub_I->Write(); + h_match_trk_nstub_F->Write(); + } + + h_trk_chi2->Draw(); + sprintf(ctxt, "|eta| < 2.4"); + mySmallText(0.52, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_trk_chi2.pdf"); + + h_trk_chi2_dof->Draw(); + sprintf(ctxt, "|eta| < 2.4"); + mySmallText(0.52, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_trk_chi2_dof.pdf"); + + h_trk_chi2rphi->Draw(); + sprintf(ctxt, "|eta| < 2.4"); + mySmallText(0.52, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_trk_chi2rphi.pdf"); + + h_trk_chi2rphi_dof->Draw(); + sprintf(ctxt, "|eta| < 2.4"); + mySmallText(0.52, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_trk_chi2rphi_dof.pdf"); + + h_trk_chi2rz->Draw(); + sprintf(ctxt, "|eta| < 2.4"); + mySmallText(0.52, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_trk_chi2rz.pdf"); + + h_trk_chi2rz_dof->Draw(); + sprintf(ctxt, "|eta| < 2.4"); + mySmallText(0.52, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_trk_chi2rz_dof.pdf"); + + h_trk_chi2->Write(); + h_trk_chi2rphi->Write(); + h_trk_chi2rz->Write(); + h_match_trk_chi2->Write(); + h_match_trk_chi2rphi->Write(); + h_match_trk_chi2rz->Write(); + + if (doDetailedPlots) { + h_match_trk_chi2_C_L->Write(); + h_match_trk_chi2_I_L->Write(); + h_match_trk_chi2_F_L->Write(); + h_match_trk_chi2_C_H->Write(); + h_match_trk_chi2_I_H->Write(); + h_match_trk_chi2_F_H->Write(); + + h_match_trk_chi2_dof_C_L->Write(); + h_match_trk_chi2_dof_I_L->Write(); + h_match_trk_chi2_dof_F_L->Write(); + h_match_trk_chi2_dof_C_H->Write(); + h_match_trk_chi2_dof_I_H->Write(); + h_match_trk_chi2_dof_F_H->Write(); + } + + // ---------------------------------------------------------------------------------------------------------------- + // efficiency plots + // ---------------------------------------------------------------------------------------------------------------- + + // rebin pt/phi plots + h_tp_pt->Rebin(2); + h_match_tp_pt->Rebin(2); + h_tp_phi->Rebin(2); + h_match_tp_phi->Rebin(2); + + h_tp_pt_L->Rebin(2); + h_match_tp_pt_L->Rebin(2); + h_tp_pt_LC->Rebin(2); + h_match_tp_pt_LC->Rebin(2); + h_tp_pt_H->Rebin(2); + h_match_tp_pt_H->Rebin(2); + + h_tp_eta->Rebin(2); + h_match_tp_eta->Rebin(2); + h_tp_eta_L->Rebin(2); + h_match_tp_eta_L->Rebin(2); + h_tp_eta_H->Rebin(2); + h_match_tp_eta_H->Rebin(2); + + // calculate the effeciency + h_match_tp_pt->Sumw2(); + h_tp_pt->Sumw2(); + TH1F* h_eff_pt = (TH1F*)h_match_tp_pt->Clone(); + h_eff_pt->SetName("eff_pt"); + h_eff_pt->GetYaxis()->SetTitle("Efficiency"); + h_eff_pt->Divide(h_match_tp_pt, h_tp_pt, 1.0, 1.0, "B"); + + h_match_tp_pt_L->Sumw2(); + h_tp_pt_L->Sumw2(); + TH1F* h_eff_pt_L = (TH1F*)h_match_tp_pt_L->Clone(); + h_eff_pt_L->SetName("eff_pt_L"); + h_eff_pt_L->GetYaxis()->SetTitle("Efficiency"); + h_eff_pt_L->Divide(h_match_tp_pt_L, h_tp_pt_L, 1.0, 1.0, "B"); + + h_match_tp_pt_LC->Sumw2(); + h_tp_pt_LC->Sumw2(); + TH1F* h_eff_pt_LC = (TH1F*)h_match_tp_pt_LC->Clone(); + h_eff_pt_LC->SetName("eff_pt_LC"); + h_eff_pt_LC->GetYaxis()->SetTitle("Efficiency"); + h_eff_pt_LC->Divide(h_match_tp_pt_LC, h_tp_pt_LC, 1.0, 1.0, "B"); + + h_match_tp_pt_H->Sumw2(); + h_tp_pt_H->Sumw2(); + TH1F* h_eff_pt_H = (TH1F*)h_match_tp_pt_H->Clone(); + h_eff_pt_H->SetName("eff_pt_H"); + h_eff_pt_H->GetYaxis()->SetTitle("Efficiency"); + h_eff_pt_H->Divide(h_match_tp_pt_H, h_tp_pt_H, 1.0, 1.0, "B"); + + h_match_tp_eta->Sumw2(); + h_tp_eta->Sumw2(); + TH1F* h_eff_eta = (TH1F*)h_match_tp_eta->Clone(); + h_eff_eta->SetName("eff_eta"); + h_eff_eta->GetYaxis()->SetTitle("Efficiency"); + h_eff_eta->Divide(h_match_tp_eta, h_tp_eta, 1.0, 1.0, "B"); + + h_match_tp_eta_L->Sumw2(); + h_tp_eta_L->Sumw2(); + TH1F* h_eff_eta_L = (TH1F*)h_match_tp_eta_L->Clone(); + h_eff_eta_L->SetName("eff_eta_L"); + h_eff_eta_L->GetYaxis()->SetTitle("Efficiency"); + h_eff_eta_L->Divide(h_match_tp_eta_L, h_tp_eta_L, 1.0, 1.0, "B"); + + h_match_tp_eta_H->Sumw2(); + h_tp_eta_H->Sumw2(); + TH1F* h_eff_eta_H = (TH1F*)h_match_tp_eta_H->Clone(); + h_eff_eta_H->SetName("eff_eta_H"); + h_eff_eta_H->GetYaxis()->SetTitle("Efficiency"); + h_eff_eta_H->Divide(h_match_tp_eta_H, h_tp_eta_H, 1.0, 1.0, "B"); + + h_match_tp_eta_23->Sumw2(); + h_tp_eta_23->Sumw2(); + TH1F* h_eff_eta_23 = (TH1F*)h_match_tp_eta_23->Clone(); + h_eff_eta_23->SetName("eff_eta_23"); + h_eff_eta_23->GetYaxis()->SetTitle("Efficiency"); + h_eff_eta_23->Divide(h_match_tp_eta_23, h_tp_eta_23, 1.0, 1.0, "B"); + + h_match_tp_eta_35->Sumw2(); + h_tp_eta_35->Sumw2(); + TH1F* h_eff_eta_35 = (TH1F*)h_match_tp_eta_35->Clone(); + h_eff_eta_35->SetName("eff_eta_35"); + h_eff_eta_35->GetYaxis()->SetTitle("Efficiency"); + h_eff_eta_35->Divide(h_match_tp_eta_35, h_tp_eta_35, 1.0, 1.0, "B"); + + h_match_tp_eta_5->Sumw2(); + h_tp_eta_5->Sumw2(); + TH1F* h_eff_eta_5 = (TH1F*)h_match_tp_eta_5->Clone(); + h_eff_eta_5->SetName("eff_eta_5"); + h_eff_eta_5->GetYaxis()->SetTitle("Efficiency"); + h_eff_eta_5->Divide(h_match_tp_eta_5, h_tp_eta_5, 1.0, 1.0, "B"); + + h_match_tp_phi->Sumw2(); + h_tp_phi->Sumw2(); + TH1F* h_eff_phi = (TH1F*)h_match_tp_phi->Clone(); + h_eff_phi->SetName("eff_phi"); + h_eff_phi->GetYaxis()->SetTitle("Efficiency"); + h_eff_phi->Divide(h_match_tp_phi, h_tp_phi, 1.0, 1.0, "B"); + + h_match_tp_z0->Sumw2(); + h_tp_z0->Sumw2(); + TH1F* h_eff_z0 = (TH1F*)h_match_tp_z0->Clone(); + h_eff_z0->SetName("eff_z0"); + h_eff_z0->GetYaxis()->SetTitle("Efficiency"); + h_eff_z0->Divide(h_match_tp_z0, h_tp_z0, 1.0, 1.0, "B"); + + h_match_tp_z0_L->Sumw2(); + h_tp_z0_L->Sumw2(); + TH1F* h_eff_z0_L = (TH1F*)h_match_tp_z0_L->Clone(); + h_eff_z0_L->SetName("eff_z0_L"); + h_eff_z0_L->GetYaxis()->SetTitle("Efficiency"); + h_eff_z0_L->Divide(h_match_tp_z0_L, h_tp_z0_L, 1.0, 1.0, "B"); + + h_match_tp_z0_H->Sumw2(); + h_tp_z0_H->Sumw2(); + TH1F* h_eff_z0_H = (TH1F*)h_match_tp_z0_H->Clone(); + h_eff_z0_H->SetName("eff_z0_H"); + h_eff_z0_H->GetYaxis()->SetTitle("Efficiency"); + h_eff_z0_H->Divide(h_match_tp_z0_H, h_tp_z0_H, 1.0, 1.0, "B"); + + h_match_tp_d0->Sumw2(); + h_tp_d0->Sumw2(); + TH1F* h_eff_d0 = (TH1F*)h_match_tp_d0->Clone(); + h_eff_d0->SetName("eff_d0"); + h_eff_d0->GetYaxis()->SetTitle("Efficiency"); + h_eff_d0->Divide(h_match_tp_d0, h_tp_d0, 1.0, 1.0, "B"); + + h_match_tp_absd0->Sumw2(); + h_tp_absd0->Sumw2(); + TH1F* h_eff_absd0 = (TH1F*)h_match_tp_absd0->Clone(); + h_eff_absd0->SetName("eff_absd0"); + h_eff_absd0->GetYaxis()->SetTitle("Efficiency"); + h_eff_absd0->Divide(h_match_tp_absd0, h_tp_absd0, 1.0, 1.0, "B"); + + h_match_tp_absd0_eta2->Sumw2(); + h_tp_absd0_eta2->Sumw2(); + TH1F* h_eff_absd0_eta2 = (TH1F*)h_match_tp_absd0_eta2->Clone(); + h_eff_absd0_eta2->SetName("eff_absd0_eta2"); + h_eff_absd0_eta2->GetYaxis()->SetTitle("Efficiency"); + h_eff_absd0_eta2->Divide(h_match_tp_absd0_eta2, h_tp_absd0_eta2, 1.0, 1.0, "B"); + + h_match_tp_absd0_eta2_pt3->Sumw2(); + h_tp_absd0_eta2_pt3->Sumw2(); + TH1F* h_eff_absd0_eta2_pt3 = (TH1F*)h_match_tp_absd0_eta2_pt3->Clone(); + h_eff_absd0_eta2_pt3->SetName("eff_absd0_eta2_pt3"); + h_eff_absd0_eta2_pt3->GetYaxis()->SetTitle("Efficiency"); + h_eff_absd0_eta2_pt3->Divide(h_match_tp_absd0_eta2_pt3, h_tp_absd0_eta2_pt3, 1.0, 1.0, "B"); + + // set the axis range + h_eff_pt->SetAxisRange(0, 1.1, "Y"); + h_eff_pt_L->SetAxisRange(0, 1.1, "Y"); + h_eff_pt_LC->SetAxisRange(0, 1.1, "Y"); + h_eff_pt_H->SetAxisRange(0, 1.1, "Y"); + h_eff_eta->SetAxisRange(0, 1.1, "Y"); + h_eff_eta_L->SetAxisRange(0, 1.1, "Y"); + h_eff_eta_H->SetAxisRange(0, 1.1, "Y"); + h_eff_eta_23->SetAxisRange(0, 1.1, "Y"); + h_eff_eta_35->SetAxisRange(0, 1.1, "Y"); + h_eff_eta_5->SetAxisRange(0, 1.1, "Y"); + h_eff_phi->SetAxisRange(0, 1.1, "Y"); + h_eff_z0->SetAxisRange(0, 1.1, "Y"); + h_eff_z0_L->SetAxisRange(0, 1.1, "Y"); + h_eff_z0_H->SetAxisRange(0, 1.1, "Y"); + h_eff_d0->SetAxisRange(0, 1.1, "Y"); + h_eff_absd0->SetAxisRange(0, 1.1, "Y"); + h_eff_absd0_eta2->SetAxisRange(0, 1.1, "Y"); + h_eff_absd0_eta2_pt3->SetAxisRange(0, 1.1, "Y"); + + gPad->SetGridx(); + gPad->SetGridy(); + + // draw and save plots + h_eff_pt->Draw(); + h_eff_pt->Write(); + c.SaveAs(DIR + type + "_eff_pt.pdf"); + + if (type.Contains("Mu")) { + h_eff_pt->GetYaxis()->SetRangeUser(0.8, 1.01); // zoomed-in plot + c.SaveAs(DIR + type + "_eff_pt_zoom.pdf"); + } + + h_eff_pt_L->Draw(); + h_eff_pt_L->Write(); + sprintf(ctxt, "p_{T} < 8 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_pt_L.pdf"); + + if (doDetailedPlots) { + h_eff_pt_LC->Draw(); + h_eff_pt_LC->Write(); + sprintf(ctxt, "p_{T} < 8 GeV, |#eta|<1.0"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_pt_LC.pdf"); + } + h_eff_pt_H->Draw(); + h_eff_pt_H->Write(); + sprintf(ctxt, "p_{T} > 8 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_pt_H.pdf"); + + h_eff_eta->Draw(); + h_eff_eta->Write(); + c.SaveAs(DIR + type + "_eff_eta.pdf"); + + if (type.Contains("Mu")) { + h_eff_eta->GetYaxis()->SetRangeUser(0.8, 1.01); // zoomed-in plot + c.SaveAs(DIR + type + "_eff_eta_zoom.pdf"); + } + + h_eff_eta_L->Draw(); + h_eff_eta_L->Write(); + sprintf(ctxt, "p_{T} < 8 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_eta_L.pdf"); + + h_eff_eta_H->Draw(); + h_eff_eta_H->Write(); + sprintf(ctxt, "p_{T} > 8 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_eta_H.pdf"); + + h_eff_eta_23->Write(); + h_eff_eta_35->Write(); + h_eff_eta_5->Write(); + + if (doDetailedPlots) { + h_eff_eta_23->Draw(); + sprintf(ctxt, "2 < p_{T} < 3 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_eta_23.pdf"); + + h_eff_eta_35->Draw(); + sprintf(ctxt, "3 < p_{T} < 5 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_eta_35.pdf"); + + h_eff_eta_5->Draw(); + sprintf(ctxt, "p_{T} > 5 GeV"); + mySmallText(0.45, 0.5, 1, ctxt); + c.SaveAs(DIR + type + "_eff_eta_5.pdf"); + + h_eff_z0->Draw(); + h_eff_z0->Write(); + c.SaveAs(DIR + type + "_eff_z0.pdf"); + + h_eff_z0_L->Write(); + h_eff_z0_H->Write(); + + h_eff_phi->Draw(); + h_eff_phi->Write(); + c.SaveAs(DIR + type + "_eff_phi.pdf"); + + if (type.Contains("Mu")) { + h_eff_phi->GetYaxis()->SetRangeUser(0.8, 1.01); // zoomed-in plot + c.SaveAs(DIR + type + "_eff_phi_zoom.pdf"); + } + } + + if (doDetailedPlots || TP_maxD0 > 1.0) { + h_eff_d0->Write(); + h_eff_absd0->Write(); + h_eff_absd0_eta2->Write(); + h_eff_absd0_eta2_pt3->Write(); + + h_eff_d0->Draw(); + c.SaveAs(DIR + type + "_eff_d0.pdf"); + + h_eff_absd0->Draw(); + c.SaveAs(DIR + type + "_eff_absd0.pdf"); + + h_eff_absd0_eta2->Draw(); + c.SaveAs(DIR + type + "_eff_absd0_eta2.pdf"); + + h_eff_absd0_eta2_pt3->Draw(); + c.SaveAs(DIR + type + "_eff_absd0_eta2_pt3.pdf"); + } + + gPad->SetGridx(0); + gPad->SetGridy(0); + + // ---------------------------------------------------------------------------------------------------------------- + // more resolution plots + // ---------------------------------------------------------------------------------------------------------------- + + float rms = 0; + + if (doDetailedPlots) { + // draw and save plots + h_res_pt->Draw(); + rms = h_res_pt->GetRMS(); + sprintf(ctxt, "RMS = %.4f", rms); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_res_pt.pdf"); + + h_res_ptRel->Draw(); + rms = h_res_ptRel->GetRMS(); + sprintf(ctxt, "RMS = %.4f", rms); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_res_ptRel.pdf"); + + h_res_eta->Draw(); + rms = h_res_eta->GetRMS(); + sprintf(ctxt, "RMS = %.3e", rms); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_res_eta.pdf"); + + h_res_phi->Draw(); + rms = h_res_phi->GetRMS(); + sprintf(ctxt, "RMS = %.3e", rms); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_res_phi.pdf"); + + h_res_z0->Draw(); + rms = h_res_z0->GetRMS(); + sprintf(ctxt, "RMS = %.4f", rms); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0.pdf"); + + h_res_z0_C->Draw(); + rms = h_res_z0_C->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| < 0.8"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_C.pdf"); + + h_res_z0_I->Draw(); + rms = h_res_z0_I->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "0.8 < |eta| < 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_I.pdf"); + + h_res_z0_F->Draw(); + rms = h_res_z0_F->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| > 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_F.pdf"); + + h_res_z0_C_L->Draw(); + h_res_z0_C_L->Write(); + rms = h_res_z0_C_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| < 0.8"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_C_L.pdf"); + + h_res_z0_I_L->Draw(); + h_res_z0_I_L->Write(); + rms = h_res_z0_I_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "0.8 < |eta| < 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_I_L.pdf"); + + h_res_z0_F_L->Draw(); + h_res_z0_F_L->Write(); + rms = h_res_z0_F_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| > 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_F_L.pdf"); + + h_res_z0_C_H->Draw(); + h_res_z0_C_H->Write(); + rms = h_res_z0_C_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| < 0.8"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_C_H.pdf"); + + h_res_z0_I_H->Draw(); + h_res_z0_I_H->Write(); + rms = h_res_z0_I_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "0.8 < |eta| < 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_I_H.pdf"); + + h_res_z0_F_H->Draw(); + h_res_z0_F_H->Write(); + rms = h_res_z0_F_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| > 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_F_H.pdf"); + + h_res_z0_L->Draw(); + h_res_z0_L->Write(); + rms = h_res_z0_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "p_{T} < 5 GeV"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_L.pdf"); + + h_res_z0_H->Draw(); + h_res_z0_H->Write(); + rms = h_res_z0_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "p_{T} > 15 GeV"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_z0_H.pdf"); + + if (h_res_d0->GetEntries() > 0) { + h_res_d0->Draw(); + rms = h_res_d0->GetRMS(); + sprintf(ctxt, "RMS = %.4f", rms); + mySmallText(0.22, 0.82, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0.pdf"); + + h_res_d0_C->Draw(); + h_res_d0_C->Write(); + rms = h_res_d0_C->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| < 0.8"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_C.pdf"); + + h_res_d0_I->Draw(); + h_res_d0_I->Write(); + rms = h_res_d0_I->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "0.8 < |eta| < 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_I.pdf"); + + h_res_d0_F->Draw(); + h_res_d0_F->Write(); + rms = h_res_d0_F->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| > 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_F.pdf"); + + h_res_d0_C_L->Draw(); + h_res_d0_C_L->Write(); + rms = h_res_d0_C_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| < 0.8"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_C_L.pdf"); + + h_res_d0_I_L->Draw(); + h_res_d0_I_L->Write(); + rms = h_res_d0_I_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "0.8 < |eta| < 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_I_L.pdf"); + + h_res_d0_F_L->Draw(); + h_res_d0_F_L->Write(); + rms = h_res_d0_F_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| > 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_F_L.pdf"); + + h_res_d0_C_H->Draw(); + h_res_d0_C_H->Write(); + rms = h_res_d0_C_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| < 0.8"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_C_H.pdf"); + + h_res_d0_I_H->Draw(); + h_res_d0_I_H->Write(); + rms = h_res_d0_I_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "0.8 < |eta| < 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_I_H.pdf"); + + h_res_d0_F_H->Draw(); + h_res_d0_F_H->Write(); + rms = h_res_d0_F_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "|eta| > 1.6"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_F_H.pdf"); + + h_res_d0_L->Draw(); + h_res_d0_L->Write(); + rms = h_res_d0_L->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "p_{T} < 5 GeV"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_L.pdf"); + + h_res_d0_H->Draw(); + h_res_d0_H->Write(); + rms = h_res_d0_H->GetRMS(); + sprintf(ctxt, "RMS = %.4f;", rms); + mySmallText(0.22, 0.82, 1, ctxt); + sprintf(ctxt, "p_{T} > 15 GeV"); + mySmallText(0.22, 0.76, 1, ctxt); + c.SaveAs(DIR + type + "_res_d0_H.pdf"); + } + } + + // --------------------------------------------------------------------------------------------------------- + // "fake rates" + + h_trk_all_vspt->Sumw2(); + h_trk_loose_vspt->Sumw2(); + h_trk_genuine_vspt->Sumw2(); + h_trk_notloose_vspt->Sumw2(); + h_trk_notgenuine_vspt->Sumw2(); + h_trk_duplicate_vspt->Sumw2(); + h_tp_vspt->Sumw2(); + + // fraction of not genuine tracks + TH1F* h_notgenuine_pt = (TH1F*)h_trk_notgenuine_vspt->Clone(); + h_notgenuine_pt->SetName("notgenuine_pt"); + h_notgenuine_pt->GetYaxis()->SetTitle("Not genuine fraction"); + h_notgenuine_pt->Divide(h_trk_notgenuine_vspt, h_trk_all_vspt, 1.0, 1.0, "B"); + + h_notgenuine_pt->Write(); + h_notgenuine_pt->Draw(); + c.SaveAs(DIR + type + "_notgenuine.pdf"); + + // fraction of not loosely genuine tracks + TH1F* h_notloose_pt = (TH1F*)h_trk_notloose_vspt->Clone(); + h_notloose_pt->SetName("notloose_pt"); + h_notloose_pt->GetYaxis()->SetTitle("Not loose fraction"); + h_notloose_pt->Divide(h_trk_notloose_vspt, h_trk_all_vspt, 1.0, 1.0, "B"); + + h_notloose_pt->Write(); + h_notloose_pt->Draw(); + c.SaveAs(DIR + type + "_notloose.pdf"); + + // fraction of DUPLICATE tracks (genuine and not matched) + TH1F* h_duplicatefrac_pt = (TH1F*)h_trk_duplicate_vspt->Clone(); + h_duplicatefrac_pt->SetName("duplicatefrac_pt"); + h_duplicatefrac_pt->GetYaxis()->SetTitle("Duplicate fraction"); + h_duplicatefrac_pt->Divide(h_trk_duplicate_vspt, h_trk_all_vspt, 1.0, 1.0, "B"); + + h_duplicatefrac_pt->Write(); + h_duplicatefrac_pt->Draw(); + c.SaveAs(DIR + type + "_duplicatefrac.pdf"); + + // --------------------------------------------------------------------------------------------------------- + // total track rates vs pt + + h_trk_all_vspt->Scale(1.0 / nevt); + h_trk_loose_vspt->Scale(1.0 / nevt); + h_trk_genuine_vspt->Scale(1.0 / nevt); + h_trk_notloose_vspt->Scale(1.0 / nevt); + h_trk_notgenuine_vspt->Scale(1.0 / nevt); + h_trk_duplicate_vspt->Scale(1.0 / nevt); + h_tp_vspt->Scale(1.0 / nevt); + + h_tp_vspt->GetYaxis()->SetTitle("Tracks / event"); + h_tp_vspt->GetXaxis()->SetTitle("Track p_{T} [GeV]"); + h_tp_vspt->SetLineColor(4); + h_tp_vspt->SetLineStyle(2); + + h_trk_notgenuine_vspt->SetLineColor(2); + h_trk_notgenuine_vspt->SetLineStyle(1); + + h_trk_duplicate_vspt->SetLineColor(8); + h_trk_duplicate_vspt->SetLineStyle(2); + + float max = h_tp_vspt->GetMaximum(); + if (h_trk_all_vspt->GetMaximum() > max) + max = h_trk_all_vspt->GetMaximum(); + h_tp_vspt->SetAxisRange(0.001, max * 1.5, "Y"); + + h_tp_vspt->Draw("hist"); + h_trk_all_vspt->Draw("same,hist"); + h_tp_vspt->Draw("same,hist"); + h_trk_notgenuine_vspt->Draw("same,hist"); + //h_trk_duplicate_vspt->Draw("same,hist"); + + h_trk_all_vspt->Write(); + h_trk_loose_vspt->Write(); + h_trk_genuine_vspt->Write(); + h_trk_notloose_vspt->Write(); + h_trk_notgenuine_vspt->Write(); + h_trk_duplicate_vspt->Write(); + h_tp_vspt->Write(); + + char txt[500]; + sprintf(txt, "# tracks/event = %.1f", h_trk_all_vspt->GetSum()); + mySmallText(0.5, 0.85, 1, txt); + char txt3[500]; + sprintf(txt3, "# TPs(stubs in #geq 4 layers)/"); + char txt2[500]; + sprintf(txt2, "event = %.1f", h_tp_vspt->GetSum()); + mySmallText(0.5, 0.79, 4, txt3); + mySmallText(0.5, 0.74, 4, txt2); + + sprintf(txt, "# !genuine tracks/event = %.1f", h_trk_notgenuine_vspt->GetSum()); + mySmallText(0.5, 0.69, 2, txt); + //sprintf(txt,"# duplicates/event = %.1f",h_trk_duplicate_vspt->GetSum()); + //mySmallText(0.5,0.64,8,txt); + + c.SaveAs(DIR + type + "_trackrate_vspt.pdf"); + + gPad->SetLogy(); + c.SaveAs(DIR + type + "_trackrate_vspt_log.pdf"); + gPad->SetLogy(0); + + // --------------------------------------------------------------------------------------------------------- + // sum track/ TP pt in jets + /* + if (TP_select_injet > 0) { + + TH1F* h_frac_sumpt_vspt = (TH1F*) h_jet_trk_sumpt_vspt->Clone(); + h_frac_sumpt_vspt->SetName("frac_sumpt_vspt"); + h_frac_sumpt_vspt->GetYaxis()->SetTitle("L1 sum(p_{T}) / TP sum(p_{T})"); + h_frac_sumpt_vspt->Divide(h_jet_trk_sumpt_vspt, h_jet_tp_sumpt_vspt, 1.0, 1.0, "B"); + + TH1F* h_frac_sumpt_vseta = (TH1F*) h_jet_trk_sumpt_vseta->Clone(); + h_frac_sumpt_vseta->SetName("frac_sumpt_vseta"); + h_frac_sumpt_vseta->GetYaxis()->SetTitle("L1 sum(p_{T}) / TP sum(p_{T})"); + h_frac_sumpt_vseta->Divide(h_jet_trk_sumpt_vseta, h_jet_tp_sumpt_vseta, 1.0, 1.0, "B"); + + + TH1F* h_matchfrac_sumpt_vspt = (TH1F*) h_jet_matchtrk_sumpt_vspt->Clone(); + h_matchfrac_sumpt_vspt->SetName("matchfrac_sumpt_vspt"); + h_matchfrac_sumpt_vspt->GetYaxis()->SetTitle("Matched L1 sum(p_{T}) / TP sum(p_{T})"); + h_matchfrac_sumpt_vspt->Divide(h_jet_matchtrk_sumpt_vspt, h_jet_tp_sumpt_vspt, 1.0, 1.0, "B"); + + TH1F* h_matchfrac_sumpt_vseta = (TH1F*) h_jet_matchtrk_sumpt_vseta->Clone(); + h_matchfrac_sumpt_vseta->SetName("matchfrac_sumpt_vseta"); + h_matchfrac_sumpt_vseta->GetYaxis()->SetTitle("Matched L1 sum(p_{T}) / TP sum(p_{T})"); + h_matchfrac_sumpt_vseta->Divide(h_jet_matchtrk_sumpt_vseta, h_jet_tp_sumpt_vseta, 1.0, 1.0, "B"); + + + h_frac_sumpt_vspt->Draw(); + c.SaveAs(DIR+type+"_sumpt_vspt.pdf"); + + h_frac_sumpt_vseta->Draw(); + c.SaveAs(DIR+type+"_sumpt_vseta.pdf"); + + h_matchfrac_sumpt_vspt->Draw(); + c.SaveAs(DIR+type+"_sumpt_match_vspt.pdf"); + + h_matchfrac_sumpt_vseta->Draw(); + c.SaveAs(DIR+type+"_sumpt_match_vseta.pdf"); + } + */ + + // nbr tracks per event + + h_ntrk_pt2->Write(); + h_ntrk_pt3->Write(); + h_ntrk_pt10->Write(); + + h_ntrkPerSector_pt2->Write(); + h_ntrkPerSector_pt3->Write(); + h_ntrkPerSector_pt4->Write(); + + h_ntrkPerSector_pt2->Scale(1.0 / nevt); + h_ntrkPerSector_pt3->Scale(1.0 / nevt); + h_ntrkPerSector_pt4->Scale(1.0 / nevt); + + h_ntrkPerSector_pt2->GetYaxis()->SetTitle("Fraction of events"); + h_ntrkPerSector_pt2->GetXaxis()->SetTitle("Max number of transmitted tracks per #phi sector"); + + h_ntrkPerSector_pt2->SetLineColor(4); + h_ntrkPerSector_pt3->SetLineColor(2); + h_ntrkPerSector_pt4->SetLineColor(8); + + max = h_ntrkPerSector_pt2->GetMaximum(); + h_ntrkPerSector_pt2->SetAxisRange(0.00001, max * 5, "Y"); + h_ntrkPerSector_pt2->SetAxisRange(0., 100, "X"); + + h_ntrkPerSector_pt2->Draw("hist"); + h_ntrkPerSector_pt3->Draw("same,hist"); + h_ntrkPerSector_pt4->Draw("same,hist"); + gPad->SetLogy(); + + TLegend* l = new TLegend(0.6, 0.55, 0.85, 0.85); + l->SetFillStyle(0); + l->SetBorderSize(0); + l->SetTextSize(0.04); + l->AddEntry(h_ntrkPerSector_pt2, "p_{T}^{track} > 2 GeV", "l"); + l->AddEntry(h_ntrkPerSector_pt3, "p_{T}^{track} > 3 GeV", "l"); + l->AddEntry(h_ntrkPerSector_pt4, "p_{T}^{track} > 4 GeV", "l"); + l->SetTextFont(42); + l->Draw(); + + c.SaveAs(DIR + type + "_trackRatePerPhiSector_log.pdf"); + gPad->SetLogy(0); + + h_ntrk_genuine_pt2->Write(); + h_ntrk_genuine_pt3->Write(); + h_ntrk_genuine_pt10->Write(); + + if (doDetailedPlots) { + h_ntrk_pt2->Draw(); + c.SaveAs(DIR + type + "_trackrate_pt2_perevt.pdf"); + + h_ntrk_pt3->Draw(); + c.SaveAs(DIR + type + "_trackrate_pt3_perevt.pdf"); + + h_ntrk_pt10->Draw(); + c.SaveAs(DIR + type + "_trackrate_pt10_perevt.pdf"); + } + + fout->Close(); + + // --------------------------------------------------------------------------------------------------------- + //some printouts + + float k = (float)n_match_eta1p0; + float N = (float)n_all_eta1p0; + if (std::abs(N) > 0) + cout << endl + << "efficiency for |eta| < 1.0 = " << k / N * 100.0 << " +- " << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 + << endl; + k = (float)n_match_eta1p75; + N = (float)n_all_eta1p75; + if (std::abs(N) > 0) + cout << "efficiency for 1.0 < |eta| < 1.75 = " << k / N * 100.0 << " +- " + << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 << endl; + k = (float)n_match_eta2p5; + N = (float)n_all_eta2p5; + if (std::abs(N) > 0) + cout << "efficiency for 1.75 < |eta| < " << std::min(TP_maxEta, 2.5f) << " = " << k / N * 100.0 << " +- " + << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 << endl; + N = (float)n_all_eta1p0 + n_all_eta1p75 + n_all_eta2p5; + k = (float)n_match_eta1p0 + n_match_eta1p75 + n_match_eta2p5; + if (std::abs(N) > 0) + cout << "combined efficiency for |eta| < " << std::min(TP_maxEta, 2.5f) << " = " << k / N * 100.0 << " +- " + << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 << " = " << k << "/" << N << endl + << endl; + + k = (float)n_match_ptg2; + N = (float)n_all_ptg2; + if (std::abs(N) > 0) + cout << "efficiency for pt > " << std::max(TP_minPt, 2.0f) << " = " << k / N * 100.0 << " +- " + << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 << endl; + k = (float)n_match_pt2to8; + N = (float)n_all_pt2to8; + if (std::abs(N) > 0) + cout << "efficiency for " << std::max(TP_minPt, 2.0f) << " < pt < 8.0 = " << k / N * 100.0 << " +- " + << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 << endl; + k = (float)n_match_ptg8; + N = (float)n_all_ptg8; + if (std::abs(N) > 0) + cout << "efficiency for pt > 8.0 = " << k / N * 100.0 << " +- " << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 + << endl; + k = (float)n_match_ptg40; + N = (float)n_all_ptg40; + if (std::abs(N) > 0) + cout << "efficiency for pt > 40.0 = " << k / N * 100.0 << " +- " << 1.0 / N * sqrt(k * (1.0 - k / N)) * 100.0 + << endl + << endl; + + // track rates + cout << "# TP/event (pt > " << std::max(TP_minPt, 2.0f) << ") = " << (float)ntp_pt2 / nevt << endl; + cout << "# TP/event (pt > 3.0) = " << (float)ntp_pt3 / nevt << endl; + cout << "# TP/event (pt > 10.0) = " << (float)ntp_pt10 / nevt << endl; + + cout << "# tracks/event (pt > " << std::max(TP_minPt, 2.0f) << ") = " << (float)ntrk_pt2 / nevt << endl; + cout << "# tracks/event (pt > 3.0) = " << (float)ntrk_pt3 / nevt << endl; + cout << "# tracks/event (pt > 10.0) = " << (float)ntrk_pt10 / nevt << endl; +} + +void SetPlotStyle() { + // from ATLAS plot style macro + + // use plain black on white colors + gStyle->SetFrameBorderMode(0); + gStyle->SetFrameFillColor(0); + gStyle->SetCanvasBorderMode(0); + gStyle->SetCanvasColor(0); + gStyle->SetPadBorderMode(0); + gStyle->SetPadColor(0); + gStyle->SetStatColor(0); + gStyle->SetHistLineColor(1); + + gStyle->SetPalette(1); + + // set the paper & margin sizes + gStyle->SetPaperSize(20, 26); + gStyle->SetPadTopMargin(0.05); + gStyle->SetPadRightMargin(0.05); + gStyle->SetPadBottomMargin(0.16); + gStyle->SetPadLeftMargin(0.16); + + // set title offsets (for axis label) + gStyle->SetTitleXOffset(1.4); + gStyle->SetTitleYOffset(1.4); + + // use large fonts + gStyle->SetTextFont(42); + gStyle->SetTextSize(0.05); + gStyle->SetLabelFont(42, "x"); + gStyle->SetTitleFont(42, "x"); + gStyle->SetLabelFont(42, "y"); + gStyle->SetTitleFont(42, "y"); + gStyle->SetLabelFont(42, "z"); + gStyle->SetTitleFont(42, "z"); + gStyle->SetLabelSize(0.05, "x"); + gStyle->SetTitleSize(0.05, "x"); + gStyle->SetLabelSize(0.05, "y"); + gStyle->SetTitleSize(0.05, "y"); + gStyle->SetLabelSize(0.05, "z"); + gStyle->SetTitleSize(0.05, "z"); + + // use bold lines and markers + gStyle->SetMarkerStyle(20); + gStyle->SetMarkerSize(1.2); + gStyle->SetHistLineWidth(2.); + gStyle->SetLineStyleString(2, "[12 12]"); + + // get rid of error bar caps + gStyle->SetEndErrorSize(0.); + + // do not display any of the standard histogram decorations + gStyle->SetOptTitle(0); + gStyle->SetOptStat(0); + gStyle->SetOptFit(0); + + // put tick marks on top and RHS of plots + gStyle->SetPadTickX(1); + gStyle->SetPadTickY(1); +} + +void mySmallText(Double_t x, Double_t y, Color_t color, char* text) { + Double_t tsize = 0.044; + TLatex l; + l.SetTextSize(tsize); + l.SetNDC(); + l.SetTextColor(color); + l.DrawLatex(x, y, text); +} + +double getIntervalContainingFractionOfEntries(TH1* absResidualHistogram, double quantileToCalculate, int minEntries) { + double totalIntegral = absResidualHistogram->Integral(0, absResidualHistogram->GetNbinsX() + 1); + double numEntries = absResidualHistogram->GetEntries(); + + // Check that the interval is not somewhere in the overflow bin + double maxAllowedEntriesInOverflow = totalIntegral * (1 - quantileToCalculate); + double nEntriesInOverflow = absResidualHistogram->GetBinContent(absResidualHistogram->GetNbinsX() + 1); + if (nEntriesInOverflow > maxAllowedEntriesInOverflow) { + // cout << "WARNING : Cannot compute range corresponding to interval, as it is in the overflow bin" << endl; + return absResidualHistogram->GetXaxis()->GetXmax() * 1.2; + } + + // Calculate quantile for given interval + double interval[1]; + double quantile[1] = {quantileToCalculate}; + if (totalIntegral > 0 && numEntries >= minEntries) { + absResidualHistogram->GetQuantiles(1, interval, quantile); + } else { + cout << "WARNING: histo " << absResidualHistogram->GetName() + << " empty or with too few entries, so can't calc quantiles." << endl; + interval[0] = 0.; + } + + return interval[0]; +} + +void makeResidualIntervalPlot( + TString type, TString dir, TString variable, TH1F* h_68, TH1F* h_90, TH1F* h_99, double minY, double maxY) { + TCanvas c; + + h_68->SetMinimum(minY); + h_90->SetMinimum(minY); + h_99->SetMinimum(minY); + + h_68->SetMaximum(maxY); + h_90->SetMaximum(maxY); + h_99->SetMaximum(maxY); + + h_68->SetMarkerStyle(20); + h_90->SetMarkerStyle(26); + h_99->SetMarkerStyle(24); + + h_68->Draw("P"); + h_68->Write(); + h_90->Draw("P same"); + h_90->Write(); + h_99->Draw("P same"); + h_99->Write(); + + TLegend* l = new TLegend(0.65, 0.65, 0.85, 0.85); + l->SetFillStyle(0); + l->SetBorderSize(0); + l->SetTextSize(0.04); + l->AddEntry(h_99, "99%", "p"); + l->AddEntry(h_90, "90%", "p"); + l->AddEntry(h_68, "68%", "p"); + l->SetTextFont(42); + l->Draw(); + + c.SaveAs(dir + type + "_" + variable + "_interval.pdf"); + + delete l; +} diff --git a/L1Trigger/TrackFindingTracklet/test/Makefile b/L1Trigger/TrackFindingTracklet/test/Makefile new file mode 100644 index 0000000000000..634405731eac9 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/Makefile @@ -0,0 +1,245 @@ +#common definitions go in here +CXX = g++ +CXXFLAGS = -O -Wall -fPIC -g -ansi -Wextra -Wno-deprecated -std=c++17 -I. -I../../.. +LD = g++ +LDFLAGS = -O +LIBDIR = $(WORKDIR) +AR = ar +ARFLAGS = cr + +OS := $(shell uname -s) +ifeq ($(OS),Darwin) + SOFLAGS = -dynamiclib +else + SOFLAGS = -shared +endif + +ifndef ROOTSYS +$(error *** Please set up Root) +endif + +ifeq ("$(wildcard lib)","") +$(shell mkdir lib) +endif + +# +# Add system headers here (hack around problem with makedepend +# if you added file remove the dummyIncl directory to rewrite files +# +ifeq ("$(wildcard dummyIncl)","") +$(shell mkdir dummyIncl) +$(shell mkdir dummyIncl/sys) +$(shell mkdir dummyIncl/ext) +$(shell touch dummyIncl/TBranch.h) +$(shell touch dummyIncl/TCanvas.h) +$(shell touch dummyIncl/TChain.h) +$(shell touch dummyIncl/TColor.h) +$(shell touch dummyIncl/TEfficiency.h) +$(shell touch dummyIncl/TFile.h) +$(shell touch dummyIncl/TH1D.h) +$(shell touch dummyIncl/TH1F.h) +$(shell touch dummyIncl/TH2F.h) +$(shell touch dummyIncl/TLatex.h) +$(shell touch dummyIncl/TLegend.h) +$(shell touch dummyIncl/TMath.h) +$(shell touch dummyIncl/TROOT.h) +$(shell touch dummyIncl/TStyle.h) +$(shell touch dummyIncl/TSystem.h) +$(shell touch dummyIncl/TTree.h) +$(shell touch dummyIncl/algorithm) +$(shell touch dummyIncl/array) +$(shell touch dummyIncl/bitset) +$(shell touch dummyIncl/cassert) +$(shell touch dummyIncl/chrono) +$(shell touch dummyIncl/cctype) +$(shell touch dummyIncl/cmath) +$(shell touch dummyIncl/ctime) +$(shell touch dummyIncl/cstdlib) +$(shell touch dummyIncl/cmath) +$(shell touch dummyIncl/exception) +$(shell touch dummyIncl/fstream) +$(shell touch dummyIncl/iomanip) +$(shell touch dummyIncl/iostream) +$(shell touch dummyIncl/limits) +$(shell touch dummyIncl/map) +$(shell touch dummyIncl/memory) +$(shell touch dummyIncl/set) +$(shell touch dummyIncl/sstream) +$(shell touch dummyIncl/string) +$(shell touch dummyIncl/vector) +$(shell touch dummyIncl/unordered_map) +$(shell touch dummyIncl/unordered_set) +$(shell touch dummyIncl/utility) +$(shell touch dummyIncl/algorithm) +$(shell touch dummyIncl/ext/hash_set) +$(shell touch dummyIncl/sys/time.h) +$(shell touch dummyIncl/ctime) +$(shell touch dummyIncl/chrono) +endif + +ifeq ("$(wildcard FWCore)","") +$(shell mkdir FWCore) +$(shell mkdir FWCore/MessageLogger) +$(shell mkdir FWCore/MessageLogger/interface) +$(shell mkdir FWCore/Utilities) +$(shell mkdir FWCore/Utilities/interface) +endif + +ifeq ("$(wildcard FWCore/Utilities/interface/Exception.h)","") +$(shell echo "#ifndef L1Trigger_TrackFindingTracklet_interface_Exception_h" > FWCore/Utilities/interface/Exception.h) +$(shell echo "#define L1Trigger_TrackFindingTracklet_interface_Exception_h" >> FWCore/Utilities/interface/Exception.h) +$(shell echo "#include" >> FWCore/Utilities/interface/Exception.h) +$(shell echo "namespace cms {" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " class Exception{" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " public:" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " Exception(std::string type) { if(0) {std::cout<> FWCore/Utilities/interface/Exception.h) +$(shell echo " ~Exception() { std::cout << std::endl;}" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " template Exception& operator<<(T const& t) {std::cout << t;return *this;}" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " Exception& operator<<(std::ostream& (*f)(std::ostream&)) {std::cout << f;return *this;}" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " Exception& operator<<(std::ios_base& (*f)(std::ios_base&)) {std::cout << f;return *this;}" >> FWCore/Utilities/interface/Exception.h) +$(shell echo " };" >> FWCore/Utilities/interface/Exception.h) +$(shell echo "};" >> FWCore/Utilities/interface/Exception.h) +$(shell echo "#endif" >> FWCore/Utilities/interface/Exception.h) +endif + +ifeq ("$(wildcard FWCore/MessageLogger/interface/MessageLogger.h)","") +$(shell echo "#ifndef L1Trigger_TrackFindingTracklet_interface_Logger_h" > FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo "#define L1Trigger_TrackFindingTracklet_interface_Logger_h" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo "#include" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo "namespace edm {" >> FWCore/MessageLogger/interface/MessageLogger.h) +# INFO statement +$(shell echo " class LogVerbatim{" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " public:" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogVerbatim(std::string type) { if(0) {std::cout<> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " ~LogVerbatim() { std::cout << std::endl;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " template LogVerbatim& operator<<(T const& t) {std::cout << t;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogVerbatim& operator<<(std::ostream& (*f)(std::ostream&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogVerbatim& operator<<(std::ios_base& (*f)(std::ios_base&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " };" >> FWCore/MessageLogger/interface/MessageLogger.h) +# WARNING statement +$(shell echo " class LogPrint{" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " public:" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogPrint(std::string type) { if(0) {std::cout<> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " ~LogPrint() { std::cout << std::endl;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " template LogPrint& operator<<(T const& t) {std::cout << t;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogPrint& operator<<(std::ostream& (*f)(std::ostream&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogPrint& operator<<(std::ios_base& (*f)(std::ios_base&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " };" >> FWCore/MessageLogger/interface/MessageLogger.h) +# another WARNING statement +$(shell echo " class LogWarning{" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " public:" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogWarning(std::string type) { if(0) {std::cout<> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " ~LogWarning() { std::cout << std::endl;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " template LogWarning& operator<<(T const& t) {std::cout << t;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogWarning& operator<<(std::ostream& (*f)(std::ostream&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogWarning& operator<<(std::ios_base& (*f)(std::ios_base&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " };" >> FWCore/MessageLogger/interface/MessageLogger.h) +# ERROR statement +$(shell echo " class LogProblem{" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " public:" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogProblem(std::string type) { if(0) {std::cout<> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " ~LogProblem() { std::cout << std::endl;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " template LogProblem& operator<<(T const& t) {std::cout << t;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogProblem& operator<<(std::ostream& (*f)(std::ostream&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " LogProblem& operator<<(std::ios_base& (*f)(std::ios_base&)) {std::cout << f;return *this;}" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo " };" >> FWCore/MessageLogger/interface/MessageLogger.h) +# +$(shell echo "};" >> FWCore/MessageLogger/interface/MessageLogger.h) +$(shell echo "#endif" >> FWCore/MessageLogger/interface/MessageLogger.h) +endif + +# reduceRange for standalone +ifeq ("$(wildcard DataFormats/Math/interface)","") +$(shell mkdir DataFormats) +$(shell mkdir DataFormats/Math) +$(shell mkdir DataFormats/Math/interface) +endif + +ifeq ("$(wildcard DataFormats/Math/interface/deltaPhi.h)","") +$(shell echo "#ifndef DataFormats_Math_interface_deltaPhi_h" > DataFormats/Math/interface/deltaPhi.h) +$(shell echo "#define DataFormats_Math_interface_deltaPhi_h" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo "namespace reco {" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " inline double reduceRange(double phi) { assert(std::abs(phi) < 100.0); " >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " while (phi < -M_PI) { phi += 2 * M_PI; }" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " while (phi > M_PI) { phi -= 2 * M_PI; }" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " return phi; } " >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo "};" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo "namespace angle0to2pi {" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " inline double make0To2pi(double phi) { assert(std::abs(phi) < 100.0); " >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " while (phi < 0.0) { phi += 2 * M_PI; }" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " while (phi > 2 * M_PI) { phi -= 2 * M_PI; }" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo " return phi; } " >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo "};" >> DataFormats/Math/interface/deltaPhi.h) +$(shell echo "#endif" >> DataFormats/Math/interface/deltaPhi.h) +endif + +#find out about the installed ROOT +ROOTCONFIG := $(ROOTSYS)/bin/root-config +ROOTCFLAGS := $(shell $(ROOTCONFIG) --cflags) +ROOTLDFLAGS := $(shell $(ROOTCONFIG) --ldflags) $(shell $(ROOTCONFIG) --libs --nonew --glibs) + +#append to options +CXXFLAGS += $(ROOTCFLAGS) +LDFLAGS += $(ROOTLDFLAGS) +# Needed for ROOT-Tree +#LDFLAGS += -L./ FPGAEvent_cxx.so + +CXXFLAGS += -std=c++17 #fix, otherwise ROOT cflags overrule c++11 + +LIBS = -lHtml + + +ifneq ($(CMSSW_BASE),) + ROOTFIT_INCLUDE := $(shell cd $(CMSSW_BASE); scram tool info roofitcore | grep INCLUDE= | sed 's|INCLUDE=||') + ROOTFIT_LIBDIR := $(shell cd $(CMSSW_BASE); scram tool info roofitcore | grep LIBDIR= | sed 's|LIBDIR=||') + + CINTINCLUDES := -I$(ROOTFIT_INCLUDE) + CXXFLAGS += -I$(ROOTFIT_INCLUDE) + LDFLAGS += -L$(ROOTFIT_LIBDIR) +endif + + +DEPDIR = .deps + +MAKEDEPEND = makedepend -I../../.. -IdummyIncl -f- $< | sed 's/..\/src/lib/' > .deps/$*.d + +SRCS = $(wildcard ../src/*.cc) + +OBJS = $(SRCS:../src/%.cc=lib/%.o) + +default: fpga + +fpga: fpga.a fpga.o + $(LD) -o $@ fpga.o fpga.a $(LDFLAGS) $(LIBS) + +fpga.o: fpga.cc $(DEPDIR)/fpga.d | $(DEPDIR) + @$(MAKEDEPEND) + $(CXX) $(CXXFLAGS) -c fpga.cc -o $@ + +fpga.a:$(OBJS) + @$(AR) $(ARFLAGS) $@ $? + +lib/%.o:../src/%.cc $(DEPDIR)/%.d | $(DEPDIR) + @$(MAKEDEPEND) + time $(CXX) $(CXXFLAGS) -o $@ -c $< + +$(DEPDIR): ; @mkdir -p $@ + +%.d: ; + +DEPFILES := $(SRCS:../src/%.cc=$(DEPDIR)/%.d) +$(DEPFILES): +include $(wildcard $(DEPFILES)) +include $(wildcard $(DEPDIR)/fpga.d) + + +clean: + @rm -f *.o + @rm -f fpga + @rm -f fpga.a + @rm -rf DataFormats/ + @rm -rf FWCore/ + @rm -rf lib/ + @rm -rf dummyIncl/ + @rm -rf .deps/ + diff --git a/L1Trigger/TrackFindingTracklet/test/WriteDesign.icc b/L1Trigger/TrackFindingTracklet/test/WriteDesign.icc new file mode 100644 index 0000000000000..740265c09a856 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/WriteDesign.icc @@ -0,0 +1,648 @@ +std::map > v; + +//////////////////////////////////////////////////////////////////////////// +// L1L2 +//////////////////////////////////////////////////////////////////////////// +v["L1L2"]; + +v.at("L1L2").push_back(&globals->ITC_L1L2()->rinv_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phi0_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->t_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->z0_final); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiL_0_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiL_1_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiL_2_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiL_3_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->zL_0_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->zL_1_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->zL_2_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->zL_3_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->der_phiL_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->der_zL_final); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiD_0_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiD_1_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiD_2_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiD_3_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->phiD_4_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->rD_0_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->rD_1_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->rD_2_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->rD_3_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->rD_4_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->der_phiD_final); +v.at("L1L2").push_back(&globals->ITC_L1L2()->der_rD_final); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_trackpar); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiL_0); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiL_1); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiL_2); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiL_3); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_zL_0); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_zL_1); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_zL_2); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_zL_3); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_der_phiL); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_der_zL); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiD_0); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiD_1); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiD_2); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiD_3); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_phiD_4); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_rD_0); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_rD_1); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_rD_2); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_rD_3); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_rD_4); + +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_der_phiD); +v.at("L1L2").push_back(&globals->ITC_L1L2()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// L3L4 +//////////////////////////////////////////////////////////////////////////// +v["L3L4"]; + +v.at("L3L4").push_back(&globals->ITC_L3L4()->rinv_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phi0_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->t_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->z0_final); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiL_0_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiL_1_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiL_2_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiL_3_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->zL_0_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->zL_1_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->zL_2_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->zL_3_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->der_phiL_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->der_zL_final); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiD_0_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiD_1_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiD_2_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiD_3_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->phiD_4_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->rD_0_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->rD_1_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->rD_2_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->rD_3_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->rD_4_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->der_phiD_final); +v.at("L3L4").push_back(&globals->ITC_L3L4()->der_rD_final); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_trackpar); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiL_0); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiL_1); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiL_2); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiL_3); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_zL_0); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_zL_1); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_zL_2); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_zL_3); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_der_phiL); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_der_zL); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiD_0); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiD_1); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiD_2); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiD_3); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_phiD_4); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_rD_0); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_rD_1); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_rD_2); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_rD_3); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_rD_4); + +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_der_phiD); +v.at("L3L4").push_back(&globals->ITC_L3L4()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// L5L6 +//////////////////////////////////////////////////////////////////////////// +v["L5L6"]; + +v.at("L5L6").push_back(&globals->ITC_L5L6()->rinv_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phi0_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->t_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->z0_final); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiL_0_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiL_1_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiL_2_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiL_3_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->zL_0_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->zL_1_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->zL_2_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->zL_3_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->der_phiL_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->der_zL_final); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiD_0_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiD_1_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiD_2_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiD_3_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->phiD_4_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->rD_0_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->rD_1_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->rD_2_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->rD_3_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->rD_4_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->der_phiD_final); +v.at("L5L6").push_back(&globals->ITC_L5L6()->der_rD_final); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_trackpar); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiL_0); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiL_1); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiL_2); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiL_3); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_zL_0); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_zL_1); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_zL_2); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_zL_3); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_der_phiL); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_der_zL); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiD_0); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiD_1); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiD_2); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiD_3); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_phiD_4); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_rD_0); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_rD_1); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_rD_2); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_rD_3); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_rD_4); + +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_der_phiD); +v.at("L5L6").push_back(&globals->ITC_L5L6()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// F1F2 +//////////////////////////////////////////////////////////////////////////// +v["F1F2"]; + +v.at("F1F2").push_back(&globals->ITC_F1F2()->rinv_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->phi0_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->t_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->z0_final); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->phiL_0_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->phiL_1_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->phiL_2_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->zL_0_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->zL_1_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->zL_2_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->der_phiL_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->der_zL_final); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->phiD_0_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->phiD_1_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->phiD_2_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->rD_0_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->rD_1_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->rD_2_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->der_phiD_final); +v.at("F1F2").push_back(&globals->ITC_F1F2()->der_rD_final); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_trackpar); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_phiL_0); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_phiL_1); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_phiL_2); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_zL_0); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_zL_1); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_zL_2); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_der_phiL); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_der_zL); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_phiD_0); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_phiD_1); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_phiD_2); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_rD_0); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_rD_1); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_rD_2); + +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_der_phiD); +v.at("F1F2").push_back(&globals->ITC_F1F2()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// B1B2 +//////////////////////////////////////////////////////////////////////////// +v["B1B2"]; + +v.at("B1B2").push_back(&globals->ITC_B1B2()->rinv_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->phi0_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->t_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->z0_final); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->phiL_0_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->phiL_1_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->phiL_2_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->zL_0_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->zL_1_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->zL_2_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->der_phiL_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->der_zL_final); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->phiD_0_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->phiD_1_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->phiD_2_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->rD_0_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->rD_1_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->rD_2_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->der_phiD_final); +v.at("B1B2").push_back(&globals->ITC_B1B2()->der_rD_final); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_trackpar); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_phiL_0); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_phiL_1); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_phiL_2); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_zL_0); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_zL_1); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_zL_2); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_der_phiL); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_der_zL); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_phiD_0); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_phiD_1); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_phiD_2); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_rD_0); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_rD_1); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_rD_2); + +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_der_phiD); +v.at("B1B2").push_back(&globals->ITC_B1B2()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// F3F4 +//////////////////////////////////////////////////////////////////////////// +v["F3F4"]; + +v.at("F3F4").push_back(&globals->ITC_F3F4()->rinv_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->phi0_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->t_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->z0_final); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->phiL_0_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->phiL_1_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->phiL_2_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->zL_0_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->zL_1_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->zL_2_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->der_phiL_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->der_zL_final); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->phiD_0_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->phiD_1_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->phiD_2_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->rD_0_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->rD_1_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->rD_2_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->der_phiD_final); +v.at("F3F4").push_back(&globals->ITC_F3F4()->der_rD_final); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_trackpar); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_phiL_0); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_phiL_1); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_phiL_2); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_zL_0); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_zL_1); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_zL_2); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_der_phiL); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_der_zL); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_phiD_0); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_phiD_1); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_phiD_2); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_rD_0); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_rD_1); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_rD_2); + +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_der_phiD); +v.at("F3F4").push_back(&globals->ITC_F3F4()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// B3B4 +//////////////////////////////////////////////////////////////////////////// +v["B3B4"]; + +v.at("B3B4").push_back(&globals->ITC_B3B4()->rinv_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->phi0_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->t_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->z0_final); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->phiL_0_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->phiL_1_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->phiL_2_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->zL_0_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->zL_1_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->zL_2_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->der_phiL_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->der_zL_final); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->phiD_0_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->phiD_1_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->phiD_2_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->rD_0_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->rD_1_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->rD_2_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->der_phiD_final); +v.at("B3B4").push_back(&globals->ITC_B3B4()->der_rD_final); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_trackpar); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_phiL_0); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_phiL_1); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_phiL_2); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_zL_0); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_zL_1); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_zL_2); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_der_phiL); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_der_zL); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_phiD_0); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_phiD_1); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_phiD_2); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_rD_0); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_rD_1); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_rD_2); + +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_der_phiD); +v.at("B3B4").push_back(&globals->ITC_B3B4()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// L1F1 +//////////////////////////////////////////////////////////////////////////// +v["L1F1"]; + +v.at("L1F1").push_back(&globals->ITC_L1F1()->rinv_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->phi0_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->t_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->z0_final); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiL_0_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiL_1_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiL_2_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->zL_0_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->zL_1_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->zL_2_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->der_phiL_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->der_zL_final); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiD_0_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiD_1_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiD_2_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->phiD_3_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->rD_0_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->rD_1_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->rD_2_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->rD_3_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->der_phiD_final); +v.at("L1F1").push_back(&globals->ITC_L1F1()->der_rD_final); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_trackpar); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiL_0); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiL_1); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiL_2); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_zL_0); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_zL_1); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_zL_2); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_der_phiL); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_der_zL); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiD_0); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiD_1); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiD_2); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_phiD_3); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_rD_0); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_rD_1); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_rD_2); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_rD_3); + +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_der_phiD); +v.at("L1F1").push_back(&globals->ITC_L1F1()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// L1B1 +//////////////////////////////////////////////////////////////////////////// +v["L1B1"]; + +v.at("L1B1").push_back(&globals->ITC_L1B1()->rinv_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->phi0_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->t_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->z0_final); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiL_0_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiL_1_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiL_2_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->zL_0_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->zL_1_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->zL_2_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->der_phiL_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->der_zL_final); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiD_0_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiD_1_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiD_2_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->phiD_3_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->rD_0_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->rD_1_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->rD_2_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->rD_3_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->der_phiD_final); +v.at("L1B1").push_back(&globals->ITC_L1B1()->der_rD_final); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_trackpar); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiL_0); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiL_1); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiL_2); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_zL_0); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_zL_1); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_zL_2); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_der_phiL); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_der_zL); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiD_0); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiD_1); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiD_2); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_phiD_3); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_rD_0); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_rD_1); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_rD_2); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_rD_3); + +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_der_phiD); +v.at("L1B1").push_back(&globals->ITC_L1B1()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// L2F1 +//////////////////////////////////////////////////////////////////////////// +v["L2F1"]; + +v.at("L2F1").push_back(&globals->ITC_L2F1()->rinv_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->phi0_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->t_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->z0_final); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiL_0_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiL_1_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiL_2_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->zL_0_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->zL_1_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->zL_2_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->der_phiL_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->der_zL_final); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiD_0_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiD_1_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiD_2_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->phiD_3_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->rD_0_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->rD_1_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->rD_2_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->rD_3_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->der_phiD_final); +v.at("L2F1").push_back(&globals->ITC_L2F1()->der_rD_final); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_trackpar); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiL_0); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiL_1); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiL_2); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_zL_0); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_zL_1); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_zL_2); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_der_phiL); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_der_zL); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiD_0); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiD_1); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiD_2); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_phiD_3); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_rD_0); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_rD_1); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_rD_2); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_rD_3); + +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_der_phiD); +v.at("L2F1").push_back(&globals->ITC_L2F1()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////// +// L2B1 +//////////////////////////////////////////////////////////////////////////// +v["L2B1"]; + +v.at("L2B1").push_back(&globals->ITC_L2B1()->rinv_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->phi0_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->t_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->z0_final); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiL_0_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiL_1_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiL_2_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->zL_0_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->zL_1_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->zL_2_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->der_phiL_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->der_zL_final); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiD_0_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiD_1_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiD_2_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->phiD_3_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->rD_0_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->rD_1_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->rD_2_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->rD_3_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->der_phiD_final); +v.at("L2B1").push_back(&globals->ITC_L2B1()->der_rD_final); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_trackpar); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiL_0); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiL_1); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiL_2); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_zL_0); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_zL_1); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_zL_2); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_der_phiL); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_der_zL); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiD_0); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiD_1); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiD_2); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_phiD_3); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_rD_0); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_rD_1); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_rD_2); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_rD_3); + +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_der_phiD); +v.at("L2B1").push_back(&globals->ITC_L2B1()->valid_der_rD); +//////////////////////////////////////////////////////////////////////////// + +for (const auto &calculator : v) { + const std::string &layer = calculator.first; + const std::vector v = calculator.second; + ofstream fv("TC_" + layer + (settings.writeVerilog() ? ".v" : ".cpp")); + + if (settings.writeVerilog()) + VarBase::design_print(v, fv, VarBase::verilog); + else + VarBase::design_print(v, fv, VarBase::hls); + fv.close(); +} diff --git a/L1Trigger/TrackFindingTracklet/test/WriteInvTables.icc b/L1Trigger/TrackFindingTracklet/test/WriteInvTables.icc new file mode 100644 index 0000000000000..6c1b3fcaf7ff4 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/WriteInvTables.icc @@ -0,0 +1,83 @@ +edm::LogVerbatim("Tracklet") << " Writing Inverse Tables"; + +ofstream finv; +void (*writeLUT)(const VarInv&, ofstream&) = NULL; +string extension = ""; +if (settings.writeInvTable()) { + writeLUT = [](const VarInv& x, ofstream& fs) -> void { return x.writeLUT(fs, VarBase::verilog); }; + extension = "h"; +} else { + writeLUT = [](const VarInv& x, ofstream& fs) -> void { return x.writeLUT(fs, VarBase::hls); }; + extension = "tab"; +} + +finv.open("TC_L1L2_drinv." + extension); +writeLUT(globals->ITC_L1L2()->drinv, finv); +finv.close(); +finv.open("TC_L1L2_invt." + extension); +writeLUT(globals->ITC_L1L2()->invt, finv); +finv.close(); +finv.open("TC_L3L4_drinv." + extension); +writeLUT(globals->ITC_L3L4()->drinv, finv); +finv.close(); +finv.open("TC_L3L4_invt." + extension); +writeLUT(globals->ITC_L3L4()->invt, finv); +finv.close(); +finv.open("TC_L5L6_drinv." + extension); +writeLUT(globals->ITC_L5L6()->drinv, finv); +finv.close(); +finv.open("TC_L5L6_invt." + extension); +writeLUT(globals->ITC_L5L6()->invt, finv); +finv.close(); + +finv.open("F1F2_drinv." + extension); +writeLUT(globals->ITC_F1F2()->drinv, finv); +finv.close(); +finv.open("F1F2_invt." + extension); +writeLUT(globals->ITC_F1F2()->invt, finv); +finv.close(); +finv.open("B1B2_drinv." + extension); +writeLUT(globals->ITC_B1B2()->drinv, finv); +finv.close(); +finv.open("B1B2_invt." + extension); +writeLUT(globals->ITC_B1B2()->invt, finv); +finv.close(); + +finv.open("F3F4_drinv." + extension); +writeLUT(globals->ITC_F3F4()->drinv, finv); +finv.close(); +finv.open("F3F4_invt." + extension); +writeLUT(globals->ITC_F3F4()->invt, finv); +finv.close(); +finv.open("B3B4_drinv." + extension); +writeLUT(globals->ITC_B3B4()->drinv, finv); +finv.close(); +finv.open("B3B4_invt." + extension); +writeLUT(globals->ITC_B3B4()->invt, finv); +finv.close(); + +finv.open("L1F1_drinv." + extension); +writeLUT(globals->ITC_L1F1()->drinv, finv); +finv.close(); +finv.open("L1F1_invt." + extension); +writeLUT(globals->ITC_L1F1()->invt, finv); +finv.close(); +finv.open("L1B1_drinv." + extension); +writeLUT(globals->ITC_L1B1()->drinv, finv); +finv.close(); +finv.open("L1B1_invt." + extension); +writeLUT(globals->ITC_L1B1()->invt, finv); +finv.close(); + +finv.open("L2F1_drinv." + extension); +writeLUT(globals->ITC_L2F1()->drinv, finv); +finv.close(); +finv.open("L2F1_invt." + extension); +writeLUT(globals->ITC_L2F1()->invt, finv); +finv.close(); +finv.open("L2B1_drinv." + extension); +writeLUT(globals->ITC_L2B1()->drinv, finv); +finv.close(); +finv.open("L2B1_invt." + extension); +writeLUT(globals->ITC_L2B1()->invt, finv); +finv.close(); diff --git a/L1Trigger/TrackFindingTracklet/test/fpga.cc b/L1Trigger/TrackFindingTracklet/test/fpga.cc new file mode 100644 index 0000000000000..eb435ceea7057 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/fpga.cc @@ -0,0 +1,327 @@ +// ---------------------------------------------------------------- +// STANDALONE (non-CMSSW) producer for L1 tracking +// ---------------------------------------------------------------- +// ROOT includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../interface/IMATH_TrackletCalculator.h" +#include "../interface/IMATH_TrackletCalculatorDisk.h" +#include "../interface/IMATH_TrackletCalculatorOverlap.h" + +#include "../interface/SLHCEvent.h" +#include "../interface/Track.h" +#include "../interface/Settings.h" +#include "../interface/TrackletEventProcessor.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +#include +#include +#include + +//Uncomment if you want root output +//#define USEROOT + +// Include file to define ROOT-Tree +// -------------------------------- +#ifdef USEROOT +#include "FPGAEvent.h" +#endif +// -------------------------------- + +using namespace trklet; +using namespace std; + +int main(const int argc, const char **argv) { + trklet::Settings settings; + + // --------------------------------------------------------- + // these are options that are read from python configuration files for the CMSSW running, set manually for the standalone version + + settings.setDTCLinkFile("../data/calcNumDTCLinks.txt"); + settings.setModuleCablingFile("../data/modules_T5v3_27SP_nonant_tracklet.dat"); + settings.setDTCLinkLayerDiskFile("../data/dtclinklayerdisk.dat"); + settings.setFitPatternFile("../data/fitpattern.txt"); + settings.setProcessingModulesFile("../data/processingmodules_" + settings.geomext() + ".dat"); + settings.setMemoryModulesFile("../data/memorymodules_" + settings.geomext() + ".dat"); + settings.setWiresFile("../data/wires_" + settings.geomext() + ".dat"); + + edm::LogVerbatim("Tracklet") << "cabling DTC links : " << settings.DTCLinkFile(); + edm::LogVerbatim("Tracklet") << "module cabling : " << settings.moduleCablingFile(); + edm::LogVerbatim("Tracklet") << "DTC link layer disk : " << settings.DTCLinkLayerDiskFile(); + + edm::LogVerbatim("Tracklet") << "fit pattern : " << settings.fitPatternFile(); + edm::LogVerbatim("Tracklet") << "process modules : " << settings.processingModulesFile(); + edm::LogVerbatim("Tracklet") << "memory modules : " << settings.memoryModulesFile(); + edm::LogVerbatim("Tracklet") << "wires : " << settings.wiresFile(); + + // --------------------------------------------------------- + + TrackletEventProcessor eventProcessor; + eventProcessor.init(settings); + + if (argc < 3) + edm::LogVerbatim("Tracklet") << "Need to specify the input ascii file and the number of events to run on!"; + + int nevents = atoi(argv[2]); + + ifstream infile; + istream *in = &cin; + if (strcmp(argv[1], "stdin")) { + infile.open(argv[1]); + in = &infile; + } + + ofstream outpars; + if (settings.writeMonitorData("Pars")) + outpars.open("trackpars.txt"); + + // --------------------------------------------------------- + // Open file to hold ROOT-Tree +#ifdef USEROOT + TFile *hfile = new TFile("myTest.root", "RECREATE", "Simple ROOT Ntuple"); + TTree *trackTree = new TTree("FPGAEvent", "L1Track Tree"); + FPGAEvent *fpgaEvent = new FPGAEvent; + fpgaEvent->reset(); + trackTree->Branch("Event", &fpgaEvent); +#endif + // --------------------------------------------------------- + + if (settings.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::out); + fout.close(); + } + + for (int eventnum = 0; eventnum < nevents && !in->eof(); eventnum++) { + SLHCEvent ev(*in); + + L1SimTrack simtrk; + + // ----------------------------------------------------------------- + // setup ROOT Tree and Add Monte Carlo tracks to the ROOT-Tree Event +#ifdef USEROOT + fpgaEvent->reset(); + fpgaEvent->nevt = eventnum; + for (int nst = 0; nst < ev.nsimtracks(); nst++) { + simtrk = ev.simtrack(nst); + FPGAEventMCTrack *mcTrack = new FPGAEventMCTrack( + simtrk.type(), simtrk.pt(), simtrk.eta(), simtrk.phi(), simtrk.vx(), simtrk.vy(), simtrk.vz()); + fpgaEvent->mcTracks.push_back(*mcTrack); + } +#endif + // ------------------------------------------------------------------ + + if (settings.writeMonitorData("Seeds")) { + ofstream fout("seeds.txt", ofstream::app); + fout << "======== Event " << eventnum << " ========" << endl; + for (unsigned nst = 0; nst < ev.nsimtracks(); nst++) { + const L1SimTrack &simtrk = ev.simtrack(nst); + fout << "SimTrk " << simtrk.pt() << " " << simtrk.eta() << " " << simtrk.phi() << " " << simtrk.d0() << " "; + + vector hitPattern; + for (int i = 0; i < ev.nstubs(); i++) { + const L1TStub &stub = ev.stub(i); + if (!stub.tpmatch(simtrk.trackid())) + continue; + if (stub.layer() < 999) { + switch (stub.layer()) { + case 0: + hitPattern.emplace_back("L1"); + break; + case 1: + hitPattern.emplace_back("L2"); + break; + case 2: + hitPattern.emplace_back("L3"); + break; + case 3: + hitPattern.emplace_back("L4"); + break; + case 4: + hitPattern.emplace_back("L5"); + break; + case 5: + hitPattern.emplace_back("L6"); + break; + default: + edm::LogVerbatim("Tracklet") << "Stub layer: " << stub.layer(); + assert(0); + } + } else { + string d = (stub.isPSmodule() ? "D" : "d"); + switch (abs(stub.disk())) { + case 1: + hitPattern.push_back(d + "1"); + break; + case 2: + hitPattern.push_back(d + "2"); + break; + case 3: + hitPattern.push_back(d + "3"); + break; + case 4: + hitPattern.push_back(d + "4"); + break; + case 5: + hitPattern.push_back(d + "5"); + break; + default: + edm::LogVerbatim("Tracklet") << "Stub disk: " << stub.disk(); + assert(0); + } + } + } + bool (*compare)(const string &, const string &) = [](const string &a, const string &b) -> bool { + if (a.at(0) == 'L' && b.at(0) == 'D') + return true; + else if (a.at(0) == 'D' && b.at(0) == 'L') + return false; + else + return a.at(1) < b.at(1); + }; + sort(hitPattern.begin(), hitPattern.end(), compare); + hitPattern.erase(unique(hitPattern.begin(), hitPattern.end()), hitPattern.end()); + for (const auto &stub : hitPattern) + fout << stub; + if (hitPattern.empty()) + fout << "XX"; + fout << endl; + } + fout.close(); + } + + edm::LogVerbatim("Tracklet") << "Process event: " << eventnum << " with " << ev.nstubs() << " stubs and " + << ev.nsimtracks() << " simtracks"; + + eventProcessor.event(ev); + + std::vector &tracks = eventProcessor.tracks(); + + // --------------------------------------------------------- + // Block for producing ROOT-Tree +#ifdef USEROOT +#include "FPGATree.icc" +#endif + // --------------------------------------------------------- + + if (settings.writeMonitorData("MatchEff")) { + static ofstream out("matcheff.txt"); + int nsim = 0; + for (unsigned int isimtrack = 0; isimtrack < ev.nsimtracks(); isimtrack++) { + L1SimTrack simtrack = ev.simtrack(isimtrack); + if (simtrack.pt() < 2.0) + continue; + if (fabs(simtrack.eta()) > 2.4) + continue; + if (fabs(simtrack.vz()) > 15.0) + continue; + if (hypot(simtrack.vx(), simtrack.vy()) > 0.1) + continue; + bool electron = (abs(simtrack.type()) == 11); + bool muon = (abs(simtrack.type()) == 13); + bool pion = (abs(simtrack.type()) == 211); + bool kaon = (abs(simtrack.type()) == 321); + bool proton = (abs(simtrack.type()) == 2212); + if (!(electron || muon || pion || kaon || proton)) + continue; + int nlayers = 0; + int ndisks = 0; + int simeventid = simtrack.eventid(); + int simtrackid = simtrack.trackid(); + ev.layersHit(simtrackid, nlayers, ndisks); + if (nlayers + ndisks < 4) + continue; + nsim++; + for (int seed = -1; seed < 8; seed++) { + bool eff = false; + bool effloose = false; + int itrackmatch = -1; + for (unsigned int itrack = 0; itrack < tracks.size(); itrack++) { + const std::vector &stubs = tracks[itrack]->stubs(); + if (seed == -1) { + if (tracks[itrack]->duplicate()) + continue; + } else { + if (seed != tracks[itrack]->seed()) + continue; + } + + unsigned int nmatch = 0; + for (auto stub : stubs) { + if (stub->tpmatch(simtrackid)) { + nmatch++; + } + } + + if (nmatch == stubs.size()) { + eff = true; + itrackmatch = itrack; + } + if (nmatch >= stubs.size() - 1) { + effloose = true; + if (!eff) + itrackmatch = itrack; + } + } + double dpt = -999; + double dphi = -999; + double deta = -999; + double dz0 = -999; + int q = 1; + if (simtrack.type() == 11 || simtrack.type() == 13 || simtrack.type() == -211 || simtrack.type() == -321 || + simtrack.type() == -2212) { + q = -1; + } + + if (itrackmatch >= 0) { + dpt = tracks[itrackmatch]->pt(settings) - q * simtrack.pt(); + dphi = tracks[itrackmatch]->phi0(settings) - simtrack.phi(); + if (dphi > M_PI) + dphi -= 2 * M_PI; + if (dphi < -M_PI) + dphi += 2 * M_PI; + deta = tracks[itrackmatch]->eta(settings) - simtrack.eta(); + dz0 = tracks[itrackmatch]->z0(settings) - simtrack.vz(); + } + + out << eventnum << " " << simeventid << " " << seed << " " << simtrackid << " " << simtrack.type() << " " + << simtrack.pt() << " " << simtrack.eta() << " " << simtrack.phi() << " " << simtrack.vx() << " " + << simtrack.vy() << " " << simtrack.vz() << " " << eff << " " << effloose << " " << dpt << " " << dphi + << " " << deta << " " << dz0 << endl; + } + } + } + + int ntrack = 0; + for (auto &track : tracks) { + if (settings.writeMonitorData("Pars")) { + outpars << track->duplicate() << " " << track->eta(settings) << " " << track->phi0(settings) << " " + << track->z0(settings) << " " << angle0to2pi::make0To2pi(track->phi0(settings)) / (2 * M_PI / N_SECTOR) + << " " << track->rinv(settings); + } + if (!track->duplicate()) { + ntrack++; + } + } + + edm::LogVerbatim("Tracklet") << "Number of found tracks : " << tracks.size() << " unique " << ntrack; + } + + eventProcessor.printSummary(); +} diff --git a/L1Trigger/TrackerDTC/interface/DTC.h b/L1Trigger/TrackerDTC/interface/DTC.h index f49ad66708e28..145e2f906d0fc 100644 --- a/L1Trigger/TrackerDTC/interface/DTC.h +++ b/L1Trigger/TrackerDTC/interface/DTC.h @@ -1,8 +1,7 @@ #ifndef L1Trigger_TrackerDTC_DTC_h #define L1Trigger_TrackerDTC_DTC_h -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" #include "L1Trigger/TrackerDTC/interface/Stub.h" #include @@ -10,9 +9,6 @@ namespace trackerDTC { - class Settings; - class Module; - // representation of an outer tracker DTC board class DTC { private: @@ -21,7 +17,10 @@ namespace trackerDTC { typedef std::vector Stubsss; public: - DTC(Settings* settings, int dtcId, const std::vector>& modules); + DTC(const edm::ParameterSet& iConfig, + const Setup& setup, + int dtcId, + const std::vector>& stubsDTC); ~DTC() {} // board level routing in two steps and products filling void produce(TTDTC& accepted, TTDTC& lost); @@ -37,13 +36,15 @@ namespace trackerDTC { Stub* pop_front(Stubs& stubs); // helper class to store configurations - Settings* settings_; + const Setup* setup_; + // enables emulation of truncation + bool enableTruncation_; // outer tracker detector region [0-8] int region_; // outer tracker dtc id in region [0-23] int board_; // container of modules connected to this DTC - std::vector modules_; + std::vector modules_; // container of stubs on this DTC std::vector stubs_; // input stubs organised in routing blocks [0..1] and channel [0..35] diff --git a/L1Trigger/TrackerDTC/interface/Module.h b/L1Trigger/TrackerDTC/interface/Module.h deleted file mode 100644 index 3a2de190cfbc4..0000000000000 --- a/L1Trigger/TrackerDTC/interface/Module.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef L1Trigger_TrackerDTC_Module_h -#define L1Trigger_TrackerDTC_Module_h - -#include "DataFormats/DetId/interface/DetId.h" -#include "DataFormats/Math/interface/deltaPhi.h" -#include "L1Trigger/TrackerDTC/interface/SettingsHybrid.h" - -#include - -namespace trackerDTC { - - class Settings; - - // representation of an outer tracker sensormodule - class Module { - friend class Stub; - - public: - Module(Settings* settings, const ::DetId& detId, int dtcId); - ~Module() {} - - private: - // handles 2 pi overflow - double deltaPhi(double phi) { return reco::deltaPhi(phi, 0.); } - - // detector region [0-8] - int region_; - // +z or -z - bool side_; - // barrel or endcap - bool barrel_; - // main sensor inside or outside - bool flipped_; - // TTStub row needs flip of sign - bool signRow_; - // TTStub col needs flip of sign - bool signCol_; - // TTStub bend needs flip of sign - bool signBend_; - // number of columns [2S=2,PS=8] - int numColumns_; - // number of rows [2S=8*127,PS=8*120] - int numRows_; - // layer id [1-6,11-15] - int layerId_; - // module radius in cm - double R_; - // module phi w.r.t. detector region centre in rad - double Phi_; - // module z in cm - double Z_; - // sensor separation in cm - double sep_; - // sensor pitch in cm [strip=.009,pixel=.01] - double pitchRow_; - // sensor length in cm [strip=5,pixel=.15625] - double pitchCol_; - // module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis - double tilt_; - // sinus of module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis - double sin_; - // cosinus of module tilt measured w.r.t. beam axis (+-1=endcap), tk layout measures w.r.t. radial axis - double cos_; - - // hybrid format specific member - - // module type (barrelPS, barrel2S, diskPS, disk2S) - SettingsHybrid::SensorType type_; - // decoded radius of disk2S stubs - int decodedR_; - // stub radius offset for barrelPS, barrel2S - double offsetR_; - // stub z offset for diskPS, disk2S - double offsetZ_; - // index = encoded bend, value = decoded bend - std::vector bendEncoding_; - }; - -} // namespace trackerDTC - -#endif diff --git a/L1Trigger/TrackerDTC/interface/SensorModule.h b/L1Trigger/TrackerDTC/interface/SensorModule.h new file mode 100644 index 0000000000000..f1286bcf2934d --- /dev/null +++ b/L1Trigger/TrackerDTC/interface/SensorModule.h @@ -0,0 +1,134 @@ +#ifndef L1Trigger_TrackerDTC_SensorModule_h +#define L1Trigger_TrackerDTC_SensorModule_h + +#include "DataFormats/DetId/interface/DetId.h" + +namespace trackerDTC { + + class Setup; + + // representation of an outer tracker sensormodule + class SensorModule { + public: + SensorModule(const Setup& setup, const DetId& detId, int dtcId, int modId); + ~SensorModule() {} + + enum Type { BarrelPS, Barrel2S, DiskPS, Disk2S, NumTypes }; + + // module type (BarrelPS, Barrel2S, DiskPS, Disk2S) + Type type() const { return type_; } + // dtc id [0-215] + int dtcId() const { return dtcId_; } + // module on dtc id [0-71] + int modId() const { return modId_; } + // +z or -z + bool side() const { return side_; } + // barrel or endcap + bool barrel() const { return barrel_; } + // Pixel-Strip or 2Strip module + bool psModule() const { return psModule_; } + // main sensor inside or outside + bool flipped() const { return flipped_; } + // TTStub row needs flip of sign + bool signRow() const { return signRow_; } + // TTStub col needs flip of sign + bool signCol() const { return signCol_; } + // TTStub bend needs flip of sign + bool signBend() const { return signBend_; } + // number of columns [2S=2,PS=8] + int numColumns() const { return numColumns_; } + // number of rows [2S=8*127,PS=8*120] + int numRows() const { return numRows_; } + // layer id [1-6,11-15] + int layerId() const { return layerId_; } + // module radius in cm + double r() const { return r_; } + // module phi w.r.t. detector region centre in rad + double phi() const { return phi_; } + // module z in cm + double z() const { return z_; } + // sensor separation in cm + double sep() const { return sep_; } + // sensor pitch in cm [strip=.009,pixel=.01] + double pitchRow() const { return pitchRow_; } + // sensor length in cm [strip=5,pixel=.15625] + double pitchCol() const { return pitchCol_; } + // module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis + double tilt() const { return tilt_; } + // sinus of module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis + double sin() const { return sin_; } + // cosinus of module tilt measured w.r.t. beam axis (+-1=endcap), tk layout measures w.r.t. radial axis + double cos() const { return cos_; } + // encoded radius of disk2S stubs, used in Hybrid + int encodedR() const { return encodedR_; } + // encoded layer id [0-3] + int encodedLayerId() const { return encodedLayerId_; } + // stub radius offset for barrelPS, barrel2S, used in Hybrid + double offsetR() const { return offsetR_; } + // stub z offset for diskPS, disk2S, used in Hybrid + double offsetZ() const { return offsetZ_; } + // bend window size in half strip units + int windowSize() const { return windowSize_; } + + private: + // cmssw det id + DetId detId_; + // dtc id [0-215] + int dtcId_; + // module on dtc id [0-71] + int modId_; + // +z or -z + bool side_; + // barrel or endcap + bool barrel_; + // Pixel-Strip or 2Strip module + bool psModule_; + // main sensor inside or outside + bool flipped_; + // TTStub row needs flip of sign + bool signRow_; + // TTStub col needs flip of sign + bool signCol_; + // TTStub bend needs flip of sign + bool signBend_; + // number of columns [2S=2,PS=8] + int numColumns_; + // number of rows [2S=8*127,PS=8*120] + int numRows_; + // layer id [1-6,11-15] + int layerId_; + // module radius in cm + double r_; + // module phi w.r.t. detector region centre in rad + double phi_; + // module z in cm + double z_; + // sensor separation in cm + double sep_; + // sensor pitch in cm [strip=.009,pixel=.01] + double pitchRow_; + // sensor length in cm [strip=5,pixel=.15625] + double pitchCol_; + // module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis + double tilt_; + // sinus of module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis + double sin_; + // cosinus of module tilt measured w.r.t. beam axis (+-1=endcap), tk layout measures w.r.t. radial axis + double cos_; + // module type (barrelPS, barrel2S, diskPS, disk2S) + Type type_; + // encoded radius of disk2S stubs, used in Hybrid + int encodedR_; + // encoded layer id [0-3] + int encodedLayerId_; + // stub radius offset for barrelPS, barrel2S, used in Hybrid + double offsetR_; + // stub z offset for diskPS, disk2S, used in Hybrid + double offsetZ_; + // bend window size in half strip units + int windowSize_; + }; + +} // namespace trackerDTC + +#endif diff --git a/L1Trigger/TrackerDTC/interface/Settings.h b/L1Trigger/TrackerDTC/interface/Settings.h deleted file mode 100644 index 8d413477b8293..0000000000000 --- a/L1Trigger/TrackerDTC/interface/Settings.h +++ /dev/null @@ -1,461 +0,0 @@ -#ifndef L1Trigger_TrackerDTC_Settings_h -#define L1Trigger_TrackerDTC_Settings_h - -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/ESInputTag.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "DataFormats/Provenance/interface/ProcessHistory.h" -#include "DataFormats/DetId/interface/DetId.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "MagneticField/Engine/interface/MagneticField.h" -#include "CondFormats/SiPhase2TrackerObjects/interface/TrackerDetToDTCELinkCablingMap.h" -#include "DetectorDescription/Core/interface/DDCompactView.h" -#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithm.h" - -#include "L1Trigger/TrackerDTC/interface/SettingsHybrid.h" -#include "L1Trigger/TrackerDTC/interface/SettingsTMTT.h" -#include "L1Trigger/TrackerDTC/interface/Module.h" - -#include -#include -#include - -namespace trackerDTC { - - // stores, calculates and provides run-time constants - class Settings { - friend class SettingsHybrid; - friend class SettingsTMTT; - - private: - enum SubDetId { pixelBarrel = 1, pixelDisks = 2 }; - - public: - Settings(const edm::ParameterSet& iConfig); - ~Settings() {} - - // store TrackerGeometry - void setTrackerGeometry(const TrackerGeometry* trackerGeometry); - // store TrackerTopology - void setTrackerTopology(const TrackerTopology* trackerTopology); - // store MagneticField - void setMagneticField(const MagneticField* magneticField); - // store TrackerDetToDTCELinkCablingMap - void setCablingMap(const TrackerDetToDTCELinkCablingMap* cablingMap); - // store TTStubAlgorithm handle - void setTTStubAlgorithm(const edm::ESHandle>& handleTTStubAlgorithm); - // store GeometryConfiguration handle - void setGeometryConfiguration(const edm::ESHandle& handleGeometryConfiguration); - // store ProcessHistory - void setProcessHistory(const edm::ProcessHistory& processHistory); - // check current coniguration consistency with input configuration - void checkConfiguration(); - // convert ES Products into handy objects - void beginRun(); - // convert DetId to module id [0:15551] - int modId(const ::DetId& detId) const; - // collection of modules connected to a specific dtc - const std::vector& modules(int dtcId) const; - - // ED parameter - - const edm::InputTag& inputTagTTStubDetSetVec() const { return inputTagTTStubDetSetVec_; } - const edm::ESInputTag& inputTagMagneticField() const { return inputTagMagneticField_; } - const edm::ESInputTag& inputTagTrackerGeometry() const { return inputTagTrackerGeometry_; } - const edm::ESInputTag& inputTagTrackerTopology() const { return inputTagTrackerTopology_; } - const edm::ESInputTag& inputTagCablingMap() const { return inputTagCablingMap_; } - const edm::ESInputTag& inputTagTTStubAlgorithm() const { return inputTagTTStubAlgorithm_; } - const edm::ESInputTag& inputTagGeometryConfiguration() const { return inputTagGeometryConfiguration_; } - const std::string& productBranchAccepted() const { return productBranchAccepted_; } - const std::string& productBranchLost() const { return productBranchLost_; } - const std::string& dataFormat() const { return dataFormat_; } - // tk layout det id minus DetSetVec->detId - int offsetDetIdDSV() const { return offsetDetIdDSV_; } - // tk layout det id minus TrackerTopology lower det id - int offsetDetIdTP() const { return offsetDetIdTP_; } - // hybrid format specific configurations - SettingsHybrid* hybrid() const { return hybrid_.get(); } - // tmtt format specific configurations - SettingsTMTT* tmtt() const { return tmtt_.get(); } - // offset in layer ids between barrel layer and endcap disks - int offsetLayerDisks() const { return offsetLayerDisks_; } - // offset between 0 and smallest layer id (barrel layer 1) - int offsetLayerId() const { return offsetLayerId_; } - - // Router parameter - - // enables emulation of truncation - bool enableTruncation() const { return enableTruncation_; } - // time multiplexed period of track finding processor - int tmpTFP() const { return tmpTFP_; } - // needed gap between events of emp-infrastructure firmware - int numFramesInfra() const { return numFramesInfra_; } - // number of systiloic arrays in stub router firmware - int numRoutingBlocks() const { return numRoutingBlocks_; } - // fifo depth in stub router firmware - int sizeStack() const { return sizeStack_; } - - // Converter parameter - - // number of row bits used in look up table - int widthRowLUT() const { return widthRowLUT_; } - // number of bits used for stub qOverPt. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 - int widthQoverPt() const { return widthQoverPt_; } - - // Tracker parameter - - // number of regions a reconstructable particles may cross - int numOverlappingRegions() const { return numOverlappingRegions_; } - // number of phi slices the outer tracker readout is organized in - int numRegions() const { return numRegions_; } - // number of DTC boards used to readout a detector region - int numDTCsPerRegion() const { return numDTCsPerRegion_; } - // max number of sensor modules connected to one DTC board - int numModulesPerDTC() const { return numModulesPerDTC_; } - // number of bits used for internal stub bend - int widthBend() const { return widthBend_; } - // number of bits used for internal stub column - int widthCol() const { return widthCol_; } - // number of bits used for internal stub row - int widthRow() const { return widthRow_; } - // precision of internal stub bend in pitch units - double baseBend() const { return baseBend_; } - // precision of internal stub column in pitch units - double baseCol() const { return baseCol_; } - // precision of internal stub row in pitch units - double baseRow() const { return baseRow_; } - // used stub bend uncertainty in pitch units - double bendCut() const { return bendCut_; } - // LHC bunch crossing rate in MHz - double freqLHC() const { return freqLHC_; } - - // format specific router parameter - - // cut on stub eta - double maxEta() const { return maxEta_; } - // cut on stub pt, also defines region overlap shape in GeV - double minPt() const { return minPt_; } - // critical radius defining region overlap shape in cm - double chosenRofPhi() const { return chosenRofPhi_; } - // tmtt: number of detector layers a reconstructbale particle may cross - // hybrid: max number of detector layer connected to one DTC - int numLayers() const { return numLayers_; } - - // f/w parameter - - // magnetic field f/w value in T - double bField() const { return bField_; } - - // Analzyer - - // open and analyze TrackingParticles, original TTStubs and Association between them - bool useMCTruth() const { return useMCTruth_; } - // tag of AssociationMap between TTCluster and TrackingParticles - const edm::InputTag& inputTagTTClusterAssMap() const { return inputTagTTClusterAssMap_; } - // label of DTC producer - const std::string& producerLabel() const { return producerLabel_; } - - // TP - - // pt cut in GeV - double tpMinPt() const { return tpMinPt_; } - // eta cut - double tpMaxEta() const { return tpMaxEta_; } - // cut on vertex pos r in cm - double tpMaxVertR() const { return tpMaxVertR_; } - // cut on vertex pos z in cm - double tpMaxVertZ() const { return tpMaxVertZ_; } - // cut on impact parameter in cm - double tpMaxD0() const { return tpMaxD0_; } - // required number of associated layers to a TP to consider it reconstruct-able - int tpMinLayers() const { return tpMinLayers_; } - // required number of associated ps layers to a TP to consider it reconstruct-able - int tpMinLayersPS() const { return tpMinLayersPS_; } - - // derived Router parameter - - // total number of outer tracker DTCs - int numDTCs() const { return numDTCs_; } - // number of DTCs connected to one TFP (48) - int numDTCsPerTFP() const { return numDTCsPerTFP_; } - // total number of max possible outer tracker modules (72 per DTC) - int numModules() const { return numModules_; } - // number of inputs per systolic arrays in dtc firmware - int numModulesPerRoutingBlock() const { return numModulesPerRoutingBlock_; } - // max number of incomming stubs per packet (emp limit not cic limit) - int maxFramesChannelInput() const { return maxFramesChannelInput_; } - // max number out outgoing stubs per packet - int maxFramesChannelOutput() const { return maxFramesChannelOutput_; } - - // derived Converter parameter - - // number of bits used for internal stub r - ChosenRofPhi - int widthR() const { return widthR_; } - // number of bits used for internal stub phi w.r.t. region centre - int widthPhi() const { return widthPhi_; } - // number of bits used for internal stub z - int widthZ() const { return widthZ_; } - // number of merged rows for look up - int numMergedRows() const { return numMergedRows_; } - // number of bits used for stub layer id - int widthLayer() const { return widthLayer_; } - // number of bits used for phi of row slope - int widthM() const { return widthM_; } - // number of bits used for phi or row intercept - int widthC() const { return widthC_; } - // number of bits used for internal stub eta - int widthEta() const { return widthEta_; } - // converts GeV in 1/cm - double invPtToDphi() const { return invPtToDphi_; } - // range of internal stub q over pt - double rangeQoverPt() const { return rangeQoverPt_; } - // cut on stub cot - double maxCot() const { return maxCot_; } - // cut on stub q over pt - double maxQoverPt() const { return maxQoverPt_; } - // region size in rad - double baseRegion() const { return baseRegion_; } - // internal stub q over pt precision in 1 /cm - double baseQoverPt() const { return baseQoverPt_; } - // internal stub r precision in cm - double baseR() const { return baseR_; } - // internal stub z precision in cm - double baseZ() const { return baseZ_; } - // internal stub phi precision in rad - double basePhi() const { return basePhi_; } - // phi of row slope precision in rad / pitch unit - double baseM() const { return baseM_; } - // phi of row intercept precision in rad - double baseC() const { return baseC_; } - - // event setup - - const ::TrackerGeometry* trackerGeometry() const { return trackerGeometry_; } - const ::TrackerTopology* trackerTopology() const { return trackerTopology_; } - - // derived event setup - - // check if TrackerGeometry is supported - bool configurationSupported() const { return configurationSupported_; } - - private: - // DataFormats - - std::unique_ptr tmtt_; - std::unique_ptr hybrid_; - - //TrackerDTCProducer parameter sets - - const edm::ParameterSet paramsED_; - const edm::ParameterSet paramsRouter_; - const edm::ParameterSet paramsConverter_; - const edm::ParameterSet paramsTracker_; - const edm::ParameterSet paramsFW_; - const edm::ParameterSet paramsFormat_; - const edm::ParameterSet paramsAnalyzer_; - const edm::ParameterSet paramsTP_; - // ED parameter - - const edm::InputTag inputTagTTStubDetSetVec_; - const edm::ESInputTag inputTagMagneticField_; - const edm::ESInputTag inputTagTrackerGeometry_; - const edm::ESInputTag inputTagTrackerTopology_; - const edm::ESInputTag inputTagCablingMap_; - const edm::ESInputTag inputTagTTStubAlgorithm_; - const edm::ESInputTag inputTagGeometryConfiguration_; - const std::string supportedTrackerXMLPSet_; - const std::string supportedTrackerXMLPath_; - const std::string supportedTrackerXMLFile_; - const std::vector supportedTrackerXMLVersions_; - const std::string productBranchAccepted_; - const std::string productBranchLost_; - // "Hybrid" and "TMTT" format supported - const std::string dataFormat_; - // tk layout det id minus DetSetVec->detId - const int offsetDetIdDSV_; - // tk layout det id minus TrackerTopology lower det id - const int offsetDetIdTP_; - // offset in layer ids between barrel layer and endcap disks - const int offsetLayerDisks_; - // offset between 0 and smallest layer id (barrel layer 1) - const int offsetLayerId_; - const bool checkHistory_; - const std::string processName_; - const std::string productLabel_; - - // router parameter - - // enables emulation of truncation - const double enableTruncation_; - // Frequency in MHz, has to be integer multiple of FreqLHC - const double freqDTC_; - // time multiplexed period of track finding processor - const int tmpTFP_; - // needed gap between events of emp-infrastructure firmware - const int numFramesInfra_; - // number of systiloic arrays in stub router firmware - const int numRoutingBlocks_; - // fifo depth in stub router firmware - const int sizeStack_; - - // converter parameter - - // number of row bits used in look up table - const int widthRowLUT_; - // number of bits used for stub qOverPt - const int widthQoverPt_; - - // Tracker parameter - - // number of phi slices the outer tracker readout is organized in - const int numRegions_; - // number of regions a reconstructable particles may cross - const int numOverlappingRegions_; - // number of DTC boards used to readout a detector region - const int numDTCsPerRegion_; - // max number of sensor modules connected to one DTC board - const int numModulesPerDTC_; - // number of events collected in front-end - const int tmpFE_; - // number of bits used for internal stub bend - const int widthBend_; - // number of bits used for internal stub column - const int widthCol_; - // number of bits used for internal stub row - const int widthRow_; - // precision of internal stub bend in pitch units - const double baseBend_; - // precision of internal stub column in pitch units - const double baseCol_; - // precision of internal stub row in pitch units - const double baseRow_; - // used stub bend uncertainty in pitch units - const double bendCut_; - // LHC bunch crossing rate in MHz - const double freqLHC_; - - // f/w constants - - // in e8 m/s - const double speedOfLight_; - // in T - const double bField_; - // accepted difference to EventSetup in T - const double bFieldError_; - // outer radius of outer tracker in cm - const double outerRadius_; - // inner radius of outer tracker in cm - const double innerRadius_; - // max strip/pixel pitch of outer tracker sensors in cm - const double maxPitch_; - - // format specific parameter - - // cut on stub eta - const double maxEta_; - // cut on stub pt, also defines region overlap shape in GeV - const double minPt_; - // critical radius defining region overlap shape in cm - const double chosenRofPhi_; - // max number of detector layer connected to one DTC (hybrid) number of detector layers a reconstructbale particle may cross (tmtt) - const int numLayers_; - - // Analzyer - - const bool useMCTruth_; - const edm::InputTag inputTagTTClusterAssMap_; - const std::string producerLabel_; - - // TP - - const double tpMinPt_; - const double tpMaxEta_; - const double tpMaxVertR_; - const double tpMaxVertZ_; - const double tpMaxD0_; - const int tpMinLayers_; - const int tpMinLayersPS_; - - // derived router parameter - - // total number of outer tracker DTCs - int numDTCs_; - // number of DTCs connected to one TFP (48) - int numDTCsPerTFP_; - // total number of max possible outer tracker modules (72 per DTC) - int numModules_; - // number of inputs per systolic arrays in dtc firmware - int numModulesPerRoutingBlock_; - // max number of incomming stubs per packet (emp limit not cic limit) - int maxFramesChannelInput_; - // max number out outgoing stubs per packet - int maxFramesChannelOutput_; - - // derived Converter parameter - - // number of bits used for internal stub r - ChosenRofPhi - int widthR_; - // number of bits used for internal stub phi w.r.t. region centre - int widthPhi_; - // number of bits used for internal stub z - int widthZ_; - // number of merged rows for look up - int numMergedRows_; - // number of bits used for stub layer id - int widthLayer_; - // number of bits used for phi of row slope - int widthM_; - // number of bits used for phi or row intercept - int widthC_; - // number of bits used for internal stub eta - int widthEta_; - // converts GeV in 1/cm - double invPtToDphi_; - // range of internal stub q over pt - double rangeQoverPt_; - // cut on stub cot - double maxCot_; - // cut on stub q over pt - double maxQoverPt_; - // region size in rad - double baseRegion_; - // internal stub q over pt precision in 1 /cm - double baseQoverPt_; - // internal stub r precision in cm - double baseR_; - // internal stub z precision in cm - double baseZ_; - // internal stub phi precision in rad - double basePhi_; - // phi of row slope precision in rad / pitch unit - double baseM_; - // phi of row intercept precision in rad - double baseC_; - - // event setup - - const ::TrackerGeometry* trackerGeometry_; - const ::TrackerTopology* trackerTopology_; - const ::MagneticField* magneticField_; - const ::TrackerDetToDTCELinkCablingMap* ttCablingMap_; - edm::ESHandle> handleTTStubAlgorithm_; - edm::ESHandle handleGeometryConfiguration_; - edm::ProcessHistory processHistory_; - - // derived event setup - - // value = track trigger module id [0-15551], key = det id - std::unordered_map<::DetId, int> cablingMap_; - // collection of outer tracker sensor modules - std::vector modules_; - // collection of outer tracker sensor modules organised in DTCS [0-215][0-71] - std::vector> dtcModules_; - // true if tracker geometry and bfield is supported - bool configurationSupported_; - }; - -} // namespace trackerDTC - -#endif diff --git a/L1Trigger/TrackerDTC/interface/SettingsHybrid.h b/L1Trigger/TrackerDTC/interface/SettingsHybrid.h deleted file mode 100644 index 166b60f63c1ce..0000000000000 --- a/L1Trigger/TrackerDTC/interface/SettingsHybrid.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef L1Trigger_TrackerDTC_SettingsHybrid_h -#define L1Trigger_TrackerDTC_SettingsHybrid_h - -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include -#include - -namespace trackerDTC { - - class Settings; - - // Hybrid data format specific settings - class SettingsHybrid { - friend class Settings; - - public: - enum SensorType { barrelPS, barrel2S, diskPS, disk2S, numSensorTypes }; - - SettingsHybrid(const edm::ParameterSet& iConfig, Settings* settings); - ~SettingsHybrid() {} - - void checkConfiguration(Settings* settings) const; - - void createEncodingsBend(Settings* settings); - void createEncodingsLayer(Settings* settings); - - // TTStubalgo parameter - - double baseWindowSize() const { return baseWindowSize_; } - - // format specific parameter - - int widthR(SensorType type) const { return widthsR_[type]; } - int widthPhi(SensorType type) const { return widthsPhi_[type]; } - int widthZ(SensorType type) const { return widthsZ_[type]; } - int widthAlpha(SensorType type) const { return widthsAlpha_[type]; } - int widthBend(SensorType type) const { return widthsBend_[type]; } - const std::vector& numRingsPS() const { return numRingsPS_; } - const std::vector& layerRs() const { return layerRs_; } - const std::vector& diskZs() const { return diskZs_; } - - // derived format specific parameter - - double baseR(SensorType type) const { return basesR_[type]; } - double basePhi(SensorType type) const { return basesPhi_[type]; } - double baseZ(SensorType type) const { return basesZ_[type]; } - double baseAlpha(SensorType type) const { return basesAlpha_[type]; } - int numUnusedBits(SensorType type) const { return numsUnusedBits_[type]; } - - // derived TTStubalgo parameter - - const std::vector& numTiltedLayerRings() const { return numTiltedLayerRings_; } - const std::vector& windowSizeBarrelLayers() const { return windowSizeBarrelLayers_; } - const std::vector>& windowSizeTiltedLayerRings() const { return windowSizeTiltedLayerRings_; } - const std::vector>& windowSizeEndcapDisksRings() const { return windowSizeEndcapDisksRings_; } - - // Hybrid specific encodings - - const std::vector>& layerIdEncodings() const { return layerIdEncodings_; } - const std::vector>& bendEncodingsPS() const { return bendEncodingsPS_; } - const std::vector>& bendEncodings2S() const { return bendEncodings2S_; } - double disk2SR(int disk, int index) const { return disk2SRs_.at(disk).at(index); } - - private: - //TrackerDTCFormat parameter sets - - const edm::ParameterSet paramsFormat_; - const edm::ParameterSet paramsTTStubAlgo_; - - // TTStubAlgo parameter - - // check consitency between configured TTStub algo and the one used during input sample production - const bool checkHistory_; - // producer name used during input sample production - const std::string productLabel_; - // process name used during input sample production - const std::string processName_; - // precision of window sizes in pitch units - const double baseWindowSize_; - - // format specific parameter - - // number of outer PS rings for disk 1-5 - const std::vector numRingsPS_; - // number of bits used for stub r w.r.t layer/disk centre - const std::vector widthsR_; - // number of bits used for stub z w.r.t layer/disk centre - const std::vector widthsZ_; - // number of bits used for stub phi w.r.t. region centre - const std::vector widthsPhi_; - // number of bits used for stub row number - const std::vector widthsAlpha_; - // number of bits used for stub bend number - const std::vector widthsBend_; - // range in stub r which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - const std::vector rangesR_; - // range in stub z which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - const std::vector rangesZ_; - // range in stub row which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - const std::vector rangesAlpha_; - // mean radius of outer tracker barrel layer - const std::vector layerRs_; - // mean z of outer tracker endcap disks - const std::vector diskZs_; - // center radius of outer tracker endcap 2S diks strips - const std::vector disk2SRsSet_; - - // derived format specific parameter - - // precision or r in cm for (barrelPS, barrel2S, diskPS, disk2S) - std::vector basesR_; - // precision or phi in rad for (barrelPS, barrel2S, diskPS, disk2S) - std::vector basesPhi_; - // precision or z in cm for (barrelPS, barrel2S, diskPS, disk2S) - std::vector basesZ_; - // precision or alpha in pitch units for (barrelPS, barrel2S, diskPS, disk2S) - std::vector basesAlpha_; - // number of padded 0s in output data format for (barrelPS, barrel2S, diskPS, disk2S) - std::vector numsUnusedBits_; - // center radius of outer tracker endcap 2S diks strips - std::vector> disk2SRs_; - - // derived TTStubalgo parameter - - std::vector numTiltedLayerRings_; - std::vector windowSizeBarrelLayers_; - std::vector> windowSizeTiltedLayerRings_; - std::vector> windowSizeEndcapDisksRings_; - - // Hybrid specific encodings - - // outer index = dtc id, inner index = encoded layer id, value = decoded layer id - std::vector> layerIdEncodings_; - // outer index = max window size in half strip units, inner index = decoded bend, value = encoded bend for PS modules - std::vector> bendEncodingsPS_; - // outer index = max window size in half strip units, inner index = decoded bend, value = encoded bend for 2S modules - std::vector> bendEncodings2S_; - }; - -} // namespace trackerDTC - -#endif \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/interface/SettingsTMTT.h b/L1Trigger/TrackerDTC/interface/SettingsTMTT.h deleted file mode 100644 index 3f677750ccaf6..0000000000000 --- a/L1Trigger/TrackerDTC/interface/SettingsTMTT.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef L1Trigger_TrackerDTC_SettingsTMTT_h -#define L1Trigger_TrackerDTC_SettingsTMTT_h - -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include - -namespace trackerDTC { - - class Settings; - - // TMTT data format specific settings - class SettingsTMTT { - friend class Settings; - - public: - SettingsTMTT(const edm::ParameterSet& iConfig, Settings* settings); - ~SettingsTMTT() {} - - // format specific parameter - - int numSectorsPhi() const { return numSectorsPhi_; } - int numBinsQoverPt() const { return numBinsQoverPt_; } - int numBinsPhiT() const { return numBinsPhiT_; } - double chosenRofZ() const { return chosenRofZ_; } - double beamWindowZ() const { return beamWindowZ_; } - double boundariesEta(const int& eta) const { return boundariesEta_[eta]; } - - // format specific parameter - - int numSectorsEta() const { return numSectorsEta_; } - int widthQoverPtBin() const { return widthQoverPtBin_; } - int numUnusedBits() const { return numUnusedBits_; } - double maxZT() const { return maxZT_; } - double baseSector() const { return baseSector_; } - double baseQoverPt() const { return baseQoverPtBin_; } - - private: - //TrackerDTCFormat parameter sets - - const edm::ParameterSet paramsFormat_; - - // format specific parameter - - // number of phi sectors used during track finding - const int numSectorsPhi_; - // number of qOverPt bins used during track finding - const int numBinsQoverPt_; - // number of phiT bins used during track finding - const int numBinsPhiT_; - // critical radius defining r-z sector shape in cm - const double chosenRofZ_; - // half lumi region size in cm - const double beamWindowZ_; - // has to be >= max stub z / 2 in cm - const double halfLength_; - // defining r-z sector shape - const std::vector boundariesEta_; - - // derived format specific parameter - - // number of eta sectors used during track finding - int numSectorsEta_; - // number of bits used for stub q over pt - int widthQoverPtBin_; - // number of padded 0s in output data format - int numUnusedBits_; - // cut on zT - double maxZT_; - // width of phi sector in rad - double baseSector_; - // precision of qOverPt bins used during track finding - double baseQoverPtBin_; - }; - -} // namespace trackerDTC - -#endif \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/interface/Setup.h b/L1Trigger/TrackerDTC/interface/Setup.h new file mode 100644 index 0000000000000..e9dadf7c9e20a --- /dev/null +++ b/L1Trigger/TrackerDTC/interface/Setup.h @@ -0,0 +1,939 @@ +#ifndef L1Trigger_TrackerDTC_Setup_h +#define L1Trigger_TrackerDTC_Setup_h + +#include "FWCore/Framework/interface/data_default_record_trait.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/Registry.h" +#include "DataFormats/Provenance/interface/ProcessHistory.h" +#include "DataFormats/Provenance/interface/ParameterSetID.h" +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "DataFormats/SiStripDetId/interface/StripSubdetector.h" +#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "DetectorDescription/Core/interface/DDCompactView.h" +#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithm_official.h" +#include "MagneticField/Engine/interface/MagneticField.h" +#include "CondFormats/SiPhase2TrackerObjects/interface/TrackerDetToDTCELinkCablingMap.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "L1Trigger/TrackerDTC/interface/SetupRcd.h" +#include "L1Trigger/TrackerDTC/interface/SensorModule.h" + +#include +#include + +namespace trackerDTC { + + typedef TTStubAlgorithm StubAlgorithm; + typedef TTStubAlgorithm_official StubAlgorithmOfficial; + // handles 2 pi overflow + inline double deltaPhi(double lhs, double rhs = 0.) { return reco::deltaPhi(lhs, rhs); } + + /*! \class trackerDTC::Setup + * \brief Class to process and provide run-time constants used by Track Trigger emulators + * \author Thomas Schuh + * \date 2020, Apr + */ + class Setup { + public: + Setup() {} + Setup(const edm::ParameterSet& iConfig, + const MagneticField& magneticField, + const TrackerGeometry& trackerGeometry, + const TrackerTopology& trackerTopology, + const TrackerDetToDTCELinkCablingMap& cablingMap, + const StubAlgorithmOfficial& stubAlgorithm, + const edm::ParameterSet& pSetStubAlgorithm, + const edm::ParameterSet& pSetGeometryConfiguration, + const edm::ParameterSetID& pSetIdTTStubAlgorithm, + const edm::ParameterSetID& pSetIdGeometryConfiguration); + ~Setup() {} + + // true if tracker geometry and magnetic field supported + bool configurationSupported() const { return configurationSupported_; } + // checks current configuration vs input sample configuration + void checkHistory(const edm::ProcessHistory& processHistory) const; + // converts tk layout id into dtc id + int dtcId(int tklId) const; + // converts dtci id into tk layout id + int tkLayoutId(int dtcId) const; + // converts TFP identifier (region[0-8], channel[0-47]) into dtcId [0-215] + int dtcId(int tfpRegion, int tfpChannel) const; + // checks if given dtcId is connected to PS or 2S sensormodules + bool psModule(int dtcId) const; + // checks if given dtcId is connected to -z (false) or +z (true) + bool side(int dtcId) const; + // ATCA slot number [0-11] of given dtcId + int slot(int dtcId) const; + // sensor module for det id + SensorModule* sensorModule(const DetId& detId) const; + // TrackerGeometry + const TrackerGeometry* trackerGeometry() const { return trackerGeometry_; } + // TrackerTopology + const TrackerTopology* trackerTopology() const { return trackerTopology_; } + // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47] + GlobalPoint stubPos(bool hybrid, const TTDTC::Frame& frame, int tfpRegion, int tfpChannel) const; + // returns global TTStub position + GlobalPoint stubPos(const TTStubRef& ttStubRef) const; + // empty trackerDTC EDProduct + TTDTC ttDTC() const { return TTDTC(numRegions_, numOverlappingRegions_, numDTCsPerRegion_); } + + // Common track finding parameter + + // half lumi region size in cm + double beamWindowZ() const { return beamWindowZ_; } + // number of frames betwen 2 resets of 18 BX packets + int numFrames() const { return numFrames_; } + // number of valid frames per 18 BX packet + int numFramesIO() const { return numFramesIO_; } + // number of valid frames per 8 BX packet + int numFramesFE() const { return numFramesFE_; } + // converts GeV in 1/cm + double invPtToDphi() const { return invPtToDphi_; } + // region size in rad + double baseRegion() const { return baseRegion_; } + // TP eta cut + double tpMaxEta() const { return tpMaxEta_; } + // TP cut on vertex pos r in cm + double tpMaxVertR() const { return tpMaxVertR_; } + // TP cut on vertex pos z in cm + double tpMaxVertZ() const { return tpMaxVertZ_; } + // TP cut on impact parameter in cm + double tpMaxD0() const { return tpMaxD0_; } + // required number of associated layers to a TP to consider it reconstruct-able + int tpMinLayers() const { return tpMinLayers_; } + // required number of associated ps layers to a TP to consider it reconstruct-able + int tpMinLayersPS() const { return tpMinLayersPS_; } + + // TMTT specific parameter + + // cut on stub and TP pt, also defines region overlap shape in GeV + double minPt() const { return minPt_; } + // cut on stub eta + double maxEta() const { return maxEta_; } + // critical radius defining region overlap shape in cm + double chosenRofPhi() const { return chosenRofPhi_; } + // number of detector layers a reconstructbale particle may cross + int numLayers() const { return numLayers_; } + // number of bits used for stub r - ChosenRofPhi + int widthR() const { return widthR_; } + // number of bits used for stub phi w.r.t. phi sector centre + int widthPhi() const { return widthPhi_; } + // number of bits used for stub z + int widthZ() const { return widthZ_; } + // number of bits used for stub layer id + int widthLayer() const { return widthLayer_; } + // internal stub r precision in cm + double baseR() const { return baseR_; } + // internal stub z precision in cm + double baseZ() const { return baseZ_; } + // internal stub phi precision in rad + double basePhi() const { return basePhi_; } + // number of padded 0s in output data format + int dtcNumUnusedBits() const { return dtcNumUnusedBits_; } + + // Hybrid specific parameter + + // cut on stub and TP pt, also defines region overlap shape in GeV + double hybridMinPt() const { return hybridMinPt_; } + // cut on stub eta + double hybridMaxEta() const { return hybridMaxEta_; } + // critical radius defining region overlap shape in cm + double hybridChosenRofPhi() const { return hybridChosenRofPhi_; } + // max number of detector layer connected to one DTC + int hybridNumLayers() const { return hybridNumLayers_; } + // number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + int hybridWidthR(SensorModule::Type type) const { return hybridWidthsR_.at(type); } + // number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + int hybridWidthZ(SensorModule::Type type) const { return hybridWidthsZ_.at(type); } + // number of bits used for stub phi w.r.t. region centre for module types (barrelPS, barrel2S, diskPS, disk2S) + int hybridWidthPhi(SensorModule::Type type) const { return hybridWidthsPhi_.at(type); } + // number of bits used for stub row number for module types (barrelPS, barrel2S, diskPS, disk2S) + int hybridWidthAlpha(SensorModule::Type type) const { return hybridWidthsAlpha_.at(type); } + // number of bits used for stub bend number for module types (barrelPS, barrel2S, diskPS, disk2S) + int hybridWidthBend(SensorModule::Type type) const { return hybridWidthsBend_.at(type); } + // number of bits used for stub layer id + int hybridWidthLayer() const { return hybridWidthLayer_; } + // precision or r in cm for (barrelPS, barrel2S, diskPS, disk2S) + double hybridBaseR(SensorModule::Type type) const { return hybridBasesR_.at(type); } + // precision or phi in rad for (barrelPS, barrel2S, diskPS, disk2S) + double hybridBasePhi(SensorModule::Type type) const { return hybridBasesPhi_.at(type); } + // precision or z in cm for (barrelPS, barrel2S, diskPS, disk2S) + double hybridBaseZ(SensorModule::Type type) const { return hybridBasesZ_.at(type); } + // precision or alpha in pitch units for (barrelPS, barrel2S, diskPS, disk2S) + double hybridBaseAlpha(SensorModule::Type type) const { return hybridBasesAlpha_.at(type); } + // number of padded 0s in output data format for (barrelPS, barrel2S, diskPS, disk2S) + int hybridNumUnusedBits(SensorModule::Type type) const { return hybridNumsUnusedBits_.at(type); } + // stub cut on cot(theta) = tan(lambda) = sinh(eta) + double hybridMaxCot() const { return hybridMaxCot_; } + // number of outer PS rings for disk 1, 2, 3, 4, 5 + int hybridNumRingsPS(int layerId) const { return hybridNumRingsPS_.at(layerId); } + // mean radius of outer tracker barrel layer + double hybridLayerR(int layerId) const { return hybridLayerRs_.at(layerId); } + // mean z of outer tracker endcap disks + double hybridDiskZ(int layerId) const { return hybridDiskZs_.at(layerId); } + + // Parameter specifying TTStub algorithm + + // number of tilted layer rings per barrel layer + double numTiltedLayerRing(int layerId) const { return numTiltedLayerRings_.at(layerId); }; + // stub bend window sizes for flat barrel layer in full pitch units + double windowSizeBarrelLayer(int layerId) const { return windowSizeBarrelLayers_.at(layerId); }; + // stub bend window sizes for tilted barrel layer rings in full pitch units + double windowSizeTiltedLayerRing(int layerId, int ring) const { + return windowSizeTiltedLayerRings_.at(layerId).at(ring); + }; + // stub bend window sizes for endcap disks rings in full pitch units + double windowSizeEndcapDisksRing(int layerId, int ring) const { + return windowSizeEndcapDisksRings_.at(layerId).at(ring); + }; + // precision of window sizes in pitch units + double baseWindowSize() const { return baseWindowSize_; } + // index = encoded bend, value = decoded bend for given window size and module type + const std::vector& encodingBend(int windowSize, bool psModule) const; + + // Parameter specifying front-end + + // number of bits used for internal stub bend + int widthBend() const { return widthBend_; } + // number of bits used for internal stub column + int widthCol() const { return widthCol_; } + // number of bits used for internal stub row + int widthRow() const { return widthRow_; } + // precision of internal stub bend in pitch units + double baseBend() const { return baseBend_; } + // precision of internal stub column in pitch units + double baseCol() const { return baseCol_; } + // precision of internal stub row in pitch units + double baseRow() const { return baseRow_; } + // used stub bend uncertainty in pitch units + double bendCut() const { return bendCut_; } + + // Parameter specifying DTC + + // number of phi slices the outer tracker readout is organized in + int numRegions() const { return numRegions_; } + // number of regions a reconstructable particles may cross + int numOverlappingRegions() const { return numOverlappingRegions_; } + // number of DTC boards used to readout a detector region, likely constructed to be an integerer multiple of NumSlots_ + int numDTCsPerRegion() const { return numDTCsPerRegion_; } + // max number of sensor modules connected to one DTC board + int numModulesPerDTC() const { return numModulesPerDTC_; } + // number of systiloic arrays in stub router firmware + int dtcNumRoutingBlocks() const { return dtcNumRoutingBlocks_; } + // fifo depth in stub router firmware + int dtcDepthMemory() const { return dtcDepthMemory_; } + // number of row bits used in look up table + int dtcWidthRowLUT() const { return dtcWidthRowLUT_; } + // number of bits used for stub qOverPt. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 + int dtcWidthQoverPt() const { return dtcWidthQoverPt_; } + // tk layout det id minus DetSetVec->detId + int offsetDetIdDSV() const { return offsetDetIdDSV_; } + // tk layout det id minus TrackerTopology lower det id + int offsetDetIdTP() const { return offsetDetIdTP_; } + // offset in layer ids between barrel layer and endcap disks + int offsetLayerDisks() const { return offsetLayerDisks_; } + // offset between 0 and smallest layer id (barrel layer 1) + int offsetLayerId() const { return offsetLayerId_; } + // total number of outer tracker DTCs + int numDTCs() const { return numDTCs_; } + // number of DTCs connected to one TFP (48) + int numDTCsPerTFP() const { return numDTCsPerTFP_; } + // total number of max possible outer tracker modules (72 per DTC) + int numModules() const { return numModules_; } + // max number of moudles connected to a systiloic array in stub router firmware + int dtcNumModulesPerRoutingBlock() const { return dtcNumModulesPerRoutingBlock_; } + // number of merged rows for look up + int dtcNumMergedRows() const { return dtcNumMergedRows_; } + // number of bits used for phi of row slope + int dtcWidthM() const { return dtcWidthM_; } + // internal stub q over pt precision in 1 /cm + double dtcBaseQoverPt() const { return dtcBaseQoverPt_; } + // phi of row slope precision in rad / pitch unit + double dtcBaseM() const { return dtcBaseM_; } + // number of bits for internal stub phi + int widthPhiDTC() const { return widthPhiDTC_; } + // sensor modules connected to given dtc id + const std::vector& dtcModules(int dtcId) const { return dtcModules_.at(dtcId); } + // index = encoded layerId, inner value = decoded layerId for given tfp channel [0-47] + const std::vector& encodingLayerId(int tfpChannel) const; + + // Parameter specifying GeometricProcessor + + // number of phi sectors used in hough transform + int numSectorsPhi() const { return numSectorsPhi_; } + // number of eta sectors used in hough transform + int numSectorsEta() const { return numSectorsEta_; } + // # critical radius defining r-z sector shape in cm + double chosenRofZ() const { return chosenRofZ_; } + // fifo depth in stub router firmware + int gpDepthMemory() const { return gpDepthMemory_; } + // defining r-z sector shape + double boundarieEta(int eta) const { return boundariesEta_.at(eta); } + // phi sector size in rad + double baseSector() const { return baseSector_; } + // cut on zT + double maxZT() const { return maxZT_; } + // cut on stub cot theta + double maxCot() const { return maxCot_; } + // number of bits used for internal stub sector eta + int widthSectorEta() const { return widthSectorEta_; } + // number of bits to represent z residual w.r.t. sector center + int widthChiZ() const { return widthChiZ_; } + + // Parameter specifying HoughTransform + + // number of qOverPt bins used in hough transform + int htNumBinsQoverPt() const { return htNumBinsQoverPt_; } + // number of phiT bins used in hough transform + int htNumBinsPhiT() const { return htNumBinsPhiT_; } + // required number of stub layers to form a candidate + int htMinLayers() const { return htMinLayers_; } + // internal fifo depth + int htDepthMemory() const { return htDepthMemory_; } + // number of bits used for candidate q over pt + int htWidthQoverPt() const { return htWidthQoverPt_; } + // number of bits used for candidate phiT + int htWidthPhiT() const { return htWidthPhiT_; } + // number of bits to represent phi residual w.r.t. ht candiate + int widthChiPhi() const { return widthChiPhi_; } + // q over pt bin width precision in 1 /cm + double htBaseQoverPt() const { return htBaseQoverPt_; } + // phiT bin width in rad + double htBasePhiT() const { return htBasePhiT_; } + + // Parameter specifying MiniHoughTransform + + // number of finer qOverPt bins inside HT bin + int mhtNumBinsQoverPt() const { return mhtNumBinsQoverPt_; } + // number of finer phiT bins inside HT bin + int mhtNumBinsPhiT() const { return mhtNumBinsPhiT_; } + // number of dynamic load balancing steps + int mhtNumDLB() const { return mhtNumDLB_; } + // required number of stub layers to form a candidate + int mhtMinLayers() const { return mhtMinLayers_; } + // number of mht cells + int mhtNumCells() const { return mhtNumCells_; } + // number of bits used for candidate q over pt + int mhtWidthQoverPt() const { return mhtWidthQoverPt_; } + // number of bits used for candidate phiT + int mhtWidthPhiT() const { return mhtWidthPhiT_; } + // q over pt bin width precision in 1 /cm + double mhtBaseQoverPt() const { return mhtBaseQoverPt_; } + // phiT bin width in rad + double mhtBasePhiT() const { return mhtBasePhiT_; } + + // Parameter specifying SeedFilter + + // required number of stub layers to form a candidate + int sfMinLayers() const { return sfMinLayers_; } + // cot(theta) precision + double sfBaseCot() const { return sfBaseCot_; } + // zT precision in cm + double sfBaseZT() const { return sfBaseZT_; } + + // Parameter specifying KalmanFilter + + // number of bits for internal reciprocal look up + int kfWidthLutInvPhi() const { return kfWidthLutInvPhi_; } + // number of bits for internal reciprocal look up + int kfWidthLutInvZ() const { return kfWidthLutInvZ_; } + // cut on number of input candidates + int kfNumTracks() const { return kfNumTracks_; } + // required number of stub layers to form a track + int kfMinLayers() const { return kfMinLayers_; } + // maximum number of layers added to a track + int kfMaxLayers() const { return kfMaxLayers_; } + // cut on number of stub per layer for input candidates + int kfMaxStubsPerLayer() const { return kfMaxStubsPerLayer_; } + // maximum allowed skipped layers from inside to outside to form a track + int kfMaxSkippedLayers() const { return kfMaxSkippedLayers_; } + double kfBasem0() const { return kfBasem0_; } + double kfBasem1() const { return kfBasem1_; } + double kfBasev0() const { return kfBasev0_; } + double kfBasev1() const { return kfBasev1_; } + double kfBasex0() const { return kfBasex0_; } + double kfBasex1() const { return kfBasex1_; } + double kfBasex2() const { return kfBasex2_; } + double kfBasex3() const { return kfBasex3_; } + double kfBaseH00() const { return kfBaseH00_; } + double kfBaseH12() const { return kfBaseH12_; } + double kfBaser0() const { return kfBaser0_; } + double kfBaser1() const { return kfBaser1_; } + double kfBaser02() const { return kfBaser02_; } + double kfBaser12() const { return kfBaser12_; } + double kfBaseS00() const { return kfBaseS00_; } + double kfBaseS01() const { return kfBaseS01_; } + double kfBaseS12() const { return kfBaseS12_; } + double kfBaseS13() const { return kfBaseS13_; } + double kfBaseR00() const { return kfBaseR00_; } + double kfBaseR11() const { return kfBaseR11_; } + double kfBaseInvR00() const { return kfBaseInvR00_; } + double kfBaseInvR11() const { return kfBaseInvR11_; } + double kfBaseK00() const { return kfBaseK00_; } + double kfBaseK10() const { return kfBaseK10_; } + double kfBaseK21() const { return kfBaseK21_; } + double kfBaseK31() const { return kfBaseK31_; } + double kfBaseC00() const { return kfBaseC00_; } + double kfBaseC01() const { return kfBaseC01_; } + double kfBaseC11() const { return kfBaseC11_; } + double kfBaseC22() const { return kfBaseC22_; } + double kfBaseC23() const { return kfBaseC23_; } + double kfBaseC33() const { return kfBaseC33_; } + double kfBaseChi20() const { return kfBaseChi20_; } + double kfBaseChi21() const { return kfBaseChi21_; } + double kfBaseChi2() const { return kfBaseChi2_; } + + // Parameter specifying DuplicateRemoval + + // internal memory depth + int drDepthMemory() const { return drDepthMemory_; } + // number of bist used for phi0 + int drWidthPhi0() const { return drWidthPhi0_; } + // umber of bist used for qOverPt + int drWidthQoverPt() const { return drWidthQoverPt_; } + // number of bist used for cot(theta) + int drWidthCot() const { return drWidthCot_; } + // number of bist used for z0 + int drWidthZ0() const { return drWidthZ0_; } + double drBaseQoverPt() const { return drBaseQoverPt_; } + double drBasePhi0() const { return drBasePhi0_; } + double drBaseCot() const { return drBaseCot_; } + double drBaseZ0() const { return drBaseZ0_; } + + private: + // checks consitency between history and current configuration for a specific module + void checkHistory(const edm::ProcessHistory&, + const edm::pset::Registry*, + const std::string&, + const edm::ParameterSetID&) const; + // dumps pSetHistory where incosistent lines with pSetProcess are highlighted + std::string dumpDiff(const edm::ParameterSet& pSetHistory, const edm::ParameterSet& pSetProcess) const; + // check if bField is supported + void checkMagneticField(); + // check if geometry is supported + void checkGeometry(); + // derive constants + void calculateConstants(); + // convert configuration of TTStubAlgorithm + void consumeStubAlgorithm(); + // create bend encodings + void encodeBend(std::vector>&, bool) const; + // create encodingsLayerId + void encodeLayerId(); + // create sensor modules + void produceSensorModules(); + // range check of dtc id + void checkDTCId(int dtcId) const; + // range check of tklayout id + void checkTKLayoutId(int tkLayoutId) const; + // range check of tfp identifier + void checkTFPIdentifier(int tfpRegion, int tfpChannel) const; + + // MagneticField + const MagneticField* magneticField_; + // TrackerGeometry + const TrackerGeometry* trackerGeometry_; + // TrackerTopology + const TrackerTopology* trackerTopology_; + // CablingMap + const TrackerDetToDTCELinkCablingMap* cablingMap_; + // TTStub algorithm used to create bend encodings + const StubAlgorithmOfficial* stubAlgorithm_; + // pSet of ttStub algorithm, used to identify bend window sizes of sensor modules + const edm::ParameterSet* pSetSA_; + // pSet of geometry configuration, used to identify if geometry is supported + const edm::ParameterSet* pSetGC_; + // pset id of current TTStubAlgorithm + edm::ParameterSetID pSetIdTTStubAlgorithm_; + // pset id of current geometry configuration + edm::ParameterSetID pSetIdGeometryConfiguration_; + + // Parameter to check if configured Tracker Geometry is supported + edm::ParameterSet pSetSG_; + // label of ESProducer/ESSource + std::string sgXMLLabel_; + // compared path + std::string sgXMLPath_; + // compared filen ame + std::string sgXMLFile_; + // list of supported versions + std::vector sgXMLVersions_; + + // Parameter to check if Process History is consistent with process configuration + edm::ParameterSet pSetPH_; + // label of compared GeometryConfiguration + std::string phGeometryConfiguration_; + // label of compared TTStubAlgorithm + std::string phTTStubAlgorithm_; + + // Common track finding parameter + edm::ParameterSet pSetTF_; + // half lumi region size in cm + double beamWindowZ_; + // required number of layers a found track has to have in common with a TP to consider it matched to it + int matchedLayers_; + // required number of ps layers a found track has to have in common with a TP to consider it matched to it + int matchedLayersPS_; + // allowed number of stubs a found track may have not in common with its matched TP + int unMatchedStubs_; + // allowed number of PS stubs a found track may have not in common with its matched TP + int unMatchedStubsPS_; + + // TMTT specific parameter + edm::ParameterSet pSetTMTT_; + // cut on stub and TP pt, also defines region overlap shape in GeV + double minPt_; + // cut on stub eta + double maxEta_; + // critical radius defining region overlap shape in cm + double chosenRofPhi_; + // number of detector layers a reconstructbale particle may cross + int numLayers_; + // number of bits used for stub r - ChosenRofPhi + int widthR_; + // number of bits used for stub phi w.r.t. phi sector centre + int widthPhi_; + // number of bits used for stub z + int widthZ_; + + // Hybrid specific parameter + edm::ParameterSet pSetHybrid_; + // cut on stub and TP pt, also defines region overlap shape in GeV + double hybridMinPt_; + // cut on stub eta + double hybridMaxEta_; + // critical radius defining region overlap shape in cm + double hybridChosenRofPhi_; + // max number of detector layer connected to one DTC + int hybridNumLayers_; + // number of outer PS rings for disk 1, 2, 3, 4, 5 + std::vector hybridNumRingsPS_; + // number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridWidthsR_; + // number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridWidthsZ_; + // number of bits used for stub phi w.r.t. region centre for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridWidthsPhi_; + // number of bits used for stub row number for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridWidthsAlpha_; + // number of bits used for stub bend number for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridWidthsBend_; + // range in stub r which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridRangesR_; + // range in stub z which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridRangesZ_; + // range in stub row which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridRangesAlpha_; + // mean radius of outer tracker barrel layer + std::vector hybridLayerRs_; + // mean z of outer tracker endcap disks + std::vector hybridDiskZs_; + // center radius of outer tracker endcap 2S diks strips + std::vector hybridDisk2SRsSet_; + + // Parameter specifying TrackingParticle used for Efficiency measurements + edm::ParameterSet pSetTP_; + // eta cut + double tpMaxEta_; + // cut on vertex pos r in cm + double tpMaxVertR_; + // cut on vertex pos z in cm + double tpMaxVertZ_; + // cut on impact parameter in cm + double tpMaxD0_; + // required number of associated layers to a TP to consider it reconstruct-able + int tpMinLayers_; + // required number of associated ps layers to a TP to consider it reconstruct-able + int tpMinLayersPS_; + + // Fimrware specific Parameter + edm::ParameterSet pSetFW_; + // needed gap between events of emp-infrastructure firmware + int numFramesInfra_; + // LHC bunch crossing rate in MHz + double freqLHC_; + // processing Frequency of DTC & TFP in MHz, has to be integer multiple of FreqLHC + double freqBE_; + // number of events collected in front-end + int tmpFE_; + // time multiplexed period of track finding processor + int tmpTFP_; + // speed of light used in FW in e8 m/s + double speedOfLight_; + // BField used in fw in T + double bField_; + // accepted BField difference between FW to EventSetup in T + double bFieldError_; + // outer radius of outer tracker in cm + double outerRadius_; + // inner radius of outer tracker in cm + double innerRadius_; + // half length of outer tracker in cm + double halfLength_; + // max strip/pixel pitch of outer tracker sensors in cm + double maxPitch_; + + // Parameter specifying front-end + edm::ParameterSet pSetFE_; + // number of bits used for internal stub bend + int widthBend_; + // number of bits used for internal stub column + int widthCol_; + // number of bits used for internal stub row + int widthRow_; + // precision of internal stub bend in pitch units + double baseBend_; + // precision of internal stub column in pitch units + double baseCol_; + // precision of internal stub row in pitch units + double baseRow_; + // precision of window sizes in pitch units + double baseWindowSize_; + // used stub bend uncertainty in pitch units + double bendCut_; + + // Parameter specifying DTC + edm::ParameterSet pSetDTC_; + // number of phi slices the outer tracker readout is organized in + int numRegions_; + // number of regions a reconstructable particles may cross + int numOverlappingRegions_; + // number of Slots in used ATCA crates + int numATCASlots_; + // number of DTC boards used to readout a detector region, likely constructed to be an integerer multiple of NumSlots_ + int numDTCsPerRegion_; + // max number of sensor modules connected to one DTC board + int numModulesPerDTC_; + // number of systiloic arrays in stub router firmware + int dtcNumRoutingBlocks_; + // fifo depth in stub router firmware + int dtcDepthMemory_; + // number of row bits used in look up table + int dtcWidthRowLUT_; + // number of bits used for stub qOverPt. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 + int dtcWidthQoverPt_; + // tk layout det id minus DetSetVec->detId + int offsetDetIdDSV_; + // tk layout det id minus TrackerTopology lower det id + int offsetDetIdTP_; + // offset in layer ids between barrel layer and endcap disks + int offsetLayerDisks_; + // offset between 0 and smallest layer id (barrel layer 1) + int offsetLayerId_; + + // Parameter specifying GeometricProcessor + edm::ParameterSet pSetGP_; + // number of phi sectors used in hough transform + int numSectorsPhi_; + // number of eta sectors used in hough transform + int numSectorsEta_; + // # critical radius defining r-z sector shape in cm + double chosenRofZ_; + // range of stub z residual w.r.t. sector center which needs to be covered + double neededRangeChiZ_; + // fifo depth in stub router firmware + int gpDepthMemory_; + // defining r-z sector shape + std::vector boundariesEta_; + + // Parameter specifying HoughTransform + edm::ParameterSet pSetHT_; + // number of qOverPt bins used in hough transform + int htNumBinsQoverPt_; + // number of phiT bins used in hough transform + int htNumBinsPhiT_; + // required number of stub layers to form a candidate + int htMinLayers_; + // internal fifo depth + int htDepthMemory_; + + // Parameter specifying MiniHoughTransform + edm::ParameterSet pSetMHT_; + // number of finer qOverPt bins inside HT bin + int mhtNumBinsQoverPt_; + // number of finer phiT bins inside HT bin + int mhtNumBinsPhiT_; + // number of dynamic load balancing steps + int mhtNumDLB_; + // required number of stub layers to form a candidate + int mhtMinLayers_; + + // Parameter specifying SeedFilter + edm::ParameterSet pSetSF_; + // used cot(Theta) bin width = 2 ** this + int sfPowerBaseCot_; + // used zT bin width = baseZ * 2 ** this + int sfBaseDiffZ_; + // required number of stub layers to form a candidate + int sfMinLayers_; + + // Parameter specifying KalmanFilter + edm::ParameterSet pSetKF_; + // number of bits for internal reciprocal look up + int kfWidthLutInvPhi_; + // number of bits for internal reciprocal look up + int kfWidthLutInvZ_; + // cut on number of input candidates + int kfNumTracks_; + // required number of stub layers to form a track + int kfMinLayers_; + // maximum number of layers added to a track + int kfMaxLayers_; + // cut on number of stub per layer for input candidates + int kfMaxStubsPerLayer_; + // maximum allowed skipped layers from inside to outside to form a track + int kfMaxSkippedLayers_; + int kfBaseShiftr0_; + int kfBaseShiftr02_; + int kfBaseShiftv0_; + int kfBaseShiftS00_; + int kfBaseShiftS01_; + int kfBaseShiftK00_; + int kfBaseShiftK10_; + int kfBaseShiftR00_; + int kfBaseShiftInvR00_; + int kfBaseShiftChi20_; + int kfBaseShiftC00_; + int kfBaseShiftC01_; + int kfBaseShiftC11_; + int kfBaseShiftr1_; + int kfBaseShiftr12_; + int kfBaseShiftv1_; + int kfBaseShiftS12_; + int kfBaseShiftS13_; + int kfBaseShiftK21_; + int kfBaseShiftK31_; + int kfBaseShiftR11_; + int kfBaseShiftInvR11_; + int kfBaseShiftChi21_; + int kfBaseShiftC22_; + int kfBaseShiftC23_; + int kfBaseShiftC33_; + int kfBaseShiftChi2_; + + // Parameter specifying DuplicateRemoval + edm::ParameterSet pSetDR_; + // internal memory depth + int drDepthMemory_; + // number of bist used for phi0 + int drWidthPhi0_; + // umber of bist used for qOverPt + int drWidthQoverPt_; + // number of bist used for cot(theta) + int drWidthCot_; + // number of bist used for z0 + int drWidthZ0_; + + // + // Derived constants + // + + // true if tracker geometry and magnetic field supported + bool configurationSupported_; + + // TTStubAlgorithm + + // number of tilted layer rings per barrel layer + std::vector numTiltedLayerRings_; + // stub bend window sizes for flat barrel layer in full pitch units + std::vector windowSizeBarrelLayers_; + // stub bend window sizes for tilted barrel layer rings in full pitch units + std::vector> windowSizeTiltedLayerRings_; + // stub bend window sizes for endcap disks rings in full pitch units + std::vector> windowSizeEndcapDisksRings_; + // maximum stub bend window in half strip units + int maxWindowSize_; + + // common Track finding + + // number of frames betwen 2 resets of 18 BX packets + int numFrames_; + // number of valid frames per 18 BX packet + int numFramesIO_; + // number of valid frames per 8 BX packet + int numFramesFE_; + // converts GeV in 1/cm + double invPtToDphi_; + // region size in rad + double baseRegion_; + + // TMTT + + // number of bits used for stub layer id + int widthLayer_; + // internal stub r precision in cm + double baseR_; + // internal stub z precision in cm + double baseZ_; + // internal stub phi precision in rad + double basePhi_; + // number of padded 0s in output data format + int dtcNumUnusedBits_; + + // hybrid + + // number of bits used for stub layer id + int hybridWidthLayer_; + // precision or r in cm for (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridBasesR_; + // precision or phi in rad for (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridBasesPhi_; + // precision or z in cm for (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridBasesZ_; + // precision or alpha in pitch units for (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridBasesAlpha_; + // stub r precision in cm + double hybridBaseZ_; + // stub z precision in cm + double hybridBaseR_; + // stub phi precision in rad + double hybridBasePhi_; + // stub cut on cot(theta) = tan(lambda) = sinh(eta) + double hybridMaxCot_; + // number of padded 0s in output data format for (barrelPS, barrel2S, diskPS, disk2S) + std::vector hybridNumsUnusedBits_; + // center radius of outer tracker endcap 2S diks strips + std::vector> disk2SRs_; + + // DTC + + // total number of outer tracker DTCs + int numDTCs_; + // number of DTCs connected to one TFP (48) + int numDTCsPerTFP_; + // total number of max possible outer tracker modules (72 per DTC) + int numModules_; + // max number of moudles connected to a systiloic array in stub router firmware + int dtcNumModulesPerRoutingBlock_; + // number of merged rows for look up + int dtcNumMergedRows_; + // number of bits used for phi of row slope + int dtcWidthM_; + // internal stub q over pt precision in 1 /cm + double dtcBaseQoverPt_; + // phi of row slope precision in rad / pitch unit + double dtcBaseM_; + // number of bits for internal stub phi + int widthPhiDTC_; + // outer index = module window size, inner index = encoded bend, inner value = decoded bend, for ps modules + std::vector> encodingsBendPS_; + // outer index = module window size, inner index = encoded bend, inner value = decoded bend, for 2s modules + std::vector> encodingsBend2S_; + // outer index = dtc id in region, inner index = encoded layerId, inner value = decoded layerId + std::vector> encodingsLayerId_; + // collection of outer tracker sensor modules + std::vector sensorModules_; + // collection of outer tracker sensor modules organised in DTCS [0-215][0-71] + std::vector> dtcModules_; + // hepler to convert Stubs quickly + std::unordered_map detIdToSensorModule_; + + // GP + + // phi sector size in rad + double baseSector_; + // cut on zT + double maxZT_; + // cut on stub cot theta + double maxCot_; + // number of bits used for internal stub sector eta + int widthSectorEta_; + // number of bits to represent z residual w.r.t. sector center + int widthChiZ_; + + // HT + + // number of bits used for candidate q over pt + int htWidthQoverPt_; + // number of bits used for candidate phiT + int htWidthPhiT_; + // number of bits to represent phi residual w.r.t. ht candiate + int widthChiPhi_; + // q over pt bin width precision in 1 /cm + double htBaseQoverPt_; + // phiT bin width precision in rad + double htBasePhiT_; + + // MHT + + // number of mht cells + int mhtNumCells_; + // number of bits used for candidate q over pt + int mhtWidthQoverPt_; + // number of bits used for candidate phiT + int mhtWidthPhiT_; + // q over pt bin width precision in 1 /cm + double mhtBaseQoverPt_; + // phiT bin width in rad + double mhtBasePhiT_; + + // SF + + // cot(theta) precision + double sfBaseCot_; + // zT precision in cm + double sfBaseZT_; + + // KF + + double kfBasem0_; + double kfBasem1_; + double kfBasev0_; + double kfBasev1_; + double kfBasex0_; + double kfBasex1_; + double kfBasex2_; + double kfBasex3_; + double kfBasex4_; + double kfBaseH00_; + double kfBaseH04_; + double kfBaseH12_; + double kfBaser0_; + double kfBaser1_; + double kfBaser02_; + double kfBaser12_; + double kfBaseS00_; + double kfBaseS01_; + double kfBaseS04_; + double kfBaseS12_; + double kfBaseS13_; + double kfBaseR00_; + double kfBaseR11_; + double kfBaseInvR00_; + double kfBaseInvR11_; + double kfBaseK00_; + double kfBaseK10_; + double kfBaseK21_; + double kfBaseK31_; + double kfBaseK40_; + double kfBaseC00_; + double kfBaseC01_; + double kfBaseC04_; + double kfBaseC11_; + double kfBaseC14_; + double kfBaseC44_; + double kfBaseC22_; + double kfBaseC23_; + double kfBaseC33_; + double kfBaseChi20_; + double kfBaseChi21_; + double kfBaseChi2_; + + // DR + + double drBaseQoverPt_; + double drBasePhi0_; + double drBaseCot_; + double drBaseZ0_; + }; + +} // namespace trackerDTC + +EVENTSETUP_DATA_DEFAULT_RECORD(trackerDTC::Setup, trackerDTC::SetupRcd); + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/interface/SetupRcd.h b/L1Trigger/TrackerDTC/interface/SetupRcd.h new file mode 100644 index 0000000000000..4b8f622c6bfba --- /dev/null +++ b/L1Trigger/TrackerDTC/interface/SetupRcd.h @@ -0,0 +1,29 @@ +#ifndef L1Trigger_TrackerDTC_SetupRcd_h +#define L1Trigger_TrackerDTC_SetupRcd_h + +#include "FWCore/Framework/interface/DependentRecordImplementation.h" + +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "CondFormats/DataRecord/interface/TrackerDetToDTCELinkCablingMapRcd.h" +#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithmRecord.h" + +#include "boost/mpl/vector.hpp" + +namespace trackerDTC { + + typedef boost::mpl::vector + Rcds; + + class SetupRcd : public edm::eventsetup::DependentRecordImplementation {}; + +} // namespace trackerDTC + +#endif \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/interface/Stub.h b/L1Trigger/TrackerDTC/interface/Stub.h index 7fab1217a277d..ecbb9fc5184eb 100644 --- a/L1Trigger/TrackerDTC/interface/Stub.h +++ b/L1Trigger/TrackerDTC/interface/Stub.h @@ -1,21 +1,17 @@ #ifndef L1Trigger_TrackerDTC_Stub_h #define L1Trigger_TrackerDTC_Stub_h -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" #include #include namespace trackerDTC { - class Settings; - class Module; - // representation of a stub class Stub { public: - Stub(Settings* settings, Module* module, const TTStubRef& ttStubRef); + Stub(const edm::ParameterSet&, const Setup&, SensorModule*, const TTStubRef&); ~Stub() {} // underlying TTStubRef @@ -28,8 +24,6 @@ namespace trackerDTC { TTDTC::BV frame(int region) const; // checks stubs region assignment bool inRegion(int region) const; - double r() const { return r_; } - double phi() const { return phi_; } private: // truncates double precision to f/w integer equivalent @@ -40,11 +34,13 @@ namespace trackerDTC { TTDTC::BV formatTMTT(int region) const; // stores, calculates and provides run-time constants - Settings* settings_; + const Setup* setup_; + // representation of an outer tracker sensormodule + SensorModule* sm_; // underlying TTStubRef TTStubRef ttStubRef_; - // representation of an outer tracker sensormodule - Module* module_; + // chosen TT algorithm + bool hybrid_; // passes pt and eta cut bool valid_; // column number in pitch units diff --git a/L1Trigger/TrackerDTC/interface/TTDTCConverter.h b/L1Trigger/TrackerDTC/interface/TTDTCConverter.h deleted file mode 100644 index fb16f212eefb9..0000000000000 --- a/L1Trigger/TrackerDTC/interface/TTDTCConverter.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef L1Trigger_TrackerDTC_TTDTCConverter_h -#define L1Trigger_TrackerDTC_TTDTCConverter_h - -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" -#include "DataFormats/Math/interface/deltaPhi.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/GeometryVector/interface/GlobalPoint.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "DataFormats/DetId/interface/DetId.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" - -#include -#include - -// returns bit accurate position of a stub from a given processing region [0-8] (phi slice of outer tracker) -GlobalPoint TTDTCConverter(trackerDTC::Settings* settings, const TTDTC::Frame& frame, int region) { - GlobalPoint p; - if (frame.first.isNull()) - return p; - TTBV bv(frame.second); - - if (settings->dataFormat() == "Hybrid") { - const TrackerGeometry* trackerGeometry = settings->trackerGeometry(); - const TrackerTopology* trackerTopology = settings->trackerTopology(); - trackerDTC::SettingsHybrid* format = settings->hybrid(); - const std::vector& diskZs = format->diskZs(); - const std::vector& layerRs = format->layerRs(); - - const DetId detId(frame.first->getDetId() + settings->offsetDetIdDSV()); - const bool barrel = detId.subdetId() == StripSubdetector::TOB; - const bool psModule = trackerGeometry->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; - const int layerId = barrel ? trackerTopology->layer(detId) : trackerTopology->tidWheel(detId) + 10; - const GeomDetUnit* det = trackerGeometry->idToDetUnit(detId); - const bool side = det->position().z() >= 0.; - - trackerDTC::SettingsHybrid::SensorType type; - if (barrel && psModule) - type = trackerDTC::SettingsHybrid::barrelPS; - if (barrel && !psModule) - type = trackerDTC::SettingsHybrid::barrel2S; - if (!barrel && psModule) - type = trackerDTC::SettingsHybrid::diskPS; - if (!barrel && !psModule) - type = trackerDTC::SettingsHybrid::disk2S; - - bv >>= 1 + settings->widthLayer() + format->widthBend(type) + format->widthAlpha(type); - - double phi = (bv.val(format->widthPhi(type), 0, true) + .5) * format->basePhi(type); - bv >>= format->widthPhi(type); - double z = (bv.val(format->widthZ(type), 0, true) + .5) * format->baseZ(type); - bv >>= format->widthZ(type); - double r = (bv.val(format->widthR(type), 0, barrel) + .5) * format->baseR(type); - - if (barrel) { - r += layerRs.at(layerId - settings->offsetLayerId()); - } else { - z += diskZs.at(layerId - settings->offsetLayerId() - settings->offsetLayerDisks()) * (side ? 1. : -1.); - } - - phi = reco::deltaPhi(phi + region * settings->baseRegion(), 0.); - - if (type == trackerDTC::SettingsHybrid::disk2S) { - r = bv.val(format->widthR(type)); - r = format->disk2SR(layerId - settings->offsetLayerId() - settings->offsetLayerDisks(), (int)r); - } - - p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); - } else if (settings->dataFormat() == "TMTT") { - trackerDTC::SettingsTMTT* format_ = settings->tmtt(); - - bv >>= - 2 * format_->widthQoverPtBin() + 2 * settings->widthEta() + format_->numSectorsPhi() + settings->widthLayer(); - - double z = (bv.val(settings->widthZ(), 0, true) + .5) * settings->baseZ(); - bv >>= settings->widthZ(); - double phi = (bv.val(settings->widthPhi(), 0, true) + .5) * settings->basePhi(); - bv >>= settings->widthPhi(); - double r = (bv.val(settings->widthR(), 0, true) + .5) * settings->baseR(); - bv >>= settings->widthR(); - - r = r + settings->chosenRofPhi(); - phi = reco::deltaPhi(phi + region * settings->baseRegion(), 0.); - - p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); - } - - return p; -} - -#endif \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/plugins/Producer.cc b/L1Trigger/TrackerDTC/plugins/Producer.cc deleted file mode 100644 index 0322a181969c4..0000000000000 --- a/L1Trigger/TrackerDTC/plugins/Producer.cc +++ /dev/null @@ -1,149 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Run.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/GenericHandle.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "MagneticField/Engine/interface/MagneticField.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" -#include "CondFormats/SiPhase2TrackerObjects/interface/TrackerDetToDTCELinkCablingMap.h" -#include "CondFormats/DataRecord/interface/TrackerDetToDTCELinkCablingMapRcd.h" -#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" -#include "Geometry/Records/interface/IdealGeometryRecord.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "DataFormats/DetId/interface/DetId.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" -#include "DetectorDescription/Core/interface/DDCompactView.h" -#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithm_official.h" -#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithmRecord.h" - -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "L1Trigger/TrackerDTC/interface/Module.h" -#include "L1Trigger/TrackerDTC/interface/DTC.h" - -#include -#include -#include -#include - -using namespace std; -using namespace edm; - -namespace trackerDTC { - - /*! \class trackerDTC::Producer - * \brief Class to produce hardware like structured TTStub Collection used by Track Trigger emulators - * \author Thomas Schuh - * \date 2020, Jan - */ - class Producer : public stream::EDProducer<> { - public: - explicit Producer(const ParameterSet&); - ~Producer() override {} - - private: - void beginRun(const Run&, const EventSetup&) override; - void produce(Event&, const EventSetup&) override; - void endJob() {} - // helper class to store configurations - Settings settings_; - // ED in- and output tokens - EDGetTokenT getTokenTTStubDetSetVec_; - EDPutTokenT putTokenTTDTCAccepted_; - EDPutTokenT putTokenTTDTCLost_; - // ES tokens - ESGetToken, TTStubAlgorithmRecord> getTokenTTStubAlgorithm_; - ESGetToken getTokenMagneticField_; - ESGetToken getTokenTrackerGeometry_; - ESGetToken getTokenTrackerTopology_; - ESGetToken getTokenCablingMap_; - ESGetToken getTokenGeometryConfiguration_; - }; - - Producer::Producer(const ParameterSet& iConfig) : settings_(iConfig) { - // book in- and output ED products - getTokenTTStubDetSetVec_ = consumes(settings_.inputTagTTStubDetSetVec()); - putTokenTTDTCAccepted_ = produces(settings_.productBranchAccepted()); - putTokenTTDTCLost_ = produces(settings_.productBranchLost()); - // book ES products - getTokenTTStubAlgorithm_ = - esConsumes, TTStubAlgorithmRecord, Transition::BeginRun>( - settings_.inputTagTTStubAlgorithm()); - getTokenMagneticField_ = - esConsumes(settings_.inputTagMagneticField()); - getTokenTrackerGeometry_ = esConsumes( - settings_.inputTagTrackerGeometry()); - getTokenTrackerTopology_ = - esConsumes(settings_.inputTagTrackerTopology()); - getTokenCablingMap_ = - esConsumes( - settings_.inputTagCablingMap()); - getTokenGeometryConfiguration_ = - esConsumes(settings_.inputTagGeometryConfiguration()); - } - - void Producer::beginRun(const Run& iRun, const EventSetup& iSetup) { - // read in detector parameter - settings_.setTrackerGeometry(&iSetup.getData(getTokenTrackerGeometry_)); - settings_.setTrackerTopology(&iSetup.getData(getTokenTrackerTopology_)); - settings_.setMagneticField(&iSetup.getData(getTokenMagneticField_)); - settings_.setCablingMap(&iSetup.getData(getTokenCablingMap_)); - settings_.setTTStubAlgorithm(iSetup.getHandle(getTokenTTStubAlgorithm_)); - settings_.setGeometryConfiguration(iSetup.getHandle(getTokenGeometryConfiguration_)); - settings_.setProcessHistory(iRun.processHistory()); - // check coniguration - settings_.checkConfiguration(); - if (!settings_.configurationSupported()) - return; - // convert ES Products into handy objects - settings_.beginRun(); - } - - void Producer::produce(Event& iEvent, const EventSetup& iSetup) { - // empty DTC products - TTDTC productAccepted(settings_.numRegions(), settings_.numOverlappingRegions(), settings_.numDTCsPerRegion()); - TTDTC productLost(settings_.numRegions(), settings_.numOverlappingRegions(), settings_.numDTCsPerRegion()); - if (settings_.configurationSupported()) { - // read in stub collection - Handle handleTTStubDetSetVec; - iEvent.getByToken(getTokenTTStubDetSetVec_, handleTTStubDetSetVec); - // apply cabling map - vector>> ttDTCs(settings_.numDTCs(), - vector>(settings_.numModulesPerDTC())); - for (TTStubDetSetVec::const_iterator module = handleTTStubDetSetVec->begin(); - module != handleTTStubDetSetVec->end(); - module++) { - // DetSetVec->detId + 1 = tk layout det id - const DetId detId = module->detId() + settings_.offsetDetIdDSV(); - // outer tracker module id [0-15551] - int modId = settings_.modId(detId); - // outer tracker dtc id [0-215] - const int dtcId = modId / settings_.numModulesPerDTC(); - // outer tracker dtc channel id [0-71] - const int channelId = modId % settings_.numModulesPerDTC(); - vector& ttModule = ttDTCs[dtcId][channelId]; - ttModule.reserve(module->size()); - for (TTStubDetSet::const_iterator ttStub = module->begin(); ttStub != module->end(); ttStub++) - ttModule.emplace_back(makeRefTo(handleTTStubDetSetVec, ttStub)); - } - // board level processing - for (int dtcId = 0; dtcId < settings_.numDTCs(); dtcId++) { - // create single outer tracker DTC board - DTC dtc(&settings_, dtcId, ttDTCs[dtcId]); - // route stubs and fill products - dtc.produce(productAccepted, productLost); - } - } - // store ED products - iEvent.emplace(putTokenTTDTCAccepted_, move(productAccepted)); - iEvent.emplace(putTokenTTDTCLost_, move(productLost)); - } - -} // namespace trackerDTC - -DEFINE_FWK_MODULE(trackerDTC::Producer); \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/plugins/ProducerED.cc b/L1Trigger/TrackerDTC/plugins/ProducerED.cc new file mode 100644 index 0000000000000..17878a7ef7bb0 --- /dev/null +++ b/L1Trigger/TrackerDTC/plugins/ProducerED.cc @@ -0,0 +1,119 @@ +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/DetId/interface/DetId.h" + +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" +#include "L1Trigger/TrackerDTC/interface/SensorModule.h" +#include "L1Trigger/TrackerDTC/interface/DTC.h" + +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; + +namespace trackerDTC { + + /*! \class trackerDTC::ProducerED + * \brief Class to produce hardware like structured TTStub Collection used by Track Trigger emulators + * \author Thomas Schuh + * \date 2020, Jan + */ + class ProducerED : public stream::EDProducer<> { + public: + explicit ProducerED(const ParameterSet&); + ~ProducerED() override {} + + private: + void beginRun(const Run&, const EventSetup&) override; + void produce(Event&, const EventSetup&) override; + void endJob() {} + // helper class to store configurations + Setup setup_; + // ED input token of TTStubs + EDGetTokenT edGetToken_; + // ED output token for accepted stubs + EDPutTokenT edPutTokenAccepted_; + // ED output token for lost stubs + EDPutTokenT edPutTokenLost_; + // Setup token + ESGetToken esGetToken_; + // configuration + ParameterSet iConfig_; + // throws an exception if current configuration inconsitent with history + bool checkHistory_; + }; + + ProducerED::ProducerED(const ParameterSet& iConfig) + : iConfig_(iConfig), checkHistory_(iConfig.getParameter("CheckHistory")) { + // book in- and output ED products + const auto& inputTag = iConfig.getParameter("InputTag"); + const auto& branchAccepted = iConfig.getParameter("BranchAccepted"); + const auto& branchLost = iConfig.getParameter("BranchLost"); + edGetToken_ = consumes(inputTag); + edPutTokenAccepted_ = produces(branchAccepted); + edPutTokenLost_ = produces(branchLost); + // book ES product + esGetToken_ = esConsumes(); + } + + void ProducerED::beginRun(const Run& iRun, const EventSetup& iSetup) { + setup_ = iSetup.getData(esGetToken_); + if (!setup_.configurationSupported()) + return; + // check process history if desired + if (checkHistory_) + setup_.checkHistory(iRun.processHistory()); + } + + void ProducerED::produce(Event& iEvent, const EventSetup& iSetup) { + // empty DTC products + TTDTC productAccepted = setup_.ttDTC(); + TTDTC productLost = setup_.ttDTC(); + if (setup_.configurationSupported()) { + // read in stub collection + Handle handle; + iEvent.getByToken(edGetToken_, handle); + // apply cabling map, reorganise stub collections + vector>> stubsDTCs(setup_.numDTCs(), + vector>(setup_.numModulesPerDTC())); + for (auto module = handle->begin(); module != handle->end(); module++) { + // DetSetVec->detId + 1 = tk layout det id + const DetId detId = module->detId() + setup_.offsetDetIdDSV(); + // corresponding sensor module + SensorModule* sm = setup_.sensorModule(detId); + // empty stub collection + vector& stubsModule = stubsDTCs[sm->dtcId()][sm->modId()]; + stubsModule.reserve(module->size()); + for (TTStubDetSet::const_iterator ttStub = module->begin(); ttStub != module->end(); ttStub++) + stubsModule.emplace_back(makeRefTo(handle, ttStub)); + } + // board level processing + for (int dtcId = 0; dtcId < setup_.numDTCs(); dtcId++) { + // create single outer tracker DTC board + DTC dtc(iConfig_, setup_, dtcId, stubsDTCs.at(dtcId)); + // route stubs and fill products + dtc.produce(productAccepted, productLost); + } + } + // store ED products + iEvent.emplace(edPutTokenAccepted_, move(productAccepted)); + iEvent.emplace(edPutTokenLost_, move(productLost)); + } + +} // namespace trackerDTC + +DEFINE_FWK_MODULE(trackerDTC::ProducerED); \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/plugins/ProducerES.cc b/L1Trigger/TrackerDTC/plugins/ProducerES.cc new file mode 100644 index 0000000000000..80b19695e7d7e --- /dev/null +++ b/L1Trigger/TrackerDTC/plugins/ProducerES.cc @@ -0,0 +1,74 @@ +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "FWCore/Utilities/interface/ESInputTag.h" +#include "DataFormats/Provenance/interface/ParameterSetID.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" + +#include + +using namespace std; +using namespace edm; + +namespace trackerDTC { + + /*! \class trackerDTC::ProducerES + * \brief Class to produce setup of Track Trigger emulators + * \author Thomas Schuh + * \date 2020, Apr + */ + class ProducerES : public ESProducer { + public: + ProducerES(const ParameterSet& iConfig); + ~ProducerES() override {} + unique_ptr produce(const SetupRcd& setupRcd); + + private: + const ParameterSet iConfig_; + ESGetToken getTokenTTStubAlgorithm_; + ESGetToken getTokenMagneticField_; + ESGetToken getTokenTrackerGeometry_; + ESGetToken getTokenTrackerTopology_; + ESGetToken getTokenCablingMap_; + ESGetToken getTokenGeometryConfiguration_; + }; + + ProducerES::ProducerES(const ParameterSet& iConfig) : iConfig_(iConfig) { + setWhatProduced(this) + .setConsumes(getTokenTTStubAlgorithm_) + .setConsumes(getTokenMagneticField_) + .setConsumes(getTokenTrackerGeometry_) + .setConsumes(getTokenTrackerTopology_) + .setConsumes(getTokenCablingMap_) + .setConsumes(getTokenGeometryConfiguration_); + } + + unique_ptr ProducerES::produce(const SetupRcd& setupRcd) { + const MagneticField& magneticField = setupRcd.get(getTokenMagneticField_); + const TrackerGeometry& trackerGeometry = setupRcd.get(getTokenTrackerGeometry_); + const TrackerTopology& trackerTopology = setupRcd.get(getTokenTrackerTopology_); + const TrackerDetToDTCELinkCablingMap& cablingMap = setupRcd.get(getTokenCablingMap_); + const ESHandle handleStubAlgorithm = setupRcd.getHandle(getTokenTTStubAlgorithm_); + const ESHandle handleGeometryConfiguration = setupRcd.getHandle(getTokenGeometryConfiguration_); + const ParameterSetID& pSetIdTTStubAlgorithm = handleStubAlgorithm.description()->pid_; + const ParameterSetID& pSetIdGeometryConfiguration = handleGeometryConfiguration.description()->pid_; + const StubAlgorithmOfficial& stubAlgoritm = + *dynamic_cast(&setupRcd.get(getTokenTTStubAlgorithm_)); + const ParameterSet& pSetStubAlgorithm = getParameterSet(handleStubAlgorithm.description()->pid_); + const ParameterSet& pSetGeometryConfiguration = getParameterSet(handleGeometryConfiguration.description()->pid_); + return make_unique(iConfig_, + magneticField, + trackerGeometry, + trackerTopology, + cablingMap, + stubAlgoritm, + pSetStubAlgorithm, + pSetGeometryConfiguration, + pSetIdTTStubAlgorithm, + pSetIdGeometryConfiguration); + } + +} // namespace trackerDTC + +DEFINE_FWK_EVENTSETUP_MODULE(trackerDTC::ProducerES); \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Analyzer_Customize_cff.py b/L1Trigger/TrackerDTC/python/Analyzer_Customize_cff.py deleted file mode 100644 index e84740ff620df..0000000000000 --- a/L1Trigger/TrackerDTC/python/Analyzer_Customize_cff.py +++ /dev/null @@ -1,10 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -def useTMTT(process): - from L1Trigger.TrackerDTC.Producer_Defaults_cfi import TrackerDTCProducer_params - from L1Trigger.TrackerDTC.Format_TMTT_cfi import TrackerDTCFormat_params - from L1Trigger.TrackerDTC.Analyzer_Defaults_cfi import TrackerDTCAnalyzer_params - TrackerDTCProducer_params.ParamsED.DataFormat = "TMTT" - TrackerDTCAnalyzer_params.ParamsTP.MinPt = cms.double( 3. ) - process.TrackerDTCAnalyzer = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTCProducer_params, TrackerDTCFormat_params) - return process \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Analyzer_Defaults_cfi.py b/L1Trigger/TrackerDTC/python/Analyzer_Defaults_cfi.py deleted file mode 100644 index 4c31477c450b8..0000000000000 --- a/L1Trigger/TrackerDTC/python/Analyzer_Defaults_cfi.py +++ /dev/null @@ -1,29 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackerDTCAnalyzer_params = cms.PSet ( - - #=== ED parameter - - ParamsAnalyzer = cms.PSet ( - ProducerLabel = cms.string( "TrackerDTCProducer" ), # label of DTC producer - InputTagTTClusterAssMap = cms.InputTag( "TTClusterAssociatorFromPixelDigis", "ClusterAccepted" ), # tag of AssociationMap between TTCluster and TrackingParticles - UseMCTruth = cms.bool ( True ) # open and analyze TrackingParticles, original TTStubs and Association between them - ), - - #=== Cuts on MC truth particles (i.e., tracking particles) used for tracking efficiency measurements. And Rules for deciding when a reconstructed L1 track matches a MC truth particle (i.e. tracking particle) - - ParamsTP = cms.PSet ( - MinPt = cms.double( 2. ), # pt cut in GeV - MaxEta = cms.double( 2.4 ), # eta cut - MaxVertR = cms.double( 1. ), # cut on vertex pos r in cm - MaxVertZ = cms.double( 30. ), # cut on vertex pos z in cm - MaxD0 = cms.double( 5. ), # cut on impact parameter in cm - MinLayers = cms.int32 ( 4 ), # required number of associated layers to a TP to consider it reconstruct-able - MinLayersPS = cms.int32 ( 0 ), # required number of associated ps layers to a TP to consider it reconstruct-able - MatchedLayers = cms.int32 ( 4 ), # required number of layers a found track has to have in common with a TP to consider it matched to it - MatchedLayersPS = cms.int32 ( 0 ), # required number of ps layers a found track has to have in common with a TP to consider it matched to it - UnMatchedStubs = cms.int32 ( 1 ), # allowed number of stubs a found track may have not in common with its matched TP - UnMatchedStubsPS = cms.int32 ( 0 ) # allowed number of PS stubs a found track may have not in common with its matched TP - ) - -) diff --git a/L1Trigger/TrackerDTC/python/Analyzer_cff.py b/L1Trigger/TrackerDTC/python/Analyzer_cff.py index 544e43c52da41..c56e8928b13fb 100644 --- a/L1Trigger/TrackerDTC/python/Analyzer_cff.py +++ b/L1Trigger/TrackerDTC/python/Analyzer_cff.py @@ -1,7 +1,6 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.TrackerDTC.Analyzer_Defaults_cfi import TrackerDTCAnalyzer_params -from L1Trigger.TrackerDTC.Producer_Defaults_cfi import TrackerDTCProducer_params -from L1Trigger.TrackerDTC.Format_Hybrid_cfi import TrackerDTCFormat_params +from L1Trigger.TrackerDTC.Analyzer_cfi import TrackerDTCAnalyzer_params +from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params -TrackerDTCAnalyzer = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTCProducer_params, TrackerDTCFormat_params) \ No newline at end of file +TrackerDTCAnalyzer = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTCProducer_params) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Analyzer_cfi.py b/L1Trigger/TrackerDTC/python/Analyzer_cfi.py new file mode 100644 index 0000000000000..d365c85d60e8e --- /dev/null +++ b/L1Trigger/TrackerDTC/python/Analyzer_cfi.py @@ -0,0 +1,11 @@ +import FWCore.ParameterSet.Config as cms + +TrackerDTCAnalyzer_params = cms.PSet ( + + InputTagAccepted = cms.InputTag( "TrackerDTCProducer", "StubAccepted" ), # dtc passed stubs selection + InputTagLost = cms.InputTag( "TrackerDTCProducer", "StubLost" ), # dtc lost stubs selection + InputTagTTStubDetSetVec = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # original TTStub selection + InputTagTTClusterAssMap = cms.InputTag( "TTClusterAssociatorFromPixelDigis", "ClusterAccepted" ), # tag of AssociationMap between TTCluster and TrackingParticles + UseMCTruth = cms.bool( True ) # eneables analyze of TPs + +) diff --git a/L1Trigger/TrackerDTC/python/Customize_cff.py b/L1Trigger/TrackerDTC/python/Customize_cff.py new file mode 100644 index 0000000000000..f9f6145857a6c --- /dev/null +++ b/L1Trigger/TrackerDTC/python/Customize_cff.py @@ -0,0 +1,14 @@ +import FWCore.ParameterSet.Config as cms + +def producerUseTMTT(process): + from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params + TrackerDTCProducer_params.UseHybrid = cms.bool( False ) + process.TrackerDTCProducer = cms.EDProducer('trackerDTC::ProducerED', TrackerDTCProducer_params) + return process + +def analyzerUseTMTT(process): + from L1Trigger.TrackerDTC.Analyzer_cfi import TrackerDTCAnalyzer_params + from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params + TrackerDTCProducer_params.UseHybrid = cms.bool( False ) + process.TrackerDTCAnalyzer = cms.EDAnalyzer('trackerDTC::Analyzer', TrackerDTCAnalyzer_params, TrackerDTCProducer_params) + return process \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Format_Hybrid_cfi.py b/L1Trigger/TrackerDTC/python/Format_Hybrid_cfi.py deleted file mode 100644 index f3d8a53c9c138..0000000000000 --- a/L1Trigger/TrackerDTC/python/Format_Hybrid_cfi.py +++ /dev/null @@ -1,47 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackerDTCFormat_params = cms.PSet ( - - #=== specific format parameter - - ParamsTTStubAlgo = cms.PSet ( - - CheckHistory = cms.bool ( False ), # check consitency between configured TTStub algo and the one used during input sample production - Label = cms.string( "TTStubAlgorithm_official_Phase2TrackerDigi_" ), # producer name used during input sample production - Process = cms.string( "HLT" ), # process name used during input sample production - BaseWindowSize = cms.double( .5 ) # precision of window sizes in pitch units - - ), - - #=== specific format parameter - - ParamsFormat = cms.PSet ( - - MaxEta = cms.double( 2.5 ), # cut on stub eta - MinPt = cms.double( 2. ), # cut on stub pt, also defines region overlap shape in GeV - ChosenRofPhi = cms.double( 55. ), # critical radius defining region overlap shape in cm - NumLayers = cms.int32 ( 4 ), # max number of detector layer connected to one DTC - NumRingsPS = cms.vint32( 11, 11, 8, 8, 8 ), # number of outer PS rings for disk 1, 2, 3, 4, 5 - - WidthsR = cms.vint32 ( 7, 7, 12, 7 ), # number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsZ = cms.vint32 ( 12, 8, 7, 7 ), # number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsPhi = cms.vint32 ( 14, 17, 14, 14 ), # number of bits used for stub phi w.r.t. region centre for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsAlpha = cms.vint32 ( 0, 0, 0, 4 ), # number of bits used for stub row number for module types (barrelPS, barrel2S, diskPS, disk2S) - WidthsBend = cms.vint32 ( 3, 4, 3, 4 ), # number of bits used for stub bend number for module types (barrelPS, barrel2S, diskPS, disk2S) - RangesR = cms.vdouble( 7.5, 7.5, 120. , 0. ), # range in stub r which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - RangesZ = cms.vdouble( 240., 240., 7.5, 7.5 ), # range in stub z which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - RangesAlpha = cms.vdouble( 0., 0., 0., 1024. ), # range in stub row which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) - - LayerRs = cms.vdouble( 24.9316, 37.1777, 52.2656, 68.7598, 86.0156, 108.3105 ), # mean radius of outer tracker barrel layer - DiskZs = cms.vdouble( 131.1914, 154.9805, 185.3320, 221.6016, 265.0195 ), # mean z of outer tracker endcap disks - Disk2SRsSet = cms.VPSet( # center radius of outer tracker endcap 2S diks strips - cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 1 - cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 2 - cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 3 - cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 4 - cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ) # disk 5 - ) - - ) - -) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Format_TMTT_cfi.py b/L1Trigger/TrackerDTC/python/Format_TMTT_cfi.py deleted file mode 100644 index f88d01176f7c4..0000000000000 --- a/L1Trigger/TrackerDTC/python/Format_TMTT_cfi.py +++ /dev/null @@ -1,28 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackerDTCFormat_params = cms.PSet ( - - #=== specific format parameter - - ParamsFormat = cms.PSet ( - - MaxEta = cms.double( 2.4 ), # cut on stub eta - MinPt = cms.double( 3. ), # cut on stub pt, also defines region overlap shape in GeV - ChosenRofPhi = cms.double( 67.24 ), # critical radius defining region overlap shape in cm - - WidthR = cms.int32 ( 12 ), # number of bits used for stub r - ChosenRofPhi - WidthPhi = cms.int32 ( 15 ), # number of bits used for stub phi w.r.t. region centre - WidthZ = cms.int32 ( 14 ), # number of bits used for stub z - NumLayers = cms.int32 ( 7 ), # number of detector layers a reconstructbale particle may cross - NumSectorsPhi = cms.int32 ( 2 ), # number of phi sectors used in hough transform - NumBinsQoverPt = cms.int32 ( 16 ), # number of qOverPt bins used in hough transform - NumBinsPhiT = cms.int32 ( 32 ), # number of phiT bins used in hough transform - - ChosenRofZ = cms.double( 50. ), # critical radius defining r-z sector shape in cm - BeamWindowZ = cms.double( 15. ), # half lumi region size in cm - HalfLength = cms.double( 270. ), # has to be >= max stub z / 2 in cm - BoundariesEta = cms.vdouble( -2.40, -2.08, -1.68, -1.26, -0.90, -0.62, -0.41, -0.20, 0.0, 0.20, 0.41, 0.62, 0.90, 1.26, 1.68, 2.08, 2.40 ) # defining r-z sector shape - - ) - -) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/ProducerED_cff.py b/L1Trigger/TrackerDTC/python/ProducerED_cff.py new file mode 100644 index 0000000000000..766c8430534f5 --- /dev/null +++ b/L1Trigger/TrackerDTC/python/ProducerED_cff.py @@ -0,0 +1,12 @@ +import FWCore.ParameterSet.Config as cms + +#--------------------------------------------------------------------------------------------------------- +# This describes the DTC Stub processing +#--------------------------------------------------------------------------------------------------------- + +#=== Import default values for all parameters & define EDProducer. + +from L1Trigger.TrackerDTC.ProducerED_cfi import TrackerDTCProducer_params +from L1Trigger.TrackerDTC.ProducerES_cff import TrackTriggerSetup + +TrackerDTCProducer = cms.EDProducer('trackerDTC::ProducerED', TrackerDTCProducer_params) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/ProducerED_cfi.py b/L1Trigger/TrackerDTC/python/ProducerED_cfi.py new file mode 100644 index 0000000000000..b7f5d04bfac1b --- /dev/null +++ b/L1Trigger/TrackerDTC/python/ProducerED_cfi.py @@ -0,0 +1,12 @@ +import FWCore.ParameterSet.Config as cms + +TrackerDTCProducer_params = cms.PSet ( + + InputTag = cms.InputTag( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # original TTStub selection + BranchAccepted = cms.string ( "StubAccepted" ), # label for prodcut with passed stubs + BranchLost = cms.string ( "StubLost" ), # label for prodcut with lost stubs + CheckHistory = cms.bool ( False ), # checks if input sample production is configured as current process + UseHybrid = cms.bool ( True ), # use Hybrid or TMTT as TT algorithm + EnableTruncation = cms.bool ( True ) # enable emulation of truncation, lost stubs are filled in BranchLost + +) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/ProducerES_cff.py b/L1Trigger/TrackerDTC/python/ProducerES_cff.py new file mode 100644 index 0000000000000..227b78564e62e --- /dev/null +++ b/L1Trigger/TrackerDTC/python/ProducerES_cff.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.TrackerDTC.ProducerES_cfi import TrackTrigger_params + +TrackTriggerSetup = cms.ESProducer("trackerDTC::ProducerES", TrackTrigger_params) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/ProducerES_cfi.py b/L1Trigger/TrackerDTC/python/ProducerES_cfi.py new file mode 100644 index 0000000000000..0b0988ee82e60 --- /dev/null +++ b/L1Trigger/TrackerDTC/python/ProducerES_cfi.py @@ -0,0 +1,199 @@ +import FWCore.ParameterSet.Config as cms + +TrackTrigger_params = cms.PSet ( + + # Parameter to check if configured Tracker Geometry is supported + SupportedGeometry = cms.PSet ( + XMLLabel = cms.string ("geomXMLFiles" ), # label of ESProducer/ESSource + XMLPath = cms.string ("Geometry/TrackerCommonData/data/PhaseII/" ), # compared path + XMLFile = cms.string ("tracker.xml" ), # compared filen ame + XMLVersions = cms.vstring("TiltedTracker613", "TiltedTracker613_MB_2019_04" ) # list of supported versions + ), + + # Parameter to check if Process History is consistent with process configuration + ProcessHistory = cms.PSet ( + GeometryConfiguration = cms.string( "XMLIdealGeometryESSource@" ), # label of compared GeometryConfiguration + TTStubAlgorithm = cms.string( "TTStubAlgorithm_official_Phase2TrackerDigi_@" ) # label of compared TTStubAlgorithm + ), + + # Common track finding parameter + TrackFinding = cms.PSet ( + BeamWindowZ = cms.double( 15. ), # half lumi region size in cm + MatchedLayers = cms.int32 ( 4 ), # required number of layers a found track has to have in common with a TP to consider it matched to it + MatchedLayersPS = cms.int32 ( 0 ), # required number of ps layers a found track has to have in common with a TP to consider it matched to it + UnMatchedStubs = cms.int32 ( 1 ), # allowed number of stubs a found track may have not in common with its matched TP + UnMatchedStubsPS = cms.int32 ( 0 ) # allowed number of PS stubs a found track may have not in common with its matched TP + ), + + # TMTT specific parameter + TMTT = cms.PSet ( + MinPt = cms.double( 3. ), # cut on stub and TP pt, also defines region overlap shape in GeV + MaxEta = cms.double( 2.4 ), # cut on stub eta + ChosenRofPhi = cms.double( 67.24 ), # critical radius defining region overlap shape in cm + NumLayers = cms.int32 ( 7 ), # number of detector layers a reconstructbale particle may cross + WidthR = cms.int32 ( 12 ), # number of bits used for stub r - ChosenRofPhi + WidthPhi = cms.int32 ( 14 ), # number of bits used for stub phi w.r.t. phi sector centre + WidthZ = cms.int32 ( 14 ) # number of bits used for stub z + ), + + # Hybrid specific parameter + Hybrid = cms.PSet ( + MinPt = cms.double( 2. ), # cut on stub and TP pt, also defines region overlap shape in GeV + MaxEta = cms.double( 2.5 ), # cut on stub eta + ChosenRofPhi = cms.double( 55. ), # critical radius defining region overlap shape in cm + NumLayers = cms.int32 ( 4 ), # max number of detector layer connected to one DTC + NumRingsPS = cms.vint32 ( 11, 11, 8, 8, 8 ), # number of outer PS rings for disk 1, 2, 3, 4, 5 + WidthsR = cms.vint32 ( 7, 7, 12, 7 ), # number of bits used for stub r w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsZ = cms.vint32 ( 12, 8, 7, 7 ), # number of bits used for stub z w.r.t layer/disk centre for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsPhi = cms.vint32 ( 14, 17, 14, 14 ), # number of bits used for stub phi w.r.t. region centre for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsAlpha = cms.vint32 ( 0, 0, 0, 4 ), # number of bits used for stub row number for module types (barrelPS, barrel2S, diskPS, disk2S) + WidthsBend = cms.vint32 ( 3, 4, 3, 4 ), # number of bits used for stub bend number for module types (barrelPS, barrel2S, diskPS, disk2S) + RangesR = cms.vdouble( 7.5, 7.5, 120. , 0. ), # range in stub r which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + RangesZ = cms.vdouble( 240., 240., 7.5, 7.5 ), # range in stub z which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + RangesAlpha = cms.vdouble( 0., 0., 0., 1024. ), # range in stub row which needs to be covered for module types (barrelPS, barrel2S, diskPS, disk2S) + LayerRs = cms.vdouble( 24.9316, 37.1777, 52.2656, 68.7598, 86.0156, 108.3105 ), # mean radius of outer tracker barrel layer + DiskZs = cms.vdouble( 131.1914, 154.9805, 185.3320, 221.6016, 265.0195 ), # mean z of outer tracker endcap disks + Disk2SRsSet = cms.VPSet( # center radius of outer tracker endcap 2S diks strips + cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 1 + cms.PSet( Disk2SRs = cms.vdouble( 66.4391, 71.4391, 76.2750, 81.2750, 82.9550, 87.9550, 93.8150, 98.8150, 99.8160, 104.8160 ) ), # disk 2 + cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 3 + cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ), # disk 4 + cms.PSet( Disk2SRs = cms.vdouble( 63.9903, 68.9903, 74.2750, 79.2750, 81.9562, 86.9562, 92.4920, 97.4920, 99.8160, 104.8160 ) ) # disk 5 + ) + ), + + # Parameter specifying TrackingParticle used for Efficiency measurements + TrackingParticle = cms.PSet ( + MaxEta = cms.double( 2.4 ), # eta cut + MaxVertR = cms.double( 1. ), # cut on vertex pos r in cm + MaxVertZ = cms.double( 30. ), # cut on vertex pos z in cm + MaxD0 = cms.double( 5. ), # cut on impact parameter in cm + MinLayers = cms.int32 ( 4 ), # required number of associated layers to a TP to consider it reconstruct-able + MinLayersPS = cms.int32 ( 0 ) # required number of associated ps layers to a TP to consider it reconstruct-able + ), + + # Fimrware specific Parameter + Firmware = cms.PSet ( + NumFramesInfra = cms.int32 ( 6 ), # needed gap between events of emp-infrastructure firmware + FreqLHC = cms.double( 40. ), # LHC bunch crossing rate in MHz + FreqBE = cms.double( 360. ), # processing Frequency of DTC & TFP in MHz, has to be integer multiple of FreqLHC + TMP_FE = cms.int32 ( 8 ), # number of events collected in front-end + TMP_TFP = cms.int32 ( 18 ), # time multiplexed period of track finding processor + SpeedOfLight = cms.double( 2.99792458 ), # in e8 m/s + BField = cms.double( 3.81120228767395 ), # in T + BFieldError = cms.double( 1.e-6 ), # accepted difference to EventSetup in T + OuterRadius = cms.double( 112.7 ), # outer radius of outer tracker in cm + InnerRadius = cms.double( 21.8 ), # inner radius of outer tracker in cm + HalfLength = cms.double( 270. ), # half length of outer tracker in cm + MaxPitch = cms.double( .01 ) # max strip/pixel pitch of outer tracker sensors in cm + ), + + # Parmeter specifying front-end + FrontEnd = cms.PSet ( + WidthBend = cms.int32 ( 6 ), # number of bits used for internal stub bend + WidthCol = cms.int32 ( 5 ), # number of bits used for internal stub column + WidthRow = cms.int32 ( 11 ), # number of bits used for internal stub row + BaseBend = cms.double( .25 ), # precision of internal stub bend in pitch units + BaseCol = cms.double( 1. ), # precision of internal stub column in pitch units + BaseRow = cms.double( .5 ), # precision of internal stub row in pitch units + BaseWindowSize = cms.double( .5 ), # precision of window sizes in pitch units + BendCut = cms.double( 1.3125 ) # used stub bend uncertainty in pitch units + ), + + # Parmeter specifying DTC + DTC = cms.PSet ( + NumRegions = cms.int32 ( 9 ), # number of phi slices the outer tracker readout is organized in + NumOverlappingRegions = cms.int32 ( 2 ), # number of regions a reconstructable particles may cross + NumATCASlots = cms.int32 ( 12 ), # number of Slots in used ATCA crates + NumDTCsPerRegion = cms.int32 ( 24 ), # number of DTC boards used to readout a detector region, likely constructed to be an integerer multiple of NumSlots_ + NumModulesPerDTC = cms.int32 ( 72 ), # max number of sensor modules connected to one DTC board + NumRoutingBlocks = cms.int32 ( 2 ), # number of systiloic arrays in stub router firmware + DepthMemory = cms.int32 ( 64 ), # fifo depth in stub router firmware + WidthRowLUT = cms.int32 ( 4 ), # number of row bits used in look up table + WidthQoverPt = cms.int32 ( 9 ), # number of bits used for stub qOverPt. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 + OffsetDetIdDSV = cms.int32 ( 1 ), # tk layout det id minus DetSetVec->detId + OffsetDetIdTP = cms.int32 ( -1 ), # tk layout det id minus TrackerTopology lower det id + OffsetLayerDisks = cms.int32 ( 10 ), # offset in layer ids between barrel layer and endcap disks + OffsetLayerId = cms.int32 ( 1 ) # offset between 0 and smallest layer id (barrel layer 1) + ), + + # Parmeter specifying GeometricProcessor + GeometricProcessor = cms.PSet ( + NumSectorsPhi = cms.int32 ( 2 ), # number of phi sectors used in hough transform + ChosenRofZ = cms.double( 50. ), # critical radius defining r-z sector shape in cm + RangeChiZ = cms.double( 90. ), # range of stub z residual w.r.t. sector center which needs to be covered + DepthMemory = cms.int32 ( 64 ), # fifo depth in stub router firmware + BoundariesEta = cms.vdouble( -2.40, -2.08, -1.68, -1.26, -0.90, -0.62, -0.41, -0.20, 0.0, 0.20, 0.41, 0.62, 0.90, 1.26, 1.68, 2.08, 2.40 ) # defining r-z sector shape + ), + + # Parmeter specifying HoughTransform + HoughTransform = cms.PSet ( + NumBinsQoverPt = cms.int32( 16 ), # number of used qOverPt bins + NumBinsPhiT = cms.int32( 32 ), # number of used phiT bins + MinLayers = cms.int32( 5 ), # required number of stub layers to form a candidate + DepthMemory = cms.int32( 32 ) # internal fifo depth + ), + + # Parmeter specifying MiniHoughTransform + MiniHoughTransform = cms.PSet ( + NumBinsQoverPt = cms.int32( 2 ), # number of finer qOverPt bins inside HT bin + NumBinsPhiT = cms.int32( 2 ), # number of finer phiT bins inside HT bin + NumDLB = cms.int32( 2 ), # number of dynamic load balancing steps + MinLayers = cms.int32( 5 ) # required number of stub layers to form a candidate + ), + + # Parmeter specifying SeedFilter + SeedFilter = cms.PSet ( + PowerBaseCot = cms.int32( -6 ), # used cot(Theta) bin width = 2 ** this + BaseDiffZ = cms.int32( 4 ), # used zT bin width = baseZ * 2 ** this + MinLayers = cms.int32( 4 ) # required number of stub layers to form a candidate + ), + + # Parmeter specifying KalmanFilter + KalmanFilter = cms.PSet ( + WidthLutInvPhi = cms.int32( 10 ), # number of bits for internal reciprocal look up + WidthLutInvZ = cms.int32( 10 ), # number of bits for internal reciprocal look up + NumTracks = cms.int32( 16 ), # cut on number of input candidates + MinLayers = cms.int32( 4 ), # required number of stub layers to form a track + MaxLayers = cms.int32( 4 ), # maximum number of layers added to a track + MaxStubsPerLayer = cms.int32( 4 ), # cut on number of stub per layer for input candidates + MaxSkippedLayers = cms.int32( 2 ), # maximum allowed skipped layers from inside to outside to form a track + BaseShiftr0 = cms.int32( -3 ), + BaseShiftr02 = cms.int32( -5 ), + BaseShiftv0 = cms.int32( -2 ), + BaseShiftS00 = cms.int32( -1 ), + BaseShiftS01 = cms.int32( -7 ), + BaseShiftK00 = cms.int32( -9 ), + BaseShiftK10 = cms.int32( -15 ), + BaseShiftR00 = cms.int32( -2 ), + BaseShiftInvR00 = cms.int32( -19 ), + BaseShiftChi20 = cms.int32( -5 ), + BaseShiftC00 = cms.int32( 5 ), + BaseShiftC01 = cms.int32( -3 ), + BaseShiftC11 = cms.int32( -7 ), + BaseShiftr1 = cms.int32( 2 ), + BaseShiftr12 = cms.int32( 5 ), + BaseShiftv1 = cms.int32( 3 ), + BaseShiftS12 = cms.int32( -3 ), + BaseShiftS13 = cms.int32( -3 ), + BaseShiftK21 = cms.int32( -13 ), + BaseShiftK31 = cms.int32( -14 ), + BaseShiftR11 = cms.int32( 3 ), + BaseShiftInvR11 = cms.int32( -21 ), + BaseShiftChi21 = cms.int32( -5 ), + BaseShiftC22 = cms.int32( -3 ), + BaseShiftC23 = cms.int32( -5 ), + BaseShiftC33 = cms.int32( -3 ), + BaseShiftChi2 = cms.int32( -5 ) + ), + + # Parmeter specifying DuplicateRemoval + DuplicateRemoval = cms.PSet ( + DepthMemory = cms.int32( 16 ), # internal memory depth + WidthPhi0 = cms.int32( 12 ), # number of bist used for phi0 + WidthQoverPt = cms.int32( 15 ), # number of bist used for qOverPt + WidthCot = cms.int32( 16 ), # number of bist used for cot(theta) + WidthZ0 = cms.int32( 12 ) # number of bist used for z0 + ) + +) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Producer_Customize_cff.py b/L1Trigger/TrackerDTC/python/Producer_Customize_cff.py deleted file mode 100644 index b2a8db0c6453d..0000000000000 --- a/L1Trigger/TrackerDTC/python/Producer_Customize_cff.py +++ /dev/null @@ -1,10 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -def useTMTT(process): - from L1Trigger.TrackerDTC.Producer_Defaults_cfi import TrackerDTCProducer_params - from L1Trigger.TrackerDTC.Format_TMTT_cfi import TrackerDTCFormat_params - from L1Trigger.TrackerDTC.Analyzer_Defaults_cfi import TrackerDTCAnalyzer_params - TrackerDTCProducer_params.ParamsED.DataFormat = "TMTT" - TrackerDTCAnalyzer_params.ParamsTP.MinPt = cms.double( 3. ) - process.TrackerDTCProducer = cms.EDProducer('trackerDTC::Producer', TrackerDTCProducer_params, TrackerDTCFormat_params, TrackerDTCAnalyzer_params) - return process \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Producer_Defaults_cfi.py b/L1Trigger/TrackerDTC/python/Producer_Defaults_cfi.py deleted file mode 100644 index ea923c56c06fd..0000000000000 --- a/L1Trigger/TrackerDTC/python/Producer_Defaults_cfi.py +++ /dev/null @@ -1,78 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -TrackerDTCProducer_params = cms.PSet ( - - #=== ED parameter - - ParamsED = cms.PSet ( - InputTagTTStubDetSetVec = cms.InputTag ( "TTStubsFromPhase2TrackerDigis", "StubAccepted" ), # - ProductBranchAccepted = cms.string ( "StubAccepted" ), # - ProductBranchLost = cms.string ( "StubLost" ), # - InputTagMagneticField = cms.ESInputTag( "VolumeBasedMagneticFieldESProducer", "" ), # - InputTagTrackerGeometry = cms.ESInputTag( "trackerGeometry", "" ), # - InputTagTrackerTopology = cms.ESInputTag( "trackerTopology", "" ), # - InputTagCablingMap = cms.ESInputTag( "GlobalTag", "" ), # - InputTagTTStubAlgorithm = cms.ESInputTag( "TTStubAlgorithm_official_Phase2TrackerDigi_", ""), # - InputTagGeometryConfiguration = cms.ESInputTag( "XMLIdealGeometryESSource", ""), # - SupportedTrackerXMLPSet = cms.string ( "geomXMLFiles"), # - SupportedTrackerXMLPath = cms.string ( "Geometry/TrackerCommonData/data/PhaseII/"), # - SupportedTrackerXMLFile = cms.string ( "tracker.xml"), # - SupportedTrackerXMLVersions = cms.vstring ( "TiltedTracker613", "TiltedTracker613_MB_2019_04", "OuterTracker616_2020_04" ), # - DataFormat = cms.string ( "Hybrid" ), # hybrid and tmtt format supported - OffsetDetIdDSV = cms.int32 ( 1 ), # tk layout det id minus DetSetVec->detId - OffsetDetIdTP = cms.int32 ( -1 ), # tk layout det id minus TrackerTopology lower det id - OffsetLayerDisks = cms.int32 ( 10 ), # offset in layer ids between barrel layer and endcap disks - OffsetLayerId = cms.int32 ( 1 ), # offset between 0 and smallest layer id (barrel layer 1) - CheckHistory = cms.bool ( False ), # - ProcessName = cms.string ( "HLT" ), # - ProductLabel = cms.string ( "XMLIdealGeometryESSource" ) # - ), - - #=== router parameter - - ParamsRouter = cms.PSet ( - EnableTruncation = cms.bool ( True ), # enables emulation of truncation - FreqDTC = cms.double( 360. ), # Frequency in MHz, has to be integer multiple of FreqLHC - TMP_TFP = cms.int32 ( 18 ), # time multiplexed period of track finding processor - NumFramesInfra = cms.int32 ( 6 ), # needed gap between events of emp-infrastructure firmware - NumRoutingBlocks = cms.int32 ( 2 ), # number of systiloic arrays in stub router firmware - SizeStack = cms.int32 ( 64 ) # fifo depth in stub router firmware - ), - - #=== converter parameter - - ParamsConverter = cms.PSet ( - WidthRowLUT = cms.int32 ( 4 ), # number of row bits used in look up table - WidthQoverPt = cms.int32 ( 9 ) # number of bits used for stub qOverPt. lut addr is col + bend = 11 => 1 BRAM -> 18 bits for min and max val -> 9 - ), - - #=== Tracker parameter - - ParamsTracker = cms.PSet ( - NumRegions = cms.int32 ( 9 ), # number of phi slices the outer tracker readout is organized in - NumOverlappingRegions = cms.int32 ( 2 ), # number of regions a reconstructable particles may cross - NumDTCsPerRegion = cms.int32 ( 24 ), # number of DTC boards used to readout a detector region - NumModulesPerDTC = cms.int32 ( 72 ), # max number of sensor modules connected to one DTC board - TMP_FE = cms.int32 ( 8 ), # number of events collected in front-end - WidthBend = cms.int32 ( 6 ), # number of bits used for internal stub bend - WidthCol = cms.int32 ( 5 ), # number of bits used for internal stub column - WidthRow = cms.int32 ( 11 ), # number of bits used for internal stub row - BaseBend = cms.double( .25 ), # precision of internal stub bend in pitch units - BaseCol = cms.double( 1. ), # precision of internal stub column in pitch units - BaseRow = cms.double( .5 ), # precision of internal stub row in pitch units - BendCut = cms.double( 1.3125 ), # used stub bend uncertainty in pitch units - FreqLHC = cms.double( 40. ) # LHC bunch crossing rate in MHz - ), - - #=== f/w constants - - ParamsFW = cms.PSet ( - SpeedOfLight = cms.double( 2.99792458 ), # in e8 m/s - BField = cms.double( 3.81120228767395 ), # in T - BFieldError = cms.double( 1.e-6 ), # accepted difference to EventSetup in T - OuterRadius = cms.double( 112.7 ), # outer radius of outer tracker in cm - InnerRadius = cms.double( 21.8 ), # inner radius of outer tracker in cm - MaxPitch = cms.double( .01 ) # max strip/pixel pitch of outer tracker sensors in cm - ) - -) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/python/Producer_cff.py b/L1Trigger/TrackerDTC/python/Producer_cff.py deleted file mode 100644 index a5404d898b809..0000000000000 --- a/L1Trigger/TrackerDTC/python/Producer_cff.py +++ /dev/null @@ -1,13 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -#--------------------------------------------------------------------------------------------------------- -# This describes the DTC Stub processing -#--------------------------------------------------------------------------------------------------------- - -#=== Import default values for all parameters & define EDProducer. - -from L1Trigger.TrackerDTC.Producer_Defaults_cfi import TrackerDTCProducer_params -from L1Trigger.TrackerDTC.Format_Hybrid_cfi import TrackerDTCFormat_params -from L1Trigger.TrackerDTC.Analyzer_Defaults_cfi import TrackerDTCAnalyzer_params - -TrackerDTCProducer = cms.EDProducer('trackerDTC::Producer', TrackerDTCProducer_params, TrackerDTCFormat_params, TrackerDTCAnalyzer_params) \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/DTC.cc b/L1Trigger/TrackerDTC/src/DTC.cc index ef8907d784fa0..dbd4138046706 100644 --- a/L1Trigger/TrackerDTC/src/DTC.cc +++ b/L1Trigger/TrackerDTC/src/DTC.cc @@ -1,12 +1,8 @@ #include "L1Trigger/TrackerDTC/interface/DTC.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "L1Trigger/TrackerDTC/interface/Module.h" #include -#include #include #include -#include #include using namespace std; @@ -14,32 +10,36 @@ using namespace edm; namespace trackerDTC { - DTC::DTC(Settings* settings, int dtcId, const std::vector>& modules) - : settings_(settings), - region_(dtcId / settings_->numDTCsPerRegion()), - board_(dtcId % settings_->numDTCsPerRegion()), - modules_(settings_->modules(dtcId)), - input_(settings_->numRoutingBlocks(), Stubss(settings_->numModulesPerRoutingBlock())), - lost_(settings_->numOverlappingRegions()) { + DTC::DTC(const ParameterSet& iConfig, + const Setup& setup, + int dtcId, + const std::vector>& stubsDTC) + : setup_(&setup), + enableTruncation_(iConfig.getParameter("EnableTruncation")), + region_(dtcId / setup.numDTCsPerRegion()), + board_(dtcId % setup.numDTCsPerRegion()), + modules_(setup.dtcModules(dtcId)), + input_(setup.dtcNumRoutingBlocks(), Stubss(setup.dtcNumModulesPerRoutingBlock())), + lost_(setup.numOverlappingRegions()) { // count number of stubs on this dtc - auto acc = [](int& sum, const vector& module) { return sum += module.size(); }; - const int nStubs = accumulate(modules.begin(), modules.end(), 0, acc); + auto acc = [](int& sum, const vector& stubsModule) { return sum += stubsModule.size(); }; + const int nStubs = accumulate(stubsDTC.begin(), stubsDTC.end(), 0, acc); stubs_.reserve(nStubs); // convert and assign Stubs to DTC routing block channel - for (int modId = 0; modId < settings_->numModulesPerDTC(); modId++) { - const vector& ttStubRefs = modules[modId]; + for (int modId = 0; modId < setup.numModulesPerDTC(); modId++) { + const vector& ttStubRefs = stubsDTC[modId]; if (ttStubRefs.empty()) continue; // Module which produced this ttStubRefs - Module* module = modules_.at(modId); + SensorModule* module = modules_.at(modId); // DTC routing block id [0-1] - const int blockId = modId / settings_->numModulesPerRoutingBlock(); + const int blockId = modId / setup.dtcNumModulesPerRoutingBlock(); // DTC routing blockc channel id [0-35] - const int channelId = modId % settings_->numModulesPerRoutingBlock(); + const int channelId = modId % setup.dtcNumModulesPerRoutingBlock(); // convert TTStubs and fill input channel Stubs& stubs = input_[blockId][channelId]; for (const TTStubRef& ttStubRef : ttStubRefs) { - stubs_.emplace_back(settings_, module, ttStubRef); + stubs_.emplace_back(iConfig, setup, module, ttStubRef); Stub& stub = stubs_.back(); if (stub.valid()) // passed pt and eta cut @@ -48,12 +48,12 @@ namespace trackerDTC { // sort stubs by bend sort(stubs.begin(), stubs.end(), [](Stub* lhs, Stub* rhs) { return abs(lhs->bend()) < abs(rhs->bend()); }); // truncate stubs if desired - if (!settings_->enableTruncation() || (int)stubs.size() <= settings_->maxFramesChannelInput()) + if (!enableTruncation_ || (int)stubs.size() <= setup.numFramesFE()) continue; // begin of truncated stubs - const auto limit = next(stubs.begin(), settings_->maxFramesChannelInput()); + const auto limit = next(stubs.begin(), setup.numFramesFE()); // copy truncated stubs into lost output channel - for (int region = 0; region < settings_->numOverlappingRegions(); region++) + for (int region = 0; region < setup.numOverlappingRegions(); region++) copy_if( limit, stubs.end(), back_inserter(lost_[region]), [region](Stub* stub) { return stub->inRegion(region); }); // remove truncated stubs form input channel @@ -65,16 +65,16 @@ namespace trackerDTC { void DTC::produce(TTDTC& productAccepted, TTDTC& productLost) { // router step 1: merges stubs of all modules connected to one routing block into one stream Stubs lost; - Stubss blockStubs(settings_->numRoutingBlocks()); - for (int routingBlock = 0; routingBlock < settings_->numRoutingBlocks(); routingBlock++) + Stubss blockStubs(setup_->dtcNumRoutingBlocks()); + for (int routingBlock = 0; routingBlock < setup_->dtcNumRoutingBlocks(); routingBlock++) merge(input_[routingBlock], blockStubs[routingBlock], lost); // copy lost stubs during merge into lost output channel - for (int region = 0; region < settings_->numOverlappingRegions(); region++) - copy_if(lost.begin(), lost.end(), back_inserter(lost_[region]), [region](Stub* stub) { - return stub->inRegion(region); - }); + for (int region = 0; region < setup_->numOverlappingRegions(); region++) { + auto inRegion = [region](Stub* stub) { return stub->inRegion(region); }; + copy_if(lost.begin(), lost.end(), back_inserter(lost_[region]), inRegion); + } // router step 2: merges stubs of all routing blocks and splits stubs into one stream per overlapping region - Stubss regionStubs(settings_->numOverlappingRegions()); + Stubss regionStubs(setup_->numOverlappingRegions()); split(blockStubs, regionStubs); // fill products produce(regionStubs, productAccepted); @@ -96,7 +96,7 @@ namespace trackerDTC { continue; Stub* stub = pop_front(input); if (stub) { - if (settings_->enableTruncation() && (int)stack.size() == settings_->sizeStack() - 1) + if (enableTruncation_ && (int)stack.size() == setup_->dtcDepthMemory() - 1) // kill current first stub when fifo overflows lost.push_back(pop_front(stack)); stack.push_back(stub); @@ -118,8 +118,8 @@ namespace trackerDTC { output.push_back(nullptr); } // truncate if desired - if (settings_->enableTruncation() && (int)output.size() > settings_->maxFramesChannelOutput()) { - const auto limit = next(output.begin(), settings_->maxFramesChannelOutput()); + if (enableTruncation_ && (int)output.size() > setup_->numFramesIO()) { + const auto limit = next(output.begin(), setup_->numFramesIO()); copy_if(limit, output.end(), back_inserter(lost), [](Stub* stub) { return stub; }); output.erase(limit, output.end()); } @@ -136,8 +136,12 @@ namespace trackerDTC { // copy of masked inputs for each output Stubss streams(inputs.size()); int i(0); - for (Stubs& input : inputs) - transform(input.begin(), input.end(), back_inserter(streams[i++]), regionMask); + for (Stubs& input : inputs) { + Stubs& stream = streams[i++]; + transform(input.begin(), input.end(), back_inserter(stream), regionMask); + for (auto it = stream.end(); it != stream.begin();) + it = (*--it) ? stream.begin() : stream.erase(it); + } merge(streams, output, lost_[region++]); } } diff --git a/L1Trigger/TrackerDTC/src/ES_Setup.cc b/L1Trigger/TrackerDTC/src/ES_Setup.cc new file mode 100644 index 0000000000000..5ff94b4b86f12 --- /dev/null +++ b/L1Trigger/TrackerDTC/src/ES_Setup.cc @@ -0,0 +1,4 @@ +#include "FWCore/Utilities/interface/typelookup.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" + +TYPELOOKUP_DATA_REG(trackerDTC::Setup); \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/Module.cc b/L1Trigger/TrackerDTC/src/Module.cc deleted file mode 100644 index 512ee1c97cf1a..0000000000000 --- a/L1Trigger/TrackerDTC/src/Module.cc +++ /dev/null @@ -1,122 +0,0 @@ -#include "L1Trigger/TrackerDTC/interface/Module.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "DataFormats/GeometryVector/interface/GlobalPoint.h" -#include "DataFormats/GeometrySurface/interface/Plane.h" -#include "DataFormats/SiStripDetId/interface/StripSubdetector.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" -#include "Geometry/CommonTopologies/interface/PixelTopology.h" - -#include -#include - -using namespace std; -using namespace edm; - -namespace trackerDTC { - - Module::Module(Settings* settings, const DetId& detId, int dtcId) { - const TrackerGeometry* trackerGeometry = settings->trackerGeometry(); - const TrackerTopology* trackerTopology = settings->trackerTopology(); - const GeomDetUnit* det0 = trackerGeometry->idToDetUnit(detId); - const PixelTopology* topol = - dynamic_cast(&(dynamic_cast(det0)->specificTopology())); - const Plane& plane = dynamic_cast(det0)->surface(); - const GlobalPoint pos0 = GlobalPoint(det0->position()); - const GlobalPoint pos1 = - GlobalPoint(trackerGeometry->idToDetUnit(trackerTopology->partnerDetId(detId))->position()); - // detector region_ [0-8] - region_ = dtcId / settings->numDTCsPerRegion(); - // module radius in cm - R_ = pos0.perp(); - // module phi w.r.t. detector region_ centre in rad - Phi_ = deltaPhi(pos0.phi() - (region_ + .5) * settings->baseRegion()); - // module z in cm - Z_ = pos0.z(); - // sensor separation in cm - sep_ = (pos1 - pos0).mag(); - // sensor pitch in cm [strip=.009,pixel=.01] - pitchRow_ = topol->pitch().first; - // sensor length in cm [strip=5,pixel=.15625] - pitchCol_ = topol->pitch().second; - // number of columns [2S=2,PS=8] - numColumns_ = topol->ncolumns(); - // number of rows [2S=8*127,PS=8*120] - numRows_ = topol->nrows(); - side_ = pos0.z() >= 0.; - flipped_ = pos0.mag() > pos1.mag(); - barrel_ = detId.subdetId() == StripSubdetector::TOB; - // module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis - tilt_ = flipped_ ? atan2(pos1.z() - pos0.z(), pos0.perp() - pos1.perp()) - : atan2(pos0.z() - pos1.z(), pos1.perp() - pos0.perp()); - // sinus of module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis - sin_ = sin(tilt_); - // cosinus of module tilt measured w.r.t. beam axis (+-1=endcap), tk layout measures w.r.t. radial axis - cos_ = cos(tilt_); - // layer id [1-6,11-15] - layerId_ = - barrel_ ? trackerTopology->layer(detId) : trackerTopology->tidWheel(detId) + settings->offsetLayerDisks(); - // TTStub row needs flip of sign - signRow_ = signbit(deltaPhi(plane.rotation().x().phi() - pos0.phi())); - // TTStub col needs flip of sign - signCol_ = !barrel_ && !side_; - // TTStub bend needs flip of sign - signBend_ = barrel_ || (!barrel_ && side_); - - // sets hybrid specific member - if (settings->dataFormat() != "Hybrid") - return; - // gettings hybrid config - SettingsHybrid* format = settings->hybrid(); - const vector& numRingsPS = format->numRingsPS(); - const vector& diskZs = format->diskZs(); - const vector& layerRs = format->layerRs(); - const vector& numTiltedLayerRings = format->numTiltedLayerRings(); - const vector& windowSizeBarrelLayers = format->windowSizeBarrelLayers(); - const vector >& windowSizeTiltedLayerRings = format->windowSizeTiltedLayerRings(); - const vector >& windowSizeEndcapDisksRings = format->windowSizeEndcapDisksRings(); - const vector >& bendEncodingsPS = format->bendEncodingsPS(); - const vector >& bendEncodings2S = format->bendEncodings2S(); - const vector >& layerIdEncodings = format->layerIdEncodings(); - // determing sensor type - const bool psModule = trackerGeometry->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; - if (barrel_ && psModule) - type_ = SettingsHybrid::barrelPS; - if (barrel_ && !psModule) - type_ = SettingsHybrid::barrel2S; - if (!barrel_ && psModule) - type_ = SettingsHybrid::diskPS; - if (!barrel_ && !psModule) - type_ = SettingsHybrid::disk2S; - // getting windows size for bend encoding - enum TypeBarrel { nonBarrel = 0, tiltedMinus = 1, tiltedPlus = 2, flat = 3 }; - const TypeBarrel type = static_cast(trackerTopology->tobSide(detId)); - int ladder = barrel_ ? trackerTopology->tobRod(detId) : trackerTopology->tidRing(detId); - if (barrel_ && type == tiltedMinus) - // Corrected ring number, bet 0 and barrelNTilt.at(layer), in ascending |z| - ladder = 1 + numTiltedLayerRings.at(layerId_) - ladder; - double windowSize = barrel_ ? windowSizeBarrelLayers.at(layerId_) - : windowSizeEndcapDisksRings.at(layerId_ - settings->offsetLayerDisks()).at(ladder); - if (barrel_ && type != flat) - windowSize = windowSizeTiltedLayerRings.at(layerId_).at(ladder); - const int ws = windowSize / format->baseWindowSize(); - // getting bend encoding - bendEncoding_ = psModule ? bendEncodingsPS.at(ws) : bendEncodings2S.at(ws); - // encoding for 2S endcap radii - decodedR_ = -1; - if (type_ == SettingsHybrid::disk2S) { - const int offset = numRingsPS.at(layerId_ - settings->offsetLayerId() - settings->offsetLayerDisks()); - decodedR_ = numColumns_ * (ladder - offset); - } - // r and z offsets - offsetR_ = barrel_ ? layerRs.at(layerId_ - settings->offsetLayerId()) : 0.; - offsetZ_ = barrel_ ? 0. : diskZs.at(layerId_ - settings->offsetLayerId() - settings->offsetLayerDisks()); - if (!side_) - offsetZ_ *= -1.; - // layer id encoding - const vector& layerIdEncoding = layerIdEncodings.at(dtcId % settings->numDTCsPerRegion()); - layerId_ = distance(layerIdEncoding.begin(), find(layerIdEncoding.begin(), layerIdEncoding.end(), layerId_)); - } - -} // namespace trackerDTC \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/SensorModule.cc b/L1Trigger/TrackerDTC/src/SensorModule.cc new file mode 100644 index 0000000000000..0febf78f0116d --- /dev/null +++ b/L1Trigger/TrackerDTC/src/SensorModule.cc @@ -0,0 +1,120 @@ +#include "L1Trigger/TrackerDTC/interface/SensorModule.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" +#include "DataFormats/GeometrySurface/interface/Plane.h" + +#include +#include +#include +#include + +using namespace std; +using namespace edm; + +namespace trackerDTC { + + SensorModule::SensorModule(const Setup& setup, const DetId& detId, int dtcId, int modId) + : detId_(detId), dtcId_(dtcId), modId_(modId) { + const TrackerGeometry* trackerGeometry = setup.trackerGeometry(); + const TrackerTopology* trackerTopology = setup.trackerTopology(); + const GeomDetUnit* geomDetUnit = trackerGeometry->idToDetUnit(detId); + const PixelTopology* pixelTopology = + dynamic_cast(&(dynamic_cast(geomDetUnit)->specificTopology())); + const Plane& plane = dynamic_cast(geomDetUnit)->surface(); + const GlobalPoint pos0 = GlobalPoint(geomDetUnit->position()); + const GlobalPoint pos1 = + GlobalPoint(trackerGeometry->idToDetUnit(trackerTopology->partnerDetId(detId))->position()); + // detector region [0-8] + const int region = dtcId_ / setup.numDTCsPerRegion(); + // module radius in cm + r_ = pos0.perp(); + // module phi w.r.t. detector region_ centre in rad + phi_ = deltaPhi(pos0.phi() - (region + .5) * setup.baseRegion()); + // module z in cm + z_ = pos0.z(); + // sensor separation in cm + sep_ = (pos1 - pos0).mag(); + // sensor pitch in cm [strip=.009,pixel=.01] + pitchRow_ = pixelTopology->pitch().first; + // sensor length in cm [strip=5,pixel=.15625] + pitchCol_ = pixelTopology->pitch().second; + // number of columns [2S=2,PS=8] + numColumns_ = pixelTopology->ncolumns(); + // number of rows [2S=8*127,PS=8*120] + numRows_ = pixelTopology->nrows(); + // +z or -z + side_ = pos0.z() >= 0.; + // main sensor inside or outside + flipped_ = pos0.mag() > pos1.mag(); + // barrel or endcap + barrel_ = detId.subdetId() == StripSubdetector::TOB; + // Pixel-Strip or 2Strip module + psModule_ = trackerGeometry->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP; + // module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis + tilt_ = flipped_ ? atan2(pos1.z() - pos0.z(), pos0.perp() - pos1.perp()) + : atan2(pos0.z() - pos1.z(), pos1.perp() - pos0.perp()); + // sinus of module tilt measured w.r.t. beam axis (0=barrel), tk layout measures w.r.t. radial axis + sin_ = std::sin(tilt_); + // cosinus of module tilt measured w.r.t. beam axis (+-1=endcap), tk layout measures w.r.t. radial axis + cos_ = std::cos(tilt_); + // layer id [barrel: 0-5, endcap: 0-4] + const int layer = + (barrel_ ? trackerTopology->layer(detId) : trackerTopology->tidWheel(detId)) - setup.offsetLayerId(); + // layer id [1-6,11-15] + layerId_ = layer + setup.offsetLayerId() + (barrel_ ? 0 : setup.offsetLayerDisks()); + // TTStub row needs flip of sign + signRow_ = signbit(deltaPhi(plane.rotation().x().phi() - pos0.phi())); + // TTStub col needs flip of sign + signCol_ = !barrel_ && !side_; + // TTStub bend needs flip of sign + signBend_ = barrel_ || (!barrel_ && side_); + // determing sensor type + if (barrel_ && psModule_) + type_ = BarrelPS; + if (barrel_ && !psModule_) + type_ = Barrel2S; + if (!barrel_ && psModule_) + type_ = DiskPS; + if (!barrel_ && !psModule_) + type_ = Disk2S; + // encoding for 2S endcap radii + encodedR_ = -1; + if (type_ == Disk2S) { + const int offset = setup.hybridNumRingsPS(layer); + const int ring = trackerTopology->tidRing(detId); + encodedR_ = numColumns_ * (ring - offset); + } + // r and z offsets + if (barrel_) { + offsetR_ = setup.hybridLayerR(layer); + offsetZ_ = 0.; + } else { + offsetR_ = 0.; + offsetZ_ = side_ ? setup.hybridDiskZ(layer) : -setup.hybridDiskZ(layer); + } + // getting bend window size + double windowSize(-1.); + if (barrel_) { + enum TypeBarrel { nonBarrel = 0, tiltedMinus = 1, tiltedPlus = 2, flat = 3 }; + const TypeBarrel type = static_cast(trackerTopology->tobSide(detId)); + if (type == flat) + windowSize = setup.windowSizeBarrelLayer(layerId_); + else { + int ladder = trackerTopology->tobRod(detId); + if (type == tiltedMinus) + // Corrected ring number, bet 0 and barrelNTilt.at(layer), in ascending |z| + ladder = 1 + setup.numTiltedLayerRing(layerId_) - ladder; + windowSize = setup.windowSizeTiltedLayerRing(layerId_, ladder); + } + } else { + const int ring = trackerTopology->tidRing(detId); + const int lay = layer + setup.offsetLayerId(); + windowSize = setup.windowSizeEndcapDisksRing(lay, ring); + } + windowSize_ = windowSize / setup.baseWindowSize(); + // getting encoded layer id + const vector& encodingLayerId = setup.encodingLayerId(dtcId_); + const auto pos = find(encodingLayerId.begin(), encodingLayerId.end(), layerId_); + encodedLayerId_ = distance(encodingLayerId.begin(), pos); + } + +} // namespace trackerDTC \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/Settings.cc b/L1Trigger/TrackerDTC/src/Settings.cc deleted file mode 100644 index 3430069a2ce03..0000000000000 --- a/L1Trigger/TrackerDTC/src/Settings.cc +++ /dev/null @@ -1,314 +0,0 @@ -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/ParameterSet/interface/Registry.h" -#include "DataFormats/Provenance/interface/ProcessConfiguration.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" -#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithm_official.h" -#include "L1Trigger/TrackerDTC/interface/Module.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; - -namespace trackerDTC { - - Settings::Settings(const ParameterSet& iConfig) - : //TrackerDTCProducer parameter sets - paramsED_(iConfig.getParameter("ParamsED")), - paramsRouter_(iConfig.getParameter("ParamsRouter")), - paramsConverter_(iConfig.getParameter("ParamsConverter")), - paramsTracker_(iConfig.getParameter("ParamsTracker")), - paramsFW_(iConfig.getParameter("ParamsFW")), - paramsFormat_(iConfig.getParameter("ParamsFormat")), - paramsAnalyzer_(iConfig.getParameter("ParamsAnalyzer")), - paramsTP_(iConfig.getParameter("ParamsTP")), - // ED parameter - inputTagTTStubDetSetVec_(paramsED_.getParameter("InputTagTTStubDetSetVec")), - inputTagMagneticField_(paramsED_.getParameter("InputTagMagneticField")), - inputTagTrackerGeometry_(paramsED_.getParameter("InputTagTrackerGeometry")), - inputTagTrackerTopology_(paramsED_.getParameter("InputTagTrackerTopology")), - inputTagCablingMap_(paramsED_.getParameter("InputTagCablingMap")), - inputTagTTStubAlgorithm_(paramsED_.getParameter("InputTagTTStubAlgorithm")), - inputTagGeometryConfiguration_(paramsED_.getParameter("InputTagGeometryConfiguration")), - supportedTrackerXMLPSet_(paramsED_.getParameter("SupportedTrackerXMLPSet")), - supportedTrackerXMLPath_(paramsED_.getParameter("SupportedTrackerXMLPath")), - supportedTrackerXMLFile_(paramsED_.getParameter("SupportedTrackerXMLFile")), - supportedTrackerXMLVersions_(paramsED_.getParameter>("SupportedTrackerXMLVersions")), - productBranchAccepted_(paramsED_.getParameter("ProductBranchAccepted")), - productBranchLost_(paramsED_.getParameter("ProductBranchLost")), - dataFormat_(paramsED_.getParameter("DataFormat")), - offsetDetIdDSV_(paramsED_.getParameter("OffsetDetIdDSV")), - offsetDetIdTP_(paramsED_.getParameter("OffsetDetIdTP")), - offsetLayerDisks_(paramsED_.getParameter("OffsetLayerDisks")), - offsetLayerId_(paramsED_.getParameter("OffsetLayerId")), - checkHistory_(paramsED_.getParameter("CheckHistory")), - processName_(paramsED_.getParameter("ProcessName")), - productLabel_(paramsED_.getParameter("ProductLabel") + "@"), - // Router parameter - enableTruncation_(paramsRouter_.getParameter("EnableTruncation")), - freqDTC_(paramsRouter_.getParameter("FreqDTC")), - tmpTFP_(paramsRouter_.getParameter("TMP_TFP")), - numFramesInfra_(paramsRouter_.getParameter("NumFramesInfra")), - numRoutingBlocks_(paramsRouter_.getParameter("NumRoutingBlocks")), - sizeStack_(paramsRouter_.getParameter("SizeStack")), - // Converter parameter - widthRowLUT_(paramsConverter_.getParameter("WidthRowLUT")), - widthQoverPt_(paramsConverter_.getParameter("WidthQoverPt")), - // Tracker parameter - numRegions_(paramsTracker_.getParameter("NumRegions")), - numOverlappingRegions_(paramsTracker_.getParameter("NumOverlappingRegions")), - numDTCsPerRegion_(paramsTracker_.getParameter("NumDTCsPerRegion")), - numModulesPerDTC_(paramsTracker_.getParameter("NumModulesPerDTC")), - tmpFE_(paramsTracker_.getParameter("TMP_FE")), - widthBend_(paramsTracker_.getParameter("WidthBend")), - widthCol_(paramsTracker_.getParameter("WidthCol")), - widthRow_(paramsTracker_.getParameter("WidthRow")), - baseBend_(paramsTracker_.getParameter("BaseBend")), - baseCol_(paramsTracker_.getParameter("BaseCol")), - baseRow_(paramsTracker_.getParameter("BaseRow")), - bendCut_(paramsTracker_.getParameter("BendCut")), - freqLHC_(paramsTracker_.getParameter("FreqLHC")), - // f/w constants - speedOfLight_(paramsFW_.getParameter("SpeedOfLight")), - bField_(paramsFW_.getParameter("BField")), - bFieldError_(paramsFW_.getParameter("BFieldError")), - outerRadius_(paramsFW_.getParameter("OuterRadius")), - innerRadius_(paramsFW_.getParameter("InnerRadius")), - maxPitch_(paramsFW_.getParameter("MaxPitch")), - // Format specific parameter - maxEta_(paramsFormat_.getParameter("MaxEta")), - minPt_(paramsFormat_.getParameter("MinPt")), - chosenRofPhi_(paramsFormat_.getParameter("ChosenRofPhi")), - numLayers_(paramsFormat_.getParameter("NumLayers")), - // Analyzer - useMCTruth_(paramsAnalyzer_.getParameter("UseMCTruth")), - inputTagTTClusterAssMap_(paramsAnalyzer_.getParameter("InputTagTTClusterAssMap")), - producerLabel_(paramsAnalyzer_.getParameter("ProducerLabel")), - // TP - tpMinPt_(paramsTP_.getParameter("MinPt")), - tpMaxEta_(paramsTP_.getParameter("MaxEta")), - tpMaxVertR_(paramsTP_.getParameter("MaxVertR")), - tpMaxVertZ_(paramsTP_.getParameter("MaxVertZ")), - tpMaxD0_(paramsTP_.getParameter("MaxD0")), - tpMinLayers_(paramsTP_.getParameter("MinLayers")), - tpMinLayersPS_(paramsTP_.getParameter("MinLayersPS")) { - // derived Router parameter - numDTCs_ = numRegions_ * numDTCsPerRegion_; - numDTCsPerTFP_ = numDTCsPerRegion_ * numOverlappingRegions_; - numModules_ = numRegions_ * numDTCsPerRegion_ * numModulesPerDTC_; - numModulesPerRoutingBlock_ = numModulesPerDTC_ / numRoutingBlocks_; - - const int numFramesPerBX = freqDTC_ / freqLHC_; - maxFramesChannelInput_ = numFramesPerBX * tmpFE_ - numFramesInfra_; - maxFramesChannelOutput_ = numFramesPerBX * tmpTFP_ - numFramesInfra_; - - numMergedRows_ = pow(2, widthRow_ - widthRowLUT_); - maxCot_ = sinh(maxEta_); - - invPtToDphi_ = speedOfLight_ * bField_ / 2000.; - rangeQoverPt_ = 2. * invPtToDphi_ / minPt_; - - widthLayer_ = ceil(log2(numLayers_)); - - baseRegion_ = 2. * M_PI / numRegions_; - - if (dataFormat_ == "TMTT") - tmtt_ = make_unique(iConfig, this); - else if (dataFormat_ == "Hybrid") - hybrid_ = make_unique(iConfig, this); - else { - cms::Exception exception("Configuration"); - exception << "unknown data format requested (" << dataFormat_ << ")."; - exception.addContext("trackerDTC::Settings::Settings"); - throw exception; - } - - maxQoverPt_ = (rangeQoverPt_ - baseQoverPt_) / 2.; - - const int baseDiffM = widthRowLUT_ - widthRow_; - - baseM_ = basePhi_ * pow(2., baseDiffM); - baseC_ = basePhi_; - - widthC_ = widthPhi_; - - const double x1 = pow(2, widthRow_) * baseRow_ * maxPitch_ / 2.; - const double x0 = x1 - pow(2, widthRowLUT_) * baseRow_ * maxPitch_; - const double maxM = atan2(x1, innerRadius_) - atan2(x0, innerRadius_); - - widthM_ = ceil(log2(maxM / baseM_)); - - // event setup - trackerGeometry_ = nullptr; - trackerTopology_ = nullptr; - magneticField_ = nullptr; - // derived event setup - dtcModules_ = vector>(numDTCs_); - configurationSupported_ = true; - } - - // store TrackerGeometry - void Settings::setTrackerGeometry(const TrackerGeometry* trackerGeometry) { trackerGeometry_ = trackerGeometry; } - // store TrackerTopology - void Settings::setTrackerTopology(const TrackerTopology* trackerTopology) { trackerTopology_ = trackerTopology; } - // store MagneticField - void Settings::setMagneticField(const MagneticField* magneticField) { magneticField_ = magneticField; } - // store TrackerDetToDTCELinkCablingMap - void Settings::setCablingMap(const TrackerDetToDTCELinkCablingMap* cablingMap) { ttCablingMap_ = cablingMap; } - // store TTStubAlgorithm handle - void Settings::setTTStubAlgorithm( - const edm::ESHandle>& handleTTStubAlgorithm) { - handleTTStubAlgorithm_ = handleTTStubAlgorithm; - } - // store GeometryConfiguration - void Settings::setGeometryConfiguration(const ESHandle& handleGeometryConfiguration) { - handleGeometryConfiguration_ = handleGeometryConfiguration; - } - // store ProcessHistory - void Settings::setProcessHistory(const ProcessHistory& processHistory) { processHistory_ = processHistory; } - - // check current coniguration consistency with input configuration - void Settings::checkConfiguration() { - // check if bField is supported - const double bField = magneticField_->inTesla(GlobalPoint(0., 0., 0.)).z(); - if (abs(bField - bField_) > bFieldError_) { - configurationSupported_ = false; - LogWarning("ConfigurationNotSupported") << "Magnetic Field from EventSetup (" << bField << ") differs more then " - << bFieldError_ << " from supported value (" << bField_ << "). "; - } - // check if geometry is supported - const ParameterSet& pSetGeometryConfiguration = getParameterSet(handleGeometryConfiguration_.description()->pid_); - const vector& geomXMLFiles = - pSetGeometryConfiguration.getParameter>(supportedTrackerXMLPSet_); - string trackerXMLVersion; - for (const string& geomXMLFile : geomXMLFiles) { - const auto begin = geomXMLFile.find(supportedTrackerXMLPath_) + supportedTrackerXMLPath_.size(); - const auto end = geomXMLFile.find(supportedTrackerXMLFile_); - if (begin != string::npos && end != string::npos) - trackerXMLVersion = geomXMLFile.substr(begin, end - begin - 1); - } - if (trackerXMLVersion.empty()) { - cms::Exception exception("LogicError"); - exception << "No " << supportedTrackerXMLPath_ << "*/" << supportedTrackerXMLFile_ - << " found in GeometryConfiguration"; - exception.addContext("trackerDTC::Settings::checkConfiguration"); - throw exception; - } - if (find(supportedTrackerXMLVersions_.begin(), supportedTrackerXMLVersions_.end(), trackerXMLVersion) == - supportedTrackerXMLVersions_.end()) { - configurationSupported_ = false; - LogWarning("ConfigurationNotSupported") - << "Geometry Configuration " << supportedTrackerXMLPath_ << trackerXMLVersion << "/" - << supportedTrackerXMLFile_ << " is not supported. "; - } - if (!configurationSupported_) - return; - // check history - if (!checkHistory_) - return; - // get iConfig of used GeometryConfiguration in input producer - const ParameterSet* historyGeometryConfigurationPSet = nullptr; - const pset::Registry* psetRegistry = pset::Registry::instance(); - for (const ProcessConfiguration& pc : processHistory_) { - if (processName_ != pc.processName()) - continue; - const ParameterSet* processPset = psetRegistry->getMapped(pc.parameterSetID()); - if (processPset && processPset->exists(productLabel_)) - historyGeometryConfigurationPSet = &processPset->getParameterSet(productLabel_); - } - if (!historyGeometryConfigurationPSet) { - cms::Exception exception("Configuration"); - exception << "GeometryConfiguration not found in process history."; - exception << "Searched for process " << processName_ << " and label " << productLabel_ << "."; - exception.addContext("trackerDTC::Settings::checkConfiguration"); - throw exception; - } - if (handleGeometryConfiguration_.description()->pid_ != historyGeometryConfigurationPSet->id()) { - cms::Exception exception("Configuration"); - exception - << "Configured GeometryConfiguration inconsistent with used GeometryConfiguration during stub production."; - exception.addContext("trackerDTC::Settings::checkConfiguration"); - throw exception; - } - // check data format specific history - if (dataFormat_ == "Hybrid") - hybrid_->checkConfiguration(this); - } - - // convert ES Products into handy objects - void Settings::beginRun() { - // convert cabling map - // DTC product used to convert between different dtc id schemes - TTDTC ttDTC(numRegions_, numOverlappingRegions_, numDTCsPerRegion_); - // module counter for each DTC - vector modIds(numDTCs_, 0); - // loop over all tracker modules - for (const DetId& detId : trackerGeometry_->detIds()) { - // skip pixel detector - if (detId.subdetId() == pixelBarrel || detId.subdetId() == pixelDisks) - continue; - // skip multiple detIds per module - if (!trackerTopology_->isLower(detId)) - continue; - // tk layout dtc id, lowerDetId - 1 = tk lyout det id - const int tklId = ttCablingMap_->detIdToDTCELinkId(detId.rawId() + offsetDetIdTP()).first->second.dtc_id(); - // track trigger dtc id [0-215] - const int dtcId = ttDTC.dtcId(tklId); - // DTC module id [0-71] - int& modId = modIds[dtcId]; - // track trigger module id [0-15551] - const int ModId = dtcId * numModulesPerDTC_ + modId; - // store connection between global module id and detId - cablingMap_.emplace(detId, ModId); - // check configuration - if (modId++ > numModulesPerDTC_) { - cms::Exception exception("overflow"); - exception << "Cabling map connects more than " << numModulesPerDTC_ << " modules to a DTC."; - exception.addContext("trackerDTC::Settings::convertCablingMap"); - throw exception; - } - } - // hybrid specific conversions - if (dataFormat_ == "Hybrid") { - hybrid_->createEncodingsBend(this); - hybrid_->createEncodingsLayer(this); - } - //convert tracker geometry - for (int dtcId = 0; dtcId < numDTCs_; dtcId++) - dtcModules_[dtcId] = vector(modIds.at(dtcId), nullptr); - modules_.reserve(cablingMap_.size()); - for (const auto& map : cablingMap_) { - const int dtcId = map.second / numModulesPerDTC_; - const int modId = map.second % numModulesPerDTC_; - modules_.emplace_back(this, map.first, dtcId); - dtcModules_[dtcId][modId] = &modules_.back(); - } - } - - // convert DetId to module id [0:15551] - int Settings::modId(const DetId& detId) const { - unordered_map::const_iterator it = cablingMap_.find(detId); - if (it == cablingMap_.end()) { - cms::Exception exception("LogicError"); - exception << "Unknown DetID (" << detId << ") received from TTStub."; - exception.addAdditionalInfo("Please check consistency between chosen cabling map and chosen tracker geometry."); - exception.addContext("trackerDTC::Settings::modId"); - throw exception; - } - return it->second; - } - - // collection of modules connected to a specific dtc - const vector& Settings::modules(int dtcId) const { return dtcModules_.at(dtcId); } - -} // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/src/SettingsHybrid.cc b/L1Trigger/TrackerDTC/src/SettingsHybrid.cc deleted file mode 100644 index b564411fb5ae6..0000000000000 --- a/L1Trigger/TrackerDTC/src/SettingsHybrid.cc +++ /dev/null @@ -1,198 +0,0 @@ -#include "L1Trigger/TrackerDTC/interface/SettingsHybrid.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "DataFormats/Provenance/interface/ProcessConfiguration.h" -#include "FWCore/ParameterSet/interface/Registry.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTDTC.h" -#include "L1Trigger/TrackTrigger/interface/TTStubAlgorithm_official.h" -#include "L1Trigger/TrackerDTC/interface/Module.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace edm; - -namespace trackerDTC { - - SettingsHybrid::SettingsHybrid(const ParameterSet& iConfig, Settings* settings) - : // TrackerDTCFormat parameter sets - paramsFormat_(iConfig.getParameter("ParamsFormat")), - paramsTTStubAlgo_(iConfig.getParameter("ParamsTTStubAlgo")), - // TTStubAlgo parameter - checkHistory_(paramsTTStubAlgo_.getParameter("CheckHistory")), - productLabel_(paramsTTStubAlgo_.getParameter("Label") + "@"), - processName_(paramsTTStubAlgo_.getParameter("Process")), - baseWindowSize_(paramsTTStubAlgo_.getParameter("BaseWindowSize")), - // format specific parameter - numRingsPS_(paramsFormat_.getParameter>("NumRingsPS")), - widthsR_(paramsFormat_.getParameter>("WidthsR")), - widthsZ_(paramsFormat_.getParameter>("WidthsZ")), - widthsPhi_(paramsFormat_.getParameter>("WidthsPhi")), - widthsAlpha_(paramsFormat_.getParameter>("WidthsAlpha")), - widthsBend_(paramsFormat_.getParameter>("WidthsBend")), - rangesR_(paramsFormat_.getParameter>("RangesR")), - rangesZ_(paramsFormat_.getParameter>("RangesZ")), - rangesAlpha_(paramsFormat_.getParameter>("RangesAlpha")), - layerRs_(paramsFormat_.getParameter>("LayerRs")), - diskZs_(paramsFormat_.getParameter>("DiskZs")), - disk2SRsSet_(paramsFormat_.getParameter>("Disk2SRsSet")) { - disk2SRs_.reserve(disk2SRsSet_.size()); - for (const auto& pSet : disk2SRsSet_) - disk2SRs_.emplace_back(pSet.getParameter>("Disk2SRs")); - - auto comp = [](const double& lhs, const double& rhs) { return lhs > 0. ? (rhs > 0. ? lhs < rhs : true) : false; }; - - const double rangeRT = 2. * max(abs(settings->outerRadius_ - settings->chosenRofPhi_), - abs(settings->innerRadius_ - settings->chosenRofPhi_)); - const double rangePhi = settings->baseRegion_ + rangeRT * settings->rangeQoverPt_ / 2.; - - bool error(false); - for (const vector& vec : {widthsR_, widthsZ_, widthsPhi_}) - if (vec.size() != numSensorTypes) - error = true; - for (const vector& vec : {rangesR_, rangesZ_}) - if (vec.size() != numSensorTypes) - error = true; - if (error) { - cms::Exception exception("LogicError"); - exception << "Expect for each sensor type specification of width and range of stub coordinates."; - exception.addContext("trackerDTC::SettingsHybrid::SettingsHybrid"); - throw exception; - } - - basesZ_.reserve(numSensorTypes); - for (int type = 0; type < numSensorTypes; type++) - basesZ_.push_back(rangesZ_[type] / pow(2., widthsZ_[type])); - - basesR_.reserve(numSensorTypes); - for (int type = 0; type < numSensorTypes; type++) - basesR_.push_back(rangesR_[type] / pow(2., widthsR_[type])); - basesR_[disk2S] = 1.; - - basesPhi_.reserve(numSensorTypes); - for (int type = 0; type < numSensorTypes; type++) - basesPhi_.push_back(rangePhi / pow(2., widthsPhi_[type])); - - basesAlpha_.reserve(numSensorTypes); - for (int type = 0; type < numSensorTypes; type++) - basesAlpha_.push_back(rangesAlpha_[type] / pow(2., widthsAlpha_[type])); - - numsUnusedBits_.reserve(numSensorTypes); - for (int type = 0; type < numSensorTypes; type++) - numsUnusedBits_.push_back(TTBV::S - widthsR_[type] - widthsZ_[type] - widthsPhi_[type] - widthsAlpha_[type] - - widthsBend_[type] - settings->widthLayer_ - 1); - - layerIdEncodings_.reserve(settings->numDTCs_); - - settings->widthR_ = *max_element(widthsR_.begin(), widthsR_.end()); - settings->widthZ_ = *max_element(widthsZ_.begin(), widthsZ_.end()); - settings->widthPhi_ = *max_element(widthsPhi_.begin(), widthsPhi_.end()); - settings->widthEta_ = 0; - - settings->baseZ_ = *min_element(basesZ_.begin(), basesZ_.end(), comp); - settings->baseR_ = *min_element(basesR_.begin(), basesR_.end(), comp); - settings->basePhi_ = *min_element(basesPhi_.begin(), basesPhi_.end(), comp); - settings->baseQoverPt_ = settings->rangeQoverPt_ / pow(2., settings->widthQoverPt_); - - layerIdEncodings_.reserve(settings->numDTCsPerRegion_); - } - - // check current coniguration consistency with input configuration - void SettingsHybrid::checkConfiguration(Settings* settings) const { - if (!checkHistory_) - return; - // get iConfig of used TTStubAlgorithm in input producer - const ParameterSet* historyTTStubAlgorithmPSet = nullptr; - const pset::Registry* psetRegistry = pset::Registry::instance(); - for (const ProcessConfiguration& pc : settings->processHistory_) { - if (processName_ != pc.processName()) - continue; - const ParameterSet* processPset = psetRegistry->getMapped(pc.parameterSetID()); - if (processPset && processPset->exists(productLabel_)) - historyTTStubAlgorithmPSet = &processPset->getParameterSet(productLabel_); - } - if (!historyTTStubAlgorithmPSet) { - cms::Exception exception("Configuration"); - exception << "TTStub algo config not found in process history."; - exception << "Searched for process " << processName_ << " and label " << productLabel_ << "."; - exception.addContext("trackerDTC::SettingsHybrid::checkConfiguration"); - throw exception; - } - if (settings->handleTTStubAlgorithm_.description()->pid_ != historyTTStubAlgorithmPSet->id()) { - cms::Exception exception("Configuration"); - exception << "Configured TTStubAlgorithm inconsistent with used TTStubAlgorithm during stub production."; - exception.addContext("trackerDTC::SettingsHybrid::checkConfiguration"); - throw exception; - } - } - - void SettingsHybrid::createEncodingsLayer(Settings* settings) { - const TrackerTopology* trackerTopology = settings->trackerTopology_; - // assess layerIds connected to each DTC per region, accumulated over all regions - vector> layerIdEncodings(settings->numDTCsPerRegion_); - for (const auto& map : settings->cablingMap_) { - const bool barrel = map.first.subdetId() == StripSubdetector::TOB; - const int layerId = barrel ? trackerTopology->layer(map.first) : trackerTopology->tidWheel(map.first) + 10; - const int dtcId = (map.second / settings->numModulesPerDTC_) % settings->numDTCsPerRegion_; - layerIdEncodings[dtcId].insert(layerId); - } - for (const set& layerIdEncoding : layerIdEncodings) { - // check configuration - if ((int)layerIdEncoding.size() > settings->numLayers_) { - cms::Exception exception("overflow"); - exception << "Cabling map connects more than " << settings->numLayers_ << " layers to a DTC."; - exception.addContext("trackerDTC::SettingsHybrid::createEncodingsLayer"); - throw exception; - } - // index = decoded layerId, value = encoded layerId - layerIdEncodings_.emplace_back(layerIdEncoding.begin(), layerIdEncoding.end()); - } - } - - void SettingsHybrid::createEncodingsBend(Settings* settings) { - // get configuration of TTStubAlgorithm - const ParameterSet& pSet = getParameterSet(settings->handleTTStubAlgorithm_.description()->pid_); - numTiltedLayerRings_ = pSet.getParameter>("NTiltedRings"); - windowSizeBarrelLayers_ = pSet.getParameter>("BarrelCut"); - const vector& pSetsEncapDisks = pSet.getParameter>("EndcapCutSet"); - const vector& pSetsTiltedLayer = pSet.getParameter>("TiltedBarrelCutSet"); - windowSizeTiltedLayerRings_.reserve(pSetsTiltedLayer.size()); - for (const auto& pSet : pSetsTiltedLayer) - windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter>("TiltedCut")); - windowSizeEndcapDisksRings_.reserve(pSetsEncapDisks.size()); - for (const auto& pSet : pSetsEncapDisks) - windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter>("EndcapCut")); - int maxWindowSize(0); - for (const auto& windowss : {windowSizeTiltedLayerRings_, windowSizeEndcapDisksRings_, {windowSizeBarrelLayers_}}) - for (const auto& windows : windowss) - for (const auto& window : windows) - maxWindowSize = max(maxWindowSize, (int)(window / baseWindowSize_)); - // create bend encodings - const TTStubAlgorithm_official* ttStubAlgorithm = - dynamic_cast*>( - settings->handleTTStubAlgorithm_.product()); - bendEncodingsPS_.reserve(maxWindowSize); - bendEncodings2S_.reserve(maxWindowSize); - for (const bool& ps : {false, true}) { - vector>& bendEncodings = ps ? bendEncodingsPS_ : bendEncodings2S_; - bendEncodings.reserve(maxWindowSize + 1); - for (int window = 0; window < maxWindowSize + 1; window++) { - set bendEncoding; - for (int bend = 0; bend < window + 1; bend++) - bendEncoding.insert(ttStubAlgorithm->degradeBend(ps, window, bend)); - // index = encoded bend, value = decoded bend - bendEncodings.emplace_back(bendEncoding.begin(), bendEncoding.end()); - } - } - } - -} // namespace trackerDTC diff --git a/L1Trigger/TrackerDTC/src/SettingsTMTT.cc b/L1Trigger/TrackerDTC/src/SettingsTMTT.cc deleted file mode 100644 index df208011c37bd..0000000000000 --- a/L1Trigger/TrackerDTC/src/SettingsTMTT.cc +++ /dev/null @@ -1,75 +0,0 @@ -#include "L1Trigger/TrackerDTC/interface/SettingsTMTT.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "DataFormats/L1TrackTrigger/interface/TTBV.h" - -#include - -using namespace std; -using namespace edm; - -namespace trackerDTC { - - SettingsTMTT::SettingsTMTT(const ParameterSet& iConfig, Settings* settings) - : //TrackerDTCFormat parameter sets - paramsFormat_(iConfig.getParameter("ParamsFormat")), - // format specific parameter - numSectorsPhi_(paramsFormat_.getParameter("NumSectorsPhi")), - numBinsQoverPt_(paramsFormat_.getParameter("NumBinsQoverPt")), - numBinsPhiT_(paramsFormat_.getParameter("NumBinsPhiT")), - chosenRofZ_(paramsFormat_.getParameter("ChosenRofZ")), - beamWindowZ_(paramsFormat_.getParameter("BeamWindowZ")), - halfLength_(paramsFormat_.getParameter("HalfLength")), - boundariesEta_(paramsFormat_.getParameter >("BoundariesEta")) { - // number of eta sectors used during track finding - numSectorsEta_ = boundariesEta_.size() - 1; - // cut on zT - maxZT_ = settings->maxCot_ * chosenRofZ_; - // width of phi sector in rad - baseSector_ = settings->baseRegion_ / (double)numSectorsPhi_; - // number of bits used for stub q over pt - widthQoverPtBin_ = ceil(log2(numBinsQoverPt_)); - - int& widthR = settings->widthR_; - int& widthPhi = settings->widthPhi_; - int& widthZ = settings->widthZ_; - int& widthEta = settings->widthEta_; - - widthR = paramsFormat_.getParameter("WidthR"); - widthPhi = paramsFormat_.getParameter("WidthPhi"); - widthZ = paramsFormat_.getParameter("WidthZ"); - widthEta = ceil(log2(numSectorsEta_)); - - numUnusedBits_ = TTBV::S - 1 - widthR - widthPhi - widthZ - 2 * widthQoverPtBin_ - 2 * widthEta - numSectorsPhi_ - - settings->widthLayer_; - - double& baseQoverPt = settings->baseQoverPt_; - double& baseR = settings->baseR_; - double& baseZ = settings->baseZ_; - double& basePhi = settings->basePhi_; - - baseQoverPtBin_ = settings->rangeQoverPt_ / numBinsQoverPt_; - - const int baseShiftQoverPt = widthQoverPtBin_ - settings->widthQoverPt_; - - baseQoverPt = baseQoverPtBin_ * pow(2., baseShiftQoverPt); - - const double basePhiT = baseSector_ / numBinsPhiT_; - - const double baseRgen = basePhiT / baseQoverPtBin_; - const double rangeR = settings->outerRadius_ - settings->innerRadius_; - const int baseShiftR = ceil(log2(rangeR / baseRgen / pow(2., widthR))); - - baseR = baseRgen * pow(2., baseShiftR); - - const double rangeZ = 2. * halfLength_; - const int baseShiftZ = ceil(log2(rangeZ / baseR / pow(2., widthZ))); - - baseZ = baseR * pow(2., baseShiftZ); - - const double rangePhi = settings->baseRegion_ + settings->rangeQoverPt_ * baseR * pow(2., widthR) / 4.; - const int baseShiftPhi = ceil(log2(rangePhi / basePhiT / pow(2., widthPhi))); - - basePhi = basePhiT * pow(2., baseShiftPhi); - } - -} // namespace trackerDTC \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/Setup.cc b/L1Trigger/TrackerDTC/src/Setup.cc new file mode 100644 index 0000000000000..87febae598830 --- /dev/null +++ b/L1Trigger/TrackerDTC/src/Setup.cc @@ -0,0 +1,730 @@ +#include "L1Trigger/TrackerDTC/interface/Setup.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/Provenance/interface/ProcessConfiguration.h" +#include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h" +#include "DataFormats/L1TrackTrigger/interface/TTBV.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; + +namespace trackerDTC { + + Setup::Setup(const ParameterSet& iConfig, + const MagneticField& magneticField, + const TrackerGeometry& trackerGeometry, + const TrackerTopology& trackerTopology, + const TrackerDetToDTCELinkCablingMap& cablingMap, + const StubAlgorithmOfficial& stubAlgorithm, + const ParameterSet& pSetStubAlgorithm, + const ParameterSet& pSetGeometryConfiguration, + const ParameterSetID& pSetIdTTStubAlgorithm, + const ParameterSetID& pSetIdGeometryConfiguration) + : magneticField_(&magneticField), + trackerGeometry_(&trackerGeometry), + trackerTopology_(&trackerTopology), + cablingMap_(&cablingMap), + stubAlgorithm_(&stubAlgorithm), + pSetSA_(&pSetStubAlgorithm), + pSetGC_(&pSetGeometryConfiguration), + pSetIdTTStubAlgorithm_(pSetIdTTStubAlgorithm), + pSetIdGeometryConfiguration_(pSetIdGeometryConfiguration), + // Parameter to check if configured Tracker Geometry is supported + pSetSG_(iConfig.getParameter("SupportedGeometry")), + sgXMLLabel_(pSetSG_.getParameter("XMLLabel")), + sgXMLPath_(pSetSG_.getParameter("XMLPath")), + sgXMLFile_(pSetSG_.getParameter("XMLFile")), + sgXMLVersions_(pSetSG_.getParameter>("XMLVersions")), + // Parameter to check if Process History is consistent with process configuration + pSetPH_(iConfig.getParameter("ProcessHistory")), + phGeometryConfiguration_(pSetPH_.getParameter("GeometryConfiguration")), + phTTStubAlgorithm_(pSetPH_.getParameter("TTStubAlgorithm")), + // Common track finding parameter + pSetTF_(iConfig.getParameter("TrackFinding")), + beamWindowZ_(pSetTF_.getParameter("BeamWindowZ")), + matchedLayers_(pSetTF_.getParameter("MatchedLayers")), + matchedLayersPS_(pSetTF_.getParameter("MatchedLayersPS")), + unMatchedStubs_(pSetTF_.getParameter("UnMatchedStubs")), + unMatchedStubsPS_(pSetTF_.getParameter("UnMatchedStubsPS")), + // TMTT specific parameter + pSetTMTT_(iConfig.getParameter("TMTT")), + minPt_(pSetTMTT_.getParameter("MinPt")), + maxEta_(pSetTMTT_.getParameter("MaxEta")), + chosenRofPhi_(pSetTMTT_.getParameter("ChosenRofPhi")), + numLayers_(pSetTMTT_.getParameter("NumLayers")), + widthR_(pSetTMTT_.getParameter("WidthR")), + widthPhi_(pSetTMTT_.getParameter("WidthPhi")), + widthZ_(pSetTMTT_.getParameter("WidthZ")), + // Hybrid specific parameter + pSetHybrid_(iConfig.getParameter("Hybrid")), + hybridMinPt_(pSetHybrid_.getParameter("MinPt")), + hybridMaxEta_(pSetHybrid_.getParameter("MaxEta")), + hybridChosenRofPhi_(pSetHybrid_.getParameter("ChosenRofPhi")), + hybridNumLayers_(pSetHybrid_.getParameter("NumLayers")), + hybridNumRingsPS_(pSetHybrid_.getParameter>("NumRingsPS")), + hybridWidthsR_(pSetHybrid_.getParameter>("WidthsR")), + hybridWidthsZ_(pSetHybrid_.getParameter>("WidthsZ")), + hybridWidthsPhi_(pSetHybrid_.getParameter>("WidthsPhi")), + hybridWidthsAlpha_(pSetHybrid_.getParameter>("WidthsAlpha")), + hybridWidthsBend_(pSetHybrid_.getParameter>("WidthsBend")), + hybridRangesR_(pSetHybrid_.getParameter>("RangesR")), + hybridRangesZ_(pSetHybrid_.getParameter>("RangesZ")), + hybridRangesAlpha_(pSetHybrid_.getParameter>("RangesAlpha")), + hybridLayerRs_(pSetHybrid_.getParameter>("LayerRs")), + hybridDiskZs_(pSetHybrid_.getParameter>("DiskZs")), + hybridDisk2SRsSet_(pSetHybrid_.getParameter>("Disk2SRsSet")), + // Parameter specifying TrackingParticle used for Efficiency measurements + pSetTP_(iConfig.getParameter("TrackingParticle")), + tpMaxEta_(pSetTP_.getParameter("MaxEta")), + tpMaxVertR_(pSetTP_.getParameter("MaxVertR")), + tpMaxVertZ_(pSetTP_.getParameter("MaxVertZ")), + tpMaxD0_(pSetTP_.getParameter("MaxD0")), + tpMinLayers_(pSetTP_.getParameter("MinLayers")), + tpMinLayersPS_(pSetTP_.getParameter("MinLayersPS")), + // Fimrware specific Parameter + pSetFW_(iConfig.getParameter("Firmware")), + numFramesInfra_(pSetFW_.getParameter("NumFramesInfra")), + freqLHC_(pSetFW_.getParameter("FreqLHC")), + freqBE_(pSetFW_.getParameter("FreqBE")), + tmpFE_(pSetFW_.getParameter("TMP_FE")), + tmpTFP_(pSetFW_.getParameter("TMP_TFP")), + speedOfLight_(pSetFW_.getParameter("SpeedOfLight")), + bField_(pSetFW_.getParameter("BField")), + bFieldError_(pSetFW_.getParameter("BFieldError")), + outerRadius_(pSetFW_.getParameter("OuterRadius")), + innerRadius_(pSetFW_.getParameter("InnerRadius")), + halfLength_(pSetFW_.getParameter("HalfLength")), + maxPitch_(pSetFW_.getParameter("MaxPitch")), + // Parmeter specifying front-end + pSetFE_(iConfig.getParameter("FrontEnd")), + widthBend_(pSetFE_.getParameter("WidthBend")), + widthCol_(pSetFE_.getParameter("WidthCol")), + widthRow_(pSetFE_.getParameter("WidthRow")), + baseBend_(pSetFE_.getParameter("BaseBend")), + baseCol_(pSetFE_.getParameter("BaseCol")), + baseRow_(pSetFE_.getParameter("BaseRow")), + baseWindowSize_(pSetFE_.getParameter("BaseWindowSize")), + bendCut_(pSetFE_.getParameter("BendCut")), + // Parmeter specifying DTC + pSetDTC_(iConfig.getParameter("DTC")), + numRegions_(pSetDTC_.getParameter("NumRegions")), + numOverlappingRegions_(pSetDTC_.getParameter("NumOverlappingRegions")), + numATCASlots_(pSetDTC_.getParameter("NumATCASlots")), + numDTCsPerRegion_(pSetDTC_.getParameter("NumDTCsPerRegion")), + numModulesPerDTC_(pSetDTC_.getParameter("NumModulesPerDTC")), + dtcNumRoutingBlocks_(pSetDTC_.getParameter("NumRoutingBlocks")), + dtcDepthMemory_(pSetDTC_.getParameter("DepthMemory")), + dtcWidthRowLUT_(pSetDTC_.getParameter("WidthRowLUT")), + dtcWidthQoverPt_(pSetDTC_.getParameter("WidthQoverPt")), + offsetDetIdDSV_(pSetDTC_.getParameter("OffsetDetIdDSV")), + offsetDetIdTP_(pSetDTC_.getParameter("OffsetDetIdTP")), + offsetLayerDisks_(pSetDTC_.getParameter("OffsetLayerDisks")), + offsetLayerId_(pSetDTC_.getParameter("OffsetLayerId")), + // Parmeter specifying GeometricProcessor + pSetGP_(iConfig.getParameter("GeometricProcessor")), + numSectorsPhi_(pSetGP_.getParameter("NumSectorsPhi")), + chosenRofZ_(pSetGP_.getParameter("ChosenRofZ")), + neededRangeChiZ_(pSetGP_.getParameter("RangeChiZ")), + gpDepthMemory_(pSetGP_.getParameter("DepthMemory")), + boundariesEta_(pSetGP_.getParameter>("BoundariesEta")), + // Parmeter specifying HoughTransform + pSetHT_(iConfig.getParameter("HoughTransform")), + htNumBinsQoverPt_(pSetHT_.getParameter("NumBinsQoverPt")), + htNumBinsPhiT_(pSetHT_.getParameter("NumBinsPhiT")), + htMinLayers_(pSetHT_.getParameter("MinLayers")), + htDepthMemory_(pSetHT_.getParameter("DepthMemory")), + // Parmeter specifying MiniHoughTransform + pSetMHT_(iConfig.getParameter("MiniHoughTransform")), + mhtNumBinsQoverPt_(pSetMHT_.getParameter("NumBinsQoverPt")), + mhtNumBinsPhiT_(pSetMHT_.getParameter("NumBinsPhiT")), + mhtNumDLB_(pSetMHT_.getParameter("NumDLB")), + mhtMinLayers_(pSetMHT_.getParameter("MinLayers")), + // Parmeter specifying SeedFilter + pSetSF_(iConfig.getParameter("SeedFilter")), + sfPowerBaseCot_(pSetSF_.getParameter("PowerBaseCot")), + sfBaseDiffZ_(pSetSF_.getParameter("BaseDiffZ")), + sfMinLayers_(pSetSF_.getParameter("MinLayers")), + // Parmeter specifying KalmanFilter + pSetKF_(iConfig.getParameter("KalmanFilter")), + kfWidthLutInvPhi_(pSetKF_.getParameter("WidthLutInvPhi")), + kfWidthLutInvZ_(pSetKF_.getParameter("WidthLutInvZ")), + kfNumTracks_(pSetKF_.getParameter("NumTracks")), + kfMinLayers_(pSetKF_.getParameter("MinLayers")), + kfMaxLayers_(pSetKF_.getParameter("MaxLayers")), + kfMaxStubsPerLayer_(pSetKF_.getParameter("MaxStubsPerLayer")), + kfMaxSkippedLayers_(pSetKF_.getParameter("MaxSkippedLayers")), + kfBaseShiftr0_(pSetKF_.getParameter("BaseShiftr0")), + kfBaseShiftr02_(pSetKF_.getParameter("BaseShiftr02")), + kfBaseShiftv0_(pSetKF_.getParameter("BaseShiftv0")), + kfBaseShiftS00_(pSetKF_.getParameter("BaseShiftS00")), + kfBaseShiftS01_(pSetKF_.getParameter("BaseShiftS01")), + kfBaseShiftK00_(pSetKF_.getParameter("BaseShiftK00")), + kfBaseShiftK10_(pSetKF_.getParameter("BaseShiftK10")), + kfBaseShiftR00_(pSetKF_.getParameter("BaseShiftR00")), + kfBaseShiftInvR00_(pSetKF_.getParameter("BaseShiftInvR00")), + kfBaseShiftChi20_(pSetKF_.getParameter("BaseShiftChi20")), + kfBaseShiftC00_(pSetKF_.getParameter("BaseShiftC00")), + kfBaseShiftC01_(pSetKF_.getParameter("BaseShiftC01")), + kfBaseShiftC11_(pSetKF_.getParameter("BaseShiftC11")), + kfBaseShiftr1_(pSetKF_.getParameter("BaseShiftr1")), + kfBaseShiftr12_(pSetKF_.getParameter("BaseShiftr12")), + kfBaseShiftv1_(pSetKF_.getParameter("BaseShiftv1")), + kfBaseShiftS12_(pSetKF_.getParameter("BaseShiftS12")), + kfBaseShiftS13_(pSetKF_.getParameter("BaseShiftS13")), + kfBaseShiftK21_(pSetKF_.getParameter("BaseShiftK21")), + kfBaseShiftK31_(pSetKF_.getParameter("BaseShiftK31")), + kfBaseShiftR11_(pSetKF_.getParameter("BaseShiftR11")), + kfBaseShiftInvR11_(pSetKF_.getParameter("BaseShiftInvR11")), + kfBaseShiftChi21_(pSetKF_.getParameter("BaseShiftChi21")), + kfBaseShiftC22_(pSetKF_.getParameter("BaseShiftC22")), + kfBaseShiftC23_(pSetKF_.getParameter("BaseShiftC23")), + kfBaseShiftC33_(pSetKF_.getParameter("BaseShiftC33")), + kfBaseShiftChi2_(pSetKF_.getParameter("BaseShiftChi2")), + // Parmeter specifying DuplicateRemoval + pSetDR_(iConfig.getParameter("DuplicateRemoval")), + drDepthMemory_(pSetDR_.getParameter("DepthMemory")), + drWidthPhi0_(pSetDR_.getParameter("WidthPhi0")), + drWidthQoverPt_(pSetDR_.getParameter("WidthQoverPt")), + drWidthCot_(pSetDR_.getParameter("WidthCot")), + drWidthZ0_(pSetDR_.getParameter("WidthZ0")) { + configurationSupported_ = true; + // check if bField is supported + checkMagneticField(); + // check if geometry is supported + checkGeometry(); + if (!configurationSupported_) + return; + // derive constants + calculateConstants(); + // convert configuration of TTStubAlgorithm + consumeStubAlgorithm(); + // create all possible encodingsBend + encodingsBendPS_.reserve(maxWindowSize_ + 1); + encodingsBend2S_.reserve(maxWindowSize_ + 1); + encodeBend(encodingsBendPS_, true); + encodeBend(encodingsBend2S_, false); + // create encodingsLayerId + encodingsLayerId_.reserve(numDTCsPerRegion_); + encodeLayerId(); + // create sensor modules + produceSensorModules(); + } + + // checks current configuration vs input sample configuration + void Setup::checkHistory(const ProcessHistory& processHistory) const { + const pset::Registry* psetRegistry = pset::Registry::instance(); + // check used TTStubAlgorithm in input producer + checkHistory(processHistory, psetRegistry, phTTStubAlgorithm_, pSetIdTTStubAlgorithm_); + // check used GeometryConfiguration in input producer + checkHistory(processHistory, psetRegistry, phGeometryConfiguration_, pSetIdGeometryConfiguration_); + } + + // checks consitency between history and current configuration for a specific module + void Setup::checkHistory(const ProcessHistory& ph, + const pset::Registry* pr, + const string& label, + const ParameterSetID& pSetId) const { + vector> pSets; + pSets.reserve(ph.size()); + for (const ProcessConfiguration& pc : ph) { + const ParameterSet* pSet = pr->getMapped(pc.parameterSetID()); + if (pSet && pSet->exists(label)) + pSets.emplace_back(pc.processName(), pSet->getParameterSet(label)); + } + if (pSets.empty()) { + cms::Exception exception("BadConfiguration"); + exception << label << " not found in process history."; + exception.addContext("tt::Setup::checkHistory"); + throw exception; + } + auto consistent = [&pSetId](const pair& p) { return p.second.id() == pSetId; }; + if (!all_of(pSets.begin(), pSets.end(), consistent)) { + const ParameterSet& pSetProcess = getParameterSet(pSetId); + cms::Exception exception("BadConfiguration"); + exception.addContext("tt::Setup::checkHistory"); + exception << label << " inconsistent with History." << endl; + exception << "Current Configuration:" << endl << pSetProcess.dump() << endl; + for (const pair& p : pSets) + if (!consistent(p)) + exception << "Process " << p.first << " Configuration:" << endl << dumpDiff(p.second, pSetProcess) << endl; + throw exception; + } + } + + // dumps pSetHistory where incosistent lines with pSetProcess are highlighted + string Setup::dumpDiff(const ParameterSet& pSetHistory, const ParameterSet& pSetProcess) const { + stringstream ssHistory, ssProcess, ss; + ssHistory << pSetHistory.dump(); + ssProcess << pSetProcess.dump(); + string lineHistory, lineProcess; + for (; getline(ssHistory, lineHistory) && getline(ssProcess, lineProcess);) + ss << (lineHistory != lineProcess ? "\033[1;31m" : "") << lineHistory << "\033[0m" << endl; + return ss.str(); + } + + // converts tk layout id into dtc id + int Setup::dtcId(int tkLayoutId) const { + checkTKLayoutId(tkLayoutId); + const int tkId = tkLayoutId - 1; + const int side = tkId / (numRegions_ * numATCASlots_); + const int region = (tkId % (numRegions_ * numATCASlots_)) / numATCASlots_; + const int slot = tkId % numATCASlots_; + return region * numDTCsPerRegion_ + side * numATCASlots_ + slot; + } + + // converts dtc id into tk layout id + int Setup::tkLayoutId(int dtcId) const { + checkDTCId(dtcId); + const int slot = dtcId % numATCASlots_; + const int region = dtcId / numDTCsPerRegion_; + const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_; + return (side * numRegions_ + region) * numATCASlots_ + slot + 1; + } + + // converts TFP identifier (region[0-8], channel[0-47]) into dtc id + int Setup::dtcId(int tfpRegion, int tfpChannel) const { + checkTFPIdentifier(tfpRegion, tfpChannel); + const int dtcChannel = numOverlappingRegions_ - (tfpChannel / numDTCsPerRegion_) - 1; + const int dtcBoard = tfpChannel % numDTCsPerRegion_; + const int dtcRegion = tfpRegion - dtcChannel >= 0 ? tfpRegion - dtcChannel : tfpRegion - dtcChannel + numRegions_; + return dtcRegion * numDTCsPerRegion_ + dtcBoard; + } + + // checks if given DTC id is connected to PS or 2S sensormodules + bool Setup::psModule(int dtcId) const { + checkDTCId(dtcId); + // from tklayout: first 3 are 10 gbps PS, next 3 are 5 gbps PS and residual 6 are 5 gbps 2S modules + return slot(dtcId) < numATCASlots_ / 2; + } + + // checks if given dtcId is connected to -z (false) or +z (true) + bool Setup::side(int dtcId) const { + checkDTCId(dtcId); + const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_; + // from tkLayout: first 12 +z, next 12 -z + return side == 0; + } + + // ATCA slot number [0-11] of given dtcId + int Setup::slot(int dtcId) const { + checkDTCId(dtcId); + return dtcId % numATCASlots_; + } + + // sensor module for det id + SensorModule* Setup::sensorModule(const DetId& detId) const { + const auto it = detIdToSensorModule_.find(detId); + if (it == detIdToSensorModule_.end()) { + cms::Exception exception("NullPtr"); + exception << "Unknown DetId used."; + exception.addContext("tt::Setup::sensorModule"); + throw exception; + } + return it->second; + } + + // index = encoded bend, value = decoded bend for given window size and module type + const vector& Setup::encodingBend(int windowSize, bool psModule) const { + const vector>& encodingsBend = psModule ? encodingsBendPS_ : encodingsBend2S_; + return encodingsBend.at(windowSize); + } + + // index = encoded layerId, inner value = decoded layerId for given dtcId or tfp channel + const vector& Setup::encodingLayerId(int dtcId) const { + const int index = dtcId % numDTCsPerRegion_; + return encodingsLayerId_.at(index); + } + + // check if bField is supported + void Setup::checkMagneticField() { + const double bFieldES = magneticField_->inTesla(GlobalPoint(0., 0., 0.)).z(); + if (abs(bField_ - bFieldES) > bFieldError_) { + configurationSupported_ = false; + LogWarning("ConfigurationNotSupported") + << "Magnetic Field from EventSetup (" << bFieldES << ") differs more then " << bFieldError_ + << " from supported value (" << bField_ << "). "; + } + } + + // check if geometry is supported + void Setup::checkGeometry() { + const vector& geomXMLFiles = pSetGC_->getParameter>(sgXMLLabel_); + string version; + for (const string& geomXMLFile : geomXMLFiles) { + const auto begin = geomXMLFile.find(sgXMLPath_) + sgXMLPath_.size(); + const auto end = geomXMLFile.find(sgXMLFile_); + if (begin != string::npos && end != string::npos) + version = geomXMLFile.substr(begin, end - begin - 1); + } + if (version.empty()) { + cms::Exception exception("LogicError"); + exception << "No " << sgXMLPath_ << "*/" << sgXMLFile_ << " found in GeometryConfiguration"; + exception.addContext("tt::Setup::checkGeometry"); + throw exception; + } + if (find(sgXMLVersions_.begin(), sgXMLVersions_.end(), version) == sgXMLVersions_.end()) { + configurationSupported_ = false; + LogWarning("ConfigurationNotSupported") + << "Geometry Configuration " << sgXMLPath_ << version << "/" << sgXMLFile_ << " is not supported. "; + } + } + + // convert configuration of TTStubAlgorithm + void Setup::consumeStubAlgorithm() { + numTiltedLayerRings_ = pSetSA_->getParameter>("NTiltedRings"); + windowSizeBarrelLayers_ = pSetSA_->getParameter>("BarrelCut"); + const auto& pSetsTiltedLayer = pSetSA_->getParameter>("TiltedBarrelCutSet"); + const auto& pSetsEncapDisks = pSetSA_->getParameter>("EndcapCutSet"); + windowSizeTiltedLayerRings_.reserve(pSetsTiltedLayer.size()); + for (const auto& pSet : pSetsTiltedLayer) + windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter>("TiltedCut")); + windowSizeEndcapDisksRings_.reserve(pSetsEncapDisks.size()); + for (const auto& pSet : pSetsEncapDisks) + windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter>("EndcapCut")); + maxWindowSize_ = -1; + for (const auto& windowss : {windowSizeTiltedLayerRings_, windowSizeEndcapDisksRings_, {windowSizeBarrelLayers_}}) + for (const auto& windows : windowss) + for (const auto& window : windows) + maxWindowSize_ = max(maxWindowSize_, (int)(window / baseWindowSize_)); + } + + // create bend encodings + void Setup::encodeBend(vector>& encodings, bool ps) const { + for (int window = 0; window < maxWindowSize_ + 1; window++) { + set encoding; + for (int bend = 0; bend < window + 1; bend++) + encoding.insert(stubAlgorithm_->degradeBend(ps, window, bend)); + encodings.emplace_back(encoding.begin(), encoding.end()); + } + } + + // create encodingsLayerId + void Setup::encodeLayerId() { + vector> dtcELinkIds(numDTCs_); + for (vector& dtcELinkId : dtcELinkIds) + dtcELinkId.reserve(numModulesPerDTC_); + for (const DTCELinkId& dtcLinkId : cablingMap_->getKnownDTCELinkIds()) + dtcELinkIds[dtcId(dtcLinkId.dtc_id())].push_back(dtcLinkId); + for (int dtcBoard = 0; dtcBoard < numDTCsPerRegion_; dtcBoard++) { + set encodingLayerId; + for (int region = 0; region < numRegions_; region++) { + const int dtcId = region * numDTCsPerRegion_ + dtcBoard; + for (const DTCELinkId& dtcLinkId : dtcELinkIds[dtcId]) { + const DetId& detId = cablingMap_->dtcELinkIdToDetId(dtcLinkId)->second; + const bool barrel = detId.subdetId() == StripSubdetector::TOB; + const int layerId = + barrel ? trackerTopology_->layer(detId) : trackerTopology_->tidWheel(detId) + offsetLayerDisks_; + encodingLayerId.insert(layerId); + } + } + // check configuration + if ((int)encodingLayerId.size() > hybridNumLayers_) { + cms::Exception exception("overflow"); + exception << "Cabling map connects more than " << hybridNumLayers_ << " layers to a DTC."; + exception.addContext("tt::Setup::Setup"); + throw exception; + } + encodingsLayerId_.emplace_back(encodingLayerId.begin(), encodingLayerId.end()); + } + } + + // create sensor modules + void Setup::produceSensorModules() { + sensorModules_.reserve(numModules_); + dtcModules_ = vector>(numDTCs_); + for (vector& dtcModules : dtcModules_) + dtcModules.reserve(numModulesPerDTC_); + // loop over all tracker modules + for (const DetId& detId : trackerGeometry_->detIds()) { + // skip pixel detector + if (detId.subdetId() == PixelSubdetector::PixelBarrel || detId.subdetId() == PixelSubdetector::PixelEndcap) + continue; + // skip multiple detIds per module + if (!trackerTopology_->isLower(detId)) + continue; + // lowerDetId - 1 = tk layout det id + const DetId detIdTkLayout = detId + offsetDetIdTP_; + // tk layout dtc id, lowerDetId - 1 = tk lyout det id + const int tklId = cablingMap_->detIdToDTCELinkId(detIdTkLayout).first->second.dtc_id(); + // track trigger dtc id [0-215] + const int dtcId = Setup::dtcId(tklId); + // collection of so far connected modules to this dtc + vector& dtcModules = dtcModules_[dtcId]; + // construct sendor module + sensorModules_.emplace_back(*this, detId, dtcId, dtcModules.size()); + SensorModule* sensorModule = &sensorModules_.back(); + // store connection between detId and sensor module + detIdToSensorModule_.emplace(detId, sensorModule); + // store connection between dtcId and sensor module + dtcModules.push_back(sensorModule); + } + for (vector& dtcModules : dtcModules_) { + dtcModules.shrink_to_fit(); + // check configuration + if ((int)dtcModules.size() > numModulesPerDTC_) { + cms::Exception exception("overflow"); + exception << "Cabling map connects more than " << numModulesPerDTC_ << " modules to a DTC."; + exception.addContext("tt::Setup::Setup"); + throw exception; + } + } + } + + // derive constants + void Setup::calculateConstants() { + // emp + const int numFramesPerBX = freqBE_ / freqLHC_; + numFrames_ = numFramesPerBX * tmpTFP_ - 1; + numFramesIO_ = numFramesPerBX * tmpTFP_ - numFramesInfra_; + numFramesFE_ = numFramesPerBX * tmpFE_ - numFramesInfra_; + // common track finding + invPtToDphi_ = speedOfLight_ * bField_ / 2000.; + baseRegion_ = 2. * M_PI / numRegions_; + // gp + baseSector_ = baseRegion_ / numSectorsPhi_; + maxCot_ = sinh(maxEta_); + maxZT_ = maxCot_ * chosenRofZ_; + numSectorsEta_ = boundariesEta_.size() - 1; + widthSectorEta_ = ceil(log2(numSectorsEta_)); + widthChiZ_ = ceil(log2(neededRangeChiZ_ / baseZ_)); + // ht + htWidthQoverPt_ = ceil(log2(htNumBinsQoverPt_)); + htWidthPhiT_ = ceil(log2(htNumBinsPhiT_)); + const double rangeQoverPt = 2. * invPtToDphi_ / minPt_; + htBaseQoverPt_ = rangeQoverPt / htNumBinsQoverPt_; + htBasePhiT_ = baseSector_ / htNumBinsPhiT_; + // tmtt + widthLayer_ = ceil(log2(numLayers_)); + const double baseRgen = htBasePhiT_ / htBaseQoverPt_; + const double rangeR = 2. * max(abs(outerRadius_ - chosenRofPhi_), abs(innerRadius_ - chosenRofPhi_)); + const int baseShiftR = ceil(log2(rangeR / baseRgen / pow(2., widthR_))); + baseR_ = baseRgen * pow(2., baseShiftR); + const double rangeZ = 2. * halfLength_; + const int baseShiftZ = ceil(log2(rangeZ / baseR_ / pow(2., widthZ_))); + baseZ_ = baseR_ * pow(2., baseShiftZ); + const double rangePhiDTC = baseRegion_ + rangeQoverPt * baseR_ * pow(2., widthR_) / 4.; + widthPhiDTC_ = widthPhi_ + ceil(log2(rangePhiDTC / baseRegion_)); + const int baseShiftPhi = ceil(log2(rangePhiDTC / htBasePhiT_ / pow(2., widthPhiDTC_))); + basePhi_ = htBasePhiT_ * pow(2., baseShiftPhi); + const double neededRangeChiPhi = 2. * htBasePhiT_; + widthChiPhi_ = ceil(log2(neededRangeChiPhi / basePhi_)); + // hybrid + const double hybridRangeQoverPt = 2. * invPtToDphi_ / hybridMinPt_; + const double hybridRangeR = + 2. * max(abs(outerRadius_ - hybridChosenRofPhi_), abs(innerRadius_ - hybridChosenRofPhi_)); + const double hybridRangePhi = baseRegion_ + hybridRangeR * hybridRangeQoverPt / 2.; + hybridWidthLayer_ = ceil(log2(hybridNumLayers_)); + hybridBasesZ_.reserve(SensorModule::NumTypes); + for (int type = 0; type < SensorModule::NumTypes; type++) + hybridBasesZ_.emplace_back(hybridRangesZ_.at(type) / pow(2., hybridWidthsZ_.at(type))); + hybridBasesR_.reserve(SensorModule::NumTypes); + for (int type = 0; type < SensorModule::NumTypes; type++) + hybridBasesR_.emplace_back(hybridRangesR_.at(type) / pow(2., hybridWidthsR_.at(type))); + hybridBasesR_[SensorModule::Disk2S] = 1.; + hybridBasesPhi_.reserve(SensorModule::NumTypes); + for (int type = 0; type < SensorModule::NumTypes; type++) + hybridBasesPhi_.emplace_back(hybridRangePhi / pow(2., hybridWidthsPhi_.at(type))); + hybridBasesAlpha_.reserve(SensorModule::NumTypes); + for (int type = 0; type < SensorModule::NumTypes; type++) + hybridBasesAlpha_.emplace_back(hybridRangesAlpha_.at(type) / pow(2., hybridWidthsAlpha_.at(type))); + hybridNumsUnusedBits_.reserve(SensorModule::NumTypes); + for (int type = 0; type < SensorModule::NumTypes; type++) + hybridNumsUnusedBits_.emplace_back(TTBV::S - hybridWidthsR_.at(type) - hybridWidthsZ_.at(type) - + hybridWidthsPhi_.at(type) - hybridWidthsAlpha_.at(type) - + hybridWidthsBend_.at(type) - hybridWidthLayer_ - 1); + hybridMaxCot_ = sinh(hybridMaxEta_); + disk2SRs_.reserve(hybridDisk2SRsSet_.size()); + for (const auto& pSet : hybridDisk2SRsSet_) + disk2SRs_.emplace_back(pSet.getParameter>("Disk2SRs")); + // dtc + numDTCs_ = numRegions_ * numDTCsPerRegion_; + numDTCsPerTFP_ = numDTCsPerRegion_ * numOverlappingRegions_; + numModules_ = numDTCs_ * numModulesPerDTC_; + dtcNumModulesPerRoutingBlock_ = numModulesPerDTC_ / dtcNumRoutingBlocks_; + dtcNumMergedRows_ = pow(2, widthRow_ - dtcWidthRowLUT_); + const double maxRangeQoverPt = max(rangeQoverPt, hybridRangeQoverPt); + const int baseShiftQoverPt = htWidthQoverPt_ - dtcWidthQoverPt_ + ceil(log2(maxRangeQoverPt / rangeQoverPt)); + dtcBaseQoverPt_ = htBaseQoverPt_ * pow(2., baseShiftQoverPt); + const int baseDiffM = dtcWidthRowLUT_ - widthRow_; + dtcBaseM_ = basePhi_ * pow(2., baseDiffM); + const double x1 = pow(2, widthRow_) * baseRow_ * maxPitch_ / 2.; + const double x0 = x1 - pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitch_; + const double maxM = atan2(x1, innerRadius_) - atan2(x0, innerRadius_); + dtcWidthM_ = ceil(log2(maxM / dtcBaseM_)); + dtcNumUnusedBits_ = TTBV::S - 1 - widthR_ - widthPhiDTC_ - widthZ_ - 2 * htWidthQoverPt_ - 2 * widthSectorEta_ - + numSectorsPhi_ - widthLayer_; + // mht + mhtNumCells_ = mhtNumBinsQoverPt_ * mhtNumBinsPhiT_; + mhtWidthQoverPt_ = ceil(log2(htNumBinsQoverPt_ * mhtNumBinsQoverPt_)); + mhtWidthPhiT_ = ceil(log2(htNumBinsPhiT_ * mhtNumBinsPhiT_)); + mhtBaseQoverPt_ = htBaseQoverPt_ / mhtNumBinsQoverPt_; + mhtBasePhiT_ = htBasePhiT_ / mhtNumBinsPhiT_; + // SF + sfBaseCot_ = pow(2, sfPowerBaseCot_); + sfBaseZT_ = baseZ_ * pow(2, sfBaseDiffZ_); + // DR + drBaseQoverPt_ = htBaseQoverPt_ * pow(2, htWidthQoverPt_ - drWidthQoverPt_); + drBasePhi0_ = basePhi_ * pow(2, widthPhiDTC_ - drWidthPhi0_); + drBaseCot_ = floor(log2(2. * maxCot_ * pow(2, -drWidthCot_))); + drBaseZ0_ = baseZ_ * pow(2, ceil(log2(2. * beamWindowZ_ / baseZ_)) - drWidthZ0_); + // KF + kfBasex0_ = drBaseQoverPt_; + kfBasex1_ = drBasePhi0_; + kfBasex2_ = drBaseCot_; + kfBasex3_ = drBaseZ0_; + kfBasem0_ = basePhi_; + kfBasem1_ = baseZ_; + kfBaseH00_ = baseR_; + kfBaseH12_ = baseR_; + kfBaseChi2_ = pow(2, kfBaseShiftChi2_); + kfBaser0_ = pow(2, kfBaseShiftr0_) * kfBasex1_; + kfBaser02_ = pow(2, kfBaseShiftr02_) * kfBasex1_ * kfBasex1_; + kfBasev0_ = pow(2, kfBaseShiftv0_) * kfBasex1_ * kfBasex1_; + kfBaseS00_ = pow(2, kfBaseShiftS00_) * kfBasex0_ * kfBasex1_; + kfBaseS01_ = pow(2, kfBaseShiftS01_) * kfBasex1_ * kfBasex1_; + kfBaseK00_ = pow(2, kfBaseShiftK00_) * kfBasex0_ / kfBasex1_; + kfBaseK10_ = pow(2, kfBaseShiftK10_); + kfBaseR00_ = pow(2, kfBaseShiftR00_) * kfBasex1_ * kfBasex1_; + kfBaseInvR00_ = pow(2, kfBaseShiftInvR00_) / kfBasex1_ / kfBasex1_; + kfBaseChi20_ = pow(2, kfBaseShiftChi20_); + kfBaseC00_ = pow(2, kfBaseShiftC00_) * kfBasex0_ * kfBasex0_; + kfBaseC01_ = pow(2, kfBaseShiftC01_) * kfBasex0_ * kfBasex1_; + kfBaseC11_ = pow(2, kfBaseShiftC11_) * kfBasex1_ * kfBasex1_; + kfBaser1_ = pow(2, kfBaseShiftr1_) * kfBasex3_; + kfBaser12_ = pow(2, kfBaseShiftr12_) * kfBasex3_ * kfBasex3_; + kfBasev1_ = pow(2, kfBaseShiftv1_) * kfBasex3_ * kfBasex3_; + kfBaseS12_ = pow(2, kfBaseShiftS12_) * kfBasex2_ * kfBasex3_; + kfBaseS13_ = pow(2, kfBaseShiftS13_) * kfBasex3_ * kfBasex3_; + kfBaseK21_ = pow(2, kfBaseShiftK21_) * kfBasex2_ / kfBasex3_; + kfBaseK31_ = pow(2, kfBaseShiftK31_); + kfBaseR11_ = pow(2, kfBaseShiftR11_) * kfBasex3_ * kfBasex3_; + kfBaseInvR11_ = pow(2, kfBaseShiftInvR11_) / kfBasex3_ / kfBasex3_; + kfBaseChi21_ = pow(2, kfBaseShiftChi21_); + kfBaseC22_ = pow(2, kfBaseShiftC22_) * kfBasex2_ * kfBasex2_; + kfBaseC23_ = pow(2, kfBaseShiftC23_) * kfBasex2_ * kfBasex3_; + kfBaseC33_ = pow(2, kfBaseShiftC33_) * kfBasex3_ * kfBasex3_; + } + + // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47] + GlobalPoint Setup::stubPos(bool hybrid, const TTDTC::Frame& frame, int tfpRegion, int tfpChannel) const { + GlobalPoint p; + if (frame.first.isNull()) + return p; + TTBV bv(frame.second); + if (hybrid) { + const DetId& detId = frame.first->getDetId(); + const int dtcId = Setup::dtcId(tfpRegion, tfpChannel); + const bool barrel = detId.subdetId() == StripSubdetector::TOB; + const bool psModule = Setup::psModule(dtcId); + const int layerId = + (barrel ? trackerTopology_->layer(detId) : trackerTopology_->tidWheel(detId)) - offsetLayerId_; + const bool side = Setup::side(dtcId); + SensorModule::Type type; + if (barrel && psModule) + type = SensorModule::BarrelPS; + if (barrel && !psModule) + type = SensorModule::Barrel2S; + if (!barrel && psModule) + type = SensorModule::DiskPS; + if (!barrel && !psModule) + type = SensorModule::Disk2S; + const int widthBend = hybridWidthsBend_.at(type); + const int widthAlpha = hybridWidthsAlpha_.at(type); + const int widthPhi = hybridWidthsPhi_.at(type); + const int widthZ = hybridWidthsZ_.at(type); + const int widthR = hybridWidthsR_.at(type); + const double basePhi = hybridBasesPhi_.at(type); + const double baseZ = hybridBasesZ_.at(type); + const double baseR = hybridBasesR_.at(type); + // parse bit vector + bv >>= 1 + hybridWidthLayer_ + widthBend + widthAlpha; + double phi = (bv.val(widthPhi, 0, true) + .5) * basePhi; + bv >>= widthPhi; + double z = (bv.val(widthZ, 0, true) + .5) * baseZ; + bv >>= widthZ; + double r = (bv.val(widthR, 0, barrel) + .5) * baseR; + if (barrel) { + r += hybridLayerRs_.at(layerId); + } else { + z += hybridDiskZs_.at(layerId) * (side ? 1. : -1.); + } + phi = deltaPhi(phi + tfpRegion * baseRegion_); + if (type == SensorModule::Disk2S) { + r = bv.val(widthR); + r = disk2SRs_.at(layerId).at((int)r); + } + p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); + } else { + bv >>= 2 * htWidthQoverPt_ + 2 * widthSectorEta_ + numSectorsPhi_ + widthLayer_; + double z = (bv.val(widthZ_, 0, true) + .5) * baseZ_; + bv >>= widthZ_; + double phi = (bv.val(widthPhiDTC_, 0, true) + .5) * basePhi_; + bv >>= widthPhiDTC_; + double r = (bv.val(widthR_, 0, true) + .5) * baseR_; + bv >>= widthR_; + r = r + chosenRofPhi_; + phi = deltaPhi(phi + tfpRegion * baseRegion_); + p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); + } + return p; + } + + // returns global TTStub position + GlobalPoint Setup::stubPos(const TTStubRef& ttStubRef) const { + const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_; + const GeomDetUnit* det = trackerGeometry_->idToDetUnit(detId); + const PixelTopology* topol = + dynamic_cast(&(dynamic_cast(det)->specificTopology())); + const Plane& plane = dynamic_cast(det)->surface(); + const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered(); + return plane.toGlobal(topol->localPosition(mp)); + } + + // range check of dtc id + void Setup::checkDTCId(int dtcId) const { + if (dtcId < 0 || dtcId >= numDTCsPerRegion_ * numRegions_) { + cms::Exception exception("out_of_range"); + exception.addContext("trackerDTC::Setup::checkDTCId"); + exception << "Used DTC Id (" << dtcId << ") " + << "is out of range 0 to " << numDTCsPerRegion_ * numRegions_ - 1 << "."; + throw exception; + } + } + + // range check of tklayout id + void Setup::checkTKLayoutId(int tkLayoutId) const { + if (tkLayoutId <= 0 || tkLayoutId > numDTCsPerRegion_ * numRegions_) { + cms::Exception exception("out_of_range"); + exception.addContext("trackerDTC::Setup::checkTKLayoutId"); + exception << "Used TKLayout Id (" << tkLayoutId << ") " + << "is out of range 1 to " << numDTCsPerRegion_ * numRegions_ << "."; + throw exception; + } + } + + // range check of tfp identifier + void Setup::checkTFPIdentifier(int tfpRegion, int tfpChannel) const { + const bool oorRegion = tfpRegion >= numRegions_ || tfpRegion < 0; + const bool oorChannel = tfpChannel >= numDTCsPerTFP_ || tfpChannel < 0; + if (oorRegion || oorChannel) { + cms::Exception exception("out_of_range"); + exception.addContext("trackerDTC::Setup::checkTFPIdentifier"); + if (oorRegion) + exception << "Requested Processing Region " + << "(" << tfpRegion << ") " + << "is out of range 0 to " << numRegions_ - 1 << "."; + if (oorChannel) + exception << "Requested TFP Channel " + << "(" << tfpChannel << ") " + << "is out of range 0 to " << numDTCsPerTFP_ - 1 << "."; + throw exception; + } + } + +} // namespace trackerDTC \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/SetupRcd.cc b/L1Trigger/TrackerDTC/src/SetupRcd.cc new file mode 100644 index 0000000000000..b407074e82c2b --- /dev/null +++ b/L1Trigger/TrackerDTC/src/SetupRcd.cc @@ -0,0 +1,4 @@ +#include "L1Trigger/TrackerDTC/interface/SetupRcd.h" +#include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h" + +EVENTSETUP_RECORD_REG(trackerDTC::SetupRcd); \ No newline at end of file diff --git a/L1Trigger/TrackerDTC/src/Stub.cc b/L1Trigger/TrackerDTC/src/Stub.cc index 5596b0ebc60eb..187c81bc20638 100644 --- a/L1Trigger/TrackerDTC/src/Stub.cc +++ b/L1Trigger/TrackerDTC/src/Stub.cc @@ -1,102 +1,101 @@ #include "L1Trigger/TrackerDTC/interface/Stub.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "L1Trigger/TrackerDTC/interface/Module.h" #include #include #include #include -#include +using namespace edm; using namespace std; namespace trackerDTC { - Stub::Stub(Settings* settings, Module* module, const TTStubRef& ttStubRef) - : settings_(settings), ttStubRef_(ttStubRef), module_(module), valid_(true) { - regions_.reserve(settings_->numOverlappingRegions()); + Stub::Stub(const ParameterSet& iConfig, const Setup& setup, SensorModule* sm, const TTStubRef& ttStubRef) + : setup_(&setup), sm_(sm), ttStubRef_(ttStubRef), hybrid_(iConfig.getParameter("UseHybrid")), valid_(true) { + regions_.reserve(setup.numOverlappingRegions()); // get stub local coordinates const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered(); // convert to uniformed local coordinates // column number in pitch units - col_ = (int)floor(pow(-1, module->signCol_) * (mp.y() - module->numColumns_ / 2) / settings_->baseCol()); + col_ = (int)floor(pow(-1, sm->signCol()) * (mp.y() - sm->numColumns() / 2) / setup.baseCol()); // row number in half pitch units - row_ = (int)floor(pow(-1, module->signRow_) * (mp.x() - module->numRows_ / 2) / settings_->baseRow()); + row_ = (int)floor(pow(-1, sm->signRow()) * (mp.x() - sm->numRows() / 2) / setup.baseRow()); // bend number in quarter pitch units - bend_ = (int)floor(pow(-1, module->signBend_) * (ttStubRef->bendBE()) / settings_->baseBend()); + bend_ = (int)floor(pow(-1, sm->signBend()) * (ttStubRef->bendBE()) / setup.baseBend()); // reduced row number for look up - rowLUT_ = (int)floor((double)row_ / pow(2., settings_->widthRow() - settings_->widthRowLUT())); + rowLUT_ = (int)floor((double)row_ / pow(2., setup.widthRow() - setup.dtcWidthRowLUT())); // sub row number inside reduced row number - rowSub_ = row_ - (rowLUT_ + .5) * pow(2, settings_->widthRow() - settings_->widthRowLUT()); + rowSub_ = row_ - (rowLUT_ + .5) * pow(2, setup.widthRow() - setup.dtcWidthRowLUT()); // convert local to global coordinates - const double y = (col_ + .5) * settings_->baseCol() * module->pitchCol_; + const double y = (col_ + .5) * setup.baseCol() * sm->pitchCol(); // radius of a column of strips/pixel in cm - d_ = module->R_ + y * module->sin_; + d_ = sm->r() + y * sm->sin(); // stub z in cm - z_ = module->Z_ + y * module->cos_; + z_ = digi(sm->z() + y * sm->cos(), setup.baseZ()); - const double x0 = rowLUT_ * settings_->baseRow() * settings_->numMergedRows() * module->pitchRow_; - const double x1 = (rowLUT_ + 1) * settings_->baseRow() * settings_->numMergedRows() * module->pitchRow_; - const double x = (rowLUT_ + .5) * settings_->baseRow() * settings_->numMergedRows() * module->pitchRow_; + const double x0 = rowLUT_ * setup.baseRow() * setup.dtcNumMergedRows() * sm->pitchRow(); + const double x1 = (rowLUT_ + 1) * setup.baseRow() * setup.dtcNumMergedRows() * sm->pitchRow(); + const double x = (rowLUT_ + .5) * setup.baseRow() * setup.dtcNumMergedRows() * sm->pitchRow(); // stub r in cm r_ = sqrt(d_ * d_ + x * x); - const double phi0 = module->Phi_ + atan2(x0, d_); - const double phi1 = module->Phi_ + atan2(x1, d_); + const double phi0 = sm->phi() + atan2(x0, d_); + const double phi1 = sm->phi() + atan2(x1, d_); const double c = (phi0 + phi1) / 2.; - const double m = (phi1 - phi0) / settings_->numMergedRows(); + const double m = (phi1 - phi0) / setup.dtcNumMergedRows(); // intercept of linearized stub phi in rad - c_ = digi(c, settings_->baseC()); + c_ = digi(c, setup.basePhi()); // slope of linearized stub phi in rad / strip - m_ = digi(m, settings_->baseM()); + m_ = digi(m, setup.dtcBaseM()); - if (settings_->dataFormat() == "TMTT") { + if (hybrid_) { + if (abs(z_ / r_) > setup.hybridMaxCot()) + // did not pass eta cut + valid_ = false; + } else { // extrapolated z at radius T assuming z0=0 - const double zT = settings_->tmtt()->chosenRofZ() * z_ / r_; + const double zT = setup.chosenRofZ() * z_ / r_; // extrapolated z0 window at radius T - const double dZT = settings_->tmtt()->beamWindowZ() * abs(1. - settings_->tmtt()->chosenRofZ() / r_); + const double dZT = setup.beamWindowZ() * abs(1. - setup.chosenRofZ() / r_); double zTMin = zT - dZT; double zTMax = zT + dZT; - if (zTMin >= settings_->tmtt()->maxZT() || zTMax < -settings_->tmtt()->maxZT()) + if (zTMin >= setup.maxZT() || zTMax < -setup.maxZT()) // did not pass "eta" cut valid_ = false; else { - zTMin = max(zTMin, -settings_->tmtt()->maxZT()); - zTMax = min(zTMax, settings_->tmtt()->maxZT()); + zTMin = max(zTMin, -setup.maxZT()); + zTMax = min(zTMax, setup.maxZT()); } // range of stub cot(theta) - cot_ = {zTMin / settings_->tmtt()->chosenRofZ(), zTMax / settings_->tmtt()->chosenRofZ()}; - - } else if (settings_->dataFormat() == "Hybrid") { - if (abs(z_ / r_) > settings_->maxCot()) - // did not pass eta cut - valid_ = false; + cot_ = {zTMin / setup.chosenRofZ(), zTMax / setup.chosenRofZ()}; } // stub r w.r.t. chosenRofPhi in cm - r_ = digi(r_ - settings_->chosenRofPhi(), settings_->baseR()); + r_ = digi(r_ - setup.chosenRofPhi(), setup.baseR()); // radial (cylindrical) component of sensor separation - const double dr = module->sep_ / (module->cos_ - module->sin_ * z_ / d_); + const double dr = sm->sep() / (sm->cos() - sm->sin() * z_ / d_); // converts bend into qOverPt in 1/cm - const double qOverPtOverBend = module->pitchRow_ / dr / d_; + const double qOverPtOverBend = sm->pitchRow() / dr / d_; // qOverPt in 1/cm - const double qOverPt = bend_ * settings_->baseBend() * qOverPtOverBend; + const double qOverPt = bend_ * setup.baseBend() * qOverPtOverBend; // qOverPt uncertainty in 1/cm - const double dQoverPt = settings_->bendCut() * qOverPtOverBend; - double qOverPtMin = digi(qOverPt - dQoverPt, settings_->baseQoverPt()); - double qOverPtMax = digi(qOverPt + dQoverPt, settings_->baseQoverPt()); - if (qOverPtMin >= settings_->maxQoverPt() || qOverPtMax < -settings_->maxQoverPt()) + const double dQoverPt = setup.bendCut() * qOverPtOverBend; + const double minPt = hybrid_ ? setup.hybridMinPt() : setup.minPt(); + const double maxQoverPt = setup.invPtToDphi() / minPt - setup.dtcBaseQoverPt() / 2.; + double qOverPtMin = digi(qOverPt - dQoverPt, setup.dtcBaseQoverPt()); + double qOverPtMax = digi(qOverPt + dQoverPt, setup.dtcBaseQoverPt()); + if (qOverPtMin >= maxQoverPt || qOverPtMax < -maxQoverPt) // did not pass pt cut valid_ = false; else { - qOverPtMin = max(qOverPtMin, -settings_->maxQoverPt()); - qOverPtMax = min(qOverPtMax, settings_->maxQoverPt()); + qOverPtMin = max(qOverPtMin, -maxQoverPt); + qOverPtMax = min(qOverPtMax, maxQoverPt); } // range of stub qOverPt in 1/cm qOverPt_ = {qOverPtMin, qOverPtMax}; @@ -116,29 +115,28 @@ namespace trackerDTC { regions_.push_back(1); // apply data format specific manipulations - if (settings_->dataFormat() != "Hybrid") + if (!hybrid_) return; // stub r w.r.t. an offset in cm - r_ -= module->offsetR_ - settings_->chosenRofPhi(); + r_ -= sm->offsetR() - setup.chosenRofPhi(); // stub z w.r.t. an offset in cm - z_ -= module->offsetZ_; - if (module->type_ == SettingsHybrid::disk2S) { - // decoded r - r_ = module->decodedR_ + (module->side_ ? -col_ : (col_ + module->numColumns_ / 2)); - r_ = (r_ + 0.5) * settings_->hybrid()->baseR(module->type_); + z_ -= sm->offsetZ(); + if (sm->type() == SensorModule::Disk2S) { + // encoded r + r_ = sm->encodedR() + (sm->side() ? -col_ : (col_ + sm->numColumns() / 2)); + r_ = (r_ + 0.5) * setup.hybridBaseR(sm->type()); } - // decode bend - const vector& bendEncoding = module->bendEncoding_; - const int uBend = distance(bendEncoding.begin(), find(bendEncoding.begin(), bendEncoding.end(), abs(bend_))); - bend_ = pow(-1, signbit(bend_)) * (uBend - (int)bendEncoding.size() / 2); + // encode bend + const vector& encodingBend = setup.encodingBend(sm->windowSize(), sm->psModule()); + const auto pos = find(encodingBend.begin(), encodingBend.end(), abs(bend_)); + const int uBend = distance(encodingBend.begin(), pos); + bend_ = pow(-1, signbit(bend_)) * (uBend - (int)encodingBend.size() / 2); } // returns bit accurate representation of Stub - TTDTC::BV Stub::frame(int region) const { - return settings_->dataFormat() == "Hybrid" ? formatHybrid(region) : formatTMTT(region); - } + TTDTC::BV Stub::frame(int region) const { return hybrid_ ? formatHybrid(region) : formatTMTT(region); } // returns true if stub belongs to region bool Stub::inRegion(int region) const { return find(regions_.begin(), regions_.end(), region) != regions_.end(); } @@ -148,18 +146,17 @@ namespace trackerDTC { // returns 64 bit stub in hybrid data format TTDTC::BV Stub::formatHybrid(int region) const { - SettingsHybrid* format = settings_->hybrid(); - SettingsHybrid::SensorType type = module_->type_; + const SensorModule::Type type = sm_->type(); // stub phi w.r.t. processing region centre in rad - const double phi = phi_ - (region - .5) * settings_->baseRegion(); + const double phi = phi_ - (region - .5) * setup_->baseRegion(); // convert stub variables into bit vectors - const TTBV hwR(r_, format->baseR(type), format->widthR(type), true); - const TTBV hwPhi(phi, format->basePhi(type), format->widthPhi(type), true); - const TTBV hwZ(z_, format->baseZ(type), format->widthZ(type), true); - const TTBV hwAlpha(row_, format->baseAlpha(type), format->widthAlpha(type), true); - const TTBV hwBend(bend_, format->widthBend(type), true); - const TTBV hwLayer(module_->layerId_, settings_->widthLayer()); - const TTBV hwGap(0, format->numUnusedBits(type)); + const TTBV hwR(r_, setup_->hybridBaseR(type), setup_->hybridWidthR(type), true); + const TTBV hwPhi(phi, setup_->hybridBasePhi(type), setup_->hybridWidthPhi(type), true); + const TTBV hwZ(z_, setup_->hybridBaseZ(type), setup_->hybridWidthZ(type), true); + const TTBV hwAlpha(row_, setup_->hybridBaseAlpha(type), setup_->hybridWidthAlpha(type), true); + const TTBV hwBend(bend_, setup_->hybridWidthBend(type), true); + const TTBV hwLayer(sm_->encodedLayerId(), setup_->hybridWidthLayer()); + const TTBV hwGap(0, setup_->hybridNumUnusedBits(type)); const TTBV hwValid(1, 1); // assemble final bitset return TTDTC::BV(hwGap.str() + hwR.str() + hwZ.str() + hwPhi.str() + hwAlpha.str() + hwBend.str() + hwLayer.str() + @@ -167,8 +164,7 @@ namespace trackerDTC { } TTDTC::BV Stub::formatTMTT(int region) const { - SettingsTMTT* format = settings_->tmtt(); - int layerM = module_->layerId_; + int layerM = sm_->layerId(); // convert unique layer id [1-6,11-15] into reduced layer id [0-6] // a fiducial track may not cross more then 7 detector layers, for stubs from a given track the reduced layer id is actually unique int layer(-1); @@ -187,52 +183,52 @@ namespace trackerDTC { else if (layerM == 3 || layerM == 15) layer = 6; // assign stub to phi sectors within a processing region, to be generalized - TTBV sectorsPhi(0, settings_->numOverlappingRegions() * format->numSectorsPhi()); + TTBV sectorsPhi(0, setup_->numOverlappingRegions() * setup_->numSectorsPhi()); if (phiT_.first < 0.) { - if (phiT_.first < -format->baseSector()) + if (phiT_.first < -setup_->baseSector()) sectorsPhi.set(0); else sectorsPhi.set(1); - if (phiT_.second < 0. && phiT_.second >= -format->baseSector()) + if (phiT_.second < 0. && phiT_.second >= -setup_->baseSector()) sectorsPhi.set(1); } if (phiT_.second >= 0.) { - if (phiT_.second < format->baseSector()) + if (phiT_.second < setup_->baseSector()) sectorsPhi.set(2); else sectorsPhi.set(3); - if (phiT_.first >= 0. && phiT_.first < format->baseSector()) + if (phiT_.first >= 0. && phiT_.first < setup_->baseSector()) sectorsPhi.set(2); } // assign stub to eta sectors within a processing region - pair setcorEta({0, format->numSectorsEta() - 1}); - for (int bin = 0; bin < format->numSectorsEta(); bin++) - if (asinh(cot_.first) < format->boundariesEta(bin + 1)) { + pair setcorEta({0, setup_->numSectorsEta() - 1}); + for (int bin = 0; bin < setup_->numSectorsEta(); bin++) + if (asinh(cot_.first) < setup_->boundarieEta(bin + 1)) { setcorEta.first = bin; break; } - for (int bin = setcorEta.first; bin < format->numSectorsEta(); bin++) - if (asinh(cot_.second) < format->boundariesEta(bin + 1)) { + for (int bin = setcorEta.first; bin < setup_->numSectorsEta(); bin++) + if (asinh(cot_.second) < setup_->boundarieEta(bin + 1)) { setcorEta.second = bin; break; } // stub phi w.r.t. processing region centre in rad - const double phi = phi_ - (region - .5) * settings_->baseRegion(); + const double phi = phi_ - (region - .5) * setup_->baseRegion(); // convert stub variables into bit vectors const TTBV hwValid(1, 1); - const TTBV hwGap(0, format->numUnusedBits()); - const TTBV hwLayer(layer, settings_->widthLayer()); - const TTBV hwSectorEtaMin(setcorEta.first, settings_->widthEta()); - const TTBV hwSectorEtaMax(setcorEta.second, settings_->widthEta()); - const TTBV hwR(r_, settings_->baseR(), settings_->widthR(), true); - const TTBV hwPhi(phi, settings_->basePhi(), settings_->widthPhi(), true); - const TTBV hwZ(z_, settings_->baseZ(), settings_->widthZ(), true); - const TTBV hwQoverPtMin(qOverPt_.first, format->baseQoverPt(), format->widthQoverPtBin(), true); - const TTBV hwQoverPtMax(qOverPt_.second, format->baseQoverPt(), format->widthQoverPtBin(), true); - TTBV hwSectorPhis(0, format->numSectorsPhi()); - for (int sectorPhi = 0; sectorPhi < format->numSectorsPhi(); sectorPhi++) - hwSectorPhis[sectorPhi] = sectorsPhi[region * format->numSectorsPhi() + sectorPhi]; - // assemble final bitset + const TTBV hwGap(0, setup_->dtcNumUnusedBits()); + const TTBV hwLayer(layer, setup_->widthLayer()); + const TTBV hwSectorEtaMin(setcorEta.first, setup_->widthSectorEta()); + const TTBV hwSectorEtaMax(setcorEta.second, setup_->widthSectorEta()); + const TTBV hwR(r_, setup_->baseR(), setup_->widthR(), true); + const TTBV hwPhi(phi, setup_->basePhi(), setup_->widthPhiDTC(), true); + const TTBV hwZ(z_, setup_->baseZ(), setup_->widthZ(), true); + const TTBV hwQoverPtMin(qOverPt_.first, setup_->htBaseQoverPt(), setup_->htWidthQoverPt(), true); + const TTBV hwQoverPtMax(qOverPt_.second, setup_->htBaseQoverPt(), setup_->htWidthQoverPt(), true); + TTBV hwSectorPhis(0, setup_->numSectorsPhi()); + for (int sectorPhi = 0; sectorPhi < setup_->numSectorsPhi(); sectorPhi++) + hwSectorPhis[sectorPhi] = sectorsPhi[region * setup_->numSectorsPhi() + sectorPhi]; + // assemble final bitsetTTDTC::BV(hwGap.str() + hwValid.str() + hwR.str() + hwPhi.str() + hwZ.str() + hwQoverPtMin.str() + return TTDTC::BV(hwGap.str() + hwValid.str() + hwR.str() + hwPhi.str() + hwZ.str() + hwQoverPtMin.str() + hwQoverPtMax.str() + hwSectorEtaMin.str() + hwSectorEtaMax.str() + hwSectorPhis.str() + hwLayer.str()); diff --git a/L1Trigger/TrackerDTC/plugins/Analyzer.cc b/L1Trigger/TrackerDTC/test/Analyzer.cc similarity index 81% rename from L1Trigger/TrackerDTC/plugins/Analyzer.cc rename to L1Trigger/TrackerDTC/test/Analyzer.cc index e4fd26c9dad03..1ca3af86f9b45 100644 --- a/L1Trigger/TrackerDTC/plugins/Analyzer.cc +++ b/L1Trigger/TrackerDTC/test/Analyzer.cc @@ -3,7 +3,6 @@ #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/GenericHandle.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/Service.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -11,26 +10,19 @@ #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/Utilities/interface/Exception.h" #include "CommonTools/UtilAlgos/interface/TFileService.h" -#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" -#include "Geometry/Records/interface/TrackerTopologyRcd.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" -#include "Geometry/CommonTopologies/interface/PixelTopology.h" #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" #include "SimTracker/TrackTriggerAssociation/interface/TTClusterAssociationMap.h" #include "SimTracker/Common/interface/TrackingParticleSelector.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "DataFormats/DetId/interface/DetId.h" -#include "DataFormats/Math/interface/deltaPhi.h" #include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/Common/interface/Handle.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1TrackTrigger/interface/TTDTC.h" #include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include "DataFormats/GeometrySurface/interface/Plane.h" #include "DataFormats/SiStripDetId/interface/StripSubdetector.h" -#include "L1Trigger/TrackerDTC/interface/Settings.h" -#include "L1Trigger/TrackerDTC/interface/TTDTCConverter.h" +#include "L1Trigger/TrackerDTC/interface/Setup.h" #include #include @@ -83,6 +75,10 @@ namespace trackerDTC { void endJob() override; private: + // configuring track particle selector + void configTPSelector(); + // book histograms + void bookHistograms(); // associate TPPtr with TTStubRef void assoc(const Handle&, const Handle&, map>&); // organize reconstrucable TrackingParticles used for efficiency measurements @@ -96,11 +92,9 @@ namespace trackerDTC { // analyze DTC products and find still reconstrucable TrackingParticles void analyzeStubs(const TTDTC*, const TTDTC*, const map>&, map>&); // fill stub related histograms - void analyzeStream(const TTDTC::Stream& stream, int region, int& sum, TH2F* th2f); - // returns global stub position - GlobalPoint stubPos(const TTStubRef& ttStubRef) const; - // handles 2 pi overflow - double deltaPhi(double lhs, double rhs = 0.) { return reco::deltaPhi(lhs, rhs); } + void analyzeStream(const TTDTC::Stream& stream, int region, int channel, int& sum, TH2F* th2f); + // returns layerId [1-6, 11-15] of stub + int layerId(const TTStubRef& ttStubRef) const; // analyze survived TPs void analyzeTPs(const map>& mapTPsStubs); // prints out MC summary @@ -108,22 +102,24 @@ namespace trackerDTC { // prints out DTC summary void endJobDTC(); - // ed input tokens - + // ED input token of DTC stubs EDGetTokenT getTokenTTDTCAccepted_; + // ED input token of lost DTC stubs EDGetTokenT getTokenTTDTCLost_; + // ED input token of TT stubs EDGetTokenT getTokenTTStubDetSetVec_; + // ED input token of TTCluster to TPPtr association EDGetTokenT getTokenTTClusterAssMap_; - - // es input tokens - - ESGetToken getTokenTrackerGeometry_; - ESGetToken getTokenTrackerTopology_; - + // Setup token + ESGetToken esGetToken_; // stores, calculates and provides run-time constants - Settings settings_; + Setup setup_; // selector to partly select TPs for efficiency measurements TrackingParticleSelector tpSelector_; + // enables analyze of TPs + bool useMCTruth_; + // specifies used TT algorithm + bool hybrid_; // Histograms @@ -144,109 +140,40 @@ namespace trackerDTC { stringstream log_; }; - Analyzer::Analyzer(const ParameterSet& iConfig) : settings_(iConfig) { + Analyzer::Analyzer(const ParameterSet& iConfig) + : useMCTruth_(iConfig.getParameter("UseMCTruth")), hybrid_(iConfig.getParameter("UseHybrid")) { usesResource("TFileService"); // book in- and output ED products - getTokenTTDTCAccepted_ = consumes(InputTag(settings_.producerLabel(), settings_.productBranchAccepted())); - getTokenTTDTCLost_ = consumes(InputTag(settings_.producerLabel(), settings_.productBranchLost())); - if (settings_.useMCTruth()) { - getTokenTTStubDetSetVec_ = consumes(settings_.inputTagTTStubDetSetVec()); - getTokenTTClusterAssMap_ = consumes(settings_.inputTagTTClusterAssMap()); - } - // book ES products - getTokenTrackerGeometry_ = esConsumes( - settings_.inputTagTrackerGeometry()); - getTokenTrackerTopology_ = - esConsumes(settings_.inputTagTrackerTopology()); - // configuring track particle selector - const double ptMin = settings_.tpMinPt(); - constexpr double ptMax = 9999999999.; - const double etaMax = settings_.tpMaxEta(); - const double tip = settings_.tpMaxVertR(); - const double lip = settings_.tpMaxVertZ(); - constexpr int minHit = 0; - constexpr bool signalOnly = true; - constexpr bool intimeOnly = true; - constexpr bool chargedOnly = true; - constexpr bool stableOnly = false; - tpSelector_ = TrackingParticleSelector( - ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly); - // book histograms - Service fs; - TFileDirectory dir; - // mc - dir = fs->mkdir("MC"); - profMC_ = dir.make("Counts", ";", 4, 0.5, 4.5); - profMC_->GetXaxis()->SetBinLabel(1, "Stubs"); - profMC_->GetXaxis()->SetBinLabel(2, "Matched Stubs"); - profMC_->GetXaxis()->SetBinLabel(3, "reco TPs"); - profMC_->GetXaxis()->SetBinLabel(4, "eff TPs"); - constexpr array binsEff{{9 * 8, 10, 16, 10, 30, 24}}; - constexpr array, NumEfficiency> rangesEff{ - {{-M_PI, M_PI}, {0., 100.}, {-1. / 3., 1. / 3.}, {-5., 5.}, {-15., 15.}, {-2.4, 2.4}}}; - if (settings_.useMCTruth()) { - hisEffMC_.reserve(NumEfficiency); - for (Efficiency e : AllEfficiency) - hisEffMC_.emplace_back( - dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); - } - // dtc - dir = fs->mkdir("DTC"); - profDTC_ = dir.make("Counts", ";", 3, 0.5, 3.5); - profDTC_->GetXaxis()->SetBinLabel(1, "Stubs"); - profDTC_->GetXaxis()->SetBinLabel(2, "Lost Stubs"); - profDTC_->GetXaxis()->SetBinLabel(3, "TPs"); - // channel occupancy - constexpr int maxOcc = 180; - const int numChannels = settings_.numDTCs(); - hisChannel_ = dir.make("Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); - profChannel_ = dir.make("Channel Occupancy", ";", numChannels, -.5, numChannels - .5); - // max tracking efficiencies - if (settings_.useMCTruth()) { - hisEff_.reserve(NumEfficiency); - for (Efficiency e : AllEfficiency) - hisEff_.emplace_back( - dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); - dir = fs->mkdir("DTC/Effi"); - eff_.reserve(NumEfficiency); - for (Efficiency e : AllEfficiency) - eff_.emplace_back( - dir.make(("Eff" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); - } - // lost stub fraction in r-z - dir = fs->mkdir("DTC/Loss"); - constexpr int bins = 400; - constexpr double maxZ = 300.; - constexpr double maxR = 120.; - hisRZStubs_ = dir.make("RZ Stubs", ";;", bins, -maxZ, maxZ, bins, 0., maxR); - hisRZStubsLost_ = dir.make("RZ Stubs Lost", ";;", bins, -maxZ, maxZ, bins, 0., maxR); - hisRZStubsEff_ = dir.make("RZ Stubs Eff", ";;", bins, -maxZ, maxZ, bins, 0., maxR); - // stub parameter resolutions - dir = fs->mkdir("DTC/Res"); - constexpr array ranges{{.2, .0001, .5}}; - constexpr int binsHis = 100; - hisResolution_.reserve(NumResolution); - profResolution_.reserve(NumResolution); - for (Resolution r : AllResolution) { - hisResolution_.emplace_back(dir.make(("HisRes" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); - profResolution_.emplace_back( - dir.make(("ProfRes" + name(r)).c_str(), ";;", bins, -maxZ, maxZ, bins, 0., maxR)); + const auto& inputTagAccepted = iConfig.getParameter("InputTagAccepted"); + const auto& inputTagLost = iConfig.getParameter("InputTagLost"); + getTokenTTDTCAccepted_ = consumes(inputTagAccepted); + getTokenTTDTCLost_ = consumes(inputTagLost); + if (useMCTruth_) { + const auto& inputTagTTStubDetSetVec = iConfig.getParameter("InputTagTTStubDetSetVec"); + const auto& inputTagTTClusterAssMap = iConfig.getParameter("InputTagTTClusterAssMap"); + getTokenTTStubDetSetVec_ = consumes(inputTagTTStubDetSetVec); + getTokenTTClusterAssMap_ = consumes(inputTagTTClusterAssMap); } + // book ES product + esGetToken_ = esConsumes(); // log config log_.setf(ios::fixed, ios::floatfield); log_.precision(4); } void Analyzer::beginRun(const Run& iEvent, const EventSetup& iSetup) { - // read in detector parameter - settings_.setTrackerGeometry(&iSetup.getData(getTokenTrackerGeometry_)); - settings_.setTrackerTopology(&iSetup.getData(getTokenTrackerTopology_)); + // helper class to store configurations + setup_ = iSetup.getData(esGetToken_); + // configuring track particle selector + configTPSelector(); + // book histograms + bookHistograms(); } void Analyzer::analyze(const Event& iEvent, const EventSetup& iSetup) { // read in TrackingParticle map> mapAllStubsTPs; - if (settings_.useMCTruth()) { + if (useMCTruth_) { Handle handleTTStubDetSetVec; iEvent.getByToken(getTokenTTStubDetSetVec_, handleTTStubDetSetVec); Handle handleTTClusterAssMap; @@ -277,7 +204,7 @@ namespace trackerDTC { hisRZStubsEff_->Add(hisRZStubsLost_); hisRZStubsEff_->Divide(&th2f); // create efficieny plots - if (settings_.useMCTruth()) { + if (useMCTruth_) { for (Efficiency e : AllEfficiency) { eff_[e]->SetPassedHistogram(*hisEff_[e], "f"); eff_[e]->SetTotalHistogram(*hisEffMC_[e], "f"); @@ -315,8 +242,8 @@ namespace trackerDTC { nStubsMatched++; } } - profMC_->Fill(1, nStubs / (double)settings_.numRegions()); - profMC_->Fill(2, nStubsMatched / (double)settings_.numRegions()); + profMC_->Fill(1, nStubs / (double)setup_.numRegions()); + profMC_->Fill(2, nStubsMatched / (double)setup_.numRegions()); } // organize reconstrucable TrackingParticles used for efficiency measurements @@ -341,8 +268,8 @@ namespace trackerDTC { // checks if a stub selection is considered reconstructable bool Analyzer::reconstructable(const set& ttStubRefs) const { - const TrackerGeometry* trackerGeometry = settings_.trackerGeometry(); - const TrackerTopology* trackerTopology = settings_.trackerTopology(); + const TrackerGeometry* trackerGeometry = setup_.trackerGeometry(); + const TrackerTopology* trackerTopology = setup_.trackerTopology(); set hitPattern; set hitPatternPS; for (const TTStubRef& ttStubRef : ttStubRefs) { @@ -354,7 +281,7 @@ namespace trackerDTC { if (psModule) hitPatternPS.insert(layerId); } - return (int)hitPattern.size() >= settings_.tpMinLayers() && (int)hitPatternPS.size() >= settings_.tpMinLayersPS(); + return (int)hitPattern.size() >= setup_.tpMinLayers() && (int)hitPatternPS.size() >= setup_.tpMinLayersPS(); } // checks if TrackingParticle is selected for efficiency measurements @@ -366,7 +293,7 @@ namespace trackerDTC { const TrackingParticle::Point& v = tp.vertex(); const double z0 = v.z() - (v.x() * c + v.y() * s) * cot; const double d0 = v.x() * s - v.y() * c; - return selected && (fabs(d0) < settings_.tpMaxD0()) && (fabs(z0) < settings_.tpMaxVertZ()); + return selected && (fabs(d0) < setup_.tpMaxD0()) && (fabs(z0) < setup_.tpMaxVertZ()); } // fills kinematic tp histograms @@ -389,13 +316,13 @@ namespace trackerDTC { const TTDTC* lost, const map>& mapStubsTPs, map>& mapTPsStubs) { - for (int region = 0; region < settings_.numRegions(); region++) { + for (int region = 0; region < setup_.numRegions(); region++) { int nStubs(0); int nLost(0); - for (int channel = 0; channel < settings_.numDTCsPerTFP(); channel++) { + for (int channel = 0; channel < setup_.numDTCsPerTFP(); channel++) { const TTDTC::Stream& stream = accepted->stream(region, channel); hisChannel_->Fill(stream.size()); - profChannel_->Fill(region * settings_.numDTCsPerTFP() + channel, stream.size()); + profChannel_->Fill(region * setup_.numDTCsPerTFP() + channel, stream.size()); for (const TTDTC::Frame& frame : stream) { if (frame.first.isNull()) continue; @@ -405,8 +332,8 @@ namespace trackerDTC { for (const TPPtr& tp : it->second) mapTPsStubs[tp].insert(frame.first); } - analyzeStream(stream, region, nStubs, hisRZStubs_); - analyzeStream(lost->stream(region, channel), region, nLost, hisRZStubsLost_); + analyzeStream(stream, region, channel, nStubs, hisRZStubs_); + analyzeStream(lost->stream(region, channel), region, channel, nLost, hisRZStubsLost_); } profDTC_->Fill(1, nStubs); profDTC_->Fill(2, nLost); @@ -414,13 +341,13 @@ namespace trackerDTC { } // fill stub related histograms - void Analyzer::analyzeStream(const TTDTC::Stream& stream, int region, int& sum, TH2F* th2f) { + void Analyzer::analyzeStream(const TTDTC::Stream& stream, int region, int channel, int& sum, TH2F* th2f) { for (const TTDTC::Frame& frame : stream) { if (frame.first.isNull()) continue; sum++; - const GlobalPoint& pos = TTDTCConverter(&settings_, frame, region); - const GlobalPoint& ttPos = stubPos(frame.first); + const GlobalPoint& pos = setup_.stubPos(hybrid_, frame, region, channel); + const GlobalPoint& ttPos = setup_.stubPos(frame.first); const vector resolutions = { ttPos.perp() - pos.perp(), deltaPhi(ttPos.phi() - pos.phi()), ttPos.z() - pos.z()}; for (Resolution r : AllResolution) { @@ -428,19 +355,22 @@ namespace trackerDTC { profResolution_[r]->Fill(ttPos.z(), ttPos.perp(), abs(resolutions[r])); } th2f->Fill(ttPos.z(), ttPos.perp()); + // check layerId encoding + if (!hybrid_) + continue; + const vector& encodingLayerId = setup_.encodingLayerId(channel); + const auto it = find(encodingLayerId.begin(), encodingLayerId.end(), layerId(frame.first)); + if (it == encodingLayerId.end()) + throw cms::Exception("LogicError") << "Stub send from a DTC which is not connected to stub's layer."; } } - // returns global stub position - GlobalPoint Analyzer::stubPos(const TTStubRef& ttStubRef) const { - const TrackerGeometry* trackerGeometry = settings_.trackerGeometry(); - const DetId detId = ttStubRef->getDetId() + settings_.offsetDetIdDSV(); - const GeomDetUnit* det = trackerGeometry->idToDetUnit(detId); - const PixelTopology* topol = - dynamic_cast(&(dynamic_cast(det)->specificTopology())); - const Plane& plane = dynamic_cast(det)->surface(); - const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered(); - return plane.toGlobal(topol->localPosition(mp)); + // returns layerId [1-6, 11-15] of stub + int Analyzer::layerId(const TTStubRef& ttStubRef) const { + const TrackerTopology* trackerTopology = setup_.trackerTopology(); + const DetId detId = ttStubRef->getDetId() + setup_.offsetDetIdDSV(); + const bool barrel = detId.subdetId() == StripSubdetector::TOB; + return barrel ? trackerTopology->layer(detId) : trackerTopology->tidWheel(detId) + setup_.offsetLayerDisks(); } // analyze survived TPs @@ -503,6 +433,86 @@ namespace trackerDTC { log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; } + // configuring track particle selector + void Analyzer::configTPSelector() { + const double ptMin = hybrid_ ? setup_.hybridMinPt() : setup_.minPt(); + constexpr double ptMax = 9999999999.; + const double etaMax = setup_.tpMaxEta(); + const double tip = setup_.tpMaxVertR(); + const double lip = setup_.tpMaxVertZ(); + constexpr int minHit = 0; + constexpr bool signalOnly = true; + constexpr bool intimeOnly = true; + constexpr bool chargedOnly = true; + constexpr bool stableOnly = false; + tpSelector_ = TrackingParticleSelector( + ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly); + } + + // book histograms + void Analyzer::bookHistograms() { + Service fs; + TFileDirectory dir; + // mc + dir = fs->mkdir("MC"); + profMC_ = dir.make("Counts", ";", 4, 0.5, 4.5); + profMC_->GetXaxis()->SetBinLabel(1, "Stubs"); + profMC_->GetXaxis()->SetBinLabel(2, "Matched Stubs"); + profMC_->GetXaxis()->SetBinLabel(3, "reco TPs"); + profMC_->GetXaxis()->SetBinLabel(4, "eff TPs"); + constexpr array binsEff{{9 * 8, 10, 16, 10, 30, 24}}; + constexpr array, NumEfficiency> rangesEff{ + {{-M_PI, M_PI}, {0., 100.}, {-1. / 3., 1. / 3.}, {-5., 5.}, {-15., 15.}, {-2.4, 2.4}}}; + if (useMCTruth_) { + hisEffMC_.reserve(NumEfficiency); + for (Efficiency e : AllEfficiency) + hisEffMC_.emplace_back( + dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); + } + // dtc + dir = fs->mkdir("DTC"); + profDTC_ = dir.make("Counts", ";", 3, 0.5, 3.5); + profDTC_->GetXaxis()->SetBinLabel(1, "Stubs"); + profDTC_->GetXaxis()->SetBinLabel(2, "Lost Stubs"); + profDTC_->GetXaxis()->SetBinLabel(3, "TPs"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = setup_.numDTCs() * setup_.numOverlappingRegions(); + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // max tracking efficiencies + if (useMCTruth_) { + dir = fs->mkdir("DTC/Effi"); + hisEff_.reserve(NumEfficiency); + for (Efficiency e : AllEfficiency) + hisEff_.emplace_back( + dir.make(("HisTP" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); + eff_.reserve(NumEfficiency); + for (Efficiency e : AllEfficiency) + eff_.emplace_back( + dir.make(("Eff" + name(e)).c_str(), ";", binsEff[e], rangesEff[e].first, rangesEff[e].second)); + } + // lost stub fraction in r-z + dir = fs->mkdir("DTC/Loss"); + constexpr int bins = 400; + constexpr double maxZ = 300.; + constexpr double maxR = 120.; + hisRZStubs_ = dir.make("RZ Stubs", ";;", bins, -maxZ, maxZ, bins, 0., maxR); + hisRZStubsLost_ = dir.make("RZ Stubs Lost", ";;", bins, -maxZ, maxZ, bins, 0., maxR); + hisRZStubsEff_ = dir.make("RZ Stubs Eff", ";;", bins, -maxZ, maxZ, bins, 0., maxR); + // stub parameter resolutions + dir = fs->mkdir("DTC/Res"); + constexpr array ranges{{.2, .0001, .5}}; + constexpr int binsHis = 100; + hisResolution_.reserve(NumResolution); + profResolution_.reserve(NumResolution); + for (Resolution r : AllResolution) { + hisResolution_.emplace_back(dir.make(("HisRes" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); + profResolution_.emplace_back( + dir.make(("ProfRes" + name(r)).c_str(), ";;", bins, -maxZ, maxZ, bins, 0., maxR)); + } + } + } // namespace trackerDTC DEFINE_FWK_MODULE(trackerDTC::Analyzer); diff --git a/L1Trigger/TrackerDTC/test/BuildFile.xml b/L1Trigger/TrackerDTC/test/BuildFile.xml new file mode 100644 index 0000000000000..90591991cf254 --- /dev/null +++ b/L1Trigger/TrackerDTC/test/BuildFile.xml @@ -0,0 +1,4 @@ + + + + diff --git a/L1Trigger/TrackerDTC/test/test_cfg.py b/L1Trigger/TrackerDTC/test/test_cfg.py index 8d46b9ca00672..157a57b48ff21 100644 --- a/L1Trigger/TrackerDTC/test/test_cfg.py +++ b/L1Trigger/TrackerDTC/test/test_cfg.py @@ -8,7 +8,6 @@ process = cms.Process( "Demo" ) process.load( 'Configuration.Geometry.GeometryExtended2026D49Reco_cff' ) -process.load( 'Configuration.Geometry.GeometryExtended2026D49_cff' ) process.load( 'Configuration.StandardSequences.MagneticField_cff' ) process.load( 'Configuration.StandardSequences.FrontierConditions_GlobalTag_cff' ) process.load( 'Configuration.StandardSequences.L1TrackTrigger_cff' ) @@ -17,23 +16,24 @@ from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag( process.GlobalTag, 'auto:phase2_realistic', '' ) -#--- Load code that produces DTCStubs -process.load( 'L1Trigger.TrackerDTC.Producer_cff' ) -process.produce = cms.Path( process.TrackerDTCProducer ) -#from L1Trigger.TrackerDTC.Producer_Customize_cff import useTMTT -#useTMTT(process) - -#--- Load code that analyzes DTCStubs +# load code that produces DTCStubs +process.load( 'L1Trigger.TrackerDTC.ProducerED_cff' ) +# load code that analyzes DTCStubs process.load( 'L1Trigger.TrackerDTC.Analyzer_cff' ) -process.analyze = cms.Path( process.TrackerDTCAnalyzer ) -#from L1Trigger.TrackerDTC.Analyzer_Customize_cff import useTMTT -#useTMTT(process) +# cosutmize TT algorithm +from L1Trigger.TrackerDTC.Customize_cff import * +#producerUseTMTT(process) +#analyzerUseTMTT(process) +# build schedule +process.produce = cms.Path( process.TrackerDTCProducer ) +process.analyze = cms.Path( process.TrackerDTCAnalyzer ) process.schedule = cms.Schedule( process.produce, process.analyze ) +# create options import FWCore.ParameterSet.VarParsing as VarParsing options = VarParsing.VarParsing( 'analysis' ) -#--- Specify input MC +# specify input MC Samples = { '/store/relval/CMSSW_11_1_0_pre1/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU25ns_110X_mcRun4_realistic_v2_2026D49PU200_ext1-v1/20000/0330453B-9B8E-CA41-88B0-A047B68D1AF9.root', '/store/relval/CMSSW_11_1_0_pre1/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU25ns_110X_mcRun4_realistic_v2_2026D49PU200_ext1-v1/20000/02180D14-024D-ED46-9899-B275EADB82CE.root', @@ -57,7 +57,7 @@ '/store/relval/CMSSW_11_1_0_pre1/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU25ns_110X_mcRun4_realistic_v2_2026D49PU200_ext1-v1/20000/C38AE82D-587E-C34B-89DC-FBAE92696270.root' } options.register( 'inputMC', Samples, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "Files to be processed" ) -#--- Specify number of events to process. +# specify number of events to process. options.register( 'Events',100,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of Events to analyze" ) options.parseArguments() diff --git a/L1TriggerConfig/L1TConfigProducers/python/L1TMuonEndCapForestOnline_cfi.py b/L1TriggerConfig/L1TConfigProducers/python/L1TMuonEndCapForestOnline_cfi.py index 0316799fe1f1f..4c37a348c99ca 100644 --- a/L1TriggerConfig/L1TConfigProducers/python/L1TMuonEndCapForestOnline_cfi.py +++ b/L1TriggerConfig/L1TConfigProducers/python/L1TMuonEndCapForestOnline_cfi.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.L1TMuonEndCap.fakeEmtfParams_cff import * +from L1Trigger.L1TMuonEndCap.fakeEmtfParams_empty_cff import * L1TMuonEndCapForestOnlineProd = cms.ESProducer("L1TMuonEndCapForestOnlineProd", onlineAuthentication = cms.string('.'), diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TCaloParamsOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TCaloParamsOnlineProd.cc index d11482a65c857..f654ba2ea5e09 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TCaloParamsOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TCaloParamsOnlineProd.cc @@ -21,6 +21,7 @@ class L1TCaloParamsOnlineProd : public L1ConfigOnlineProdBaseExt baseSettings_token; bool readCaloLayer1OnlineSettings(l1t::CaloParamsHelperO2O& paramsHelper, std::map& conf, @@ -210,6 +211,7 @@ bool L1TCaloParamsOnlineProd::readCaloLayer2OnlineSettings(l1t::CaloParamsHelper L1TCaloParamsOnlineProd::L1TCaloParamsOnlineProd(const edm::ParameterSet& iConfig) : L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig).setConsumes(baseSettings_token); exclusiveLayer = iConfig.getParameter("exclusiveLayer"); transactionSafe = iConfig.getParameter("transactionSafe"); } @@ -217,8 +219,7 @@ L1TCaloParamsOnlineProd::L1TCaloParamsOnlineProd(const edm::ParameterSet& iConfi std::unique_ptr L1TCaloParamsOnlineProd::newObject(const std::string& objectKey, const L1TCaloParamsO2ORcd& record) { const L1TCaloParamsRcd& baseRcd = record.template getRecord(); - edm::ESHandle baseSettings; - baseRcd.get(baseSettings); + auto const& baseSettings = baseRcd.get(baseSettings_token); if (objectKey.empty()) { edm::LogError("L1-O2O: L1TCaloParamsOnlineProd") << "Key is empty"; @@ -226,7 +227,7 @@ std::unique_ptr L1TCaloParamsOnlineProd::newObject(const throw std::runtime_error("SummaryForFunctionManager: Calo | Faulty | Empty objectKey"); else { edm::LogError("L1-O2O: L1TCaloParamsOnlineProd") << "returning unmodified prototype of l1t::CaloParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -283,7 +284,7 @@ std::unique_ptr L1TCaloParamsOnlineProd::newObject(const throw std::runtime_error(std::string("SummaryForFunctionManager: Calo | Faulty | ") + e.what()); else { edm::LogError("L1-O2O: L1TCaloParamsOnlineProd") << "returning unmodified prototype of l1t::CaloParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -305,7 +306,7 @@ std::unique_ptr L1TCaloParamsOnlineProd::newObject(const output.close(); } - l1t::CaloParamsHelperO2O m_params_helper(*(baseSettings.product())); + l1t::CaloParamsHelperO2O m_params_helper(baseSettings); if (exclusiveLayer == 0 || exclusiveLayer == 1) { try { @@ -329,7 +330,7 @@ std::unique_ptr L1TCaloParamsOnlineProd::newObject(const throw std::runtime_error(std::string("SummaryForFunctionManager: Calo | Faulty | ") + e.what()); else { edm::LogError("L1-O2O: L1TCaloParamsOnlineProd") << "returning unmodified prototype of l1t::CaloParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } } @@ -363,7 +364,7 @@ std::unique_ptr L1TCaloParamsOnlineProd::newObject(const throw std::runtime_error(std::string("SummaryForFunctionManager: Calo | Faulty | ") + e.what()); else { edm::LogError("L1-O2O: L1TCaloParamsOnlineProd") << "returning unmodified prototype of l1t::CaloParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } } diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosObjectKeysOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosObjectKeysOnlineProd.cc index c582e0ded2d6e..91609abcdb858 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosObjectKeysOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosObjectKeysOnlineProd.cc @@ -18,7 +18,7 @@ L1TGlobalPrescalesVetosObjectKeysOnlineProd::L1TGlobalPrescalesVetosObjectKeysOn void L1TGlobalPrescalesVetosObjectKeysOnlineProd::fillObjectKeys(L1TriggerKeyExt* pL1TriggerKey) { std::string uGTKey = pL1TriggerKey->subsystemKey(L1TriggerKeyExt::kuGT); - pL1TriggerKey->add("L1TGlobalPrescalesVetosO2ORcd", "L1TGlobalPrescalesVetos", uGTKey); + pL1TriggerKey->add("L1TGlobalPrescalesVetosFractO2ORcd", "L1TGlobalPrescalesVetosFract", uGTKey); } //define this as a plug-in diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosOnlineProd.cc index 197b8d0d14b8e..1cdf3b0b6ed51 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TGlobalPrescalesVetosOnlineProd.cc @@ -17,34 +17,35 @@ #include "CondFormats/L1TObjects/interface/L1TUtmTriggerMenu.h" #include "CondTools/L1TriggerExt/interface/L1ConfigOnlineProdBaseExt.h" -#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetos.h" -#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosRcd.h" -#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosO2ORcd.h" -#include "L1Trigger/L1TGlobal/interface/PrescalesVetosHelper.h" +#include "CondFormats/L1TObjects/interface/L1TGlobalPrescalesVetosFract.h" +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractRcd.h" +#include "CondFormats/DataRecord/interface/L1TGlobalPrescalesVetosFractO2ORcd.h" +#include "L1Trigger/L1TGlobal/interface/PrescalesVetosFractHelper.h" #include "L1Trigger/L1TCommon/interface/TriggerSystem.h" #include "L1Trigger/L1TCommon/interface/XmlConfigParser.h" #include "OnlineDBqueryHelper.h" class L1TGlobalPrescalesVetosOnlineProd - : public L1ConfigOnlineProdBaseExt { + : public L1ConfigOnlineProdBaseExt { private: bool transactionSafe; public: - std::unique_ptr newObject(const std::string &objectKey, - const L1TGlobalPrescalesVetosO2ORcd &record) override; + std::unique_ptr newObject( + const std::string &objectKey, const L1TGlobalPrescalesVetosFractO2ORcd &record) override; L1TGlobalPrescalesVetosOnlineProd(const edm::ParameterSet &); ~L1TGlobalPrescalesVetosOnlineProd(void) override {} }; L1TGlobalPrescalesVetosOnlineProd::L1TGlobalPrescalesVetosOnlineProd(const edm::ParameterSet &iConfig) - : L1ConfigOnlineProdBaseExt(iConfig) { + : L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig); transactionSafe = iConfig.getParameter("transactionSafe"); } -std::unique_ptr L1TGlobalPrescalesVetosOnlineProd::newObject( - const std::string &objectKey, const L1TGlobalPrescalesVetosO2ORcd &record) { +std::unique_ptr L1TGlobalPrescalesVetosOnlineProd::newObject( + const std::string &objectKey, const L1TGlobalPrescalesVetosFractO2ORcd &record) { edm::LogInfo("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "Producing L1TGlobalPrescalesVetos with TSC:RS key = " << objectKey; @@ -52,8 +53,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty | Empty objectKey"); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -80,8 +82,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty | Broken key"); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -95,8 +98,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty | Empty objectKey"); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -112,8 +116,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error("SummaryForFunctionManager: uGTrs | Faulty | Broken key"); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -155,8 +160,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty | ") + e.what()); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -176,7 +182,7 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd ////////////////// - std::vector> prescales; + std::vector> prescales; std::vector triggerMasks; std::vector triggerVetoMasks; std::map> triggerAlgoBxMaskAlgoTrig; @@ -203,9 +209,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (nPrescaleSets > 0) { // Fill default prescale set for (int iSet = 0; iSet < nPrescaleSets; iSet++) { - prescales.push_back(std::vector()); + prescales.push_back(std::vector()); for (unsigned int iBit = 0; iBit < m_numberPhysTriggers; ++iBit) { - int inputDefaultPrescale = 0; // only prescales that are set in the block below are used + double inputDefaultPrescale = 0; // only prescales that are set in the block below are used prescales[iSet].push_back(inputDefaultPrescale); } } @@ -214,10 +220,10 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (col.second < 1) continue; // we don't care for the algorithms' indicies in 0th column int iSet = col.second - 1; - std::vector prescalesForSet = - settings_prescale.at("prescales").getTableColumn(col.first.c_str()); + std::vector prescalesForSet = + settings_prescale.at("prescales").getTableColumn(col.first.c_str()); for (unsigned int row = 0; row < prescalesForSet.size(); row++) { - unsigned int prescale = prescalesForSet[row]; + double prescale = prescalesForSet[row]; std::string algoName = algoNames[row]; unsigned int algoBit = algoName2bit[algoName]; prescales[iSet][algoBit] = prescale; @@ -228,8 +234,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty | ") + e.what()); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -281,8 +288,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty | ") + e.what()); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -332,8 +340,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty | ") + e.what()); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -364,8 +373,9 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd if (transactionSafe) throw std::runtime_error(std::string("SummaryForFunctionManager: uGTrs | Faulty | ") + e.what()); else { - edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") << "returning empty L1TGlobalPrescalesVetos object"; - return std::make_unique(); + edm::LogError("L1-O2O: L1TGlobalPrescalesVetosOnlineProd") + << "returning empty L1TGlobalPrescalesVetosFract object"; + return std::make_unique(); } } @@ -639,14 +649,14 @@ std::unique_ptr L1TGlobalPrescalesVetosOnlineProd ///////////// - l1t::PrescalesVetosHelper data_(new L1TGlobalPrescalesVetos()); + l1t::PrescalesVetosFractHelper data_(new L1TGlobalPrescalesVetosFract()); data_.setBxMaskDefault(m_bx_mask_default); data_.setPrescaleFactorTable(prescales); data_.setTriggerMaskVeto(triggerVetoMasks); data_.setTriggerAlgoBxMask(triggerAlgoBxMaskAlgoTrig); - auto payload = std::make_unique(*data_.getWriteInstance()); + auto payload = std::make_unique(*data_.getWriteInstance()); edm::LogInfo("L1-O2O: L1TCaloParamsOnlineProd") << "SummaryForFunctionManager: uGTrs | OK | All looks good"; diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonBarrelParamsOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonBarrelParamsOnlineProd.cc index b89c366780d77..583f727514e03 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonBarrelParamsOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonBarrelParamsOnlineProd.cc @@ -16,6 +16,7 @@ using namespace XERCES_CPP_NAMESPACE; class L1TMuonBarrelParamsOnlineProd : public L1ConfigOnlineProdBaseExt { private: bool transactionSafe; + edm::ESGetToken baseSettings_token; public: std::unique_ptr newObject(const std::string& objectKey, @@ -27,14 +28,14 @@ class L1TMuonBarrelParamsOnlineProd : public L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig).setConsumes(baseSettings_token); transactionSafe = iConfig.getParameter("transactionSafe"); } std::unique_ptr L1TMuonBarrelParamsOnlineProd::newObject( const std::string& objectKey, const L1TMuonBarrelParamsO2ORcd& record) { const L1TMuonBarrelParamsRcd& baseRcd = record.template getRecord(); - edm::ESHandle baseSettings; - baseRcd.get(baseSettings); + auto const& baseSettings = baseRcd.get(baseSettings_token); if (objectKey.empty()) { edm::LogError("L1-O2O: L1TMuonBarrelParamsOnlineProd") << "Key is empty, returning empty L1TMuonBarrelParams"; @@ -42,7 +43,7 @@ std::unique_ptr L1TMuonBarrelParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: BMTF | Faulty | Empty objectKey"); else { edm::LogError("L1-O2O: L1TMuonBarrelParamsOnlineProd") << "returning unmodified prototype of L1TMuonBarrelParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -79,7 +80,7 @@ std::unique_ptr L1TMuonBarrelParamsOnlineProd::newObj throw std::runtime_error(std::string("SummaryForFunctionManager: BMTF | Faulty | ") + e.what()); else { edm::LogError("L1-O2O: L1TMuonBarrelParamsOnlineProd") << "returning unmodified prototype of L1TMuonBarrelParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -131,11 +132,11 @@ std::unique_ptr L1TMuonBarrelParamsOnlineProd::newObj throw std::runtime_error(std::string("SummaryForFunctionManager: BMTF | Faulty | ") + e.what()); else { edm::LogError("L1-O2O: L1TMuonBarrelParamsOnlineProd") << "returning unmodified prototype of L1TMuonBarrelParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } - L1TMuonBarrelParamsHelper m_params_helper(*(baseSettings.product())); + L1TMuonBarrelParamsHelper m_params_helper(baseSettings); try { m_params_helper.configFromDB(parsedXMLs); } catch (std::runtime_error& e) { @@ -144,7 +145,7 @@ std::unique_ptr L1TMuonBarrelParamsOnlineProd::newObj throw std::runtime_error(std::string("SummaryForFunctionManager: BMTF | Faulty | ") + e.what()); else { edm::LogError("L1-O2O: L1TMuonBarrelParamsOnlineProd") << "returning unmodified prototype of L1TMuonBarrelParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProd.cc index 612789813d068..c17b708c25b32 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProd.cc @@ -21,6 +21,7 @@ class L1TMuonEndCapForestOnlineProd : public L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig); transactionSafe = iConfig.getParameter("transactionSafe"); } diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProxy.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProxy.cc index e63a6528f9b10..56d74056fe32b 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProxy.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapForestOnlineProxy.cc @@ -9,6 +9,9 @@ #include "CondFormats/DataRecord/interface/L1TMuonEndCapForestO2ORcd.h" class L1TMuonEndCapForestOnlineProxy : public edm::ESProducer { +private: + edm::ESGetToken baseSettings_token; + public: std::unique_ptr produce(const L1TMuonEndCapForestO2ORcd& record); @@ -17,15 +20,14 @@ class L1TMuonEndCapForestOnlineProxy : public edm::ESProducer { }; L1TMuonEndCapForestOnlineProxy::L1TMuonEndCapForestOnlineProxy(const edm::ParameterSet& iConfig) : edm::ESProducer() { - setWhatProduced(this); + setWhatProduced(this).setConsumes(baseSettings_token); } std::unique_ptr L1TMuonEndCapForestOnlineProxy::produce(const L1TMuonEndCapForestO2ORcd& record) { const L1TMuonEndCapForestRcd& baseRcd = record.template getRecord(); - edm::ESHandle baseSettings; - baseRcd.get(baseSettings); + auto const& baseSettings = baseRcd.get(baseSettings_token); - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } //define this as a plug-in diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapParamsOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapParamsOnlineProd.cc index f792f3e907861..4d37a583a037a 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapParamsOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonEndCapParamsOnlineProd.cc @@ -15,6 +15,7 @@ class L1TMuonEndCapParamsOnlineProd : public L1ConfigOnlineProdBaseExt { private: bool transactionSafe; + edm::ESGetToken baseSettings_token; public: std::unique_ptr newObject(const std::string& objectKey, @@ -26,22 +27,22 @@ class L1TMuonEndCapParamsOnlineProd : public L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig).setConsumes(baseSettings_token); transactionSafe = iConfig.getParameter("transactionSafe"); } std::unique_ptr L1TMuonEndCapParamsOnlineProd::newObject( const std::string& objectKey, const L1TMuonEndCapParamsO2ORcd& record) { const L1TMuonEndCapParamsRcd& baseRcd = record.template getRecord(); - edm::ESHandle baseSettings; - baseRcd.get(baseSettings); + auto const& baseSettings = baseRcd.get(baseSettings_token); if (objectKey.empty()) { edm::LogError("L1-O2O: L1TMuonEndCapParamsOnlineProd") << "Key is empty"; if (transactionSafe) - throw std::runtime_error("SummaryForFunctionManager: BMTF | Faulty | Empty objectKey"); + throw std::runtime_error("SummaryForFunctionManager: EMTF | Faulty | Empty objectKey"); else { edm::LogError("L1-O2O: L1TMuonEndCapParamsOnlineProd") << "returning unmodified prototype of L1TMuonEndCapParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -70,7 +71,7 @@ std::unique_ptr L1TMuonEndCapParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: EMTF | Faulty | Broken key"); else { edm::LogError("L1-O2O: L1TMuonEndCapParamsOnlineProd") << "returning unmodified prototype of L1TMuonEndCapParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -103,7 +104,7 @@ std::unique_ptr L1TMuonEndCapParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: EMTF | Faulty | Cannot parse XMLs"); else { edm::LogError("L1-O2O: L1TMuonEndCapParamsOnlineProd") << "returning unmodified prototype of L1TMuonEndCapParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonGlobalParamsOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonGlobalParamsOnlineProd.cc index 7220e0fe5ad97..601ed09c98b7d 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonGlobalParamsOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonGlobalParamsOnlineProd.cc @@ -15,6 +15,7 @@ class L1TMuonGlobalParamsOnlineProd : public L1ConfigOnlineProdBaseExt { private: bool transactionSafe; + edm::ESGetToken baseSettings_token; public: std::unique_ptr newObject(const std::string &objectKey, @@ -26,14 +27,14 @@ class L1TMuonGlobalParamsOnlineProd : public L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig).setConsumes(baseSettings_token); transactionSafe = iConfig.getParameter("transactionSafe"); } std::unique_ptr L1TMuonGlobalParamsOnlineProd::newObject( const std::string &objectKey, const L1TMuonGlobalParamsO2ORcd &record) { const L1TMuonGlobalParamsRcd &baseRcd = record.template getRecord(); - edm::ESHandle baseSettings; - baseRcd.get(baseSettings); + auto const &baseSettings = baseRcd.get(baseSettings_token); if (objectKey.empty()) { edm::LogError("L1-O2O: L1TMuonGlobalParamsOnlineProd") << "Key is empty"; @@ -41,7 +42,7 @@ std::unique_ptr L1TMuonGlobalParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: uGMT | Faulty | Empty objectKey"); else { edm::LogError("L1-O2O: L1TMuonGlobalParams") << "returning unmodified prototype of L1TMuonGlobalParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -81,7 +82,7 @@ std::unique_ptr L1TMuonGlobalParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: uGMT | Faulty | Broken key"); else { edm::LogError("L1-O2O: L1TMuonGlobalParamsOnlineProd") << "returning unmodified prototype of L1TMuonGlobalParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } @@ -127,11 +128,11 @@ std::unique_ptr L1TMuonGlobalParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: uGMT | Faulty | Cannot parse XMLs"); else { edm::LogError("L1-O2O: L1TMuonGlobalParamsOnlineProd") << "returning unmodified prototype of L1TMuonGlobalParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } - L1TMuonGlobalParamsHelper m_params_helper(*(baseSettings.product())); + L1TMuonGlobalParamsHelper m_params_helper(baseSettings); try { m_params_helper.loadFromOnline(trgSys); } catch (std::runtime_error &e) { @@ -140,7 +141,7 @@ std::unique_ptr L1TMuonGlobalParamsOnlineProd::newObj throw std::runtime_error("SummaryForFunctionManager: uGMT | Faulty | Cannot run helper"); else { edm::LogError("L1-O2O: L1TMuonGlobalParamsOnlineProd") << "returning unmodified prototype of L1TMuonGlobalParams"; - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } } diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProd.cc index 80f1427379ef3..729a2399a0208 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProd.cc @@ -22,6 +22,7 @@ class L1TMuonOverlapParamsOnlineProd L1TMuonOverlapParamsOnlineProd::L1TMuonOverlapParamsOnlineProd(const edm::ParameterSet& iConfig) : L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig); transactionSafe = iConfig.getParameter("transactionSafe"); } diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProxy.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProxy.cc index 43935be966d17..2c949e5aba27a 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProxy.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TMuonOverlapParamsOnlineProxy.cc @@ -3,13 +3,15 @@ #include "FWCore/Framework/interface/ModuleFactory.h" #include "FWCore/Framework/interface/ESProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" + #include "CondFormats/L1TObjects/interface/L1TMuonOverlapParams.h" #include "CondFormats/DataRecord/interface/L1TMuonOverlapParamsRcd.h" #include "CondFormats/DataRecord/interface/L1TMuonOverlapParamsO2ORcd.h" class L1TMuonOverlapParamsOnlineProxy : public edm::ESProducer { private: + edm::ESGetToken baseSettings_token; + public: std::unique_ptr produce(const L1TMuonOverlapParamsO2ORcd& record); @@ -18,16 +20,15 @@ class L1TMuonOverlapParamsOnlineProxy : public edm::ESProducer { }; L1TMuonOverlapParamsOnlineProxy::L1TMuonOverlapParamsOnlineProxy(const edm::ParameterSet& iConfig) : edm::ESProducer() { - setWhatProduced(this); + setWhatProduced(this).setConsumes(baseSettings_token); } std::unique_ptr L1TMuonOverlapParamsOnlineProxy::produce( const L1TMuonOverlapParamsO2ORcd& record) { const L1TMuonOverlapParamsRcd& baseRcd = record.template getRecord(); - edm::ESHandle baseSettings; - baseRcd.get(baseSettings); + auto const& baseSettings = baseRcd.get(baseSettings_token); - return std::make_unique(*(baseSettings.product())); + return std::make_unique(baseSettings); } //define this as a plug-in diff --git a/L1TriggerConfig/L1TConfigProducers/src/L1TUtmTriggerMenuOnlineProd.cc b/L1TriggerConfig/L1TConfigProducers/src/L1TUtmTriggerMenuOnlineProd.cc index 0870b8692d51e..2dd82dadb59df 100644 --- a/L1TriggerConfig/L1TConfigProducers/src/L1TUtmTriggerMenuOnlineProd.cc +++ b/L1TriggerConfig/L1TConfigProducers/src/L1TUtmTriggerMenuOnlineProd.cc @@ -28,7 +28,9 @@ class L1TUtmTriggerMenuOnlineProd : public L1ConfigOnlineProdBaseExt(iConfig) {} + : L1ConfigOnlineProdBaseExt(iConfig) { + wrappedSetWhatProduced(iConfig); +} std::unique_ptr L1TUtmTriggerMenuOnlineProd::newObject(const std::string& objectKey, const L1TUtmTriggerMenuO2ORcd& record) { diff --git a/PhysicsTools/NanoAOD/python/nano_cff.py b/PhysicsTools/NanoAOD/python/nano_cff.py index 58c5a1f3e3845..dcfb273492b98 100644 --- a/PhysicsTools/NanoAOD/python/nano_cff.py +++ b/PhysicsTools/NanoAOD/python/nano_cff.py @@ -146,7 +146,7 @@ import RecoTauTag.RecoTau.tools.runTauIdMVA as tauIdConfig def nanoAOD_addTauIds(process): updatedTauName = "slimmedTausUpdated" - tauIdEmbedder = tauIdConfig.TauIDEmbedder(process, cms, debug = False, updatedTauName = updatedTauName, + tauIdEmbedder = tauIdConfig.TauIDEmbedder(process, debug = False, updatedTauName = updatedTauName, toKeep = [ "deepTau2017v2p1" ]) tauIdEmbedder.runTauID() process.patTauMVAIDsSeq.insert(process.patTauMVAIDsSeq.index(getattr(process, updatedTauName)), diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/tauProducer_cfi.py b/PhysicsTools/PatAlgos/python/producersLayer1/tauProducer_cfi.py index 585e22b86a37e..a3ad88c7648ad 100644 --- a/PhysicsTools/PatAlgos/python/producersLayer1/tauProducer_cfi.py +++ b/PhysicsTools/PatAlgos/python/producersLayer1/tauProducer_cfi.py @@ -164,3 +164,4 @@ def containerID(pset, inputID, provCfgLabel, wps): ["againstElectronTightMVA6", "_Tight"], ["againstElectronVTightMVA6", "_VTight"] ]) +singleID(patTaus.tauIDSources, "hpsPFTauDiscriminationByDeadECALElectronRejection", "againstElectronDeadECAL") diff --git a/PhysicsTools/PatAlgos/python/slimming/MicroEventContent_cff.py b/PhysicsTools/PatAlgos/python/slimming/MicroEventContent_cff.py index 95186b80942a7..a77ab064adf8a 100644 --- a/PhysicsTools/PatAlgos/python/slimming/MicroEventContent_cff.py +++ b/PhysicsTools/PatAlgos/python/slimming/MicroEventContent_cff.py @@ -2,7 +2,6 @@ MicroEventContent = cms.PSet( outputCommands = cms.untracked.vstring( - 'drop *', 'keep *_slimmedPhotons_*_*', 'keep *_slimmedOOTPhotons_*_*', 'keep *_slimmedElectrons_*_*', diff --git a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py index 3a13dd584b065..d4792ca7fe4dc 100644 --- a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py +++ b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py @@ -335,7 +335,7 @@ def miniAOD_customizeCommon(process): _noUpdatedTauName = 'slimmedTausNoDeepIDs' import RecoTauTag.RecoTau.tools.runTauIdMVA as tauIdConfig tauIdEmbedder = tauIdConfig.TauIDEmbedder( - process, cms, debug = False, + process, debug = False, updatedTauName = _updatedTauName, toKeep = ['deepTau2017v2p1'] ) diff --git a/PhysicsTools/PatAlgos/python/tools/tauTools.py b/PhysicsTools/PatAlgos/python/tools/tauTools.py index d63e5f1be200f..7beb431372102 100644 --- a/PhysicsTools/PatAlgos/python/tools/tauTools.py +++ b/PhysicsTools/PatAlgos/python/tools/tauTools.py @@ -154,6 +154,7 @@ def _switchToPFTau(process, ("againstElectronMediumMVA6", "DiscriminationByMVA6MediumElectronRejection"), ("againstElectronTightMVA6", "DiscriminationByMVA6TightElectronRejection"), ("againstElectronVTightMVA6", "DiscriminationByMVA6VTightElectronRejection"), + ("againstElectronDeadECAL", "DiscriminationByDeadECALElectronRejection"), ] # switch to PFTau collection produced for fixed dR = 0.07 signal cone size diff --git a/RecoEgamma/EgammaElectronAlgos/interface/GsfElectronAlgo.h b/RecoEgamma/EgammaElectronAlgos/interface/GsfElectronAlgo.h index 723ff6262064d..20808bca37811 100644 --- a/RecoEgamma/EgammaElectronAlgos/interface/GsfElectronAlgo.h +++ b/RecoEgamma/EgammaElectronAlgos/interface/GsfElectronAlgo.h @@ -78,13 +78,15 @@ class GsfElectronAlgo { bool ecalDrivenEcalErrorFromClassBasedParameterization; bool pureTrackerDrivenEcalErrorFromSimpleParameterization; // ambiguity solving - bool applyAmbResolution; // if not true, ambiguity solving is not applied + bool applyAmbResolution; // if not true, ambiguity solving is not applied + bool ignoreNotPreselected; unsigned ambSortingStrategy; // 0:isBetter, 1:isInnermost unsigned ambClustersOverlapStrategy; // 0:sc adresses, 1:bc shared energy // for backward compatibility bool ctfTracksCheck; float PreSelectMVA; float MaxElePtForOnlyMVA; + bool useDefaultEnergyCorrection; // GED-Regression (ECAL and combination) bool useEcalRegression; bool useCombinationRegression; diff --git a/RecoEgamma/EgammaElectronAlgos/src/GsfElectronAlgo.cc b/RecoEgamma/EgammaElectronAlgos/src/GsfElectronAlgo.cc index 0d55de9099de3..cc2fda34d103d 100644 --- a/RecoEgamma/EgammaElectronAlgos/src/GsfElectronAlgo.cc +++ b/RecoEgamma/EgammaElectronAlgos/src/GsfElectronAlgo.cc @@ -952,7 +952,7 @@ void GsfElectronAlgo::createElectron(reco::GsfElectronCollection& electrons, // momentum // Keep the default correction running first. The track momentum error is computed in there - if (ele.core()->ecalDrivenSeed() && !unexpectedClassification) { + if (cfg_.strategy.useDefaultEnergyCorrection && ele.core()->ecalDrivenSeed() && !unexpectedClassification) { if (ele.p4Error(reco::GsfElectron::P4_COMBINATION) != 999.) { edm::LogWarning("ElectronMomentumCorrector::correct") << "already done"; } else { diff --git a/RecoEgamma/EgammaElectronProducers/plugins/GsfElectronProducer.cc b/RecoEgamma/EgammaElectronProducers/plugins/GsfElectronProducer.cc index cc43ec9f4c4f3..872d1488bb793 100644 --- a/RecoEgamma/EgammaElectronProducers/plugins/GsfElectronProducer.cc +++ b/RecoEgamma/EgammaElectronProducers/plugins/GsfElectronProducer.cc @@ -131,12 +131,14 @@ void GsfElectronProducer::fillDescriptions(edm::ConfigurationDescriptions& descr desc.add("checkHcalStatus", true); // steering + desc.add("useDefaultEnergyCorrection", true); desc.add("useCombinationRegression", false); desc.add("ecalDrivenEcalEnergyFromClassBasedParameterization", true); desc.add("ecalDrivenEcalErrorFromClassBasedParameterization", true); desc.add("applyPreselection", false); desc.add("useEcalRegression", false); desc.add("applyAmbResolution", false); + desc.add("ignoreNotPreselected", true); desc.add("useGsfPfRecTracks", true); desc.add("pureTrackerDrivenEcalErrorFromSimpleParameterization", true); desc.add("ambSortingStrategy", 1); @@ -306,6 +308,7 @@ GsfElectronProducer::GsfElectronProducer(const edm::ParameterSet& cfg, const Gsf if (cfg.getParameter("fillConvVtxFitProb")) inputCfg_.conversions = consumes(cfg.getParameter("conversionsTag")); + strategyCfg_.useDefaultEnergyCorrection = cfg.getParameter("useDefaultEnergyCorrection"); strategyCfg_.applyPreselection = cfg.getParameter("applyPreselection"); strategyCfg_.ecalDrivenEcalEnergyFromClassBasedParameterization = cfg.getParameter("ecalDrivenEcalEnergyFromClassBasedParameterization"); @@ -314,6 +317,7 @@ GsfElectronProducer::GsfElectronProducer(const edm::ParameterSet& cfg, const Gsf strategyCfg_.pureTrackerDrivenEcalErrorFromSimpleParameterization = cfg.getParameter("pureTrackerDrivenEcalErrorFromSimpleParameterization"); strategyCfg_.applyAmbResolution = cfg.getParameter("applyAmbResolution"); + strategyCfg_.ignoreNotPreselected = cfg.getParameter("ignoreNotPreselected"); strategyCfg_.ambSortingStrategy = cfg.getParameter("ambSortingStrategy"); strategyCfg_.ambClustersOverlapStrategy = cfg.getParameter("ambClustersOverlapStrategy"); strategyCfg_.ctfTracksCheck = cfg.getParameter("ctfTracksCheck"); @@ -572,7 +576,7 @@ void GsfElectronProducer::produce(edm::Event& event, const edm::EventSetup& setu logElectrons(electrons, event, "GsfElectronAlgo Info (after preselection)"); } // ambiguity - setAmbiguityData(electrons, event); + setAmbiguityData(electrons, event, strategyCfg_.ignoreNotPreselected); if (strategyCfg_.applyAmbResolution) { electrons.erase(std::remove_if(electrons.begin(), electrons.end(), std::mem_fn(&reco::GsfElectron::ambiguous)), electrons.end()); diff --git a/RecoEgamma/EgammaElectronProducers/python/gsfElectrons_cfi.py b/RecoEgamma/EgammaElectronProducers/python/gsfElectrons_cfi.py index 4d17986b031b3..04801b705451f 100644 --- a/RecoEgamma/EgammaElectronProducers/python/gsfElectrons_cfi.py +++ b/RecoEgamma/EgammaElectronProducers/python/gsfElectrons_cfi.py @@ -29,5 +29,10 @@ pp_on_AA_2018.toModify(ecalDrivenGsfElectrons.preselection, minSCEtEndcaps = 15.0) ecalDrivenGsfElectronsFromMultiCl = ecalDrivenGsfElectrons.clone( - gsfElectronCoresTag = "ecalDrivenGsfElectronCoresFromMultiCl", + gsfElectronCoresTag = "ecalDrivenGsfElectronCoresFromMultiCl", + useGsfPfRecTracks = False, + useDefaultEnergyCorrection = False, + ambClustersOverlapStrategy = 0, + applyAmbResolution = True, + ignoreNotPreselected = False, ) diff --git a/RecoEgamma/EgammaHLTProducers/plugins/EgammaHLTGsfTrackVarProducer.cc b/RecoEgamma/EgammaHLTProducers/plugins/EgammaHLTGsfTrackVarProducer.cc index b7e26f9b47048..46c72f32af0c6 100644 --- a/RecoEgamma/EgammaHLTProducers/plugins/EgammaHLTGsfTrackVarProducer.cc +++ b/RecoEgamma/EgammaHLTProducers/plugins/EgammaHLTGsfTrackVarProducer.cc @@ -86,8 +86,8 @@ EgammaHLTGsfTrackVarProducer::EgammaHLTGsfTrackVarProducer(const edm::ParameterS oneOverESeedMinusOneOverPMapPutToken_{produces("OneOESeedMinusOneOP")}, missingHitsMapPutToken_{ produces("MissingHits").setBranchAlias("missinghits")}, - validHitsMapPutToken_{produces("Chi2").setBranchAlias("chi2")}, - chi2MapPutToken_{produces("ValidHits").setBranchAlias("validhits")} {} + validHitsMapPutToken_{produces("ValidHits").setBranchAlias("validhits")}, + chi2MapPutToken_{produces("Chi2").setBranchAlias("chi2")} {} void EgammaHLTGsfTrackVarProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; @@ -197,11 +197,11 @@ void EgammaHLTGsfTrackVarProducer::produce(edm::StreamID, edm::Event& iEvent, co missingHitsValue = gsfTracks[trkNr]->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS); } - if (gsfTracks[trkNr]->numberOfValidHits() < validHitsValue) { + if (gsfTracks[trkNr]->numberOfValidHits() > validHitsValue) { validHitsValue = gsfTracks[trkNr]->numberOfValidHits(); } - if (gsfTracks[trkNr]->numberOfValidHits() < chi2Value) { + if (gsfTracks[trkNr]->normalizedChi2() < chi2Value) { chi2Value = gsfTracks[trkNr]->normalizedChi2(); } diff --git a/RecoEgamma/EgammaTools/interface/HGCalEgammaIDHelper.h b/RecoEgamma/EgammaTools/interface/HGCalEgammaIDHelper.h index 2d6eadb4b9a39..9e7360c6c9f55 100644 --- a/RecoEgamma/EgammaTools/interface/HGCalEgammaIDHelper.h +++ b/RecoEgamma/EgammaTools/interface/HGCalEgammaIDHelper.h @@ -14,6 +14,7 @@ #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/ESGetToken.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -78,6 +79,7 @@ class HGCalEgammaIDHelper { edm::EDGetTokenT recHitsEE_; edm::EDGetTokenT recHitsFH_; edm::EDGetTokenT recHitsBH_; + edm::ESGetToken caloGeometry_; hgcal::RecHitTools recHitTools_; bool debug_; }; diff --git a/RecoEgamma/EgammaTools/src/HGCalEgammaIDHelper.cc b/RecoEgamma/EgammaTools/src/HGCalEgammaIDHelper.cc index 5331e24782291..0dfbadabfc00d 100644 --- a/RecoEgamma/EgammaTools/src/HGCalEgammaIDHelper.cc +++ b/RecoEgamma/EgammaTools/src/HGCalEgammaIDHelper.cc @@ -14,6 +14,7 @@ HGCalEgammaIDHelper::HGCalEgammaIDHelper(const edm::ParameterSet& iConfig, edm:: recHitsEE_ = iC.consumes(eeRecHitInputTag_); recHitsFH_ = iC.consumes(fhRecHitInputTag_); recHitsBH_ = iC.consumes(bhRecHitInputTag_); + caloGeometry_ = iC.esConsumes(); pcaHelper_.setdEdXWeights(dEdXWeights_); debug_ = iConfig.getUntrackedParameter("debug", false); } @@ -26,7 +27,8 @@ void HGCalEgammaIDHelper::eventInit(const edm::Event& iEvent, const edm::EventSe edm::Handle recHitHandleBH; iEvent.getByToken(recHitsBH_, recHitHandleBH); - recHitTools_.getEventSetup(iSetup); + edm::ESHandle geom = iSetup.getHandle(caloGeometry_); + recHitTools_.setGeometry(*geom); pcaHelper_.setRecHitTools(&recHitTools_); isoHelper_.setRecHitTools(&recHitTools_); pcaHelper_.fillHitMap(*recHitHandleEE, *recHitHandleFH, *recHitHandleBH); diff --git a/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py b/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py index 18c568e4a74b4..77b647e6ce291 100644 --- a/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py +++ b/RecoHGCal/Configuration/python/RecoHGCal_EventContent_cff.py @@ -7,6 +7,7 @@ 'keep *_ticlMultiClustersFromTrackstersEM_*_*', 'keep *_ticlMultiClustersFromTrackstersHAD_*_*', 'keep *_ticlMultiClustersFromTrackstersTrk_*_*', + 'keep *_ticlMultiClustersFromTrackstersTrkEM_*_*', 'keep *_ticlMultiClustersFromTrackstersMIP_*_*', 'keep *_ticlMultiClustersFromTrackstersMerge_*_*', ) @@ -15,12 +16,15 @@ #RECO content TICL_RECO = cms.PSet( outputCommands = cms.untracked.vstring( + 'keep *_ticlTrackstersTrkEM_*_*', 'keep *_ticlTrackstersEM_*_*', 'keep *_ticlTrackstersHAD_*_*', 'keep *_ticlTrackstersTrk_*_*', 'keep *_ticlTrackstersMIP_*_*', 'keep *_ticlTrackstersMerge_*_*', - 'keep *_ticlCandidateFromTracksters_*_*', + 'keep *_ticlTrackstersHFNoseEM_*_*', + 'keep *_ticlTrackstersHFNoseMIP_*_*', + 'keep *_ticlTrackstersHFNoseMerge_*_*', 'keep *_pfTICL_*_*' ) ) diff --git a/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h b/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h new file mode 100644 index 0000000000000..5f1d9388c3fe4 --- /dev/null +++ b/RecoHGCal/TICL/plugins/ClusterFilterByAlgoAndSizeAndLayerRange.h @@ -0,0 +1,55 @@ +// Authors: Marco Rovere - marco.rovere@cern.ch, Felice Pantaleo - felice.pantaleo@cern.ch +// Date: 09/2020 + +#ifndef RecoHGCal_TICL_ClusterFilterByAlgoAndSizeAndLayerRange_H__ +#define RecoHGCal_TICL_ClusterFilterByAlgoAndSizeAndLayerRange_H__ + +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "ClusterFilterBase.h" + +#include +#include + +// Filter clusters that belong to a specific algorithm +namespace ticl { + class ClusterFilterByAlgoAndSizeAndLayerRange final : public ClusterFilterBase { + public: + ClusterFilterByAlgoAndSizeAndLayerRange(const edm::ParameterSet& ps) + : ClusterFilterBase(ps), + algo_number_(ps.getParameter("algo_number")), + min_cluster_size_(ps.getParameter("min_cluster_size")), + max_cluster_size_(ps.getParameter("max_cluster_size")), + min_layerId_(ps.getParameter("min_layerId")), + max_layerId_(ps.getParameter("max_layerId")) {} + ~ClusterFilterByAlgoAndSizeAndLayerRange() override{}; + + void filter(const std::vector& layerClusters, + const HgcalClusterFilterMask& availableLayerClusters, + std::vector& layerClustersMask, + hgcal::RecHitTools& rhtools) const override { + auto filteredLayerClusters = std::make_unique(); + for (auto const& cl : availableLayerClusters) { + auto const& layerCluster = layerClusters[cl.first]; + auto const& haf = layerCluster.hitsAndFractions(); + auto layerId = rhtools.getLayerWithOffset(haf[0].first); + + if (layerCluster.algo() == algo_number_ and layerId <= max_layerId_ and layerId >= min_layerId_ and + haf.size() <= max_cluster_size_ and + (haf.size() >= min_cluster_size_ or !(rhtools.isSilicon(haf[0].first)))) { + filteredLayerClusters->emplace_back(cl); + } else { + layerClustersMask[cl.first] = 0.; + } + } + } + + private: + int algo_number_; + unsigned int min_cluster_size_; + unsigned int max_cluster_size_; + unsigned int min_layerId_; + unsigned int max_layerId_; + }; +} // namespace ticl + +#endif diff --git a/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc b/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc index e0dfc901b008e..e3f0204cf47ba 100644 --- a/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc +++ b/RecoHGCal/TICL/plugins/FilteredLayerClustersProducer.cc @@ -10,6 +10,7 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/ESGetToken.h" #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -30,6 +31,7 @@ class FilteredLayerClustersProducer : public edm::stream::EDProducer<> { private: edm::EDGetTokenT> clusters_token_; edm::EDGetTokenT> clustersMask_token_; + edm::ESGetToken caloGeometry_token_; std::string clusterFilter_; std::string iteration_label_; std::unique_ptr theFilter_; @@ -39,26 +41,32 @@ class FilteredLayerClustersProducer : public edm::stream::EDProducer<> { DEFINE_FWK_MODULE(FilteredLayerClustersProducer); FilteredLayerClustersProducer::FilteredLayerClustersProducer(const edm::ParameterSet& ps) { - clusters_token_ = consumes>(ps.getParameter("HGCLayerClusters")); + clusters_token_ = consumes>(ps.getParameter("LayerClusters")); clustersMask_token_ = consumes>(ps.getParameter("LayerClustersInputMask")); + caloGeometry_token_ = esConsumes(); clusterFilter_ = ps.getParameter("clusterFilter"); theFilter_ = ClusterFilterFactory::get()->create(clusterFilter_, ps); iteration_label_ = ps.getParameter("iteration_label"); produces>(iteration_label_); } -void FilteredLayerClustersProducer::beginRun(edm::Run const&, edm::EventSetup const& es) { rhtools_.getEventSetup(es); } +void FilteredLayerClustersProducer::beginRun(edm::Run const&, edm::EventSetup const& es) { + edm::ESHandle geom = es.getHandle(caloGeometry_token_); + rhtools_.setGeometry(*geom); +} void FilteredLayerClustersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { // hgcalMultiClusters edm::ParameterSetDescription desc; - desc.add("HGCLayerClusters", edm::InputTag("hgcalLayerClusters")); + desc.add("LayerClusters", edm::InputTag("hgcalLayerClusters")); desc.add("LayerClustersInputMask", edm::InputTag("hgcalLayerClusters", "InitialLayerClustersMask")); desc.add("iteration_label", "iterationLabelGoesHere"); desc.add("clusterFilter", "ClusterFilterByAlgoAndSize"); desc.add("algo_number", 9); desc.add("min_cluster_size", 0); desc.add("max_cluster_size", 9999); + desc.add("min_layerId", 0); + desc.add("max_layerId", 9999); descriptions.add("filteredLayerClustersProducer", desc); } diff --git a/RecoHGCal/TICL/plugins/HGCDoublet.cc b/RecoHGCal/TICL/plugins/HGCDoublet.cc index 2cddcb6684288..cac2c4d1a52df 100644 --- a/RecoHGCal/TICL/plugins/HGCDoublet.cc +++ b/RecoHGCal/TICL/plugins/HGCDoublet.cc @@ -81,14 +81,17 @@ int HGCDoublet::areAligned(double xi, // inner product auto dot = dx1 * dx2 + dy1 * dy2 + dz1 * dz2; + auto dotsq = dot * dot; // magnitudes - auto mag1 = std::sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1); - auto mag2 = std::sqrt(dx2 * dx2 + dy2 * dy2 + dz2 * dz2); - // angle between the vectors - auto cosTheta = dot / (mag1 * mag2); + auto mag1sq = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; + auto mag2sq = dx2 * dx2 + dy2 * dy2 + dz2 * dz2; + + auto minCosTheta_sq = minCosTheta * minCosTheta; + bool isWithinLimits = (dotsq > minCosTheta_sq * mag1sq * mag2sq); + if (debug) { - LogDebug("HGCDoublet") << "-- Are Aligned -- dot: " << dot << " mag1: " << mag1 << " mag2: " << mag2 - << " cosTheta: " << cosTheta << " isWithinLimits: " << (cosTheta > minCosTheta) << std::endl; + LogDebug("HGCDoublet") << "-- Are Aligned -- dotsq: " << dotsq << " mag1sq: " << mag1sq << " mag2sq: " << mag2sq + << "minCosTheta_sq:" << minCosTheta_sq << " isWithinLimits: " << isWithinLimits << std::endl; } // Now check the compatibility with the pointing origin. @@ -102,15 +105,18 @@ int HGCDoublet::areAligned(double xi, const GlobalVector pointingDir = (seedIndex_ == -1) ? GlobalVector(innerX(), innerY(), innerZ()) : refDir; auto dot_pointing = pointingDir.dot(firstDoublet); - auto mag_pointing = sqrt(pointingDir.mag2()); - auto cosTheta_pointing = dot_pointing / (mag2 * mag_pointing); + auto dot_pointing_sq = dot_pointing * dot_pointing; + auto mag_pointing_sq = pointingDir.mag2(); + auto minCosPointing_sq = minCosPointing * minCosPointing; + bool isWithinLimitsPointing = (dot_pointing_sq > minCosPointing_sq * mag_pointing_sq * mag2sq); if (debug) { - LogDebug("HGCDoublet") << "-- Are Aligned -- dot_pointing: " << dot_pointing << " mag_pointing: " << mag_pointing - << " mag2: " << mag2 << " cosTheta_pointing: " << cosTheta_pointing - << " isWithinLimits: " << (cosTheta_pointing > minCosPointing) << std::endl; + LogDebug("HGCDoublet") << "-- Are Aligned -- dot_pointing_sq: " << dot_pointing * dot_pointing + << " mag_pointing_sq: " << mag_pointing_sq << " mag2sq: " << mag2sq + << " isWithinLimits: " << isWithinLimitsPointing << std::endl; } - - return (cosTheta > minCosTheta) && (cosTheta_pointing > minCosPointing); + // by squaring cosTheta and multiplying by the squares of the magnitudes + // an equivalent comparison is made without the division and square root which are costly FP ops. + return isWithinLimits && isWithinLimitsPointing; } void HGCDoublet::findNtuplets(std::vector &allDoublets, diff --git a/RecoHGCal/TICL/plugins/HGCGraph.cc b/RecoHGCal/TICL/plugins/HGCGraph.cc index 707a425b06e0f..e94b87426bc95 100644 --- a/RecoHGCal/TICL/plugins/HGCGraph.cc +++ b/RecoHGCal/TICL/plugins/HGCGraph.cc @@ -7,25 +7,30 @@ #include "HGCGraph.h" #include "DataFormats/Common/interface/ValueMap.h" -void HGCGraph::makeAndConnectDoublets(const TICLLayerTiles &histo, - const std::vector ®ions, - int nEtaBins, - int nPhiBins, - const std::vector &layerClusters, - const std::vector &mask, - const edm::ValueMap> &layerClustersTime, - int deltaIEta, - int deltaIPhi, - float minCosTheta, - float minCosPointing, - float etaLimitIncreaseWindow, - int missing_layers, - int maxNumberOfLayers, - float maxDeltaTime) { +template +void HGCGraphT::makeAndConnectDoublets(const TILES &histo, + const std::vector ®ions, + int nEtaBins, + int nPhiBins, + const std::vector &layerClusters, + const std::vector &mask, + const edm::ValueMap> &layerClustersTime, + int deltaIEta, + int deltaIPhi, + float minCosTheta, + float minCosPointing, + float root_doublet_max_distance_from_seed_squared, + float etaLimitIncreaseWindow, + int skip_layers, + int maxNumberOfLayers, + float maxDeltaTime) { isOuterClusterOfDoublets_.clear(); isOuterClusterOfDoublets_.resize(layerClusters.size()); allDoublets_.clear(); theRootDoublets_.clear(); + bool checkDistanceRootDoubletVsSeed = root_doublet_max_distance_from_seed_squared < 9999; + float origin_eta; + float origin_phi; for (const auto &r : regions) { bool isGlobal = (r.index == -1); auto zSide = r.zSide; @@ -36,19 +41,22 @@ void HGCGraph::makeAndConnectDoublets(const TICLLayerTiles &histo, startPhiBin = 0; endEtaBin = nEtaBins; endPhiBin = nPhiBins; + origin_eta = 0; + origin_phi = 0; } else { auto firstLayerOnZSide = maxNumberOfLayers * zSide; const auto &firstLayerHisto = histo[firstLayerOnZSide]; - - int entryEtaBin = firstLayerHisto.etaBin(r.origin.eta()); - int entryPhiBin = firstLayerHisto.phiBin(r.origin.phi()); + origin_eta = r.origin.eta(); + origin_phi = r.origin.phi(); + int entryEtaBin = firstLayerHisto.etaBin(origin_eta); + int entryPhiBin = firstLayerHisto.phiBin(origin_phi); // For track-seeded iterations, if the impact point is below a certain // eta-threshold, i.e., it has higher eta, make the initial search // window bigger in both eta and phi by one bin, to contain better low // energy showers. auto etaWindow = deltaIEta; auto phiWindow = deltaIPhi; - if (std::abs(r.origin.eta()) > etaLimitIncreaseWindow) { + if (std::abs(origin_eta) > etaLimitIncreaseWindow) { etaWindow++; phiWindow++; LogDebug("HGCGraph") << "Limit of Eta for increase: " << etaLimitIncreaseWindow @@ -59,9 +67,9 @@ void HGCGraph::makeAndConnectDoublets(const TICLLayerTiles &histo, startPhiBin = entryPhiBin - phiWindow; endPhiBin = entryPhiBin + phiWindow + 1; if (verbosity_ > Guru) { - LogDebug("HGCGraph") << " Entrance eta, phi: " << r.origin.eta() << ", " << r.origin.phi() + LogDebug("HGCGraph") << " Entrance eta, phi: " << origin_eta << ", " << origin_phi << " entryEtaBin: " << entryEtaBin << " entryPhiBin: " << entryPhiBin - << " globalBin: " << firstLayerHisto.globalBin(r.origin.eta(), r.origin.phi()) + << " globalBin: " << firstLayerHisto.globalBin(origin_eta, origin_phi) << " on layer: " << firstLayerOnZSide << " startEtaBin: " << startEtaBin << " endEtaBin: " << endEtaBin << " startPhiBin: " << startPhiBin << " endPhiBin: " << endPhiBin << " phiBin(0): " << firstLayerHisto.phiBin(0.) @@ -74,7 +82,7 @@ void HGCGraph::makeAndConnectDoublets(const TICLLayerTiles &histo, } for (int il = 0; il < maxNumberOfLayers - 1; ++il) { - for (int outer_layer = 0; outer_layer < std::min(1 + missing_layers, maxNumberOfLayers - 1 - il); ++outer_layer) { + for (int outer_layer = 0; outer_layer < std::min(1 + skip_layers, maxNumberOfLayers - 1 - il); ++outer_layer) { int currentInnerLayerId = il + maxNumberOfLayers * zSide; int currentOuterLayerId = currentInnerLayerId + 1 + outer_layer; auto const &outerLayerHisto = histo[currentOuterLayerId]; @@ -170,8 +178,17 @@ void HGCGraph::makeAndConnectDoublets(const TICLLayerTiles &histo, minCosTheta, minCosPointing, verbosity_ > Advanced); - if (isRootDoublet) + if (isRootDoublet and checkDistanceRootDoubletVsSeed) { + auto dEtaSquared = (layerClusters[innerClusterId].eta() - origin_eta); + dEtaSquared *= dEtaSquared; + auto dPhiSquared = (layerClusters[innerClusterId].phi() - origin_phi); + dPhiSquared *= dPhiSquared; + if (dEtaSquared + dPhiSquared > root_doublet_max_distance_from_seed_squared) + isRootDoublet = false; + } + if (isRootDoublet) { theRootDoublets_.push_back(doubletId); + } } } } @@ -189,10 +206,11 @@ void HGCGraph::makeAndConnectDoublets(const TICLLayerTiles &histo, // #endif } -bool HGCGraph::areTimeCompatible(int innerIdx, - int outerIdx, - const edm::ValueMap> &layerClustersTime, - float maxDeltaTime) { +template +bool HGCGraphT::areTimeCompatible(int innerIdx, + int outerIdx, + const edm::ValueMap> &layerClustersTime, + float maxDeltaTime) { float timeIn = layerClustersTime.get(innerIdx).first; float timeInE = layerClustersTime.get(innerIdx).second; float timeOut = layerClustersTime.get(outerIdx).first; @@ -203,11 +221,12 @@ bool HGCGraph::areTimeCompatible(int innerIdx, } //also return a vector of seedIndex for the reconstructed tracksters -void HGCGraph::findNtuplets(std::vector &foundNtuplets, - std::vector &seedIndices, - const unsigned int minClustersPerNtuplet, - const bool outInDFS, - unsigned int maxOutInHops) { +template +void HGCGraphT::findNtuplets(std::vector &foundNtuplets, + std::vector &seedIndices, + const unsigned int minClustersPerNtuplet, + const bool outInDFS, + unsigned int maxOutInHops) { HGCDoublet::HGCntuplet tmpNtuplet; tmpNtuplet.reserve(minClustersPerNtuplet); std::vector> outInToVisit; @@ -230,3 +249,6 @@ void HGCGraph::findNtuplets(std::vector &foundNtuplets, } } } + +template class HGCGraphT; +template class HGCGraphT; diff --git a/RecoHGCal/TICL/plugins/HGCGraph.h b/RecoHGCal/TICL/plugins/HGCGraph.h index 8f0a5fb3bedff..f8cc626016f40 100644 --- a/RecoHGCal/TICL/plugins/HGCGraph.h +++ b/RecoHGCal/TICL/plugins/HGCGraph.h @@ -11,9 +11,10 @@ #include "DataFormats/HGCalReco/interface/TICLSeedingRegion.h" #include "HGCDoublet.h" -class HGCGraph { +template +class HGCGraphT { public: - void makeAndConnectDoublets(const TICLLayerTiles &h, + void makeAndConnectDoublets(const TILES &h, const std::vector ®ions, int nEtaBins, int nPhiBins, @@ -24,8 +25,9 @@ class HGCGraph { int deltaIPhi, float minCosThetai, float maxCosPointing, + float root_doublet_max_distance_from_seed_squared, float etaLimitIncreaseWindow, - int missing_layers, + int skip_layers, int maxNumberOfLayers, float maxDeltaTime); diff --git a/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc b/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc index 195843d0015e8..27cf92d6c1265 100644 --- a/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc +++ b/RecoHGCal/TICL/plugins/MultiClustersFromTrackstersProducer.cc @@ -63,13 +63,14 @@ void MultiClustersFromTrackstersProducer::produce(edm::Event& evt, const edm::Ev } std::for_each(std::begin(tracksters), std::end(tracksters), [&](auto const& trackster) { - // Do not create a multicluster if the trackster has no layer clusters. + // Create an empty multicluster if the trackster has no layer clusters. // This could happen when a seed leads to no trackster and a dummy one is produced. + + std::array baricenter{{0., 0., 0.}}; + double total_weight = 0.; + reco::HGCalMultiCluster temp; + int counter = 0; if (!trackster.vertices().empty()) { - std::array baricenter{{0., 0., 0.}}; - double total_weight = 0.; - reco::HGCalMultiCluster temp; - int counter = 0; std::for_each(std::begin(trackster.vertices()), std::end(trackster.vertices()), [&](unsigned int idx) { temp.push_back(clusterPtrs[idx]); auto fraction = 1.f / trackster.vertex_multiplicity(counter++); @@ -86,13 +87,13 @@ void MultiClustersFromTrackstersProducer::produce(edm::Event& evt, const edm::Ev std::begin(baricenter), std::end(baricenter), std::begin(baricenter), [&total_weight](double val) -> double { return val / total_weight; }); - temp.setEnergy(total_weight); - temp.setCorrectedEnergy(total_weight); - temp.setPosition(math::XYZPoint(baricenter[0], baricenter[1], baricenter[2])); - temp.setAlgoId(reco::CaloCluster::hgcal_em); - temp.setTime(trackster.time(), trackster.timeError()); - multiclusters->push_back(temp); } + temp.setEnergy(total_weight); + temp.setCorrectedEnergy(total_weight); + temp.setPosition(math::XYZPoint(baricenter[0], baricenter[1], baricenter[2])); + temp.setAlgoId(reco::CaloCluster::hgcal_em); + temp.setTime(trackster.time(), trackster.timeError()); + multiclusters->push_back(temp); }); evt.put(std::move(multiclusters)); diff --git a/RecoHGCal/TICL/plugins/PFTICLProducer.cc b/RecoHGCal/TICL/plugins/PFTICLProducer.cc index 443340944b39b..1c9f9b35035ed 100644 --- a/RecoHGCal/TICL/plugins/PFTICLProducer.cc +++ b/RecoHGCal/TICL/plugins/PFTICLProducer.cc @@ -36,7 +36,7 @@ PFTICLProducer::PFTICLProducer(const edm::ParameterSet& conf) void PFTICLProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; - desc.add("ticlCandidateSrc", edm::InputTag("ticlCandidateFromTracksters")); + desc.add("ticlCandidateSrc", edm::InputTag("ticlTrackstersMerge")); descriptions.add("pfTICLProducer", desc); } @@ -52,6 +52,15 @@ void PFTICLProducer::produce(edm::StreamID, edm::Event& evt, const edm::EventSet const auto abs_pdg_id = std::abs(ticl_cand.pdgId()); const auto charge = ticl_cand.charge(); const auto& four_mom = ticl_cand.p4(); + double ecal_energy = 0.; + + for (const auto& t : ticl_cand.tracksters()) { + double ecal_energy_fraction = t->raw_em_pt() / t->raw_pt(); + ecal_energy += t->raw_energy() * ecal_energy_fraction; + } + double hcal_energy = ticl_cand.rawEnergy() - ecal_energy; + // fix for floating point rounding could go slightly below 0 + hcal_energy = hcal_energy < 0 ? 0 : hcal_energy; reco::PFCandidate::ParticleType part_type; switch (abs_pdg_id) { @@ -78,6 +87,8 @@ void PFTICLProducer::produce(edm::StreamID, edm::Event& evt, const edm::EventSet candidates->emplace_back(charge, four_mom, part_type); auto& candidate = candidates->back(); + candidate.setEcalEnergy(ecal_energy, ecal_energy); + candidate.setHcalEnergy(hcal_energy, hcal_energy); if (candidate.charge()) { // otherwise PFCandidate throws // Construct edm::Ref from edm::Ptr. As of now, assumes type to be reco::Track. To be extended (either via // dynamic type checking or configuration) if additional track types are needed. diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionAlgoBase.h b/RecoHGCal/TICL/plugins/PatternRecognitionAlgoBase.h index e9e67e7d5c959..23edaac568a6f 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionAlgoBase.h +++ b/RecoHGCal/TICL/plugins/PatternRecognitionAlgoBase.h @@ -7,7 +7,6 @@ #include #include #include "DataFormats/CaloRecHit/interface/CaloCluster.h" -#include "DataFormats/HGCalReco/interface/Common.h" #include "DataFormats/HGCalReco/interface/Trackster.h" #include "DataFormats/HGCalReco/interface/TICLLayerTile.h" #include "DataFormats/HGCalReco/interface/TICLSeedingRegion.h" @@ -21,11 +20,12 @@ namespace edm { } // namespace edm namespace ticl { - class PatternRecognitionAlgoBase { + template + class PatternRecognitionAlgoBaseT { public: - PatternRecognitionAlgoBase(const edm::ParameterSet& conf, const CacheBase* cache) + PatternRecognitionAlgoBaseT(const edm::ParameterSet& conf, const CacheBase* cache) : algo_verbosity_(conf.getParameter("algo_verbosity")) {} - virtual ~PatternRecognitionAlgoBase(){}; + virtual ~PatternRecognitionAlgoBaseT(){}; struct Inputs { const edm::Event& ev; @@ -33,7 +33,7 @@ namespace ticl { const std::vector& layerClusters; const std::vector& mask; const edm::ValueMap>& layerClustersTime; - const TICLLayerTiles& tiles; + const TILES& tiles; const std::vector& regions; Inputs(const edm::Event& eV, @@ -41,7 +41,7 @@ namespace ticl { const std::vector& lC, const std::vector& mS, const edm::ValueMap>& lT, - const TICLLayerTiles& tL, + const TILES& tL, const std::vector& rG) : ev(eV), es(eS), layerClusters(lC), mask(mS), layerClustersTime(lT), tiles(tL), regions(rG) {} }; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc index a782a56787efc..8340aa261fea8 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.cc @@ -7,25 +7,38 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/Exception.h" #include "PatternRecognitionbyCA.h" -#include "HGCGraph.h" #include "RecoLocalCalo/HGCalRecProducers/interface/ComputeClusterTime.h" #include "TrackstersPCA.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "FWCore/Framework/interface/EventSetup.h" using namespace ticl; -PatternRecognitionbyCA::PatternRecognitionbyCA(const edm::ParameterSet &conf, const CacheBase *cache) - : PatternRecognitionAlgoBase(conf, cache), - theGraph_(std::make_unique()), +template +PatternRecognitionbyCA::PatternRecognitionbyCA(const edm::ParameterSet &conf, const CacheBase *cache) + : PatternRecognitionAlgoBaseT(conf, cache), + theGraph_(std::make_unique>()), oneTracksterPerTrackSeed_(conf.getParameter("oneTracksterPerTrackSeed")), promoteEmptyRegionToTrackster_(conf.getParameter("promoteEmptyRegionToTrackster")), out_in_dfs_(conf.getParameter("out_in_dfs")), max_out_in_hops_(conf.getParameter("max_out_in_hops")), min_cos_theta_(conf.getParameter("min_cos_theta")), min_cos_pointing_(conf.getParameter("min_cos_pointing")), + root_doublet_max_distance_from_seed_squared_( + conf.getParameter("root_doublet_max_distance_from_seed_squared")), etaLimitIncreaseWindow_(conf.getParameter("etaLimitIncreaseWindow")), - missing_layers_(conf.getParameter("missing_layers")), - min_clusters_per_ntuplet_(conf.getParameter("min_clusters_per_ntuplet")), + skip_layers_(conf.getParameter("skip_layers")), + max_missing_layers_in_trackster_(conf.getParameter("max_missing_layers_in_trackster")), + check_missing_layers_(max_missing_layers_in_trackster_ < 100), + shower_start_max_layer_(conf.getParameter("shower_start_max_layer")), + min_layers_per_trackster_(conf.getParameter("min_layers_per_trackster")), + filter_on_categories_(conf.getParameter>("filter_on_categories")), + pid_threshold_(conf.getParameter("pid_threshold")), + energy_em_over_total_threshold_(conf.getParameter("energy_em_over_total_threshold")), + max_longitudinal_sigmaPCA_(conf.getParameter("max_longitudinal_sigmaPCA")), + min_clusters_per_ntuplet_(min_layers_per_trackster_), max_delta_time_(conf.getParameter("max_delta_time")), eidInputName_(conf.getParameter("eid_input_name")), eidOutputNameEnergy_(conf.getParameter("eid_output_name_energy")), @@ -43,31 +56,41 @@ PatternRecognitionbyCA::PatternRecognitionbyCA(const edm::ParameterSet &conf, co eidSession_ = tensorflow::createSession(trackstersCache->eidGraphDef); } -PatternRecognitionbyCA::~PatternRecognitionbyCA(){}; +template +PatternRecognitionbyCA::~PatternRecognitionbyCA(){}; -void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::Inputs &input, - std::vector &result, - std::unordered_map> &seedToTracksterAssociation) { +template +void PatternRecognitionbyCA::makeTracksters( + const typename PatternRecognitionAlgoBaseT::Inputs &input, + std::vector &result, + std::unordered_map> &seedToTracksterAssociation) { // Protect from events with no seeding regions if (input.regions.empty()) return; - rhtools_.getEventSetup(input.es); + edm::ESHandle geom; + edm::EventSetup const &es = input.es; + es.get().get(geom); + rhtools_.setGeometry(*geom); - theGraph_->setVerbosity(algo_verbosity_); + theGraph_->setVerbosity(PatternRecognitionAlgoBaseT::algo_verbosity_); theGraph_->clear(); - if (algo_verbosity_ > None) { + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::None) { LogDebug("HGCPatternRecoByCA") << "Making Tracksters with CA" << std::endl; } + int type = input.tiles[0].typeT(); + int nEtaBin = (type == 1) ? ticl::TileConstantsHFNose::nEtaBins : ticl::TileConstants::nEtaBins; + int nPhiBin = (type == 1) ? ticl::TileConstantsHFNose::nPhiBins : ticl::TileConstants::nPhiBins; + bool isRegionalIter = (input.regions[0].index != -1); std::vector foundNtuplets; std::vector seedIndices; std::vector layer_cluster_usage(input.layerClusters.size(), 0); theGraph_->makeAndConnectDoublets(input.tiles, input.regions, - ticl::TileConstants::nEtaBins, - ticl::TileConstants::nPhiBins, + nEtaBin, + nPhiBin, input.layerClusters, input.mask, input.layerClustersTime, @@ -75,17 +98,24 @@ void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::In 1, min_cos_theta_, min_cos_pointing_, + root_doublet_max_distance_from_seed_squared_, etaLimitIncreaseWindow_, - missing_layers_, - rhtools_.lastLayerFH(), + skip_layers_, + rhtools_.lastLayer(type), max_delta_time_); theGraph_->findNtuplets(foundNtuplets, seedIndices, min_clusters_per_ntuplet_, out_in_dfs_, max_out_in_hops_); //#ifdef FP_DEBUG const auto &doublets = theGraph_->getAllDoublets(); - int tracksterId = 0; + int tracksterId = -1; + + // container for holding tracksters before selection + std::vector tmpTracksters; + tmpTracksters.reserve(foundNtuplets.size()); for (auto const &ntuplet : foundNtuplets) { + tracksterId++; + std::set effective_cluster_idx; std::pair::iterator, bool> retVal; @@ -114,7 +144,7 @@ void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::In } } - if (algo_verbosity_ > Advanced) { + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Advanced) { LogDebug("HGCPatternRecoByCA") << " New doublet " << doublet << " for trackster: " << result.size() << " InnerCl " << innerCluster << " " << input.layerClusters[innerCluster].x() << " " << input.layerClusters[innerCluster].y() << " " @@ -124,41 +154,113 @@ void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::In << input.layerClusters[outerCluster].z() << " " << tracksterId << std::endl; } } + unsigned showerMinLayerId = 99999; + std::vector uniqueLayerIds; + uniqueLayerIds.reserve(effective_cluster_idx.size()); + std::vector> lcIdAndLayer; + lcIdAndLayer.reserve(effective_cluster_idx.size()); for (auto const i : effective_cluster_idx) { - layer_cluster_usage[i]++; - if (algo_verbosity_ > Basic) - LogDebug("HGCPatternRecoByCA") << "LayerID: " << i << " count: " << (int)layer_cluster_usage[i] << std::endl; + auto const &haf = input.layerClusters[i].hitsAndFractions(); + auto layerId = rhtools_.getLayerWithOffset(haf[0].first); + showerMinLayerId = std::min(layerId, showerMinLayerId); + uniqueLayerIds.push_back(layerId); + lcIdAndLayer.emplace_back(i, layerId); } - // Put back indices, in the form of a Trackster, into the results vector - Trackster tmp; - tmp.vertices().reserve(effective_cluster_idx.size()); - tmp.vertex_multiplicity().resize(effective_cluster_idx.size(), 0); - //regions and seedIndices can have different size - //if a seeding region does not lead to any trackster - tmp.setSeed(input.regions[0].collectionID, seedIndices[tracksterId]); - if (isRegionalIter) { - seedToTracksterAssociation[tmp.seedIndex()].push_back(tracksterId); + std::sort(uniqueLayerIds.begin(), uniqueLayerIds.end()); + uniqueLayerIds.erase(std::unique(uniqueLayerIds.begin(), uniqueLayerIds.end()), uniqueLayerIds.end()); + unsigned int numberOfLayersInTrackster = uniqueLayerIds.size(); + if (check_missing_layers_) { + int numberOfMissingLayers = 0; + unsigned int j = showerMinLayerId; + unsigned int indexInVec = 0; + for (const auto &layer : uniqueLayerIds) { + if (layer != j) { + numberOfMissingLayers++; + j++; + if (numberOfMissingLayers > max_missing_layers_in_trackster_) { + numberOfLayersInTrackster = indexInVec; + for (auto &llpair : lcIdAndLayer) { + if (llpair.second >= layer) { + effective_cluster_idx.erase(llpair.first); + } + } + break; + } + } + indexInVec++; + j++; + } } - std::pair timeTrackster(-99., -1.); - hgcalsimclustertime::ComputeClusterTime timeEstimator; - timeTrackster = timeEstimator.fixSizeHighestDensity(times, timeErrors); - tmp.setTimeAndError(timeTrackster.first, timeTrackster.second); - std::copy(std::begin(effective_cluster_idx), std::end(effective_cluster_idx), std::back_inserter(tmp.vertices())); - result.push_back(tmp); - tracksterId++; + if ((numberOfLayersInTrackster >= min_layers_per_trackster_) and (showerMinLayerId <= shower_start_max_layer_)) { + // Put back indices, in the form of a Trackster, into the results vector + Trackster tmp; + tmp.vertices().reserve(effective_cluster_idx.size()); + tmp.vertex_multiplicity().resize(effective_cluster_idx.size(), 1); + //regions and seedIndices can have different size + //if a seeding region does not lead to any trackster + tmp.setSeed(input.regions[0].collectionID, seedIndices[tracksterId]); + + std::pair timeTrackster(-99., -1.); + hgcalsimclustertime::ComputeClusterTime timeEstimator; + timeTrackster = timeEstimator.fixSizeHighestDensity(times, timeErrors); + tmp.setTimeAndError(timeTrackster.first, timeTrackster.second); + std::copy(std::begin(effective_cluster_idx), std::end(effective_cluster_idx), std::back_inserter(tmp.vertices())); + tmpTracksters.push_back(tmp); + } + } + ticl::assignPCAtoTracksters( + tmpTracksters, input.layerClusters, rhtools_.getPositionLayer(rhtools_.lastLayerEE(type)).z()); + + // run energy regression and ID + energyRegressionAndID(input.layerClusters, tmpTracksters); + // Filter results based on PID criteria or EM/Total energy ratio. + // We want to **keep** tracksters whose cumulative + // probability summed up over the selected categories + // is greater than the chosen threshold. Therefore + // the filtering function should **discard** all + // tracksters **below** the threshold. + auto filter_on_pids = [&](Trackster &t) -> bool { + auto cumulative_prob = 0.; + for (auto index : filter_on_categories_) { + cumulative_prob += t.id_probabilities(index); + } + return (cumulative_prob <= pid_threshold_) && + (t.raw_em_energy() < energy_em_over_total_threshold_ * t.raw_energy()); + }; + + std::vector selectedTrackstersIds; + for (unsigned i = 0; i < tmpTracksters.size(); ++i) { + if (!filter_on_pids(tmpTracksters[i]) and tmpTracksters[i].sigmasPCA()[0] < max_longitudinal_sigmaPCA_) { + selectedTrackstersIds.push_back(i); + } + } + + result.reserve(selectedTrackstersIds.size()); + + for (unsigned i = 0; i < selectedTrackstersIds.size(); ++i) { + const auto &t = tmpTracksters[selectedTrackstersIds[i]]; + for (auto const lcId : t.vertices()) { + layer_cluster_usage[lcId]++; + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) + LogDebug("HGCPatternRecoByCA") << "LayerID: " << lcId << " count: " << (int)layer_cluster_usage[lcId] + << std::endl; + } + if (isRegionalIter) { + seedToTracksterAssociation[t.seedIndex()].push_back(i); + } + result.push_back(t); } for (auto &trackster : result) { assert(trackster.vertices().size() <= trackster.vertex_multiplicity().size()); for (size_t i = 0; i < trackster.vertices().size(); ++i) { trackster.vertex_multiplicity()[i] = layer_cluster_usage[trackster.vertices(i)]; - if (algo_verbosity_ > Basic) + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) LogDebug("HGCPatternRecoByCA") << "LayerID: " << trackster.vertices(i) << " count: " << (int)trackster.vertex_multiplicity(i) << std::endl; } } - // Now decide if the tracksters from the track-based iterations have to be merged if (oneTracksterPerTrackSeed_) { std::vector tmp; @@ -166,8 +268,7 @@ void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::In tmp.swap(result); } - ticl::assignPCAtoTracksters(result, input.layerClusters, rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z()); - + ticl::assignPCAtoTracksters(result, input.layerClusters, rhtools_.getPositionLayer(rhtools_.lastLayerEE(type)).z()); // run energy regression and ID energyRegressionAndID(input.layerClusters, result); @@ -177,7 +278,7 @@ void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::In emptyTrackstersFromSeedsTRK(result, seedToTracksterAssociation, input.regions[0].collectionID); } - if (algo_verbosity_ > Advanced) { + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Advanced) { for (auto &trackster : result) { LogDebug("HGCPatternRecoByCA") << "Trackster characteristics: " << std::endl; LogDebug("HGCPatternRecoByCA") << "Size: " << trackster.vertices().size() << std::endl; @@ -190,7 +291,8 @@ void PatternRecognitionbyCA::makeTracksters(const PatternRecognitionAlgoBase::In theGraph_->clear(); } -void PatternRecognitionbyCA::mergeTrackstersTRK( +template +void PatternRecognitionbyCA::mergeTrackstersTRK( const std::vector &input, const std::vector &layerClusters, std::vector &output, @@ -207,7 +309,7 @@ void PatternRecognitionbyCA::mergeTrackstersTRK( for (unsigned int j = 1; j < numberOfTrackstersInSeed; ++j) { auto &thisTrackster = input[tracksters[j]]; updated_size += thisTrackster.vertices().size(); - if (algo_verbosity_ > Basic) { + if (PatternRecognitionAlgoBaseT::algo_verbosity_ > PatternRecognitionAlgoBaseT::Basic) { LogDebug("HGCPatternRecoByCA") << "Updated size: " << updated_size << std::endl; } outTrackster.vertices().reserve(updated_size); @@ -225,7 +327,8 @@ void PatternRecognitionbyCA::mergeTrackstersTRK( output.shrink_to_fit(); } -void PatternRecognitionbyCA::emptyTrackstersFromSeedsTRK( +template +void PatternRecognitionbyCA::emptyTrackstersFromSeedsTRK( std::vector &tracksters, std::unordered_map> &seedToTracksterAssociation, const edm::ProductID &collectionID) const { @@ -242,8 +345,9 @@ void PatternRecognitionbyCA::emptyTrackstersFromSeedsTRK( } } -void PatternRecognitionbyCA::energyRegressionAndID(const std::vector &layerClusters, - std::vector &tracksters) { +template +void PatternRecognitionbyCA::energyRegressionAndID(const std::vector &layerClusters, + std::vector &tracksters) { // Energy regression and particle identification strategy: // // 1. Set default values for regressed energy and particle id for each trackster. @@ -379,3 +483,6 @@ void PatternRecognitionbyCA::energyRegressionAndID(const std::vector; +template class ticl::PatternRecognitionbyCA; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h index c39f21d9ec40b..c337dd344ec78 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyCA.h @@ -7,16 +7,16 @@ #include "RecoHGCal/TICL/plugins/PatternRecognitionAlgoBase.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" #include "PhysicsTools/TensorFlow/interface/TensorFlow.h" - -class HGCGraph; +#include "HGCGraph.h" namespace ticl { - class PatternRecognitionbyCA final : public PatternRecognitionAlgoBase { + template + class PatternRecognitionbyCA final : public PatternRecognitionAlgoBaseT { public: PatternRecognitionbyCA(const edm::ParameterSet& conf, const CacheBase* cache); ~PatternRecognitionbyCA() override; - void makeTracksters(const PatternRecognitionAlgoBase::Inputs& input, + void makeTracksters(const typename PatternRecognitionAlgoBaseT::Inputs& input, std::vector& result, std::unordered_map>& seedToTracksterAssociation) override; @@ -30,15 +30,24 @@ namespace ticl { const std::vector&, std::vector&, std::unordered_map>& seedToTracksterAssociation) const; - const std::unique_ptr theGraph_; + const std::unique_ptr> theGraph_; const bool oneTracksterPerTrackSeed_; const bool promoteEmptyRegionToTrackster_; const bool out_in_dfs_; const unsigned int max_out_in_hops_; const float min_cos_theta_; const float min_cos_pointing_; + const float root_doublet_max_distance_from_seed_squared_; const float etaLimitIncreaseWindow_; - const int missing_layers_; + const int skip_layers_; + const int max_missing_layers_in_trackster_; + bool check_missing_layers_ = false; + const unsigned int shower_start_max_layer_; + const unsigned int min_layers_per_trackster_; + const std::vector filter_on_categories_; + const double pid_threshold_; + const double energy_em_over_total_threshold_; + const double max_longitudinal_sigmaPCA_; const int min_clusters_per_ntuplet_; const float max_delta_time_; const std::string eidInputName_; @@ -53,5 +62,6 @@ namespace ticl { static const int eidNFeatures_ = 3; }; + } // namespace ticl #endif diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc b/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc index 59159b49ec568..68f303b5a0bc3 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.cc @@ -1,8 +1,9 @@ #include "PatternRecognitionbyMultiClusters.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -void ticl::PatternRecognitionbyMultiClusters::makeTracksters( - const PatternRecognitionAlgoBase::Inputs& input, +template +void ticl::PatternRecognitionbyMultiClusters::makeTracksters( + const typename PatternRecognitionAlgoBaseT::Inputs& input, std::vector& result, std::unordered_map>& seedToTracksterAssociation) { LogDebug("HGCPatterRecoTrackster") << "making Tracksters" << std::endl; diff --git a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h b/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h index d787a6002397d..027cebb8c3033 100644 --- a/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h +++ b/RecoHGCal/TICL/plugins/PatternRecognitionbyMultiClusters.h @@ -14,13 +14,14 @@ namespace edm { } // namespace edm namespace ticl { - class PatternRecognitionbyMultiClusters final : public PatternRecognitionAlgoBase { + template + class PatternRecognitionbyMultiClusters final : public PatternRecognitionAlgoBaseT { public: PatternRecognitionbyMultiClusters(const edm::ParameterSet& conf, const CacheBase* cache) - : PatternRecognitionAlgoBase(conf, cache) {} + : PatternRecognitionAlgoBaseT(conf, cache) {} ~PatternRecognitionbyMultiClusters() override{}; - void makeTracksters(const PatternRecognitionAlgoBase::Inputs& input, + void makeTracksters(const typename PatternRecognitionAlgoBaseT::Inputs& input, std::vector& result, std::unordered_map>& seedToTracksterAssociation) override; }; diff --git a/RecoHGCal/TICL/plugins/SeedingRegionByTracks.cc b/RecoHGCal/TICL/plugins/SeedingRegionByTracks.cc index e384db9b7fb8e..16d69c391f38a 100644 --- a/RecoHGCal/TICL/plugins/SeedingRegionByTracks.cc +++ b/RecoHGCal/TICL/plugins/SeedingRegionByTracks.cc @@ -17,19 +17,23 @@ SeedingRegionByTracks::SeedingRegionByTracks(const edm::ParameterSet &conf, edm: : SeedingRegionAlgoBase(conf, sumes), tracks_token_(sumes.consumes(conf.getParameter("tracks"))), cutTk_(conf.getParameter("cutTk")), - propName_(conf.getParameter("propagator")) {} + propName_(conf.getParameter("propagator")), + hdc_token_(sumes.esConsumes( + edm::ESInputTag("", detectorName_))), + bfield_token_(sumes.esConsumes()), + propagator_token_(sumes.esConsumes( + edm::ESInputTag("", propName_))) {} SeedingRegionByTracks::~SeedingRegionByTracks() {} void SeedingRegionByTracks::initialize(const edm::EventSetup &es) { - edm::ESHandle hdc; - es.get().get(detectorName_, hdc); + edm::ESHandle hdc = es.getHandle(hdc_token_); hgcons_ = hdc.product(); buildFirstLayers(); - es.get().get(bfield_); - es.get().get(propName_, propagator_); + bfield_ = es.getHandle(bfield_token_); + propagator_ = es.getHandle(propagator_token_); } void SeedingRegionByTracks::makeRegions(const edm::Event &ev, @@ -55,6 +59,10 @@ void SeedingRegionByTracks::makeRegions(const edm::Event &ev, result.emplace_back(tsos.globalPosition(), tsos.globalMomentum(), iSide, i, trkId); } } + // sorting seeding region by descending momentum + std::sort(result.begin(), result.end(), [](const TICLSeedingRegion &a, const TICLSeedingRegion &b) { + return a.directionAtOrigin.perp2() > b.directionAtOrigin.perp2(); + }); } void SeedingRegionByTracks::buildFirstLayers() { diff --git a/RecoHGCal/TICL/plugins/SeedingRegionByTracks.h b/RecoHGCal/TICL/plugins/SeedingRegionByTracks.h index a0b56e22e728c..d8d9f61214c02 100644 --- a/RecoHGCal/TICL/plugins/SeedingRegionByTracks.h +++ b/RecoHGCal/TICL/plugins/SeedingRegionByTracks.h @@ -22,8 +22,10 @@ #include "TrackingTools/Records/interface/TrackingComponentsRecord.h" #include "Geometry/CommonDetUnit/interface/GeomDet.h" #include "CommonTools/Utils/interface/StringCutObjectSelector.h" - -class HGCGraph; +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" namespace ticl { class SeedingRegionByTracks final : public SeedingRegionAlgoBase { @@ -47,6 +49,9 @@ namespace ticl { const std::string propName_; edm::ESHandle bfield_; std::unique_ptr firstDisk_[2]; + edm::ESGetToken hdc_token_; + edm::ESGetToken bfield_token_; + edm::ESGetToken propagator_token_; }; } // namespace ticl #endif diff --git a/RecoHGCal/TICL/plugins/TICLLayerTileProducer.cc b/RecoHGCal/TICL/plugins/TICLLayerTileProducer.cc index 541f08354e404..e3b1c633eddbf 100644 --- a/RecoHGCal/TICL/plugins/TICLLayerTileProducer.cc +++ b/RecoHGCal/TICL/plugins/TICLLayerTileProducer.cc @@ -7,9 +7,9 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/ESGetToken.h" #include "DataFormats/CaloRecHit/interface/CaloCluster.h" -#include "DataFormats/HGCalReco/interface/Common.h" #include "DataFormats/HGCalReco/interface/TICLLayerTile.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -24,41 +24,72 @@ class TICLLayerTileProducer : public edm::stream::EDProducer<> { private: edm::EDGetTokenT> clusters_token_; + edm::EDGetTokenT> clusters_HFNose_token_; + edm::ESGetToken geometry_token_; hgcal::RecHitTools rhtools_; + std::string detector_; + bool doNose_; }; -TICLLayerTileProducer::TICLLayerTileProducer(const edm::ParameterSet &ps) { +TICLLayerTileProducer::TICLLayerTileProducer(const edm::ParameterSet &ps) + : detector_(ps.getParameter("detector")) { + clusters_HFNose_token_ = + consumes>(ps.getParameter("layer_HFNose_clusters")); clusters_token_ = consumes>(ps.getParameter("layer_clusters")); + geometry_token_ = esConsumes(); - produces(); + doNose_ = (detector_ == "HFNose"); + + if (doNose_) + produces(); + else + produces(); } -void TICLLayerTileProducer::beginRun(edm::Run const &, edm::EventSetup const &es) { rhtools_.getEventSetup(es); } +void TICLLayerTileProducer::beginRun(edm::Run const &, edm::EventSetup const &es) { + edm::ESHandle geom = es.getHandle(geometry_token_); + rhtools_.setGeometry(*geom); +} void TICLLayerTileProducer::produce(edm::Event &evt, const edm::EventSetup &) { auto result = std::make_unique(); + auto resultHFNose = std::make_unique(); edm::Handle> cluster_h; - evt.getByToken(clusters_token_, cluster_h); + if (doNose_) + evt.getByToken(clusters_HFNose_token_, cluster_h); + else + evt.getByToken(clusters_token_, cluster_h); + const auto &layerClusters = *cluster_h; int lcId = 0; for (auto const &lc : layerClusters) { const auto firstHitDetId = lc.hitsAndFractions()[0].first; int layer = rhtools_.getLayerWithOffset(firstHitDetId) + - rhtools_.lastLayerFH() * ((rhtools_.zside(firstHitDetId) + 1) >> 1) - 1; + rhtools_.lastLayer(doNose_) * ((rhtools_.zside(firstHitDetId) + 1) >> 1) - 1; + assert(layer >= 0); - result->fill(layer, lc.eta(), lc.phi(), lcId); + + if (doNose_) + resultHFNose->fill(layer, lc.eta(), lc.phi(), lcId); + else + result->fill(layer, lc.eta(), lc.phi(), lcId); LogDebug("TICLLayerTileProducer") << "Adding layerClusterId: " << lcId << " into bin [eta,phi]: [ " << (*result)[layer].etaBin(lc.eta()) << ", " << (*result)[layer].phiBin(lc.phi()) << "] for layer: " << layer << std::endl; lcId++; } - evt.put(std::move(result)); + if (doNose_) + evt.put(std::move(resultHFNose)); + else + evt.put(std::move(result)); } void TICLLayerTileProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { edm::ParameterSetDescription desc; + desc.add("detector", "HGCAL"); desc.add("layer_clusters", edm::InputTag("hgcalLayerClusters")); + desc.add("layer_HFNose_clusters", edm::InputTag("hgcalLayerClustersHFNose")); descriptions.add("ticlLayerTileProducer", desc); } diff --git a/RecoHGCal/TICL/plugins/TICLSeedingRegionProducer.cc b/RecoHGCal/TICL/plugins/TICLSeedingRegionProducer.cc index 152c7b7898eb4..b886b69aef8e0 100644 --- a/RecoHGCal/TICL/plugins/TICLSeedingRegionProducer.cc +++ b/RecoHGCal/TICL/plugins/TICLSeedingRegionProducer.cc @@ -59,7 +59,7 @@ void TICLSeedingRegionProducer::fillDescriptions(edm::ConfigurationDescriptions& desc.add("tracks", edm::InputTag("generalTracks")); desc.add("cutTk", "1.48 < abs(eta) < 3.0 && pt > 1. && quality(\"highPurity\") && " - "hitPattern().numberOfLostHits(\"MISSING_OUTER_HITS\") < 10"); + "hitPattern().numberOfLostHits(\"MISSING_OUTER_HITS\") < 5"); desc.add("propagator", "PropagatorWithMaterial"); desc.add("algoId", 1); descriptions.add("ticlSeedingRegionProducer", desc); diff --git a/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc b/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc index b0a2ec14a4427..03e36a7187786 100644 --- a/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc +++ b/RecoHGCal/TICL/plugins/TrackstersMergeProducer.cc @@ -1,9 +1,9 @@ #include // unique_ptr - #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/ESGetToken.h" #include "DataFormats/CaloRecHit/interface/CaloCluster.h" #include "DataFormats/HGCalReco/interface/Common.h" @@ -14,6 +14,7 @@ #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" #include "RecoHGCal/TICL/plugins/GlobalCache.h" #include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +#include "DataFormats/HGCalReco/interface/TICLCandidate.h" #include "TrackstersPCA.h" @@ -32,29 +33,38 @@ class TrackstersMergeProducer : public edm::stream::EDProducer &, TracksterIterIndex); void printTrackstersDebug(const std::vector &, const char *label) const; void dumpTrackster(const Trackster &) const; + const edm::EDGetTokenT> tracksterstrkem_token_; const edm::EDGetTokenT> trackstersem_token_; const edm::EDGetTokenT> tracksterstrk_token_; const edm::EDGetTokenT> trackstershad_token_; const edm::EDGetTokenT> seedingTrk_token_; const edm::EDGetTokenT> clusters_token_; const edm::EDGetTokenT> tracks_token_; + const edm::ESGetToken geometry_token_; const bool optimiseAcrossTracksters_; const int eta_bin_window_; const int phi_bin_window_; const double pt_sigma_high_; const double pt_sigma_low_; + const double halo_max_distance2_; + const double track_min_pt_; + const double track_min_eta_; + const double track_max_eta_; + const int track_max_missing_outerhits_; const double cosangle_align_; const double e_over_h_threshold_; const double pt_neutral_threshold_; - const double resol_calo_offset_; - const double resol_calo_scale_; + const double resol_calo_offset_had_; + const double resol_calo_scale_had_; + const double resol_calo_offset_em_; + const double resol_calo_scale_em_; const bool debug_; const std::string eidInputName_; const std::string eidOutputNameEnergy_; @@ -70,22 +80,31 @@ class TrackstersMergeProducer : public edm::stream::EDProducer>(ps.getParameter("trackstersem"))), + : tracksterstrkem_token_(consumes>(ps.getParameter("tracksterstrkem"))), + trackstersem_token_(consumes>(ps.getParameter("trackstersem"))), tracksterstrk_token_(consumes>(ps.getParameter("tracksterstrk"))), trackstershad_token_(consumes>(ps.getParameter("trackstershad"))), seedingTrk_token_(consumes>(ps.getParameter("seedingTrk"))), clusters_token_(consumes>(ps.getParameter("layer_clusters"))), tracks_token_(consumes>(ps.getParameter("tracks"))), + geometry_token_(esConsumes()), optimiseAcrossTracksters_(ps.getParameter("optimiseAcrossTracksters")), eta_bin_window_(ps.getParameter("eta_bin_window")), phi_bin_window_(ps.getParameter("phi_bin_window")), pt_sigma_high_(ps.getParameter("pt_sigma_high")), pt_sigma_low_(ps.getParameter("pt_sigma_low")), + halo_max_distance2_(ps.getParameter("halo_max_distance2")), + track_min_pt_(ps.getParameter("track_min_pt")), + track_min_eta_(ps.getParameter("track_min_eta")), + track_max_eta_(ps.getParameter("track_max_eta")), + track_max_missing_outerhits_(ps.getParameter("track_max_missing_outerhits")), cosangle_align_(ps.getParameter("cosangle_align")), e_over_h_threshold_(ps.getParameter("e_over_h_threshold")), pt_neutral_threshold_(ps.getParameter("pt_neutral_threshold")), - resol_calo_offset_(ps.getParameter("resol_calo_offset")), - resol_calo_scale_(ps.getParameter("resol_calo_scale")), + resol_calo_offset_had_(ps.getParameter("resol_calo_offset_had")), + resol_calo_scale_had_(ps.getParameter("resol_calo_scale_had")), + resol_calo_offset_em_(ps.getParameter("resol_calo_offset_em")), + resol_calo_scale_em_(ps.getParameter("resol_calo_scale_em")), debug_(ps.getParameter("debug")), eidInputName_(ps.getParameter("eid_input_name")), eidOutputNameEnergy_(ps.getParameter("eid_output_name_energy")), @@ -103,6 +122,7 @@ TrackstersMergeProducer::TrackstersMergeProducer(const edm::ParameterSet &ps, co eidSession_ = tensorflow::createSession(trackstersCache->eidGraphDef); produces>(); + produces>(); } void TrackstersMergeProducer::fillTile(TICLTracksterTiles &tracksterTile, @@ -143,16 +163,22 @@ void TrackstersMergeProducer::dumpTrackster(const Trackster &t) const { } void TrackstersMergeProducer::produce(edm::Event &evt, const edm::EventSetup &es) { - rhtools_.getEventSetup(es); - auto result = std::make_unique>(); - auto mergedTrackstersTRK = std::make_unique>(); + edm::ESHandle geom = es.getHandle(geometry_token_); + rhtools_.setGeometry(*geom); + auto resultTrackstersMerged = std::make_unique>(); + auto resultCandidates = std::make_unique>(); TICLTracksterTiles tracksterTile; - std::vector usedTrackstersEM; - std::vector usedTrackstersTRK; - std::vector usedTrackstersHAD; + std::vector usedTrackstersMerged; + std::vector indexInMergedCollTRKEM; + std::vector indexInMergedCollEM; + std::vector indexInMergedCollTRK; + std::vector indexInMergedCollHAD; std::vector usedSeeds; + // associating seed to the index of the trackster in the merged collection and the iteration that found it + std::map>> seedToTracksterAssociator; + std::vector iterMergedTracksters; edm::Handle> track_h; evt.getByToken(tracks_token_, track_h); const auto &tracks = *track_h; @@ -164,185 +190,345 @@ void TrackstersMergeProducer::produce(edm::Event &evt, const edm::EventSetup &es edm::Handle> trackstersem_h; evt.getByToken(trackstersem_token_, trackstersem_h); const auto &trackstersEM = *trackstersem_h; - usedTrackstersEM.resize(trackstersEM.size(), false); + + edm::Handle> tracksterstrkem_h; + evt.getByToken(tracksterstrkem_token_, tracksterstrkem_h); + const auto &trackstersTRKEM = *tracksterstrkem_h; edm::Handle> tracksterstrk_h; evt.getByToken(tracksterstrk_token_, tracksterstrk_h); const auto &trackstersTRK = *tracksterstrk_h; - usedTrackstersTRK.resize(trackstersTRK.size(), false); edm::Handle> trackstershad_h; evt.getByToken(trackstershad_token_, trackstershad_h); const auto &trackstersHAD = *trackstershad_h; - usedTrackstersHAD.resize(trackstersHAD.size(), false); edm::Handle> seedingTrk_h; evt.getByToken(seedingTrk_token_, seedingTrk_h); const auto &seedingTrk = *seedingTrk_h; - usedSeeds.resize(seedingTrk.size(), false); + usedSeeds.resize(tracks.size(), false); + fillTile(tracksterTile, trackstersTRKEM, TracksterIterIndex::TRKEM); fillTile(tracksterTile, trackstersEM, TracksterIterIndex::EM); fillTile(tracksterTile, trackstersTRK, TracksterIterIndex::TRK); fillTile(tracksterTile, trackstersHAD, TracksterIterIndex::HAD); - auto seedId = 0; - for (auto const &s : seedingTrk) { - tracksterTile.fill(TracksterIterIndex::SEED, s.origin.eta(), s.origin.phi(), seedId++); - - if (debug_) { - LogDebug("TrackstersMergeProducer") - << "Seed index: " << seedId << " internal index: " << s.index << " origin: " << s.origin - << " mom: " << s.directionAtOrigin << " pt: " << std::sqrt(s.directionAtOrigin.perp2()) - << " zSide: " << s.zSide << " collectionID: " << s.collectionID << " track pt " << tracks[s.index].pt() - << std::endl; - } - } + auto totalNumberOfTracksters = + trackstersTRKEM.size() + trackstersTRK.size() + trackstersEM.size() + trackstersHAD.size(); + resultTrackstersMerged->reserve(totalNumberOfTracksters); + iterMergedTracksters.reserve(totalNumberOfTracksters); + usedTrackstersMerged.resize(totalNumberOfTracksters, false); + indexInMergedCollTRKEM.reserve(trackstersTRKEM.size()); + indexInMergedCollEM.reserve(trackstersEM.size()); + indexInMergedCollTRK.reserve(trackstersTRK.size()); + indexInMergedCollHAD.reserve(trackstersHAD.size()); if (debug_) { - printTrackstersDebug(trackstersTRK, "tracksterTRK"); + printTrackstersDebug(trackstersTRKEM, "tracksterTRKEM"); printTrackstersDebug(trackstersEM, "tracksterEM"); + printTrackstersDebug(trackstersTRK, "tracksterTRK"); printTrackstersDebug(trackstersHAD, "tracksterHAD"); } - int tracksterTRK_idx = 0; - int tracksterHAD_idx = 0; - if (optimiseAcrossTracksters_) { - for (auto const &t : trackstersTRK) { - if (debug_) { - int entryEtaBin = tracksterTile[TracksterIterIndex::TRK].etaBin(t.barycenter().eta()); - int entryPhiBin = tracksterTile[TracksterIterIndex::TRK].phiBin(t.barycenter().phi()); - int bin = tracksterTile[TracksterIterIndex::TRK].globalBin(t.barycenter().eta(), t.barycenter().phi()); - LogDebug("TrackstersMergeProducer") - << "TrackstersMergeProducer Tracking obj: " << t.barycenter() << " in bin " << bin << " etaBin " - << entryEtaBin << " phiBin " << entryPhiBin << std::endl; - dumpTrackster(t); - } - auto const &track = tracks[t.seedIndex()]; - auto trk_pt = (float)track.pt(); - auto diff_pt = t.raw_pt() - trk_pt; - auto pt_err = trk_pt * resol_calo_scale_ + resol_calo_offset_; - auto w_cal = 1. / (pt_err * pt_err); - auto w_trk = 1. / (track.ptError() * track.ptError()); - auto diff_pt_sigmas = diff_pt / pt_err; - auto e_over_h = (t.raw_em_pt() / ((t.raw_pt() - t.raw_em_pt()) != 0. ? (t.raw_pt() - t.raw_em_pt()) : 1.)); - LogDebug("TrackstersMergeProducer") - << "trackster_pt: " << t.raw_pt() << std::endl - << "track pt (inner): " << track.pt() << std::endl - << "track eta (inner): " << track.eta() << std::endl - << "track _phi (inner): " << track.phi() << std::endl - << "track pt (outer): " << std::sqrt(track.outerMomentum().perp2()) << std::endl - << "track eta (outer): " << track.outerMomentum().eta() << std::endl - << "track _phi (outer): " << track.outerMomentum().phi() << std::endl - << "pt_err_track: " << track.ptError() << std::endl - << "diff_pt: " << diff_pt << std::endl - << "pt_err: " << pt_err << std::endl - << "diff_pt_sigmas: " << diff_pt_sigmas << std::endl - << "w_cal: " << w_cal << std::endl - << "w_trk: " << w_trk << std::endl - << "average_pt: " << (t.raw_pt() * w_cal + trk_pt * w_trk) / (w_cal + w_trk) << std::endl - << "e_over_h: " << e_over_h << std::endl; - - // If the energy is unbalanced and higher in Calo ==> balance it by - // emitting gammas/neutrals - if (diff_pt_sigmas > pt_sigma_high_) { - if (e_over_h > e_over_h_threshold_) { - auto gamma_pt = std::min(diff_pt, t.raw_em_pt()); - // Create gamma with calo direction - LogDebug("TrackstersMergeProducer") - << " Creating a photon from TRK Trackster with energy " << gamma_pt << " and direction " - << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() << std::endl; - diff_pt -= gamma_pt; - if (diff_pt > pt_neutral_threshold_) { - // Create also a neutral on top, with calo direction and diff_pt as energy - LogDebug("TrackstersMergeProducer") - << " Adding also a neutral hadron from TRK Trackster with energy " << diff_pt << " and direction " - << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() << std::endl; - } - } else { - // Create neutral with calo direction - LogDebug("TrackstersMergeProducer") - << " Creating a neutral hadron from TRK Trackster with energy " << diff_pt << " and direction " - << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() << std::endl; - } - } - // If the energy is in the correct ball-park (this also covers the - // previous case after the neutral emission), use weighted averages - if (diff_pt_sigmas > -pt_sigma_low_) { - // Create either an electron or a charged hadron, using the weighted - // average information between the track and the cluster for the - // energy, the direction of the track at the vertex. The PID is simply - // passed over to the final trackster, while the energy is changed. - auto average_pt = (w_cal * t.raw_pt() + trk_pt * w_trk) / (w_cal + w_trk); - LogDebug("TrackstersMergeProducer") - << " Creating electron/charged hadron from TRK Trackster with weighted p_t " << average_pt - << " and direction " << track.eta() << ", " << track.phi() << std::endl; + for (auto const &t : trackstersTRKEM) { + indexInMergedCollTRKEM.push_back(resultTrackstersMerged->size()); + seedToTracksterAssociator[t.seedIndex()].emplace_back(resultTrackstersMerged->size(), TracksterIterIndex::TRKEM); + resultTrackstersMerged->push_back(t); + iterMergedTracksters.push_back(TracksterIterIndex::TRKEM); + } - } - // If the energy of the calo is too low, just use track-only information - else { - // Create either an electron or a charged hadron, using the track - // information only. - LogDebug("TrackstersMergeProducer") - << " Creating electron/charged hadron from TRK Trackster with track p_t " << trk_pt << " and direction " - << track.eta() << ", " << track.phi() << std::endl; - } - result->push_back(t); - usedTrackstersTRK[tracksterTRK_idx] = true; - tracksterTRK_idx++; - } + for (auto const &t : trackstersEM) { + indexInMergedCollEM.push_back(resultTrackstersMerged->size()); + resultTrackstersMerged->push_back(t); + iterMergedTracksters.push_back(TracksterIterIndex::EM); } - tracksterTRK_idx = 0; for (auto const &t : trackstersTRK) { - if (debug_) { - LogDebug("TrackstersMergeProducer") << " Considering trackster " << tracksterTRK_idx - << " as used: " << usedTrackstersTRK[tracksterTRK_idx] << std::endl; - } - if (!usedTrackstersTRK[tracksterTRK_idx]) { - LogDebug("TrackstersMergeProducer") - << " Creating a charge hadron from TRK Trackster with track energy " << t.raw_energy() << " and direction " - << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() << std::endl; - result->push_back(t); - } - tracksterTRK_idx++; + indexInMergedCollTRK.push_back(resultTrackstersMerged->size()); + seedToTracksterAssociator[t.seedIndex()].emplace_back(resultTrackstersMerged->size(), TracksterIterIndex::TRK); + resultTrackstersMerged->push_back(t); + iterMergedTracksters.push_back(TracksterIterIndex::TRK); } - auto tracksterEM_idx = 0; - for (auto const &t : trackstersEM) { - if (debug_) { - LogDebug("TrackstersMergeProducer") << " Considering trackster " << tracksterEM_idx - << " as used: " << usedTrackstersEM[tracksterEM_idx] << std::endl; - } - if (!usedTrackstersEM[tracksterEM_idx]) { - LogDebug("TrackstersMergeProducer") - << " Creating a photon from EM Trackster with track energy " << t.raw_energy() << " and direction " - << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() << std::endl; - result->push_back(t); - } - tracksterEM_idx++; + for (auto const &t : trackstersHAD) { + indexInMergedCollHAD.push_back(resultTrackstersMerged->size()); + resultTrackstersMerged->push_back(t); + iterMergedTracksters.push_back(TracksterIterIndex::HAD); } - tracksterHAD_idx = 0; - for (auto const &t : trackstersHAD) { - if (debug_) { - LogDebug("TrackstersMergeProducer") << " Considering trackster " << tracksterHAD_idx - << " as used: " << usedTrackstersHAD[tracksterHAD_idx] << std::endl; + assignPCAtoTracksters(*resultTrackstersMerged, layerClusters, rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z()); + energyRegressionAndID(layerClusters, *resultTrackstersMerged); + + printTrackstersDebug(*resultTrackstersMerged, "TrackstersMergeProducer"); + + auto trackstersMergedHandle = evt.put(std::move(resultTrackstersMerged)); + + // TICL Candidate creation + // We start from neutrals first + + // Photons + for (unsigned i = 0; i < trackstersEM.size(); ++i) { + auto mergedIdx = indexInMergedCollEM[i]; + usedTrackstersMerged[mergedIdx] = true; + const auto &t = trackstersEM[i]; //trackster + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); + tmpCandidate.setCharge(0); + tmpCandidate.setPdgId(22); + tmpCandidate.setRawEnergy(t.raw_energy()); + math::XYZTLorentzVector p4(t.raw_energy() * t.barycenter().unit().x(), + t.raw_energy() * t.barycenter().unit().y(), + t.raw_energy() * t.barycenter().unit().z(), + t.raw_energy()); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + } + + // Neutral Hadrons + constexpr float mpion2 = 0.13957f * 0.13957f; + for (unsigned i = 0; i < trackstersHAD.size(); ++i) { + auto mergedIdx = indexInMergedCollHAD[i]; + usedTrackstersMerged[mergedIdx] = true; + const auto &t = trackstersHAD[i]; //trackster + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); + tmpCandidate.setCharge(0); + tmpCandidate.setPdgId(130); + tmpCandidate.setRawEnergy(t.raw_energy()); + float momentum = std::sqrt(t.raw_energy() * t.raw_energy() - mpion2); + math::XYZTLorentzVector p4(momentum * t.barycenter().unit().x(), + momentum * t.barycenter().unit().y(), + momentum * t.barycenter().unit().z(), + t.raw_energy()); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + } + + // Charged Particles + for (unsigned i = 0; i < trackstersTRKEM.size(); ++i) { + auto mergedIdx = indexInMergedCollTRKEM[i]; + if (!usedTrackstersMerged[mergedIdx]) { + const auto &t = trackstersTRKEM[i]; //trackster + auto trackIdx = t.seedIndex(); + auto const &track = tracks[trackIdx]; + if (!usedSeeds[trackIdx] and t.raw_energy() > 0) { + usedSeeds[trackIdx] = true; + usedTrackstersMerged[mergedIdx] = true; + + std::vector trackstersTRKwithSameSeed; + std::vector trackstersTRKEMwithSameSeed; + + for (const auto &tracksterIterationPair : seedToTracksterAssociator[trackIdx]) { + if (tracksterIterationPair.first != mergedIdx and !usedTrackstersMerged[tracksterIterationPair.first] and + trackstersMergedHandle->at(tracksterIterationPair.first).raw_energy() > 0.) { + if (tracksterIterationPair.second == TracksterIterIndex::TRKEM) { + trackstersTRKEMwithSameSeed.push_back(tracksterIterationPair.first); + } else if (tracksterIterationPair.second == TracksterIterIndex::TRK) { + trackstersTRKwithSameSeed.push_back(tracksterIterationPair.first); + } + } + } + + float tracksterTotalRawPt = t.raw_pt(); + std::vector haloTrackstersTRKIdx; + bool foundCompatibleTRK = false; + + for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { + usedTrackstersMerged[otherTracksterIdx] = true; + tracksterTotalRawPt += trackstersMergedHandle->at(otherTracksterIdx).raw_pt(); + + // Check the X,Y,Z barycenter and merge if they are very close (halo) + if ((t.barycenter() - trackstersMergedHandle->at(otherTracksterIdx).barycenter()).mag2() < + halo_max_distance2_) { + haloTrackstersTRKIdx.push_back(otherTracksterIdx); + + } else { + foundCompatibleTRK = true; + } + } + + //check if there is 1-to-1 relationship + if (trackstersTRKEMwithSameSeed.empty()) { + if (foundCompatibleTRK) { + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); + double raw_energy = t.raw_energy(); + + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); + tmpCandidate.setPdgId(211 * track.charge()); + for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); + raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); + } + tmpCandidate.setRawEnergy(raw_energy); + math::XYZTLorentzVector p4(raw_energy * track.momentum().unit().x(), + raw_energy * track.momentum().unit().y(), + raw_energy * track.momentum().unit().z(), + raw_energy); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + + } else { + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); + double raw_energy = t.raw_energy(); + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); + for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); + raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); + } + tmpCandidate.setPdgId(11 * track.charge()); + + tmpCandidate.setRawEnergy(raw_energy); + math::XYZTLorentzVector p4(raw_energy * track.momentum().unit().x(), + raw_energy * track.momentum().unit().y(), + raw_energy * track.momentum().unit().z(), + raw_energy); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + } + + } else { + // if 1-to-many find closest trackster in momentum + int closestTrackster = mergedIdx; + float minPtDiff = std::abs(t.raw_pt() - track.pt()); + for (auto otherTracksterIdx : trackstersTRKEMwithSameSeed) { + auto thisPt = tracksterTotalRawPt + trackstersMergedHandle->at(otherTracksterIdx).raw_pt() - t.raw_pt(); + closestTrackster = std::abs(thisPt - track.pt()) < minPtDiff ? otherTracksterIdx : closestTrackster; + } + usedTrackstersMerged[closestTrackster] = true; + + if (foundCompatibleTRK) { + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, closestTrackster)); + double raw_energy = trackstersMergedHandle->at(closestTrackster).raw_energy(); + + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); + tmpCandidate.setPdgId(211 * track.charge()); + for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); + raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); + } + tmpCandidate.setRawEnergy(raw_energy); + float momentum = std::sqrt(raw_energy * raw_energy - mpion2); + math::XYZTLorentzVector p4(momentum * track.momentum().unit().x(), + momentum * track.momentum().unit().y(), + momentum * track.momentum().unit().z(), + raw_energy); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + + } else { + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, closestTrackster)); + double raw_energy = trackstersMergedHandle->at(closestTrackster).raw_energy(); + + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); + for (auto otherTracksterIdx : trackstersTRKwithSameSeed) { + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, otherTracksterIdx)); + raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy(); + } + tmpCandidate.setPdgId(11 * track.charge()); + tmpCandidate.setRawEnergy(raw_energy); + math::XYZTLorentzVector p4(raw_energy * track.momentum().unit().x(), + raw_energy * track.momentum().unit().y(), + raw_energy * track.momentum().unit().z(), + raw_energy); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + } + // Promote all other TRKEM tracksters as photons with their energy. + for (auto otherTracksterIdx : trackstersTRKEMwithSameSeed) { + auto tmpIndex = (otherTracksterIdx != closestTrackster) ? otherTracksterIdx : mergedIdx; + TICLCandidate photonCandidate; + const auto &otherTrackster = trackstersMergedHandle->at(tmpIndex); + auto gammaEnergy = otherTrackster.raw_energy(); + photonCandidate.setCharge(0); + photonCandidate.setPdgId(22); + photonCandidate.setRawEnergy(gammaEnergy); + math::XYZTLorentzVector gammaP4(gammaEnergy * otherTrackster.barycenter().unit().x(), + gammaEnergy * otherTrackster.barycenter().unit().y(), + gammaEnergy * otherTrackster.barycenter().unit().z(), + gammaEnergy); + photonCandidate.setP4(gammaP4); + photonCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, tmpIndex)); + resultCandidates->push_back(photonCandidate); + } + } + } } - if (!usedTrackstersHAD[tracksterHAD_idx]) { - LogDebug("TrackstersMergeProducer") - << " Creating a neutral hadron from HAD Trackster with track energy " << t.raw_energy() << " and direction " - << t.eigenvectors(0).eta() << ", " << t.eigenvectors(0).phi() << std::endl; - result->push_back(t); + } //end of loop over trackstersTRKEM + + for (unsigned i = 0; i < trackstersTRK.size(); ++i) { + auto mergedIdx = indexInMergedCollTRK[i]; + const auto &t = trackstersTRK[i]; //trackster + + if (!usedTrackstersMerged[mergedIdx] and t.raw_energy() > 0) { + auto trackIdx = t.seedIndex(); + auto const &track = tracks[trackIdx]; + if (!usedSeeds[trackIdx]) { + usedSeeds[trackIdx] = true; + usedTrackstersMerged[mergedIdx] = true; + TICLCandidate tmpCandidate; + tmpCandidate.addTrackster(edm::Ptr(trackstersMergedHandle, mergedIdx)); + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, trackIdx)); + tmpCandidate.setPdgId(211 * track.charge()); + tmpCandidate.setRawEnergy(t.raw_energy()); + float momentum = std::sqrt(t.raw_energy() * t.raw_energy() - mpion2); + math::XYZTLorentzVector p4(momentum * track.momentum().unit().x(), + momentum * track.momentum().unit().y(), + momentum * track.momentum().unit().z(), + t.raw_energy()); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + } + } + } + // For all seeds that have 0-energy tracksters whose track is not marked as used, create a charged hadron with the track information. + for (auto const &s : seedingTrk) { + if (usedSeeds[s.index] == false) { + auto const &track = tracks[s.index]; + // emit a charged hadron + TICLCandidate tmpCandidate; + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, s.index)); + tmpCandidate.setPdgId(211 * track.charge()); + float energy = std::sqrt(track.pt() * track.pt() + mpion2); + tmpCandidate.setRawEnergy(energy); + math::XYZTLorentzVector p4(track.momentum().x(), track.momentum().y(), track.momentum().z(), energy); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + usedSeeds[s.index] = true; } - tracksterHAD_idx++; } - assignPCAtoTracksters(*result, layerClusters, rhtools_.getPositionLayer(rhtools_.lastLayerEE()).z()); - energyRegressionAndID(layerClusters, *result); - - printTrackstersDebug(*result, "TrackstersMergeProducer"); + // for all general tracks (high purity, pt > 1), check if they have been used: if not, promote them as charged hadrons + for (unsigned i = 0; i < tracks.size(); ++i) { + auto const &track = tracks[i]; + if (track.pt() > track_min_pt_ and track.quality(reco::TrackBase::highPurity) and + track.hitPattern().numberOfLostHits(reco::HitPattern::MISSING_OUTER_HITS) < track_max_missing_outerhits_ and + std::abs(track.outerEta()) > track_min_eta_ and std::abs(track.outerEta()) < track_max_eta_ and + usedSeeds[i] == false) { + // emit a charged hadron + TICLCandidate tmpCandidate; + tmpCandidate.setCharge(track.charge()); + tmpCandidate.setTrackPtr(edm::Ptr(track_h, i)); + tmpCandidate.setPdgId(211 * track.charge()); + float energy = std::sqrt(track.pt() * track.pt() + mpion2); + tmpCandidate.setRawEnergy(energy); + math::XYZTLorentzVector p4(track.momentum().x(), track.momentum().y(), track.momentum().z(), energy); + tmpCandidate.setP4(p4); + resultCandidates->push_back(tmpCandidate); + usedSeeds[i] = true; + } + } - evt.put(std::move(result)); + evt.put(std::move(resultCandidates)); } void TrackstersMergeProducer::energyRegressionAndID(const std::vector &layerClusters, @@ -534,6 +720,7 @@ void TrackstersMergeProducer::printTrackstersDebug(const std::vector void TrackstersMergeProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { edm::ParameterSetDescription desc; + desc.add("tracksterstrkem", edm::InputTag("ticlTrackstersTrkEM")); desc.add("trackstersem", edm::InputTag("ticlTrackstersEM")); desc.add("tracksterstrk", edm::InputTag("ticlTrackstersTrk")); desc.add("trackstershad", edm::InputTag("ticlTrackstersHAD")); @@ -545,11 +732,18 @@ void TrackstersMergeProducer::fillDescriptions(edm::ConfigurationDescriptions &d desc.add("phi_bin_window", 1); desc.add("pt_sigma_high", 2.); desc.add("pt_sigma_low", 2.); + desc.add("halo_max_distance2", 4.); + desc.add("track_min_pt", 1.); + desc.add("track_min_eta", 1.48); + desc.add("track_max_eta", 3.); + desc.add("track_max_missing_outerhits", 5); desc.add("cosangle_align", 0.9945); desc.add("e_over_h_threshold", 1.); desc.add("pt_neutral_threshold", 2.); - desc.add("resol_calo_offset", 1.5); - desc.add("resol_calo_scale", 0.15); + desc.add("resol_calo_offset_had", 1.5); + desc.add("resol_calo_scale_had", 0.15); + desc.add("resol_calo_offset_em", 1.5); + desc.add("resol_calo_scale_em", 0.15); desc.add("debug", true); desc.add("eid_graph_path", "RecoHGCal/TICL/data/tf_models/energy_id_v0.pb"); desc.add("eid_input_name", "input"); diff --git a/RecoHGCal/TICL/plugins/TrackstersProducer.cc b/RecoHGCal/TICL/plugins/TrackstersProducer.cc index d9d485d216404..38650eeab1211 100644 --- a/RecoHGCal/TICL/plugins/TrackstersProducer.cc +++ b/RecoHGCal/TICL/plugins/TrackstersProducer.cc @@ -42,16 +42,18 @@ class TrackstersProducer : public edm::stream::EDProducer myAlgo_; + std::string detector_; + bool doNose_; + std::unique_ptr> myAlgo_; + std::unique_ptr> myAlgoHFNose_; const edm::EDGetTokenT> clusters_token_; const edm::EDGetTokenT> filtered_layerclusters_mask_token_; const edm::EDGetTokenT> original_layerclusters_mask_token_; const edm::EDGetTokenT>> clustersTime_token_; - const edm::EDGetTokenT layer_clusters_tiles_token_; + edm::EDGetTokenT layer_clusters_tiles_token_; + edm::EDGetTokenT layer_clusters_tiles_hfnose_token_; const edm::EDGetTokenT> seeding_regions_token_; - const std::vector filter_on_categories_; - const double pid_threshold_; const std::string itername_; }; DEFINE_FWK_MODULE(TrackstersProducer); @@ -76,18 +78,24 @@ void TrackstersProducer::globalEndJob(TrackstersCache* cache) { } TrackstersProducer::TrackstersProducer(const edm::ParameterSet& ps, const TrackstersCache* cache) - : myAlgo_(std::make_unique(ps, cache)), + : detector_(ps.getParameter("detector")), + doNose_(detector_ == "HFNose"), + myAlgo_(std::make_unique>(ps, cache)), + myAlgoHFNose_(std::make_unique>(ps, cache)), clusters_token_(consumes>(ps.getParameter("layer_clusters"))), filtered_layerclusters_mask_token_(consumes>(ps.getParameter("filtered_mask"))), original_layerclusters_mask_token_(consumes>(ps.getParameter("original_mask"))), clustersTime_token_( consumes>>(ps.getParameter("time_layerclusters"))), - layer_clusters_tiles_token_(consumes(ps.getParameter("layer_clusters_tiles"))), seeding_regions_token_( consumes>(ps.getParameter("seeding_regions"))), - filter_on_categories_(ps.getParameter>("filter_on_categories")), - pid_threshold_(ps.getParameter("pid_threshold")), itername_(ps.getParameter("itername")) { + if (doNose_) { + layer_clusters_tiles_hfnose_token_ = + consumes(ps.getParameter("layer_clusters_hfnose_tiles")); + } else { + layer_clusters_tiles_token_ = consumes(ps.getParameter("layer_clusters_tiles")); + } produces>(); produces>(); // Mask to be applied at the next iteration } @@ -95,20 +103,27 @@ TrackstersProducer::TrackstersProducer(const edm::ParameterSet& ps, const Tracks void TrackstersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { // hgcalMultiClusters edm::ParameterSetDescription desc; + desc.add("detector", "HGCAL"); desc.add("layer_clusters", edm::InputTag("hgcalLayerClusters")); desc.add("filtered_mask", edm::InputTag("filteredLayerClusters", "iterationLabelGoesHere")); desc.add("original_mask", edm::InputTag("hgcalLayerClusters", "InitialLayerClustersMask")); desc.add("time_layerclusters", edm::InputTag("hgcalLayerClusters", "timeLayerCluster")); desc.add("layer_clusters_tiles", edm::InputTag("ticlLayerTileProducer")); + desc.add("layer_clusters_hfnose_tiles", edm::InputTag("ticlLayerTileHFNose")); desc.add("seeding_regions", edm::InputTag("ticlSeedingRegionProducer")); desc.add>("filter_on_categories", {0}); - desc.add("pid_threshold", 0.); // make default such that no filtering is applied + desc.add("pid_threshold", 0.); // make default such that no filtering is applied + desc.add("energy_em_over_total_threshold", -1.); // make default such that no filtering is applied + desc.add("max_longitudinal_sigmaPCA", 9999); + desc.add("shower_start_max_layer", 9999); // make default such that no filtering is applied desc.add("algo_verbosity", 0); desc.add("min_cos_theta", 0.915); + desc.add("root_doublet_max_distance_from_seed_squared", 9999); desc.add("min_cos_pointing", -1.); - desc.add("missing_layers", 0); + desc.add("skip_layers", 0); + desc.add("max_missing_layers_in_trackster", 9999); desc.add("etaLimitIncreaseWindow", 2.1); - desc.add("min_clusters_per_ntuplet", 10); + desc.add("min_layers_per_trackster", 10); desc.add("max_delta_time", 3.); //nsigma desc.add("out_in_dfs", true); desc.add("max_out_in_hops", 10); @@ -129,27 +144,11 @@ void TrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) { auto result = std::make_unique>(); auto output_mask = std::make_unique>(); - edm::Handle> cluster_h; - edm::Handle> filtered_layerclusters_mask_h; - edm::Handle> original_layerclusters_mask_h; - edm::Handle>> time_clusters_h; - edm::Handle layer_clusters_tiles_h; - edm::Handle> seeding_regions_h; - - evt.getByToken(clusters_token_, cluster_h); - evt.getByToken(filtered_layerclusters_mask_token_, filtered_layerclusters_mask_h); - evt.getByToken(original_layerclusters_mask_token_, original_layerclusters_mask_h); - evt.getByToken(clustersTime_token_, time_clusters_h); - evt.getByToken(layer_clusters_tiles_token_, layer_clusters_tiles_h); - evt.getByToken(seeding_regions_token_, seeding_regions_h); - - const auto& layerClusters = *cluster_h; - const auto& inputClusterMask = *filtered_layerclusters_mask_h; - const auto& layerClustersTimes = *time_clusters_h; - const auto& layer_clusters_tiles = *layer_clusters_tiles_h; - const auto& seeding_regions = *seeding_regions_h; - const ticl::PatternRecognitionAlgoBase::Inputs input( - evt, es, layerClusters, inputClusterMask, layerClustersTimes, layer_clusters_tiles, seeding_regions); + const std::vector& original_layerclusters_mask = evt.get(original_layerclusters_mask_token_); + const auto& layerClusters = evt.get(clusters_token_); + const auto& inputClusterMask = evt.get(filtered_layerclusters_mask_token_); + const auto& layerClustersTimes = evt.get(clustersTime_token_); + const auto& seeding_regions = evt.get(seeding_regions_token_); std::unordered_map> seedToTrackstersAssociation; // if it's regional iteration and there are seeding regions @@ -159,31 +158,26 @@ void TrackstersProducer::produce(edm::Event& evt, const edm::EventSetup& es) { seedToTrackstersAssociation.emplace(seeding_regions[i].index, 0); } } - myAlgo_->makeTracksters(input, *result, seedToTrackstersAssociation); + if (doNose_) { + const auto& layer_clusters_hfnose_tiles = evt.get(layer_clusters_tiles_hfnose_token_); + const typename PatternRecognitionAlgoBaseT::Inputs inputHFNose( + evt, es, layerClusters, inputClusterMask, layerClustersTimes, layer_clusters_hfnose_tiles, seeding_regions); + + myAlgoHFNose_->makeTracksters(inputHFNose, *result, seedToTrackstersAssociation); + + } else { + const auto& layer_clusters_tiles = evt.get(layer_clusters_tiles_token_); + const typename PatternRecognitionAlgoBaseT::Inputs input( + evt, es, layerClusters, inputClusterMask, layerClustersTimes, layer_clusters_tiles, seeding_regions); + + myAlgo_->makeTracksters(input, *result, seedToTrackstersAssociation); + } // Now update the global mask and put it into the event - output_mask->reserve(original_layerclusters_mask_h->size()); + output_mask->reserve(original_layerclusters_mask.size()); // Copy over the previous state - std::copy(std::begin(*original_layerclusters_mask_h), - std::end(*original_layerclusters_mask_h), - std::back_inserter(*output_mask)); - - // Filter results based on PID criteria. - // We want to **keep** tracksters whose cumulative - // probability summed up over the selected categories - // is greater than the chosen threshold. Therefore - // the filtering function should **discard** all - // tracksters **below** the threshold. - auto filter_on_pids = [&](Trackster& t) -> bool { - auto cumulative_prob = 0.; - for (auto index : filter_on_categories_) { - cumulative_prob += t.id_probabilities(index); - } - return cumulative_prob <= pid_threshold_; - }; - - // Actually filter results and shrink size to fit - result->erase(std::remove_if(result->begin(), result->end(), filter_on_pids), result->end()); + std::copy( + std::begin(original_layerclusters_mask), std::end(original_layerclusters_mask), std::back_inserter(*output_mask)); // Mask the used elements, accordingly for (auto const& trackster : *result) { diff --git a/RecoHGCal/TICL/plugins/filters.cc b/RecoHGCal/TICL/plugins/filters.cc index edbd834f4df90..54a89147dfb1d 100644 --- a/RecoHGCal/TICL/plugins/filters.cc +++ b/RecoHGCal/TICL/plugins/filters.cc @@ -7,9 +7,13 @@ #include "ClusterFilterByAlgo.h" #include "ClusterFilterByAlgoAndSize.h" #include "ClusterFilterBySize.h" +#include "ClusterFilterByAlgoAndSizeAndLayerRange.h" using namespace ticl; DEFINE_EDM_PLUGIN(ClusterFilterFactory, ClusterFilterByAlgo, "ClusterFilterByAlgo"); DEFINE_EDM_PLUGIN(ClusterFilterFactory, ClusterFilterByAlgoAndSize, "ClusterFilterByAlgoAndSize"); DEFINE_EDM_PLUGIN(ClusterFilterFactory, ClusterFilterBySize, "ClusterFilterBySize"); +DEFINE_EDM_PLUGIN(ClusterFilterFactory, + ClusterFilterByAlgoAndSizeAndLayerRange, + "ClusterFilterByAlgoAndSizeAndLayerRange"); diff --git a/RecoHGCal/TICL/python/EMStep_cff.py b/RecoHGCal/TICL/python/EMStep_cff.py index 7bc07499f3b80..0aa6f9ca50fd9 100644 --- a/RecoHGCal/TICL/python/EMStep_cff.py +++ b/RecoHGCal/TICL/python/EMStep_cff.py @@ -1,7 +1,6 @@ import FWCore.ParameterSet.Config as cms -from RecoHGCal.TICL.TICLSeedingRegions_cff import ticlSeedingGlobal -from RecoHGCal.TICL.ticlLayerTileProducer_cfi import ticlLayerTileProducer as _ticlLayerTileProducer +from RecoHGCal.TICL.TICLSeedingRegions_cff import ticlSeedingGlobal, ticlSeedingGlobalHFNose from RecoHGCal.TICL.trackstersProducer_cfi import trackstersProducer as _trackstersProducer from RecoHGCal.TICL.filteredLayerClustersProducer_cfi import filteredLayerClustersProducer as _filteredLayerClustersProducer from RecoHGCal.TICL.multiClustersFromTrackstersProducer_cfi import multiClustersFromTrackstersProducer as _multiClustersFromTrackstersProducer @@ -9,25 +8,30 @@ # CLUSTER FILTERING/MASKING filteredLayerClustersEM = _filteredLayerClustersProducer.clone( - clusterFilter = "ClusterFilterByAlgoAndSize", - min_cluster_size = 2, # inclusive + clusterFilter = "ClusterFilterByAlgoAndSizeAndLayerRange", + min_cluster_size = 3, # inclusive + max_layerId = 30, # inclusive algo_number = 8, - LayerClustersInputMask = 'ticlTrackstersTrk', + LayerClustersInputMask = 'ticlTrackstersTrkEM', iteration_label = "EM" ) # CA - PATTERN RECOGNITION ticlTrackstersEM = _trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersEM", "EM"), - original_mask = 'ticlTrackstersTrk', + filtered_mask = "filteredLayerClustersEM:EM", + original_mask = 'ticlTrackstersTrkEM', seeding_regions = "ticlSeedingGlobal", filter_on_categories = [0, 1], - pid_threshold = 0.8, - max_out_in_hops = 4, - missing_layers = 1, - min_clusters_per_ntuplet = 10, - min_cos_theta = 0.978, # ~12 degrees + pid_threshold = 0.5, + energy_em_over_total_threshold = 0.9, + max_longitudinal_sigmaPCA = 10, + shower_start_max_layer = 5, #inclusive + max_out_in_hops = 1, + skip_layers = 2, + max_missing_layers_in_trackster = 1, + min_layers_per_trackster = 10, + min_cos_theta = 0.97, # ~14 degrees min_cos_pointing = 0.9, # ~25 degrees max_delta_time = 3., itername = "EM", @@ -45,3 +49,26 @@ ,ticlTrackstersEM ,ticlMultiClustersFromTrackstersEM) +filteredLayerClustersHFNoseEM = filteredLayerClustersEM.clone( + LayerClusters = 'hgcalLayerClustersHFNose', + LayerClustersInputMask = "hgcalLayerClustersHFNose:InitialLayerClustersMask", + iteration_label = "EMn", + algo_number = 9 +#no tracking mask for EM for now +) + +ticlTrackstersHFNoseEM = ticlTrackstersEM.clone( + detector = "HFNose", + layer_clusters = "hgcalLayerClustersHFNose", + layer_clusters_hfnose_tiles = "ticlLayerTileHFNose", + original_mask = "hgcalLayerClustersHFNose:InitialLayerClustersMask", + filtered_mask = "filteredLayerClustersHFNoseEM:EMn", + seeding_regions = "ticlSeedingGlobalHFNose", + time_layerclusters = "hgcalLayerClustersHFNose:timeLayerCluster", + min_layers_per_trackster = 6 +) + +ticlHFNoseEMStepTask = cms.Task(ticlSeedingGlobalHFNose + ,filteredLayerClustersHFNoseEM + ,ticlTrackstersHFNoseEM +) diff --git a/RecoHGCal/TICL/python/HADStep_cff.py b/RecoHGCal/TICL/python/HADStep_cff.py index 9f4b726250c03..72efaebc201ec 100644 --- a/RecoHGCal/TICL/python/HADStep_cff.py +++ b/RecoHGCal/TICL/python/HADStep_cff.py @@ -10,23 +10,23 @@ filteredLayerClustersHAD = _filteredLayerClustersProducer.clone( clusterFilter = "ClusterFilterByAlgoAndSize", - min_cluster_size = 2, # inclusive + min_cluster_size = 3, # inclusive algo_number = 8, iteration_label = "HAD", - LayerClustersInputMask = "ticlTrackstersEM" + LayerClustersInputMask = "ticlTrackstersTrk" ) # CA - PATTERN RECOGNITION ticlTrackstersHAD = _trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersHAD", "HAD"), - original_mask = 'ticlTrackstersEM', + filtered_mask = "filteredLayerClustersHAD:HAD", + original_mask = 'ticlTrackstersTrk', seeding_regions = "ticlSeedingGlobal", # For the moment we mask everything w/o requirements since we are last # filter_on_categories = [5], # filter neutral hadrons # pid_threshold = 0.7, - missing_layers = 1, - min_clusters_per_ntuplet = 12, + skip_layers = 1, + min_layers_per_trackster = 12, min_cos_theta = 0.866, # ~30 degrees min_cos_pointing = 0.819, # ~35 degrees max_delta_time = -1, diff --git a/RecoHGCal/TICL/python/MIPStep_cff.py b/RecoHGCal/TICL/python/MIPStep_cff.py index 8e1c5881986e8..f7e5234b3aa9c 100644 --- a/RecoHGCal/TICL/python/MIPStep_cff.py +++ b/RecoHGCal/TICL/python/MIPStep_cff.py @@ -1,7 +1,6 @@ import FWCore.ParameterSet.Config as cms -from RecoHGCal.TICL.TICLSeedingRegions_cff import ticlSeedingGlobal -from RecoHGCal.TICL.ticlLayerTileProducer_cfi import ticlLayerTileProducer as _ticlLayerTileProducer +from RecoHGCal.TICL.TICLSeedingRegions_cff import ticlSeedingGlobal, ticlSeedingGlobalHFNose from RecoHGCal.TICL.trackstersProducer_cfi import trackstersProducer as _trackstersProducer from RecoHGCal.TICL.filteredLayerClustersProducer_cfi import filteredLayerClustersProducer as _filteredLayerClustersProducer from RecoHGCal.TICL.multiClustersFromTrackstersProducer_cfi import multiClustersFromTrackstersProducer as _multiClustersFromTrackstersProducer @@ -15,13 +14,14 @@ iteration_label = "MIP" ) + # CA - PATTERN RECOGNITION ticlTrackstersMIP = _trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersMIP", "MIP"), + filtered_mask = "filteredLayerClustersMIP:MIP", seeding_regions = "ticlSeedingGlobal", - missing_layers = 3, - min_clusters_per_ntuplet = 10, + skip_layers = 3, + min_layers_per_trackster = 10, min_cos_theta = 0.99, # ~10 degrees min_cos_pointing = 0.5, out_in_dfs = False, @@ -40,3 +40,25 @@ ,ticlTrackstersMIP ,ticlMultiClustersFromTrackstersMIP) +filteredLayerClustersHFNoseMIP = filteredLayerClustersMIP.clone( + LayerClusters = 'hgcalLayerClustersHFNose', + LayerClustersInputMask = "hgcalLayerClustersHFNose:InitialLayerClustersMask", + iteration_label = "MIPn", + algo_number = 9 +) + +ticlTrackstersHFNoseMIP = ticlTrackstersMIP.clone( + detector = "HFNose", + layer_clusters = "hgcalLayerClustersHFNose", + layer_clusters_hfnose_tiles = "ticlLayerTileHFNose", + original_mask = "hgcalLayerClustersHFNose:InitialLayerClustersMask", + filtered_mask = "filteredLayerClustersHFNoseMIP:MIPn", + seeding_regions = "ticlSeedingGlobalHFNose", + time_layerclusters = "hgcalLayerClustersHFNose:timeLayerCluster", + min_layers_per_trackster = 6 +) + +ticlHFNoseMIPStepTask = cms.Task(ticlSeedingGlobalHFNose + ,filteredLayerClustersHFNoseMIP + ,ticlTrackstersHFNoseMIP +) diff --git a/RecoHGCal/TICL/python/TICLSeedingRegions_cff.py b/RecoHGCal/TICL/python/TICLSeedingRegions_cff.py index 9e4698c944d02..4b76fd39d322c 100644 --- a/RecoHGCal/TICL/python/TICLSeedingRegions_cff.py +++ b/RecoHGCal/TICL/python/TICLSeedingRegions_cff.py @@ -12,3 +12,6 @@ algoId = 1 ) +ticlSeedingGlobalHFNose = _ticlSeedingRegionProducer.clone( + algoId = 2 +) diff --git a/RecoHGCal/TICL/python/TrkEMStep_cff.py b/RecoHGCal/TICL/python/TrkEMStep_cff.py new file mode 100644 index 0000000000000..458f489f696ec --- /dev/null +++ b/RecoHGCal/TICL/python/TrkEMStep_cff.py @@ -0,0 +1,51 @@ +import FWCore.ParameterSet.Config as cms + +from RecoHGCal.TICL.TICLSeedingRegions_cff import ticlSeedingTrk +from RecoHGCal.TICL.trackstersProducer_cfi import trackstersProducer as _trackstersProducer +from RecoHGCal.TICL.filteredLayerClustersProducer_cfi import filteredLayerClustersProducer as _filteredLayerClustersProducer +from RecoHGCal.TICL.multiClustersFromTrackstersProducer_cfi import multiClustersFromTrackstersProducer as _multiClustersFromTrackstersProducer + +# CLUSTER FILTERING/MASKING + +filteredLayerClustersTrkEM = _filteredLayerClustersProducer.clone( + clusterFilter = "ClusterFilterByAlgoAndSizeAndLayerRange", + min_cluster_size = 3, # inclusive + max_layerId = 30, # inclusive + algo_number = 8, + iteration_label = "TrkEM" +) + +# CA - PATTERN RECOGNITION + +ticlTrackstersTrkEM = _trackstersProducer.clone( + filtered_mask = cms.InputTag("filteredLayerClustersTrkEM", "TrkEM"), + seeding_regions = "ticlSeedingTrk", + filter_on_categories = [0, 1], + pid_threshold = 0.5, + energy_em_over_total_threshold = 0.9, + max_longitudinal_sigmaPCA = 10, + shower_start_max_layer = 5, #inclusive + max_out_in_hops = 1, + max_missing_layers_in_trackster = 2, + skip_layers = 2, + min_layers_per_trackster = 10, + min_cos_theta = 0.97, # ~14 degrees + min_cos_pointing = 0.94, # ~20 degrees + root_doublet_max_distance_from_seed_squared = 2.5e-3, # dR=0.05 + max_delta_time = 3., + itername = "TrkEM", + algo_verbosity = 0, +) + + +# MULTICLUSTERS + +ticlMultiClustersFromTrackstersTrkEM = _multiClustersFromTrackstersProducer.clone( + Tracksters = "ticlTrackstersTrkEM" +) + +ticlTrkEMStepTask = cms.Task(ticlSeedingTrk + ,filteredLayerClustersTrkEM + ,ticlTrackstersTrkEM + ,ticlMultiClustersFromTrackstersTrkEM) + diff --git a/RecoHGCal/TICL/python/TrkStep_cff.py b/RecoHGCal/TICL/python/TrkStep_cff.py index 686ea18b9032a..739a7cafd5d2b 100644 --- a/RecoHGCal/TICL/python/TrkStep_cff.py +++ b/RecoHGCal/TICL/python/TrkStep_cff.py @@ -9,20 +9,23 @@ # CLUSTER FILTERING/MASKING filteredLayerClustersTrk = _filteredLayerClustersProducer.clone( - clusterFilter = "ClusterFilterByAlgo", + clusterFilter = "ClusterFilterByAlgoAndSize", + min_cluster_size = 3, # inclusive algo_number = 8, + LayerClustersInputMask = 'ticlTrackstersEM', iteration_label = "Trk" ) # CA - PATTERN RECOGNITION ticlTrackstersTrk = _trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersTrk", "Trk"), + filtered_mask = "filteredLayerClustersTrk:Trk", seeding_regions = "ticlSeedingTrk", + original_mask = 'ticlTrackstersEM', filter_on_categories = [2, 4], # filter muons and charged hadrons pid_threshold = 0.0, - missing_layers = 3, - min_clusters_per_ntuplet = 10, + skip_layers = 3, + min_layers_per_trackster = 10, min_cos_theta = 0.866, # ~30 degrees min_cos_pointing = 0.798, # ~ 37 degrees max_delta_time = -1., @@ -43,3 +46,4 @@ ,ticlTrackstersTrk ,ticlMultiClustersFromTrackstersTrk) + diff --git a/RecoHGCal/TICL/python/iterativeTICL_cff.py b/RecoHGCal/TICL/python/iterativeTICL_cff.py index 18f3e67a00f4d..9af6dc68a9af6 100644 --- a/RecoHGCal/TICL/python/iterativeTICL_cff.py +++ b/RecoHGCal/TICL/python/iterativeTICL_cff.py @@ -1,16 +1,15 @@ import FWCore.ParameterSet.Config as cms from RecoHGCal.TICL.MIPStep_cff import * +from RecoHGCal.TICL.TrkEMStep_cff import * from RecoHGCal.TICL.TrkStep_cff import * from RecoHGCal.TICL.EMStep_cff import * from RecoHGCal.TICL.HADStep_cff import * from RecoHGCal.TICL.ticlLayerTileProducer_cfi import ticlLayerTileProducer -from RecoHGCal.TICL.ticlCandidateFromTrackstersProducer_cfi import ticlCandidateFromTrackstersProducer as _ticlCandidateFromTrackstersProducer from RecoHGCal.TICL.pfTICLProducer_cfi import pfTICLProducer as _pfTICLProducer from RecoHGCal.TICL.trackstersMergeProducer_cfi import trackstersMergeProducer as _trackstersMergeProducer from RecoHGCal.TICL.multiClustersFromTrackstersProducer_cfi import multiClustersFromTrackstersProducer as _multiClustersFromTrackstersProducer - ticlLayerTileTask = cms.Task(ticlLayerTileProducer) ticlTrackstersMerge = _trackstersMergeProducer.clone() @@ -19,23 +18,31 @@ ) ticlTracksterMergeTask = cms.Task(ticlTrackstersMerge, ticlMultiClustersFromTrackstersMerge) -ticlCandidateFromTracksters = _ticlCandidateFromTrackstersProducer.clone( - tracksterCollections = ["ticlTrackstersMerge"], - # A possible alternative for momentum computation: - # momentumPlugin = dict(plugin="TracksterP4FromTrackAndPCA") - ) + pfTICL = _pfTICLProducer.clone() -ticlPFTask = cms.Task(ticlCandidateFromTracksters, pfTICL) +ticlPFTask = cms.Task(pfTICL) iterTICLTask = cms.Task(ticlLayerTileTask - ,ticlMIPStepTask - ,ticlTrkStepTask + ,ticlTrkEMStepTask ,ticlEMStepTask + ,ticlTrkStepTask ,ticlHADStepTask ,ticlTracksterMergeTask ,ticlPFTask ) +ticlLayerTileHFNose = ticlLayerTileProducer.clone( + detector = 'HFNose' +) + +ticlLayerTileHFNoseTask = cms.Task(ticlLayerTileHFNose) + +iterHFNoseTICLTask = cms.Task( + ticlLayerTileHFNoseTask, + ticlHFNoseMIPStepTask, + ticlHFNoseEMStepTask +) + def injectTICLintoPF(process): if getattr(process,'particleFlowTmp', None): process.particleFlowTmp.src = ['particleFlowTmpBarrel', 'pfTICL'] diff --git a/RecoHGCal/TICL/python/ticl_iterations.py b/RecoHGCal/TICL/python/ticl_iterations.py index 09bd7f9e27597..4d54b16a6b8ab 100644 --- a/RecoHGCal/TICL/python/ticl_iterations.py +++ b/RecoHGCal/TICL/python/ticl_iterations.py @@ -39,11 +39,11 @@ def TICL_iterations_withReco(process): ) process.trackstersTrk = trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersTrk", "Trk"), + filtered_mask = "filteredLayerClustersTrk:Trk", seeding_regions = "ticlSeedingTrk", - missing_layers = 3, - min_clusters_per_ntuplet = 5, - min_cos_theta = 0.99, # ~10 degrees + skip_layers = 3, + min_layers_per_trackster = 5, + min_cos_theta = 0.99, # ~10 degrees min_cos_pointing = 0.9 ) @@ -64,10 +64,10 @@ def TICL_iterations_withReco(process): ) process.trackstersMIP = trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersMIP", "MIP"), + filtered_mask = "filteredLayerClustersMIP:MIP", seeding_regions = "ticlSeedingGlobal", - missing_layers = 3, - min_clusters_per_ntuplet = 15, + skip_layers = 3, + min_layers_per_trackster = 15, min_cos_theta = 0.99, # ~10 degrees min_cos_pointing = 0.9, out_in_dfs = False, @@ -89,10 +89,10 @@ def TICL_iterations_withReco(process): process.trackstersEM = trackstersProducer.clone( max_out_in_hops = 4, original_mask = "trackstersMIP", - filtered_mask = cms.InputTag("filteredLayerClusters", "algo8"), + filtered_mask = "filteredLayerClusters:algo8", seeding_regions = "ticlSeedingGlobal", - missing_layers = 1, - min_clusters_per_ntuplet = 10, + skip_layers = 1, + min_layers_per_trackster = 10, min_cos_theta = 0.984, # ~10 degrees min_cos_pointing = 0.9 # ~26 degrees ) @@ -103,11 +103,11 @@ def TICL_iterations_withReco(process): process.trackstersHAD = trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClusters", "algo8"), + filtered_mask = "filteredLayerClusters:algo8", seeding_regions = "ticlSeedingGlobal", - missing_layers = 2, - min_clusters_per_ntuplet = 10, - min_cos_theta = 0.8, + skip_layers = 2, + min_layers_per_trackster = 10, + min_cos_theta = 0.8, min_cos_pointing = 0.7 ) @@ -142,13 +142,13 @@ def TICL_iterations_withReco(process): process.ticlPFValidation = ticlPFValidation process.hgcalValidation.insert(-1, process.ticlPFValidation) - + if getattr(process,'hgcalValidator'): - process.hgcalValidator.label_lcl = cms.InputTag("hgcalLayerClusters") - process.hgcalValidator.label_mcl = cms.VInputTag(cms.InputTag("multiClustersFromTrackstersEM", "MultiClustersFromTracksterByCA"), cms.InputTag("multiClustersFromTrackstersHAD", "MultiClustersFromTracksterByCA")) + process.hgcalValidator.label_lcl = "hgcalLayerClusters" + process.hgcalValidator.label_mcl = ["multiClustersFromTrackstersEM:MultiClustersFromTracksterByCA", "multiClustersFromTrackstersHAD:MultiClustersFromTracksterByCA"] process.hgcalValidator.domulticlustersPlots = True - + return process @@ -171,10 +171,10 @@ def TICL_iterations(process): ) process.trackstersMIP = trackstersProducer.clone( - filtered_mask = cms.InputTag("filteredLayerClustersMIP", "MIP"), + filtered_mask = "filteredLayerClustersMIP:MIP", seeding_regions = "ticlSeedingGlobal", - missing_layers = 3, - min_clusters_per_ntuplet = 15, + skip_layers = 3, + min_layers_per_trackster = 15, min_cos_theta = 0.99, # ~10 degrees ) @@ -192,10 +192,10 @@ def TICL_iterations(process): process.tracksters = trackstersProducer.clone( original_mask = "trackstersMIP", - filtered_mask = cms.InputTag("filteredLayerClusters", "algo8"), + filtered_mask = "filteredLayerClusters:algo8", seeding_regions = "ticlSeedingGlobal", - missing_layers = 2, - min_clusters_per_ntuplet = 15, + skip_layers = 2, + min_layers_per_trackster = 15, min_cos_theta = 0.94, # ~20 degrees min_cos_pointing = 0.7 ) diff --git a/RecoJets/JetProducers/plugins/BoostedTauSeedsProducer.cc b/RecoJets/JetProducers/plugins/BoostedTauSeedsProducer.cc index 69503a88ab451..832c0ab5aac00 100644 --- a/RecoJets/JetProducers/plugins/BoostedTauSeedsProducer.cc +++ b/RecoJets/JetProducers/plugins/BoostedTauSeedsProducer.cc @@ -157,10 +157,7 @@ namespace { const reco::Jet& jet, const edm::Handle& pfCandidates, const JetToConstitMap::value_type& constitmap, - const reco::Jet::Constituents& jetConstituents, - double /*dRmatch*/, bool invert) { - //const double dRmatch2 = dRmatch*dRmatch; // comment out for now in case someone needs a dR-based search again auto const& collection_cand = (*pfCandidates); std::vector pfCandidates_exclJetConstituents; size_t numPFCandidates = pfCandidates->size(); @@ -256,10 +253,10 @@ void BoostedTauSeedsProducer::produce(edm::Event& evt, const edm::EventSetup& es edm::Ref subjetRef2(selectedSubjetRefProd, selectedSubjets->size() - 1); // find all PFCandidates that are not constituents of the **other** subjet - std::vector pfCandidatesNotInSubjet1 = getPFCandidates_exclJetConstituents( - *subjet1, pfCandidates, constitmap[2 * idx], subjetConstituents2, 1.e-4, false); - std::vector pfCandidatesNotInSubjet2 = getPFCandidates_exclJetConstituents( - *subjet2, pfCandidates, constitmap[2 * idx + 1], subjetConstituents1, 1.e-4, false); + std::vector pfCandidatesNotInSubjet1 = + getPFCandidates_exclJetConstituents(*subjet1, pfCandidates, constitmap[2 * idx + 1], false); + std::vector pfCandidatesNotInSubjet2 = + getPFCandidates_exclJetConstituents(*subjet2, pfCandidates, constitmap[2 * idx], false); if (verbosity_ >= 1) { std::cout << "#pfCandidatesNotInSubjet1 = " << pfCandidatesNotInSubjet1.size() << std::endl; std::cout << "#pfCandidatesNotInSubjet2 = " << pfCandidatesNotInSubjet2.size() << std::endl; diff --git a/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py b/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py index 057707c80534e..ddcab0252afcf 100644 --- a/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py +++ b/RecoLocalCalo/Configuration/python/hcalLocalReco_cff.py @@ -22,6 +22,9 @@ from RecoLocalCalo.HcalRecProducers.HFPhase1Reconstructor_cfi import hfreco as _phase1_hfreco from RecoLocalCalo.HcalRecProducers.hbheplan1_cfi import hbheplan1 +#--- for HCALonly wf +hcalOnlyLocalRecoTask = cms.Task(hbheprereco,hfprereco,hfreco,horeco) + # copy for cosmics _default_hfreco = hfreco.clone() diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/HGCal3DClustering.h b/RecoLocalCalo/HGCalRecAlgos/interface/HGCal3DClustering.h index e12d2620d064c..0fd3fba15249c 100644 --- a/RecoLocalCalo/HGCalRecAlgos/interface/HGCal3DClustering.h +++ b/RecoLocalCalo/HGCalRecAlgos/interface/HGCal3DClustering.h @@ -36,7 +36,9 @@ class HGCal3DClustering { void getEvent(const edm::Event& ev) { clusterTools->getEvent(ev); } void getEventSetup(const edm::EventSetup& es) { clusterTools->getEventSetup(es); - rhtools_.getEventSetup(es); + edm::ESHandle geom; + es.get().get(geom); + rhtools_.setGeometry(*geom); maxlayer = rhtools_.lastLayerBH(); points.clear(); minpos.clear(); diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/HGCalDepthPreClusterer.h b/RecoLocalCalo/HGCalRecAlgos/interface/HGCalDepthPreClusterer.h index 1be09da6c8251..ad74c02963802 100644 --- a/RecoLocalCalo/HGCalRecAlgos/interface/HGCalDepthPreClusterer.h +++ b/RecoLocalCalo/HGCalRecAlgos/interface/HGCalDepthPreClusterer.h @@ -35,7 +35,9 @@ class HGCalDepthPreClusterer { void getEvent(const edm::Event& ev) { clusterTools->getEvent(ev); } void getEventSetup(const edm::EventSetup& es) { clusterTools->getEventSetup(es); - rhtools_.getEventSetup(es); + edm::ESHandle geom; + es.get().get(geom); + rhtools_.setGeometry(*geom); } typedef std::vector ClusterCollection; diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/HGCalRecHitAbsAlgo.h b/RecoLocalCalo/HGCalRecAlgos/interface/HGCalRecHitAbsAlgo.h index 66611fca86844..d880716869f09 100644 --- a/RecoLocalCalo/HGCalRecAlgos/interface/HGCalRecHitAbsAlgo.h +++ b/RecoLocalCalo/HGCalRecAlgos/interface/HGCalRecHitAbsAlgo.h @@ -22,7 +22,7 @@ class HGCalRecHitAbsAlgo { /// Destructor virtual ~HGCalRecHitAbsAlgo(){}; - inline void set(const edm::EventSetup& es) { rhtools_.getEventSetup(es); } + inline void set(const CaloGeometry& geom) { rhtools_.setGeometry(geom); } /// make rechits from dataframes virtual void setLayerWeights(const std::vector& weights){}; diff --git a/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h b/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h index 2ef4de13a1cf0..f18c1cafb8d33 100644 --- a/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h +++ b/RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h @@ -7,6 +7,8 @@ #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/ForwardDetId/interface/ForwardSubdetector.h" #include "DataFormats/ForwardDetId/interface/HFNoseDetId.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" class CaloGeometry; class CaloSubdetectorGeometry; @@ -23,8 +25,7 @@ namespace hgcal { RecHitTools() : geom_(nullptr), fhOffset_(0), bhOffset_(0), fhLastLayer_(0), noseLastLayer_(0), geometryType_(0) {} ~RecHitTools() {} - void getEvent(const edm::Event&); - void getEventSetup(const edm::EventSetup&); + void setGeometry(CaloGeometry const&); const CaloSubdetectorGeometry* getSubdetectorGeometry(const DetId& id) const; GlobalPoint getPosition(const DetId& id) const; diff --git a/RecoLocalCalo/HGCalRecAlgos/src/ClusterTools.cc b/RecoLocalCalo/HGCalRecAlgos/src/ClusterTools.cc index 778db1264fb31..098c5b3990510 100644 --- a/RecoLocalCalo/HGCalRecAlgos/src/ClusterTools.cc +++ b/RecoLocalCalo/HGCalRecAlgos/src/ClusterTools.cc @@ -5,6 +5,7 @@ #include "DataFormats/HcalDetId/interface/HcalSubdetector.h" #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" #include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" #include "FWCore/Framework/interface/ESHandle.h" @@ -25,7 +26,6 @@ ClusterTools::ClusterTools(const edm::ParameterSet& conf, edm::ConsumesCollector bhtok(sumes.consumes(conf.getParameter("HGCBHInput"))) {} void ClusterTools::getEvent(const edm::Event& ev) { - rhtools_.getEvent(ev); edm::Handle temp; ev.getByToken(eetok, temp); eerh_ = temp.product(); @@ -35,7 +35,11 @@ void ClusterTools::getEvent(const edm::Event& ev) { bhrh_ = temp.product(); } -void ClusterTools::getEventSetup(const edm::EventSetup& es) { rhtools_.getEventSetup(es); } +void ClusterTools::getEventSetup(const edm::EventSetup& es) { + edm::ESHandle geom; + es.get().get(geom); + rhtools_.setGeometry(*geom); +} float ClusterTools::getClusterHadronFraction(const reco::CaloCluster& clus) const { float energy = 0.f, energyHad = 0.f; diff --git a/RecoLocalCalo/HGCalRecAlgos/src/RecHitTools.cc b/RecoLocalCalo/HGCalRecAlgos/src/RecHitTools.cc index fafea478bce5b..2d99384d5b197 100644 --- a/RecoLocalCalo/HGCalRecAlgos/src/RecHitTools.cc +++ b/RecoLocalCalo/HGCalRecAlgos/src/RecHitTools.cc @@ -65,13 +65,8 @@ namespace { } // namespace -void RecHitTools::getEvent(const edm::Event& ev) {} - -void RecHitTools::getEventSetup(const edm::EventSetup& es) { - edm::ESHandle geom; - es.get().get(geom); - - geom_ = geom.product(); +void RecHitTools::setGeometry(const CaloGeometry& geom) { + geom_ = &geom; unsigned int wmaxEE(0), wmaxFH(0); auto geomEE = static_cast( geom_->getSubdetectorGeometry(DetId::HGCalEE, ForwardSubdetector::ForwardEmpty)); @@ -364,6 +359,7 @@ unsigned int RecHitTools::getLayerWithOffset(const DetId& id) const { } else if (id.det() == DetId::Hcal && id.subdetId() == HcalEndcap) { layer += bhOffset_; } + // no need to add offset for HFnose return layer; } @@ -417,13 +413,12 @@ bool RecHitTools::isHalfCell(const DetId& id) const { } bool RecHitTools::isSilicon(const DetId& id) const { - bool issilicon = false; - if (id.det() == DetId::HGCalEE || id.det() == DetId::HGCalHSi) - issilicon = true; - return issilicon; + return (id.det() == DetId::HGCalEE || id.det() == DetId::HGCalHSi || + (id.det() == DetId::Forward && id.subdetId() == static_cast(HFNose))); } bool RecHitTools::isOnlySilicon(const unsigned int layer) const { + // HFnose TODO bool isonlysilicon = (layer % bhLastLayer_) < bhOffset_; return isonlysilicon; } diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h index 3d7dbf4d7b0c0..11dd849ea1f80 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h @@ -59,7 +59,9 @@ class HGCalClusteringAlgoBase { virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} inline void getEventSetup(const edm::EventSetup &es) { - rhtools_.getEventSetup(es); + edm::ESHandle geom; + es.get().get(geom); + rhtools_.setGeometry(*geom); maxlayer_ = rhtools_.lastLayer(isNose_); lastLayerEE_ = rhtools_.lastLayerEE(isNose_); lastLayerFH_ = rhtools_.lastLayerFH(); diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h index 6d7e2dd900265..ba072a85de7fd 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h @@ -65,9 +65,12 @@ class HGCalImagingAlgo : public HGCalClusteringAlgoBase { // use this if you want to reuse the same cluster object but don't want to accumulate clusters (hardly useful?) void reset() override { clusters_v_.clear(); + clusters_v_.shrink_to_fit(); layerClustersPerLayer_.clear(); + layerClustersPerLayer_.shrink_to_fit(); for (auto &it : points_) { it.clear(); + it.shrink_to_fit(); std::vector().swap(it); } for (unsigned int i = 0; i < minpos_.size(); i++) { diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h index caf5faee1e374..bfca51b3c0384 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h @@ -63,12 +63,16 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { void reset() override { clusters_v_.clear(); + clusters_v_.shrink_to_fit(); for (auto& cl : numberOfClustersPerLayer_) { cl = 0; } - for (auto& cells : cells_) + for (auto& cells : cells_) { cells.clear(); + cells.shrink_to_fit(); + } + density_.clear(); } Density getDensity() override; @@ -174,6 +178,23 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { followers.clear(); isSeed.clear(); } + + void shrink_to_fit() { + detid.shrink_to_fit(); + isSi.shrink_to_fit(); + x.shrink_to_fit(); + y.shrink_to_fit(); + eta.shrink_to_fit(); + phi.shrink_to_fit(); + weight.shrink_to_fit(); + rho.shrink_to_fit(); + delta.shrink_to_fit(); + nearestHigher.shrink_to_fit(); + clusterIndex.shrink_to_fit(); + sigmaNoise.shrink_to_fit(); + followers.shrink_to_fit(); + isSeed.shrink_to_fit(); + } }; std::vector cells_; diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc index bc5c7d90692b2..fba15664ae202 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc @@ -133,8 +133,6 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& clusters_sharing(new std::vector); auto density = std::make_unique(); - algo->reset(); - algo->getEventSetup(es); //make a map detid-rechit @@ -246,6 +244,7 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& clusterPtrsSharing.push_back(ptr); } } + algo->reset(); } #endif diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalRecHitWorkerSimple.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalRecHitWorkerSimple.cc index fffceca3877fa..12d1aea330aef 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalRecHitWorkerSimple.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalRecHitWorkerSimple.cc @@ -87,8 +87,10 @@ HGCalRecHitWorkerSimple::HGCalRecHitWorkerSimple(const edm::ParameterSet& ps) : } void HGCalRecHitWorkerSimple::set(const edm::EventSetup& es) { - tools_->getEventSetup(es); - rechitMaker_->set(es); + edm::ESHandle geom; + es.get().get(geom); + tools_->setGeometry(*geom); + rechitMaker_->set(*geom); if (hgcEE_isSiFE_) { edm::ESHandle hgceeGeoHandle; es.get().get("HGCalEESensitive", hgceeGeoHandle); diff --git a/RecoMET/METPUSubtraction/plugins/DeepMETProducer.cc b/RecoMET/METPUSubtraction/plugins/DeepMETProducer.cc index 8ffa271c9aa20..ed349276b5b75 100644 --- a/RecoMET/METPUSubtraction/plugins/DeepMETProducer.cc +++ b/RecoMET/METPUSubtraction/plugins/DeepMETProducer.cc @@ -69,7 +69,7 @@ DeepMETProducer::DeepMETProducer(const edm::ParameterSet& cfg, const DeepMETCach void DeepMETProducer::produce(edm::Event& event, const edm::EventSetup& setup) { auto const& pfs = event.get(pf_token_); - static const tensorflow::NamedTensorList input_list = { + const tensorflow::NamedTensorList input_list = { {"input", input_}, {"input_cat0", input_cat0_}, {"input_cat1", input_cat1_}, {"input_cat2", input_cat2_}}; // Set all inputs to zero diff --git a/RecoParticleFlow/PFClusterProducer/interface/PFHGCalRecHitCreator.h b/RecoParticleFlow/PFClusterProducer/interface/PFHGCalRecHitCreator.h index 3809c1ec02500..73d4a8197bad4 100644 --- a/RecoParticleFlow/PFClusterProducer/interface/PFHGCalRecHitCreator.h +++ b/RecoParticleFlow/PFClusterProducer/interface/PFHGCalRecHitCreator.h @@ -36,7 +36,9 @@ class PFHGCalRecHitCreator : public PFRecHitCreatorBase { const edm::Event& iEvent, const edm::EventSetup& iSetup) override { // Setup RecHitTools to properly compute the position of the HGCAL Cells vie their DetIds - recHitTools_.getEventSetup(iSetup); + edm::ESHandle geoHandle; + iSetup.get().get(geoHandle); + recHitTools_.setGeometry(*geoHandle); for (unsigned int i = 0; i < qualityTests_.size(); ++i) { qualityTests_.at(i)->beginEvent(iEvent, iSetup); @@ -46,8 +48,6 @@ class PFHGCalRecHitCreator : public PFRecHitCreatorBase { iEvent.getByToken(recHitToken_, recHitHandle); const HGCRecHitCollection& rechits = *recHitHandle; - edm::ESHandle geoHandle; - iSetup.get().get(geoHandle); const CaloGeometry* geom = geoHandle.product(); unsigned skipped_rechits = 0; diff --git a/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.cc b/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.cc index d219a28516ad7..bd30a46aaec10 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.cc @@ -5,7 +5,10 @@ #include "DataFormats/ForwardDetId/interface/HGCalDetId.h" -void PFClusterFromHGCalMultiCluster::updateEvent(const edm::Event& ev) { ev.getByToken(clusterToken_, clusterH_); } +void PFClusterFromHGCalMultiCluster::updateEvent(const edm::Event& ev) { + ev.getByToken(clusterToken_, clusterH_); + ev.getByToken(tracksterToken_, trackstersH_); +} void PFClusterFromHGCalMultiCluster::buildClusters(const edm::Handle& input, const std::vector& rechitMask, @@ -14,43 +17,74 @@ void PFClusterFromHGCalMultiCluster::buildClusters(const edm::Handle detIdToIndex(hits.size()); for (uint32_t i = 0; i < hits.size(); ++i) { detIdToIndex[hits[i].detId()] = i; } + int iMultiClus = -1; + for (const auto& mcl : hgcalMultiClusters) { + iMultiClus++; + + // Skip empty multiclusters + if (mcl.hitsAndFractions().empty()) { + continue; + } + + // Filter using trackster PID + if (filterByTracksterPID_) { + float probTotal = 0.0f; + + for (int cat : filter_on_categories_) { + probTotal += tracksters[iMultiClus].id_probabilities(cat); + } + + if (probTotal < pid_threshold_) { + continue; + } + } + DetId seed; double energy = 0.0, highest_energy = 0.0; output.emplace_back(); reco::PFCluster& back = output.back(); - for (const auto& cl : mcl) { - const auto& hitsAndFractions = cl->hitsAndFractions(); - for (const auto& hAndF : hitsAndFractions) { - auto itr = detIdToIndex.find(hAndF.first); - if (itr == detIdToIndex.end()) { - continue; // hit wasn't saved in reco - } - auto ref = makeRefhit(input, itr->second); - assert(ref->detId() == hAndF.first.rawId()); - const double hit_energy = hAndF.second * ref->energy(); - energy += hit_energy; - back.addRecHitFraction(reco::PFRecHitFraction(ref, hAndF.second)); - // TODO: the following logic to identify the seed of a cluster - // could be appropriate for the Run2 Ecal Calorimetric - // detector, but could be wrong for the HGCal one. This has to - // be reviewd. - if (hit_energy > highest_energy || highest_energy == 0.0) { - highest_energy = hit_energy; - seed = ref->detId(); - } - } // end of hitsAndFractions - } // end of loop over clusters (2D/layer) - if (energy <= 1) { - output.pop_back(); - continue; + const auto& hitsAndFractions_mcl = mcl.hitsAndFractions(); + + std::vector > hitsAndFractions; + hitsAndFractions.insert(hitsAndFractions.end(), hitsAndFractions_mcl.begin(), hitsAndFractions_mcl.end()); + + // Use the H&F of the clusters inside the multicluster if the latter's H&F are not stored + if (hitsAndFractions.empty()) { + for (const auto& cl : mcl) { + const auto& hAndF_temp = cl->hitsAndFractions(); + hitsAndFractions.insert(hitsAndFractions.end(), hAndF_temp.begin(), hAndF_temp.end()); + } } + + for (const auto& hAndF : hitsAndFractions) { + auto itr = detIdToIndex.find(hAndF.first); + if (itr == detIdToIndex.end()) { + continue; // hit wasn't saved in reco + } + auto ref = makeRefhit(input, itr->second); + assert(ref->detId() == hAndF.first.rawId()); + const double hit_energy = hAndF.second * ref->energy(); + energy += hit_energy; + back.addRecHitFraction(reco::PFRecHitFraction(ref, hAndF.second)); + // TODO: the following logic to identify the seed of a cluster + // could be appropriate for the Run2 Ecal Calorimetric + // detector, but could be wrong for the HGCal one. This has to + // be reviewd. + if (hit_energy > highest_energy || highest_energy == 0.0) { + highest_energy = hit_energy; + seed = ref->detId(); + } + } // end of hitsAndFractions + if (!back.hitsAndFractions().empty()) { back.setSeed(seed); back.setEnergy(energy); diff --git a/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.h b/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.h index b6695719eb649..4bd77a95e6673 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.h +++ b/RecoParticleFlow/PFClusterProducer/plugins/PFClusterFromHGCalMultiCluster.h @@ -1,6 +1,7 @@ #ifndef __RecoParticleFlow_PFClusterProducer_PFClusterFromHGCalMultiCluster_H__ #define __RecoParticleFlow_PFClusterProducer_PFClusterFromHGCalMultiCluster_H__ +#include "DataFormats/HGCalReco/interface/Trackster.h" #include "DataFormats/ParticleFlowReco/interface/HGCalMultiCluster.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h" #include "RecoParticleFlow/PFClusterProducer/interface/InitialClusteringStepBase.h" @@ -9,9 +10,15 @@ class PFClusterFromHGCalMultiCluster : public InitialClusteringStepBase { public: PFClusterFromHGCalMultiCluster(const edm::ParameterSet& conf, edm::ConsumesCollector& sumes) : InitialClusteringStepBase(conf, sumes) { + filterByTracksterPID_ = conf.getParameter("filterByTracksterPID"); + pid_threshold_ = conf.getParameter("pid_threshold"); + filter_on_categories_ = conf.getParameter >("filter_on_categories"); + clusterToken_ = sumes.consumes >(conf.getParameter("clusterSrc")); + tracksterToken_ = sumes.consumes >(conf.getParameter("tracksterSrc")); } + ~PFClusterFromHGCalMultiCluster() override {} PFClusterFromHGCalMultiCluster(const PFClusterFromHGCalMultiCluster&) = delete; PFClusterFromHGCalMultiCluster& operator=(const PFClusterFromHGCalMultiCluster&) = delete; @@ -24,8 +31,15 @@ class PFClusterFromHGCalMultiCluster : public InitialClusteringStepBase { reco::PFClusterCollection&) override; private: + bool filterByTracksterPID_; + float pid_threshold_; + std::vector filter_on_categories_; + edm::EDGetTokenT > clusterToken_; edm::Handle > clusterH_; + + edm::EDGetTokenT > tracksterToken_; + edm::Handle > trackstersH_; }; DEFINE_EDM_PLUGIN(InitialClusteringStepFactory, PFClusterFromHGCalMultiCluster, "PFClusterFromHGCalMultiCluster"); diff --git a/RecoParticleFlow/PFClusterProducer/plugins/SimMappers/RealisticSimClusterMapper.cc b/RecoParticleFlow/PFClusterProducer/plugins/SimMappers/RealisticSimClusterMapper.cc index 4bfe67108cf1d..9022fbf721593 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/SimMappers/RealisticSimClusterMapper.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/SimMappers/RealisticSimClusterMapper.cc @@ -43,7 +43,11 @@ namespace { void RealisticSimClusterMapper::updateEvent(const edm::Event& ev) { ev.getByToken(simClusterToken_, simClusterH_); } -void RealisticSimClusterMapper::update(const edm::EventSetup& es) { rhtools_.getEventSetup(es); } +void RealisticSimClusterMapper::update(const edm::EventSetup& es) { + edm::ESHandle geom; + es.get().get(geom); + rhtools_.setGeometry(*geom); +} void RealisticSimClusterMapper::buildClusters(const edm::Handle& input, const std::vector& rechitMask, diff --git a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHBHE_cfi.py b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHBHE_cfi.py index 85aa0b6db8b14..f021415aa3ef1 100644 --- a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHBHE_cfi.py +++ b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHBHE_cfi.py @@ -141,3 +141,8 @@ allCellsPositionCalc = dict(logWeightDenominatorByDetector = {0 : dict(logWeightDenominator = _thresholdsHBphase1) } ), ), ) + +# HCALonly WF +particleFlowClusterHBHEOnly = particleFlowClusterHBHE.clone( + recHitsSource = cms.InputTag("particleFlowRecHitHBHEOnly") +) diff --git a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHCAL_cfi.py b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHCAL_cfi.py index a37a6f16f57ff..d5244e33a3fa8 100644 --- a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHCAL_cfi.py +++ b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHCAL_cfi.py @@ -50,3 +50,8 @@ allCellsPositionCalc = dict(logWeightDenominatorByDetector = {0 : dict(logWeightDenominator = _thresholdsHBphase1) } ), ), ) + +# HCALonly WF +particleFlowClusterHCALOnly = particleFlowClusterHCAL.clone( + clustersSource = cms.InputTag("particleFlowClusterHBHEOnly") +) diff --git a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py index e9c5860c95322..04dfee19e226d 100644 --- a/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py +++ b/RecoParticleFlow/PFClusterProducer/python/particleFlowClusterHGC_cfi.py @@ -48,7 +48,11 @@ algoName = cms.string("PFClusterFromHGCalMultiCluster"), thresholdsByDetector = cms.VPSet( ), - clusterSrc = cms.InputTag("hgcalMultiClusters") + clusterSrc = cms.InputTag("ticlMultiClustersFromTrackstersMerge"), + tracksterSrc = cms.InputTag("ticlTrackstersMerge"), + filterByTracksterPID = cms.bool(False), + pid_threshold = cms.double(0.8), + filter_on_categories = cms.vint32([0, 1]), ) particleFlowClusterHGCal = cms.EDProducer( diff --git a/RecoParticleFlow/PFClusterProducer/python/particleFlowCluster_cff.py b/RecoParticleFlow/PFClusterProducer/python/particleFlowCluster_cff.py index b4fe8317924d0..a6f99cd036911 100644 --- a/RecoParticleFlow/PFClusterProducer/python/particleFlowCluster_cff.py +++ b/RecoParticleFlow/PFClusterProducer/python/particleFlowCluster_cff.py @@ -38,6 +38,12 @@ particleFlowClusterHCAL) pfClusteringHBHEHF = cms.Sequence(pfClusteringHBHEHFTask) +pfClusteringHBHEHFOnlyTask = cms.Task(particleFlowRecHitHBHEOnly, + particleFlowRecHitHF, + particleFlowClusterHBHEOnly, + particleFlowClusterHF, + particleFlowClusterHCALOnly) + pfClusteringHOTask = cms.Task(particleFlowRecHitHO,particleFlowClusterHO) pfClusteringHO = cms.Sequence(pfClusteringHOTask) diff --git a/RecoParticleFlow/PFClusterProducer/python/particleFlowRecHitHBHE_cfi.py b/RecoParticleFlow/PFClusterProducer/python/particleFlowRecHitHBHE_cfi.py index 9a27ef70f53cf..9acc44e6470d0 100644 --- a/RecoParticleFlow/PFClusterProducer/python/particleFlowRecHitHBHE_cfi.py +++ b/RecoParticleFlow/PFClusterProducer/python/particleFlowRecHitHBHE_cfi.py @@ -53,3 +53,8 @@ run3_HB.toModify(particleFlowRecHitHBHE, producers = {0 : dict(qualityTests = {0 : dict(cuts = {0 : dict(threshold = _thresholdsHBphase1) } ) } ) }, ) + +# HCALonly WF +particleFlowRecHitHBHEOnly = particleFlowRecHitHBHE.clone( + producers = { 0: dict(src = cms.InputTag("hbheprereco","")) } +) diff --git a/RecoTauTag/Configuration/python/HPSPFTaus_cff.py b/RecoTauTag/Configuration/python/HPSPFTaus_cff.py index f5b5c66c46405..e4e48b362898d 100644 --- a/RecoTauTag/Configuration/python/HPSPFTaus_cff.py +++ b/RecoTauTag/Configuration/python/HPSPFTaus_cff.py @@ -13,7 +13,7 @@ from RecoTauTag.RecoTau.PFRecoTauDiscriminationByLeadingTrackFinding_cfi import * from RecoTauTag.RecoTau.PFRecoTauDiscriminationAgainstElectron_cfi import * from RecoTauTag.RecoTau.PFRecoTauDiscriminationAgainstElectronMVA6_cfi import * -from RecoTauTag.RecoTau.PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi import * +from RecoTauTag.RecoTau.pfRecoTauDiscriminationAgainstElectronDeadECAL_cfi import * from RecoTauTag.RecoTau.PFRecoTauDiscriminationAgainstMuon_cfi import * from RecoTauTag.RecoTau.pfRecoTauDiscriminationAgainstMuon2Container_cfi import * from RecoTauTag.RecoTau.PFRecoTauDiscriminationAgainstMuonMVA_cfi import * diff --git a/RecoTauTag/RecoTau/BuildFile.xml b/RecoTauTag/RecoTau/BuildFile.xml index 5a798e598d987..ee15b23a648ed 100644 --- a/RecoTauTag/RecoTau/BuildFile.xml +++ b/RecoTauTag/RecoTau/BuildFile.xml @@ -1,12 +1,17 @@ + + + + + diff --git a/RecoTauTag/RecoTau/interface/AntiElectronDeadECAL.h b/RecoTauTag/RecoTau/interface/AntiElectronDeadECAL.h new file mode 100644 index 0000000000000..d37bb1b73b5bd --- /dev/null +++ b/RecoTauTag/RecoTau/interface/AntiElectronDeadECAL.h @@ -0,0 +1,74 @@ +#ifndef RecoTauTag_RecoTau_AntiElectronDeadECAL_h +#define RecoTauTag_RecoTau_AntiElectronDeadECAL_h + +/** \class AntiElectronDeadECAL + * + * Flag tau candidates reconstructed near dead ECAL channels, + * in order to reduce e -> tau fakes not rejected by anti-e MVA discriminator + * + * The motivation for this flag is this presentation: + * https://indico.cern.ch/getFile.py/access?contribId=0&resId=0&materialId=slides&confId=177223 + * + * Code adapted from: + * RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationAgainstElectronDeadECAL.cc + * + * \authors Lauri Andreas Wendland, + * Christian Veelken + * + * + * + */ + +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ESWatcher.h" +#include "DataFormats/Candidate/interface/Candidate.h" +#include "RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h" + +#include +#include + +class EcalChannelStatusRcd; +class CaloGeometryRecord; +class IdealGeometryRecord; + +class AntiElectronDeadECAL { +public: + explicit AntiElectronDeadECAL(const edm::ParameterSet&); + ~AntiElectronDeadECAL(); + + void beginEvent(const edm::EventSetup&); + + bool operator()(const reco::Candidate* tau) const; + +private: + const unsigned minStatus_; + const double dR2_; + const bool extrapolateToECalEntrance_; + const int verbosity_; + + PositionAtECalEntranceComputer positionAtECalEntrance_; + + void updateBadTowers(const edm::EventSetup&); + + struct TowerInfo { + TowerInfo(uint32_t id, unsigned nBad, unsigned maxStatus, double eta, double phi) + : id_(id), nBad_(nBad), maxStatus_(maxStatus), eta_(eta), phi_(phi) {} + uint32_t id_; + unsigned nBad_; + unsigned maxStatus_; + double eta_; + double phi_; + }; + + std::vector badTowers_; + static const uint16_t statusMask_ = 0x1F; + + edm::ESWatcher channelStatusWatcher_; + edm::ESWatcher caloGeometryWatcher_; + edm::ESWatcher idealGeometryWatcher_; + + bool isFirstEvent_; +}; + +#endif // RecoTauTag_RecoTau_AntiElectronDeadECAL_h diff --git a/RecoTauTag/RecoTau/interface/AntiElectronIDMVA6.h b/RecoTauTag/RecoTau/interface/AntiElectronIDMVA6.h index 1283be084da1f..0a6473d62d6ad 100644 --- a/RecoTauTag/RecoTau/interface/AntiElectronIDMVA6.h +++ b/RecoTauTag/RecoTau/interface/AntiElectronIDMVA6.h @@ -22,9 +22,8 @@ #include "CondFormats/EgammaObjects/interface/GBRForest.h" #include "DataFormats/PatCandidates/interface/Tau.h" #include "DataFormats/PatCandidates/interface/Electron.h" - -#include "CommonTools/BaseParticlePropagator/interface/BaseParticlePropagator.h" #include "DataFormats/PatCandidates/interface/PackedCandidate.h" +#include "RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h" #include "TMVA/Tools.h" #include "TMVA/Reader.h" @@ -125,7 +124,7 @@ class AntiElectronIDMVA6 { double MVAValue(const pat::Tau& theTau, const pat::Electron& theEle); // this function can be called for category 1 only !! double MVAValue(const pat::Tau& theTau); - // track extrapolation to ECAL entrance (used to re-calculate varibales that might not be available on miniAOD) + // track extrapolation to ECAL entrance (used to re-calculate variables that might not be available on miniAOD) bool atECalEntrance(const reco::Candidate* part, math::XYZPoint& pos); private: @@ -168,7 +167,8 @@ class AntiElectronIDMVA6 { std::vector inputFilesToDelete_; - double bField_; + PositionAtECalEntranceComputer positionAtECalEntrance_; + int verbosity_; }; diff --git a/RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h b/RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h new file mode 100644 index 0000000000000..0b167c2568549 --- /dev/null +++ b/RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h @@ -0,0 +1,33 @@ +#ifndef RecoTauTag_RecoTau_PositionAtECalEntranceComputer_h +#define RecoTauTag_RecoTau_PositionAtECalEntranceComputer_h + +/** \class PositionAtECalEntranceComputer + * + * Extrapolate particle (charged or neutral) to ECAL entrance, + * in order to compute the distance of the tau to ECAL cracks and/or dead ECAL channels + * + * \authors Fabio Colombo, + * Christian Veelken + * + * + * + */ + +#include "FWCore/Framework/interface/EventSetup.h" +#include "DataFormats/Candidate/interface/Candidate.h" + +class PositionAtECalEntranceComputer { +public: + PositionAtECalEntranceComputer(); + ~PositionAtECalEntranceComputer(); + + void beginEvent(const edm::EventSetup&); + + //To do: it seems to more practical to put this to the ES + reco::Candidate::Point operator()(const reco::Candidate* particle, bool& success) const; + +private: + double bField_z_; +}; + +#endif // RecoTauTag_RecoTau_PositionAtECalEntranceComputer_h diff --git a/RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h b/RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h index cdf527c5af624..521b2ac1f29f0 100644 --- a/RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h +++ b/RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h @@ -93,6 +93,10 @@ class TauDiscriminationProducerBase : public edm::stream::EDProducer<> { static void fillProducerDescriptions(edm::ParameterSetDescription& desc); + /// helper method to retrieve tau type name, e.g. to build correct cfi getter + //string (i.e. PFTau/PATTauProducer) + static std::string getTauTypeString(); + protected: //value given to taus that fail prediscriminants double prediscriminantFailValue_; @@ -125,13 +129,4 @@ typedef TauDiscriminationProducerBase PATTauDiscriminationProducerBase; -/// helper function retrieve the correct cfi getter string (ie PFTauProducer) -//for this tau type -template -std::string getProducerString() { - // this generic one shoudl never be called. - // these are specialized in TauDiscriminationProducerBase.cc - throw cms::Exception("TauDiscriminationProducerBase") - << "Unsupported TauType used. You must use either PFTau or PATTau."; -} #endif diff --git a/RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationAgainstElectronDeadECAL.cc b/RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationAgainstElectronDeadECAL.cc deleted file mode 100644 index b7f7634c9c41d..0000000000000 --- a/RecoTauTag/RecoTau/plugins/PFRecoTauDiscriminationAgainstElectronDeadECAL.cc +++ /dev/null @@ -1,204 +0,0 @@ - -/** \class PFRecoTauDiscriminationAgainstElectronDeadECAL - * - * Flag tau candidates reconstructed near dead ECAL channels, - * in order to reduce e -> tau fakes not rejected by anti-e MVA discriminator - * - * The motivation for this flag is this presentation: - * https://indico.cern.ch/getFile.py/access?contribId=0&resId=0&materialId=slides&confId=177223 - * - * \authors Lauri Andreas Wendland, - * Christian Veelken - * - * - * - */ - -#include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include -#include - -#include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h" -#include "CondFormats/EcalObjects/interface/EcalChannelStatus.h" -#include "Geometry/Records/interface/CaloGeometryRecord.h" -#include "Geometry/CaloGeometry/interface/CaloGeometry.h" -#include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h" -#include "Geometry/Records/interface/IdealGeometryRecord.h" -#include "DataFormats/DetId/interface/DetId.h" -#include "DataFormats/EcalDetId/interface/EBDetId.h" -#include "DataFormats/EcalDetId/interface/EEDetId.h" -#include "DataFormats/Math/interface/deltaR.h" -#include "DataFormats/TauReco/interface/PFTauDiscriminator.h" - -#include - -using namespace reco; - -class PFRecoTauDiscriminationAgainstElectronDeadECAL : public PFTauDiscriminationProducerBase { -public: - explicit PFRecoTauDiscriminationAgainstElectronDeadECAL(const edm::ParameterSet& cfg) - : PFTauDiscriminationProducerBase(cfg), - moduleLabel_(cfg.getParameter("@module_label")), - isFirstEvent_(true) { - minStatus_ = cfg.getParameter("minStatus"); - dR_ = cfg.getParameter("dR"); - - verbosity_ = cfg.getParameter("verbosity"); - } - ~PFRecoTauDiscriminationAgainstElectronDeadECAL() override {} - - void beginEvent(const edm::Event& evt, const edm::EventSetup& es) override { updateBadTowers(es); } - - double discriminate(const PFTauRef& pfTau) const override { - if (verbosity_) { - edm::LogPrint("PFTauAgainstEleDeadECAL") << ":"; - edm::LogPrint("PFTauAgainstEleDeadECAL") << " moduleLabel = " << moduleLabel_; - edm::LogPrint("PFTauAgainstEleDeadECAL") << "#badTowers = " << badTowers_.size(); - edm::LogPrint("PFTauAgainstEleDeadECAL") - << "tau: Pt = " << pfTau->pt() << ", eta = " << pfTau->eta() << ", phi = " << pfTau->phi(); - } - double discriminator = 1.; - for (std::vector::const_iterator badTower = badTowers_.begin(); badTower != badTowers_.end(); - ++badTower) { - if (deltaR(badTower->eta_, badTower->phi_, pfTau->eta(), pfTau->phi()) < dR_) { - if (verbosity_) { - edm::LogPrint("PFTauAgainstEleDeadECAL") - << " matches badTower: eta = " << badTower->eta_ << ", phi = " << badTower->phi_; - } - discriminator = 0.; - } - } - if (verbosity_) { - edm::LogPrint("PFTauAgainstEleDeadECAL") << "--> discriminator = " << discriminator; - } - return discriminator; - } - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - -private: - void updateBadTowers(const edm::EventSetup& es) { - // NOTE: modified version of SUSY CAF code - // UserCode/SusyCAF/plugins/SusyCAF_EcalDeadChannels.cc - const uint32_t channelStatusId = es.get().cacheIdentifier(); - const uint32_t caloGeometryId = es.get().cacheIdentifier(); - const uint32_t idealGeometryId = es.get().cacheIdentifier(); - - if (!isFirstEvent_ && channelStatusId == channelStatusId_cache_ && caloGeometryId == caloGeometryId_cache_ && - idealGeometryId == idealGeometryId_cache_) - return; - - edm::ESHandle channelStatus; - es.get().get(channelStatus); - channelStatusId_cache_ = channelStatusId; - - edm::ESHandle caloGeometry; - es.get().get(caloGeometry); - caloGeometryId_cache_ = caloGeometryId; - - edm::ESHandle ttMap; - es.get().get(ttMap); - idealGeometryId_cache_ = idealGeometryId; - - std::map nBadCrystals, maxStatus; - std::map sumEta, sumPhi; - - loopXtals( - nBadCrystals, maxStatus, sumEta, sumPhi, channelStatus.product(), caloGeometry.product(), ttMap.product()); - loopXtals( - nBadCrystals, maxStatus, sumEta, sumPhi, channelStatus.product(), caloGeometry.product(), ttMap.product()); - - badTowers_.clear(); - for (std::map::const_iterator it = nBadCrystals.begin(); it != nBadCrystals.end(); ++it) { - uint32_t key = it->first; - badTowers_.push_back( - towerInfo(key, it->second, maxStatus[key], sumEta[key] / it->second, sumPhi[key] / it->second)); - } - - isFirstEvent_ = false; - } - - template - void loopXtals(std::map& nBadCrystals, - std::map& maxStatus, - std::map& sumEta, - std::map& sumPhi, - const EcalChannelStatus* channelStatus, - const CaloGeometry* caloGeometry, - const EcalTrigTowerConstituentsMap* ttMap) const { - // NOTE: modified version of SUSY CAF code - // UserCode/SusyCAF/plugins/SusyCAF_EcalDeadChannels.cc - for (int i = 0; i < Id::kSizeForDenseIndexing; ++i) { - Id id = Id::unhashIndex(i); - if (id == Id(0)) - continue; - EcalChannelStatusMap::const_iterator it = channelStatus->getMap().find(id.rawId()); - unsigned status = (it == channelStatus->end()) ? 0 : (it->getStatusCode() & statusMask_); - if (status >= minStatus_) { - const GlobalPoint& point = caloGeometry->getPosition(id); - uint32_t key = ttMap->towerOf(id); - maxStatus[key] = TMath::Max(status, maxStatus[key]); - ++nBadCrystals[key]; - sumEta[key] += point.eta(); - sumPhi[key] += point.phi(); - } - } - } - - struct towerInfo { - towerInfo(uint32_t id, unsigned nBad, unsigned maxStatus, double eta, double phi) - : id_(id), nBad_(nBad), maxStatus_(maxStatus), eta_(eta), phi_(phi) {} - uint32_t id_; - unsigned nBad_; - unsigned maxStatus_; - double eta_; - double phi_; - }; - typedef ROOT::Math::LorentzVector > PolarLorentzVector; - - std::string moduleLabel_; - unsigned minStatus_; - double dR_; - - std::vector badTowers_; - static const uint16_t statusMask_ = 0x1F; - - uint32_t channelStatusId_cache_; - uint32_t caloGeometryId_cache_; - uint32_t idealGeometryId_cache_; - bool isFirstEvent_; - - int verbosity_; -}; - -void PFRecoTauDiscriminationAgainstElectronDeadECAL::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - // pfRecoTauDiscriminationAgainstElectronDeadECAL - edm::ParameterSetDescription desc; - desc.add("verbosity", 0); - { - edm::ParameterSetDescription pset_Prediscriminants; - pset_Prediscriminants.add("BooleanOperator", "and"); - { - edm::ParameterSetDescription psd1; - psd1.add("cut"); - psd1.add("Producer"); - pset_Prediscriminants.addOptional("leadTrack", psd1); - } - { - // encountered this at - // RecoTauTag/Configuration/python/HPSPFTaus_cff.py - edm::ParameterSetDescription psd1; - psd1.add("cut"); - psd1.add("Producer"); - pset_Prediscriminants.addOptional("decayMode", psd1); - } - desc.add("Prediscriminants", pset_Prediscriminants); - } - desc.add("dR", 0.08); - desc.add("PFTauProducer", edm::InputTag("pfTauProducer")); - desc.add("minStatus", 12); - descriptions.add("pfRecoTauDiscriminationAgainstElectronDeadECAL", desc); -} - -DEFINE_FWK_MODULE(PFRecoTauDiscriminationAgainstElectronDeadECAL); diff --git a/RecoTauTag/RecoTau/plugins/TauDiscriminationAgainstElectronDeadECAL.cc b/RecoTauTag/RecoTau/plugins/TauDiscriminationAgainstElectronDeadECAL.cc new file mode 100644 index 0000000000000..578a232bb1d67 --- /dev/null +++ b/RecoTauTag/RecoTau/plugins/TauDiscriminationAgainstElectronDeadECAL.cc @@ -0,0 +1,87 @@ +/** \class TauDiscriminationAgainstElectronDeadECAL + * + * Template class for producing PFTau and PATTau discriminators which + * flag tau candidates reconstructed near dead ECAL channels, + * in order to reduce e -> tau fakes not rejected by anti-e MVA discriminator + * + * The motivation for this flag is this presentation: + * https://indico.cern.ch/getFile.py/access?contribId=0&resId=0&materialId=slides&confId=177223 + * + * \authors Lauri Andreas Wendland, + * Christian Veelken + * + * + * + */ +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h" +#include "RecoTauTag/RecoTau/interface/AntiElectronDeadECAL.h" + +template +class TauDiscriminationAgainstElectronDeadECAL : public TauDiscriminationProducerBase { +public: + typedef std::vector TauCollection; + typedef edm::Ref TauRef; + explicit TauDiscriminationAgainstElectronDeadECAL(const edm::ParameterSet& cfg) + : TauDiscriminationProducerBase::TauDiscriminationProducerBase(cfg), + moduleLabel_(cfg.getParameter("@module_label")), + verbosity_(cfg.getParameter("verbosity")), + antiElectronDeadECAL_(cfg) {} + ~TauDiscriminationAgainstElectronDeadECAL() override {} + + void beginEvent(const edm::Event& evt, const edm::EventSetup& es) override { antiElectronDeadECAL_.beginEvent(es); } + + double discriminate(const TauRef& tau) const override { + if (verbosity_) { + edm::LogPrint(this->getTauTypeString() + "AgainstEleDeadECAL") + << "<" + this->getTauTypeString() + "AgainstElectronDeadECAL::discriminate>:"; + edm::LogPrint(this->getTauTypeString() + "AgainstEleDeadECAL") << " moduleLabel = " << moduleLabel_; + edm::LogPrint(this->getTauTypeString() + "AgainstEleDeadECAL") + << " tau: Pt = " << tau->pt() << ", eta = " << tau->eta() << ", phi = " << tau->phi(); + } + double discriminator = 1.; + if (antiElectronDeadECAL_(tau.get())) { + discriminator = 0.; + } + if (verbosity_) { + edm::LogPrint(this->getTauTypeString() + "AgainstEleDeadECAL") << "--> discriminator = " << discriminator; + } + return discriminator; + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + std::string moduleLabel_; + int verbosity_; + + AntiElectronDeadECAL antiElectronDeadECAL_; +}; + +template +void TauDiscriminationAgainstElectronDeadECAL::fillDescriptions( + edm::ConfigurationDescriptions& descriptions) { + // {pfReco,pat}TauDiscriminationAgainstElectronDeadECAL + edm::ParameterSetDescription desc; + + desc.add("dR", 0.08); + desc.add("minStatus", 12); + desc.add("extrapolateToECalEntrance", true); + desc.add("verbosity", 0); + + TauDiscriminationProducerBase::fillProducerDescriptions( + desc); // inherited from the base-class + + descriptions.addWithDefaultLabel(desc); +} + +typedef TauDiscriminationAgainstElectronDeadECAL + PFRecoTauDiscriminationAgainstElectronDeadECAL; +typedef TauDiscriminationAgainstElectronDeadECAL + PATTauDiscriminationAgainstElectronDeadECAL; + +DEFINE_FWK_MODULE(PFRecoTauDiscriminationAgainstElectronDeadECAL); +DEFINE_FWK_MODULE(PATTauDiscriminationAgainstElectronDeadECAL); diff --git a/RecoTauTag/RecoTau/python/PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi.py b/RecoTauTag/RecoTau/python/PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi.py deleted file mode 100644 index f891f28f305d2..0000000000000 --- a/RecoTauTag/RecoTau/python/PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi.py +++ /dev/null @@ -1,21 +0,0 @@ -import FWCore.ParameterSet.Config as cms -from RecoTauTag.RecoTau.TauDiscriminatorTools import requireLeadTrack - -pfRecoTauDiscriminationAgainstElectronDeadECAL = cms.EDProducer( - "PFRecoTauDiscriminationAgainstElectronDeadECAL", - - # tau collection to discriminate - PFTauProducer = cms.InputTag('pfTauProducer'), - - # Require leading pion ensures that: - # 1) these is at least one track above threshold (0.5 GeV) in the signal cone - # 2) a track OR a pi-zero in the signal cone has pT > 5 GeV - Prediscriminants = requireLeadTrack, - - # status flag indicating dead/masked ECAL crystals - minStatus = cms.uint32(12), - - # region around dead/masked ECAL crystals that is to be cut - dR = cms.double(0.08), - verbosity = cms.int32(0) -) diff --git a/RecoTauTag/RecoTau/python/tools/runTauIdMVA.py b/RecoTauTag/RecoTau/python/tools/runTauIdMVA.py index b2571e18a42ba..311ad4065215c 100644 --- a/RecoTauTag/RecoTau/python/tools/runTauIdMVA.py +++ b/RecoTauTag/RecoTau/python/tools/runTauIdMVA.py @@ -1,4 +1,5 @@ from __future__ import print_function +import FWCore.ParameterSet.Config as cms from RecoTauTag.RecoTau.TauDiscriminatorTools import noPrediscriminants from RecoTauTag.RecoTau.PATTauDiscriminationByMVAIsolationRun2_cff import patDiscriminationByIsolationMVArun2v1raw, patDiscriminationByIsolationMVArun2v1 import os @@ -14,7 +15,7 @@ class TauIDEmbedder(object): "againstEle2018" ] - def __init__(self, process, cms, debug = False, + def __init__(self, process, debug = False, updatedTauName = "slimmedTausNewID", toKeep = ["deepTau2017v2p1"], tauIdDiscrMVA_trainings_run2_2017 = { 'tauIdMVAIsoDBoldDMwLT2017' : "tauIdMVAIsoDBoldDMwLT2017", }, @@ -34,7 +35,6 @@ def __init__(self, process, cms, debug = False, ): super(TauIDEmbedder, self).__init__() self.process = process - self.cms = cms self.debug = debug self.updatedTauName = updatedTauName self.process.load('RecoTauTag.Configuration.loadRecoTauTagMVAsFromPrepDB_cfi') @@ -90,8 +90,8 @@ def is_above_cmssw_version(klass, release=9, subversion=4, patch=0, debug = Fals if debug: print ("is_above_cmssw_version:", True) return True - def tauIDMVAinputs(module, wp): - return cms.PSet(inputTag = self.cms.InputTag(module), workingPointIndex = self.cms.int32(-1 if wp=="raw" else -2 if wp=="category" else getattr(self.process, module).workingPoints.index(wp))) + def tauIDMVAinputs(self, module, wp): + return cms.PSet(inputTag = cms.InputTag(module), workingPointIndex = cms.int32(-1 if wp=="raw" else -2 if wp=="category" else getattr(self.process, module).workingPoints.index(wp))) def loadMVA_WPs_run2_2017(self): if self.debug: print ("loadMVA_WPs_run2_2017: performed") @@ -99,34 +99,34 @@ def loadMVA_WPs_run2_2017(self): for training, gbrForestName in self.tauIdDiscrMVA_trainings_run2_2017.items(): self.process.loadRecoTauTagMVAsFromPrepDB.toGet.append( - self.cms.PSet( - record = self.cms.string('GBRWrapperRcd'), - tag = self.cms.string("RecoTauTag_%s%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version)), - label = self.cms.untracked.string("RecoTauTag_%s%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version)) + cms.PSet( + record = cms.string('GBRWrapperRcd'), + tag = cms.string("RecoTauTag_%s%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version)), + label = cms.untracked.string("RecoTauTag_%s%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version)) ) ) for WP in self.tauIdDiscrMVA_WPs_run2_2017[training].keys(): self.process.loadRecoTauTagMVAsFromPrepDB.toGet.append( - self.cms.PSet( - record = self.cms.string('PhysicsTGraphPayloadRcd'), - tag = self.cms.string("RecoTauTag_%s%s_WP%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version, WP)), - label = self.cms.untracked.string("RecoTauTag_%s%s_WP%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version, WP)) + cms.PSet( + record = cms.string('PhysicsTGraphPayloadRcd'), + tag = cms.string("RecoTauTag_%s%s_WP%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version, WP)), + label = cms.untracked.string("RecoTauTag_%s%s_WP%s" % (gbrForestName, self.tauIdDiscrMVA_2017_version, WP)) ) ) self.process.loadRecoTauTagMVAsFromPrepDB.toGet.append( - self.cms.PSet( - record = self.cms.string('PhysicsTFormulaPayloadRcd'), - tag = self.cms.string("RecoTauTag_%s%s_mvaOutput_normalization" % (gbrForestName, self.tauIdDiscrMVA_2017_version)), - label = self.cms.untracked.string("RecoTauTag_%s%s_mvaOutput_normalization" % (gbrForestName, self.tauIdDiscrMVA_2017_version)) + cms.PSet( + record = cms.string('PhysicsTFormulaPayloadRcd'), + tag = cms.string("RecoTauTag_%s%s_mvaOutput_normalization" % (gbrForestName, self.tauIdDiscrMVA_2017_version)), + label = cms.untracked.string("RecoTauTag_%s%s_mvaOutput_normalization" % (gbrForestName, self.tauIdDiscrMVA_2017_version)) ) ) def runTauID(self): - self.process.rerunMvaIsolationTask = self.cms.Task() - self.process.rerunMvaIsolationSequence = self.cms.Sequence() - tauIDSources = self.cms.PSet() + self.process.rerunMvaIsolationTask = cms.Task() + self.process.rerunMvaIsolationSequence = cms.Sequence() + tauIDSources = cms.PSet() # rerun the seq to obtain the 2017 nom training with 0.5 iso cone, old DM, ptph>1, trained on 2017MCv1 if "2017v1" in self.toKeep: @@ -151,25 +151,25 @@ def runTauID(self): self.loadMVA_WPs_run2_2017() self.process.rerunDiscriminationByIsolationOldDMMVArun2017v1raw = patDiscriminationByIsolationMVArun2v1raw.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - loadMVAfromDB = self.cms.bool(True), - mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v1"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs - mvaOpt = self.cms.string("DBoldDMwLTwGJ"), - verbosity = self.cms.int32(0) + loadMVAfromDB = cms.bool(True), + mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v1"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs + mvaOpt = cms.string("DBoldDMwLTwGJ"), + verbosity = cms.int32(0) ) self.process.rerunDiscriminationByIsolationOldDMMVArun2017v1 = patDiscriminationByIsolationMVArun2v1.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2017v1raw'), - loadMVAfromDB = self.cms.bool(True), - mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v1_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v1"), #writeTauIdDiscrWPs - variable = self.cms.string("pt"), + toMultiplex = cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2017v1raw'), + loadMVAfromDB = cms.bool(True), + mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v1_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v1"), #writeTauIdDiscrWPs + variable = cms.string("pt"), ) ), workingPoints = cms.vstring( @@ -183,21 +183,21 @@ def runTauID(self): ) ) - self.rerunIsolationOldDMMVArun2017v1Task = self.cms.Task( + self.rerunIsolationOldDMMVArun2017v1Task = cms.Task( self.process.rerunDiscriminationByIsolationOldDMMVArun2017v1raw, self.process.rerunDiscriminationByIsolationOldDMMVArun2017v1 ) self.process.rerunMvaIsolationTask.add(self.rerunIsolationOldDMMVArun2017v1Task) - self.process.rerunMvaIsolationSequence += self.cms.Sequence(self.rerunIsolationOldDMMVArun2017v1Task) + self.process.rerunMvaIsolationSequence += cms.Sequence(self.rerunIsolationOldDMMVArun2017v1Task) - tauIDSources.byIsolationMVArun2017v1DBoldDMwLTraw2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "raw") - tauIDSources.byVVLooseIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff95") - tauIDSources.byVLooseIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff90") - tauIDSources.byLooseIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff80") - tauIDSources.byMediumIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff70") - tauIDSources.byTightIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff60") - tauIDSources.byVTightIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff50") - tauIDSources.byVVTightIsolationMVArun2017v1DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff40") + tauIDSources.byIsolationMVArun2017v1DBoldDMwLTraw2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "raw") + tauIDSources.byVVLooseIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff95") + tauIDSources.byVLooseIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff90") + tauIDSources.byLooseIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff80") + tauIDSources.byMediumIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff70") + tauIDSources.byTightIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff60") + tauIDSources.byVTightIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff50") + tauIDSources.byVVTightIsolationMVArun2017v1DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v1", "_WPEff40") if "2017v2" in self.toKeep: @@ -222,25 +222,25 @@ def runTauID(self): self.loadMVA_WPs_run2_2017() self.process.rerunDiscriminationByIsolationOldDMMVArun2017v2raw = patDiscriminationByIsolationMVArun2v1raw.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - loadMVAfromDB = self.cms.bool(True), - mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v2"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs - mvaOpt = self.cms.string("DBoldDMwLTwGJ"), - verbosity = self.cms.int32(0) + loadMVAfromDB = cms.bool(True), + mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v2"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs + mvaOpt = cms.string("DBoldDMwLTwGJ"), + verbosity = cms.int32(0) ) self.process.rerunDiscriminationByIsolationOldDMMVArun2017v2 = patDiscriminationByIsolationMVArun2v1.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2017v2raw'), - loadMVAfromDB = self.cms.bool(True), - mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v2"), #writeTauIdDiscrWPs - variable = self.cms.string("pt"), + toMultiplex = cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2017v2raw'), + loadMVAfromDB = cms.bool(True), + mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2017v2"), #writeTauIdDiscrWPs + variable = cms.string("pt"), ) ), workingPoints = cms.vstring( @@ -252,24 +252,24 @@ def runTauID(self): "_WPEff50", "_WPEff40" ), - verbosity = self.cms.int32(0) + verbosity = cms.int32(0) ) - self.rerunIsolationOldDMMVArun2017v2Task = self.cms.Task( + self.rerunIsolationOldDMMVArun2017v2Task = cms.Task( self.process.rerunDiscriminationByIsolationOldDMMVArun2017v2raw, self.process.rerunDiscriminationByIsolationOldDMMVArun2017v2 ) self.process.rerunMvaIsolationTask.add(self.rerunIsolationOldDMMVArun2017v2Task) - self.process.rerunMvaIsolationSequence += self.cms.Sequence(self.rerunIsolationOldDMMVArun2017v2Task) + self.process.rerunMvaIsolationSequence += cms.Sequence(self.rerunIsolationOldDMMVArun2017v2Task) - tauIDSources.byIsolationMVArun2017v2DBoldDMwLTraw2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "raw") - tauIDSources.byVVLooseIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff95") - tauIDSources.byVLooseIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff90") - tauIDSources.byLooseIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff80") - tauIDSources.byMediumIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff70") - tauIDSources.byTightIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff60") - tauIDSources.byVTightIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff50") - tauIDSources.byVVTightIsolationMVArun2017v2DBoldDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff40") + tauIDSources.byIsolationMVArun2017v2DBoldDMwLTraw2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "raw") + tauIDSources.byVVLooseIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff95") + tauIDSources.byVLooseIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff90") + tauIDSources.byLooseIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff80") + tauIDSources.byMediumIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff70") + tauIDSources.byTightIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff60") + tauIDSources.byVTightIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff50") + tauIDSources.byVVTightIsolationMVArun2017v2DBoldDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2017v2", "_WPEff40") if "newDM2017v2" in self.toKeep: self.tauIdDiscrMVA_2017_version = "v2" @@ -293,25 +293,25 @@ def runTauID(self): self.loadMVA_WPs_run2_2017() self.process.rerunDiscriminationByIsolationNewDMMVArun2017v2raw = patDiscriminationByIsolationMVArun2v1raw.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - loadMVAfromDB = self.cms.bool(True), - mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2017v2"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs - mvaOpt = self.cms.string("DBnewDMwLTwGJ"), - verbosity = self.cms.int32(0) + loadMVAfromDB = cms.bool(True), + mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2017v2"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs + mvaOpt = cms.string("DBnewDMwLTwGJ"), + verbosity = cms.int32(0) ) self.process.rerunDiscriminationByIsolationNewDMMVArun2017v2 = patDiscriminationByIsolationMVArun2v1.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationNewDMMVArun2017v2raw'), - loadMVAfromDB = self.cms.bool(True), - mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2017v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2017v2"), #writeTauIdDiscrWPs - variable = self.cms.string("pt"), + toMultiplex = cms.InputTag('rerunDiscriminationByIsolationNewDMMVArun2017v2raw'), + loadMVAfromDB = cms.bool(True), + mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2017v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2017v2"), #writeTauIdDiscrWPs + variable = cms.string("pt"), ) ), workingPoints = cms.vstring( @@ -323,24 +323,24 @@ def runTauID(self): "_WPEff50", "_WPEff40" ), - verbosity = self.cms.int32(0) + verbosity = cms.int32(0) ) - self.rerunIsolationNewDMMVArun2017v2Task = self.cms.Task( + self.rerunIsolationNewDMMVArun2017v2Task = cms.Task( self.process.rerunDiscriminationByIsolationNewDMMVArun2017v2raw, self.process.rerunDiscriminationByIsolationNewDMMVArun2017v2 ) self.process.rerunMvaIsolationTask.add(self.rerunIsolationNewDMMVArun2017v2Task) - self.process.rerunMvaIsolationSequence += self.cms.Sequence(self.rerunIsolationNewDMMVArun2017v2Task) + self.process.rerunMvaIsolationSequence += cms.Sequence(self.rerunIsolationNewDMMVArun2017v2Task) - tauIDSources.byIsolationMVArun2017v2DBnewDMwLTraw2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "raw") - tauIDSources.byVVLooseIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff95") - tauIDSources.byVLooseIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff90") - tauIDSources.byLooseIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff80") - tauIDSources.byMediumIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff70") - tauIDSources.byTightIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff60") - tauIDSources.byVTightIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff50") - tauIDSources.byVVTightIsolationMVArun2017v2DBnewDMwLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff40") + tauIDSources.byIsolationMVArun2017v2DBnewDMwLTraw2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "raw") + tauIDSources.byVVLooseIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff95") + tauIDSources.byVLooseIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff90") + tauIDSources.byLooseIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff80") + tauIDSources.byMediumIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff70") + tauIDSources.byTightIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff60") + tauIDSources.byVTightIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff50") + tauIDSources.byVVTightIsolationMVArun2017v2DBnewDMwLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2017v2", "_WPEff40") if "dR0p32017v2" in self.toKeep: self.tauIdDiscrMVA_2017_version = "v2" @@ -364,29 +364,29 @@ def runTauID(self): self.loadMVA_WPs_run2_2017() self.process.rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2raw = patDiscriminationByIsolationMVArun2v1raw.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - loadMVAfromDB = self.cms.bool(True), - mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMdR0p3wLT2017v2"), - mvaOpt = self.cms.string("DBoldDMwLTwGJ"), - srcChargedIsoPtSum = self.cms.string('chargedIsoPtSumdR03'), - srcFootprintCorrection = self.cms.string('footprintCorrectiondR03'), - srcNeutralIsoPtSum = self.cms.string('neutralIsoPtSumdR03'), - srcPhotonPtSumOutsideSignalCone = self.cms.string('photonPtSumOutsideSignalConedR03'), - verbosity = self.cms.int32(0) + loadMVAfromDB = cms.bool(True), + mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMdR0p3wLT2017v2"), + mvaOpt = cms.string("DBoldDMwLTwGJ"), + srcChargedIsoPtSum = cms.string('chargedIsoPtSumdR03'), + srcFootprintCorrection = cms.string('footprintCorrectiondR03'), + srcNeutralIsoPtSum = cms.string('neutralIsoPtSumdR03'), + srcPhotonPtSumOutsideSignalCone = cms.string('photonPtSumOutsideSignalConedR03'), + verbosity = cms.int32(0) ) self.process.rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2= patDiscriminationByIsolationMVArun2v1.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2raw'), - loadMVAfromDB = self.cms.bool(True), - mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMdR0p3wLT2017v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMdR0p3wLT2017v2"), #writeTauIdDiscrWPs - variable = self.cms.string("pt"), + toMultiplex = cms.InputTag('rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2raw'), + loadMVAfromDB = cms.bool(True), + mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMdR0p3wLT2017v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMdR0p3wLT2017v2"), #writeTauIdDiscrWPs + variable = cms.string("pt"), ) ), workingPoints = cms.vstring( @@ -398,47 +398,47 @@ def runTauID(self): "_WPEff50", "_WPEff40" ), - verbosity = self.cms.int32(0) + verbosity = cms.int32(0) ) - self.rerunIsolationOldDMdR0p3MVArun2017v2Task = self.cms.Task( + self.rerunIsolationOldDMdR0p3MVArun2017v2Task = cms.Task( self.process.rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2raw, self.process.rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2 ) self.process.rerunMvaIsolationTask.add(self.rerunIsolationOldDMdR0p3MVArun2017v2Task) - self.process.rerunMvaIsolationSequence += self.cms.Sequence(self.rerunIsolationOldDMdR0p3MVArun2017v2Task) + self.process.rerunMvaIsolationSequence += cms.Sequence(self.rerunIsolationOldDMdR0p3MVArun2017v2Task) - tauIDSources.byIsolationMVArun2017v2DBoldDMdR0p3wLTraw2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "raw") - tauIDSources.byVVLooseIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff95") - tauIDSources.byVLooseIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff90") - tauIDSources.byLooseIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff80") - tauIDSources.byMediumIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff70") - tauIDSources.byTightIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff60") - tauIDSources.byVTightIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff50") - tauIDSources.byVVTightIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff40") + tauIDSources.byIsolationMVArun2017v2DBoldDMdR0p3wLTraw2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "raw") + tauIDSources.byVVLooseIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff95") + tauIDSources.byVLooseIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff90") + tauIDSources.byLooseIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff80") + tauIDSources.byMediumIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff70") + tauIDSources.byTightIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff60") + tauIDSources.byVTightIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff50") + tauIDSources.byVVTightIsolationMVArun2017v2DBoldDMdR0p3wLT2017 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMdR0p3MVArun2017v2", "_WPEff40") # 2016 training strategy(v2) - essentially the same as 2017 training strategy (v1), trained on 2016MC, old DM - currently not implemented in the tau sequence of any release # self.process.rerunDiscriminationByIsolationOldDMMVArun2v2raw = patDiscriminationByIsolationMVArun2v1raw.clone( - # PATTauProducer = self.cms.InputTag('slimmedTaus'), + # PATTauProducer = cms.InputTag('slimmedTaus'), # Prediscriminants = noPrediscriminants, - # loadMVAfromDB = self.cms.bool(True), - # mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v2"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs - # mvaOpt = self.cms.string("DBoldDMwLTwGJ"), - # verbosity = self.cms.int32(0) + # loadMVAfromDB = cms.bool(True), + # mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v2"),#RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1 writeTauIdDiscrMVAs + # mvaOpt = cms.string("DBoldDMwLTwGJ"), + # verbosity = cms.int32(0) # ) # # # self.process.rerunDiscriminationByIsolationOldDMMVArun2v2VLoose = patDiscriminationByIsolationMVArun2v1VLoose.clone( - # PATTauProducer = self.cms.InputTag('slimmedTaus'), + # PATTauProducer = cms.InputTag('slimmedTaus'), # Prediscriminants = noPrediscriminants, - # toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2v2raw'), - # key = self.cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2v2raw:category'),#? - # loadMVAfromDB = self.cms.bool(True), - # mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations - # mapping = self.cms.VPSet( - # self.cms.PSet( - # category = self.cms.uint32(0), - # cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v2_WPEff90"), #writeTauIdDiscrWPs - # variable = self.cms.string("pt"), + # toMultiplex = cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2v2raw'), + # key = cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2v2raw:category'),#? + # loadMVAfromDB = cms.bool(True), + # mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v2_mvaOutput_normalization"), #writeTauIdDiscrMVAoutputNormalizations + # mapping = cms.VPSet( + # cms.PSet( + # category = cms.uint32(0), + # cut = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v2_WPEff90"), #writeTauIdDiscrWPs + # variable = cms.string("pt"), # ) # ) # ) @@ -446,25 +446,25 @@ def runTauID(self): # 2016 training strategy(v1), trained on 2016MC, old DM if "2016v1" in self.toKeep: self.process.rerunDiscriminationByIsolationOldDMMVArun2v1raw = patDiscriminationByIsolationMVArun2v1raw.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - loadMVAfromDB = self.cms.bool(True), - mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1"), - mvaOpt = self.cms.string("DBoldDMwLT"), - verbosity = self.cms.int32(0) + loadMVAfromDB = cms.bool(True), + mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1"), + mvaOpt = cms.string("DBoldDMwLT"), + verbosity = cms.int32(0) ) self.process.rerunDiscriminationByIsolationOldDMMVArun2v1 = patDiscriminationByIsolationMVArun2v1.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2v1raw'), - loadMVAfromDB = self.cms.bool(True), - mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1_mvaOutput_normalization"), - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1"), - variable = self.cms.string("pt"), + toMultiplex = cms.InputTag('rerunDiscriminationByIsolationOldDMMVArun2v1raw'), + loadMVAfromDB = cms.bool(True), + mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1_mvaOutput_normalization"), + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string("RecoTauTag_tauIdMVAIsoDBoldDMwLT2016v1"), + variable = cms.string("pt"), ) ), workingPoints = cms.vstring( @@ -477,43 +477,43 @@ def runTauID(self): ) ) - self.rerunIsolationOldDMMVArun2016v1Task = self.cms.Task( + self.rerunIsolationOldDMMVArun2016v1Task = cms.Task( self.process.rerunDiscriminationByIsolationOldDMMVArun2v1raw, self.process.rerunDiscriminationByIsolationOldDMMVArun2v1 ) self.process.rerunMvaIsolationTask.add(self.rerunIsolationOldDMMVArun2016v1Task) - self.process.rerunMvaIsolationSequence += self.cms.Sequence(self.rerunIsolationOldDMMVArun2016v1Task) + self.process.rerunMvaIsolationSequence += cms.Sequence(self.rerunIsolationOldDMMVArun2016v1Task) - tauIDSources.byIsolationMVArun2v1DBoldDMwLTraw2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "raw") - tauIDSources.byVLooseIsolationMVArun2v1DBoldDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff90") - tauIDSources.byLooseIsolationMVArun2v1DBoldDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff80") - tauIDSources.byMediumIsolationMVArun2v1DBoldDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff70") - tauIDSources.byTightIsolationMVArun2v1DBoldDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff60") - tauIDSources.byVTightIsolationMVArun2v1DBoldDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff50") - tauIDSources.byVVTightIsolationMVArun2v1DBoldDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff40") + tauIDSources.byIsolationMVArun2v1DBoldDMwLTraw2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "raw") + tauIDSources.byVLooseIsolationMVArun2v1DBoldDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff90") + tauIDSources.byLooseIsolationMVArun2v1DBoldDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff80") + tauIDSources.byMediumIsolationMVArun2v1DBoldDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff70") + tauIDSources.byTightIsolationMVArun2v1DBoldDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff60") + tauIDSources.byVTightIsolationMVArun2v1DBoldDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff50") + tauIDSources.byVVTightIsolationMVArun2v1DBoldDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationOldDMMVArun2v1", "_WPEff40") # 2016 training strategy(v1), trained on 2016MC, new DM if "newDM2016v1" in self.toKeep: self.process.rerunDiscriminationByIsolationNewDMMVArun2v1raw = patDiscriminationByIsolationMVArun2v1raw.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - loadMVAfromDB = self.cms.bool(True), - mvaName = self.cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2016v1"), - mvaOpt = self.cms.string("DBnewDMwLT"), - verbosity = self.cms.int32(0) + loadMVAfromDB = cms.bool(True), + mvaName = cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2016v1"), + mvaOpt = cms.string("DBnewDMwLT"), + verbosity = cms.int32(0) ) self.process.rerunDiscriminationByIsolationNewDMMVArun2v1 = patDiscriminationByIsolationMVArun2v1.clone( - PATTauProducer = self.cms.InputTag('slimmedTaus'), + PATTauProducer = cms.InputTag('slimmedTaus'), Prediscriminants = noPrediscriminants, - toMultiplex = self.cms.InputTag('rerunDiscriminationByIsolationNewDMMVArun2v1raw'), - loadMVAfromDB = self.cms.bool(True), - mvaOutput_normalization = self.cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2016v1_mvaOutput_normalization"), - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2016v1_WPEff90"), - variable = self.cms.string("pt"), + toMultiplex = cms.InputTag('rerunDiscriminationByIsolationNewDMMVArun2v1raw'), + loadMVAfromDB = cms.bool(True), + mvaOutput_normalization = cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2016v1_mvaOutput_normalization"), + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string("RecoTauTag_tauIdMVAIsoDBnewDMwLT2016v1_WPEff90"), + variable = cms.string("pt"), ) ), workingPoints = cms.vstring( @@ -526,20 +526,20 @@ def runTauID(self): ) ) - self.rerunIsolationNewDMMVArun2016v1Task = self.cms.Task( + self.rerunIsolationNewDMMVArun2016v1Task = cms.Task( self.process.rerunDiscriminationByIsolationNewDMMVArun2v1raw, self.process.rerunDiscriminationByIsolationNewDMMVArun2v1 ) self.process.rerunMvaIsolationTask.add(self.rerunIsolationNewDMMVArun2016v1Task) - self.process.rerunMvaIsolationSequence += self.cms.Sequence(self.rerunIsolationNewDMMVArun2016v1Task) + self.process.rerunMvaIsolationSequence += cms.Sequence(self.rerunIsolationNewDMMVArun2016v1Task) - tauIDSources.byIsolationMVArun2v1DBnewDMwLTraw2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "raw") - tauIDSources.byVLooseIsolationMVArun2v1DBnewDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff90") - tauIDSources.byLooseIsolationMVArun2v1DBnewDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff80") - tauIDSources.byMediumIsolationMVArun2v1DBnewDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff70") - tauIDSources.byTightIsolationMVArun2v1DBnewDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff60") - tauIDSources.byVTightIsolationMVArun2v1DBnewDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff50") - tauIDSources.byVVTightIsolationMVArun2v1DBnewDMwLT2016 = tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff40") + tauIDSources.byIsolationMVArun2v1DBnewDMwLTraw2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "raw") + tauIDSources.byVLooseIsolationMVArun2v1DBnewDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff90") + tauIDSources.byLooseIsolationMVArun2v1DBnewDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff80") + tauIDSources.byMediumIsolationMVArun2v1DBnewDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff70") + tauIDSources.byTightIsolationMVArun2v1DBnewDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff60") + tauIDSources.byVTightIsolationMVArun2v1DBnewDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff50") + tauIDSources.byVVTightIsolationMVArun2v1DBnewDMwLT2016 = self.tauIDMVAinputs("rerunDiscriminationByIsolationNewDMMVArun2v1", "_WPEff40") if "deepTau2017v1" in self.toKeep: if self.debug: print ("Adding DeepTau IDs") @@ -578,18 +578,18 @@ def runTauID(self): } } file_names = ['RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v1_20L1024N_quantized.pb'] - self.process.deepTau2017v1 = self.cms.EDProducer("DeepTauId", - electrons = self.cms.InputTag('slimmedElectrons'), - muons = self.cms.InputTag('slimmedMuons'), - taus = self.cms.InputTag('slimmedTaus'), - pfcands = self.cms.InputTag('packedPFCandidates'), - vertices = self.cms.InputTag('offlineSlimmedPrimaryVertices'), - rho = self.cms.InputTag('fixedGridRhoAll'), - graph_file = self.cms.vstring(file_names), - mem_mapped = self.cms.bool(False), - version = self.cms.uint32(self.getDeepTauVersion(file_names[0])[1]), - debug_level = self.cms.int32(0), - disable_dxy_pca = self.cms.bool(False) + self.process.deepTau2017v1 = cms.EDProducer("DeepTauId", + electrons = cms.InputTag('slimmedElectrons'), + muons = cms.InputTag('slimmedMuons'), + taus = cms.InputTag('slimmedTaus'), + pfcands = cms.InputTag('packedPFCandidates'), + vertices = cms.InputTag('offlineSlimmedPrimaryVertices'), + rho = cms.InputTag('fixedGridRhoAll'), + graph_file = cms.vstring(file_names), + mem_mapped = cms.bool(False), + version = cms.uint32(self.getDeepTauVersion(file_names[0])[1]), + debug_level = cms.int32(0), + disable_dxy_pca = cms.bool(False) ) self.processDeepProducer('deepTau2017v1', tauIDSources, workingPoints_) @@ -634,18 +634,18 @@ def runTauID(self): 'inner:RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6_inner.pb', 'outer:RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6_outer.pb', ] - self.process.deepTau2017v2 = self.cms.EDProducer("DeepTauId", - electrons = self.cms.InputTag('slimmedElectrons'), - muons = self.cms.InputTag('slimmedMuons'), - taus = self.cms.InputTag('slimmedTaus'), - pfcands = self.cms.InputTag('packedPFCandidates'), - vertices = self.cms.InputTag('offlineSlimmedPrimaryVertices'), - rho = self.cms.InputTag('fixedGridRhoAll'), - graph_file = self.cms.vstring(file_names), - mem_mapped = self.cms.bool(False), - version = self.cms.uint32(self.getDeepTauVersion(file_names[0])[1]), - debug_level = self.cms.int32(0), - disable_dxy_pca = self.cms.bool(False) + self.process.deepTau2017v2 = cms.EDProducer("DeepTauId", + electrons = cms.InputTag('slimmedElectrons'), + muons = cms.InputTag('slimmedMuons'), + taus = cms.InputTag('slimmedTaus'), + pfcands = cms.InputTag('packedPFCandidates'), + vertices = cms.InputTag('offlineSlimmedPrimaryVertices'), + rho = cms.InputTag('fixedGridRhoAll'), + graph_file = cms.vstring(file_names), + mem_mapped = cms.bool(False), + version = cms.uint32(self.getDeepTauVersion(file_names[0])[1]), + debug_level = cms.int32(0), + disable_dxy_pca = cms.bool(False) ) self.processDeepProducer('deepTau2017v2', tauIDSources, workingPoints_) @@ -690,18 +690,18 @@ def runTauID(self): 'inner:RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6_inner.pb', 'outer:RecoTauTag/TrainingFiles/data/DeepTauId/deepTau_2017v2p6_e6_outer.pb', ] - self.process.deepTau2017v2p1 = self.cms.EDProducer("DeepTauId", - electrons = self.cms.InputTag('slimmedElectrons'), - muons = self.cms.InputTag('slimmedMuons'), - taus = self.cms.InputTag('slimmedTaus'), - pfcands = self.cms.InputTag('packedPFCandidates'), - vertices = self.cms.InputTag('offlineSlimmedPrimaryVertices'), - rho = self.cms.InputTag('fixedGridRhoAll'), - graph_file = self.cms.vstring(file_names), - mem_mapped = self.cms.bool(False), - version = self.cms.uint32(self.getDeepTauVersion(file_names[0])[1]), - debug_level = self.cms.int32(0), - disable_dxy_pca = self.cms.bool(True) + self.process.deepTau2017v2p1 = cms.EDProducer("DeepTauId", + electrons = cms.InputTag('slimmedElectrons'), + muons = cms.InputTag('slimmedMuons'), + taus = cms.InputTag('slimmedTaus'), + pfcands = cms.InputTag('packedPFCandidates'), + vertices = cms.InputTag('offlineSlimmedPrimaryVertices'), + rho = cms.InputTag('fixedGridRhoAll'), + graph_file = cms.vstring(file_names), + mem_mapped = cms.bool(False), + version = cms.uint32(self.getDeepTauVersion(file_names[0])[1]), + debug_level = cms.int32(0), + disable_dxy_pca = cms.bool(True) ) self.processDeepProducer('deepTau2017v2p1', tauIDSources, workingPoints_) @@ -727,13 +727,13 @@ def runTauID(self): } } file_names = [ 'RecoTauTag/TrainingFiles/data/DPFTauId/DPFIsolation_2017v0_quantized.pb' ] - self.process.dpfTau2016v0 = self.cms.EDProducer("DPFIsolation", - pfcands = self.cms.InputTag('packedPFCandidates'), - taus = self.cms.InputTag('slimmedTaus'), - vertices = self.cms.InputTag('offlineSlimmedPrimaryVertices'), - graph_file = self.cms.vstring(file_names), - version = self.cms.uint32(self.getDpfTauVersion(file_names[0])), - mem_mapped = self.cms.bool(False) + self.process.dpfTau2016v0 = cms.EDProducer("DPFIsolation", + pfcands = cms.InputTag('packedPFCandidates'), + taus = cms.InputTag('slimmedTaus'), + vertices = cms.InputTag('offlineSlimmedPrimaryVertices'), + graph_file = cms.vstring(file_names), + version = cms.uint32(self.getDpfTauVersion(file_names[0])), + mem_mapped = cms.bool(False) ) self.processDeepProducer('dpfTau2016v0', tauIDSources, workingPoints_) @@ -752,13 +752,13 @@ def runTauID(self): } file_names = [ 'RecoTauTag/TrainingFiles/data/DPFTauId/DPFIsolation_2017v1_quantized.pb' ] - self.process.dpfTau2016v1 = self.cms.EDProducer("DPFIsolation", - pfcands = self.cms.InputTag('packedPFCandidates'), - taus = self.cms.InputTag('slimmedTaus'), - vertices = self.cms.InputTag('offlineSlimmedPrimaryVertices'), - graph_file = self.cms.vstring(file_names), - version = self.cms.uint32(self.getDpfTauVersion(file_names[0])), - mem_mapped = self.cms.bool(False) + self.process.dpfTau2016v1 = cms.EDProducer("DPFIsolation", + pfcands = cms.InputTag('packedPFCandidates'), + taus = cms.InputTag('slimmedTaus'), + vertices = cms.InputTag('offlineSlimmedPrimaryVertices'), + graph_file = cms.vstring(file_names), + version = cms.uint32(self.getDpfTauVersion(file_names[0])), + mem_mapped = cms.bool(False) ) self.processDeepProducer('dpfTau2016v1', tauIDSources, workingPoints_) @@ -773,7 +773,7 @@ def runTauID(self): from RecoTauTag.RecoTau.PATTauDiscriminationAgainstElectronMVA6_cfi import patTauDiscriminationAgainstElectronMVA6 self.process.patTauDiscriminationByElectronRejectionMVA62018Raw = patTauDiscriminationAgainstElectronMVA6.clone( Prediscriminants = noPrediscriminants, #already selected for MiniAOD - vetoEcalCracks = self.cms.bool(False), #keep taus in EB-EE cracks + vetoEcalCracks = cms.bool(False), #keep taus in EB-EE cracks mvaName_NoEleMatch_wGwoGSF_BL = 'RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_wGwoGSF_BL', mvaName_NoEleMatch_wGwoGSF_EC = 'RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_wGwoGSF_EC', mvaName_NoEleMatch_woGwoGSF_BL = 'RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_woGwoGSF_BL', @@ -785,50 +785,50 @@ def runTauID(self): ) ## WPs from RecoTauTag.RecoTau.PATTauDiscriminantCutMultiplexer_cfi import patTauDiscriminantCutMultiplexer - self.process.patTauDiscriminationByVLooseElectronRejectionMVA62018 = patTauDiscriminantCutMultiplexer.clone( + self.process.patTauDiscriminationByElectronRejectionMVA62018 = patTauDiscriminantCutMultiplexer.clone( PATTauProducer = self.process.patTauDiscriminationByElectronRejectionMVA62018Raw.PATTauProducer, Prediscriminants = self.process.patTauDiscriminationByElectronRejectionMVA62018Raw.Prediscriminants, - toMultiplex = self.cms.InputTag("patTauDiscriminationByElectronRejectionMVA62018Raw"), - mapping = self.cms.VPSet( - self.cms.PSet( - category = self.cms.uint32(0), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_woGwoGSF_BL'), - variable = self.cms.string('pt') + toMultiplex = cms.InputTag("patTauDiscriminationByElectronRejectionMVA62018Raw"), + mapping = cms.VPSet( + cms.PSet( + category = cms.uint32(0), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_woGwoGSF_BL'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(2), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_wGwoGSF_BL'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(2), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_wGwoGSF_BL'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(5), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_woGwGSF_BL'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(5), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_woGwGSF_BL'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(7), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_wGwGSF_BL'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(7), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_wGwGSF_BL'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(8), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_woGwoGSF_EC'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(8), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_woGwoGSF_EC'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(10), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_wGwoGSF_EC'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(10), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_NoEleMatch_wGwoGSF_EC'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(13), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_woGwGSF_EC'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(13), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_woGwGSF_EC'), + variable = cms.string('pt') ), - self.cms.PSet( - category = self.cms.uint32(15), - cut = self.cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_wGwGSF_EC'), - variable = self.cms.string('pt') + cms.PSet( + category = cms.uint32(15), + cut = cms.string('RecoTauTag_antiElectron'+antiElectronDiscrMVA6_version+'_gbr_wGwGSF_EC'), + variable = cms.string('pt') ) ), workingPoints = cms.vstring( @@ -840,24 +840,24 @@ def runTauID(self): ) ) ### Put all new anti-e discrminats to a sequence - self.process.patTauDiscriminationByElectronRejectionMVA62018Task = self.cms.Task( + self.process.patTauDiscriminationByElectronRejectionMVA62018Task = cms.Task( self.process.patTauDiscriminationByElectronRejectionMVA62018Raw, self.process.patTauDiscriminationByElectronRejectionMVA62018 ) - self.process.patTauDiscriminationByElectronRejectionMVA62018Seq = self.cms.Sequence(self.process.patTauDiscriminationByElectronRejectionMVA62018Task) + self.process.patTauDiscriminationByElectronRejectionMVA62018Seq = cms.Sequence(self.process.patTauDiscriminationByElectronRejectionMVA62018Task) self.process.rerunMvaIsolationTask.add(self.process.patTauDiscriminationByElectronRejectionMVA62018Task) self.process.rerunMvaIsolationSequence += self.process.patTauDiscriminationByElectronRejectionMVA62018Seq - _againstElectronTauIDSources = self.cms.PSet( - againstElectronMVA6Raw2018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "raw"), - againstElectronMVA6category2018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "category"), - againstElectronVLooseMVA62018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff98"), - againstElectronLooseMVA62018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff90"), - againstElectronMediumMVA62018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff80"), - againstElectronTightMVA62018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff70"), - againstElectronVTightMVA62018 = tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff60") + _againstElectronTauIDSources = cms.PSet( + againstElectronMVA6Raw2018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "raw"), + againstElectronMVA6category2018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "category"), + againstElectronVLooseMVA62018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff98"), + againstElectronLooseMVA62018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff90"), + againstElectronMediumMVA62018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff80"), + againstElectronTightMVA62018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff70"), + againstElectronVTightMVA62018 = self.tauIDMVAinputs("patTauDiscriminationByElectronRejectionMVA62018", "_WPeff60") ) - _tauIDSourcesWithAgainistEle = self.cms.PSet( + _tauIDSourcesWithAgainistEle = cms.PSet( tauIDSources.clone(), _againstElectronTauIDSources ) @@ -866,13 +866,13 @@ def runTauID(self): ## if self.debug: print('Embedding new TauIDs into \"'+self.updatedTauName+'\"') if not hasattr(self.process, self.updatedTauName): - embedID = self.cms.EDProducer("PATTauIDEmbedder", - src = self.cms.InputTag('slimmedTaus'), + embedID = cms.EDProducer("PATTauIDEmbedder", + src = cms.InputTag('slimmedTaus'), tauIDSources = tauIDSources ) setattr(self.process, self.updatedTauName, embedID) else: #assume same type - tauIDSources = self.cms.PSet( + tauIDSources = cms.PSet( getattr(self.process, self.updatedTauName).tauIDSources, tauIDSources) getattr(self.process, self.updatedTauName).tauIDSources = tauIDSources @@ -881,16 +881,16 @@ def runTauID(self): def processDeepProducer(self, producer_name, tauIDSources, workingPoints_): for target,points in six.iteritems(workingPoints_): setattr(tauIDSources, 'by{}VS{}raw'.format(producer_name[0].upper()+producer_name[1:], target), - self.cms.PSet(inputTag = self.cms.InputTag(producer_name, 'VS{}'.format(target)), workingPointIndex = self.cms.int32(-1))) + cms.PSet(inputTag = cms.InputTag(producer_name, 'VS{}'.format(target)), workingPointIndex = cms.int32(-1))) cut_expressions = [] for index, (point,cut) in enumerate(six.iteritems(points)): cut_expressions.append(str(cut)) setattr(tauIDSources, 'by{}{}VS{}'.format(point, producer_name[0].upper()+producer_name[1:], target), - self.cms.PSet(inputTag = self.cms.InputTag(producer_name, 'VS{}'.format(target)), workingPointIndex = self.cms.int32(index))) + cms.PSet(inputTag = cms.InputTag(producer_name, 'VS{}'.format(target)), workingPointIndex = cms.int32(index))) - setattr(getattr(self.process, producer_name), 'VS{}WP'.format(target), self.cms.vstring(*cut_expressions)) + setattr(getattr(self.process, producer_name), 'VS{}WP'.format(target), cms.vstring(*cut_expressions)) def getDpfTauVersion(self, file_name): diff --git a/RecoTauTag/RecoTau/src/AntiElectronDeadECAL.cc b/RecoTauTag/RecoTau/src/AntiElectronDeadECAL.cc new file mode 100644 index 0000000000000..080c333fcf01b --- /dev/null +++ b/RecoTauTag/RecoTau/src/AntiElectronDeadECAL.cc @@ -0,0 +1,159 @@ +#include "RecoTauTag/RecoTau/interface/AntiElectronDeadECAL.h" + +#include "FWCore/Framework/interface/ESHandle.h" +#include "CondFormats/DataRecord/interface/EcalChannelStatusRcd.h" +#include "CondFormats/EcalObjects/interface/EcalChannelStatus.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h" +#include "Geometry/Records/interface/IdealGeometryRecord.h" +#include "DataFormats/TauReco/interface/PFTau.h" +#include "DataFormats/PatCandidates/interface/Tau.h" +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/EcalDetId/interface/EBDetId.h" +#include "DataFormats/EcalDetId/interface/EEDetId.h" +#include "DataFormats/Math/interface/deltaR.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +AntiElectronDeadECAL::AntiElectronDeadECAL(const edm::ParameterSet& cfg) + : minStatus_(cfg.getParameter("minStatus")), + dR2_(std::pow(cfg.getParameter("dR"), 2)), + extrapolateToECalEntrance_(cfg.getParameter("extrapolateToECalEntrance")), + verbosity_(cfg.getParameter("verbosity")), + isFirstEvent_(true) {} + +AntiElectronDeadECAL::~AntiElectronDeadECAL() {} + +void AntiElectronDeadECAL::beginEvent(const edm::EventSetup& es) { + updateBadTowers(es); + positionAtECalEntrance_.beginEvent(es); +} + +namespace { + template + void loopXtals(std::map& nBadCrystals, + std::map& maxStatus, + std::map& sumEta, + std::map& sumPhi, + const EcalChannelStatus* channelStatus, + const CaloGeometry* caloGeometry, + const EcalTrigTowerConstituentsMap* ttMap, + unsigned minStatus, + const uint16_t statusMask) { + // NOTE: modified version of SUSY CAF code + // UserCode/SusyCAF/plugins/SusyCAF_EcalDeadChannels.cc + for (int i = 0; i < Id::kSizeForDenseIndexing; ++i) { + Id id = Id::unhashIndex(i); + if (id == Id(0)) + continue; + EcalChannelStatusMap::const_iterator it = channelStatus->getMap().find(id.rawId()); + unsigned status = (it == channelStatus->end()) ? 0 : (it->getStatusCode() & statusMask); + if (status >= minStatus) { + const GlobalPoint& point = caloGeometry->getPosition(id); + uint32_t key = ttMap->towerOf(id); + maxStatus[key] = std::max(status, maxStatus[key]); + ++nBadCrystals[key]; + sumEta[key] += point.eta(); + sumPhi[key] += point.phi(); + } + } + } +} // namespace + +void AntiElectronDeadECAL::updateBadTowers(const edm::EventSetup& es) { + // NOTE: modified version of SUSY CAF code + // UserCode/SusyCAF/plugins/SusyCAF_EcalDeadChannels.cc + + if (!isFirstEvent_ && !channelStatusWatcher_.check(es) && !caloGeometryWatcher_.check(es) && + !idealGeometryWatcher_.check(es)) + return; + + edm::ESHandle channelStatus; + es.get().get(channelStatus); + + edm::ESHandle caloGeometry; + es.get().get(caloGeometry); + + edm::ESHandle ttMap; + es.get().get(ttMap); + + std::map nBadCrystals, maxStatus; + std::map sumEta, sumPhi; + + loopXtals(nBadCrystals, + maxStatus, + sumEta, + sumPhi, + channelStatus.product(), + caloGeometry.product(), + ttMap.product(), + minStatus_, + statusMask_); + loopXtals(nBadCrystals, + maxStatus, + sumEta, + sumPhi, + channelStatus.product(), + caloGeometry.product(), + ttMap.product(), + minStatus_, + statusMask_); + + badTowers_.clear(); + for (auto it : nBadCrystals) { + uint32_t key = it.first; + badTowers_.push_back(TowerInfo(key, it.second, maxStatus[key], sumEta[key] / it.second, sumPhi[key] / it.second)); + } + + isFirstEvent_ = false; +} + +bool AntiElectronDeadECAL::operator()(const reco::Candidate* tau) const { + bool isNearBadTower = false; + double tau_eta = tau->eta(); + double tau_phi = tau->phi(); + const reco::Candidate* leadChargedHadron = nullptr; + if (extrapolateToECalEntrance_) { + const reco::PFTau* pfTau = dynamic_cast(tau); + if (pfTau != nullptr) { + leadChargedHadron = pfTau->leadChargedHadrCand().isNonnull() ? pfTau->leadChargedHadrCand().get() : nullptr; + } else { + const pat::Tau* patTau = dynamic_cast(tau); + if (patTau != nullptr) { + leadChargedHadron = patTau->leadChargedHadrCand().isNonnull() ? patTau->leadChargedHadrCand().get() : nullptr; + } + } + } + if (leadChargedHadron != nullptr) { + bool success = false; + reco::Candidate::Point positionAtECalEntrance = positionAtECalEntrance_(leadChargedHadron, success); + if (success) { + tau_eta = positionAtECalEntrance.eta(); + tau_phi = positionAtECalEntrance.phi(); + } + } + if (verbosity_) { + edm::LogPrint("TauAgainstEleDeadECAL") << ":"; + edm::LogPrint("TauAgainstEleDeadECAL") << " #badTowers = " << badTowers_.size(); + if (leadChargedHadron != nullptr) { + edm::LogPrint("TauAgainstEleDeadECAL") + << " leadChargedHadron (" << leadChargedHadron->pdgId() << "): Pt = " << leadChargedHadron->pt() + << ", eta at ECAL (vtx) = " << tau_eta << " (" << leadChargedHadron->eta() << ")" + << ", phi at ECAL (vtx) = " << tau_phi << " (" << leadChargedHadron->phi() << ")"; + } else { + edm::LogPrint("TauAgainstEleDeadECAL") + << " tau: Pt = " << tau->pt() << ", eta at vtx = " << tau_eta << ", phi at vtx = " << tau_phi; + } + } + for (auto const& badTower : badTowers_) { + if (deltaR2(badTower.eta_, badTower.phi_, tau_eta, tau_phi) < dR2_) { + if (verbosity_) { + edm::LogPrint("TauAgainstEleDeadECAL") + << " matches badTower: eta = " << badTower.eta_ << ", phi = " << badTower.phi_; + } + isNearBadTower = true; + break; + } + } + return isNearBadTower; +} diff --git a/RecoTauTag/RecoTau/src/AntiElectronIDMVA6.cc b/RecoTauTag/RecoTau/src/AntiElectronIDMVA6.cc index c66ea912ccd94..547dc14e07090 100644 --- a/RecoTauTag/RecoTau/src/AntiElectronIDMVA6.cc +++ b/RecoTauTag/RecoTau/src/AntiElectronIDMVA6.cc @@ -11,9 +11,6 @@ #include "CondFormats/DataRecord/interface/GBRWrapperRcd.h" #include "FWCore/Framework/interface/ESHandle.h" -#include "MagneticField/Engine/interface/MagneticField.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" - #include #include #include @@ -57,7 +54,6 @@ AntiElectronIDMVA6::AntiElectronIDMVA6(const edm::ParameterSet& cfg) Var_woGwGSF_Endcap_ = new Float_t[23]; Var_wGwGSF_Endcap_ = new Float_t[31]; - bField_ = 0; verbosity_ = 0; } @@ -134,10 +130,7 @@ void AntiElectronIDMVA6::beginEvent(const edm::Event& evt, const edm::EventSetup } isInitialized_ = true; } - - edm::ESHandle pSetup; - es.get().get(pSetup); - bField_ = pSetup->inTesla(GlobalPoint(0, 0, 0)).z(); + positionAtECalEntrance_.beginEvent(es); } double AntiElectronIDMVA6::MVAValue(Float_t TauPt, @@ -624,9 +617,11 @@ double AntiElectronIDMVA6::MVAValue(const reco::PFTau& thePFTau, const reco::Gsf for (const auto& signalPFCand : signalPFCands) { reco::Candidate const* signalCand = signalPFCand.get(); float phi = thePFTau.phi(); - math::XYZPoint aPos; - if (atECalEntrance(signalCand, aPos)) + bool success = false; + reco::Candidate::Point aPos = positionAtECalEntrance_(signalCand, success); + if (success) { phi = aPos.Phi(); + } sumPhiTimesEnergy += phi * signalCand->energy(); sumEnergy += signalCand->energy(); } @@ -839,9 +834,11 @@ double AntiElectronIDMVA6::MVAValue(const reco::PFTau& thePFTau) { for (const auto& signalPFCand : signalPFCands) { reco::Candidate const* signalCand = signalPFCand.get(); float phi = thePFTau.phi(); - math::XYZPoint aPos; - if (atECalEntrance(signalCand, aPos) == true) + bool success = false; + reco::Candidate::Point aPos = positionAtECalEntrance_(signalCand, success); + if (success) { phi = aPos.Phi(); + } sumPhiTimesEnergy += phi * signalCand->energy(); sumEnergy += signalCand->energy(); } @@ -981,9 +978,11 @@ double AntiElectronIDMVA6::MVAValue(const pat::Tau& theTau, const pat::Electron& for (const auto& signalCandPtr : signalCands) { reco::Candidate const* signalCand = signalCandPtr.get(); float phi = theTau.phi(); - math::XYZPoint aPos; - if (atECalEntrance(signalCand, aPos) == true) + bool success = false; + reco::Candidate::Point aPos = positionAtECalEntrance_(signalCand, success); + if (success) { phi = aPos.Phi(); + } sumPhiTimesEnergy += phi * signalCand->energy(); sumEnergy += signalCand->energy(); } @@ -1172,9 +1171,11 @@ double AntiElectronIDMVA6::MVAValue(const pat::Tau& theTau) { for (const auto& signalCandPtr : signalCands) { reco::Candidate const* signalCand = signalCandPtr.get(); float phi = theTau.phi(); - math::XYZPoint aPos; - if (atECalEntrance(signalCand, aPos) == true) + bool success = false; + reco::Candidate::Point aPos = positionAtECalEntrance_(signalCand, success); + if (success) { phi = aPos.Phi(); + } sumPhiTimesEnergy += phi * signalCand->energy(); sumEnergy += signalCand->energy(); } @@ -1329,22 +1330,3 @@ double AntiElectronIDMVA6::dCrackEta(double eta) { return std::abs(retVal); } - -bool AntiElectronIDMVA6::atECalEntrance(const reco::Candidate* part, math::XYZPoint& pos) { - bool result = false; - BaseParticlePropagator theParticle = BaseParticlePropagator( - RawParticle(math::XYZTLorentzVector(part->px(), part->py(), part->pz(), part->energy()), - math::XYZTLorentzVector(part->vertex().x(), part->vertex().y(), part->vertex().z(), 0.), - part->charge()), - 0., - 0., - bField_); - theParticle.propagateToEcalEntrance(false); - if (theParticle.getSuccess() != 0) { - pos = math::XYZPoint(theParticle.particle().vertex()); - result = true; - } else { - result = false; - } - return result; -} diff --git a/RecoTauTag/RecoTau/src/PositionAtECalEntranceComputer.cc b/RecoTauTag/RecoTau/src/PositionAtECalEntranceComputer.cc new file mode 100644 index 0000000000000..aedab0dab18fb --- /dev/null +++ b/RecoTauTag/RecoTau/src/PositionAtECalEntranceComputer.cc @@ -0,0 +1,37 @@ +#include "RecoTauTag/RecoTau/interface/PositionAtECalEntranceComputer.h" + +#include "MagneticField/Engine/interface/MagneticField.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "CommonTools/BaseParticlePropagator/interface/BaseParticlePropagator.h" + +#include + +PositionAtECalEntranceComputer::PositionAtECalEntranceComputer() : bField_z_(-1.) {} + +PositionAtECalEntranceComputer::~PositionAtECalEntranceComputer() {} + +void PositionAtECalEntranceComputer::beginEvent(const edm::EventSetup& es) { + edm::ESHandle bField; + es.get().get(bField); + bField_z_ = bField->inTesla(GlobalPoint(0., 0., 0.)).z(); +} + +reco::Candidate::Point PositionAtECalEntranceComputer::operator()(const reco::Candidate* particle, bool& success) const { + assert(bField_z_ != -1.); + BaseParticlePropagator propagator = BaseParticlePropagator( + RawParticle(particle->p4(), + math::XYZTLorentzVector(particle->vertex().x(), particle->vertex().y(), particle->vertex().z(), 0.), + particle->charge()), + 0., + 0., + bField_z_); + propagator.propagateToEcalEntrance(false); + reco::Candidate::Point position; + if (propagator.getSuccess() != 0) { + position = propagator.particle().vertex().Vect(); + success = true; + } else { + success = false; + } + return position; +} diff --git a/RecoTauTag/RecoTau/src/TauDiscriminationProducerBase.cc b/RecoTauTag/RecoTau/src/TauDiscriminationProducerBase.cc index c114f0680f0d0..50d25e568e6cd 100644 --- a/RecoTauTag/RecoTau/src/TauDiscriminationProducerBase.cc +++ b/RecoTauTag/RecoTau/src/TauDiscriminationProducerBase.cc @@ -40,7 +40,7 @@ TauDiscriminationProducerBase("@module_label")) { // tau collection to discriminate - TauProducer_ = iConfig.getParameter(getProducerString()); + TauProducer_ = iConfig.getParameter(getTauTypeString() + "Producer"); Tau_token = consumes(TauProducer_); // prediscriminant operator @@ -172,7 +172,7 @@ template :: fillProducerDescriptions(edm::ParameterSetDescription& desc) { // helper function, it fills the description of the Producers parameter - desc.add(getProducerString(), edm::InputTag("fixme")); + desc.add(getTauTypeString() + "Producer", edm::InputTag("fixme")); { edm::ParameterSetDescription pset_prediscriminants; pset_prediscriminants.add("BooleanOperator", "AND"); @@ -191,14 +191,15 @@ void TauDiscriminationProducerBase -std::string getProducerString() { - return "PFTauProducer"; -} -template <> -std::string getProducerString() { - return "PATTauProducer"; +template +std::string +TauDiscriminationProducerBase::getTauTypeString() { + if (std::is_same::value) + return "PFTau"; + if (std::is_same::value) + return "PATTau"; + throw cms::Exception("TauDiscriminationProducerBase") + << "Unsupported TauType used. You must use either PFTau or PATTau."; } // compile our desired types and make available to linker diff --git a/RecoTauTag/RecoTau/test/runDeepTauIDsOnMiniAOD.py b/RecoTauTag/RecoTau/test/runDeepTauIDsOnMiniAOD.py index b8cdfd2c46190..9a555068fea5b 100644 --- a/RecoTauTag/RecoTau/test/runDeepTauIDsOnMiniAOD.py +++ b/RecoTauTag/RecoTau/test/runDeepTauIDsOnMiniAOD.py @@ -8,7 +8,7 @@ # options.parseArguments() updatedTauName = "slimmedTausNewID" minimalOutput = True -eventsToProcess = 1 +eventsToProcess = 100 nThreads = 1 process = cms.Process('TauID') @@ -23,14 +23,14 @@ # Input source process.source = cms.Source('PoolSource', fileNames = cms.untracked.vstring( # File from dataset DY1JetsToLL_M-50_TuneCP5_13TeV-madgraphMLM-pythia8 - ' /store/mc/RunIIFall17MiniAODv2/TTToHadronic_TuneCP5_13TeV-powheg-pythia8/MINIAODSIM/PU2017_12Apr2018_94X_mc2017_realistic_v14-v1/40000/A256C80D-0943-E811-998E-7CD30AB0522C.root' + '/store/relval/CMSSW_10_5_0_pre1/RelValZTT_13/MINIAODSIM/PU25ns_103X_upgrade2018_realistic_v8-v1/20000/EA29017F-9967-3F41-BB8A-22C44A454235.root' )) process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(eventsToProcess) ) # Add new TauIDs import RecoTauTag.RecoTau.tools.runTauIdMVA as tauIdConfig -tauIdEmbedder = tauIdConfig.TauIDEmbedder(process, cms, debug = False, +tauIdEmbedder = tauIdConfig.TauIDEmbedder(process, debug = False, updatedTauName = updatedTauName, toKeep = [ "2017v2", "dR0p32017v2", "newDM2017v2", # "deepTau2017v1", diff --git a/RecoTauTag/RecoTau/test/runtests.sh b/RecoTauTag/RecoTau/test/runtests.sh index 8a0a2d274efe9..0dc7c497042eb 100755 --- a/RecoTauTag/RecoTau/test/runtests.sh +++ b/RecoTauTag/RecoTau/test/runtests.sh @@ -3,4 +3,4 @@ function die { echo $1: status $2 ; exit $2; } cmsRun ${LOCAL_TEST_DIR}/rerunTauRecoOnMiniAOD.py || die 'Failure using rerunTauRecoOnMiniAOD.py' $? - +cmsRun ${LOCAL_TEST_DIR}/runDeepTauIDsOnMiniAOD.py || die 'Failure using runDeepTauIDsOnMiniAOD.py' $? diff --git a/RecoTracker/FinalTrackSelectors/plugins/TrackSelectorByRegion.cc b/RecoTracker/FinalTrackSelectors/plugins/TrackSelectorByRegion.cc new file mode 100644 index 0000000000000..f8541fc2c8333 --- /dev/null +++ b/RecoTracker/FinalTrackSelectors/plugins/TrackSelectorByRegion.cc @@ -0,0 +1,81 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/Common/interface/OwnVector.h" +#include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h" + +#include +#include + +class TrackSelectorByRegion final : public edm::global::EDProducer<> { +public: + explicit TrackSelectorByRegion(const edm::ParameterSet& conf) + : produceCollection_(conf.getParameter("produceTrackCollection")), + produceMask_(conf.getParameter("produceMask")), + tracksToken_(consumes(conf.getParameter("tracks"))), + inputTrkRegionToken_(consumes>(conf.getParameter("regions"))), + outputTracksToken_(produceCollection_ ? produces() + : edm::EDPutTokenT{}), + outputMaskToken_(produceMask_ ? produces>() : edm::EDPutTokenT>{}) {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("tracks", edm::InputTag("hltPixelTracks")); + desc.add("regions", edm::InputTag("")); + desc.add("produceTrackCollection", true); + desc.add("produceMask", true); + descriptions.add("trackSelectorByRegion", desc); + } + +private: + using MaskCollection = std::vector; + + void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const override { + if (not produceCollection_ and not produceMask_) + return; + + auto const& regions = iEvent.get(inputTrkRegionToken_); + auto const& tracks = iEvent.get(tracksToken_); + MaskCollection mask(tracks.size(), false); // output mask + + for (auto const& region : regions) { + region.checkTracks(tracks, mask); + } + + if (produceCollection_) { + reco::TrackCollection output_tracks; // output collection with a (shallow) copy of the selected tracks + size_t size = 0; + // count the number of selected tracks + for (size_t i = 0; i < mask.size(); i++) { + size += mask[i]; + } + output_tracks.reserve(size); + for (size_t i = 0; i < mask.size(); i++) { + if (mask[i]) + output_tracks.push_back(tracks[i]); + } + iEvent.emplace(outputTracksToken_, std::move(output_tracks)); + } + if (produceMask_) { + iEvent.emplace(outputMaskToken_, std::move(mask)); + } + } + + const bool produceCollection_; + const bool produceMask_; + const edm::EDGetTokenT tracksToken_; + const edm::EDGetTokenT> inputTrkRegionToken_; + const edm::EDPutTokenT outputTracksToken_; + const edm::EDPutTokenT> outputMaskToken_; +}; + +#include "FWCore/PluginManager/interface/ModuleDef.h" +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(TrackSelectorByRegion); diff --git a/RecoTracker/SpecialSeedGenerators/interface/CosmicTrackingRegion.h b/RecoTracker/SpecialSeedGenerators/interface/CosmicTrackingRegion.h index 900860e167cca..c89070933d887 100644 --- a/RecoTracker/SpecialSeedGenerators/interface/CosmicTrackingRegion.h +++ b/RecoTracker/SpecialSeedGenerators/interface/CosmicTrackingRegion.h @@ -94,6 +94,10 @@ class CosmicTrackingRegion : public TrackingRegionBase { return nullptr; } + /// Set the elements of the mask corresponding to the tracks that are compatable with the region. + /// Does not reset the elements corresponding to the tracks that are not compatible. + void checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const override; + std::unique_ptr clone() const override { return std::make_unique(*this); } std::string name() const override { return "CosmicTrackingRegion"; } diff --git a/RecoTracker/SpecialSeedGenerators/src/CosmicTrackingRegion.cc b/RecoTracker/SpecialSeedGenerators/src/CosmicTrackingRegion.cc index f3cbdc642166c..dd80119ce3b09 100644 --- a/RecoTracker/SpecialSeedGenerators/src/CosmicTrackingRegion.cc +++ b/RecoTracker/SpecialSeedGenerators/src/CosmicTrackingRegion.cc @@ -24,6 +24,30 @@ namespace { using namespace std; +void CosmicTrackingRegion::checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const { + const math::XYZPoint regOrigin(origin().x(), origin().y(), origin().z()); + + assert(mask.size() == tracks.size()); + int i = -1; + for (auto const& track : tracks) { + i++; + if (mask[i]) + continue; + + if (track.pt() < ptMin()) { + continue; + } + if (std::abs(track.dxy(regOrigin)) > originRBound()) { + continue; + } + if (std::abs(track.dz(regOrigin)) > originZBound()) { + continue; + } + + mask[i] = true; + } +} + TrackingRegion::Hits CosmicTrackingRegion::hits(const edm::EventSetup& es, const SeedingLayerSetsHits::SeedingLayer& layer) const { TrackingRegion::Hits result; diff --git a/RecoTracker/TkSeedGenerator/BuildFile.xml b/RecoTracker/TkSeedGenerator/BuildFile.xml index 514c12d8d35d6..8b9736b9119b0 100644 --- a/RecoTracker/TkSeedGenerator/BuildFile.xml +++ b/RecoTracker/TkSeedGenerator/BuildFile.xml @@ -8,6 +8,7 @@ + diff --git a/RecoTracker/TkSeedGenerator/plugins/SeedGeneratorFromL1TTracksEDProducer.cc b/RecoTracker/TkSeedGenerator/plugins/SeedGeneratorFromL1TTracksEDProducer.cc new file mode 100644 index 0000000000000..4bbefe783be16 --- /dev/null +++ b/RecoTracker/TkSeedGenerator/plugins/SeedGeneratorFromL1TTracksEDProducer.cc @@ -0,0 +1,203 @@ +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +#include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" + +#include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "Geometry/CommonDetUnit/interface/GeomDetType.h" +#include "Geometry/CommonDetUnit/interface/GeomDet.h" + +#include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" + +#include "TrackingTools/GeomPropagators/interface/Propagator.h" +#include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimatorBase.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include + +class dso_hidden SeedGeneratorFromL1TTracksEDProducer : public edm::global::EDProducer<> { +public: + SeedGeneratorFromL1TTracksEDProducer(const edm::ParameterSet& cfg); + ~SeedGeneratorFromL1TTracksEDProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + void findSeedsOnLayer(const GeometricSearchDet& layer, + const TrajectoryStateOnSurface& tsosAtIP, + Propagator& propagatorAlong, + const TTTrack& l1, + const MeasurementEstimator& estimator, + unsigned int& numSeedsMade, + std::unique_ptr>& out) const; + + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + +private: + const edm::EDGetTokenT>> theInputCollectionTag_; + const edm::EDGetTokenT theMeasurementTrackerTag_; + + // Minimum eta value to activate searching in the TEC + const double theMinEtaForTEC_; + + // Maximum eta value to activate searching in the TOB + const double theMaxEtaForTOB_; + + const double theErrorSFHitless_; + + const edm::ESGetToken mfToken_; + const edm::ESGetToken geomToken_; + const edm::ESGetToken estToken_; + const edm::ESGetToken propagatorAlongToken_; + const edm::ESGetToken propagatorOppositeToken_; +}; + +SeedGeneratorFromL1TTracksEDProducer::SeedGeneratorFromL1TTracksEDProducer(const edm::ParameterSet& cfg) + : theInputCollectionTag_( + consumes>>(cfg.getParameter("InputCollection"))), + theMeasurementTrackerTag_( + consumes(cfg.getParameter("MeasurementTrackerEvent"))), + theMinEtaForTEC_(cfg.getParameter("minEtaForTEC")), + theMaxEtaForTOB_(cfg.getParameter("maxEtaForTOB")), + theErrorSFHitless_(cfg.getParameter("errorSFHitless")), + mfToken_{esConsumes()}, + geomToken_{esConsumes()}, + estToken_{esConsumes( + edm::ESInputTag("", cfg.getParameter("estimator")))}, + propagatorAlongToken_{esConsumes( + edm::ESInputTag("", cfg.getParameter("propagator")))}, + propagatorOppositeToken_{esConsumes( + edm::ESInputTag("", cfg.getParameter("propagator")))} { + produces(); +} + +void SeedGeneratorFromL1TTracksEDProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("InputCollection", {"TTTracksFromTrackletEmulation", "Level1TTTracks"}); + desc.add("estimator", ""); + desc.add("propagator", ""); + desc.add("MeasurementTrackerEvent", {""}); + desc.add("minEtaForTEC", 0.9); + desc.add("maxEtaForTOB", 1.2); + desc.add("errorSFHitless", 1e-9); + descriptions.addWithDefaultLabel(desc); +} + +void SeedGeneratorFromL1TTracksEDProducer::findSeedsOnLayer(const GeometricSearchDet& layer, + const TrajectoryStateOnSurface& tsosAtIP, + Propagator& propagatorAlong, + const TTTrack& l1, + const MeasurementEstimator& estimator, + unsigned int& numSeedsMade, + std::unique_ptr>& out) const { + std::vector dets; + layer.compatibleDetsV(tsosAtIP, propagatorAlong, estimator, dets); + + if (!dets.empty()) { + auto const& detOnLayer = dets.front().first; + auto const& tsosOnLayer = dets.front().second; + if (!tsosOnLayer.isValid()) { + LogDebug("SeedGeneratorFromL1TTracks") << "Hitless TSOS is not valid!"; + } else { + dets.front().second.rescaleError(theErrorSFHitless_); + + PTrajectoryStateOnDet const& ptsod = + trajectoryStateTransform::persistentState(tsosOnLayer, detOnLayer->geographicalId().rawId()); + TrajectorySeed::recHitContainer rHC; + if (numSeedsMade < 1) { // only outermost seed + out->emplace_back(ptsod, rHC, oppositeToMomentum); + numSeedsMade++; + } + } + } +} + +void SeedGeneratorFromL1TTracksEDProducer::produce(edm::StreamID, edm::Event& ev, const edm::EventSetup& es) const { + std::unique_ptr> result(new std::vector()); + + // TTrack Collection + auto const& trks = ev.get(theInputCollectionTag_); + + // Trk Geometry + const auto& geom = es.getData(geomToken_); + + // Mag field + const auto& mag = es.getData(mfToken_); + + // Estimator + auto const& estimator = es.getData(estToken_); + + // Get Propagators + const auto& propagatorAlongH = es.getData(propagatorAlongToken_); + std::unique_ptr propagatorAlong = SetPropagationDirection(propagatorAlongH, alongMomentum); + + const auto& propagatorOppositeH = es.getData(propagatorOppositeToken_); + std::unique_ptr propagatorOpposite = SetPropagationDirection(propagatorOppositeH, oppositeToMomentum); + + // Get vector of Detector layers + auto const& measurementTracker = ev.get(theMeasurementTrackerTag_); + std::vector const& tob = measurementTracker.geometricSearchTracker()->tobLayers(); + + std::vector const& tecPositive = + geom.isThere(GeomDetEnumerators::P2OTEC) ? measurementTracker.geometricSearchTracker()->posTidLayers() + : measurementTracker.geometricSearchTracker()->posTecLayers(); + std::vector const& tecNegative = + geom.isThere(GeomDetEnumerators::P2OTEC) ? measurementTracker.geometricSearchTracker()->negTidLayers() + : measurementTracker.geometricSearchTracker()->negTecLayers(); + + /// Surface used to make a TSOS at the PCA to the beamline + Plane::PlanePointer dummyPlane = Plane::build(Plane::PositionType(), Plane::RotationType()); + + // Loop over the L1's and make seeds for all of them: + for (auto const& l1 : trks) { + std::unique_ptr> out(new std::vector()); + FreeTrajectoryState fts = trajectoryStateTransform::initialFreeStateL1TTrack(l1, &mag, true); + dummyPlane->move(fts.position() - dummyPlane->position()); + TrajectoryStateOnSurface tsosAtIP = TrajectoryStateOnSurface(fts, *dummyPlane); + + unsigned int numSeedsMade = 0; + //BARREL + if (std::abs(l1.momentum().eta()) < theMaxEtaForTOB_) { + for (auto it = tob.rbegin(); it != tob.rend(); ++it) { //This goes from outermost to innermost layer + findSeedsOnLayer(**it, tsosAtIP, *(propagatorAlong.get()), l1, estimator, numSeedsMade, out); + } + } + if (std::abs(l1.momentum().eta()) > theMinEtaForTEC_) { + numSeedsMade = 0; // reset num of seeds + } + //ENDCAP+ + if (l1.momentum().eta() > theMinEtaForTEC_) { + for (auto it = tecPositive.rbegin(); it != tecPositive.rend(); ++it) { + findSeedsOnLayer(**it, tsosAtIP, *(propagatorAlong.get()), l1, estimator, numSeedsMade, out); + } + } + //ENDCAP- + if (l1.momentum().eta() < -theMinEtaForTEC_) { + for (auto it = tecNegative.rbegin(); it != tecNegative.rend(); ++it) { + findSeedsOnLayer(**it, tsosAtIP, *(propagatorAlong.get()), l1, estimator, numSeedsMade, out); + } + } + std::copy(out->begin(), out->end(), std::back_inserter(*result)); + } // end loop over L1Tracks + + ev.put(std::move(result)); +} + +#include "FWCore/PluginManager/interface/ModuleDef.h" +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(SeedGeneratorFromL1TTracksEDProducer); diff --git a/RecoTracker/TkTrackingRegions/interface/GlobalTrackingRegion.h b/RecoTracker/TkTrackingRegions/interface/GlobalTrackingRegion.h index 69a78b67ed63d..d0f490d76af6f 100644 --- a/RecoTracker/TkTrackingRegions/interface/GlobalTrackingRegion.h +++ b/RecoTracker/TkTrackingRegions/interface/GlobalTrackingRegion.h @@ -43,6 +43,10 @@ class GlobalTrackingRegion final : public TrackingRegion { TrackingRegion::Hits hits(const edm::EventSetup& es, const SeedingLayerSetsHits::SeedingLayer& layer) const override; + /// Set the elements of the mask corresponding to the tracks that are compatable with the region. + /// Does not reset the elements corresponding to the tracks that are not compatible. + void checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const override; + std::unique_ptr checkRZ(const DetLayer* layer, const Hit& outerHit, const edm::EventSetup& iSetup, diff --git a/RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h b/RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h index 365bb566663f3..b021740ba03e8 100644 --- a/RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h +++ b/RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h @@ -175,6 +175,10 @@ class RectangularEtaPhiTrackingRegion final : public TrackingRegion { TrackingRegion::Hits hits(const edm::EventSetup& es, const SeedingLayerSetsHits::SeedingLayer& layer) const override; + /// Set the elements of the mask corresponding to the tracks that are compatable with the region. + /// Does not reset the elements corresponding to the tracks that are not compatible. + void checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const override; + std::unique_ptr checkRZ(const DetLayer* layer, const Hit& outerHit, const edm::EventSetup& iSetup, diff --git a/RecoTracker/TkTrackingRegions/interface/TrackingRegion.h b/RecoTracker/TkTrackingRegions/interface/TrackingRegion.h index ebebbe0602678..92826ea04a3f9 100644 --- a/RecoTracker/TkTrackingRegions/interface/TrackingRegion.h +++ b/RecoTracker/TkTrackingRegions/interface/TrackingRegion.h @@ -15,6 +15,8 @@ #include "RecoTracker/TkTrackingRegions/interface/HitEtaCheck.h" #include "RecoTracker/TkTrackingRegions/interface/HitRCheck.h" #include "RecoTracker/TkTrackingRegions/interface/HitZCheck.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/TrackReco/interface/TrackFwd.h" #include "FWCore/Framework/interface/EventSetup.h" #include "TrackingTools/TransientTrackingRecHit/interface/SeedingLayerSetsHits.h" @@ -96,6 +98,17 @@ class TrackingRegion { /// get hits from layer compatible with region constraints virtual Hits hits(const edm::EventSetup& es, const SeedingLayerSetsHits::SeedingLayer& layer) const = 0; + /// Set the elements of the mask corresponding to the tracks that are compatable with the region. + /// Does not reset the elements corresponding to the tracks that are not compatible. + virtual void checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const = 0; + + /// return a boolean mask over the TrackCollection reflecting the compatibility of each track with the region constraints + std::vector checkTracks(reco::TrackCollection const& tracks) const { + std::vector region_mask(tracks.size(), false); + checkTracks(tracks, region_mask); + return region_mask; + } + /// clone region with new vertex position std::unique_ptr restrictedRegion(const GlobalPoint& originPos, const float& originRBound, diff --git a/RecoTracker/TkTrackingRegions/src/GlobalTrackingRegion.cc b/RecoTracker/TkTrackingRegions/src/GlobalTrackingRegion.cc index e1947833d29bd..df262d4ee28dc 100644 --- a/RecoTracker/TkTrackingRegions/src/GlobalTrackingRegion.cc +++ b/RecoTracker/TkTrackingRegions/src/GlobalTrackingRegion.cc @@ -115,3 +115,27 @@ std::unique_ptr GlobalTrackingRegion::checkRZ(const DetLayer return std::make_unique(rzConstraint, HitRCheck::Margin(corr, corr)); } } + +void GlobalTrackingRegion::checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const { + const math::XYZPoint regOrigin(origin().x(), origin().y(), origin().z()); + + assert(mask.size() == tracks.size()); + int i = -1; + for (auto const& track : tracks) { + i++; + if (mask[i]) + continue; + + if (track.pt() < ptMin()) { + continue; + } + if (std::abs(track.dxy(regOrigin)) > originRBound()) { + continue; + } + if (std::abs(track.dz(regOrigin)) > originZBound()) { + continue; + } + + mask[i] = true; + } +} diff --git a/RecoTracker/TkTrackingRegions/src/RectangularEtaPhiTrackingRegion.cc b/RecoTracker/TkTrackingRegions/src/RectangularEtaPhiTrackingRegion.cc index 1f773abc7b04d..5edc2419154da 100644 --- a/RecoTracker/TkTrackingRegions/src/RectangularEtaPhiTrackingRegion.cc +++ b/RecoTracker/TkTrackingRegions/src/RectangularEtaPhiTrackingRegion.cc @@ -32,6 +32,7 @@ #include "DataFormats/GeometrySurface/interface/BoundPlane.h" #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h" #include "TrackingTools/KalmanUpdators/interface/EtaPhiMeasurementEstimator.h" +#include "DataFormats/Math/interface/normalizedPhi.h" #include #include @@ -47,6 +48,37 @@ namespace { using namespace PixelRecoUtilities; using namespace std; +void RectangularEtaPhiTrackingRegion::checkTracks(reco::TrackCollection const& tracks, std::vector& mask) const { + const math::XYZPoint regOrigin(origin().x(), origin().y(), origin().z()); + auto phi0 = phiDirection() + 0.5 * (phiMargin().right() - phiMargin().left()); + auto dphi = 0.5 * (phiMargin().right() + phiMargin().left()); + + assert(mask.size() == tracks.size()); + int i = -1; + for (auto const& track : tracks) { + i++; + if (mask[i]) + continue; + + if (track.pt() < ptMin()) { + continue; + } + if (!etaRange().inside(track.eta())) { + continue; + } + if (std::abs(proxim(track.phi(), phi0) - phi0) > dphi) { + continue; + } + if (std::abs(track.dxy(regOrigin)) > originRBound()) { + continue; + } + if (std::abs(track.dz(regOrigin)) > originZBound()) { + continue; + } + mask[i] = true; + } +} + RectangularEtaPhiTrackingRegion::UseMeasurementTracker RectangularEtaPhiTrackingRegion::stringToUseMeasurementTracker( const std::string& name) { std::string tmp = name; diff --git a/RecoVertex/BeamSpotProducer/plugins/BuildFile.xml b/RecoVertex/BeamSpotProducer/plugins/BuildFile.xml index 7f596993b6237..c7498da5ae33f 100644 --- a/RecoVertex/BeamSpotProducer/plugins/BuildFile.xml +++ b/RecoVertex/BeamSpotProducer/plugins/BuildFile.xml @@ -5,31 +5,39 @@ + + - + - - - - + + + + + + + + + + diff --git a/RecoVertex/BeamSpotProducer/plugins/OfflineToTransientBeamSpotESProducer.cc b/RecoVertex/BeamSpotProducer/plugins/OfflineToTransientBeamSpotESProducer.cc new file mode 100644 index 0000000000000..de297f2f52cc7 --- /dev/null +++ b/RecoVertex/BeamSpotProducer/plugins/OfflineToTransientBeamSpotESProducer.cc @@ -0,0 +1,53 @@ +#include "CondFormats/DataRecord/interface/BeamSpotObjectsRcd.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotObjects.h" +#include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/Framework/interface/ESProductHost.h" +#include "FWCore/Utilities/interface/ReusableObjectHolder.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ModuleFactory.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Utilities/interface/do_nothing_deleter.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include +#include +#include + +using namespace edm; +class OfflineToTransientBeamSpotESProducer : public edm::ESProducer { +public: + OfflineToTransientBeamSpotESProducer(const edm::ParameterSet& p); + std::shared_ptr produce(const BeamSpotTransientObjectsRcd&); + static void fillDescriptions(edm::ConfigurationDescriptions& desc); + +private: + const BeamSpotObjects dummyBS_; + edm::ESGetToken const bsToken_; + edm::ESGetToken bsOfflineToken_; +}; + +OfflineToTransientBeamSpotESProducer::OfflineToTransientBeamSpotESProducer(const edm::ParameterSet& p) { + auto cc = setWhatProduced(this); + + bsOfflineToken_ = cc.consumesFrom(); +} + +void OfflineToTransientBeamSpotESProducer::fillDescriptions(edm::ConfigurationDescriptions& desc) { + edm::ParameterSetDescription dsc; + desc.addWithDefaultLabel(dsc); +} +std::shared_ptr OfflineToTransientBeamSpotESProducer::produce( + const BeamSpotTransientObjectsRcd& iRecord) { + auto optionalRec = iRecord.tryToGetRecord(); + if (not optionalRec) { + return std::shared_ptr(&dummyBS_, edm::do_nothing_deleter()); + } + return std::shared_ptr(&optionalRec->get(bsOfflineToken_), edm::do_nothing_deleter()); +}; + +DEFINE_FWK_EVENTSETUP_MODULE(OfflineToTransientBeamSpotESProducer); diff --git a/RecoVertex/BeamSpotProducer/plugins/OnlineBeamSpotESProducer.cc b/RecoVertex/BeamSpotProducer/plugins/OnlineBeamSpotESProducer.cc new file mode 100644 index 0000000000000..b24c79e8971b2 --- /dev/null +++ b/RecoVertex/BeamSpotProducer/plugins/OnlineBeamSpotESProducer.cc @@ -0,0 +1,94 @@ +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/ModuleFactory.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/Utilities/interface/do_nothing_deleter.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "CondFormats/DataRecord/interface/BeamSpotObjectsRcd.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotOnlineObjects.h" +#include "CondFormats/DataRecord/interface/BeamSpotOnlineLegacyObjectsRcd.h" +#include "CondFormats/DataRecord/interface/BeamSpotOnlineHLTObjectsRcd.h" +#include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" + +#include "FWCore/Framework/interface/ESProductHost.h" +#include "FWCore/Utilities/interface/ReusableObjectHolder.h" +#include "FWCore/Framework/interface/ESProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include +#include +#include + +using namespace edm; + +class OnlineBeamSpotESProducer : public edm::ESProducer { +public: + OnlineBeamSpotESProducer(const edm::ParameterSet& p); + std::shared_ptr produce(const BeamSpotTransientObjectsRcd&); + static void fillDescriptions(edm::ConfigurationDescriptions& desc); + +private: + const BeamSpotOnlineObjects* compareBS(const BeamSpotOnlineObjects* bs1, const BeamSpotOnlineObjects* bs2); + BeamSpotObjects fakeBS_; + + edm::ESGetToken const bsToken_; + edm::ESGetToken bsHLTToken_; + edm::ESGetToken bsLegacyToken_; +}; +OnlineBeamSpotESProducer::OnlineBeamSpotESProducer(const edm::ParameterSet& p) { + auto cc = setWhatProduced(this); + + fakeBS_.SetBeamWidthX(0.1); + fakeBS_.SetBeamWidthY(0.1); + fakeBS_.SetSigmaZ(15.); + fakeBS_.SetPosition(0., 0., 0.); + fakeBS_.SetType(-1); + + bsHLTToken_ = cc.consumesFrom(); + bsLegacyToken_ = cc.consumesFrom(); +} + +void OnlineBeamSpotESProducer::fillDescriptions(edm::ConfigurationDescriptions& desc) { + edm::ParameterSetDescription dsc; + desc.addWithDefaultLabel(dsc); +} + +const BeamSpotOnlineObjects* OnlineBeamSpotESProducer::compareBS(const BeamSpotOnlineObjects* bs1, + const BeamSpotOnlineObjects* bs2) { + //Random logic so far ... + if (bs1->GetSigmaZ() - 0.0001 < bs2->GetSigmaZ()) { //just temporary for debugging + if (bs1->GetSigmaZ() > 5.) { + return bs1; + } else { + return bs2; + } + + } else { + if (bs2->GetSigmaZ() > 5.) { + return bs2; + } else { + return bs1; + } + } +} + +std::shared_ptr OnlineBeamSpotESProducer::produce(const BeamSpotTransientObjectsRcd& iRecord) { + auto legacyRec = iRecord.tryToGetRecord(); + auto hltRec = iRecord.tryToGetRecord(); + if (not legacyRec and not hltRec) { + return std::shared_ptr(&fakeBS_, edm::do_nothing_deleter()); + } + + const BeamSpotOnlineObjects* best; + if (legacyRec and hltRec) { + best = compareBS(&legacyRec->get(bsLegacyToken_), &hltRec->get(bsHLTToken_)); + } else if (legacyRec) { + best = &legacyRec->get(bsLegacyToken_); + } else { + best = &hltRec->get(bsHLTToken_); + } + return std::shared_ptr(best, edm::do_nothing_deleter()); +}; + +DEFINE_FWK_EVENTSETUP_MODULE(OnlineBeamSpotESProducer); diff --git a/RecoVertex/BeamSpotProducer/plugins/OnlineBeamSpotFromDB.cc b/RecoVertex/BeamSpotProducer/plugins/OnlineBeamSpotFromDB.cc new file mode 100644 index 0000000000000..f1a6349706546 --- /dev/null +++ b/RecoVertex/BeamSpotProducer/plugins/OnlineBeamSpotFromDB.cc @@ -0,0 +1,56 @@ +/**_________________________________________________________________ + class: OnlineBeamSpotFromDB.cc + package: RecoVertex/BeamSpotProducer + + + + author: Francisco Yumiceva, Fermilab (yumiceva@fnal.gov) + + +________________________________________________________________**/ + +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/IOVSyncValue.h" +#include "CondFormats/DataRecord/interface/BeamSpotTransientObjectsRcd.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotOnlineObjects.h" +#include "CondFormats/BeamSpotObjects/interface/BeamSpotObjects.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include + +class OnlineBeamSpotFromDB : public edm::one::EDAnalyzer<> { +public: + explicit OnlineBeamSpotFromDB(const edm::ParameterSet& iConfig); + static void fillDescriptions(edm::ConfigurationDescriptions& desc); + edm::ESGetToken bsToken_; + +private: + void analyze(const edm::Event&, const edm::EventSetup&) override; +}; + +OnlineBeamSpotFromDB::OnlineBeamSpotFromDB(const edm::ParameterSet& iConfig) + : bsToken_(esConsumes()) {} + +void OnlineBeamSpotFromDB::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto const& mybeamspot = iSetup.getData(bsToken_); + + edm::LogInfo("Run numver: ") << iEvent.id().run(); + edm::LogInfo("beamspot from HLT ") << mybeamspot; +} +void OnlineBeamSpotFromDB::fillDescriptions(edm::ConfigurationDescriptions& desc) { + edm::ParameterSetDescription dsc; + desc.addWithDefaultLabel(dsc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(OnlineBeamSpotFromDB); diff --git a/RecoVertex/BeamSpotProducer/test/readOnlineBeamSpotFromDB.py b/RecoVertex/BeamSpotProducer/test/readOnlineBeamSpotFromDB.py new file mode 100644 index 0000000000000..d5b0db285c24e --- /dev/null +++ b/RecoVertex/BeamSpotProducer/test/readOnlineBeamSpotFromDB.py @@ -0,0 +1,55 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("readDB") +process.load("FWCore.MessageLogger.MessageLogger_cfi") + + +process.load("CondCore.DBCommon.CondDBSetup_cfi") + + +tesOnLineESProducer = True + +if tesOnLineESProducer: + process.BeamSpotDBSource = cms.ESSource("PoolDBESSource", + process.CondDBSetup, + toGet = cms.VPSet( + cms.PSet( + record = cms.string('BeamSpotOnlineLegacyObjectsRcd'), + tag = cms.string("BeamSpotOnlineTestLegacy"), + refreshTime = cms.uint64(1) + + ), + #cms.PSet( + # record = cms.string('BeamSpotOnlineHLTObjectsRcd'), + # tag = cms.string('BSOnLineHLT_tag'), + # refreshTime = cms.uint64(1) + # ) + + ), + connect = cms.string('oracle://cms_orcon_prod/CMS_CONDITIONS') + + ) + process.BeamSpotESProducer = cms.ESProducer("OnlineBeamSpotESProducer") + +else: + from Configuration.AlCa.GlobalTag import GlobalTag as customiseGlobalTag + process.GlobalTag = customiseGlobalTag(globaltag = "auto:run3_hlt_GRun") + process.BeamSpotESProducer = cms.ESProducer("OfflineToTransientBeamSpotESProducer") + + +process.MessageLogger.destinations = cms.untracked.vstring('detailedInfo') +process.MessageLogger.detailedInfo = cms.untracked.PSet(threshold = cms.untracked.string('INFO')) + +process.source = cms.Source("EmptySource") +process.source.numberEventsInRun=cms.untracked.uint32(2) +process.source.firstRun = cms.untracked.uint32(336365) +process.source.firstLuminosityBlock = cms.untracked.uint32(13) +process.source.numberEventsInLuminosityBlock = cms.untracked.uint32(1) +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(5) + ) +process.beamspot = cms.EDAnalyzer("OnlineBeamSpotFromDB") + + +process.p = cms.Path(process.beamspot) + diff --git a/SimCalorimetry/HcalSimAlgos/src/HcalShapes.cc b/SimCalorimetry/HcalSimAlgos/src/HcalShapes.cc index 741f577605229..9558094fb80f3 100644 --- a/SimCalorimetry/HcalSimAlgos/src/HcalShapes.cc +++ b/SimCalorimetry/HcalSimAlgos/src/HcalShapes.cc @@ -20,11 +20,12 @@ HcalShapes::HcalShapes() : theDbService(nullptr) { 205 - SiPMs from Data (HE data 2017) 206 - SiPMs Hamamatsu shape (HE 2018) 207 - SiPMs from Data (HE 2017) + 208 - SiPMs from Data, 2021 MC phase scan 301 - regular HF PMT shape 401 - regular ZDC shape */ - std::vector theHcalShapeNums = {101, 102, 103, 104, 105, 123, 124, 125, 201, 202, 203, 205, 206, 207, 301}; + std::vector theHcalShapeNums = {101, 102, 103, 104, 105, 123, 124, 125, 201, 202, 203, 205, 206, 207, 208, 301}; // use resize so vector won't invalidate pointers by reallocating memory while filling theHcalShapes.resize(theHcalShapeNums.size()); for (unsigned inum = 0; inum < theHcalShapeNums.size(); ++inum) { diff --git a/SimG4Core/GeometryProducer/src/GeometryProducer.cc b/SimG4Core/GeometryProducer/src/GeometryProducer.cc index b53d056b5bd20..3c55f8e0fbbd8 100644 --- a/SimG4Core/GeometryProducer/src/GeometryProducer.cc +++ b/SimG4Core/GeometryProducer/src/GeometryProducer.cc @@ -101,7 +101,7 @@ void GeometryProducer::beginLuminosityBlock(edm::LuminosityBlock &, edm::EventSe // updateMagneticField( es ); } -void GeometryProducer::beginRun(const edm::Run &, const edm::EventSetup &) {} +void GeometryProducer::beginRun(const edm::Run &run, const edm::EventSetup &es) { updateMagneticField(es); } void GeometryProducer::endRun(const edm::Run &, const edm::EventSetup &) {} diff --git a/TrackingTools/TrajectoryState/BuildFile.xml b/TrackingTools/TrajectoryState/BuildFile.xml index 79c66c7122d1d..a6afb70dd0359 100644 --- a/TrackingTools/TrajectoryState/BuildFile.xml +++ b/TrackingTools/TrajectoryState/BuildFile.xml @@ -5,6 +5,7 @@ + diff --git a/TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h b/TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h index fd341dfb62504..6ddb0924c6660 100644 --- a/TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h +++ b/TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h @@ -3,6 +3,8 @@ #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" class TrajectoryStateOnSurface; class FreeTrajectoryState; @@ -21,6 +23,9 @@ namespace trajectoryStateTransform { /// Construct a FreeTrajectoryState from the reco::Track innermost or outermost state, /// does not require access to tracking geometry FreeTrajectoryState initialFreeState(const reco::Track& tk, const MagneticField* field, bool withErr = true); + FreeTrajectoryState initialFreeStateL1TTrack(const TTTrack& tk, + const MagneticField* field, + bool withErr = false); FreeTrajectoryState innerFreeState(const reco::Track& tk, const MagneticField* field, bool withErr = true); FreeTrajectoryState outerFreeState(const reco::Track& tk, const MagneticField* field, bool withErr = true); diff --git a/TrackingTools/TrajectoryState/src/TrajectoryStateTransform.cc b/TrackingTools/TrajectoryState/src/TrajectoryStateTransform.cc index e31eb77b46010..fe4492c88b7f4 100644 --- a/TrackingTools/TrajectoryState/src/TrajectoryStateTransform.cc +++ b/TrackingTools/TrajectoryState/src/TrajectoryStateTransform.cc @@ -67,6 +67,22 @@ namespace trajectoryStateTransform { return FreeTrajectoryState(par, err); } + FreeTrajectoryState initialFreeStateL1TTrack(const TTTrack& tk, + const MagneticField* field, + bool withErr) { + Basic3DVector pos(tk.POCA()); + GlobalPoint gpos(pos); + GlobalVector gmom = tk.momentum(); + int charge = tk.rInv() > 0.f ? 1 : -1; + + GlobalTrajectoryParameters par(gpos, gmom, charge, field); + if (!withErr) + return FreeTrajectoryState(par); + AlgebraicSymMatrix55 mat = AlgebraicMatrixID(); + mat *= 1e-8; + return FreeTrajectoryState(par, mat); + } + FreeTrajectoryState innerFreeState(const reco::Track& tk, const MagneticField* field, bool withErr) { Basic3DVector pos(tk.innerPosition()); GlobalPoint gpos(pos); diff --git a/Utilities/DavixAdaptor/test/http.cpp b/Utilities/DavixAdaptor/test/http.cpp index 2845c704951b0..62648dcdbbb16 100644 --- a/Utilities/DavixAdaptor/test/http.cpp +++ b/Utilities/DavixAdaptor/test/http.cpp @@ -8,7 +8,7 @@ int main(int, char** /*argv*/) try { IOSize n; char buf[1024]; - auto s = StorageFactory::get()->open("http://home.web.cern.ch", IOFlags::OpenRead); + auto s = StorageFactory::get()->open("http://google.com", IOFlags::OpenRead); assert(s); while ((n = s->read(buf, sizeof(buf)))) diff --git a/Validation/Configuration/python/autoValidation.py b/Validation/Configuration/python/autoValidation.py index 24e74a58bd6a4..579b4c48d110e 100644 --- a/Validation/Configuration/python/autoValidation.py +++ b/Validation/Configuration/python/autoValidation.py @@ -9,7 +9,8 @@ 'photonOnlyValidation' : ['', 'photonValidationSequence', 'photonPostProcessor'], 'tauOnlyValidation' : ['produceDenoms', 'pfTauRunDQMValidation', 'runTauEff'], 'ecalOnlyValidation' : ['globalPrevalidationECALOnly','globalValidationECALOnly','postValidation_ECAL'], - 'hcalOnlyValidation' : ['globalPrevalidationHCAL','globalValidationHCAL','postValidation_HCAL'], + 'hcalValidation' : ['globalPrevalidationHCAL','globalValidationHCAL','postValidation_HCAL'], + 'hcalOnlyValidation' : ['globalPrevalidationHCALOnly','globalValidationHCALOnly','postValidation_HCAL'], 'baseValidation' : ['baseCommonPreValidation','baseCommonValidation','postValidation_common'], 'miniAODValidation' : ['prevalidationMiniAOD','validationMiniAOD','validationHarvestingMiniAOD'], 'standardValidation' : ['prevalidation','validation','validationHarvesting'], @@ -21,7 +22,7 @@ 'TrackerPhase2Validation' : ['', 'trackerphase2ValidationSource', 'trackerphase2ValidationHarvesting'], } -_phase2_allowed = ['baseValidation','trackingValidation','muonOnlyValidation','JetMETOnlyValidation', 'electronOnlyValidation', 'photonOnlyValidation','bTagOnlyValidation', 'tauOnlyValidation', 'hcalOnlyValidation', 'HGCalValidation', 'MTDValidation', 'OuterTrackerValidation', 'ecalValidation_phase2', 'TrackerPhase2Validation'] +_phase2_allowed = ['baseValidation','trackingValidation','muonOnlyValidation','JetMETOnlyValidation', 'electronOnlyValidation', 'photonOnlyValidation','bTagOnlyValidation', 'tauOnlyValidation', 'hcalValidation', 'HGCalValidation', 'MTDValidation', 'OuterTrackerValidation', 'ecalValidation_phase2', 'TrackerPhase2Validation'] autoValidation['phase2Validation'] = ['','',''] for i in range(0,3): autoValidation['phase2Validation'][i] = '+'.join([_f for _f in [autoValidation[m][i] for m in _phase2_allowed] if _f]) diff --git a/Validation/Configuration/python/globalValidation_cff.py b/Validation/Configuration/python/globalValidation_cff.py index d46e656c8bc9d..7ac89acd5bbea 100644 --- a/Validation/Configuration/python/globalValidation_cff.py +++ b/Validation/Configuration/python/globalValidation_cff.py @@ -173,6 +173,13 @@ # HCAL local reconstruction globalPrevalidationHCAL = cms.Sequence() +globalPrevalidationHCALOnly = cms.Sequence( + baseCommonPreValidation + + globalPrevalidationHCAL +) + +hcalRecHitsOnlyValidationSequence = hcalRecHitsValidationSequence.copyAndExclude([NoiseRatesValidation]) + globalValidationHCAL = cms.Sequence( hcalSimHitsValidationSequence + hcaldigisValidationSequence @@ -181,6 +188,13 @@ + calotowersValidationSequence ) +globalValidationHCALOnly = cms.Sequence( + hcalSimHitsValidationSequence + + hcaldigisValidationSequence + + hcalSimHitStudy + + hcalRecHitsOnlyValidationSequence +) + globalValidationHGCal = cms.Sequence(hgcalValidation) globalValidationMTD = cms.Sequence() diff --git a/Validation/Geometry/test/runMaterialDumpAnalyser_PhaseII.sh b/Validation/Geometry/test/runMaterialDumpAnalyser_PhaseII.sh index 6967df60be721..cad59b8237a02 100755 --- a/Validation/Geometry/test/runMaterialDumpAnalyser_PhaseII.sh +++ b/Validation/Geometry/test/runMaterialDumpAnalyser_PhaseII.sh @@ -59,7 +59,7 @@ fi # DIGI comes next if checkFile SingleMuPt10_step2_DIGI_L1_DIGI2RAW_HLT_PhaseII.root ; then cmsDriver.py step2 \ --s DIGI:pdigi_valid,L1,L1TrackTrigger,DIGI2RAW,HLT:@fake2 \ +-s DIGI:pdigi_valid,L1TrackTrigger,L1,DIGI2RAW,HLT:@fake2 \ --conditions auto:phase2_realistic \ -n -1 \ --era Phase2C2 \ diff --git a/Validation/HGCalValidation/plugins/HGCalHitCalibration.cc b/Validation/HGCalValidation/plugins/HGCalHitCalibration.cc index bf9fb01ef0da9..2d3e08ba1fe14 100644 --- a/Validation/HGCalValidation/plugins/HGCalHitCalibration.cc +++ b/Validation/HGCalValidation/plugins/HGCalHitCalibration.cc @@ -191,7 +191,9 @@ void HGCalHitCalibration::fillWithRecHits(std::map& hit void HGCalHitCalibration::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { using namespace edm; - recHitTools_.getEventSetup(iSetup); + edm::ESHandle geom; + iSetup.get().get(geom); + recHitTools_.setGeometry(*geom); Handle recHitHandleEE; Handle recHitHandleFH; diff --git a/Validation/HGCalValidation/plugins/HGCalShowerSeparation.cc b/Validation/HGCalValidation/plugins/HGCalShowerSeparation.cc index 5cad7d1ff7abd..34b209edc99a6 100644 --- a/Validation/HGCalValidation/plugins/HGCalShowerSeparation.cc +++ b/Validation/HGCalValidation/plugins/HGCalShowerSeparation.cc @@ -166,7 +166,9 @@ void HGCalShowerSeparation::bookHistograms(DQMStore::IBooker& ibooker, void HGCalShowerSeparation::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { using namespace edm; - recHitTools_.getEventSetup(iSetup); + edm::ESHandle geom; + iSetup.get().get(geom); + recHitTools_.setGeometry(*geom); Handle recHitHandleEE; Handle recHitHandleFH; diff --git a/Validation/HGCalValidation/plugins/HGCalValidator.cc b/Validation/HGCalValidation/plugins/HGCalValidator.cc index 8752281a0996f..13cf7095454fe 100644 --- a/Validation/HGCalValidation/plugins/HGCalValidator.cc +++ b/Validation/HGCalValidation/plugins/HGCalValidator.cc @@ -177,7 +177,9 @@ void HGCalValidator::dqmAnalyze(const edm::Event& event, event.getByToken(label_cp_effic, caloParticleHandle); std::vector const& caloParticles = *caloParticleHandle; - tools_->getEventSetup(setup); + edm::ESHandle geom; + setup.get().get(geom); + tools_->setGeometry(*geom); histoProducerAlgo_->setRecHitTools(tools_); edm::Handle recHitHandleEE; diff --git a/Validation/HGCalValidation/src/HGVHistoProducerAlgo.cc b/Validation/HGCalValidation/src/HGVHistoProducerAlgo.cc index 86e1ae1aa318f..aa875dd282edd 100644 --- a/Validation/HGCalValidation/src/HGVHistoProducerAlgo.cc +++ b/Validation/HGCalValidation/src/HGVHistoProducerAlgo.cc @@ -1726,292 +1726,287 @@ void HGVHistoProducerAlgo::multiClusters_to_CaloParticles(const Histograms& hist for (unsigned int mclId = 0; mclId < nMultiClusters; ++mclId) { const auto& hits_and_fractions = multiClusters[mclId].hitsAndFractions(); - std::unordered_map CPEnergyInMCL; - int maxCPId_byNumberOfHits = -1; - unsigned int maxCPNumberOfHitsInMCL = 0; - int maxCPId_byEnergy = -1; - float maxEnergySharedMCLandCP = 0.f; - float energyFractionOfMCLinCP = 0.f; - float energyFractionOfCPinMCL = 0.f; - - //In case of matched rechit-simhit, so matched - //caloparticle-layercluster-multicluster, he counts and saves the number of - //rechits related to the maximum energy CaloParticle out of all - //CaloParticles related to that layer cluster and multicluster. - - std::unordered_map occurrencesCPinMCL; - unsigned int numberOfNoiseHitsInMCL = 0; - unsigned int numberOfHaloHitsInMCL = 0; - unsigned int numberOfHitsInMCL = 0; - - //number of hits related to that cluster. - unsigned int numberOfHitsInLC = hits_and_fractions.size(); - numberOfHitsInMCL += numberOfHitsInLC; - std::unordered_map CPEnergyInLC; - - //hitsToCaloParticleId is a vector of ints, one for each rechit of the - //layer cluster under study. If negative, there is no simhit from any CaloParticle related. - //If positive, at least one CaloParticle has been found with matched simhit. - //In more detail: - // 1. hitsToCaloParticleId[hitId] = -3 - // TN: These represent Halo Cells(N) that have not been - // assigned to any CaloParticle (hence the T). - // 2. hitsToCaloParticleId[hitId] = -2 - // FN: There represent Halo Cells(N) that have been assigned - // to a CaloParticle (hence the F, since those should have not been marked as halo) - // 3. hitsToCaloParticleId[hitId] = -1 - // FP: These represent Real Cells(P) that have not been - // assigned to any CaloParticle (hence the F, since these are fakes) - // 4. hitsToCaloParticleId[hitId] >= 0 - // TP There represent Real Cells(P) that have been assigned - // to a CaloParticle (hence the T) - - std::vector hitsToCaloParticleId(numberOfHitsInLC); - //det id of the first hit just to make the lcLayerId variable - //which maps the layers in -z: 0->51 and in +z: 52->103 - const auto firstHitDetId = hits_and_fractions[0].first; - int lcLayerId = - recHitTools_->getLayerWithOffset(firstHitDetId) + layers * ((recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1; + if (!hits_and_fractions.empty()) { + std::unordered_map CPEnergyInMCL; + int maxCPId_byNumberOfHits = -1; + unsigned int maxCPNumberOfHitsInMCL = 0; + int maxCPId_byEnergy = -1; + float maxEnergySharedMCLandCP = 0.f; + float energyFractionOfMCLinCP = 0.f; + float energyFractionOfCPinMCL = 0.f; + + //In case of matched rechit-simhit, so matched + //caloparticle-layercluster-multicluster, he counts and saves the number of + //rechits related to the maximum energy CaloParticle out of all + //CaloParticles related to that layer cluster and multicluster. + + std::unordered_map occurrencesCPinMCL; + unsigned int numberOfNoiseHitsInMCL = 0; + unsigned int numberOfHaloHitsInMCL = 0; + unsigned int numberOfHitsInMCL = 0; + + //number of hits related to that cluster. + unsigned int numberOfHitsInLC = hits_and_fractions.size(); + numberOfHitsInMCL += numberOfHitsInLC; + std::unordered_map CPEnergyInLC; + + //hitsToCaloParticleId is a vector of ints, one for each rechit of the + //layer cluster under study. If negative, there is no simhit from any CaloParticle related. + //If positive, at least one CaloParticle has been found with matched simhit. + //In more detail: + // 1. hitsToCaloParticleId[hitId] = -3 + // TN: These represent Halo Cells(N) that have not been + // assigned to any CaloParticle (hence the T). + // 2. hitsToCaloParticleId[hitId] = -2 + // FN: There represent Halo Cells(N) that have been assigned + // to a CaloParticle (hence the F, since those should have not been marked as halo) + // 3. hitsToCaloParticleId[hitId] = -1 + // FP: These represent Real Cells(P) that have not been + // assigned to any CaloParticle (hence the F, since these are fakes) + // 4. hitsToCaloParticleId[hitId] >= 0 + // TP There represent Real Cells(P) that have been assigned + // to a CaloParticle (hence the T) + + std::vector hitsToCaloParticleId(numberOfHitsInLC); + //det id of the first hit just to make the lcLayerId variable + //which maps the layers in -z: 0->51 and in +z: 52->103 + const auto firstHitDetId = hits_and_fractions[0].first; + int lcLayerId = recHitTools_->getLayerWithOffset(firstHitDetId) + + layers * ((recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1; - //Loop though the hits of the layer cluster under study - for (unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) { - DetId rh_detid = hits_and_fractions[hitId].first; - auto rhFraction = hits_and_fractions[hitId].second; + //Loop though the hits of the layer cluster under study + for (unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) { + DetId rh_detid = hits_and_fractions[hitId].first; + auto rhFraction = hits_and_fractions[hitId].second; - //Since the hit is belonging to the layer cluster, it must also be in the rechits map. - std::map::const_iterator itcheck = hitMap.find(rh_detid); - const HGCRecHit* hit = itcheck->second; + //Since the hit is belonging to the layer cluster, it must also be in the rechits map. + std::map::const_iterator itcheck = hitMap.find(rh_detid); + const HGCRecHit* hit = itcheck->second; - //Make a map that will connect a detid (that belongs to a rechit of the layer cluster under study, - //no need to save others) with: - //1. the layer clusters that have rechits in that detid - //2. the fraction of the rechit of each layer cluster that contributes to that detid. - //So, something like: - //detid: (layer cluster 1, hit fraction) , (layer cluster 2, hit fraction), (layer cluster 3, hit fraction) ... - //here comparing with the calo particle map above the - auto hit_find_in_LC = detIdToMultiClusterId_Map.find(rh_detid); - if (hit_find_in_LC == detIdToMultiClusterId_Map.end()) { - detIdToMultiClusterId_Map[rh_detid] = std::vector(); - } - detIdToMultiClusterId_Map[rh_detid].emplace_back( - HGVHistoProducerAlgo::detIdInfoInMultiCluster{mclId, mclId, rhFraction}); + //Make a map that will connect a detid (that belongs to a rechit of the layer cluster under study, + //no need to save others) with: + //1. the layer clusters that have rechits in that detid + //2. the fraction of the rechit of each layer cluster that contributes to that detid. + //So, something like: + //detid: (layer cluster 1, hit fraction) , (layer cluster 2, hit fraction), (layer cluster 3, hit fraction) ... + //here comparing with the calo particle map above the + auto hit_find_in_LC = detIdToMultiClusterId_Map.find(rh_detid); + if (hit_find_in_LC == detIdToMultiClusterId_Map.end()) { + detIdToMultiClusterId_Map[rh_detid] = std::vector(); + } + detIdToMultiClusterId_Map[rh_detid].emplace_back( + HGVHistoProducerAlgo::detIdInfoInMultiCluster{mclId, mclId, rhFraction}); - //Check whether the rechit of the layer cluster under study has a sim hit in the same cell. - auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid); + //Check whether the rechit of the layer cluster under study has a sim hit in the same cell. + auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid); - // if the fraction is zero or the hit does not belong to any calo - // particle, set the caloparticleId for the hit to -1 this will - // contribute to the number of noise hits + // if the fraction is zero or the hit does not belong to any calo + // particle, set the caloparticleId for the hit to -1 this will + // contribute to the number of noise hits - // MR Remove the case in which the fraction is 0, since this could be a - // real hit that has been marked as halo. - if (rhFraction == 0.) { - hitsToCaloParticleId[hitId] = -2; - numberOfHaloHitsInMCL++; - } - if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) { - hitsToCaloParticleId[hitId] -= 1; - } else { - auto maxCPEnergyInLC = 0.f; - auto maxCPId = -1; - for (auto& h : hit_find_in_CP->second) { - auto shared_fraction = std::min(rhFraction, h.fraction); - //We are in the case where there are calo particles with simhits connected via detid with the rechit under study - //So, from all layers clusters, find the rechits that are connected with a calo particle and save/calculate the - //energy of that calo particle as the sum over all rechits of the rechits energy weighted - //by the caloparticle's fraction related to that rechit. - CPEnergyInMCL[h.clusterId] += shared_fraction * hit->energy(); - //Same but for layer clusters for the cell association per layer - CPEnergyInLC[h.clusterId] += shared_fraction * hit->energy(); - //Here cPOnLayer[caloparticle][layer] describe above is set. - //Here for multi clusters with matched rechit the CP fraction times hit energy is added and saved . - cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[mclId].first += - shared_fraction * hit->energy(); - cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[mclId].second = FLT_MAX; - //cpsInMultiCluster[multicluster][CPids] - //Connects a multi cluster with all related caloparticles. - cpsInMultiCluster[mclId].emplace_back(std::make_pair(h.clusterId, FLT_MAX)); - //From all CaloParticles related to a layer cluster, he saves id and energy of the calo particle - //that after simhit-rechit matching in layer has the maximum energy. - if (shared_fraction > maxCPEnergyInLC) { - //energy is used only here. cpid is saved for multiclusters - maxCPEnergyInLC = CPEnergyInLC[h.clusterId]; - maxCPId = h.clusterId; + // MR Remove the case in which the fraction is 0, since this could be a + // real hit that has been marked as halo. + if (rhFraction == 0.) { + hitsToCaloParticleId[hitId] = -2; + numberOfHaloHitsInMCL++; + } + if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) { + hitsToCaloParticleId[hitId] -= 1; + } else { + auto maxCPEnergyInLC = 0.f; + auto maxCPId = -1; + for (auto& h : hit_find_in_CP->second) { + auto shared_fraction = std::min(rhFraction, h.fraction); + //We are in the case where there are calo particles with simhits connected via detid with the rechit under study + //So, from all layers clusters, find the rechits that are connected with a calo particle and save/calculate the + //energy of that calo particle as the sum over all rechits of the rechits energy weighted + //by the caloparticle's fraction related to that rechit. + CPEnergyInMCL[h.clusterId] += shared_fraction * hit->energy(); + //Same but for layer clusters for the cell association per layer + CPEnergyInLC[h.clusterId] += shared_fraction * hit->energy(); + //Here cPOnLayer[caloparticle][layer] describe above is set. + //Here for multi clusters with matched rechit the CP fraction times hit energy is added and saved . + cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[mclId].first += + shared_fraction * hit->energy(); + cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[mclId].second = FLT_MAX; + //cpsInMultiCluster[multicluster][CPids] + //Connects a multi cluster with all related caloparticles. + cpsInMultiCluster[mclId].emplace_back(h.clusterId, FLT_MAX); + //From all CaloParticles related to a layer cluster, he saves id and energy of the calo particle + //that after simhit-rechit matching in layer has the maximum energy. + if (shared_fraction > maxCPEnergyInLC) { + //energy is used only here. cpid is saved for multiclusters + maxCPEnergyInLC = CPEnergyInLC[h.clusterId]; + maxCPId = h.clusterId; + } } + //Keep in mind here maxCPId could be zero. So, below ask for negative not including zero to count noise. + hitsToCaloParticleId[hitId] = maxCPId; } - //Keep in mind here maxCPId could be zero. So, below ask for negative not including zero to count noise. - hitsToCaloParticleId[hitId] = maxCPId; - } - } //end of loop through rechits of the layer cluster. + } //end of loop through rechits of the layer cluster. - //Loop through all rechits to count how many of them are noise and how many are matched. - //In case of matched rechit-simhit, he counts and saves the number of rechits related to the maximum energy CaloParticle. - for (auto& c : hitsToCaloParticleId) { - if (c < 0) { - numberOfNoiseHitsInMCL++; - } else { - occurrencesCPinMCL[c]++; + //Loop through all rechits to count how many of them are noise and how many are matched. + //In case of matched rechit-simhit, he counts and saves the number of rechits related to the maximum energy CaloParticle. + for (auto c : hitsToCaloParticleId) { + if (c < 0) { + numberOfNoiseHitsInMCL++; + } else { + occurrencesCPinMCL[c]++; + } } - } - //Below from all maximum energy CaloParticles, he saves the one with the largest amount - //of related rechits. - for (auto& c : occurrencesCPinMCL) { - if (c.second > maxCPNumberOfHitsInMCL) { - maxCPId_byNumberOfHits = c.first; - maxCPNumberOfHitsInMCL = c.second; + //Below from all maximum energy CaloParticles, he saves the one with the largest amount + //of related rechits. + for (auto& c : occurrencesCPinMCL) { + if (c.second > maxCPNumberOfHitsInMCL) { + maxCPId_byNumberOfHits = c.first; + maxCPNumberOfHitsInMCL = c.second; + } } - } - //Find the CaloParticle that has the maximum energy shared with the multicluster under study. - for (auto& c : CPEnergyInMCL) { - if (c.second > maxEnergySharedMCLandCP) { - maxCPId_byEnergy = c.first; - maxEnergySharedMCLandCP = c.second; - } - } - //The energy of the CaloParticle that found to have the maximum energy shared with the multicluster under study. - float totalCPEnergyFromLayerCP = 0.f; - if (maxCPId_byEnergy >= 0) { - //Loop through all layers - for (unsigned int j = 0; j < layers * 2; ++j) { - totalCPEnergyFromLayerCP = totalCPEnergyFromLayerCP + cPOnLayer[maxCPId_byEnergy][j].energy; + //Find the CaloParticle that has the maximum energy shared with the multicluster under study. + for (auto& c : CPEnergyInMCL) { + if (c.second > maxEnergySharedMCLandCP) { + maxCPId_byEnergy = c.first; + maxEnergySharedMCLandCP = c.second; + } } - energyFractionOfCPinMCL = maxEnergySharedMCLandCP / totalCPEnergyFromLayerCP; - if (multiClusters[mclId].energy() > 0.f) { - energyFractionOfMCLinCP = maxEnergySharedMCLandCP / multiClusters[mclId].energy(); + //The energy of the CaloParticle that found to have the maximum energy shared with the multicluster under study. + float totalCPEnergyFromLayerCP = 0.f; + if (maxCPId_byEnergy >= 0) { + //Loop through all layers + for (unsigned int j = 0; j < layers * 2; ++j) { + totalCPEnergyFromLayerCP = totalCPEnergyFromLayerCP + cPOnLayer[maxCPId_byEnergy][j].energy; + } + energyFractionOfCPinMCL = maxEnergySharedMCLandCP / totalCPEnergyFromLayerCP; + if (multiClusters[mclId].energy() > 0.f) { + energyFractionOfMCLinCP = maxEnergySharedMCLandCP / multiClusters[mclId].energy(); + } } - } - LogDebug("HGCalValidator") << std::setw(12) << "multiCluster" - << "\t" //LogDebug("HGCalValidator") - << std::setw(10) << "mulcl energy" - << "\t" << std::setw(5) << "nhits" - << "\t" << std::setw(12) << "noise hits" - << "\t" << std::setw(22) << "maxCPId_byNumberOfHits" - << "\t" << std::setw(8) << "nhitsCP" - << "\t" << std::setw(16) << "maxCPId_byEnergy" - << "\t" << std::setw(23) << "maxEnergySharedMCLandCP" - << "\t" << std::setw(22) << "totalCPEnergyFromAllLayerCP" - << "\t" << std::setw(22) << "energyFractionOfMCLinCP" - << "\t" << std::setw(25) << "energyFractionOfCPinMCL" - << "\t" << std::endl; - LogDebug("HGCalValidator") << std::setw(12) << mclId << "\t" //LogDebug("HGCalValidator") - << std::setw(10) << multiClusters[mclId].energy() << "\t" << std::setw(5) - << numberOfHitsInMCL << "\t" << std::setw(12) << numberOfNoiseHitsInMCL << "\t" - << std::setw(22) << maxCPId_byNumberOfHits << "\t" << std::setw(8) - << maxCPNumberOfHitsInMCL << "\t" << std::setw(16) << maxCPId_byEnergy << "\t" - << std::setw(23) << maxEnergySharedMCLandCP << "\t" << std::setw(22) - << totalCPEnergyFromLayerCP << "\t" << std::setw(22) << energyFractionOfMCLinCP << "\t" - << std::setw(25) << energyFractionOfCPinMCL << std::endl; - - } //end of loop through multi clusters + LogDebug("HGCalValidator") << std::setw(12) << "multiCluster" + << "\t" //LogDebug("HGCalValidator") + << std::setw(10) << "mulcl energy" + << "\t" << std::setw(5) << "nhits" + << "\t" << std::setw(12) << "noise hits" + << "\t" << std::setw(22) << "maxCPId_byNumberOfHits" + << "\t" << std::setw(8) << "nhitsCP" + << "\t" << std::setw(16) << "maxCPId_byEnergy" + << "\t" << std::setw(23) << "maxEnergySharedMCLandCP" + << "\t" << std::setw(22) << "totalCPEnergyFromAllLayerCP" + << "\t" << std::setw(22) << "energyFractionOfMCLinCP" + << "\t" << std::setw(25) << "energyFractionOfCPinMCL" + << "\t" << std::endl; + LogDebug("HGCalValidator") << std::setw(12) << mclId << "\t" //LogDebug("HGCalValidator") + << std::setw(10) << multiClusters[mclId].energy() << "\t" << std::setw(5) + << numberOfHitsInMCL << "\t" << std::setw(12) << numberOfNoiseHitsInMCL << "\t" + << std::setw(22) << maxCPId_byNumberOfHits << "\t" << std::setw(8) + << maxCPNumberOfHitsInMCL << "\t" << std::setw(16) << maxCPId_byEnergy << "\t" + << std::setw(23) << maxEnergySharedMCLandCP << "\t" << std::setw(22) + << totalCPEnergyFromLayerCP << "\t" << std::setw(22) << energyFractionOfMCLinCP << "\t" + << std::setw(25) << energyFractionOfCPinMCL << std::endl; + + } //end of loop through multi clusters + } //Loop through multiclusters for (unsigned int mclId = 0; mclId < nMultiClusters; ++mclId) { const auto& hits_and_fractions = multiClusters[mclId].hitsAndFractions(); - // find the unique caloparticles id contributing to the multi clusters - //cpsInMultiCluster[multicluster][CPids] - std::sort(cpsInMultiCluster[mclId].begin(), cpsInMultiCluster[mclId].end()); - auto last = std::unique(cpsInMultiCluster[mclId].begin(), cpsInMultiCluster[mclId].end()); - cpsInMultiCluster[mclId].erase(last, cpsInMultiCluster[mclId].end()); - - if (multiClusters[mclId].energy() == 0. && !cpsInMultiCluster[mclId].empty()) { - //Loop through all CaloParticles contributing to multicluster mclId. - for (auto& cpPair : cpsInMultiCluster[mclId]) { - //In case of a multi cluster with zero energy but related CaloParticles the score is set to 1. - cpPair.second = 1.; - // LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId - // << "\t CP id: \t" << cpPair.first - // << "\t score \t" << cpPair.second - // << "\n"; - LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId << "\t CP id: \t" << cpPair.first << "\t score \t" - << cpPair.second << std::endl; - histograms.h_score_multicl2caloparticle[count]->Fill(cpPair.second); + if (!hits_and_fractions.empty()) { + // find the unique caloparticles id contributing to the multi clusters + //cpsInMultiCluster[multicluster][CPids] + std::sort(cpsInMultiCluster[mclId].begin(), cpsInMultiCluster[mclId].end()); + auto last = std::unique(cpsInMultiCluster[mclId].begin(), cpsInMultiCluster[mclId].end()); + cpsInMultiCluster[mclId].erase(last, cpsInMultiCluster[mclId].end()); + + if (multiClusters[mclId].energy() == 0. && !cpsInMultiCluster[mclId].empty()) { + //Loop through all CaloParticles contributing to multicluster mclId. + for (auto& cpPair : cpsInMultiCluster[mclId]) { + //In case of a multi cluster with zero energy but related CaloParticles the score is set to 1. + cpPair.second = 1.; + LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId << "\t CP id: \t" << cpPair.first + << "\t score \t" << cpPair.second << std::endl; + histograms.h_score_multicl2caloparticle[count]->Fill(cpPair.second); + } + continue; } - continue; - } - // Compute the correct normalization - float invMultiClusterEnergyWeight = 0.f; - for (auto const& haf : multiClusters[mclId].hitsAndFractions()) { - invMultiClusterEnergyWeight += - (haf.second * hitMap.at(haf.first)->energy()) * (haf.second * hitMap.at(haf.first)->energy()); - } - invMultiClusterEnergyWeight = 1.f / invMultiClusterEnergyWeight; + // Compute the correct normalization + float invMultiClusterEnergyWeight = 0.f; + for (auto const& haf : multiClusters[mclId].hitsAndFractions()) { + invMultiClusterEnergyWeight += + (haf.second * hitMap.at(haf.first)->energy()) * (haf.second * hitMap.at(haf.first)->energy()); + } + invMultiClusterEnergyWeight = 1.f / invMultiClusterEnergyWeight; + + unsigned int numberOfHitsInLC = hits_and_fractions.size(); + for (unsigned int i = 0; i < numberOfHitsInLC; ++i) { + DetId rh_detid = hits_and_fractions[i].first; + float rhFraction = hits_and_fractions[i].second; + bool hitWithNoCP = false; + + auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid); + if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) + hitWithNoCP = true; + auto itcheck = hitMap.find(rh_detid); + const HGCRecHit* hit = itcheck->second; + float hitEnergyWeight = hit->energy() * hit->energy(); - unsigned int numberOfHitsInLC = hits_and_fractions.size(); - for (unsigned int i = 0; i < numberOfHitsInLC; ++i) { - DetId rh_detid = hits_and_fractions[i].first; - float rhFraction = hits_and_fractions[i].second; - bool hitWithNoCP = false; + for (auto& cpPair : cpsInMultiCluster[mclId]) { + float cpFraction = 0.f; + if (!hitWithNoCP) { + auto findHitIt = std::find(detIdToCaloParticleId_Map[rh_detid].begin(), + detIdToCaloParticleId_Map[rh_detid].end(), + HGVHistoProducerAlgo::detIdInfoInCluster{cpPair.first, 0.f}); + if (findHitIt != detIdToCaloParticleId_Map[rh_detid].end()) { + cpFraction = findHitIt->fraction; + } + } + if (cpPair.second == FLT_MAX) { + cpPair.second = 0.f; + } + cpPair.second += + (rhFraction - cpFraction) * (rhFraction - cpFraction) * hitEnergyWeight * invMultiClusterEnergyWeight; + } + } //end of loop through rechits of layer cluster - auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid); - if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) - hitWithNoCP = true; - auto itcheck = hitMap.find(rh_detid); - const HGCRecHit* hit = itcheck->second; - float hitEnergyWeight = hit->energy() * hit->energy(); + //In case of a multi cluster with some energy but none related CaloParticles print some info. + if (cpsInMultiCluster[mclId].empty()) + LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId << "\tCP id:\t-1 " + << "\t score \t-1" + << "\n"; + auto score = std::min_element(std::begin(cpsInMultiCluster[mclId]), + std::end(cpsInMultiCluster[mclId]), + [](const auto& obj1, const auto& obj2) { return obj1.second < obj2.second; }); for (auto& cpPair : cpsInMultiCluster[mclId]) { - float cpFraction = 0.f; - if (!hitWithNoCP) { - auto findHitIt = std::find(detIdToCaloParticleId_Map[rh_detid].begin(), - detIdToCaloParticleId_Map[rh_detid].end(), - HGVHistoProducerAlgo::detIdInfoInCluster{cpPair.first, 0.f}); - if (findHitIt != detIdToCaloParticleId_Map[rh_detid].end()) { - cpFraction = findHitIt->fraction; - } + LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId << "\t CP id: \t" << cpPair.first << "\t score \t" + << cpPair.second << std::endl; + if (cpPair.first == score->first) { + histograms.h_score_multicl2caloparticle[count]->Fill(score->second); } - if (cpPair.second == FLT_MAX) { - cpPair.second = 0.f; + float sharedeneCPallLayers = 0.; + //Loop through all layers + for (unsigned int j = 0; j < layers * 2; ++j) { + auto const& cp_linked = cPOnLayer[cpPair.first][j].layerClusterIdToEnergyAndScore[mclId]; + sharedeneCPallLayers += cp_linked.first; + } //end of loop through layers + LogDebug("HGCalValidator") << "sharedeneCPallLayers " << sharedeneCPallLayers << std::endl; + if (cpPair.first == score->first) { + histograms.h_sharedenergy_multicl2caloparticle[count]->Fill(sharedeneCPallLayers / + multiClusters[mclId].energy()); + histograms.h_energy_vs_score_multicl2caloparticle[count]->Fill( + score->second, sharedeneCPallLayers / multiClusters[mclId].energy()); } - cpPair.second += - (rhFraction - cpFraction) * (rhFraction - cpFraction) * hitEnergyWeight * invMultiClusterEnergyWeight; } - } //end of loop through rechits of layer cluster - - //In case of a multi cluster with some energy but none related CaloParticles print some info. - if (cpsInMultiCluster[mclId].empty()) - LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId << "\tCP id:\t-1 " - << "\t score \t-1" - << "\n"; - auto score = std::min_element(std::begin(cpsInMultiCluster[mclId]), - std::end(cpsInMultiCluster[mclId]), - [](const auto& obj1, const auto& obj2) { return obj1.second < obj2.second; }); - for (auto& cpPair : cpsInMultiCluster[mclId]) { - // LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId - // << "\t CP id: \t" << cpPair.first - // << "\t score \t" << cpPair.second - // << "\n"; - LogDebug("HGCalValidator") << "multiCluster Id: \t" << mclId << "\t CP id: \t" << cpPair.first << "\t score \t" - << cpPair.second << std::endl; - if (cpPair.first == score->first) { - histograms.h_score_multicl2caloparticle[count]->Fill(score->second); - } - float sharedeneCPallLayers = 0.; - //Loop through all layers - for (unsigned int j = 0; j < layers * 2; ++j) { - auto const& cp_linked = cPOnLayer[cpPair.first][j].layerClusterIdToEnergyAndScore[mclId]; - sharedeneCPallLayers += cp_linked.first; - } //end of loop through layers - LogDebug("HGCalValidator") << "sharedeneCPallLayers " << sharedeneCPallLayers << std::endl; - if (cpPair.first == score->first) { - histograms.h_sharedenergy_multicl2caloparticle[count]->Fill(sharedeneCPallLayers / - multiClusters[mclId].energy()); - histograms.h_energy_vs_score_multicl2caloparticle[count]->Fill( - score->second, sharedeneCPallLayers / multiClusters[mclId].energy()); - } + auto assocFakeMerge = std::count_if(std::begin(cpsInMultiCluster[mclId]), + std::end(cpsInMultiCluster[mclId]), + [](const auto& obj) { return obj.second < ScoreCutMCLtoCPFakeMerge_; }); + tracksters_fakemerge[mclId] = assocFakeMerge; } - - auto assocFakeMerge = std::count_if(std::begin(cpsInMultiCluster[mclId]), - std::end(cpsInMultiCluster[mclId]), - [](const auto& obj) { return obj.second < ScoreCutMCLtoCPFakeMerge_; }); - tracksters_fakemerge[mclId] = assocFakeMerge; - } //end of loop through multiclusters std::unordered_map> score3d; @@ -2193,37 +2188,40 @@ void HGVHistoProducerAlgo::multiClusters_to_CaloParticles(const Histograms& hist // reco-level, namely fake-rate an merge-rate. In this loop we should *not* // restrict only to the selected caloParaticles. for (unsigned int mclId = 0; mclId < nMultiClusters; ++mclId) { - auto assocFakeMerge = tracksters_fakemerge[mclId]; - auto assocDuplicate = tracksters_duplicate[mclId]; - if (assocDuplicate) { - histograms.h_numDup_multicl_eta[count]->Fill(multiClusters[mclId].eta()); - histograms.h_numDup_multicl_phi[count]->Fill(multiClusters[mclId].phi()); - } - if (assocFakeMerge > 0) { - histograms.h_num_multicl_eta[count]->Fill(multiClusters[mclId].eta()); - histograms.h_num_multicl_phi[count]->Fill(multiClusters[mclId].phi()); - auto best = std::min_element(std::begin(cpsInMultiCluster[mclId]), - std::end(cpsInMultiCluster[mclId]), - [](const auto& obj1, const auto& obj2) { return obj1.second < obj2.second; }); - - //This is the shared energy taking the best caloparticle in each layer - float sharedeneCPallLayers = 0.; - //Loop through all layers - for (unsigned int j = 0; j < layers * 2; ++j) { - auto const& best_cp_linked = cPOnLayer[best->first][j].layerClusterIdToEnergyAndScore[mclId]; - sharedeneCPallLayers += best_cp_linked.first; - } //end of loop through layers - histograms.h_sharedenergy_multicl2caloparticle_vs_eta[count]->Fill( - multiClusters[mclId].eta(), sharedeneCPallLayers / multiClusters[mclId].energy()); - histograms.h_sharedenergy_multicl2caloparticle_vs_phi[count]->Fill( - multiClusters[mclId].phi(), sharedeneCPallLayers / multiClusters[mclId].energy()); - } - if (assocFakeMerge >= 2) { - histograms.h_numMerge_multicl_eta[count]->Fill(multiClusters[mclId].eta()); - histograms.h_numMerge_multicl_phi[count]->Fill(multiClusters[mclId].phi()); + const auto& hits_and_fractions = multiClusters[mclId].hitsAndFractions(); + if (!hits_and_fractions.empty()) { + auto assocFakeMerge = tracksters_fakemerge[mclId]; + auto assocDuplicate = tracksters_duplicate[mclId]; + if (assocDuplicate) { + histograms.h_numDup_multicl_eta[count]->Fill(multiClusters[mclId].eta()); + histograms.h_numDup_multicl_phi[count]->Fill(multiClusters[mclId].phi()); + } + if (assocFakeMerge > 0) { + histograms.h_num_multicl_eta[count]->Fill(multiClusters[mclId].eta()); + histograms.h_num_multicl_phi[count]->Fill(multiClusters[mclId].phi()); + auto best = std::min_element(std::begin(cpsInMultiCluster[mclId]), + std::end(cpsInMultiCluster[mclId]), + [](const auto& obj1, const auto& obj2) { return obj1.second < obj2.second; }); + + //This is the shared energy taking the best caloparticle in each layer + float sharedeneCPallLayers = 0.; + //Loop through all layers + for (unsigned int j = 0; j < layers * 2; ++j) { + auto const& best_cp_linked = cPOnLayer[best->first][j].layerClusterIdToEnergyAndScore[mclId]; + sharedeneCPallLayers += best_cp_linked.first; + } //end of loop through layers + histograms.h_sharedenergy_multicl2caloparticle_vs_eta[count]->Fill( + multiClusters[mclId].eta(), sharedeneCPallLayers / multiClusters[mclId].energy()); + histograms.h_sharedenergy_multicl2caloparticle_vs_phi[count]->Fill( + multiClusters[mclId].phi(), sharedeneCPallLayers / multiClusters[mclId].energy()); + } + if (assocFakeMerge >= 2) { + histograms.h_numMerge_multicl_eta[count]->Fill(multiClusters[mclId].eta()); + histograms.h_numMerge_multicl_phi[count]->Fill(multiClusters[mclId].phi()); + } + histograms.h_denom_multicl_eta[count]->Fill(multiClusters[mclId].eta()); + histograms.h_denom_multicl_phi[count]->Fill(multiClusters[mclId].phi()); } - histograms.h_denom_multicl_eta[count]->Fill(multiClusters[mclId].eta()); - histograms.h_denom_multicl_phi[count]->Fill(multiClusters[mclId].phi()); } } @@ -2266,6 +2264,10 @@ void HGVHistoProducerAlgo::fill_multi_cluster_histos(const Histograms& histogram for (unsigned int mclId = 0; mclId < nMultiClusters; ++mclId) { const auto layerClusters = multiClusters[mclId].clusters(); auto nLayerClusters = layerClusters.size(); + + if (nLayerClusters == 0) + continue; + if (multiClusters[mclId].z() < 0.) { tnmclmz++; } @@ -2330,18 +2332,20 @@ void HGVHistoProducerAlgo::fill_multi_cluster_histos(const Histograms& histogram //Since we want to also check for non contiguous multiclusters bool contimulti = false; //Observe that we start from 1 and go up to size - 1 element. - for (unsigned int i = 1; i < multicluster_layers_vec.size() - 1; ++i) { - if ((multicluster_layers_vec[i - 1] + 1 == multicluster_layers_vec[i]) && - (multicluster_layers_vec[i + 1] - 1 == multicluster_layers_vec[i])) { - //So, this is a multicluster with 3 contiguous layers per event - if (multiclusterInZplus) { - tncontmclpz++; - } - if (multiclusterInZminus) { - tncontmclmz++; + if (multicluster_layers_vec.size() >= 3) { + for (unsigned int i = 1; i < multicluster_layers_vec.size() - 1; ++i) { + if ((multicluster_layers_vec[i - 1] + 1 == multicluster_layers_vec[i]) && + (multicluster_layers_vec[i + 1] - 1 == multicluster_layers_vec[i])) { + //So, this is a multicluster with 3 contiguous layers per event + if (multiclusterInZplus) { + tncontmclpz++; + } + if (multiclusterInZminus) { + tncontmclmz++; + } + contimulti = true; + break; } - contimulti = true; - break; } } //Count non contiguous multiclusters @@ -2382,17 +2386,18 @@ void HGVHistoProducerAlgo::fill_multi_cluster_histos(const Histograms& histogram histograms.h_multiplicityOfLCinMCL_vs_layerclusterenergy[count]->Fill(mlp, layerClusters[lc]->energy()); } - histograms.h_multicluster_pt[count]->Fill(multiClusters[mclId].pt()); - histograms.h_multicluster_eta[count]->Fill(multiClusters[mclId].eta()); - histograms.h_multicluster_phi[count]->Fill(multiClusters[mclId].phi()); - histograms.h_multicluster_energy[count]->Fill(multiClusters[mclId].energy()); - histograms.h_multicluster_x[count]->Fill(multiClusters[mclId].x()); - histograms.h_multicluster_y[count]->Fill(multiClusters[mclId].y()); - histograms.h_multicluster_z[count]->Fill(multiClusters[mclId].z()); - histograms.h_multicluster_firstlayer[count]->Fill((float)*multicluster_layers.begin()); - histograms.h_multicluster_lastlayer[count]->Fill((float)*multicluster_layers.rbegin()); - histograms.h_multicluster_layersnum[count]->Fill((float)multicluster_layers.size()); - + if (!multicluster_layers.empty()) { + histograms.h_multicluster_pt[count]->Fill(multiClusters[mclId].pt()); + histograms.h_multicluster_eta[count]->Fill(multiClusters[mclId].eta()); + histograms.h_multicluster_phi[count]->Fill(multiClusters[mclId].phi()); + histograms.h_multicluster_energy[count]->Fill(multiClusters[mclId].energy()); + histograms.h_multicluster_x[count]->Fill(multiClusters[mclId].x()); + histograms.h_multicluster_y[count]->Fill(multiClusters[mclId].y()); + histograms.h_multicluster_z[count]->Fill(multiClusters[mclId].z()); + histograms.h_multicluster_firstlayer[count]->Fill((float)*multicluster_layers.begin()); + histograms.h_multicluster_lastlayer[count]->Fill((float)*multicluster_layers.rbegin()); + histograms.h_multicluster_layersnum[count]->Fill((float)multicluster_layers.size()); + } } //end of loop through multiclusters histograms.h_multiclusternum[count]->Fill(tnmclmz + tnmclpz); diff --git a/Validation/RecoTrack/test/publicPlots/plot.py b/Validation/RecoTrack/test/publicPlots/plot.py index 7b7d12ca6c768..19ae2a58cac72 100755 --- a/Validation/RecoTrack/test/publicPlots/plot.py +++ b/Validation/RecoTrack/test/publicPlots/plot.py @@ -180,6 +180,7 @@ def __init__(self): self._legends = [] def add(self, histo, legend): + histo.ResetBit(ROOT.TH1.kIsAverage) self._histos.append(histo) self._legends.append(legend)