diff --git a/DataFormats/CSCDigi/interface/GEMCSCLCTDigi.h b/DataFormats/CSCDigi/interface/GEMCSCLCTDigi.h new file mode 100644 index 0000000000000..c56e3603c214b --- /dev/null +++ b/DataFormats/CSCDigi/interface/GEMCSCLCTDigi.h @@ -0,0 +1,32 @@ +#ifndef CSCDigi_GEMCSCLCTDigi_h +#define CSCDigi_GEMCSCLCTDigi_h + +#include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h" +#include +#include + +class GEMCSCLCTDigi +{ + public: + + /// Constructors + GEMCSCLCTDigi(const CSCCorrelatedLCTDigi, float); + GEMCSCLCTDigi(); /// default + + /// return track number + const CSCCorrelatedLCTDigi& getDigi() const { return digi_; } + + /// return bend + int getBend() const { return bend_; } + + ///Comparison + bool operator == (const GEMCSCLCTDigi &) const; + bool operator != (const GEMCSCLCTDigi &rhs) const + { return !(this->operator==(rhs)); } + + private: + CSCCorrelatedLCTDigi digi_; + float bend_; +}; + +#endif diff --git a/DataFormats/CSCDigi/interface/GEMCSCLCTDigiCollection.h b/DataFormats/CSCDigi/interface/GEMCSCLCTDigiCollection.h new file mode 100644 index 0000000000000..b3f3fc0accaed --- /dev/null +++ b/DataFormats/CSCDigi/interface/GEMCSCLCTDigiCollection.h @@ -0,0 +1,10 @@ +#ifndef GEMCSCLCTDigi_GEMCSCLCTDigiCollection_h +#define GEMCSCLCTDigi_GEMCSCLCTDigiCollection_h + +#include +#include +#include + +typedef MuonDigiCollection GEMCSCLCTDigiCollection; + +#endif diff --git a/DataFormats/CSCDigi/src/GEMCSCLCTDigi.cc b/DataFormats/CSCDigi/src/GEMCSCLCTDigi.cc new file mode 100644 index 0000000000000..651064da1ec76 --- /dev/null +++ b/DataFormats/CSCDigi/src/GEMCSCLCTDigi.cc @@ -0,0 +1,18 @@ +#include "DataFormats/CSCDigi/interface/GEMCSCLCTDigi.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include + +/// Constructors +GEMCSCLCTDigi::GEMCSCLCTDigi(const CSCCorrelatedLCTDigi digi, float bend) : + digi_(digi), + bend_(bend) +{} + +/// Default +GEMCSCLCTDigi::GEMCSCLCTDigi() { +} + +/// Comparison +bool GEMCSCLCTDigi::operator==(const GEMCSCLCTDigi &rhs) const { + return ( digi_ == rhs.getDigi() && bend_ == rhs.getBend() ); +} diff --git a/DataFormats/CSCDigi/src/classes.h b/DataFormats/CSCDigi/src/classes.h index c5861cde21f04..19190e4e5d606 100644 --- a/DataFormats/CSCDigi/src/classes.h +++ b/DataFormats/CSCDigi/src/classes.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -44,6 +46,7 @@ namespace DataFormats_CSCDigi { CSCCLCTDigi cCLCTD_; CSCALCTDigi cALCTD_; CSCCorrelatedLCTDigi cCorLCTD_; + GEMCSCLCTDigi gcLCTD_; CSCCFEBStatusDigi cCSD_; CSCTMBStatusDigi cTMBSD_; CSCDCCFormatStatusDigi cDFSD_; @@ -61,6 +64,7 @@ namespace DataFormats_CSCDigi { std::vector vCLCTD_; std::vector vALCTD_; std::vector vCorLCTD_; + std::vector vgcLCTD_; std::vector vCSD_; std::vector vTMBSD_; std::vector vDFSD_; @@ -77,6 +81,7 @@ namespace DataFormats_CSCDigi { std::vector > vvCLCTD_; std::vector > vvALCTD_; std::vector > vvCorLCTD_; + std::vector > vvgcLCTD_; std::vector > vvCSD_; std::vector > vvTMBSD_; std::vector > vvDMBSD_; @@ -93,6 +98,7 @@ namespace DataFormats_CSCDigi { CSCCLCTDigiCollection clCLCTD_; CSCALCTDigiCollection clALCTD_; CSCCorrelatedLCTDigiCollection clCorLCTD_; + GEMCSCLCTDigiCollection clgcLCTD_; CSCCFEBStatusDigiCollection clCSD_; CSCTMBStatusDigiCollection clTMBSD_; CSCDCCFormatStatusDigiCollection clDFSD_; @@ -109,6 +115,7 @@ namespace DataFormats_CSCDigi { edm::Wrapper wCLCTD_; edm::Wrapper wALCTD_; edm::Wrapper wCorLCTD_; + edm::Wrapper wgcLCTD_; edm::Wrapper wCSD_; edm::Wrapper wTMBSD_; edm::Wrapper wDFSD_; diff --git a/DataFormats/CSCDigi/src/classes_def.xml b/DataFormats/CSCDigi/src/classes_def.xml index 282299c92a82e..6d281f87fb6d0 100644 --- a/DataFormats/CSCDigi/src/classes_def.xml +++ b/DataFormats/CSCDigi/src/classes_def.xml @@ -14,6 +14,9 @@ + + + @@ -47,6 +50,7 @@ + @@ -62,6 +66,7 @@ + @@ -78,6 +83,7 @@ + @@ -95,6 +101,7 @@ + @@ -111,6 +118,7 @@ + diff --git a/L1Trigger/CSCTriggerPrimitives/BuildFile.xml b/L1Trigger/CSCTriggerPrimitives/BuildFile.xml index 424977eb96984..7cea26f64b9c3 100644 --- a/L1Trigger/CSCTriggerPrimitives/BuildFile.xml +++ b/L1Trigger/CSCTriggerPrimitives/BuildFile.xml @@ -1,10 +1,12 @@ + + diff --git a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc index 594ed32234f51..739f2955cd4c8 100644 --- a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc +++ b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc @@ -22,6 +22,7 @@ #include "Geometry/Records/interface/MuonGeometryRecord.h" #include "L1Trigger/CSCCommonTrigger/interface/CSCTriggerGeometry.h" #include "CondFormats/DataRecord/interface/CSCBadChambersRcd.h" +#include "Geometry/GEMGeometry/interface/GEMGeometry.h" //#include "DataFormats/CSCDigi/interface/CSCComparatorDigiCollection.h" //#include "DataFormats/CSCDigi/interface/CSCWireDigiCollection.h" @@ -29,6 +30,10 @@ #include "DataFormats/CSCDigi/interface/CSCCLCTDigiCollection.h" #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h" +#include "DataFormats/CSCDigi/interface/GEMCSCLCTDigiCollection.h" +#include "DataFormats/GEMDigi/interface/GEMPadDigiCollection.h" +#include "DataFormats/GEMDigi/interface/GEMCoPadDigiCollection.h" + // Configuration via EventSetup #include "CondFormats/CSCObjects/interface/CSCDBL1TPParameters.h" #include "CondFormats/DataRecord/interface/CSCDBL1TPParametersRcd.h" @@ -38,16 +43,18 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS // if false, parameters will be read in from DB using EventSetup mechanism // else will use all parameters from the config file - debugParameters_ = conf.getUntrackedParameter("debugParameters",false); + debugParameters_ = conf.getParameter("debugParameters"); wireDigiProducer_ = conf.getParameter("CSCWireDigiProducer"); compDigiProducer_ = conf.getParameter("CSCComparatorDigiProducer"); - checkBadChambers_ = conf.getUntrackedParameter("checkBadChambers", true); + gemPadDigiProducer_ = conf.existsAs("GEMPadDigiProducer")?conf.getParameter("GEMPadDigiProducer"):edm::InputTag(""); + checkBadChambers_ = conf.getParameter("checkBadChambers"); lctBuilder_ = new CSCTriggerPrimitivesBuilder(conf); // pass on the conf wire_token_ = consumes(wireDigiProducer_); comp_token_ = consumes(compDigiProducer_); + gem_pad_token_ = consumes(gemPadDigiProducer_); // register what this produces produces(); @@ -55,9 +62,12 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS produces(); produces(); produces("MPCSORTED"); + produces(); + produces(); usesResource("CSCTriggerGeometry"); consumes(compDigiProducer_); consumes(wireDigiProducer_); + consumes(gemPadDigiProducer_); } CSCTriggerPrimitivesProducer::~CSCTriggerPrimitivesProducer() { @@ -80,6 +90,15 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, edm::ESHandle h; setup.get().get(h); CSCTriggerGeometry::setGeometry(h); + + edm::ESHandle h_gem; + try { + setup.get().get(h_gem); + // lctBuilder_->setGEMGeometry(&*h_gem); + } catch (edm::eventsetup::NoProxyException& e) { + edm::LogInfo("L1CSCTPEmulatorNoGEMGeometry") + << "+++ Info: GEM geometry is unavailable. Running CSC-only trigger algorithm. +++\n"; + } } // Find conditions data for bad chambers. @@ -109,13 +128,24 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, ev.getByToken(comp_token_, compDigis); ev.getByToken(wire_token_, wireDigis); - // Create empty collections of ALCTs, CLCTs, and correlated LCTs upstream + + const GEMPadDigiCollection *gemPads = nullptr; + if (!gemPadDigiProducer_.label().empty()) { + edm::Handle gemPadDigis; + ev.getByToken(gem_pad_token_, gemPadDigis); + gemPads = gemPadDigis.product(); + } + + + // Create empty collections of ALCTs, CLCTs, and correlated LCTs upstream // and downstream of MPC. std::auto_ptr oc_alct(new CSCALCTDigiCollection); std::auto_ptr oc_clct(new CSCCLCTDigiCollection); std::auto_ptr oc_pretrig(new CSCCLCTPreTriggerCollection); std::auto_ptr oc_lct(new CSCCorrelatedLCTDigiCollection); std::auto_ptr oc_sorted_lct(new CSCCorrelatedLCTDigiCollection); + std::auto_ptr oc_gemcopad(new GEMCoPadDigiCollection); + std::auto_ptr oc_gemcsclct(new GEMCSCLCTDigiCollection); if (!wireDigis.isValid()) { edm::LogWarning("L1CSCTPEmulatorNoInputCollection") @@ -135,8 +165,8 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, if (wireDigis.isValid() && compDigis.isValid()) { const CSCBadChambers* temp = checkBadChambers_ ? pBadChambers.product() : new CSCBadChambers; lctBuilder_->build(temp, - wireDigis.product(), compDigis.product(), - *oc_alct, *oc_clct, *oc_pretrig, *oc_lct, *oc_sorted_lct); + wireDigis.product(), compDigis.product(), gemPads, + *oc_alct, *oc_clct, *oc_pretrig, *oc_lct, *oc_sorted_lct, *oc_gemcopad, *oc_gemcsclct); if (!checkBadChambers_) delete temp; } @@ -147,4 +177,6 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, ev.put(oc_pretrig); ev.put(oc_lct); ev.put(oc_sorted_lct,"MPCSORTED"); + ev.put(oc_gemcopad); + ev.put(oc_gemcsclct); } diff --git a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h index a92934acb5d3c..ac147007cce61 100644 --- a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h +++ b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.h @@ -22,6 +22,8 @@ #include "DataFormats/CSCDigi/interface/CSCComparatorDigiCollection.h" #include "DataFormats/CSCDigi/interface/CSCWireDigiCollection.h" +#include "DataFormats/GEMDigi/interface/GEMPadDigiCollection.h" + #include #include #include @@ -45,8 +47,10 @@ class CSCTriggerPrimitivesProducer : public edm::one::EDProducer comp_token_; edm::EDGetTokenT wire_token_; + edm::EDGetTokenT gem_pad_token_; // switch to force the use of parameters from config file rather then from DB bool debugParameters_; diff --git a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS1_cfi.py b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS1_cfi.py index b970cab603799..5f6c65d8fc293 100644 --- a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS1_cfi.py +++ b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS1_cfi.py @@ -8,14 +8,14 @@ # if False, parameters will be read in from DB using EventSetup mechanism # else will use parameters from this config - debugParameters = cms.untracked.bool(True), + debugParameters = cms.bool(True), # Name of digi producer module(s) CSCComparatorDigiProducer = cms.InputTag("simMuonCSCDigis","MuonCSCComparatorDigi"), CSCWireDigiProducer = cms.InputTag("simMuonCSCDigis","MuonCSCWireDigi"), # for SLHC studies we don't want bad chambers checks so far - checkBadChambers_ = cms.untracked.bool(False), + checkBadChambers_ = cms.bool(False), # Parameters common for all boards commonParam = cms.PSet( @@ -24,7 +24,7 @@ # Flag for SLHC studies (upgraded ME11, MPC) # (if true, isTMB07 should be true as well) - isSLHC = cms.untracked.bool(True), + isSLHC = cms.bool(True), # ME1a configuration: # smartME1aME1b=f, gangedME1a=t @@ -36,12 +36,12 @@ # smartME1aME1b=t, gangedME1a=t # the previous case with ME1a still being ganged # Note: gangedME1a has effect only if smartME1aME1b=t - smartME1aME1b = cms.untracked.bool(True), - gangedME1a = cms.untracked.bool(False), + smartME1aME1b = cms.bool(True), + gangedME1a = cms.bool(False), # flagis to optionally disable finding stubs in ME42 or ME1a - disableME1a = cms.untracked.bool(False), - disableME42 = cms.untracked.bool(False) + disableME1a = cms.bool(False), + disableME42 = cms.bool(False) ), # Parameters for ALCT processors: old MC studies @@ -56,7 +56,7 @@ alctTrigMode = cms.uint32(3), alctAccelMode = cms.uint32(1), alctL1aWindowWidth = cms.uint32(5), - verbosity = cms.untracked.int32(0) + verbosity = cms.int32(0) ), # Parameters for ALCT processors: MTCC-II @@ -71,7 +71,7 @@ alctTrigMode = cms.uint32(2), alctAccelMode = cms.uint32(0), alctL1aWindowWidth = cms.uint32(3), - verbosity = cms.untracked.int32(0) + verbosity = cms.int32(0) ), # Parameters for ALCT processors: 2007 and later @@ -86,28 +86,28 @@ alctTrigMode = cms.uint32(2), alctAccelMode = cms.uint32(0), alctL1aWindowWidth = cms.uint32(7), - verbosity = cms.untracked.int32(0), + verbosity = cms.int32(0), # Configure early_tbins instead of hardcoding it - alctEarlyTbins = cms.untracked.int32(4), + alctEarlyTbins = cms.int32(4), # Use narrow pattern mask for ring 1 chambers - alctNarrowMaskForR1 = cms.untracked.bool(True), + alctNarrowMaskForR1 = cms.bool(True), # configured, not hardcoded, hit persistency - alctHitPersist = cms.untracked.uint32(6), + alctHitPersist = cms.uint32(6), # configure, not hardcode, up to how many BXs in the past # ghost cancellation in neighboring WGs may happen - alctGhostCancellationBxDepth = cms.untracked.int32(1), + alctGhostCancellationBxDepth = cms.int32(1), # whether to compare the quality of stubs in neighboring WGs in the past # to the quality of a stub in current WG # when doing ghost cancellation - alctGhostCancellationSideQuality = cms.untracked.bool(True), + alctGhostCancellationSideQuality = cms.bool(True), # how soon after pretrigger and alctDriftDelay can next pretrigger happen? - alctPretrigDeadtime = cms.untracked.uint32(4) + alctPretrigDeadtime = cms.uint32(4) ), # Parameters for ALCT processors: SLHC studies @@ -122,34 +122,34 @@ alctTrigMode = cms.uint32(2), alctAccelMode = cms.uint32(0), alctL1aWindowWidth = cms.uint32(7), - verbosity = cms.untracked.int32(0), + verbosity = cms.int32(0), # Configure early_tbins instead of hardcoding it - alctEarlyTbins = cms.untracked.int32(4), + alctEarlyTbins = cms.int32(4), # Use narrow pattern mask for ring 1 chambers - alctNarrowMaskForR1 = cms.untracked.bool(True), + alctNarrowMaskForR1 = cms.bool(True), # configured, not hardcoded, hit persistency - alctHitPersist = cms.untracked.uint32(6), + alctHitPersist = cms.uint32(6), # configure, not hardcode, up to how many BXs in the past # ghost cancellation in neighboring WGs may happen - alctGhostCancellationBxDepth = cms.untracked.int32(1), + alctGhostCancellationBxDepth = cms.int32(1), # whether to compare the quality of stubs in neighboring WGs in the past # to the quality of a stub in current WG # when doing ghost cancellation - alctGhostCancellationSideQuality = cms.untracked.bool(True), + alctGhostCancellationSideQuality = cms.bool(True), # how soon after pretrigger and alctDriftDelay can next pretrigger happen? - alctPretrigDeadtime = cms.untracked.uint32(0), + alctPretrigDeadtime = cms.uint32(0), # SLHC only for ME11: # whether to store the "corrected" ALCT stub time # (currently it is median time of particular hits in a pattern) into the ASCCLCTDigi bx, # and temporary store the regular "key layer hit" time into the CSCCLCTDigi fullBX: - alctUseCorrectedBx = cms.untracked.bool(True) + alctUseCorrectedBx = cms.bool(True) ), # Parameters for CLCT processors: old MC studies @@ -163,7 +163,7 @@ clctPidThreshPretrig = cms.uint32(2), clctMinSeparation = cms.uint32(10), # Debug - verbosity = cms.untracked.int32(0) + verbosity = cms.int32(0) ), # Parameters for CLCT processors: MTCC-II @@ -177,7 +177,7 @@ clctPidThreshPretrig = cms.uint32(2), clctMinSeparation = cms.uint32(10), # Debug - verbosity = cms.untracked.int32(0) + verbosity = cms.int32(0) ), # Parameters for CLCT processors: 2007 and later @@ -193,10 +193,10 @@ # decrease possible minimal #HS distance between two CLCTs in a BX from 10 to 5: clctMinSeparation = cms.uint32(5), # Debug - verbosity = cms.untracked.int32(0), + verbosity = cms.int32(0), # BX to start CLCT finding (poor man's dead-time shortening): - clctStartBxShift = cms.untracked.int32(0) + clctStartBxShift = cms.int32(0) ), # Parameters for CLCT processors: SLHC studies @@ -212,31 +212,31 @@ # decrease possible minimal #HS distance between two CLCTs in a BX from 10 to 5: clctMinSeparation = cms.uint32(5), # Debug - verbosity = cms.untracked.int32(0), + verbosity = cms.int32(0), # BX to start CLCT finding (poor man's to shorten the dead-time): - clctStartBxShift = cms.untracked.int32(0), + clctStartBxShift = cms.int32(0), # Turns on algorithms of localized dead-time zones: - useDeadTimeZoning = cms.untracked.bool(True), + useDeadTimeZoning = cms.bool(True), # Width (in #HS) of a fixed dead zone around a key HS: - clctStateMachineZone = cms.untracked.uint32(8), + clctStateMachineZone = cms.uint32(8), # Enables the algo which instead of using the fixed dead zone width, # varies it depending on the width of a triggered CLCT pattern # (if True, the clctStateMachineZone is ignored): - useDynamicStateMachineZone = cms.untracked.bool(True), + useDynamicStateMachineZone = cms.bool(True), # Pretrigger HS +- clctPretriggerTriggerZone sets the trigger matching zone # which defines how far from pretrigger HS the TMB may look for a trigger HS # (it becomes important to do so with localized dead-time zoning): - clctPretriggerTriggerZone = cms.untracked.uint32(5), + clctPretriggerTriggerZone = cms.uint32(5), # whether to store the "corrected" CLCT stub time # (currently it is median time of all hits in a pattern) into the CSCCLCTDigi bx, # and temporary store the regular "key layer hit" time into the CSCCLCTDigi fullBX: - clctUseCorrectedBx = cms.untracked.bool(True) + clctUseCorrectedBx = cms.bool(True) ), tmbParam = cms.PSet( @@ -248,20 +248,20 @@ matchTrigWindowSize = cms.uint32(3), tmbL1aWindowSize = cms.uint32(7), # Debug - verbosity = cms.untracked.int32(0), + verbosity = cms.int32(0), # Configure early_tbins instead of hardcoding it - tmbEarlyTbins = cms.untracked.int32(4), + tmbEarlyTbins = cms.int32(4), # Flag for whether to readout only the earliest max two LCTs in a # L1A readout window, as there is only room just for two in the TMB header. # If false, all LCTs would be readout in L1A window. - tmbReadoutEarliest2 = cms.untracked.bool(True), + tmbReadoutEarliest2 = cms.bool(True), # For CLCT-centric matching, whether to drop ALCTs that were matched # to CLCTs in this BX, and not use them in the following BX # (default non-upgrade TMB behavior). - tmbDropUsedAlcts = cms.untracked.bool(True) + tmbDropUsedAlcts = cms.bool(True) ), # to be used by ME11 chambers with upgraded TMB and ALCT @@ -274,54 +274,54 @@ matchTrigWindowSize = cms.uint32(3), tmbL1aWindowSize = cms.uint32(7), # Debug - verbosity = cms.untracked.int32(0), + verbosity = cms.int32(0), # Configure early_tbins instead of hardcoding it - tmbEarlyTbins = cms.untracked.int32(4), + tmbEarlyTbins = cms.int32(4), # Flag for whether to readout only the earliest max two LCTs in a # L1A readout window, as there is only room just for two in the TMB header. # If false, all LCTs would be readout in L1A window. - tmbReadoutEarliest2 = cms.untracked.bool(False), + tmbReadoutEarliest2 = cms.bool(False), # For CLCT-centric matching, whether to drop ALCTs that were matched # to CLCTs in this BX, and not use them in the following BX # (default non-upgrade TMB behavior). - tmbDropUsedAlcts = cms.untracked.bool(False), + tmbDropUsedAlcts = cms.bool(False), # Switch to enable # True = CLCT-centric matching (default non-upgrade behavior, # take CLCTs in BX look for matching ALCTs in window) # False = ALCT-centric matching (recommended for SLHC, # take ALCTs in BX look for matching CLCTs in window) - clctToAlct = cms.untracked.bool(False), + clctToAlct = cms.bool(False), # For ALCT-centric matching, whether to drop CLCTs that were matched # to ALCTs in this BX, and not use them in the following BX - tmbDropUsedClcts = cms.untracked.bool(False), + tmbDropUsedClcts = cms.bool(False), # For CLCT-centric matching in ME11, break after finding # the first BX with matching ALCT - matchEarliestAlctME11Only = cms.untracked.bool(False), + matchEarliestAlctME11Only = cms.bool(False), # For ALCT-centric matching in ME11, break after finding # the first BX with matching CLCT - matchEarliestClctME11Only = cms.untracked.bool(False), + matchEarliestClctME11Only = cms.bool(False), # 0 = default "non-X-BX" sorting algorithm, # where the first BX with match goes first # 1 = simple X-BX sorting algorithm, # where the central match BX goes first, # then the closest early, the slocest late, etc. - tmbCrossBxAlgorithm = cms.untracked.uint32(1), + tmbCrossBxAlgorithm = cms.uint32(1), # How many maximum LCTs per whole chamber per BX to keep # (supposedly, 1b and 1a can have max 2 each) - maxME11LCTs = cms.untracked.uint32(2) + maxME11LCTs = cms.uint32(2) ), # MPC sorter config for SLHC studies mpcSLHC = cms.PSet( - mpcMaxStubs = cms.untracked.uint32(3) + mpcMaxStubs = cms.uint32(3) ) ) diff --git a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS2_cfi.py b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS2_cfi.py new file mode 100644 index 0000000000000..b970cab603799 --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS2_cfi.py @@ -0,0 +1,327 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.CSCCommonTrigger.CSCCommonTrigger_cfi import * +# Default parameters for CSCTriggerPrimitives generator +# ===================================================== +cscTriggerPrimitiveDigisPostLS1 = cms.EDProducer("CSCTriggerPrimitivesProducer", + CSCCommonTrigger, + + # if False, parameters will be read in from DB using EventSetup mechanism + # else will use parameters from this config + debugParameters = cms.untracked.bool(True), + + # Name of digi producer module(s) + CSCComparatorDigiProducer = cms.InputTag("simMuonCSCDigis","MuonCSCComparatorDigi"), + CSCWireDigiProducer = cms.InputTag("simMuonCSCDigis","MuonCSCWireDigi"), + + # for SLHC studies we don't want bad chambers checks so far + checkBadChambers_ = cms.untracked.bool(False), + + # Parameters common for all boards + commonParam = cms.PSet( + isTMB07 = cms.bool(True), + isMTCC = cms.bool(False), + + # Flag for SLHC studies (upgraded ME11, MPC) + # (if true, isTMB07 should be true as well) + isSLHC = cms.untracked.bool(True), + + # ME1a configuration: + # smartME1aME1b=f, gangedME1a=t + # default logic for current HW + # smartME1aME1b=t, gangedME1a=f + # realistic upgrade scenario: + # one ALCT finder and two CLCT finders per ME11 + # with additional logic for A/CLCT matching with ME1a unganged + # smartME1aME1b=t, gangedME1a=t + # the previous case with ME1a still being ganged + # Note: gangedME1a has effect only if smartME1aME1b=t + smartME1aME1b = cms.untracked.bool(True), + gangedME1a = cms.untracked.bool(False), + + # flagis to optionally disable finding stubs in ME42 or ME1a + disableME1a = cms.untracked.bool(False), + disableME42 = cms.untracked.bool(False) + ), + + # Parameters for ALCT processors: old MC studies + alctParamOldMC = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(3), + alctNplanesHitPretrig = cms.uint32(2), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(2), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(3), + alctAccelMode = cms.uint32(1), + alctL1aWindowWidth = cms.uint32(5), + verbosity = cms.untracked.int32(0) + ), + + # Parameters for ALCT processors: MTCC-II + alctParamMTCC = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(3), + alctNplanesHitPretrig = cms.uint32(2), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(2), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(2), + alctAccelMode = cms.uint32(0), + alctL1aWindowWidth = cms.uint32(3), + verbosity = cms.untracked.int32(0) + ), + + # Parameters for ALCT processors: 2007 and later + alctParam07 = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(2), + alctNplanesHitPretrig = cms.uint32(3), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(3), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(2), + alctAccelMode = cms.uint32(0), + alctL1aWindowWidth = cms.uint32(7), + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + alctEarlyTbins = cms.untracked.int32(4), + + # Use narrow pattern mask for ring 1 chambers + alctNarrowMaskForR1 = cms.untracked.bool(True), + + # configured, not hardcoded, hit persistency + alctHitPersist = cms.untracked.uint32(6), + + # configure, not hardcode, up to how many BXs in the past + # ghost cancellation in neighboring WGs may happen + alctGhostCancellationBxDepth = cms.untracked.int32(1), + + # whether to compare the quality of stubs in neighboring WGs in the past + # to the quality of a stub in current WG + # when doing ghost cancellation + alctGhostCancellationSideQuality = cms.untracked.bool(True), + + # how soon after pretrigger and alctDriftDelay can next pretrigger happen? + alctPretrigDeadtime = cms.untracked.uint32(4) + ), + + # Parameters for ALCT processors: SLHC studies + alctSLHC = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(2), + alctNplanesHitPretrig = cms.uint32(3), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(3), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(2), + alctAccelMode = cms.uint32(0), + alctL1aWindowWidth = cms.uint32(7), + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + alctEarlyTbins = cms.untracked.int32(4), + + # Use narrow pattern mask for ring 1 chambers + alctNarrowMaskForR1 = cms.untracked.bool(True), + + # configured, not hardcoded, hit persistency + alctHitPersist = cms.untracked.uint32(6), + + # configure, not hardcode, up to how many BXs in the past + # ghost cancellation in neighboring WGs may happen + alctGhostCancellationBxDepth = cms.untracked.int32(1), + + # whether to compare the quality of stubs in neighboring WGs in the past + # to the quality of a stub in current WG + # when doing ghost cancellation + alctGhostCancellationSideQuality = cms.untracked.bool(True), + + # how soon after pretrigger and alctDriftDelay can next pretrigger happen? + alctPretrigDeadtime = cms.untracked.uint32(0), + + # SLHC only for ME11: + # whether to store the "corrected" ALCT stub time + # (currently it is median time of particular hits in a pattern) into the ASCCLCTDigi bx, + # and temporary store the regular "key layer hit" time into the CSCCLCTDigi fullBX: + alctUseCorrectedBx = cms.untracked.bool(True) + ), + + # Parameters for CLCT processors: old MC studies + clctParamOldMC = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(6), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(2), + clctNplanesHitPattern = cms.uint32(4), + clctPidThreshPretrig = cms.uint32(2), + clctMinSeparation = cms.uint32(10), + # Debug + verbosity = cms.untracked.int32(0) + ), + + # Parameters for CLCT processors: MTCC-II + clctParamMTCC = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(6), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(4), + clctNplanesHitPattern = cms.uint32(1), + clctPidThreshPretrig = cms.uint32(2), + clctMinSeparation = cms.uint32(10), + # Debug + verbosity = cms.untracked.int32(0) + ), + + # Parameters for CLCT processors: 2007 and later + clctParam07 = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(4), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(3), + clctNplanesHitPattern = cms.uint32(4), + # increase pattern ID threshold from 2 to 4 to trigger higher pt tracks + clctPidThreshPretrig = cms.uint32(4), + # decrease possible minimal #HS distance between two CLCTs in a BX from 10 to 5: + clctMinSeparation = cms.uint32(5), + # Debug + verbosity = cms.untracked.int32(0), + + # BX to start CLCT finding (poor man's dead-time shortening): + clctStartBxShift = cms.untracked.int32(0) + ), + + # Parameters for CLCT processors: SLHC studies + clctSLHC = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(4), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(3), + clctNplanesHitPattern = cms.uint32(4), + # increase pattern ID threshold from 2 to 4 to trigger higher pt tracks + clctPidThreshPretrig = cms.uint32(4), + # decrease possible minimal #HS distance between two CLCTs in a BX from 10 to 5: + clctMinSeparation = cms.uint32(5), + # Debug + verbosity = cms.untracked.int32(0), + + # BX to start CLCT finding (poor man's to shorten the dead-time): + clctStartBxShift = cms.untracked.int32(0), + + # Turns on algorithms of localized dead-time zones: + useDeadTimeZoning = cms.untracked.bool(True), + + # Width (in #HS) of a fixed dead zone around a key HS: + clctStateMachineZone = cms.untracked.uint32(8), + + # Enables the algo which instead of using the fixed dead zone width, + # varies it depending on the width of a triggered CLCT pattern + # (if True, the clctStateMachineZone is ignored): + useDynamicStateMachineZone = cms.untracked.bool(True), + + # Pretrigger HS +- clctPretriggerTriggerZone sets the trigger matching zone + # which defines how far from pretrigger HS the TMB may look for a trigger HS + # (it becomes important to do so with localized dead-time zoning): + clctPretriggerTriggerZone = cms.untracked.uint32(5), + + # whether to store the "corrected" CLCT stub time + # (currently it is median time of all hits in a pattern) into the CSCCLCTDigi bx, + # and temporary store the regular "key layer hit" time into the CSCCLCTDigi fullBX: + clctUseCorrectedBx = cms.untracked.bool(True) + ), + + tmbParam = cms.PSet( + mpcBlockMe1a = cms.uint32(0), + alctTrigEnable = cms.uint32(0), + clctTrigEnable = cms.uint32(0), + matchTrigEnable = cms.uint32(1), + # reduce ALCT-CLCT matching window size from 7 to 3 + matchTrigWindowSize = cms.uint32(3), + tmbL1aWindowSize = cms.uint32(7), + # Debug + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + tmbEarlyTbins = cms.untracked.int32(4), + + # Flag for whether to readout only the earliest max two LCTs in a + # L1A readout window, as there is only room just for two in the TMB header. + # If false, all LCTs would be readout in L1A window. + tmbReadoutEarliest2 = cms.untracked.bool(True), + + # For CLCT-centric matching, whether to drop ALCTs that were matched + # to CLCTs in this BX, and not use them in the following BX + # (default non-upgrade TMB behavior). + tmbDropUsedAlcts = cms.untracked.bool(True) + ), + + # to be used by ME11 chambers with upgraded TMB and ALCT + tmbSLHC = cms.PSet( + mpcBlockMe1a = cms.uint32(0), + alctTrigEnable = cms.uint32(0), + clctTrigEnable = cms.uint32(0), + matchTrigEnable = cms.uint32(1), + # reduce ALCT-CLCT matching window size from 7 to 3 + matchTrigWindowSize = cms.uint32(3), + tmbL1aWindowSize = cms.uint32(7), + # Debug + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + tmbEarlyTbins = cms.untracked.int32(4), + + # Flag for whether to readout only the earliest max two LCTs in a + # L1A readout window, as there is only room just for two in the TMB header. + # If false, all LCTs would be readout in L1A window. + tmbReadoutEarliest2 = cms.untracked.bool(False), + + # For CLCT-centric matching, whether to drop ALCTs that were matched + # to CLCTs in this BX, and not use them in the following BX + # (default non-upgrade TMB behavior). + tmbDropUsedAlcts = cms.untracked.bool(False), + + # Switch to enable + # True = CLCT-centric matching (default non-upgrade behavior, + # take CLCTs in BX look for matching ALCTs in window) + # False = ALCT-centric matching (recommended for SLHC, + # take ALCTs in BX look for matching CLCTs in window) + clctToAlct = cms.untracked.bool(False), + + # For ALCT-centric matching, whether to drop CLCTs that were matched + # to ALCTs in this BX, and not use them in the following BX + tmbDropUsedClcts = cms.untracked.bool(False), + + # For CLCT-centric matching in ME11, break after finding + # the first BX with matching ALCT + matchEarliestAlctME11Only = cms.untracked.bool(False), + + # For ALCT-centric matching in ME11, break after finding + # the first BX with matching CLCT + matchEarliestClctME11Only = cms.untracked.bool(False), + + # 0 = default "non-X-BX" sorting algorithm, + # where the first BX with match goes first + # 1 = simple X-BX sorting algorithm, + # where the central match BX goes first, + # then the closest early, the slocest late, etc. + tmbCrossBxAlgorithm = cms.untracked.uint32(1), + + # How many maximum LCTs per whole chamber per BX to keep + # (supposedly, 1b and 1a can have max 2 each) + maxME11LCTs = cms.untracked.uint32(2) + ), + + # MPC sorter config for SLHC studies + mpcSLHC = cms.PSet( + mpcMaxStubs = cms.untracked.uint32(3) + ) +) diff --git a/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS3_cfi.py b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS3_cfi.py new file mode 100644 index 0000000000000..b970cab603799 --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/python/cscTriggerPrimitiveDigisPostLS3_cfi.py @@ -0,0 +1,327 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.CSCCommonTrigger.CSCCommonTrigger_cfi import * +# Default parameters for CSCTriggerPrimitives generator +# ===================================================== +cscTriggerPrimitiveDigisPostLS1 = cms.EDProducer("CSCTriggerPrimitivesProducer", + CSCCommonTrigger, + + # if False, parameters will be read in from DB using EventSetup mechanism + # else will use parameters from this config + debugParameters = cms.untracked.bool(True), + + # Name of digi producer module(s) + CSCComparatorDigiProducer = cms.InputTag("simMuonCSCDigis","MuonCSCComparatorDigi"), + CSCWireDigiProducer = cms.InputTag("simMuonCSCDigis","MuonCSCWireDigi"), + + # for SLHC studies we don't want bad chambers checks so far + checkBadChambers_ = cms.untracked.bool(False), + + # Parameters common for all boards + commonParam = cms.PSet( + isTMB07 = cms.bool(True), + isMTCC = cms.bool(False), + + # Flag for SLHC studies (upgraded ME11, MPC) + # (if true, isTMB07 should be true as well) + isSLHC = cms.untracked.bool(True), + + # ME1a configuration: + # smartME1aME1b=f, gangedME1a=t + # default logic for current HW + # smartME1aME1b=t, gangedME1a=f + # realistic upgrade scenario: + # one ALCT finder and two CLCT finders per ME11 + # with additional logic for A/CLCT matching with ME1a unganged + # smartME1aME1b=t, gangedME1a=t + # the previous case with ME1a still being ganged + # Note: gangedME1a has effect only if smartME1aME1b=t + smartME1aME1b = cms.untracked.bool(True), + gangedME1a = cms.untracked.bool(False), + + # flagis to optionally disable finding stubs in ME42 or ME1a + disableME1a = cms.untracked.bool(False), + disableME42 = cms.untracked.bool(False) + ), + + # Parameters for ALCT processors: old MC studies + alctParamOldMC = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(3), + alctNplanesHitPretrig = cms.uint32(2), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(2), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(3), + alctAccelMode = cms.uint32(1), + alctL1aWindowWidth = cms.uint32(5), + verbosity = cms.untracked.int32(0) + ), + + # Parameters for ALCT processors: MTCC-II + alctParamMTCC = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(3), + alctNplanesHitPretrig = cms.uint32(2), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(2), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(2), + alctAccelMode = cms.uint32(0), + alctL1aWindowWidth = cms.uint32(3), + verbosity = cms.untracked.int32(0) + ), + + # Parameters for ALCT processors: 2007 and later + alctParam07 = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(2), + alctNplanesHitPretrig = cms.uint32(3), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(3), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(2), + alctAccelMode = cms.uint32(0), + alctL1aWindowWidth = cms.uint32(7), + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + alctEarlyTbins = cms.untracked.int32(4), + + # Use narrow pattern mask for ring 1 chambers + alctNarrowMaskForR1 = cms.untracked.bool(True), + + # configured, not hardcoded, hit persistency + alctHitPersist = cms.untracked.uint32(6), + + # configure, not hardcode, up to how many BXs in the past + # ghost cancellation in neighboring WGs may happen + alctGhostCancellationBxDepth = cms.untracked.int32(1), + + # whether to compare the quality of stubs in neighboring WGs in the past + # to the quality of a stub in current WG + # when doing ghost cancellation + alctGhostCancellationSideQuality = cms.untracked.bool(True), + + # how soon after pretrigger and alctDriftDelay can next pretrigger happen? + alctPretrigDeadtime = cms.untracked.uint32(4) + ), + + # Parameters for ALCT processors: SLHC studies + alctSLHC = cms.PSet( + alctFifoTbins = cms.uint32(16), + alctFifoPretrig = cms.uint32(10), + alctDriftDelay = cms.uint32(2), + alctNplanesHitPretrig = cms.uint32(3), + alctNplanesHitPattern = cms.uint32(4), + alctNplanesHitAccelPretrig = cms.uint32(3), + alctNplanesHitAccelPattern = cms.uint32(4), + alctTrigMode = cms.uint32(2), + alctAccelMode = cms.uint32(0), + alctL1aWindowWidth = cms.uint32(7), + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + alctEarlyTbins = cms.untracked.int32(4), + + # Use narrow pattern mask for ring 1 chambers + alctNarrowMaskForR1 = cms.untracked.bool(True), + + # configured, not hardcoded, hit persistency + alctHitPersist = cms.untracked.uint32(6), + + # configure, not hardcode, up to how many BXs in the past + # ghost cancellation in neighboring WGs may happen + alctGhostCancellationBxDepth = cms.untracked.int32(1), + + # whether to compare the quality of stubs in neighboring WGs in the past + # to the quality of a stub in current WG + # when doing ghost cancellation + alctGhostCancellationSideQuality = cms.untracked.bool(True), + + # how soon after pretrigger and alctDriftDelay can next pretrigger happen? + alctPretrigDeadtime = cms.untracked.uint32(0), + + # SLHC only for ME11: + # whether to store the "corrected" ALCT stub time + # (currently it is median time of particular hits in a pattern) into the ASCCLCTDigi bx, + # and temporary store the regular "key layer hit" time into the CSCCLCTDigi fullBX: + alctUseCorrectedBx = cms.untracked.bool(True) + ), + + # Parameters for CLCT processors: old MC studies + clctParamOldMC = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(6), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(2), + clctNplanesHitPattern = cms.uint32(4), + clctPidThreshPretrig = cms.uint32(2), + clctMinSeparation = cms.uint32(10), + # Debug + verbosity = cms.untracked.int32(0) + ), + + # Parameters for CLCT processors: MTCC-II + clctParamMTCC = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(6), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(4), + clctNplanesHitPattern = cms.uint32(1), + clctPidThreshPretrig = cms.uint32(2), + clctMinSeparation = cms.uint32(10), + # Debug + verbosity = cms.untracked.int32(0) + ), + + # Parameters for CLCT processors: 2007 and later + clctParam07 = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(4), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(3), + clctNplanesHitPattern = cms.uint32(4), + # increase pattern ID threshold from 2 to 4 to trigger higher pt tracks + clctPidThreshPretrig = cms.uint32(4), + # decrease possible minimal #HS distance between two CLCTs in a BX from 10 to 5: + clctMinSeparation = cms.uint32(5), + # Debug + verbosity = cms.untracked.int32(0), + + # BX to start CLCT finding (poor man's dead-time shortening): + clctStartBxShift = cms.untracked.int32(0) + ), + + # Parameters for CLCT processors: SLHC studies + clctSLHC = cms.PSet( + clctFifoTbins = cms.uint32(12), + clctFifoPretrig = cms.uint32(7), + clctHitPersist = cms.uint32(4), + clctDriftDelay = cms.uint32(2), + clctNplanesHitPretrig = cms.uint32(3), + clctNplanesHitPattern = cms.uint32(4), + # increase pattern ID threshold from 2 to 4 to trigger higher pt tracks + clctPidThreshPretrig = cms.uint32(4), + # decrease possible minimal #HS distance between two CLCTs in a BX from 10 to 5: + clctMinSeparation = cms.uint32(5), + # Debug + verbosity = cms.untracked.int32(0), + + # BX to start CLCT finding (poor man's to shorten the dead-time): + clctStartBxShift = cms.untracked.int32(0), + + # Turns on algorithms of localized dead-time zones: + useDeadTimeZoning = cms.untracked.bool(True), + + # Width (in #HS) of a fixed dead zone around a key HS: + clctStateMachineZone = cms.untracked.uint32(8), + + # Enables the algo which instead of using the fixed dead zone width, + # varies it depending on the width of a triggered CLCT pattern + # (if True, the clctStateMachineZone is ignored): + useDynamicStateMachineZone = cms.untracked.bool(True), + + # Pretrigger HS +- clctPretriggerTriggerZone sets the trigger matching zone + # which defines how far from pretrigger HS the TMB may look for a trigger HS + # (it becomes important to do so with localized dead-time zoning): + clctPretriggerTriggerZone = cms.untracked.uint32(5), + + # whether to store the "corrected" CLCT stub time + # (currently it is median time of all hits in a pattern) into the CSCCLCTDigi bx, + # and temporary store the regular "key layer hit" time into the CSCCLCTDigi fullBX: + clctUseCorrectedBx = cms.untracked.bool(True) + ), + + tmbParam = cms.PSet( + mpcBlockMe1a = cms.uint32(0), + alctTrigEnable = cms.uint32(0), + clctTrigEnable = cms.uint32(0), + matchTrigEnable = cms.uint32(1), + # reduce ALCT-CLCT matching window size from 7 to 3 + matchTrigWindowSize = cms.uint32(3), + tmbL1aWindowSize = cms.uint32(7), + # Debug + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + tmbEarlyTbins = cms.untracked.int32(4), + + # Flag for whether to readout only the earliest max two LCTs in a + # L1A readout window, as there is only room just for two in the TMB header. + # If false, all LCTs would be readout in L1A window. + tmbReadoutEarliest2 = cms.untracked.bool(True), + + # For CLCT-centric matching, whether to drop ALCTs that were matched + # to CLCTs in this BX, and not use them in the following BX + # (default non-upgrade TMB behavior). + tmbDropUsedAlcts = cms.untracked.bool(True) + ), + + # to be used by ME11 chambers with upgraded TMB and ALCT + tmbSLHC = cms.PSet( + mpcBlockMe1a = cms.uint32(0), + alctTrigEnable = cms.uint32(0), + clctTrigEnable = cms.uint32(0), + matchTrigEnable = cms.uint32(1), + # reduce ALCT-CLCT matching window size from 7 to 3 + matchTrigWindowSize = cms.uint32(3), + tmbL1aWindowSize = cms.uint32(7), + # Debug + verbosity = cms.untracked.int32(0), + + # Configure early_tbins instead of hardcoding it + tmbEarlyTbins = cms.untracked.int32(4), + + # Flag for whether to readout only the earliest max two LCTs in a + # L1A readout window, as there is only room just for two in the TMB header. + # If false, all LCTs would be readout in L1A window. + tmbReadoutEarliest2 = cms.untracked.bool(False), + + # For CLCT-centric matching, whether to drop ALCTs that were matched + # to CLCTs in this BX, and not use them in the following BX + # (default non-upgrade TMB behavior). + tmbDropUsedAlcts = cms.untracked.bool(False), + + # Switch to enable + # True = CLCT-centric matching (default non-upgrade behavior, + # take CLCTs in BX look for matching ALCTs in window) + # False = ALCT-centric matching (recommended for SLHC, + # take ALCTs in BX look for matching CLCTs in window) + clctToAlct = cms.untracked.bool(False), + + # For ALCT-centric matching, whether to drop CLCTs that were matched + # to ALCTs in this BX, and not use them in the following BX + tmbDropUsedClcts = cms.untracked.bool(False), + + # For CLCT-centric matching in ME11, break after finding + # the first BX with matching ALCT + matchEarliestAlctME11Only = cms.untracked.bool(False), + + # For ALCT-centric matching in ME11, break after finding + # the first BX with matching CLCT + matchEarliestClctME11Only = cms.untracked.bool(False), + + # 0 = default "non-X-BX" sorting algorithm, + # where the first BX with match goes first + # 1 = simple X-BX sorting algorithm, + # where the central match BX goes first, + # then the closest early, the slocest late, etc. + tmbCrossBxAlgorithm = cms.untracked.uint32(1), + + # How many maximum LCTs per whole chamber per BX to keep + # (supposedly, 1b and 1a can have max 2 each) + maxME11LCTs = cms.untracked.uint32(2) + ), + + # MPC sorter config for SLHC studies + mpcSLHC = cms.PSet( + mpcMaxStubs = cms.untracked.uint32(3) + ) +) diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc index 450c32b2202e6..b546e0f6d364d 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc @@ -206,10 +206,10 @@ CSCAnodeLCTProcessor::CSCAnodeLCTProcessor(unsigned endcap, unsigned station, accel_mode = conf.getParameter("alctAccelMode"); l1a_window_width = conf.getParameter("alctL1aWindowWidth"); - hit_persist = conf.getUntrackedParameter("alctHitPersist", 6); + hit_persist = conf.getParameter("alctHitPersist"); // Verbosity level, set to 0 (no print) by default. - infoV = conf.getUntrackedParameter("verbosity", 0); + infoV = conf.getParameter("verbosity"); // Other parameters. // Use open pattern instead of more restrictive (slim) ones. @@ -218,27 +218,27 @@ CSCAnodeLCTProcessor::CSCAnodeLCTProcessor(unsigned endcap, unsigned station, isTMB07 = comm.getParameter("isTMB07"); // Flag for SLHC studies - isSLHC = comm.getUntrackedParameter("isSLHC", false); + isSLHC = comm.getParameter("isSLHC"); // special configuration parameters for ME11 treatment - disableME1a = comm.getUntrackedParameter("disableME1a", false); + disableME1a = comm.getParameter("disableME1a"); // separate handle for early time bins - early_tbins = conf.getUntrackedParameter("alctEarlyTbins",-1); + early_tbins = conf.getParameter("alctEarlyTbins"); int fpga_latency = 6; if (early_tbins<0) early_tbins = fifo_pretrig - fpga_latency; // delta BX time depth for ghostCancellationLogic - ghost_cancellation_bx_depth = conf.getUntrackedParameter("alctGhostCancellationBxDepth", 4); + ghost_cancellation_bx_depth = conf.getParameter("alctGhostCancellationBxDepth"); // whether to consider ALCT candidates' qualities while doing ghostCancellationLogic on +-1 wire groups - ghost_cancellation_side_quality = conf.getUntrackedParameter("alctGhostCancellationSideQuality", false); + ghost_cancellation_side_quality = conf.getParameter("alctGhostCancellationSideQuality"); // deadtime clocks after pretrigger (extra in addition to drift_delay) - pretrig_extra_deadtime = conf.getUntrackedParameter("alctPretrigDeadtime", 4); + pretrig_extra_deadtime = conf.getParameter("alctPretrigDeadtime"); // whether to use narrow pattern mask for the rings close to the beam - narrow_mask_r1 = conf.getUntrackedParameter("alctNarrowMaskForR1", false); + narrow_mask_r1 = conf.getParameter("alctNarrowMaskForR1"); // Check and print configuration parameters. checkConfigParameters(); @@ -263,9 +263,13 @@ CSCAnodeLCTProcessor::CSCAnodeLCTProcessor(unsigned endcap, unsigned station, // whether to calculate bx as corrected_bx instead of pretrigger one use_corrected_bx = false; if (isSLHC && isME11) { - use_corrected_bx = conf.getUntrackedParameter("alctUseCorrectedBx", false); + use_corrected_bx = conf.getParameter("alctUseCorrectedBx"); } + // run the ALCT processor for the Phase-II ME2/1 integrated local trigger + runME21ILT_ = conf.existsAs("runME21ILT")? + conf.getParameter("runME21ILT"):false; + //if (theStation==1 && theRing==2) infoV = 3; // Load appropriate pattern mask. @@ -967,8 +971,12 @@ bool CSCAnodeLCTProcessor::patternDetection(const int key_wire) { else { // Quality definition changed on 22 June 2007: it no longer depends // on pattern_thresh. - if (temp_quality > 3) temp_quality -= 3; - else temp_quality = 0; // quality code 0 is valid! + int Q; + // hack to run the Phase-II ME2/1, ME3/1 and ME4/1 ILT + if (temp_quality == 3 and runME21ILT_) Q = 4; + else if (temp_quality > 3) Q = temp_quality - 3; + else Q = 0; // quality code 0 is valid! + temp_quality = Q; } if (i_pattern == 0) { @@ -1115,6 +1123,7 @@ void CSCAnodeLCTProcessor::ghostCancellationLogicSLHC() { int qual_this = quality[key_wire][i_pattern]; if (qual_this > 0) { + if (runME21ILT_) qual_this = (qual_this & 0x03); // Previous wire. int dt = -1; int qual_prev = (key_wire > 0) ? quality[key_wire-1][i_pattern] : 0; @@ -1123,6 +1132,9 @@ void CSCAnodeLCTProcessor::ghostCancellationLogicSLHC() { dt = first_bx_corrected[key_wire] - first_bx_corrected[key_wire-1]; 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 (runME21ILT_) qual_prev = (qual_prev & 0x03); + // Cancel this wire // 1) If the candidate at the previous wire is at the same bx // clock and has better quality (or equal? quality - this has @@ -1162,6 +1174,9 @@ void CSCAnodeLCTProcessor::ghostCancellationLogicSLHC() { dt = first_bx_corrected[key_wire] - first_bx_corrected[key_wire+1]; 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 (runME21ILT_) + qual_next = (qual_next & 0x03); // Same cancellation logic as for the previous wire. if (dt == 0) { if (qual_next >= qual_this) ghost_cleared[key_wire][i_pattern] = 1; diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.h b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.h index 85bad7dd0c84c..681a13d3d1591 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.h +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.h @@ -153,6 +153,9 @@ class CSCAnodeLCTProcessor /** SLHC: whether to use narrow pattern mask for the rings close to the beam */ bool narrow_mask_r1; + /** SLHC: run the ALCT processor for the Phase-II ME2/1 integrated local trigger */ + bool runME21ILT_; + /** Default values of configuration parameters. */ static const unsigned int def_fifo_tbins, def_fifo_pretrig; static const unsigned int def_drift_delay; diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc index 7f3b2f3f7498a..72806e99e9765 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc @@ -265,12 +265,12 @@ CSCCathodeLCTProcessor::CSCCathodeLCTProcessor(unsigned endcap, isTMB07 = comm.getParameter("isTMB07"); // Flag for SLHC studies - isSLHC = comm.getUntrackedParameter("isSLHC",false); + isSLHC = comm.getParameter("isSLHC"); // special configuration parameters for ME11 treatment - smartME1aME1b = comm.getUntrackedParameter("smartME1aME1b",false); - disableME1a = comm.getUntrackedParameter("disableME1a",false); - gangedME1a = comm.getUntrackedParameter("gangedME1a",true); + smartME1aME1b = comm.getParameter("smartME1aME1b"); + disableME1a = comm.getParameter("disableME1a"); + gangedME1a = comm.getParameter("gangedME1a"); if (isSLHC && !smartME1aME1b) edm::LogError("L1CSCTPEmulatorConfigError") << "+++ SLHC upgrade configuration is used (isSLHC=True) but smartME1aME1b=False!\n" @@ -282,24 +282,24 @@ CSCCathodeLCTProcessor::CSCCathodeLCTProcessor(unsigned endcap, min_separation = conf.getParameter("clctMinSeparation"); - start_bx_shift = conf.getUntrackedParameter("clctStartBxShift",0); + start_bx_shift = conf.getParameter("clctStartBxShift"); } if (smartME1aME1b) { // use of localized dead-time zones use_dead_time_zoning = - conf.getUntrackedParameter("useDeadTimeZoning",true); + conf.getParameter("useDeadTimeZoning"); clct_state_machine_zone = - conf.getUntrackedParameter("clctStateMachineZone",8); + conf.getParameter("clctStateMachineZone"); dynamic_state_machine_zone = - conf.getUntrackedParameter("useDynamicStateMachineZone",true); + conf.getParameter("useDynamicStateMachineZone"); // how far away may trigger happen from pretrigger pretrig_trig_zone = - conf.getUntrackedParameter("clctPretriggerTriggerZone",5); + conf.getParameter("clctPretriggerTriggerZone"); // whether to calculate bx as corrected_bx instead of pretrigger one - use_corrected_bx = conf.getUntrackedParameter("clctUseCorrectedBx",false); + use_corrected_bx = conf.getParameter("clctUseCorrectedBx"); } // Motherboard parameters: common for all configurations. @@ -307,15 +307,15 @@ CSCCathodeLCTProcessor::CSCCathodeLCTProcessor(unsigned endcap, ctmb.getParameter("tmbL1aWindowSize"); // separate handle for early time bins - early_tbins = ctmb.getUntrackedParameter("tmbEarlyTbins",-1); + early_tbins = ctmb.getParameter("tmbEarlyTbins"); static int fpga_latency = 3; if (early_tbins<0) early_tbins = fifo_pretrig - fpga_latency; // wether to readout only the earliest two LCTs in readout window - readout_earliest_2 = ctmb.getUntrackedParameter("tmbReadoutEarliest2",0); + readout_earliest_2 = ctmb.getParameter("tmbReadoutEarliest2"); // Verbosity level, set to 0 (no print) by default. - infoV = conf.getUntrackedParameter("verbosity", 0); + infoV = conf.getParameter("verbosity"); // Check and print configuration parameters. checkConfigParameters(); diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc index 6ac6860b6ea3c..b608a103a5d15 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc @@ -52,6 +52,9 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, unsigned station, const edm::ParameterSet& conf) : theEndcap(endcap), theStation(station), theSector(sector), theSubsector(subsector), theTrigChamber(chamber) { + + theRing = CSCTriggerNumbering::ringFromTriggerLabels(theStation, theTrigChamber); + // Normal constructor. -JM // Pass ALCT, CLCT, and common parameters on to ALCT and CLCT processors. static bool config_dumped = false; @@ -68,7 +71,7 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, unsigned station, isTMB07 = commonParams.getParameter("isTMB07"); // is it (non-upgrade algorithm) run along with upgrade one? - isSLHC = commonParams.getUntrackedParameter("isSLHC"); + isSLHC = commonParams.getParameter("isSLHC"); // Choose the appropriate set of configuration parameters depending on // isTMB07 and isMTCC flags. @@ -90,12 +93,31 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, unsigned station, // Motherboard parameters: edm::ParameterSet tmbParams = conf.getParameter("tmbParam"); - - if (isSLHC && theStation == 1 && - CSCTriggerNumbering::ringFromTriggerLabels(theStation, theTrigChamber) == 1 ) { - alctParams = conf.getParameter("alctSLHC"); - clctParams = conf.getParameter("clctSLHC"); - tmbParams = conf.getParameter("tmbSLHC"); + const edm::ParameterSet me11tmbGemParams(conf.existsAs("me11tmbSLHCGEM")? + conf.getParameter("me11tmbSLHCGEM"):edm::ParameterSet()); + const edm::ParameterSet me21tmbGemParams(conf.existsAs("me21tmbSLHCGEM")? + conf.getParameter("me21tmbSLHCGEM"):edm::ParameterSet()); + const edm::ParameterSet me3141tmbRpcParams(conf.existsAs("me3141tmbSLHCRPC")? + conf.getParameter("me3141tmbSLHCRPC"):edm::ParameterSet()); + + const bool runME11ILT(commonParams.existsAs("runME11ILT")?commonParams.getParameter("runME11ILT"):false); + const bool runME21ILT(commonParams.existsAs("runME21ILT")?commonParams.getParameter("runME21ILT"):false); + + // run upgrade TMBs for all MEX/1 stations + if (isSLHC and theRing == 1){ + if (theStation == 1) { + tmbParams = conf.getParameter("tmbSLHC"); + alctParams = conf.getParameter("alctSLHC"); + clctParams = conf.getParameter("clctSLHC"); + if (runME11ILT) { + tmbParams = me11tmbGemParams; + } + } + else if (theStation == 2 and runME21ILT) { + tmbParams = me21tmbGemParams; + alctParams = conf.getParameter("alctSLHCME21"); + clctParams = conf.getParameter("clctSLHCME21"); + } } mpc_block_me1a = tmbParams.getParameter("mpcBlockMe1a"); @@ -107,16 +129,18 @@ CSCMotherboard::CSCMotherboard(unsigned endcap, unsigned station, tmb_l1a_window_size = // Common to CLCT and TMB tmbParams.getParameter("tmbL1aWindowSize"); + lct_central_bx = 6; + // configuration handle for number of early time bins - early_tbins = tmbParams.getUntrackedParameter("tmbEarlyTbins",4); + early_tbins = tmbParams.getParameter("tmbEarlyTbins"); // whether to not reuse ALCTs that were used by previous matching CLCTs - drop_used_alcts = tmbParams.getUntrackedParameter("tmbDropUsedAlcts",true); + drop_used_alcts = tmbParams.getParameter("tmbDropUsedAlcts"); // whether to readout only the earliest two LCTs in readout window - readout_earliest_2 = tmbParams.getUntrackedParameter("tmbReadoutEarliest2",false); + readout_earliest_2 = tmbParams.getParameter("tmbReadoutEarliest2"); - infoV = tmbParams.getUntrackedParameter("verbosity", 0); + infoV = tmbParams.getParameter("verbosity"); alct = new CSCAnodeLCTProcessor(endcap, station, sector, subsector, chamber, alctParams, commonParams); clct = new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, tmbParams); @@ -810,3 +834,17 @@ void CSCMotherboard::dumpConfigParams() const { LogDebug("CSCMotherboard") << strm.str(); //std::cerr << strm.str()< lct2.getQuality(); +} + +// compare LCTs by GEM bending angle +bool CSCMotherboard::sortByGEMDphi(const CSCCorrelatedLCTDigi& lct1, const CSCCorrelatedLCTDigi& lct2) +{ + // return lct1.getGEMDPhi() < lct2.getGEMDPhi(); + return true; +} diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.h b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.h index 7bffe57f53ef6..76fcf00d9ef2a 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.h +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.h @@ -93,6 +93,7 @@ class CSCMotherboard const unsigned theSector; const unsigned theSubsector; const unsigned theTrigChamber; + unsigned theRing; /** Flag for MTCC data. */ bool isMTCC; @@ -108,6 +109,9 @@ class CSCMotherboard unsigned int alct_trig_enable, clct_trig_enable, match_trig_enable; unsigned int match_trig_window_size, tmb_l1a_window_size; + /** Central BX */ + int lct_central_bx; + /** SLHC: whether to not reuse ALCTs that were used by previous matching CLCTs */ bool drop_used_alcts; @@ -147,5 +151,9 @@ class CSCMotherboard // Method for tests void testLCT(); + + // utilities for sorting + static bool sortByQuality(const CSCCorrelatedLCTDigi&, const CSCCorrelatedLCTDigi&); + static bool sortByGEMDphi(const CSCCorrelatedLCTDigi&, const CSCCorrelatedLCTDigi&); }; #endif diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc index f4621bfd435af..c2ed3147ca152 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.cc @@ -69,9 +69,9 @@ CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, unsigned station, edm::ParameterSet commonParams = conf.getParameter("commonParam"); // special configuration parameters for ME11 treatment - smartME1aME1b = commonParams.getUntrackedParameter("smartME1aME1b", true); - disableME1a = commonParams.getUntrackedParameter("disableME1a", false); - gangedME1a = commonParams.getUntrackedParameter("gangedME1a", false); + smartME1aME1b = commonParams.getParameter("smartME1aME1b"); + disableME1a = commonParams.getParameter("disableME1a"); + gangedME1a = commonParams.getParameter("gangedME1a"); if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError") << "+++ Upgrade CSCMotherboardME11 constructed while isSLHC is not set! +++\n"; @@ -85,21 +85,21 @@ CSCMotherboardME11::CSCMotherboardME11(unsigned endcap, unsigned station, clct1a = new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, tmbParams); clct1a->setRing(4); - match_earliest_alct_me11_only = tmbParams.getUntrackedParameter("matchEarliestAlctME11Only",true); - match_earliest_clct_me11_only = tmbParams.getUntrackedParameter("matchEarliestClctME11Only",true); + match_earliest_alct_me11_only = tmbParams.getParameter("matchEarliestAlctME11Only"); + match_earliest_clct_me11_only = tmbParams.getParameter("matchEarliestClctME11Only"); // if true: use regular CLCT-to-ALCT matching in TMB // if false: do ALCT-to-CLCT matching - clct_to_alct = tmbParams.getUntrackedParameter("clctToAlct",true); + clct_to_alct = tmbParams.getParameter("clctToAlct"); // whether to not reuse CLCTs that were used by previous matching ALCTs // in ALCT-to-CLCT algorithm - drop_used_clcts = tmbParams.getUntrackedParameter("tmbDropUsedClcts",true); + drop_used_clcts = tmbParams.getParameter("tmbDropUsedClcts"); - tmb_cross_bx_algo = tmbParams.getUntrackedParameter("tmbCrossBxAlgorithm"); + tmb_cross_bx_algo = tmbParams.getParameter("tmbCrossBxAlgorithm"); // maximum lcts per BX in ME11: 2, 3, 4 or 999 - max_me11_lcts = tmbParams.getUntrackedParameter("maxME11LCTs",4); + max_me11_lcts = tmbParams.getParameter("maxME11LCTs"); pref[0] = match_trig_window_size/2; for (unsigned int m=2; m +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "boost/container/flat_set.hpp" + +// LUT for which ME1/1 wire group can cross which ME1/a halfstrip +// 1st index: WG number +// 2nd index: inclusive HS range +const int CSCMotherboardME11GEM::lut_wg_vs_hs_me1a[48][2] = { +{0, 95},{0, 95},{0, 95},{0, 95},{0, 95}, +{0, 95},{0, 95},{0, 95},{0, 95},{0, 95}, +{0, 95},{0, 95},{0, 77},{0, 61},{0, 39}, +{0, 22},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1} }; +// a modified LUT for ganged ME1a +const int CSCMotherboardME11GEM::lut_wg_vs_hs_me1ag[48][2] = { +{0, 31},{0, 31},{0, 31},{0, 31},{0, 31}, +{0, 31},{0, 31},{0, 31},{0, 31},{0, 31}, +{0, 31},{0, 31},{0, 31},{0, 31},{0, 31}, +{0, 22},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1} }; + +// LUT for which ME1/1 wire group can cross which ME1/b halfstrip +// 1st index: WG number +// 2nd index: inclusive HS range +const int CSCMotherboardME11GEM::lut_wg_vs_hs_me1b[48][2] = { +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}, +{100, 127},{73, 127},{47, 127},{22, 127},{0, 127}, +{0, 127},{0, 127},{0, 127},{0, 127},{0, 127}, +{0, 127},{0, 127},{0, 127},{0, 127},{0, 127}, +{0, 127},{0, 127},{0, 127},{0, 127},{0, 127}, +{0, 127},{0, 127},{0, 127},{0, 127},{0, 127}, +{0, 127},{0, 127},{0, 127},{0, 127},{0, 127}, +{0, 127},{0, 127},{0, 127},{0, 127},{0, 105}, +{0, 93},{0, 78},{0, 63} }; + +// LUT with bending angles of the GEM-CSC high efficiency patterns (98%) +// 1st index: pt value = {5,10,15,20,30,40} +// 2nd index: bending angle for odd numbered chambers +// 3rd index: bending angle for even numbered chambers +/* +const double CSCMotherboardME11GEM::lut_pt_vs_dphi_gemcsc[7][3] = { + {5., 0.02203511, 0.00930056}, + {6 , 0.0182579 , 0.00790009}, + {10., 0.01066000, 0.00483286}, + {15., 0.00722795, 0.00363230}, + {20., 0.00562598, 0.00304878}, + {30., 0.00416544, 0.00253782}, + {40., 0.00342827, 0.00230833} }; +*/ + +const double CSCMotherboardME11GEM::lut_pt_vs_dphi_gemcsc[8][3] = { + {3, 0.03971647, 0.01710244}, + {5, 0.02123785, 0.00928431}, + {7, 0.01475524, 0.00650928}, + {10, 0.01023299, 0.00458796}, + {15, 0.00689220, 0.00331313}, + {20, 0.00535176, 0.00276152}, + {30, 0.00389050, 0.00224959}, + {40, 0.00329539, 0.00204670}}; + +const double CSCMotherboardME11GEM::lut_wg_etaMin_etaMax_odd[48][3] = { +{0, 2.44005, 2.44688}, +{1, 2.38863, 2.45035}, +{2, 2.32742, 2.43077}, +{3, 2.30064, 2.40389}, +{4, 2.2746, 2.37775}, +{5, 2.24925, 2.35231}, +{6, 2.22458, 2.32754}, +{7, 2.20054, 2.30339}, +{8, 2.1771, 2.27985}, +{9, 2.15425, 2.25689}, +{10, 2.13194, 2.23447}, +{11, 2.11016, 2.21258}, +{12, 2.08889, 2.19119}, +{13, 2.06809, 2.17028}, +{14, 2.04777, 2.14984}, +{15, 2.02788, 2.12983}, +{16, 2.00843, 2.11025}, +{17, 1.98938, 2.09108}, +{18, 1.97073, 2.0723}, +{19, 1.95246, 2.0539}, +{20, 1.93456, 2.03587}, +{21, 1.91701, 2.01818}, +{22, 1.8998, 2.00084}, +{23, 1.88293, 1.98382}, +{24, 1.86637, 1.96712}, +{25, 1.85012, 1.95073}, +{26, 1.83417, 1.93463}, +{27, 1.8185, 1.91882}, +{28, 1.80312, 1.90329}, +{29, 1.788, 1.88803}, +{30, 1.77315, 1.87302}, +{31, 1.75855, 1.85827}, +{32, 1.74421, 1.84377}, +{33, 1.7301, 1.8295}, +{34, 1.71622, 1.81547}, +{35, 1.70257, 1.80166}, +{36, 1.68914, 1.78807}, +{37, 1.67592, 1.77469}, +{38, 1.66292, 1.76151}, +{39, 1.65011, 1.74854}, +{40, 1.63751, 1.73577}, +{41, 1.62509, 1.72319}, +{42, 1.61287, 1.71079}, +{43, 1.60082, 1.69857}, +{44, 1.59924, 1.68654}, +{45, 1.6006, 1.67467}, +{46, 1.60151, 1.66297}, +{47, 1.60198, 1.65144} }; + +const double CSCMotherboardME11GEM::lut_wg_etaMin_etaMax_even[48][3] = { +{0, 2.3917, 2.39853}, +{1, 2.34037, 2.40199}, +{2, 2.27928, 2.38244}, +{3, 2.25254, 2.35561}, +{4, 2.22655, 2.32951}, +{5, 2.20127, 2.30412}, +{6, 2.17665, 2.27939}, +{7, 2.15267, 2.25529}, +{8, 2.12929, 2.2318}, +{9, 2.1065, 2.20889}, +{10, 2.08425, 2.18652}, +{11, 2.06253, 2.16468}, +{12, 2.04132, 2.14334}, +{13, 2.0206, 2.12249}, +{14, 2.00033, 2.1021}, +{15, 1.98052, 2.08215}, +{16, 1.96113, 2.06262}, +{17, 1.94215, 2.04351}, +{18, 1.92357, 2.02479}, +{19, 1.90538, 2.00645}, +{20, 1.88755, 1.98847}, +{21, 1.87007, 1.97085}, +{22, 1.85294, 1.95357}, +{23, 1.83614, 1.93662}, +{24, 1.81965, 1.91998}, +{25, 1.80348, 1.90365}, +{26, 1.78761, 1.88762}, +{27, 1.77202, 1.87187}, +{28, 1.75672, 1.85641}, +{29, 1.74168, 1.84121}, +{30, 1.72691, 1.82628}, +{31, 1.7124, 1.8116}, +{32, 1.69813, 1.79716}, +{33, 1.68411, 1.78297}, +{34, 1.67032, 1.769}, +{35, 1.65675, 1.75526}, +{36, 1.64341, 1.74174}, +{37, 1.63028, 1.72844}, +{38, 1.61736, 1.71534}, +{39, 1.60465, 1.70245}, +{40, 1.59213, 1.68975}, +{41, 1.57981, 1.67724}, +{42, 1.56767, 1.66492}, +{43, 1.55572, 1.65278}, +{44, 1.55414, 1.64082}, +{45, 1.55549, 1.62903}, +{46, 1.5564, 1.61742}, +{47, 1.55686, 1.60596} }; + +CSCMotherboardME11GEM::CSCMotherboardME11GEM(unsigned endcap, unsigned station, + unsigned sector, unsigned subsector, + unsigned chamber, + const edm::ParameterSet& conf) : + CSCMotherboard(endcap, station, sector, subsector, chamber, conf) +{ + const edm::ParameterSet commonParams(conf.getParameter("commonParam")); + + // special configuration parameters for ME11 treatment + smartME1aME1b = commonParams.getParameter("smartME1aME1b"); + disableME1a = commonParams.getParameter("disableME1a"); + gangedME1a = commonParams.getParameter("gangedME1a"); + runME11ILT_ = commonParams.getParameter("runME11ILT"); + + if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError") + << "+++ Upgrade CSCMotherboardME11GEM constructed while isSLHC is not set! +++\n"; + if (!smartME1aME1b) edm::LogError("L1CSCTPEmulatorConfigError") + << "+++ Upgrade CSCMotherboardME11GEM constructed while smartME1aME1b is not set! +++\n"; + + const edm::ParameterSet alctParams(conf.getParameter("alctSLHC")); + const edm::ParameterSet clctParams(conf.getParameter("clctSLHC")); + const edm::ParameterSet me11tmbParams(conf.getParameter("me11tmbSLHCGEM")); + + clct1a = new CSCCathodeLCTProcessor(endcap, station, sector, subsector, chamber, clctParams, commonParams, me11tmbParams); + clct1a->setRing(4); + + match_earliest_alct_me11_only = me11tmbParams.getParameter("matchEarliestAlctME11Only"); + match_earliest_clct_me11_only = me11tmbParams.getParameter("matchEarliestClctME11Only"); + + // if true: use regular CLCT-to-ALCT matching in TMB + // if false: do ALCT-to-CLCT matching + clct_to_alct = me11tmbParams.getParameter("clctToAlct"); + + // whether to not reuse CLCTs that were used by previous matching ALCTs + // in ALCT-to-CLCT algorithm + drop_used_clcts = me11tmbParams.getParameter("tmbDropUsedClcts"); + + tmb_cross_bx_algo = me11tmbParams.getParameter("tmbCrossBxAlgorithm"); + + // maximum lcts per BX in ME11: 2, 3, 4 or 999 + max_me11_lcts = me11tmbParams.getParameter("maxME11LCTs"); + + pref[0] = match_trig_window_size/2; + for (unsigned int m=2; m("doGemMatching"); + + /// GEM matching dphi and deta + gem_match_delta_phi_odd = me11tmbParams.getParameter("gemMatchDeltaPhiOdd"); + gem_match_delta_phi_even = me11tmbParams.getParameter("gemMatchDeltaPhiEven"); + gem_match_delta_eta = me11tmbParams.getParameter("gemMatchDeltaEta"); + + /// delta BX for GEM pads matching + gem_match_delta_bx = me11tmbParams.getParameter("gemMatchDeltaBX"); + + /// min eta of LCT for which we require GEM match (we don't throw out LCTs below this min eta) + gem_match_min_eta = me11tmbParams.getParameter("gemMatchMinEta"); + gem_match_max_eta = me11tmbParams.getParameter("gemMatchMaxEta"); + + /// whether to throw out GEM-fiducial LCTs that have no gem match + gem_clear_nomatch_lcts = me11tmbParams.getParameter("gemClearNomatchLCTs"); + + // debug gem matching + debug_gem_matching = me11tmbParams.getParameter("debugMatching"); + debug_luts = me11tmbParams.getParameter("debugLUTs"); + debug_gem_dphi = me11tmbParams.getParameter("debugGEMDphi"); + + // deltas used to construct GEM coincidence pads + maxDeltaBXInCoPad_ = me11tmbParams.getParameter("maxDeltaBXInCoPad"); + maxDeltaPadInCoPad_ = me11tmbParams.getParameter("maxDeltaPadInCoPad"); + + // deltas used to match to GEM pads + maxDeltaBXPadEven_ = me11tmbParams.getParameter("maxDeltaBXPadEven"); + maxDeltaPadPadEven_ = me11tmbParams.getParameter("maxDeltaPadPadEven"); + maxDeltaBXPadOdd_ = me11tmbParams.getParameter("maxDeltaBXPadOdd"); + maxDeltaPadPadOdd_ = me11tmbParams.getParameter("maxDeltaPadPadOdd"); + + // deltas used to match to GEM coincidence pads + maxDeltaBXCoPadEven_ = me11tmbParams.getParameter("maxDeltaBXCoPadEven"); + maxDeltaPadCoPadEven_ = me11tmbParams.getParameter("maxDeltaPadCoPadEven"); + maxDeltaBXCoPadOdd_ = me11tmbParams.getParameter("maxDeltaBXCoPadOdd"); + maxDeltaPadCoPadOdd_ = me11tmbParams.getParameter("maxDeltaPadCoPadOdd"); + + // drop low quality stubs if they don't have GEMs + dropLowQualityCLCTsNoGEMs_ME1a_ = me11tmbParams.getParameter("dropLowQualityCLCTsNoGEMs_ME1a"); + dropLowQualityCLCTsNoGEMs_ME1b_ = me11tmbParams.getParameter("dropLowQualityCLCTsNoGEMs_ME1b"); + dropLowQualityALCTsNoGEMs_ME1a_ = me11tmbParams.getParameter("dropLowQualityALCTsNoGEMs_ME1a"); + dropLowQualityALCTsNoGEMs_ME1b_ = me11tmbParams.getParameter("dropLowQualityALCTsNoGEMs_ME1b"); + + // build LCT from ALCT and GEM + buildLCTfromALCTandGEM_ME1a_ = me11tmbParams.getParameter("buildLCTfromALCTandGEM_ME1a"); + buildLCTfromALCTandGEM_ME1b_ = me11tmbParams.getParameter("buildLCTfromALCTandGEM_ME1b"); + buildLCTfromCLCTandGEM_ME1a_ = me11tmbParams.getParameter("buildLCTfromCLCTandGEM_ME1a"); + buildLCTfromCLCTandGEM_ME1b_ = me11tmbParams.getParameter("buildLCTfromCLCTandGEM_ME1b"); + + // LCT ghostbusting + doLCTGhostBustingWithGEMs_ = me11tmbParams.getParameter("doLCTGhostBustingWithGEMs"); + + // correct LCT timing with GEMs + correctLCTtimingWithGEM_ = me11tmbParams.getParameter("correctLCTtimingWithGEM"); + + // use "old" or "new" dataformat for integrated LCTs? + useOldLCTDataFormatALCTGEM_ = me11tmbParams.getParameter("useOldLCTDataFormatALCTGEM"); + useOldLCTDataFormatCLCTGEM_ = me11tmbParams.getParameter("useOldLCTDataFormatCLCTGEM"); + + // promote ALCT-GEM pattern + promoteALCTGEMpattern_ = me11tmbParams.getParameter("promoteALCTGEMpattern"); + + // promote ALCT-GEM quality + promoteALCTGEMquality_ = me11tmbParams.getParameter("promoteALCTGEMquality"); + promoteCLCTGEMquality_ME1a_ = me11tmbParams.getParameter("promoteCLCTGEMquality_ME1a"); + promoteCLCTGEMquality_ME1b_ = me11tmbParams.getParameter("promoteCLCTGEMquality_ME1b"); + + // send first 2 LCTs + firstTwoLCTsInChamber_ = me11tmbParams.getParameter("firstTwoLCTsInChamber"); +} + + +CSCMotherboardME11GEM::CSCMotherboardME11GEM() : CSCMotherboard() +{ + // Constructor used only for testing. + + clct1a = new CSCCathodeLCTProcessor(); + clct1a->setRing(4); + + pref[0] = match_trig_window_size/2; + for (unsigned int m=2; mclear(); + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + { + //firstLCT1a[bx].clear(); + //secondLCT1a[bx].clear(); + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + allLCTs1b[bx][mbx][i].clear(); + allLCTs1a[bx][mbx][i].clear(); + } + } + gemRollToEtaLimits_.clear(); + cscWgToGemRoll_.clear(); + + gemPadToCscHsME1a_.clear(); + gemPadToCscHsME1b_.clear(); + + cscHsToGemPadME1a_.clear(); + cscHsToGemPadME1b_.clear(); + + pads_.clear(); + coPads_.clear(); +} + +// Set configuration parameters obtained via EventSetup mechanism. +void CSCMotherboardME11GEM::setConfigParameters(const CSCDBL1TPParameters* conf) +{ + alct->setConfigParameters(conf); + clct->setConfigParameters(conf); + clct1a->setConfigParameters(conf); + // No config. parameters in DB for the TMB itself yet. +} + + +void CSCMotherboardME11GEM::run(const CSCWireDigiCollection* wiredc, + const CSCComparatorDigiCollection* compdc, + const GEMPadDigiCollection* gemPads) +{ + /* + clear(); + + if (!( alct and clct and clct1a and smartME1aME1b)) + { + if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + return; + } + + alctV = alct->run(wiredc); // run anodeLCT + clctV1b = clct->run(compdc); // run cathodeLCT in ME1/b + clctV1a = clct1a->run(compdc); // run cathodeLCT in ME1/a + + bool gemGeometryAvailable(false); + if (gem_g != nullptr) { + if (infoV >= 0) edm::LogInfo("L1CSCTPEmulatorSetupInfo") + << "+++ run() called for GEM-CSC integrated trigger! +++ \n"; + gemGeometryAvailable = true; + } + + int used_clct_mask[20], used_clct_mask_1a[20]; + for (int b=0;b<20;b++) + used_clct_mask[b] = used_clct_mask_1a[b] = 0; + + // retrieve CSCChamber geometry + CSCTriggerGeomManager* geo_manager(CSCTriggerGeometry::get()); + const CSCChamber* cscChamberME1b(geo_manager->chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber)); + const CSCDetId me1bId(cscChamberME1b->id()); + const CSCDetId me1aId(me1bId.endcap(), 1, 4, me1bId.chamber()); + const CSCChamber* cscChamberME1a(csc_g->chamber(me1aId)); + + if (runME11ILT_){ + + // check for GEM geometry + if (not gemGeometryAvailable){ + if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError") + << "+++ run() called for GEM-CSC integrated trigger without valid GEM geometry! +++ \n"; + return; + } + + // trigger geometry + const CSCLayer* keyLayerME1b(cscChamberME1b->layer(3)); + const CSCLayerGeometry* keyLayerGeometryME1b(keyLayerME1b->geometry()); + const CSCLayer* keyLayerME1a(cscChamberME1a->layer(3)); + const CSCLayerGeometry* keyLayerGeometryME1a(keyLayerME1a->geometry()); + + const bool isEven(me1bId.chamber()%2==0); + const int region((theEndcap == 1) ? 1: -1); + const GEMDetId gem_id(region, 1, theStation, 1, me1bId.chamber(), 0); + const GEMChamber* gemChamber(gem_g->chamber(gem_id)); + + // initialize depending on whether even or odd + maxDeltaBXPad_ = isEven ? maxDeltaBXPadEven_ : maxDeltaBXPadOdd_; + maxDeltaPadPad_ = isEven ? maxDeltaPadPadEven_ : maxDeltaPadPadOdd_; + maxDeltaBXCoPad_ = isEven ? maxDeltaBXCoPadEven_ : maxDeltaBXCoPadOdd_; + maxDeltaPadCoPad_ = isEven ? maxDeltaPadCoPadEven_ : maxDeltaPadCoPadOdd_; + + // LUT > + createGEMRollEtaLUT(isEven); + if (debug_luts){ + std::cout<<"me1b Det "<< me1bId<<" "<< me1bId.rawId() <<" " << (isEven ? "Even":"odd") <<" chamber "<< me1bId.chamber()< + const int numberOfWG(keyLayerGeometryME1b->numberOfWireGroups()); + for (int i = 0; i< numberOfWG; ++i){ + auto etaMin(isEven ? lut_wg_etaMin_etaMax_even[i][1] : lut_wg_etaMin_etaMax_odd[i][1]); + auto etaMax(isEven ? lut_wg_etaMin_etaMax_even[i][2] : lut_wg_etaMin_etaMax_odd[i][2]); + cscWgToGemRoll_[i] = std::make_pair(assignGEMRoll(etaMin), assignGEMRoll(etaMax)); + } + if (debug_luts){ + for(auto p : cscWgToGemRoll_) { + std::cout << "WG "<< p.first << " GEM pads " << (p.second).first << " " << (p.second).second << std::endl; + } + } + + // pick any roll + auto randRoll(gemChamber->etaPartition(2)); + + // ME1a + auto nStripsME1a(keyLayerGeometryME1a->numberOfStrips()); + for (float i = 0; i< nStripsME1a; i = i+0.5){ + const LocalPoint lpCSC(keyLayerGeometryME1a->topology()->localPosition(i)); + const GlobalPoint gp(keyLayerME1a->toGlobal(lpCSC)); + const LocalPoint lpGEM(randRoll->toLocal(gp)); + const int HS(i/0.5); + const bool edge(HS < 4 or HS > 93); + const float pad(edge ? -99 : randRoll->pad(lpGEM)); + // HS are wrapped-around + cscHsToGemPadME1a_[HS] = std::make_pair(std::floor(pad),std::ceil(pad)); + } + // ME1b + auto nStripsME1b(keyLayerGeometryME1b->numberOfStrips()); + for (float i = 0; i< nStripsME1b; i = i+0.5){ + const LocalPoint lpCSC(keyLayerGeometryME1b->topology()->localPosition(i)); + const GlobalPoint gp(keyLayerME1b->toGlobal(lpCSC)); + const LocalPoint lpGEM(randRoll->toLocal(gp)); + const int HS(i/0.5); + const bool edge(HS < 5 or HS > 124); + const float pad(edge ? -99 : randRoll->pad(lpGEM)); + // HS are wrapped-around + cscHsToGemPadME1b_[HS] = std::make_pair(std::floor(pad),std::ceil(pad)); + } + if (debug_luts){ + std::cout << "detId " << me1bId << std::endl; + std::cout << "CSCHSToGEMPad LUT in ME1a" << std::endl; + for(auto p : cscHsToGemPadME1a_) { + std::cout << "CSC HS "<< p.first << " GEM Pad low " << (p.second).first << " GEM Pad high " << (p.second).second << std::endl; + } + std::cout << "detId " << me1aId << std::endl; + std::cout << "CSCHSToGEMPad LUT in ME1b" << std::endl; + for(auto p : cscHsToGemPadME1b_) { + std::cout << "CSC HS "<< p.first << " GEM Pad low " << (p.second).first << " GEM Pad high " << (p.second).second << std::endl; + } + } + + const int nGEMPads(randRoll->npads()); + for (int i = 0; i< nGEMPads; ++i){ + const LocalPoint lpGEM(randRoll->centreOfPad(i)); + const GlobalPoint gp(randRoll->toGlobal(lpGEM)); + const LocalPoint lpCSCME1a(keyLayerME1a->toLocal(gp)); + const LocalPoint lpCSCME1b(keyLayerME1b->toLocal(gp)); + const float stripME1a(keyLayerGeometryME1a->strip(lpCSCME1a)); + const float stripME1b(keyLayerGeometryME1b->strip(lpCSCME1b)); + // HS are wrapped-around + gemPadToCscHsME1a_[i] = (int) (stripME1a - 0.25)/0.5; + gemPadToCscHsME1b_[i] = (int) (stripME1b - 0.25)/0.5; + } + if (debug_luts){ + std::cout << "detId " << me1bId << std::endl; + std::cout << "GEMPadToCSCHs LUT in ME1a" << std::endl; + for(auto p : gemPadToCscHsME1a_) { + std::cout << "GEM Pad "<< p.first << " CSC HS: " << p.second << std::endl; + } + std::cout << "GEMPadToCSCHs LUT in ME1b" << std::endl; + for(auto p : gemPadToCscHsME1b_) { + std::cout << "GEM Pad "<< p.first << " CSC HS: " << p.second << std::endl; + } + } + + // build coincidence pads + std::auto_ptr pCoPads(new GEMPadDigiCollection()); + buildCoincidencePads(gemPads, *pCoPads, me1bId); + + // retrieve pads and copads in a certain BX window for this CSC + pads_.clear(); + coPads_.clear(); + retrieveGEMPads(gemPads, gem_id); + retrieveGEMPads(pCoPads.get(), gem_id, true); + + const bool debugStubs(false); + if (debugStubs){ + for (auto& p : alctV){ + std::cout << "ALCT: " << p << std::endl; + } + + for (auto& p : clctV1b){ + std::cout << "CLCT in ME1b: " << p << std::endl; + } + + for (auto& p : clctV1a){ + std::cout << "CLCT in ME1a: " << p << std::endl; + } + + auto superChamber(gem_g->superChamber(gem_id)); + for (auto ch : superChamber->chambers()) { + for (auto roll : ch->etaPartitions()) { + 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) { + // auto id_pad = std::make_pair(roll_id(), &(*pad)); + if (abs((*pad).bx())<=1) + std::cout << "GEM: " << roll_id << " " << *pad << std::endl; + } + } + } + } + } + + const bool hasPads(pads_.size()!=0); + const bool hasCoPads(hasPads and coPads_.size()!=0); + bool hasLCTs(false); + + // ALCT-centric matching + for (int bx_alct = 0; bx_alct < CSCAnodeLCTProcessor::MAX_ALCT_BINS; bx_alct++) + { + if (alct->bestALCT[bx_alct].isValid()) + { + const int bx_clct_start(bx_alct - match_trig_window_size/2); + const int bx_clct_stop(bx_alct + match_trig_window_size/2); + const int bx_copad_start(bx_alct - maxDeltaBXCoPad_); + const int bx_copad_stop(bx_alct + maxDeltaBXCoPad_); + + if (debug_gem_matching){ + std::cout << "========================================================================" << std::endl; + std::cout << "ALCT-CLCT matching in ME1/1 chamber: " << cscChamberME1b->id() << std::endl; + std::cout << "------------------------------------------------------------------------" << std::endl; + std::cout << "+++ Best ALCT Details: "; + alct->bestALCT[bx_alct].print(); + std::cout << "+++ Second ALCT Details: "; + alct->secondALCT[bx_alct].print(); + + printGEMTriggerPads(bx_clct_start, bx_clct_stop); + printGEMTriggerPads(bx_clct_start, bx_clct_stop, true); + + std::cout << "------------------------------------------------------------------------" << std::endl; + std::cout << "Attempt ALCT-CLCT matching in ME1/b in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl; + } + + // ALCT-to-CLCT matching in ME1b + int nSuccesFulMatches = 0; + for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) + { + if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue; + if (drop_used_clcts and used_clct_mask[bx_clct]) continue; + if (clct->bestCLCT[bx_clct].isValid()) + { + const int quality(clct->bestCLCT[bx_clct].getQuality()); + if (debug_gem_matching) std::cout << "++Valid ME1b CLCT: " << clct->bestCLCT[bx_clct] << std::endl; + + // pick the pad that corresponds + auto matchingPads(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_clct], ME1B, false)); + auto matchingCoPads(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_clct], ME1B, true)); + if (runME11ILT_ and dropLowQualityCLCTsNoGEMs_ME1b_ and quality < 4 and hasPads){ + int nFound(matchingPads.size()); + const bool clctInEdge(clct->bestCLCT[bx_clct].getKeyStrip() < 5 or clct->bestCLCT[bx_clct].getKeyStrip() > 124); + if (clctInEdge){ + if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT in CSC chamber edge, don't care about GEM pads" << std::endl; + } + else { + if (nFound != 0){ + if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT with " << nFound << " matching GEM trigger pads" << std::endl; + } + else { + if (debug_gem_matching) std::cout << "\tWarning: low quality CLCT without matching GEM trigger pad" << std::endl; + continue; + } + } + } + + // check timing + if (runME11ILT_ and correctLCTtimingWithGEM_){ + int nFound(matchingCoPads.size()); + if (nFound != 0 and bx_alct == 6 and bx_clct != 6){ + if (debug_gem_matching) std::cout << "\tInfo: CLCT with incorrect timing" << std::endl; + continue; + } + } + + ++nSuccesFulMatches; + + hasLCTs = true; + // if (infoV > 1) LogTrace("CSCMotherboard") + int mbx = bx_clct-bx_clct_start; + correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct], + clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct], + allLCTs1b[bx_alct][mbx][0], allLCTs1b[bx_alct][mbx][1], ME1B, matchingPads, matchingCoPads); + if (debug_gem_matching) { + std::cout << "Successful ALCT-CLCT match in ME1b: bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop + << "]; bx_clct = " << bx_clct << std::endl; + std::cout << "+++ Best CLCT Details: "; + clct->bestCLCT[bx_clct].print(); + std::cout << "+++ Second CLCT Details: "; + clct->secondCLCT[bx_clct].print(); + } + + if (allLCTs1b[bx_alct][mbx][0].isValid()) { + used_clct_mask[bx_clct] += 1; + if (match_earliest_clct_me11_only) break; + } + } + } + + // ALCT-to-GEM matching in ME1b + int nSuccesFulGEMMatches = 0; + if (runME11ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandGEM_ME1b_){ + if (debug_gem_matching) std::cout << "++No valid ALCT-CLCT matches in ME1b" << std::endl; + for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) { + if (not hasCoPads) { + continue; + } + + // find the best matching copad - first one + auto copads(matchingGEMPads(alct->bestALCT[bx_alct], coPads_[bx_gem], ME1B, true)); + if (debug_gem_matching) std::cout << "\t++Number of matching GEM CoPads in BX " << bx_alct << " : "<< copads.size() << std::endl; + if (copads.size()==0) { + continue; + } + + correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct], + *(copads.at(0)).second, allLCTs1b[bx_alct][0][0], allLCTs1b[bx_alct][0][1], ME1B); + if (allLCTs1b[bx_alct][0][0].isValid()) { + ++nSuccesFulGEMMatches; + if (match_earliest_clct_me11_only) break; + } + if (debug_gem_matching) { + std::cout << "Successful ALCT-GEM CoPad match in ME1b: bx_alct = " << bx_alct << std::endl << std::endl; + std::cout << "------------------------------------------------------------------------" << std::endl << std::endl; + } + } + } + + if (debug_gem_matching) { + std::cout << "========================================================================" << std::endl; + std::cout << "Summary: " << std::endl; + if (nSuccesFulMatches>1) + std::cout << "Too many successful ALCT-CLCT matches in ME1b: " << nSuccesFulMatches + << ", CSCDetId " << cscChamberME1b->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else if (nSuccesFulMatches==1) + std::cout << "1 successful ALCT-CLCT match in ME1b: " + << " CSCDetId " << cscChamberME1b->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else if (nSuccesFulGEMMatches==1) + std::cout << "1 successful ALCT-GEM match in ME1b: " + << " CSCDetId " << cscChamberME1b->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else + std::cout << "Unsuccessful ALCT-CLCT match in ME1b: " + << "CSCDetId " << cscChamberME1b->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + + std::cout << "------------------------------------------------------------------------" << std::endl; + std::cout << "Attempt ALCT-CLCT matching in ME1/a in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl; + } + + // ALCT-to-CLCT matching in ME1a + nSuccesFulMatches = 0; + for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) + { + if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue; + if (drop_used_clcts and used_clct_mask_1a[bx_clct]) continue; + if (clct1a->bestCLCT[bx_clct].isValid()) + { + const int quality(clct1a->bestCLCT[bx_clct].getQuality()); + if (debug_gem_matching) std::cout << "++Valid ME1a CLCT: " << clct1a->bestCLCT[bx_clct] << std::endl; + + // pick the pad that corresponds + auto matchingPads(matchingGEMPads(clct1a->bestCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_clct], ME1A, false)); + auto matchingCoPads(matchingGEMPads(clct1a->bestCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_clct], ME1A, true)); + if (runME11ILT_ and dropLowQualityCLCTsNoGEMs_ME1a_ and quality < 4 and hasPads){ + int nFound(matchingPads.size()); + const bool clctInEdge(clct1a->bestCLCT[bx_clct].getKeyStrip() < 4 or clct1a->bestCLCT[bx_clct].getKeyStrip() > 93); + if (clctInEdge){ + if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT in CSC chamber edge, don't care about GEM pads" << std::endl; + } + else { + if (nFound != 0){ + if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT with " << nFound << " matching GEM trigger pads" << std::endl; + } + else { + if (debug_gem_matching) std::cout << "\tWarning: low quality CLCT without matching GEM trigger pad" << std::endl; + continue; + } + } + } + ++nSuccesFulMatches; + int mbx = bx_clct-bx_clct_start; + correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct], + clct1a->bestCLCT[bx_clct], clct1a->secondCLCT[bx_clct], + allLCTs1a[bx_alct][mbx][0], allLCTs1a[bx_alct][mbx][1], ME1A, matchingPads, matchingCoPads); + if (debug_gem_matching) { + std::cout << "Successful ALCT-CLCT match in ME1a: bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop + << "]; bx_clct = " << bx_clct << std::endl; + std::cout << "+++ Best CLCT Details: "; + clct1a->bestCLCT[bx_clct].print(); + std::cout << "+++ Second CLCT Details: "; + clct1a->secondCLCT[bx_clct].print(); + } + if (allLCTs1a[bx_alct][mbx][0].isValid()){ + used_clct_mask_1a[bx_clct] += 1; + if (match_earliest_clct_me11_only) break; + } + } + } + + // ALCT-to-GEM matching in ME1a + nSuccesFulGEMMatches = 0; + if (runME11ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandGEM_ME1a_){ + if (debug_gem_matching) std::cout << "++No valid ALCT-CLCT matches in ME1a" << std::endl; + for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) { + if (not hasCoPads) { + continue; + } + + // find the best matching copad - first one + auto copads(matchingGEMPads(alct->bestALCT[bx_alct], coPads_[bx_gem], ME1A, true)); + if (debug_gem_matching) std::cout << "\t++Number of matching GEM CoPads in BX " << bx_alct << " : "<< copads.size() << std::endl; + if (copads.size()==0) { + continue; + } + + correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct], + *(copads.at(0)).second, allLCTs1a[bx_alct][0][0], allLCTs1a[bx_alct][0][1], ME1A); + if (allLCTs1a[bx_alct][0][0].isValid()) { + ++nSuccesFulGEMMatches; + if (match_earliest_clct_me11_only) break; + } + if (debug_gem_matching) { + std::cout << "Successful ALCT-GEM CoPad match in ME1a: bx_alct = " << bx_alct << std::endl << std::endl; + std::cout << "------------------------------------------------------------------------" << std::endl << std::endl; + } + } + } + + if (debug_gem_matching) { + std::cout << "========================================================================" << std::endl; + std::cout << "Summary: " << std::endl; + if (nSuccesFulMatches>1) + std::cout << "Too many successful ALCT-CLCT matches in ME1a: " << nSuccesFulMatches + << ", CSCDetId " << cscChamberME1a->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else if (nSuccesFulMatches==1) + std::cout << "1 successful ALCT-CLCT match in ME1a: " + << " CSCDetId " << cscChamberME1a->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else if (nSuccesFulGEMMatches==1) + std::cout << "1 successful ALCT-GEM match in ME1a: " + << " CSCDetId " << cscChamberME1a->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else + std::cout << "Unsuccessful ALCT-CLCT match in ME1a: " + << "CSCDetId " << cscChamberME1a->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + } + + } // end of ALCT valid block + else { + auto coPads(coPads_[bx_alct]); + if (runME11ILT_ and coPads.size()!=0) { + // keep it simple for the time being, only consider the first copad + const int bx_clct_start(bx_alct - match_trig_window_size/2); + const int bx_clct_stop(bx_alct + match_trig_window_size/2); + + // matching in ME1b + if (buildLCTfromCLCTandGEM_ME1b_) { + for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) { + if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue; + if (drop_used_clcts and used_clct_mask[bx_clct]) continue; + if (clct->bestCLCT[bx_clct].isValid()) { + const int quality(clct->bestCLCT[bx_clct].getQuality()); + // only use high-Q stubs for the time being + if (quality < 4) continue; + int mbx = bx_clct-bx_clct_start; + correlateLCTsGEM(clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct], *(coPads[0].second), GEMDetId(coPads[0].first).roll(), + allLCTs1b[bx_alct][mbx][0], allLCTs1b[bx_alct][mbx][1], ME1B); + if (debug_gem_matching) { + // if (infoV > 1) LogTrace("CSCMotherboard") + std::cout << "Successful GEM-CLCT match in ME1b: bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop + << "]; bx_clct = " << bx_clct << std::endl; + std::cout << "+++ Best CLCT Details: "; + clct->bestCLCT[bx_clct].print(); + std::cout << "+++ Second CLCT Details: "; + clct->secondCLCT[bx_clct].print(); + } + if (allLCTs1b[bx_alct][mbx][0].isValid()) { + used_clct_mask[bx_clct] += 1; + if (match_earliest_clct_me11_only) break; + } + } + } + } + + // matching in ME1a + if (buildLCTfromCLCTandGEM_ME1a_) { + for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) { + if (bx_clct < 0 || bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue; + if (drop_used_clcts && used_clct_mask_1a[bx_clct]) continue; + if (clct1a->bestCLCT[bx_clct].isValid()){ + const int quality(clct1a->bestCLCT[bx_clct].getQuality()); + // only use high-Q stubs for the time being + if (quality < 4) continue; + int mbx = bx_clct-bx_clct_start; + correlateLCTsGEM(clct1a->bestCLCT[bx_clct], clct1a->secondCLCT[bx_clct], *(coPads[0].second), GEMDetId(coPads[0].first).roll(), + allLCTs1a[bx_alct][mbx][0], allLCTs1a[bx_alct][mbx][1], ME1A); + if (debug_gem_matching) { + // if (infoV > 1) LogTrace("CSCMotherboard") + std::cout << "Successful GEM-CLCT match in ME1a: bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop + << "]; bx_clct = " << bx_clct << std::endl; + std::cout << "+++ Best CLCT Details: "; + clct1a->bestCLCT[bx_clct].print(); + std::cout << "+++ Second CLCT Details: "; + clct1a->secondCLCT[bx_clct].print(); + } + if (allLCTs1a[bx_alct][mbx][0].isValid()){ + used_clct_mask_1a[bx_clct] += 1; + if (match_earliest_clct_me11_only) break; + } + } + } + } + } + } + } // end of ALCT-centric matching + + // possibly use some discrimination from GEMs + if (gemGeometryAvailable and runME11ILT_ and do_gem_matching) { + matchGEMPads(ME1A); + matchGEMPads(ME1B); + } + + if (hasLCTs and debug_gem_matching){ + std::cout << "========================================================================" << std::endl; + std::cout << "Counting the LCTs" << std::endl; + std::cout << "========================================================================" << std::endl; + } + + // reduction of nLCTs per each BX + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + { + // counting + unsigned int n1a=0, n1b=0; + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + int cbx = bx + mbx - match_trig_window_size/2; + if (allLCTs1b[bx][mbx][i].isValid()) + { + n1b++; + if (infoV > 0) LogDebug("CSCMotherboard") + << "1b LCT"< 0) LogDebug("CSCMotherboard") + << "1a LCT"< 0 and n1a+n1b>0) LogDebug("CSCMotherboard") + <<"bx "<2 or n1b>2) ) + { + n1a=0, n1b=0; + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + if (allLCTs1b[bx][pref[mbx]][i].isValid()) + { + n1b++; + if (n1b>2) allLCTs1b[bx][pref[mbx]][i].clear(); + } + if (allLCTs1a[bx][pref[mbx]][i].isValid()) + { + n1a++; + if (n1a>2) allLCTs1a[bx][pref[mbx]][i].clear(); + } + } + + n1a=0, n1b=0; + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + int cbx = bx + mbx - match_trig_window_size/2; + if (allLCTs1b[bx][mbx][i].isValid()) + { + n1b++; + if (infoV > 0) LogDebug("CSCMotherboard") + << "1b LCT"< 0) LogDebug("CSCMotherboard") + << "1a LCT"< 0 and n1a+n1b>0) LogDebug("CSCMotherboard") + <<"bx "< max_me11_lcts and tmb_cross_bx_algo == 1) + { + // do it simple so far: take all low eta 1/b stubs + unsigned int nLCT=n1b; + n1a=0; + // right now nLCT<=2; cut 1a if necessary + for (unsigned int mbx=0; mbxmax_me11_lcts) allLCTs1a[bx][mbx][i].clear(); + else n1a++; + } + // if (infoV > 0 and nLCT>0) LogDebug("CSCMotherboard") +// std::cout <<"bx "< 1) LogTrace("CSCMotherboardME11GEM")<<"clct_count E:"< CSCMotherboardME11GEM::readoutLCTs1a() +{ + return readoutLCTs(ME1A); +} + + +std::vector CSCMotherboardME11GEM::readoutLCTs1b() +{ + return readoutLCTs(ME1B); +} + + +// Returns vector of read-out correlated LCTs, if any. Starts with +// the vector of all found LCTs and selects the ones in the read-out +// time window. +std::vector CSCMotherboardME11GEM::readoutLCTs(enum ME11Part me1ab) +{ + std::vector tmpV; + + // The start time of the L1A*LCT coincidence window should be related + // to the fifo_pretrig parameter, but I am not completely sure how. + // Just choose it such that the window is centered at bx=7. This may + // need further tweaking if the value of tmb_l1a_window_size changes. + //static int early_tbins = 4; + // The number of LCT bins in the read-out is given by the + // tmb_l1a_window_size parameter, forced to be odd + static int lct_bins = + (tmb_l1a_window_size % 2 == 0) ? tmb_l1a_window_size + 1 : tmb_l1a_window_size; + static int late_tbins = early_tbins + lct_bins; + + + // Start from the vector of all found correlated LCTs and select + // those within the LCT*L1A coincidence window. + int bx_readout = -1; + std::vector tmp_lcts; + std::vector all_lcts; + if (me1ab == ME1A) tmp_lcts = getLCTs1a(); + if (me1ab == ME1B) tmp_lcts = getLCTs1b(); + switch(tmb_cross_bx_algo){ + case 0: all_lcts = tmp_lcts; + break; + case 1: all_lcts = tmp_lcts; + break; + case 2: all_lcts = sortLCTsByQuality(me1ab); + break; + case 3: all_lcts = sortLCTsByGEMDPhi(me1ab); + break; + default: std::cout<<"tmb_cross_bx_algo error" <::const_iterator plct = all_lcts.begin(); + for (; plct != all_lcts.end(); plct++) + { + if (!plct->isValid()) continue; + + int bx = (*plct).getBX(); + // Skip LCTs found too early relative to L1Accept. + if (bx <= early_tbins) continue; + + // Skip LCTs found too late relative to L1Accept. + if (bx > late_tbins) continue; + + // If (readout_earliest_2) take only LCTs in the earliest bx in the read-out window: + // in digi->raw step, LCTs have to be packed into the TMB header, and + // currently there is room just for two. + if (readout_earliest_2 and (bx_readout == -1 or bx == bx_readout) ) + { + tmpV.push_back(*plct); + if (bx_readout == -1) bx_readout = bx; + } + else tmpV.push_back(*plct); + } + return tmpV; +} + + +// Returns vector of found correlated LCTs, if any. +std::vector CSCMotherboardME11GEM::getLCTs1b() +{ + std::vector tmpV; + + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + if (allLCTs1b[bx][mbx][i].isValid()) tmpV.push_back(allLCTs1b[bx][mbx][i]); + return tmpV; +} + + +// Returns vector of found correlated LCTs, if any. +std::vector CSCMotherboardME11GEM::getLCTs1a() +{ + std::vector tmpV; + + // disabled ME1a + if (mpc_block_me1a or disableME1a) return tmpV; + + // Report all LCTs found. + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + if (allLCTs1a[bx][mbx][i].isValid()) tmpV.push_back(allLCTs1a[bx][mbx][i]); + return tmpV; +} + + +//sort LCTs by Quality in each BX +std::vector CSCMotherboardME11GEM::sortLCTsByQuality(int bx, enum ME11Part me) +{ + auto allLCTs(me==ME1A ? allLCTs1a : allLCTs1b); + std::vector LCTs; + std::vector tmpV; + tmpV.clear(); + LCTs.clear(); + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + if (allLCTs[bx][mbx][i].isValid()) + LCTs.push_back(allLCTs[bx][mbx][i]); + + std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByQuality); + tmpV = LCTs; + if (tmpV.size()> max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end()); + return tmpV; +} + +std::vector CSCMotherboardME11GEM::sortLCTsByQuality(std::vector LCTs) +{ + std::vector tmpV; + tmpV.clear(); + std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByQuality); + tmpV = LCTs; + if (tmpV.size()> max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end()); + return tmpV; +} + + +//sort LCTs in whole LCTs BX window +std::vector CSCMotherboardME11GEM::sortLCTsByQuality(enum ME11Part me) +{ + std::vector LCTs_final; + LCTs_final.clear(); + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + { + std::vector LCTs1a; + std::vector LCTs1b; + std::vector LCTs_tmp; + std::vector LCTs_tmp1; + LCTs1a = sortLCTsByQuality(bx, ME1A); + LCTs1b = sortLCTsByQuality(bx, ME1B); + std::vector::iterator it1a = LCTs1a.begin(); + std::vector::iterator it1b = LCTs1b.begin(); + LCTs_tmp.insert(LCTs_tmp.begin(), LCTs1b.begin(), LCTs1b.end()); + LCTs_tmp.insert(LCTs_tmp.end(), LCTs1a.begin(), LCTs1a.end()); + LCTs_tmp1 = sortLCTsByQuality(LCTs_tmp);//LCTs reduction per BX + if (firstTwoLCTsInChamber_) + { + std::vector::iterator itp = LCTs_tmp1.begin(); + for ( ; itp != LCTs_tmp1.end(); itp++) + { + if (me==ME1A and it1a != LCTs1a.end() and *itp==*it1a ) + { + LCTs_final.push_back(*it1a); + it1a++; + } + if (me==ME1B and it1b != LCTs1b.end() and *itp==*it1b) + { + LCTs_final.push_back(*it1b); + it1b++; + } + } + } + else { + if (LCTs1a.size() and LCTs1b.size() and me==ME1A) + LCTs_final.push_back(*LCTs1a.begin()); + else if (LCTs1a.size() and LCTs1b.size() and me==ME1B) + LCTs_final.push_back(*LCTs1b.begin()); + else if (LCTs1a.size() and LCTs1b.size()==0 and me==ME1A) + LCTs_final.insert(LCTs_final.end(), LCTs1a.begin(), LCTs1a.end()); + else if (LCTs1b.size() and LCTs1a.size()==0 and me==ME1B) + LCTs_final.insert(LCTs_final.end(), LCTs1b.begin(), LCTs1b.end()); + } + } + return LCTs_final; +} + + +//sort LCTs by GEMDPhi in each BX +std::vector CSCMotherboardME11GEM::sortLCTsByGEMDPhi(int bx, enum ME11Part me) +{ + + auto allLCTs(me==ME1A ? allLCTs1a : allLCTs1b); + std::vector LCTs; + std::vector tmpV; + tmpV.clear(); + LCTs.clear(); + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + if (allLCTs[bx][mbx][i].isValid()) + LCTs.push_back(allLCTs[bx][mbx][i]); + + std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByGEMDphi); + tmpV = LCTs; + if (tmpV.size() > max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end()); + return tmpV; +} + +std::vector CSCMotherboardME11GEM::sortLCTsByGEMDPhi(std::vector LCTs) +{ + std::vector tmpV; + tmpV.clear(); + std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByGEMDphi); + tmpV = LCTs; + if (tmpV.size() > max_me11_lcts) tmpV.erase(tmpV.begin()+max_me11_lcts, tmpV.end()); + return tmpV; +} + + +//sort LCTs in whole LCTs BX window +std::vector CSCMotherboardME11GEM::sortLCTsByGEMDPhi(enum ME11Part me) +{ + std::vector LCTs_final; + LCTs_final.clear(); + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + { + std::vector LCTs1a; + std::vector LCTs1b; + std::vector LCTs_tmp; + std::vector LCTs_tmp1; + LCTs1a = sortLCTsByGEMDPhi(bx, ME1A); + LCTs1b = sortLCTsByGEMDPhi(bx, ME1B); + std::vector::iterator it1a = LCTs1a.begin(); + std::vector::iterator it1b = LCTs1b.begin(); + LCTs_tmp.insert(LCTs_tmp.begin(), LCTs1b.begin(), LCTs1b.end()); + LCTs_tmp.insert(LCTs_tmp.end(), LCTs1a.begin(), LCTs1a.end()); + LCTs_tmp1 = sortLCTsByGEMDPhi(LCTs_tmp);//LCTs reduction per BX + if (firstTwoLCTsInChamber_) + { + std::vector::iterator itp = LCTs_tmp1.begin(); + while (itp != LCTs_tmp1.end()) + { + if (me==ME1B and it1b != LCTs1b.end() and *itp==*it1b) + { + LCTs_final.push_back(*it1b); + it1b++; + } + if (me==ME1A and it1a != LCTs1a.end() and *itp==*it1a) + { + LCTs_final.push_back(*it1a); + it1a++; + } + itp++; + } + } + else { + if (LCTs1a.size() and LCTs1b.size() and me==ME1A) + LCTs_final.push_back(*LCTs1a.begin()); + else if (LCTs1a.size() and LCTs1b.size() and me==ME1B) + LCTs_final.push_back(*LCTs1b.begin()); + else if (LCTs1a.size() and LCTs1b.size()==0 and me==ME1A) + LCTs_final.insert(LCTs_final.end(), LCTs1a.begin(), LCTs1a.end()); + else if (LCTs1b.size() and LCTs1a.size()==0 and me==ME1B) + LCTs_final.insert(LCTs_final.end(), LCTs1b.begin(), LCTs1b.end()); + } + } + return LCTs_final; +} + + +bool CSCMotherboardME11GEM::doesALCTCrossCLCT(CSCALCTDigi &a, CSCCLCTDigi &c, int me) +{ + if ( !c.isValid() or !a.isValid() ) return false; + int key_hs = c.getKeyStrip(); + int key_wg = a.getKeyWG(); + if ( me == ME1A ) + { + if ( !gangedME1a ) + { + // wrap around ME11 HS number for -z endcap + if (theEndcap==2) key_hs = 95 - key_hs; + if ( key_hs >= lut_wg_vs_hs_me1a[key_wg][0] and + key_hs <= lut_wg_vs_hs_me1a[key_wg][1] ) return true; + return false; + } + else + { + if (theEndcap==2) key_hs = 31 - key_hs; + if ( key_hs >= lut_wg_vs_hs_me1ag[key_wg][0] and + key_hs <= lut_wg_vs_hs_me1ag[key_wg][1] ) return true; + return false; + } + } + if ( me == ME1B) + { + if (theEndcap==2) key_hs = 127 - key_hs; + if ( key_hs >= lut_wg_vs_hs_me1b[key_wg][0] and + key_hs <= lut_wg_vs_hs_me1b[key_wg][1] ) return true; + } + return false; +} + +void CSCMotherboardME11GEM::correlateLCTs(CSCALCTDigi bestALCT, + CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, + CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2) +{ + bool anodeBestValid = bestALCT.isValid(); + bool anodeSecondValid = secondALCT.isValid(); + bool cathodeBestValid = bestCLCT.isValid(); + bool cathodeSecondValid = secondCLCT.isValid(); + + if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT; + if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT; + if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT; + if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT; + + // ALCT-CLCT matching conditions are defined by "trig_enable" configuration + // parameters. + if ((alct_trig_enable and bestALCT.isValid()) or + (clct_trig_enable and bestCLCT.isValid()) or + (match_trig_enable and bestALCT.isValid() and bestCLCT.isValid())) + { + lct1 = constructLCTs(bestALCT, bestCLCT); + lct1.setTrknmb(1); + } + + if (((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) and + ((alct_trig_enable and secondALCT.isValid()) or + (clct_trig_enable and secondCLCT.isValid()) or + (match_trig_enable and secondALCT.isValid() and secondCLCT.isValid()))) + { + lct2 = constructLCTs(secondALCT, secondCLCT); + lct2.setTrknmb(2); + } +} + + +void CSCMotherboardME11GEM::correlateLCTsGEM(CSCALCTDigi bestALCT, + CSCALCTDigi secondALCT, + GEMPadDigi gemPad, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2, int ME) +{ + bool anodeBestValid = bestALCT.isValid(); + bool anodeSecondValid = secondALCT.isValid(); + + if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT; + if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT; + + if ((alct_trig_enable and bestALCT.isValid()) or + (match_trig_enable and bestALCT.isValid())) + { + lct1 = constructLCTsGEM(bestALCT, gemPad, ME, useOldLCTDataFormatALCTGEM_); + lct1.setTrknmb(1); + // lct1.setGEMDPhi(0.0); + } + + if ((alct_trig_enable and secondALCT.isValid()) or + (match_trig_enable and secondALCT.isValid() and secondALCT != bestALCT)) + { + lct2 = constructLCTsGEM(secondALCT, gemPad, ME, useOldLCTDataFormatALCTGEM_); + lct2.setTrknmb(2); + // lct2.setGEMDPhi(0.0); + } +} + + +void CSCMotherboardME11GEM::correlateLCTsGEM(CSCCLCTDigi bestCLCT, + CSCCLCTDigi secondCLCT, + GEMPadDigi gemPad, int roll, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2, int ME) +{ + bool cathodeBestValid = bestCLCT.isValid(); + bool cathodeSecondValid = secondCLCT.isValid(); + + if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT; + if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT; + + if ((clct_trig_enable and bestCLCT.isValid()) or + (match_trig_enable and bestCLCT.isValid())) + { + lct1 = constructLCTsGEM(bestCLCT, gemPad, roll, ME, useOldLCTDataFormatALCTGEM_); + lct1.setTrknmb(1); + } + + if ((clct_trig_enable and secondCLCT.isValid()) or + (match_trig_enable and secondCLCT.isValid() and secondCLCT != bestCLCT)) + { + lct2 = constructLCTsGEM(secondCLCT, gemPad, roll, ME, useOldLCTDataFormatALCTGEM_); + lct2.setTrknmb(2); + } +} + +void CSCMotherboardME11GEM::correlateLCTsGEM(CSCALCTDigi bestALCT, + CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, + CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2, + int me, + const GEMPadsBX& pads, + const GEMPadsBX& copads) +{ + // assume that always anodeBestValid and cathodeBestValid + + if (secondALCT == bestALCT) secondALCT.clear(); + if (secondCLCT == bestCLCT) secondCLCT.clear(); + + int ok11 = doesALCTCrossCLCT( bestALCT, bestCLCT, me); + int ok12 = doesALCTCrossCLCT( bestALCT, secondCLCT, me); + int ok21 = doesALCTCrossCLCT( secondALCT, bestCLCT, me); + int ok22 = doesALCTCrossCLCT( secondALCT, secondCLCT, me); + int code = (ok11<<3) | (ok12<<2) | (ok21<<1) | (ok22); + + int dbg=0; + int ring = me; + int chamb= CSCTriggerNumbering::chamberFromTriggerLabels(theSector,theSubsector, theStation, theTrigChamber); + CSCDetId did(theEndcap, theStation, ring, chamb, 0); + if (dbg) LogTrace("CSCMotherboardME11GEM")<<"debug correlateLCTs in "< mypair; + // for each trigger pad, store (deltaRoll,deltaHS) for 11,22,12 and 21. + std::vector> deltas; + deltas.clear(); + + if (hasCoPads){ + for (auto p : copads) { + const GEMDetId detId(p.first); + const int rollN(detId.roll()); + const int padN((p.second)->pad()); + + auto t11(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN))); + auto t22(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN))); + auto t12(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN))); + auto t21(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN))); + + deltas.push_back(std::make_tuple(t11,t22,t12,t21)); + } + if (debug_gem_matching){ + std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl; + std::cout << "Printing (deltaRoll, deltaPad) for each (ALCT,CLCT) pair and for each trigger copad" << std::endl; + for (unsigned i =0; i < deltas.size(); ++i){ + auto c(deltas.at(i)); + std::cout << "\tCoPad " << i << std::endl; + std::cout << "\t11: " << "(" << std::get<0>(c).first << "," << std::get<0>(c).second << "); " + << "22: " << "(" << std::get<1>(c).first << "," << std::get<1>(c).second << "); " + << "12: " << "(" << std::get<2>(c).first << "," << std::get<2>(c).second << "); " + << "21: " << "(" << std::get<3>(c).first << "," << std::get<3>(c).second << ")" << std::endl << std::endl; + } + std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl; + } + + +// lct1 = constructLCTs(bestALCT, bestCLCT); +// lct1.setTrknmb(1); +// lct2 = constructLCTs(secondALCT, secondCLCT); +// lct2.setTrknmb(2); + +// lct1 = constructLCTs(bestALCT, secondCLCT); +// lct1.setTrknmb(1); +// lct2 = constructLCTs(secondLCT, bestCLCT); +// lct2.setTrknmb(2); + return; + } + + // if no copads were found, do the same with pads... + if (hasPads){ + for (auto p : pads) { + const GEMDetId detId(p.first); + const int rollN(detId.roll()); + const int padN((p.second)->pad()); + + auto t11(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN))); + auto t22(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN))); + auto t12(std::make_pair(deltaRoll( bestALCT.getKeyWG(), rollN), deltaPad(secondCLCT.getKeyStrip(), padN))); + auto t21(std::make_pair(deltaRoll(secondALCT.getKeyWG(), rollN), deltaPad( bestCLCT.getKeyStrip(), padN))); + + deltas.push_back(std::make_tuple(t11,t22,t12,t21)); + } + if (debug_gem_matching){ + std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl; + std::cout << "Printing (deltaRoll, deltaPad) for each (ALCT,CLCT) pair and for each trigger pad" << std::endl; + for (unsigned i =0; i < deltas.size(); ++i){ + auto c(deltas.at(i)); + std::cout << "\tPad " << i << std::endl; + std::cout << "\t11: " << "(" << std::get<0>(c).first << "," << std::get<0>(c).second << "); " + << "22: " << "(" << std::get<1>(c).first << "," << std::get<1>(c).second << "); " + << "12: " << "(" << std::get<2>(c).first << "," << std::get<2>(c).second << "); " + << "21: " << "(" << std::get<3>(c).first << "," << std::get<3>(c).second << ")" << std::endl << std::endl; + } + std::cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << std::endl; + } + + return; + } + } + + switch (lut[code][0]) { + case 11: + lct1 = constructLCTsGEM(bestALCT, bestCLCT, hasPads, hasCoPads); + break; + case 12: + lct1 = constructLCTsGEM(bestALCT, secondCLCT, hasPads, hasCoPads); + break; + case 21: + lct1 = constructLCTsGEM(secondALCT, bestCLCT, hasPads, hasCoPads); + break; + case 22: + lct1 = constructLCTsGEM(secondALCT, secondCLCT, hasPads, hasCoPads); + break; + default: return; + } + lct1.setTrknmb(1); + + if (dbg) LogTrace("CSCMotherboardME11GEM")<<"lct1: "<chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber)); + + const CSCDetId me1bId(cscChamberME1b->id()); + const CSCDetId me1aId(me1bId.endcap(), 1, 4, me1bId.chamber()); + const CSCDetId me1abId(ME==ME1A ? me1aId : me1bId); + const int chamber(me1abId.chamber()); + const bool is_odd(chamber%2==1); + auto cscChamber = csc_g->chamber(me1abId); + + if (debug_gem_dphi) std::cout<<"++++++++ matchGEMPads "<< me1abId <<" +++++++++ "<layer(CSCConstants::KEY_CLCT_LAYER)->geometry(); + // LCT::getKeyWG() also starts from 0 + float wire = layer_geo->middleWireOfGroup(lct.getKeyWG() + 1); + + LocalPoint csc_intersect = layer_geo->intersectionOfStripAndWire(fractional_strip, wire); + GlobalPoint csc_gp = csc_g->idToDet(key_id)->surface().toGlobal(csc_intersect); + + if (debug_gem_dphi) + std::cout<<"CSC det id"<= gem_match_min_eta and + std::abs(csc_gp.eta()) <= gem_match_max_eta); + + if (debug_gem_dphi) std::cout<<" lct eta "< zap it + { + if (gem_clear_nomatch_lcts) lct.clear(); + if (debug_gem_dphi) std::cout<<" -- no gem"<second) + { + GEMDetId gem_id(id_pad.first); + LocalPoint gem_lp = gem_g->etaPartition(gem_id)->centreOfPad(id_pad.second->pad()); + GlobalPoint gem_gp = gem_g->idToDet(gem_id)->surface().toGlobal(gem_lp); + float dphi = deltaPhi(csc_gp.phi(), gem_gp.phi()); + float deta = csc_gp.eta() - gem_gp.eta(); + if (debug_gem_dphi) std::cout<<"pad"<< id_pad.second->pad()<<" phi:"<bx(); + } + } + if (gem_matched) + { + if (debug_gem_dphi) std::cout<<" GOT MATCHED GEM!"< lut_pt_vs_dphi_gemcsc[i+1][oddEven]) + iFound = i+1; + } + } + lct.setGEMDPhiBits(iFound); + if (debug_gem_dphi) std::cout<<"found bend angle "<begin(); det_range != out_pads->end(); ++det_range) { + const GEMDetId& id = (*det_range).first; + // same chamber + if (id.region() != csc_id.zendcap() or id.station() != csc_id.station() or + id.ring() != csc_id.ring() or id.chamber() != csc_id.chamber()) continue; + + // all coincidences detIDs will have layer=1 + if (id.layer() != 1) continue; + + // find the corresponding id with layer=2 + GEMDetId co_id(id.region(), id.ring(), id.station(), 2, id.chamber(), id.roll()); + + auto co_pads_range = out_pads->get(co_id); + // empty range = no possible coincidence pads + if (co_pads_range.first == co_pads_range.second) continue; + + // now let's correlate the pads in two layers of this partition + const auto& pads_range = (*det_range).second; + for (auto p = pads_range.first; p != pads_range.second; ++p) { + for (auto co_p = co_pads_range.first; co_p != co_pads_range.second; ++co_p) { + // check the match in pad + if (std::abs(p->pad() - co_p->pad()) > maxDeltaPadInCoPad_) continue; + // check the match in BX + if (std::abs(p->bx() - co_p->bx()) > maxDeltaBXInCoPad_ ) continue; + + // make a new coincidence pad digi + gemCoPadV.push_back(GEMCoPadDigi(*p,*co_p)); + + // always use layer1 pad's BX as a copad's BX + GEMPadDigi co_pad_digi(p->pad(), p->bx()); + out_co_pads.insertDigi(id, co_pad_digi); + } + } + } + + // removal of duplicates in copads + std::auto_ptr pCoPads(new GEMPadDigiCollection()); + const bool removeDuplicates(true); + if (removeDuplicates){ + for (auto det_range = out_co_pads.begin(); det_range != out_co_pads.end(); ++det_range) { + const GEMDetId& id = (*det_range).first; + auto co_pads_range = out_co_pads.get(id); + std::set clean_co_pads(co_pads_range.first,co_pads_range.second); + for (auto& p : clean_co_pads) + (*pCoPads).insertDigi(id, p); + } + out_co_pads = *pCoPads; + } +} + + +void CSCMotherboardME11GEM::createGEMRollEtaLUT(bool isEven) +{ + int ch(isEven ? 2 : 1); + auto chamber(gem_g->chamber(GEMDetId(1,1,1,1,ch,0))); + if (chamber==nullptr) return; + + int n = 1; + if (isEven) n = 2; // this only works for the 9-10 partition geometry!!! FIXME + for(auto roll : chamber->etaPartitions()) { + const float half_striplength(roll->specs()->specificTopology().stripLength()/2.); + const LocalPoint lp_top(0., half_striplength, 0.); + const LocalPoint lp_bottom(0., -half_striplength, 0.); + const GlobalPoint gp_top(roll->toGlobal(lp_top)); + const GlobalPoint gp_bottom(roll->toGlobal(lp_bottom)); + gemRollToEtaLimits_[n] = std::make_pair(gp_top.eta(), gp_bottom.eta()); + ++n; + } +} + + +int CSCMotherboardME11GEM::assignGEMRoll(double eta) +{ + int result = -99; + for(auto p : gemRollToEtaLimits_) { + const float minEta((p.second).first); + const float maxEta((p.second).second); + if (minEta <= eta and eta <= maxEta) { + result = p.first; + break; + } + } + return result; +} + + +CSCCorrelatedLCTDigi CSCMotherboardME11GEM::constructLCTsGEM(const CSCALCTDigi& alct, + const GEMPadDigi& gem, + int ME, bool oldDataFormat) +{ + auto mymap(ME==ME1A ? gemPadToCscHsME1a_ : gemPadToCscHsME1b_); + auto wgvshs(ME==ME1A ? lut_wg_vs_hs_me1a : lut_wg_vs_hs_me1b); + if (oldDataFormat){ + // CLCT pattern number - set it to a highest value + // hack to get LCTs in the CSCTF + unsigned int pattern = promoteALCTGEMpattern_ ? 10 : 0; + + // LCT quality number - set it to a very high value + // hack to get LCTs in the CSCTF + unsigned int quality = promoteALCTGEMquality_ ? 14 : 11; + + // Bunch crossing + int bx = alct.getBX(); + + // get keyStrip from LUT + int keyStrip = mymap[gem.pad()]; + + // get wiregroup from ALCT + int wg = alct.getKeyWG(); + + if (keyStrip>wgvshs[wg][0] && keyStripwgvshs[wg][0] && keyStrip 6) { + if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues") + << "+++ findQuality: sumQual = " << sumQual << "+++ \n"; + } + if (isDistrip) { // distrip pattern + if (sumQual == 2) {quality = 6;} + else if (sumQual == 3) {quality = 7;} + else if (sumQual == 4) {quality = 8;} + else if (sumQual == 5) {quality = 9;} + else if (sumQual == 6) {quality = 10;} + } + else { // halfstrip pattern + if (sumQual == 2) {quality = 11;} + else if (sumQual == 3) {quality = 12;} + else if (sumQual == 4) {quality = 13;} + else if (sumQual == 5) {quality = 14;} + else if (sumQual == 6) {quality = 15;} + } + } + } + } +#ifdef OLD + else { + // Temporary definition, used until July 2008. + // First if statement is fictitious, just to help the CSC TF emulator + // handle such cases (one needs to make sure they will be accounted for + // in the new quality definition. + if (!(aLCT.isValid()) || !(cLCT.isValid())) { + if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT + else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT + else quality = 0; // both absent; should never happen. + } + else { + // Sum of ALCT and CLCT quality bits. CLCT quality is, in fact, the + // number of layers hit, so subtract 3 to put it to the same footing as + // the ALCT quality. + int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3); + if (sumQual < 1 || sumQual > 6) { + if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues") + << "+++ findQuality: Unexpected sumQual = " << sumQual << "+++\n"; + } + + // LCT quality is basically the sum of ALCT and CLCT qualities, but split + // in two groups depending on the CLCT pattern id (higher quality for + // straighter patterns). + int offset = 0; + if (cLCT.getPattern() <= 7) offset = 4; + else offset = 9; + quality = offset + sumQual; + } + } +#endif + else { + // 2008 definition. + if (!(aLCT.isValid()) || !(cLCT.isValid())) { + if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT + else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT + else quality = 0; // both absent; should never happen. + } + else { + int pattern = cLCT.getPattern(); + if (pattern == 1) quality = 3; // layer-trigger in CLCT + else { + // CLCT quality is the number of layers hit minus 3. + // CLCT quality is the number of layers hit. + // const int n_gem((pad!=NULL and 1) or (copad!=NULL and 2)); + int n_gem = 0; + if (hasPad) n_gem = 1; + if (hasCoPad) n_gem = 2; + const bool a4(aLCT.getQuality() >= 1); + const bool c4((cLCT.getQuality() >= 4) or (cLCT.getQuality() >= 3 and n_gem>=1)); + // quality = 4; "reserved for low-quality muons in future" + if (!a4 && !c4) quality = 5; // marginal anode and cathode + else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode + else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode + else if ( a4 && c4) { + if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT + else { + // quality = 9; "reserved for HQ muons with future patterns + // quality = 10; "reserved for HQ muons with future patterns + if (pattern == 2 || pattern == 3) quality = 11; + else if (pattern == 4 || pattern == 5) quality = 12; + else if (pattern == 6 || pattern == 7) quality = 13; + else if (pattern == 8 || pattern == 9) quality = 14; + else if (pattern == 10) quality = 15; + else { + if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues") + << "+++ findQuality: Unexpected CLCT pattern id = " + << pattern << "+++\n"; + } + } + } + } + } + } + return quality; +} + + +unsigned int CSCMotherboardME11GEM::findQualityGEM(const CSCCLCTDigi& cLCT, const GEMPadDigi& gem) +{ + return 0; +} + + +void CSCMotherboardME11GEM::printGEMTriggerPads(int bx_start, int bx_stop, bool iscopad) +{ + // pads or copads? + auto thePads(!iscopad ? pads_ : coPads_); + const bool hasPads(thePads.size()!=0); + + std::cout << "------------------------------------------------------------------------" << std::endl; + bool first = true; + for (int bx = bx_start; bx <= bx_stop; bx++) { + // print only the pads for the central BX + if (bx!=lct_central_bx and iscopad) continue; + std::vector > in_pads = thePads[bx]; + if (first) { + if (!iscopad) std::cout << "* GEM trigger pads: " << std::endl; + else std::cout << "* GEM trigger coincidence pads: " << std::endl; + } + first = false; + if (!iscopad) std::cout << "N(pads) BX " << bx << " : " << in_pads.size() << std::endl; + else std::cout << "N(copads) BX " << bx << " : " << in_pads.size() << std::endl; + if (hasPads){ + for (auto pad : in_pads){ + auto roll_id(GEMDetId(pad.first)); + std::cout << "\tdetId " << pad.first << " " << roll_id << ", pad = " << pad.second->pad() << ", BX = " << pad.second->bx() + 6; + if (isPadInOverlap(roll_id.roll())) std::cout << " (in overlap)" << std::endl; + else std::cout << std::endl; + } + } + else + break; + } +} + + +void CSCMotherboardME11GEM::retrieveGEMPads(const GEMPadDigiCollection* gemPads, unsigned id, bool iscopad) +{ + auto superChamber(gem_g->superChamber(id)); + for (auto ch : superChamber->chambers()) { + for (auto roll : ch->etaPartitions()) { + 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) { + auto id_pad = std::make_pair(roll_id(), &(*pad)); + const int bx_shifted(lct_central_bx + pad->bx()); + for (int bx = bx_shifted - maxDeltaBXPad_;bx <= bx_shifted + maxDeltaBXPad_; ++bx) { + if (iscopad){ + if(bx != lct_central_bx) continue; + coPads_[bx].push_back(id_pad); + }else{ + pads_[bx].push_back(id_pad); + } + } + } + } + } +} + + +bool CSCMotherboardME11GEM::isPadInOverlap(int roll) +{ + for (auto& p : cscWgToGemRoll_) { + // overlap region are WGs 10-15 + if ((p.first < 10) or (p.first > 15)) continue; + if (((p.second).first <= roll) and (roll <= (p.second).second)) return true; + } + return false; +} + + +int CSCMotherboardME11GEM::deltaRoll(int wg, int pad) +{ + const auto p(cscWgToGemRoll_[wg]); + return std::min(std::abs(p.first - pad), std::abs(p.second - pad)); +} + + +int CSCMotherboardME11GEM::deltaPad(int hs, int pad) +{ + const auto p(cscHsToGemPadME1b_[hs]); + return std::min(std::abs(p.first - pad), std::abs(p.second - pad)); +} + + +CSCMotherboardME11GEM::GEMPadsBX +CSCMotherboardME11GEM::matchingGEMPads(const CSCCLCTDigi& clct, const GEMPadsBX& pads, enum ME11Part part, bool isCoPad, bool first) +{ + CSCMotherboardME11GEM::GEMPadsBX result; + + // fetch the low and high pad edges + auto mymap(part==ME1A ? cscHsToGemPadME1a_ : cscHsToGemPadME1b_); + int deltaPad(isCoPad ? maxDeltaPadCoPad_ : maxDeltaPadPad_); + const int lowPad(mymap[clct.getKeyStrip()].first); + const int highPad(mymap[clct.getKeyStrip()].second); + const bool debug(false); + if (debug) std::cout << "lowpad " << lowPad << " highpad " << highPad << " delta pad " << deltaPad <pad()); + if (debug) std::cout << "padRoll " << padRoll << std::endl; + if (std::abs(lowPad - padRoll) <= deltaPad or std::abs(padRoll - highPad) <= deltaPad){ + if (debug) std::cout << "++Matches! " << std::endl; + result.push_back(p); + if (first) return result; + } + } + return result; +} + + +CSCMotherboardME11GEM::GEMPadsBX +CSCMotherboardME11GEM::matchingGEMPads(const CSCALCTDigi& alct, const GEMPadsBX& pads, enum ME11Part part, bool isCoPad, bool first) +{ + CSCMotherboardME11GEM::GEMPadsBX result; + + auto alctRoll(cscWgToGemRoll_[alct.getKeyWG()]); + const bool debug(false); + if (debug) std::cout << "ALCT keyWG " << alct.getKeyWG() << ", rolls " << alctRoll.first << " " << alctRoll.second << std::endl; + for (auto p: pads){ + auto padRoll(GEMDetId(p.first).roll()); + if (debug) std::cout << "Candidate ALCT: " << padRoll << std::endl; + // only pads in overlap are good for ME1A + if (part==ME1A and !isPadInOverlap(padRoll)) continue; + if (alctRoll.first == -99 and alctRoll.second == -99) continue; //invalid region + else if (alctRoll.first == -99 and !(padRoll <= alctRoll.second)) continue; // top of the chamber + else if (alctRoll.second == -99 and !(padRoll >= alctRoll.first)) continue; // bottom of the chamber + else if ((alctRoll.first != -99 and alctRoll.second != -99) and // center + (alctRoll.first > padRoll or padRoll > alctRoll.second)) continue; + if (debug) std::cout << "++Matches! " << std::endl; + result.push_back(p); + if (first) return result; + } + return result; +} + + +CSCMotherboardME11GEM::GEMPadsBX +CSCMotherboardME11GEM::matchingGEMPads(const CSCCLCTDigi& clct, const CSCALCTDigi& alct, const GEMPadsBX& pads, + enum ME11Part part, bool isCoPad, bool first) +{ + CSCMotherboardME11GEM::GEMPadsBX result; + + // Fetch all (!) pads matching to ALCTs and CLCTs + auto padsClct(matchingGEMPads(clct, pads, part, isCoPad, false)); + auto padsAlct(matchingGEMPads(alct, pads, part, isCoPad, false)); + + const bool debug(false); + if (debug) std::cout << "-----------------------------------------------------------------------"< CSCMotherboardME11GEM::readoutCoPads() +{ + return gemCoPadV; +} + + +int CSCMotherboardME11GEM::getRandomWGForGEMRoll(int roll) +{ + boost::container::flat_set wgs; + for (auto p: cscWgToGemRoll_) + if (p.first == roll) + wgs.insert(p.first); + // return a random one + return *(wgs.begin() + rand() % wgs.size()); +} diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11GEM.h b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11GEM.h new file mode 100644 index 0000000000000..0c3cd76ba616c --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11GEM.h @@ -0,0 +1,288 @@ +#ifndef CSCTriggerPrimitives_CSCMotherboardME11GEM_h +#define CSCTriggerPrimitives_CSCMotherboardME11GEM_h + +/** \class CSCMotherboardME11GEM + * + * Extended CSCMotherboard for ME11 TMB upgrade + * + * \author Sven Dildick March 2014 + * + * Based on CSCMotherboard code + * + */ + +#include +#include +#include +#include "DataFormats/GEMDigi/interface/GEMCoPadDigiCollection.h" + +class CSCGeometry; +class CSCChamber; +class GEMGeometry; +class GEMSuperChamber; + +class CSCMotherboardME11GEM : public CSCMotherboard +{ + typedef std::pair GEMPadBX; + typedef std::vector GEMPadsBX; + typedef std::map GEMPads; + + public: + /** Normal constructor. */ + CSCMotherboardME11GEM(unsigned endcap, unsigned station, unsigned sector, + unsigned subsector, unsigned chamber, + const edm::ParameterSet& conf); + + /** Constructor for use during testing. */ + CSCMotherboardME11GEM(); + + /** Default destructor. */ + ~CSCMotherboardME11GEM(); + + /** Run function for normal usage. Runs cathode and anode LCT processors, + takes results and correlates into CorrelatedLCT. */ + void run(const CSCWireDigiCollection* wiredc, + const CSCComparatorDigiCollection* compdc, + const GEMPadDigiCollection* gemPads); + + /** Returns vectors of found correlated LCTs in ME1a and ME1b, if any. */ + std::vector getLCTs1a(); + std::vector getLCTs1b(); + + /** labels for ME1a and ME1B */ + enum ME11Part {ME1B = 1, ME1A=4}; + + /** Methods to sort the LCTs */ + std::vector sortLCTsByQuality(int bx, enum ME11Part = ME1B); + std::vector sortLCTsByQuality(enum ME11Part = ME1B); + std::vector sortLCTsByQuality(std::vector); + std::vector sortLCTsByGEMDPhi(int bx, enum ME11Part = ME1B); + std::vector sortLCTsByGEMDPhi(enum ME11Part = ME1B); + std::vector sortLCTsByGEMDPhi(std::vector); + + /** Returns vectors of found ALCTs in ME1a and ME1b, if any. */ + std::vector getALCTs1b() {return alctV;} + + /** Returns vectors of found CLCTs in ME1a and ME1b, if any. */ + std::vector getCLCTs1a() {return clctV1a;} + std::vector getCLCTs1b() {return clctV1b;} + + /** Clears correlated LCT and passes clear signal on to cathode and anode + LCT processors. */ + void clear(); + + /** Set configuration parameters obtained via EventSetup mechanism. */ + void setConfigParameters(const CSCDBL1TPParameters* conf); + + /** additional Cathode LCT processor for ME1a */ + CSCCathodeLCTProcessor* clct1a; + + std::vector readoutLCTs1a(); + std::vector readoutLCTs1b(); + std::vector readoutLCTs(enum ME11Part me1ab); + std::vector readoutCoPads(); + + /// set CSC and GEM geometries for the matching needs + void setCSCGeometry(const CSCGeometry *g) { csc_g = g; } + void setGEMGeometry(const GEMGeometry *g) { gem_g = g; } + + private: + + static const int lut_wg_vs_hs_me1b[48][2]; + static const int lut_wg_vs_hs_me1a[48][2]; + static const int lut_wg_vs_hs_me1ag[48][2]; + static const double lut_pt_vs_dphi_gemcsc[8][3]; + static const double lut_wg_etaMin_etaMax_odd[48][3]; + static const double lut_wg_etaMin_etaMax_even[48][3]; + + /** SLHC: special configuration parameters for ME11 treatment. */ + bool smartME1aME1b, disableME1a, gangedME1a; + + bool doesALCTCrossCLCT(CSCALCTDigi &a, CSCCLCTDigi &c, int me); + + /** Container for first correlated LCT in ME1a. */ + //CSCCorrelatedLCTDigi firstLCT1a[MAX_LCT_BINS]; + + /** Container for second correlated LCT in ME1a. */ + //CSCCorrelatedLCTDigi secondLCT1a[MAX_LCT_BINS]; + + /** for the case when more than 2 LCTs/BX are allowed; + maximum match window = 15 */ + CSCCorrelatedLCTDigi allLCTs1b[MAX_LCT_BINS][15][2]; + CSCCorrelatedLCTDigi allLCTs1a[MAX_LCT_BINS][15][2]; + + void correlateLCTs(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2); + + void correlateLCTsGEM(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2, int me, + const GEMPadsBX& pads = GEMPadsBX(), const GEMPadsBX& copads = GEMPadsBX()); + + void correlateLCTsGEM(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, GEMPadDigi gemPad, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2, int me); + + void correlateLCTsGEM(CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, GEMPadDigi gemPad, int roll, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2, int me); + + void matchGEMPads(enum ME11Part = ME1B); + + void buildCoincidencePads(const GEMPadDigiCollection* out_pads, + GEMPadDigiCollection& out_co_pads, + CSCDetId csc_id); + + void retrieveGEMPads(const GEMPadDigiCollection* pads, unsigned id, bool iscopad = false); + + void createGEMRollEtaLUT(bool isEven); + + int assignGEMRoll(double eta); + int deltaRoll(int wg, int roll); + int deltaPad(int hs, int pad); + int getRandomWGForGEMRoll(int roll); + + CSCCorrelatedLCTDigi constructLCTsGEM(const CSCALCTDigi& alct, const GEMPadDigi& gem, + int me, bool oldDataFormat = false); + CSCCorrelatedLCTDigi constructLCTsGEM(const CSCCLCTDigi& clct, const GEMPadDigi& gem, int roll, + int me, bool oldDataFormat = true); + CSCCorrelatedLCTDigi constructLCTsGEM(const CSCALCTDigi& alct, const CSCCLCTDigi& clct, + bool hasPad, bool hasCoPad); + + unsigned int encodePatternGEM(const int ptn, const int highPt); + unsigned int findQualityGEM(const CSCALCTDigi& aLCT, const GEMPadDigi& gem); + unsigned int findQualityGEM(const CSCCLCTDigi& cLCT, const GEMPadDigi& gem); + unsigned int findQualityGEM(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, + bool hasPad, bool hasCoPad); + + void printGEMTriggerPads(int minBX, int maxBx, bool iscopad = false); + + bool isPadInOverlap(int roll); + + GEMPadsBX matchingGEMPads(const CSCCLCTDigi& cLCT, const GEMPadsBX& pads = GEMPadsBX(), + enum ME11Part = ME1B, bool isCopad = false, bool first = true); + GEMPadsBX matchingGEMPads(const CSCALCTDigi& aLCT, const GEMPadsBX& pads = GEMPadsBX(), + enum ME11Part = ME1B, bool isCopad = false, bool first = true); + GEMPadsBX matchingGEMPads(const CSCCLCTDigi& cLCT, const CSCALCTDigi& aLCT, const GEMPadsBX& pads = GEMPadsBX(), + enum ME11Part = ME1B, bool isCopad = false, bool first = true); + + std::vector alctV; + std::vector clctV1b; + std::vector clctV1a; + std::vector gemCoPadV; + + /** "preferential" index array in matching window for cross-BX sorting */ + int pref[MAX_LCT_BINS]; + + bool match_earliest_alct_me11_only; + bool match_earliest_clct_me11_only; + + /** if true: use regular CLCT-to-ALCT matching in TMB + if false: do ALCT-to-CLCT matching */ + bool clct_to_alct; + + /** whether to not reuse CLCTs that were used by previous matching ALCTs + in ALCT-to-CLCT algorithm */ + bool drop_used_clcts; + + unsigned int tmb_cross_bx_algo; + + /** maximum lcts per BX in ME11: 2, 3, 4 or 999 */ + unsigned int max_me11_lcts; + + /// GEM-CSC integrated local algorithm + bool runME11ILT_; + + /// Do GEM matching? + bool do_gem_matching; + + /// GEM matching dphi and deta + double gem_match_delta_phi_odd; + double gem_match_delta_phi_even; + double gem_match_delta_eta; + + /// delta BX for GEM pads matching + int gem_match_delta_bx; + + /// min eta of LCT for which we require GEM match (we don't throw out LCTs below this min eta) + double gem_match_min_eta; + double gem_match_max_eta; + + /// whether to throw out GEM-fiducial LCTs that have no gem match + bool gem_clear_nomatch_lcts; + + const CSCGeometry* csc_g; + const GEMGeometry* gem_g; + + // debug gem matching + bool debug_gem_matching; + bool debug_luts; + bool debug_gem_dphi; + + // deltas used to construct GEM coincidence pads + int maxDeltaBXInCoPad_; + int maxDeltaPadInCoPad_; + + // deltas used to match to GEM pads + int maxDeltaBXPad_; + int maxDeltaPadPad_; + int maxDeltaBXPadEven_; + int maxDeltaPadPadEven_; + int maxDeltaBXPadOdd_; + int maxDeltaPadPadOdd_; + + // deltas used to match to GEM coincidence pads + int maxDeltaBXCoPad_; + int maxDeltaPadCoPad_; + int maxDeltaBXCoPadEven_; + int maxDeltaPadCoPadEven_; + int maxDeltaBXCoPadOdd_; + int maxDeltaPadCoPadOdd_; + + // Drop low quality stubs if they don't have GEMs + bool dropLowQualityCLCTsNoGEMs_ME1a_; + bool dropLowQualityCLCTsNoGEMs_ME1b_; + bool dropLowQualityALCTsNoGEMs_ME1a_; + bool dropLowQualityALCTsNoGEMs_ME1b_; + + // build LCT from ALCT and GEM + bool buildLCTfromALCTandGEM_ME1a_; + bool buildLCTfromALCTandGEM_ME1b_; + bool buildLCTfromCLCTandGEM_ME1a_; + bool buildLCTfromCLCTandGEM_ME1b_; + + // LCT ghostbusting + bool doLCTGhostBustingWithGEMs_; + + // correct LCT timing with GEMs + bool correctLCTtimingWithGEM_; + + // send LCT old dataformat + bool useOldLCTDataFormatALCTGEM_; + bool useOldLCTDataFormatCLCTGEM_; + + // send only first 2 lcts + bool firstTwoLCTsInChamber_; + + // promote ALCT-GEM pattern + bool promoteALCTGEMpattern_; + + // promote ALCT-GEM quality + bool promoteALCTGEMquality_; + bool promoteCLCTGEMquality_ME1a_; + bool promoteCLCTGEMquality_ME1b_; + + // map of roll N to min and max eta + std::map > gemRollToEtaLimits_; + std::map> cscWgToGemRoll_; + + // map of pad to HS + std::map gemPadToCscHsME1a_; + std::map gemPadToCscHsME1b_; + std::map> cscHsToGemPadME1a_; + std::map> cscHsToGemPadME1b_; + + // map< bx , vector > + GEMPads pads_; + GEMPads coPads_; +}; +#endif diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME21GEM.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME21GEM.cc new file mode 100644 index 0000000000000..3b16e3e6b472a --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME21GEM.cc @@ -0,0 +1,1408 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "boost/container/flat_set.hpp" + +const double CSCMotherboardME21GEM::lut_wg_eta_odd[112][2] = { +{ 0,2.441},{ 1,2.435},{ 2,2.425},{ 3,2.414},{ 4,2.404},{ 5,2.394},{ 6,2.384},{ 7,2.374}, +{ 8,2.365},{ 9,2.355},{10,2.346},{11,2.336},{12,2.327},{13,2.317},{14,2.308},{15,2.299}, +{16,2.290},{17,2.281},{18,2.273},{19,2.264},{20,2.255},{21,2.247},{22,2.238},{23,2.230}, +{24,2.221},{25,2.213},{26,2.205},{27,2.197},{28,2.189},{29,2.181},{30,2.173},{31,2.165}, +{32,2.157},{33,2.149},{34,2.142},{35,2.134},{36,2.127},{37,2.119},{38,2.112},{39,2.104}, +{40,2.097},{41,2.090},{42,2.083},{43,2.075},{44,2.070},{45,2.059},{46,2.054},{47,2.047}, +{48,2.041},{49,2.034},{50,2.027},{51,2.020},{52,2.014},{53,2.007},{54,2.000},{55,1.994}, +{56,1.988},{57,1.981},{58,1.975},{59,1.968},{60,1.962},{61,1.956},{62,1.950},{63,1.944}, +{64,1.937},{65,1.931},{66,1.924},{67,1.916},{68,1.909},{69,1.902},{70,1.895},{71,1.888}, +{72,1.881},{73,1.875},{74,1.868},{75,1.861},{76,1.854},{77,1.848},{78,1.841},{79,1.835}, +{80,1.830},{81,1.820},{82,1.815},{83,1.809},{84,1.803},{85,1.796},{86,1.790},{87,1.784}, +{88,1.778},{89,1.772},{90,1.766},{91,1.760},{92,1.754},{93,1.748},{94,1.742},{95,1.736}, +{96,1.731},{97,1.725},{98,1.719},{99,1.714},{100,1.708},{101,1.702},{102,1.697},{103,1.691}, +{104,1.686},{105,1.680},{106,1.675},{107,1.670},{108,1.664},{109,1.659},{110,1.654},{111,1.648}, +}; + +const double CSCMotherboardME21GEM::lut_wg_eta_even[112][2] = { +{ 0,2.412},{ 1,2.405},{ 2,2.395},{ 3,2.385},{ 4,2.375},{ 5,2.365},{ 6,2.355},{ 7,2.345}, +{ 8,2.335},{ 9,2.325},{10,2.316},{11,2.306},{12,2.297},{13,2.288},{14,2.279},{15,2.270}, +{16,2.261},{17,2.252},{18,2.243},{19,2.234},{20,2.226},{21,2.217},{22,2.209},{23,2.200}, +{24,2.192},{25,2.184},{26,2.175},{27,2.167},{28,2.159},{29,2.151},{30,2.143},{31,2.135}, +{32,2.128},{33,2.120},{34,2.112},{35,2.105},{36,2.097},{37,2.090},{38,2.082},{39,2.075}, +{40,2.068},{41,2.060},{42,2.053},{43,2.046},{44,2.041},{45,2.030},{46,2.025},{47,2.018}, +{48,2.011},{49,2.005},{50,1.998},{51,1.991},{52,1.985},{53,1.978},{54,1.971},{55,1.965}, +{56,1.958},{57,1.952},{58,1.946},{59,1.939},{60,1.933},{61,1.927},{62,1.921},{63,1.915}, +{64,1.909},{65,1.902},{66,1.895},{67,1.887},{68,1.880},{69,1.873},{70,1.866},{71,1.859}, +{72,1.853},{73,1.846},{74,1.839},{75,1.832},{76,1.826},{77,1.819},{78,1.812},{79,1.806}, +{80,1.801},{81,1.792},{82,1.787},{83,1.780},{84,1.774},{85,1.768},{86,1.762},{87,1.756}, +{88,1.750},{89,1.744},{90,1.738},{91,1.732},{92,1.726},{93,1.720},{94,1.714},{95,1.708}, +{96,1.702},{97,1.697},{98,1.691},{99,1.685},{100,1.680},{101,1.674},{102,1.669},{103,1.663}, +{104,1.658},{105,1.652},{106,1.647},{107,1.642},{108,1.636},{109,1.631},{110,1.626},{111,1.621}, +}; + +// LUT with bending angles of the GEM-CSC high efficiency patterns (98%) +// 1st index: pt value = {5,10,15,20,30,40} +// 2nd index: bending angle for odd numbered chambers +// 3rd index: bending angle for even numbered chambers +const double CSCMotherboardME21GEM::lut_pt_vs_dphi_gemcsc[8][3] = { + {3, 0.01832829, 0.01003643 }, + {5, 0.01095490, 0.00631625 }, + {7, 0.00786026, 0.00501017 }, + {10, 0.00596349, 0.00414560 }, + {15, 0.00462411, 0.00365550 }, + {20, 0.00435298, 0.00361550 }, + {30, 0.00465160, 0.00335700 }, + {40, 0.00372145, 0.00366262 } +}; + +CSCMotherboardME21GEM::CSCMotherboardME21GEM(unsigned endcap, unsigned station, + unsigned sector, unsigned subsector, + unsigned chamber, + const edm::ParameterSet& conf) : + CSCMotherboard(endcap, station, sector, subsector, chamber, conf) +{ + const edm::ParameterSet commonParams(conf.getParameter("commonParam")); + runME21ILT_ = commonParams.getParameter("runME21ILT"); + + if (!isSLHC) edm::LogError("L1CSCTPEmulatorConfigError") + << "+++ Upgrade CSCMotherboardME21GEM constructed while isSLHC is not set! +++\n"; + + const edm::ParameterSet me21tmbParams(conf.getParameter("me21tmbSLHCGEM")); + + // whether to not reuse CLCTs that were used by previous matching ALCTs + // in ALCT-to-CLCT algorithm + drop_used_clcts = me21tmbParams.getParameter("tmbDropUsedClcts"); + + match_earliest_clct_me21_only = me21tmbParams.getParameter("matchEarliestClctME21Only"); + + tmb_cross_bx_algo = me21tmbParams.getParameter("tmbCrossBxAlgorithm"); + + // maximum lcts per BX in ME2 + max_me21_lcts = me21tmbParams.getParameter("maxME21LCTs"); + + pref[0] = match_trig_window_size/2; + for (unsigned int m=2; m("doGemMatching"); + + /// GEM matching dphi and deta + gem_match_delta_phi_odd = me21tmbParams.getParameter("gemMatchDeltaPhiOdd"); + gem_match_delta_phi_even = me21tmbParams.getParameter("gemMatchDeltaPhiEven"); + gem_match_delta_eta = me21tmbParams.getParameter("gemMatchDeltaEta"); + + /// delta BX for GEM pads matching + gem_match_delta_bx = me21tmbParams.getParameter("gemMatchDeltaBX"); + + /// min eta of LCT for which we require GEM match (we don't throw out LCTs below this min eta) + gem_match_min_eta = me21tmbParams.getParameter("gemMatchMinEta"); + gem_match_max_eta = me21tmbParams.getParameter("gemMatchMaxEta"); + + /// whether to throw out GEM-fiducial LCTs that have no gem match + gem_clear_nomatch_lcts = me21tmbParams.getParameter("gemClearNomatchLCTs"); + + // debug gem matching + debug_gem_matching = me21tmbParams.getParameter("debugMatching"); + debug_luts = me21tmbParams.getParameter("debugLUTs"); + debug_gem_dphi = me21tmbParams.getParameter("debugGEMDphi"); + + // deltas used to construct GEM coincidence pads + maxDeltaBXInCoPad_ = me21tmbParams.getParameter("maxDeltaBXInCoPad"); + maxDeltaPadInCoPad_ = me21tmbParams.getParameter("maxDeltaPadInCoPad"); + + // deltas used to match to GEM pads + maxDeltaBXPad_ = me21tmbParams.getParameter("maxDeltaBXPad"); + maxDeltaPadPadOdd_ = me21tmbParams.getParameter("maxDeltaPadPadOdd"); + maxDeltaPadPadEven_ = me21tmbParams.getParameter("maxDeltaPadPadEven"); + maxDeltaWg_ = me21tmbParams.getParameter("maxDeltaWg"); + + // deltas used to match to GEM coincidence pads + maxDeltaBXCoPad_ = me21tmbParams.getParameter("maxDeltaBXCoPad"); + maxDeltaPadCoPad_ = me21tmbParams.getParameter("maxDeltaPadCoPad"); + + // drop low quality stubs if they don't have GEMs + dropLowQualityCLCTsNoGEMs_ = me21tmbParams.getParameter("dropLowQualityCLCTsNoGEMs"); + dropLowQualityALCTsNoGEMs_ = me21tmbParams.getParameter("dropLowQualityALCTsNoGEMs"); + + // correct LCT timing with GEMs + correctLCTtimingWithGEM_ = me21tmbParams.getParameter("correctLCTtimingWithGEM"); + + // build LCT from ALCT and GEM + buildLCTfromALCTandGEM_ = me21tmbParams.getParameter("buildLCTfromALCTandGEM"); + buildLCTfromCLCTandGEM_ = me21tmbParams.getParameter("buildLCTfromCLCTandGEM"); + + // LCT ghostbusting + doLCTGhostBustingWithGEMs_ = me21tmbParams.getParameter("doLCTGhostBustingWithGEMs"); + + // use "old" or "new" dataformat for integrated LCTs? + useOldLCTDataFormatALCTGEM_ = me21tmbParams.getParameter("useOldLCTDataFormatALCTGEM"); + useOldLCTDataFormatCLCTGEM_ = me21tmbParams.getParameter("useOldLCTDataFormatCLCTGEM"); + + // promote ALCT-GEM pattern + promoteALCTGEMpattern_ = me21tmbParams.getParameter("promoteALCTGEMpattern"); + + // promote ALCT-GEM quality + promoteALCTGEMquality_ = me21tmbParams.getParameter("promoteALCTGEMquality"); + promoteCLCTGEMquality_ = me21tmbParams.getParameter("promoteCLCTGEMquality"); +} + +CSCMotherboardME21GEM::~CSCMotherboardME21GEM() +{ +} + +void CSCMotherboardME21GEM::clear() +{ + CSCMotherboard::clear(); + + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + allLCTs[bx][mbx][i].clear(); + + gemRollToEtaLimits_.clear(); + cscWgToGemRoll_.clear(); + gemPadToCscHs_.clear(); + cscHsToGemPad_.clear(); + pads_.clear(); + coPads_.clear(); +} + +void +CSCMotherboardME21GEM::run(const CSCWireDigiCollection* wiredc, + const CSCComparatorDigiCollection* compdc, + const GEMPadDigiCollection* gemPads) +{ + /* + + + clear(); + + if (!( alct and clct and runME21ILT_)) + { + if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError") + << "+++ run() called for non-existing ALCT/CLCT processor! +++ \n"; + return; + } + + alct->run(wiredc); // run anodeLCT + clct->run(compdc); // run cathodeLCT + + bool gemGeometryAvailable(false); + if (gem_g != nullptr) { + if (infoV >= 0) edm::LogInfo("L1CSCTPEmulatorSetupInfo") + << "+++ run() called for GEM-CSC integrated trigger! +++ \n"; + gemGeometryAvailable = true; + } + + // retrieve CSCChamber geometry + CSCTriggerGeomManager* geo_manager(CSCTriggerGeometry::get()); + const CSCChamber* cscChamber(geo_manager->chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber)); + const CSCDetId csc_id(cscChamber->id()); + + if (runME21ILT_){ + + // check for GE2/1 geometry + if ((not gemGeometryAvailable) or (gemGeometryAvailable and (gem_g->stations()).size()==2)) { + if (infoV >= 0) edm::LogError("L1CSCTPEmulatorSetupError") + << "+++ run() called for GEM-CSC integrated trigger without valid GE21 geometry! +++ \n"; + return; + } + + // trigger geometry + const CSCLayer* keyLayer(cscChamber->layer(3)); + const CSCLayerGeometry* keyLayerGeometry(keyLayer->geometry()); + + // const bool isEven(csc_id%2==0); + const int region((theEndcap == 1) ? 1: -1); + const bool isEven(csc_id.chamber()%2==0); + const GEMDetId gem_id_long(region, 1, 3, 1, csc_id.chamber(), 0); + const GEMChamber* gemChamberLong(gem_g->chamber(gem_id_long)); + + // LUT > + gemRollToEtaLimits_ = createGEMRollEtaLUT(); + + if (debug_luts){ + std::cout<<"csc id "<< csc_id <<" "<< csc_id.rawId() << (isEven ? " even" : " odd") << " chamber" << csc_id.chamber()< + const int numberOfWG(keyLayerGeometry->numberOfWireGroups()); + for (int i = 0; i< numberOfWG; ++i){ + auto eta(isEven ? lut_wg_eta_even[i][1] : lut_wg_eta_odd[i][1]); + cscWgToGemRoll_[i] = assignGEMRoll(eta); + } + if (debug_luts){ + for(auto p : cscWgToGemRoll_) { + std::cout << "WG "<< p.first << " GEM roll " << p.second << std::endl; + } + } + + auto randRoll(gemChamberLong->etaPartition(2)); + auto nStrips(keyLayerGeometry->numberOfStrips()); + for (float i = 0; i< nStrips; i = i+0.5){ + const LocalPoint lpCSC(keyLayerGeometry->topology()->localPosition(i)); + const GlobalPoint gp(keyLayer->toGlobal(lpCSC)); + const LocalPoint lpGEM(randRoll->toLocal(gp)); + const int HS(i/0.5); + const bool edge(HS < 5 or HS > 155); + const float pad(edge ? -99 : randRoll->pad(lpGEM)); + // HS are wrapped-around + cscHsToGemPad_[HS] = std::make_pair(std::floor(pad),std::ceil(pad)); + } + if (debug_luts){ + std::cout << "detId " << csc_id << std::endl; + for(auto p : cscHsToGemPad_) { + std::cout << "CSC HS "<< p.first << " GEM Pad low " << (p.second).first << " GEM Pad high " << (p.second).second << std::endl; + } + } + + // pick any roll + const int nGEMPads(randRoll->npads()); + for (int i = 0; i< nGEMPads; ++i){ + const LocalPoint lpGEM(randRoll->centreOfPad(i)); + const GlobalPoint gp(randRoll->toGlobal(lpGEM)); + const LocalPoint lpCSC(keyLayer->toLocal(gp)); + const float strip(keyLayerGeometry->strip(lpCSC)); + // HS are wrapped-around + gemPadToCscHs_[i] = (int) (strip - 0.25)/0.5; + } + if (debug_luts){ + std::cout << "detId " << csc_id << std::endl; + for(auto p : gemPadToCscHs_) { + std::cout << "GEM Pad "<< p.first << " CSC HS : " << p.second << std::endl; + } + } + + //select correct scenario, even or odd + maxDeltaPadPad_ = (isEven ? maxDeltaPadPadEven_ : maxDeltaPadPadOdd_); + // build coincidence pads + //std::auto_ptr pCoPads(new GEMPadDigiCollection()); + GEMPadDigiCollection *GEMCoPad(new GEMPadDigiCollection()); + buildCoincidencePads(gemPads, *GEMCoPad, csc_id); + + // retrieve pads and copads in a certain BX window for this CSC + pads_ = retrieveGEMPads(gemPads, gem_id_long); + //coPads_ = retrieveGEMPads(pCoPads.get(), gem_id_long, true); + coPads_ = retrieveGEMPads( GEMCoPad, gem_id_long, true); + } + + const bool hasPads(pads_.size()!=0); + const bool hasCoPads(hasPads and coPads_.size()!=0); + + int used_clct_mask[20]; + for (int c=0;c<20;++c) used_clct_mask[c]=0; + + // ALCT centric matching + for (int bx_alct = 0; bx_alct < CSCAnodeLCTProcessor::MAX_ALCT_BINS; bx_alct++) + { + if (alct->bestALCT[bx_alct].isValid()) + { + const int bx_clct_start(bx_alct - match_trig_window_size/2); + const int bx_clct_stop(bx_alct + match_trig_window_size/2); + const int bx_copad_start(bx_alct - maxDeltaBXCoPad_); + const int bx_copad_stop(bx_alct + maxDeltaBXCoPad_); + + if (debug_gem_matching){ + std::cout << "========================================================================" << std::endl; + std::cout << "ALCT-CLCT matching in ME2/1 chamber: " << cscChamber->id() << std::endl; + std::cout << "------------------------------------------------------------------------" << std::endl; + std::cout << "+++ Best ALCT Details: "; + alct->bestALCT[bx_alct].print(); + std::cout << "+++ Second ALCT Details: "; + alct->secondALCT[bx_alct].print(); + + //printGEMTriggerPads(bx_clct_start, bx_clct_stop, true); + //printGEMTriggerPads(bx_clct_start, bx_clct_stop, true, true); + printGEMTriggerPads(bx_clct_start, bx_clct_stop, false); + printGEMTriggerPads(bx_clct_start, bx_clct_stop, false, true); + + std::cout << "------------------------------------------------------------------------" << std::endl; + std::cout << "Attempt ALCT-CLCT matching in ME2/1 in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl; + } + + // ALCT-to-CLCT + int nSuccesFulMatches = 0; + for (int bx_clct = bx_clct_start; bx_clct <= bx_clct_stop; bx_clct++) + { + if (bx_clct < 0 or bx_clct >= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue; + if (drop_used_clcts and used_clct_mask[bx_clct]) continue; + if (clct->bestCLCT[bx_clct].isValid()) + { + // clct quality + const int quality(clct->bestCLCT[bx_clct].getQuality()); + // low quality ALCT + const bool lowQualityALCT(alct->bestALCT[bx_alct].getQuality() == 0); + // low quality ALCT or CLCT + const bool lowQuality(quality<4 or lowQualityALCT); + if (debug_gem_matching) std::cout << "++Valid ME21 CLCT: " << clct->bestCLCT[bx_clct] << std::endl; + + // pick the pad that corresponds + auto matchingPads(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], pads_[bx_clct], false)); + auto matchingCoPads(matchingGEMPads(clct->bestCLCT[bx_clct], alct->bestALCT[bx_alct], coPads_[bx_clct], true)); + if (runME21ILT_ and dropLowQualityCLCTsNoGEMs_ and lowQuality and hasPads){ + int nFound(matchingPads.size()); + const bool clctInEdge(clct->bestCLCT[bx_clct].getKeyStrip() < 5 or clct->bestCLCT[bx_clct].getKeyStrip() > 155); + if (clctInEdge){ + if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT in CSC chamber edge, don't care about GEM pads" << std::endl; + } + else { + if (nFound != 0){ + if (debug_gem_matching) std::cout << "\tInfo: low quality CLCT with " << nFound << " matching GEM trigger pads" << std::endl; + } + else { + if (debug_gem_matching) std::cout << "\tWarning: low quality CLCT without matching GEM trigger pad" << std::endl; + continue; + } + } + } + + // check timing + if (runME21ILT_ and correctLCTtimingWithGEM_){ + int nFound(matchingCoPads.size()); + if (nFound != 0 and bx_alct == 6 and bx_clct != 6){ + if (debug_gem_matching) std::cout << "\tInfo: CLCT with incorrect timing" << std::endl; + continue; + } + } + + ++nSuccesFulMatches; + + int mbx = bx_clct-bx_clct_start; + + correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct], + clct->bestCLCT[bx_clct], clct->secondCLCT[bx_clct], + allLCTs[bx_alct][mbx][0], allLCTs[bx_alct][mbx][1], matchingPads, matchingCoPads); + if (debug_gem_matching) { + // if (infoV > 1) LogTrace("CSCMotherboard") + std::cout << "Successful ALCT-CLCT match in ME21: bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop + << "]; bx_clct = " << bx_clct << std::endl; + std::cout << "+++ Best CLCT Details: "; + clct->bestCLCT[bx_clct].print(); + std::cout << "+++ Second CLCT Details: "; + clct->secondCLCT[bx_clct].print(); + } + if (allLCTs[bx_alct][mbx][0].isValid()) { + used_clct_mask[bx_clct] += 1; + if (match_earliest_clct_me21_only) break; + } + } + } + + // ALCT-to-GEM matching + int nSuccesFulGEMMatches = 0; + if (runME21ILT_ and nSuccesFulMatches==0 and buildLCTfromALCTandGEM_){ + if (debug_gem_matching) std::cout << "++No valid ALCT-CLCT matches in ME21" << std::endl; + for (int bx_gem = bx_copad_start; bx_gem <= bx_copad_stop; bx_gem++) { + if (not hasCoPads) { + continue; + } + + // find the best matching copad - first one + auto copads(matchingGEMPads(alct->bestALCT[bx_alct], coPads_[bx_gem], true)); + if (debug_gem_matching) std::cout << "\t++Number of matching GEM CoPads in BX " << bx_alct << " : "<< copads.size() << std::endl; + if (copads.size()==0) { + continue; + } + + correlateLCTsGEM(alct->bestALCT[bx_alct], alct->secondALCT[bx_alct], + *(copads.at(0)).second, allLCTs[bx_alct][0][0], allLCTs[bx_alct][0][1]); + if (allLCTs[bx_alct][0][0].isValid()) { + ++nSuccesFulGEMMatches; + if (match_earliest_clct_me21_only) break; + } + if (debug_gem_matching) { + std::cout << "Successful ALCT-GEM CoPad match in ME21: bx_alct = " << bx_alct << std::endl << std::endl; + std::cout << "------------------------------------------------------------------------" << std::endl << std::endl; + } + } + } + + if (debug_gem_matching) { + std::cout << "========================================================================" << std::endl; + std::cout << "Summary: " << std::endl; + if (nSuccesFulMatches>1) + std::cout << "Too many successful ALCT-CLCT matches in ME21: " << nSuccesFulMatches + << ", CSCDetId " << cscChamber->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else if (nSuccesFulMatches==1) + std::cout << "1 successful ALCT-CLCT match in ME21: " + << " CSCDetId " << cscChamber->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else if (nSuccesFulGEMMatches==1) + std::cout << "1 successful ALCT-GEM match in ME21: " + << " CSCDetId " << cscChamber->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + else + std::cout << "Unsuccessful ALCT-CLCT match in ME21: " + << "CSCDetId " << cscChamber->id() + << ", bx_alct = " << bx_alct + << "; match window: [" << bx_clct_start << "; " << bx_clct_stop << "]" << std::endl; + } + } + // at this point we have invalid ALCTs --> try GEM pad matching + else{ + auto coPads(coPads_[bx_alct]); + if (runME21ILT_ and coPads.size() and buildLCTfromCLCTandGEM_) { + //const int bx_clct_start(bx_alct - match_trig_window_size/2); + //const int bx_clct_stop(bx_alct + match_trig_window_size/2); + + if (debug_gem_matching){ + std::cout << "========================================================================" << std::endl; + // std::cout << "GEM-CLCT matching in ME2/1 chamber: " << cscChamber->id() << " in bx range: [" << bx_clct_start << "," << bx_clct_stop << "]" << std::endl; + std::cout <<"GEM-CLCT matching in ME2/1 chamber: "<< cscChamber->id()<< "in bx:"<= CSCCathodeLCTProcessor::MAX_CLCT_BINS) continue; + if (drop_used_clcts and used_clct_mask[bx_alct]) continue; + if (clct->bestCLCT[bx_alct].isValid()) + { + const int quality(clct->bestCLCT[bx_alct].getQuality()); + // only use high-Q stubs for the time being + if (quality < 4) continue; + + ++nSuccesFulMatches; + + int mbx = std::abs(clct->bestCLCT[bx_alct].getBX()-bx_alct); + int bx_gem = (coPads[0].second)->bx()+lct_central_bx; + correlateLCTsGEM(clct->bestCLCT[bx_alct], clct->secondCLCT[bx_alct], *(coPads[0].second), GEMDetId(coPads[0].first).roll(), + allLCTs[bx_gem][mbx][0], allLCTs[bx_gem][mbx][1]); + if (debug_gem_matching) { + // if (infoV > 1) LogTrace("CSCMotherboard") + std::cout << "Successful GEM-CLCT match in ME21: bx_alct = " << bx_alct <bestCLCT[bx_alct].print(); + std::cout << "+++ Second CLCT Details: "; + clct->secondCLCT[bx_alct].print(); + } + if (allLCTs[bx_gem][mbx][0].isValid()) { + used_clct_mask[bx_alct] += 1; + if (match_earliest_clct_me21_only) break; + } + } + } + } + } + + // Possibly use some discrimination from GEMs + if (gemGeometryAvailable and runME21ILT_ and do_gem_matching) matchGEMPads(); + + // reduction of nLCTs per each BX + for (int bx = 0; bx < MAX_LCT_BINS; bx++) + { + // counting + unsigned int n=0; + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + int cbx = bx + mbx - match_trig_window_size/2; + if (allLCTs[bx][mbx][i].isValid()) + { + ++n; + if (infoV > 0) LogDebug("CSCMotherboard") + << "LCT"<2)) + { + n=0; + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + if (allLCTs[bx][pref[mbx]][i].isValid()) + { + n++; + if (n>2) allLCTs[bx][pref[mbx]][i].clear(); + } + } + + n=0; + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + { + int cbx = bx + mbx - match_trig_window_size/2; + if (allLCTs[bx][mbx][i].isValid()) + { + n++; + if (infoV > 0) LogDebug("CSCMotherboard") + << "LCT"< 0 and n>0) LogDebug("CSCMotherboard") + <<"bx "< CSCMotherboardME21GEM::readoutLCTs() +{ + return getLCTs(); +} + +//getLCTs when we use different sort algorithm +std::vector CSCMotherboardME21GEM::getLCTs() +{ + std::vector result; + for (int bx = 0; bx < MAX_LCT_BINS; bx++) { + std::vector tmpV; + if (tmb_cross_bx_algo == 2) { + tmpV = sortLCTsByQuality(bx); + result.insert(result.end(), tmpV.begin(), tmpV.end()); + } + else if (tmb_cross_bx_algo == 3) { + tmpV = sortLCTsByGEMDPhi(bx); + result.insert(result.end(), tmpV.begin(), tmpV.end()); + } + else { + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) { + for (int i=0;i<2;i++) { + if (allLCTs[bx][mbx][i].isValid()) { + result.push_back(allLCTs[bx][mbx][i]); + } + } + } + } + } + return result; +} + +//sort LCTs by Quality in each BX +std::vector CSCMotherboardME21GEM::sortLCTsByQuality(int bx) +{ + std::vector LCTs; + LCTs.clear(); + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + if (allLCTs[bx][mbx][i].isValid()) + LCTs.push_back(allLCTs[bx][mbx][i]); + + //std::cout<<"LCT before sorting in Bx:"< max_me21_lcts) LCTs.erase(LCTs.begin()+max_me21_lcts, LCTs.end()); + //std::cout<<"LCT after sorting by quality in BX:"< CSCMotherboardME21GEM::sortLCTsByGEMDPhi(int bx) +{ + std::vector LCTs; + LCTs.clear(); + for (unsigned int mbx = 0; mbx < match_trig_window_size; mbx++) + for (int i=0;i<2;i++) + if (allLCTs[bx][mbx][i].isValid()) + LCTs.push_back(allLCTs[bx][mbx][i]); + + // return sorted vector with 2 highest quality LCTs + std::sort(LCTs.begin(), LCTs.end(), CSCMotherboard::sortByGEMDphi); + if (LCTs.size()> max_me21_lcts) LCTs.erase(LCTs.begin()+max_me21_lcts, LCTs.end()); + return LCTs; +} + + +void CSCMotherboardME21GEM::correlateLCTsGEM(CSCALCTDigi bestALCT, + CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, + CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2, + const GEMPadsBX& pads, + const GEMPadsBX& copads) +{ + // check for pads + const int nPads(pads.size()); + const int nCoPads(copads.size()); + const bool hasPads(nPads!=0); + const bool hasCoPads(nCoPads!=0); + + bool anodeBestValid = bestALCT.isValid(); + bool anodeSecondValid = secondALCT.isValid(); + bool cathodeBestValid = bestCLCT.isValid(); + bool cathodeSecondValid = secondCLCT.isValid(); + + if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT; + if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT; + if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT; + if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT; + + // ALCT-CLCT matching conditions are defined by "trig_enable" configuration + // parameters. + if ((alct_trig_enable and bestALCT.isValid()) or + (clct_trig_enable and bestCLCT.isValid()) or + (match_trig_enable and bestALCT.isValid() and bestCLCT.isValid())) + { + lct1 = constructLCTsGEM(bestALCT, bestCLCT, hasPads, hasCoPads); + lct1.setTrknmb(1); + } + + if (((secondALCT != bestALCT) or (secondCLCT != bestCLCT)) and + ((alct_trig_enable and secondALCT.isValid()) or + (clct_trig_enable and secondCLCT.isValid()) or + (match_trig_enable and secondALCT.isValid() and secondCLCT.isValid()))) + { + lct2 = constructLCTsGEM(secondALCT, secondCLCT, hasPads, hasCoPads); + lct2.setTrknmb(2); + } +} + + +void CSCMotherboardME21GEM::correlateLCTsGEM(CSCALCTDigi bestALCT, + CSCALCTDigi secondALCT, + GEMPadDigi gemPad, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2) +{ + bool anodeBestValid = bestALCT.isValid(); + bool anodeSecondValid = secondALCT.isValid(); + + if (anodeBestValid and !anodeSecondValid) secondALCT = bestALCT; + if (!anodeBestValid and anodeSecondValid) bestALCT = secondALCT; + + if ((alct_trig_enable and bestALCT.isValid()) or + (match_trig_enable and bestALCT.isValid())) + { + lct1 = constructLCTsGEM(bestALCT, gemPad, useOldLCTDataFormatALCTGEM_); + lct1.setTrknmb(1); + // lct1.setGEMDPhi(0.0); + } + + if ((alct_trig_enable and secondALCT.isValid()) or + (match_trig_enable and secondALCT.isValid() and secondALCT != bestALCT)) + { + lct2 = constructLCTsGEM(secondALCT, gemPad, useOldLCTDataFormatALCTGEM_); + lct2.setTrknmb(2); + // lct2.setGEMDPhi(0.0); + } +} + + +void CSCMotherboardME21GEM::correlateLCTsGEM(CSCCLCTDigi bestCLCT, + CSCCLCTDigi secondCLCT, + GEMPadDigi gemPad, int roll, + CSCCorrelatedLCTDigi& lct1, + CSCCorrelatedLCTDigi& lct2) +{ + bool cathodeBestValid = bestCLCT.isValid(); + bool cathodeSecondValid = secondCLCT.isValid(); + + if (cathodeBestValid and !cathodeSecondValid) secondCLCT = bestCLCT; + if (!cathodeBestValid and cathodeSecondValid) bestCLCT = secondCLCT; + + if ((clct_trig_enable and bestCLCT.isValid()) or + (match_trig_enable and bestCLCT.isValid())) + { + lct1 = constructLCTsGEM(bestCLCT, gemPad, roll, useOldLCTDataFormatCLCTGEM_); + lct1.setTrknmb(1); + } + + if ((clct_trig_enable and secondCLCT.isValid()) or + (match_trig_enable and secondCLCT.isValid() and secondCLCT != bestCLCT)) + { + lct2 = constructLCTsGEM(secondCLCT, gemPad, roll, useOldLCTDataFormatCLCTGEM_); + lct2.setTrknmb(2); + } +} + + +CSCCorrelatedLCTDigi CSCMotherboardME21GEM::constructLCTsGEM(const CSCALCTDigi& alct, + const GEMPadDigi& gem, + bool oldDataFormat) +{ + if (oldDataFormat){ + // CLCT pattern number - set it to a highest value + // hack to get LCTs in the CSCTF + unsigned int pattern = promoteALCTGEMpattern_ ? 10 : 0; + + // LCT quality number - set it to a very high value + // hack to get LCTs in the CSCTF + unsigned int quality = promoteALCTGEMquality_ ? 14 : 11; + + // Bunch crossing + int bx = alct.getBX(); + + // get keyStrip from LUT + int keyStrip = gemPadToCscHs_[gem.pad()]; + + // get wiregroup from ALCT + int wg = alct.getKeyWG(); + + // construct correlated LCT; temporarily assign track number of 0. + return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber); + } + else { + // CLCT pattern number - no pattern + unsigned int pattern = 0; + + // LCT quality number + unsigned int quality = 1; + + // Bunch crossing + int bx = gem.bx() + lct_central_bx; + + // get keyStrip from LUT + int keyStrip = gemPadToCscHs_[gem.pad()]; + // get wiregroup from ALCT + int wg = alct.getKeyWG(); + + // construct correlated LCT; temporarily assign track number of 0. + return CSCCorrelatedLCTDigi(0, 1, quality, wg, keyStrip, pattern, 0, bx, 0, 0, 0, theTrigChamber); + } +} + +CSCCorrelatedLCTDigi CSCMotherboardME21GEM::constructLCTsGEM(const CSCCLCTDigi& clct, + const GEMPadDigi& gem, int roll, + bool oldDataFormat) +{ + if (oldDataFormat){ + // CLCT pattern number - for the time being, do not include GEMs in the pattern + unsigned int pattern = encodePattern(clct.getPattern(), clct.getStripType()); + + // LCT quality number - dummy quality + unsigned int quality = promoteCLCTGEMquality_ ? 14 : 11; + + // Bunch crossing: pick GEM bx + int bx = gem.bx() + lct_central_bx; + + // pick a random WG in the roll range + int wg(getRandomWGForGEMRoll(roll)); + + // construct correlated LCT; temporarily assign track number of 0. + return CSCCorrelatedLCTDigi(0, 1, quality, wg, clct.getKeyStrip(), pattern, clct.getBend(), bx, 0, 0, 0, theTrigChamber); + } + else { + // CLCT pattern number - no pattern + unsigned int pattern = 0;//encodePatternGEM(clct.getPattern(), clct.getStripType()); + + // LCT quality number - dummy quality + unsigned int quality = 5;//findQualityGEM(alct, gem); + + // Bunch crossing: get it from cathode LCT if anode LCT is not there. + int bx = gem.bx() + lct_central_bx;; + + // ALCT WG + int wg(0); + + // construct correlated LCT; temporarily assign track number of 0. + return CSCCorrelatedLCTDigi(0, 1, quality, wg, 0, pattern, 0, bx, 0, 0, 0, theTrigChamber); + } +} + + +CSCCorrelatedLCTDigi CSCMotherboardME21GEM::constructLCTsGEM(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, + bool hasPad, bool hasCoPad) +{ + // CLCT pattern number + unsigned int pattern = encodePattern(cLCT.getPattern(), cLCT.getStripType()); + + // LCT quality number + unsigned int quality = findQualityGEM(aLCT, cLCT, hasPad, hasCoPad); + + // Bunch crossing: get it from cathode LCT if anode LCT is not there. + int bx = aLCT.isValid() ? aLCT.getBX() : cLCT.getBX(); + + // construct correlated LCT; temporarily assign track number of 0. + int trknmb = 0; + CSCCorrelatedLCTDigi thisLCT(trknmb, 1, quality, aLCT.getKeyWG(), + cLCT.getKeyStrip(), pattern, cLCT.getBend(), + bx, 0, 0, 0, theTrigChamber); + return thisLCT; +} + + +unsigned int CSCMotherboardME21GEM::findQualityGEM(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, + bool hasPad, bool hasCoPad) +{ + + /* + Same LCT quality definition as standard LCTs + c4 takes GEMs into account!!! + */ + + unsigned int quality = 0; + + if (!isTMB07) { + bool isDistrip = (cLCT.getStripType() == 0); + + if (aLCT.isValid() && !(cLCT.isValid())) { // no CLCT + if (aLCT.getAccelerator()) {quality = 1;} + else {quality = 3;} + } + else if (!(aLCT.isValid()) && cLCT.isValid()) { // no ALCT + if (isDistrip) {quality = 4;} + else {quality = 5;} + } + else if (aLCT.isValid() && cLCT.isValid()) { // both ALCT and CLCT + if (aLCT.getAccelerator()) {quality = 2;} // accelerator muon + else { // collision muon + // CLCT quality is, in fact, the number of layers hit, so subtract 3 + // to get quality analogous to ALCT one. + int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3); + if (sumQual < 1 || sumQual > 6) { + if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues") + << "+++ findQuality: sumQual = " << sumQual << "+++ \n"; + } + if (isDistrip) { // distrip pattern + if (sumQual == 2) {quality = 6;} + else if (sumQual == 3) {quality = 7;} + else if (sumQual == 4) {quality = 8;} + else if (sumQual == 5) {quality = 9;} + else if (sumQual == 6) {quality = 10;} + } + else { // halfstrip pattern + if (sumQual == 2) {quality = 11;} + else if (sumQual == 3) {quality = 12;} + else if (sumQual == 4) {quality = 13;} + else if (sumQual == 5) {quality = 14;} + else if (sumQual == 6) {quality = 15;} + } + } + } + } +#ifdef OLD + else { + // Temporary definition, used until July 2008. + // First if statement is fictitious, just to help the CSC TF emulator + // handle such cases (one needs to make sure they will be accounted for + // in the new quality definition. + if (!(aLCT.isValid()) || !(cLCT.isValid())) { + if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT + else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT + else quality = 0; // both absent; should never happen. + } + else { + // Sum of ALCT and CLCT quality bits. CLCT quality is, in fact, the + // number of layers hit, so subtract 3 to put it to the same footing as + // the ALCT quality. + int sumQual = aLCT.getQuality() + (cLCT.getQuality()-3); + if (sumQual < 1 || sumQual > 6) { + if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues") + << "+++ findQuality: Unexpected sumQual = " << sumQual << "+++\n"; + } + + // LCT quality is basically the sum of ALCT and CLCT qualities, but split + // in two groups depending on the CLCT pattern id (higher quality for + // straighter patterns). + int offset = 0; + if (cLCT.getPattern() <= 7) offset = 4; + else offset = 9; + quality = offset + sumQual; + } + } +#endif + else { + // 2008 definition. + if (!(aLCT.isValid()) || !(cLCT.isValid())) { + if (aLCT.isValid() && !(cLCT.isValid())) quality = 1; // no CLCT + else if (!(aLCT.isValid()) && cLCT.isValid()) quality = 2; // no ALCT + else quality = 0; // both absent; should never happen. + } + else { + const int pattern(cLCT.getPattern()); + if (pattern == 1) quality = 3; // layer-trigger in CLCT + else { + // ALCT quality is the number of layers hit minus 3. + // CLCT quality is the number of layers hit. + int n_gem = 0; + if (hasPad) n_gem = 1; + if (hasCoPad) n_gem = 2; + const bool a4((aLCT.getQuality() >= 1) or (aLCT.getQuality() >= 0 and n_gem >=1)); + const bool c4((cLCT.getQuality() >= 4) or (cLCT.getQuality() >= 3 and n_gem>=1)); + // quality = 4; "reserved for low-quality muons in future" + if (!a4 && !c4) quality = 5; // marginal anode and cathode + else if ( a4 && !c4) quality = 6; // HQ anode, but marginal cathode + else if (!a4 && c4) quality = 7; // HQ cathode, but marginal anode + else if ( a4 && c4) { + if (aLCT.getAccelerator()) quality = 8; // HQ muon, but accel ALCT + else { + // quality = 9; "reserved for HQ muons with future patterns + // quality = 10; "reserved for HQ muons with future patterns + if (pattern == 2 || pattern == 3) quality = 11; + else if (pattern == 4 || pattern == 5) quality = 12; + else if (pattern == 6 || pattern == 7) quality = 13; + else if (pattern == 8 || pattern == 9) quality = 14; + else if (pattern == 10) quality = 15; + else { + if (infoV >= 0) edm::LogWarning("L1CSCTPEmulatorWrongValues") + << "+++ findQuality: Unexpected CLCT pattern id = " + << pattern << "+++\n"; + } + } + } + } + } + } + return quality; +} + + +void CSCMotherboardME21GEM::buildCoincidencePads(const GEMPadDigiCollection* out_pads, + GEMPadDigiCollection& out_co_pads, + CSCDetId csc_id) +{ + gemCoPadV.clear(); + + // build coincidences + for (auto det_range = out_pads->begin(); det_range != out_pads->end(); ++det_range) { + const GEMDetId& id = (*det_range).first; + //std::cout<<"GEMDet Id " << id << std::endl; + + // same chamber + if (id.region() != csc_id.zendcap() or + id.ring() != csc_id.ring() or id.chamber() != csc_id.chamber()) continue; + // build coincidences only in station 2 + if (id.station() != 2 and id.station() != 3) continue; + + // all coincidences detIDs will have layer=1 + if (id.layer() != 1) continue; + + // find the corresponding id with layer=2 + GEMDetId co_id(id.region(), id.ring(), id.station(), 2, id.chamber(), id.roll()); + + auto co_pads_range = out_pads->get(co_id); + // empty range = no possible coincidence pads + if (co_pads_range.first == co_pads_range.second) continue; + + // now let's correlate the pads in two layers of this partition + const auto& pads_range = (*det_range).second; + for (auto p = pads_range.first; p != pads_range.second; ++p) { + for (auto co_p = co_pads_range.first; co_p != co_pads_range.second; ++co_p) { + // std::cout<<"Detid "<< id <<"Pad in layer1 " << *p <pad() - co_p->pad()) > maxDeltaPadInCoPad_) continue; + // check the match in BX + if (std::abs(p->bx() - co_p->bx()) > maxDeltaBXInCoPad_ ) continue; + + // make a new coincidence pad digi + gemCoPadV.push_back(GEMCoPadDigi(*p,*co_p)); + + // always use layer1 pad's BX as a copad's BX + GEMPadDigi co_pad_digi(p->pad(), p->bx()); + //std::cout<<"building Copad : "<< co_pad_digi < > +CSCMotherboardME21GEM::createGEMRollEtaLUT() +{ + std::map > result; + + auto chamber(gem_g->chamber(GEMDetId(1,1,3,1,1,0))); + if (chamber==nullptr) return result; + + for(int i = 1; i<= chamber->nEtaPartitions(); ++i){ + auto roll(chamber->etaPartition(i)); + if (roll==nullptr) continue; + const float half_striplength(roll->specs()->specificTopology().stripLength()/2.); + const LocalPoint lp_top(0., half_striplength, 0.); + const LocalPoint lp_bottom(0., -half_striplength, 0.); + const GlobalPoint gp_top(roll->toGlobal(lp_top)); + const GlobalPoint gp_bottom(roll->toGlobal(lp_bottom)); + //result[i] = std::make_pair(floorf(gp_top.eta() * 100) / 100, ceilf(gp_bottom.eta() * 100) / 100); + result[i] = std::make_pair(gp_top.eta(), gp_bottom.eta()); + } + return result; +} + +std::map > > +CSCMotherboardME21GEM::retrieveGEMPads(const GEMPadDigiCollection* gemPads, unsigned id, bool iscopad) +{ + int deltaBX(iscopad ? maxDeltaBXCoPad_ : maxDeltaBXPad_); + GEMPads result; + + auto superChamber(gem_g->superChamber(id)); + for (auto ch : superChamber->chambers()) { + for (auto roll : ch->etaPartitions()) { + 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) { + auto id_pad = std::make_pair(roll_id(), &(*pad)); + const int bx_shifted(lct_central_bx + pad->bx()); + for (int bx = bx_shifted - deltaBX;bx <= bx_shifted + deltaBX; ++bx) { + //if (iscopad){ + //if(bx != lct_central_bx) continue; + //if (bx != bx_shifted) continue; + result[bx].push_back(id_pad); + // }else{ + // result[bx].push_back(id_pad); + // } + } + } + } + } + return result; +} + + +void CSCMotherboardME21GEM::printGEMTriggerPads(int bx_start, int bx_stop, bool iscopad) +{ + // pads or copads? + auto thePads(!iscopad ? pads_ : coPads_ ); + const bool hasPads(thePads.size()!=0); + + std::cout << "------------------------------------------------------------------------" << std::endl; + bool first = true; + for (int bx = bx_start; bx <= bx_stop; bx++) { + // print only the pads for the central BX + //if (bx!=lct_central_bx and iscopad) continue; + std::vector > in_pads = thePads[bx]; + if (first) { + if (!iscopad) std::cout << "* GEM trigger pads: " << std::endl; + else std::cout << "* GEM trigger coincidence pads: " << std::endl; + } + first = false; + if (!iscopad) std::cout << "N(pads) BX " << bx << " : " << in_pads.size() << std::endl; + else std::cout << "N(copads) BX " << bx << " : " << in_pads.size() << std::endl; + if (hasPads){ + for (auto pad : in_pads){ + auto roll_id(GEMDetId(pad.first)); + std::cout << "\tdetId " << pad.first << " " << roll_id << ", pad = " << pad.second->pad() << ", BX = " << pad.second->bx() + 6 << std::endl; + } + } + else + break; + } +} + + +CSCMotherboardME21GEM::GEMPadsBX +CSCMotherboardME21GEM::matchingGEMPads(const CSCCLCTDigi& clct, const GEMPadsBX& pads, bool isCoPad, bool first) +{ + CSCMotherboardME21GEM::GEMPadsBX result; + + // fetch the low and high pad edges for the long superchambers + int deltaPad(isCoPad ? maxDeltaPadCoPad_ : maxDeltaPadPad_); + int deltaBX(isCoPad ? maxDeltaBXCoPad_ : maxDeltaBXPad_); + int clct_bx = clct.getBX(); + const int lowPad(cscHsToGemPad_[clct.getKeyStrip()].first); + const int highPad(cscHsToGemPad_[clct.getKeyStrip()].second); + const bool debug(false); + if (debug) std::cout << "lowpad " << lowPad << " highpad " << highPad << " delta pad " << deltaPad <pad()); + int pad_bx = (p.second)->bx()+lct_central_bx; + if (debug) std::cout << "padRoll " << padRoll << std::endl; + if (std::abs(clct_bx-pad_bx)>deltaBX) continue; + if (std::abs(lowPad - padRoll) <= deltaPad or std::abs(padRoll - highPad) <= deltaPad){ + if (debug) std::cout << "++Matches! " << std::endl; + result.push_back(p); + if (first) return result; + } + } + return result; +} + + +CSCMotherboardME21GEM::GEMPadsBX +CSCMotherboardME21GEM::matchingGEMPads(const CSCALCTDigi& alct, const GEMPadsBX& pads, bool isCoPad, bool first) +{ + CSCMotherboardME21GEM::GEMPadsBX result; + int deltaBX(isCoPad ? maxDeltaBXCoPad_ : maxDeltaBXPad_); + int alct_bx = alct.getBX(); + int Wg = alct.getKeyWG(); + std::vector Rolls; + Rolls.push_back(cscWgToGemRoll_[Wg]); + if (Wg>=maxDeltaWg_ && cscWgToGemRoll_[Wg] != cscWgToGemRoll_[Wg-maxDeltaWg_]) + Rolls.push_back(cscWgToGemRoll_[Wg-maxDeltaWg_]); + if ((unsigned int)(Wg+maxDeltaWg_)bx()+lct_central_bx; + if (debug) std::cout<<"Detid "<< GEMDetId(p.first) <<" "<< *(p.second)<deltaBX) continue; + if (alctRoll != padRoll) continue; + if (debug) std::cout << "++Matches! " << std::endl; + result.push_back(p); + if (first) return result; + } + } + return result; +} + + +CSCMotherboardME21GEM::GEMPadsBX +CSCMotherboardME21GEM::matchingGEMPads(const CSCCLCTDigi& clct, const CSCALCTDigi& alct, const GEMPadsBX& pads, + bool isCoPad, bool first) +{ + CSCMotherboardME21GEM::GEMPadsBX result; + + // Fetch all (!) pads matching to ALCTs and CLCTs + auto padsClct(matchingGEMPads(clct, pads, isCoPad, false)); + auto padsAlct(matchingGEMPads(alct, pads, isCoPad, false)); + + const bool debug(false); + if (debug) std::cout << "-----------------------------------------------------------------------"<chamber(theEndcap, theStation, theSector, theSubsector, theTrigChamber); + const CSCDetId csc_id(cscChamber->id()); + const int chamber(csc_id.chamber()); + const bool is_odd(chamber%2==1); + + + if (debug_gem_dphi) std::cout<<"++++++++ matchGEMPads "<< csc_id <<" +++++++++ "<layer(CSCConstants::KEY_CLCT_LAYER)->geometry(); + // LCT::getKeyWG() also starts from 0 + float wire = layer_geo->middleWireOfGroup(lct.getKeyWG() + 1); + + LocalPoint csc_intersect = layer_geo->intersectionOfStripAndWire(fractional_strip, wire); + GlobalPoint csc_gp = csc_g->idToDet(csc_id)->surface().toGlobal(csc_intersect); + + // is LCT located in the high efficiency GEM eta range? + bool gem_fid = ( std::abs(csc_gp.eta()) >= gem_match_min_eta ); + + if (debug_gem_dphi) std::cout<<" lct eta "< zap it + { + if (gem_clear_nomatch_lcts) lct.clear(); + if (debug_gem_dphi) std::cout<<" -- no gem"<second) + { + GEMDetId gem_id(id_pad.first); + LocalPoint gem_lp = gem_g->etaPartition(gem_id)->centreOfPad(id_pad.second->pad()); + GlobalPoint gem_gp = gem_g->idToDet(gem_id)->surface().toGlobal(gem_lp); + float dphi = deltaPhi(csc_gp.phi(), gem_gp.phi()); + float deta = csc_gp.eta() - gem_gp.eta(); + if (debug_gem_dphi) std::cout<<" gem with dphi "<< std::abs(dphi) <<" deta "<< std::abs(deta) <bx(); + } + } + if (gem_matched) + { + if (debug_gem_dphi) std::cout<<" GOT MATCHED GEM!"< lut_pt_vs_dphi_gemcsc[i+1][oddEven]) + iFound = i+1; + } + } + lct.setGEMDPhiBits(iFound); + if (debug_gem_dphi) std::cout<<"found bend angle "< CSCMotherboardME21GEM::readoutCoPads() +{ + return gemCoPadV; +} + + +int CSCMotherboardME21GEM::getRandomWGForGEMRoll(int roll) +{ + boost::container::flat_set wgs; + for (auto p: cscWgToGemRoll_) + if (p.first == roll) + wgs.insert(p.first); + // return a random one + return *(wgs.begin() + rand() % wgs.size()); +} diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME21GEM.h b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME21GEM.h new file mode 100644 index 0000000000000..f577503e16700 --- /dev/null +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME21GEM.h @@ -0,0 +1,219 @@ +#ifndef CSCTriggerPrimitives_CSCMotherboardME21GEM_h +#define CSCTriggerPrimitives_CSCMotherboardME21GEM_h + +/** \class CSCMotherboardME21GEM + * + * Extended CSCMotherboard for ME21 TMB upgrade + * + * \author Sven Dildick March 2014 + * + * Based on CSCMotherboard code + * + */ + +#include +#include +#include "DataFormats/GEMDigi/interface/GEMCoPadDigiCollection.h" + +class CSCGeometry; +class CSCChamber; +class GEMGeometry; +class GEMSuperChamber; + +class CSCMotherboardME21GEM : public CSCMotherboard +{ + typedef std::map > > GEMPads; + typedef std::pair GEMPadBX; + typedef std::vector GEMPadsBX; + + public: + /** Normal constructor. */ + CSCMotherboardME21GEM(unsigned endcap, unsigned station, unsigned sector, + unsigned subsector, unsigned chamber, + const edm::ParameterSet& conf); + + /** Default destructor. */ + ~CSCMotherboardME21GEM(); + + void clear(); + + /** Run function for normal usage. Runs cathode and anode LCT processors, + takes results and correlates into CorrelatedLCT. */ + void run(const CSCWireDigiCollection* wiredc, + const CSCComparatorDigiCollection* compdc, + const GEMPadDigiCollection* gemPads); + + /// set CSC and GEM geometries for the matching needs + void setCSCGeometry(const CSCGeometry *g) { csc_g = g; } + void setGEMGeometry(const GEMGeometry *g) { gem_g = g; } + + void buildCoincidencePads(const GEMPadDigiCollection* out_pads, + GEMPadDigiCollection& out_co_pads, + CSCDetId csc_id); + + GEMPads retrieveGEMPads(const GEMPadDigiCollection* pads, unsigned id, bool iscopad = false); + + std::map > createGEMRollEtaLUT(); + + int assignGEMRoll(double eta); + int deltaRoll(int wg, int roll); + int deltaPad(int hs, int pad); + int getRandomWGForGEMRoll(int roll); + + void printGEMTriggerPads(int minBX, int maxBx, bool iscopad = false); + + GEMPadsBX matchingGEMPads(const CSCCLCTDigi& cLCT, const GEMPadsBX& pads = GEMPadsBX(), + bool isCopad = false, bool first = true); + GEMPadsBX matchingGEMPads(const CSCALCTDigi& aLCT, const GEMPadsBX& pads = GEMPadsBX(), + bool isCopad = false, bool first = true); + GEMPadsBX matchingGEMPads(const CSCCLCTDigi& cLCT, const CSCALCTDigi& aLCT, const GEMPadsBX& pads = GEMPadsBX(), + bool isCopad = false, bool first = true); + + unsigned int findQualityGEM(const CSCALCTDigi& aLCT, const CSCCLCTDigi& cLCT, + bool hasPad, bool hasCoPad); + + void correlateLCTs(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2, + const GEMPadsBX& pads = GEMPadsBX(), const GEMPadsBX& copads = GEMPadsBX()); + + void matchGEMPads(); + + void correlateLCTsGEM(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, + GEMPadDigi gemPad, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2); + + void correlateLCTsGEM(CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, + GEMPadDigi gemPad, int roll, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2); + + void correlateLCTsGEM(CSCALCTDigi bestALCT, CSCALCTDigi secondALCT, + CSCCLCTDigi bestCLCT, CSCCLCTDigi secondCLCT, + CSCCorrelatedLCTDigi& lct1, CSCCorrelatedLCTDigi& lct2, + const GEMPadsBX& pads = GEMPadsBX(), const GEMPadsBX& copads = GEMPadsBX()); + + CSCCorrelatedLCTDigi constructLCTsGEM(const CSCALCTDigi& alct, const GEMPadDigi& gem, + bool oldDataFormat = false); + CSCCorrelatedLCTDigi constructLCTsGEM(const CSCCLCTDigi& clct, const GEMPadDigi& gem, int roll, + bool oldDataFormat = true); + CSCCorrelatedLCTDigi constructLCTsGEM(const CSCALCTDigi& alct, const CSCCLCTDigi& clct, + bool hasPad, bool hasCoPad); + + /** Methods to sort the LCTs */ + std::vector sortLCTsByQuality(int bx); + std::vector sortLCTsByQuality(std::vector); + std::vector sortLCTsByGEMDPhi(int bx); + std::vector sortLCTsByGEMDPhi(std::vector); + + std::vector getLCTs(); + std::vector readoutLCTs(); + std::vector readoutCoPads(); + + private: + + /** for the case when more than 2 LCTs/BX are allowed; + maximum match window = 15 */ + CSCCorrelatedLCTDigi allLCTs[MAX_LCT_BINS][15][2]; + + static const double lut_pt_vs_dphi_gemcsc[8][3]; + static const double lut_wg_eta_odd[112][2]; + static const double lut_wg_eta_even[112][2]; + + const CSCGeometry* csc_g; + const GEMGeometry* gem_g; + + + std::vector alctV; + std::vector clctV; + std::vector gemCoPadV; + + /** "preferential" index array in matching window for cross-BX sorting */ + int pref[MAX_LCT_BINS]; + + bool match_earliest_clct_me21_only; + + /** whether to not reuse CLCTs that were used by previous matching ALCTs + in ALCT-to-CLCT algorithm */ + bool drop_used_clcts; + + unsigned int tmb_cross_bx_algo; + + /** maximum lcts per BX in ME2 */ + unsigned int max_me21_lcts; + + // masterswitch + bool runME21ILT_; + + /// Do GEM matching? + bool do_gem_matching; + + /// GEM matching dphi and deta + double gem_match_delta_phi_odd; + double gem_match_delta_phi_even; + double gem_match_delta_eta; + + /// delta BX for GEM pads matching + int gem_match_delta_bx; + + /// min eta of LCT for which we require GEM match (we don't throw out LCTs below this min eta) + double gem_match_min_eta; + double gem_match_max_eta; + + /// whether to throw out GEM-fiducial LCTs that have no gem match + bool gem_clear_nomatch_lcts; + + // debug gem matching + bool debug_gem_matching; + bool debug_luts; + bool debug_gem_dphi; + + // deltas used to construct GEM coincidence pads + int maxDeltaBXInCoPad_; + int maxDeltaPadInCoPad_; + + // deltas used to match to GEM pads + int maxDeltaBXPad_; + int maxDeltaPadPad_; + int maxDeltaPadPadEven_; + int maxDeltaPadPadOdd_; + int maxDeltaWg_; + + // deltas used to match to GEM coincidence pads + int maxDeltaBXCoPad_; + int maxDeltaPadCoPad_; + + bool doLCTGhostBustingWithGEMs_; + + // drop low quality stubs if they don't have GEMs + bool dropLowQualityCLCTsNoGEMs_; + bool dropLowQualityALCTsNoGEMs_; + + // correct LCT timing with GEMs + bool correctLCTtimingWithGEM_; + + // build LCT from ALCT and GEM + bool buildLCTfromALCTandGEM_; + bool buildLCTfromCLCTandGEM_; + + bool useOldLCTDataFormatALCTGEM_; + bool useOldLCTDataFormatCLCTGEM_; + + // promote ALCT-GEM pattern + bool promoteALCTGEMpattern_; + + // promote ALCT-GEM quality + bool promoteALCTGEMquality_; + bool promoteCLCTGEMquality_; + + std::map > gemRollToEtaLimits_; + std::map cscWgToGemRoll_; + + // map of pad to HS + std::map gemPadToCscHs_; + std::map> cscHsToGemPad_; + + // map< bx , vector > + GEMPads pads_; + GEMPads coPads_; +}; +#endif diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCMuonPortCard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCMuonPortCard.cc index 63a30954c0b20..9120bb08cb49e 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCMuonPortCard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCMuonPortCard.cc @@ -32,10 +32,10 @@ CSCMuonPortCard::CSCMuonPortCard(const edm::ParameterSet& conf) max_stubs_ = CSCConstants::maxStubs; edm::ParameterSet commonParams = conf.getParameter("commonParam"); - if (commonParams.getUntrackedParameter("isSLHC",false)) + if (commonParams.getParameter("isSLHC")) { edm::ParameterSet mpcParams = conf.getParameter("mpcSLHC"); - max_stubs_ = mpcParams.getUntrackedParameter("mpcMaxStubs", CSCConstants::maxStubs); + max_stubs_ = mpcParams.getParameter("mpcMaxStubs"); } } diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc index ced07088032e6..a7c1bb6ca8107 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.cc @@ -13,16 +13,19 @@ // //----------------------------------------------------------------------------- -#include -#include -#include -#include +#include "L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.h" +#include "L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.h" +#include "L1Trigger/CSCTriggerPrimitives/src/CSCMotherboardME11.h" +#include +#include +#include "L1Trigger/CSCTriggerPrimitives/src/CSCMuonPortCard.h" -#include +#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include -#include -#include +#include "L1Trigger/CSCCommonTrigger/interface/CSCTriggerGeometry.h" +#include "DataFormats/MuonDetId/interface/CSCTriggerNumbering.h" +#include "DataFormats/MuonDetId/interface/CSCDetId.h" +#include "Geometry/GEMGeometry/interface/GEMGeometry.h" //------------------ // Static variables @@ -53,6 +56,9 @@ CSCTriggerPrimitivesBuilder::CSCTriggerPrimitivesBuilder(const edm::ParameterSet checkBadChambers_ = conf.getUntrackedParameter("checkBadChambers", true); + runME11ILT_ = commonParams.existsAs("runME11ILT")?commonParams.getParameter("runME11ILT"):false; + runME21ILT_ = commonParams.existsAs("runME21ILT")?commonParams.getParameter("runME21ILT"):false; + // ORCA way of initializing boards. for (int endc = min_endcap; endc <= max_endcap; endc++) { @@ -81,8 +87,12 @@ CSCTriggerPrimitivesBuilder::CSCTriggerPrimitivesBuilder(const edm::ParameterSet int ring = CSCTriggerNumbering::ringFromTriggerLabels(stat, cham); // When the motherboard is instantiated, it instantiates ALCT // and CLCT processors. - if (stat==1 && ring==1 && smartME1aME1b) + if (stat==1 && ring==1 && smartME1aME1b && !runME11ILT_) tmb_[endc-1][stat-1][sect-1][subs-1][cham-1] = new CSCMotherboardME11(endc, stat, sect, subs, cham, conf); + else if (stat==1 && ring==1 && smartME1aME1b && runME11ILT_) + tmb_[endc-1][stat-1][sect-1][subs-1][cham-1] = new CSCMotherboardME11GEM(endc, stat, sect, subs, cham, conf); + else if (stat==2 && ring==1 && runME21ILT_) + tmb_[endc-1][stat-1][sect-1][subs-1][cham-1] = new CSCMotherboardME21GEM(endc, stat, sect, subs, cham, conf); else tmb_[endc-1][stat-1][sect-1][subs-1][cham-1] = new CSCMotherboard(endc, stat, sect, subs, cham, conf); } @@ -164,11 +174,14 @@ void CSCTriggerPrimitivesBuilder::setConfigParameters(const CSCDBL1TPParameters* void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, const CSCWireDigiCollection* wiredc, const CSCComparatorDigiCollection* compdc, + const GEMPadDigiCollection* gemPads, CSCALCTDigiCollection& oc_alct, CSCCLCTDigiCollection& oc_clct, CSCCLCTPreTriggerCollection & oc_pretrig, CSCCorrelatedLCTDigiCollection& oc_lct, - CSCCorrelatedLCTDigiCollection& oc_sorted_lct) + CSCCorrelatedLCTDigiCollection& oc_sorted_lct, + GEMCoPadDigiCollection& oc_gemcopad, + GEMCSCLCTDigiCollection& oc_gemcsclct) { // CSC geometry. CSCTriggerGeomManager* theGeom = CSCTriggerGeometry::get(); @@ -204,8 +217,8 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, if (checkBadChambers_ && badChambers->isInBadChamber(detid)) continue; - // running upgraded ME1/1 TMBs (non-upgraded) - if (stat==1 && ring==1 && smartME1aME1b) + // running upgraded ME1/1 TMBs + if (stat==1 && ring==1 && smartME1aME1b && !runME11ILT_) { CSCMotherboardME11* tmb11 = static_cast(tmb); @@ -316,6 +329,195 @@ void CSCTriggerPrimitivesBuilder::build(const CSCBadChambers* badChambers, } } // upgraded TMB + // running upgraded ME1/1 TMBs with GEMs + else if (stat==1 && ring==1 && smartME1aME1b && runME11ILT_) + { + CSCMotherboardME11GEM* tmb11GEM = static_cast(tmb); + + tmb11GEM->setCSCGeometry(csc_g); + tmb11GEM->setGEMGeometry(gem_g); + //LogTrace("CSCTriggerPrimitivesBuilder")<<"CSCTriggerPrimitivesBuilder::build in E:"<run(wiredc, compdc, gemPads); + + std::vector lctV = tmb11GEM->readoutLCTs1b(); + std::vector lctV1a = tmb11GEM->readoutLCTs1a(); + + std::vector alctV1a, alctV = tmb11GEM->alct->readoutALCTs(); + + std::vector clctV = tmb11GEM->clct->readoutCLCTs(); + std::vector preTriggerBXs = tmb11GEM->clct->preTriggerBXs(); + std::vector clctV1a = tmb11GEM->clct1a->readoutCLCTs(); + std::vector preTriggerBXs1a = tmb11GEM->clct1a->preTriggerBXs(); + + std::vector copads = tmb11GEM->readoutCoPads(); + + // perform simple separation of ALCTs into 1/a and 1/b + // for 'smart' case. Some duplication occurs for WG [10,15] + std::vector tmpV(alctV); + alctV.clear(); + for (unsigned int al=0; al < tmpV.size(); al++) + { + if (tmpV[al].getKeyWG()<=15) alctV1a.push_back(tmpV[al]); + if (tmpV[al].getKeyWG()>=10) alctV.push_back(tmpV[al]); + } + //LogTrace("CSCTriggerPrimitivesBuilder")<<"CSCTriggerPrimitivesBuilder:: a="< 1) ? "s " : " ") << "in collection\n"; + oc_lct.put(std::make_pair(lctV.begin(),lctV.end()), detid); + } + + // Anode LCTs. + if (!alctV.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << alctV.size() << " ME1b ALCT digi" + << ((alctV.size() > 1) ? "s " : " ") << "in collection\n"; + oc_alct.put(std::make_pair(alctV.begin(),alctV.end()), detid); + } + + // Cathode LCTs. + if (!clctV.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << clctV.size() << " ME1b CLCT digi" + << ((clctV.size() > 1) ? "s " : " ") << "in collection\n"; + oc_clct.put(std::make_pair(clctV.begin(),clctV.end()), detid); + } + + // Cathode LCTs pretriggers + if (!preTriggerBXs.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << preTriggerBXs.size() << " CLCT pretrigger" + << ((preTriggerBXs.size() > 1) ? "s " : " ") << "in collection\n"; + oc_pretrig.put(std::make_pair(preTriggerBXs.begin(),preTriggerBXs.end()), detid); + } + // 0th layer means whole chamber. + GEMDetId gemId(detid.zendcap(), 1, 1, 1, chid, 0); + + // GEM coincidence pads + if (!copads.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << copads.size() << " GEM coincidence pad" + << ((copads.size() > 1) ? "s " : " ") << "in collection\n"; + oc_gemcopad.put(std::make_pair(copads.begin(),copads.end()), gemId); + } + + // ME1/a + + if (disableME1a) continue; + + CSCDetId detid1a(endc, stat, 4, chid, 0); + + if (!(lctV1a.empty()&&alctV1a.empty()&&clctV1a.empty())){ + LogTrace("L1CSCTrigger") << "CSCTriggerPrimitivesBuilder results in " < 1) ? "s " : " ") << "in collection\n"; + oc_lct.put(std::make_pair(lctV1a.begin(),lctV1a.end()), detid1a); + } + + // Anode LCTs. + if (!alctV1a.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << alctV1a.size() << " ME1a ALCT digi" + << ((alctV1a.size() > 1) ? "s " : " ") << "in collection\n"; + oc_alct.put(std::make_pair(alctV1a.begin(),alctV1a.end()), detid1a); + } + + // Cathode LCTs. + if (!clctV1a.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << clctV1a.size() << " ME1a CLCT digi" + << ((clctV1a.size() > 1) ? "s " : " ") << "in collection\n"; + oc_clct.put(std::make_pair(clctV1a.begin(),clctV1a.end()), detid1a); + } + + // Cathode LCTs pretriggers + if (!preTriggerBXs1a.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << preTriggerBXs.size() << " CLCT pretrigger" + << ((preTriggerBXs.size() > 1) ? "s " : " ") << "in collection\n"; + oc_pretrig.put(std::make_pair(preTriggerBXs.begin(),preTriggerBXs.end()), detid); + } + } + + // running upgraded ME2/1 TMBs + else if (stat==2 && ring==1 && runME21ILT_) + { + CSCMotherboardME21GEM* tmb21GEM = static_cast(tmb); + tmb21GEM->setCSCGeometry(csc_g); + tmb21GEM->setGEMGeometry(gem_g); + tmb21GEM->run(wiredc, compdc, gemPads); + std::vector lctV = tmb21GEM->readoutLCTs(); + std::vector alctV = tmb21GEM->alct->readoutALCTs(); + std::vector clctV = tmb21GEM->clct->readoutCLCTs(); + std::vector preTriggerBXs = tmb21GEM->clct->preTriggerBXs(); + + std::vector copads = tmb21GEM->readoutCoPads(); + + if (!(alctV.empty() && clctV.empty() && lctV.empty())) { + LogTrace("L1CSCTrigger") + << "CSCTriggerPrimitivesBuilder got results in " < 1) ? "s " : " ") << "in collection\n"; + oc_lct.put(std::make_pair(lctV.begin(),lctV.end()), detid); + } + + // Anode LCTs. + if (!alctV.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << alctV.size() << " ALCT digi" + << ((alctV.size() > 1) ? "s " : " ") << "in collection\n"; + oc_alct.put(std::make_pair(alctV.begin(),alctV.end()), detid); + } + + // Cathode LCTs. + if (!clctV.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << clctV.size() << " CLCT digi" + << ((clctV.size() > 1) ? "s " : " ") << "in collection\n"; + oc_clct.put(std::make_pair(clctV.begin(),clctV.end()), detid); + } + + // Cathode LCTs pretriggers + if (!preTriggerBXs.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << preTriggerBXs.size() << " CLCT pretrigger" + << ((preTriggerBXs.size() > 1) ? "s " : " ") << "in collection\n"; + oc_pretrig.put(std::make_pair(preTriggerBXs.begin(),preTriggerBXs.end()), detid); + } + + // 0th layer means whole chamber. + GEMDetId gemId(detid.zendcap(), 1, 2, 1, chid, 0); + + // GEM coincidence pads + if (!copads.empty()) { + LogTrace("L1CSCTrigger") + << "Put " << copads.size() << " GEM coincidence pad" + << ((copads.size() > 1) ? "s " : " ") << "in collection\n"; + oc_gemcopad.put(std::make_pair(copads.begin(),copads.end()), gemId); + } + } + // running non-upgraded TMB else { diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.h b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.h index 68521c05d7c5b..8fac34d768880 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.h +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCTriggerPrimitivesBuilder.h @@ -1,5 +1,5 @@ -#ifndef CSCTriggerPrimitives_CSCTriggerPrimitivesBuilder_h -#define CSCTriggerPrimitives_CSCTriggerPrimitivesBuilder_h +#ifndef L1Trigger_CSCTriggerPrimitives_CSCTriggerPrimitivesBuilder_h +#define L1Trigger_CSCTriggerPrimitives_CSCTriggerPrimitivesBuilder_h /** \class CSCTriggerPrimitivesBuilder * @@ -14,18 +14,23 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include +#include "CondFormats/CSCObjects/interface/CSCBadChambers.h" +#include "DataFormats/CSCDigi/interface/CSCComparatorDigiCollection.h" +#include "DataFormats/CSCDigi/interface/CSCWireDigiCollection.h" +#include "DataFormats/CSCDigi/interface/CSCALCTDigiCollection.h" +#include "DataFormats/CSCDigi/interface/CSCCLCTDigiCollection.h" +#include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h" +#include "DataFormats/CSCDigi/interface/CSCCLCTPreTriggerCollection.h" +#include "DataFormats/CSCDigi/interface/GEMCSCLCTDigiCollection.h" +#include "DataFormats/GEMDigi/interface/GEMPadDigiCollection.h" +#include "DataFormats/GEMDigi/interface/GEMCoPadDigiCollection.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" class CSCDBL1TPParameters; class CSCMotherboard; class CSCMuonPortCard; +class CSCGeometry; +class GEMGeometry; class CSCTriggerPrimitivesBuilder { @@ -42,16 +47,23 @@ class CSCTriggerPrimitivesBuilder /** Sets configuration parameters obtained via EventSetup mechanism. */ void setConfigParameters(const CSCDBL1TPParameters* conf); + /// set CSC and GEM geometries for the matching needs + void setCSCGeometry(const CSCGeometry *g) { csc_g = g; } + void setGEMGeometry(const GEMGeometry *g) { gem_g = g; } + /** Build anode, cathode, and correlated LCTs in each chamber and fill * them into output collections. Select up to three best correlated LCTs * in each (sub)sector and put them into an output collection as well. */ void build(const CSCBadChambers* badChambers, const CSCWireDigiCollection* wiredc, const CSCComparatorDigiCollection* compdc, + const GEMPadDigiCollection* gemPads, CSCALCTDigiCollection& oc_alct, CSCCLCTDigiCollection& oc_clct, CSCCLCTPreTriggerCollection & oc_pretrig, CSCCorrelatedLCTDigiCollection& oc_lct, - CSCCorrelatedLCTDigiCollection& oc_sorted_lct); + CSCCorrelatedLCTDigiCollection& oc_sorted_lct, + GEMCoPadDigiCollection& oc_gemcopad, + GEMCSCLCTDigiCollection& oc_gemcsclct); /** Max values of trigger labels for all CSCs; used to construct TMB * processors. */ @@ -81,12 +93,21 @@ class CSCTriggerPrimitivesBuilder /** SLHC: special switch for disabling ME42 */ bool disableME42; + /** SLHC: special switch for the upgrade ME1/1 TMB */ + bool runME11ILT_; + + /** SLHC: special switch for the upgrade ME2/1 TMB */ + bool runME21ILT_; + int m_minBX, m_maxBX; // min and max BX to sort. /** Pointers to TMB processors for all possible chambers. */ CSCMotherboard* tmb_[MAX_ENDCAPS][MAX_STATIONS][MAX_SECTORS][MAX_SUBSECTORS][MAX_CHAMBERS]; + const CSCGeometry* csc_g; + const GEMGeometry* gem_g; + /** Pointer to MPC processor. */ CSCMuonPortCard* m_muonportcard; };