Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DataFormats/L1TGlobal/interface/GlobalObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace l1t {
/// ObjNull catch all errors
enum GlobalObject {
gtMu,
gtMuShower,
gtEG,
gtJet,
gtTau,
Expand Down
5 changes: 5 additions & 0 deletions DataFormats/L1TGlobal/src/GlobalObject.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ using namespace l1t;

l1t::GlobalObject l1TGtObjectStringToEnum(const std::string& label) {
static const l1t::L1TGtObjectStringToEnum l1TGtObjectStringToEnumMap[] = {{"Mu", gtMu},
{"MuShower", gtMuShower},
{"EG", gtEG},
{"Tau", gtTau},
{"Jet", gtJet},
Expand Down Expand Up @@ -87,6 +88,10 @@ std::string l1t::l1TGtObjectEnumToString(const GlobalObject& gtObject) {
gtObjectString = "Mu";
} break;

case gtMuShower: {
gtObjectString = "MuShower";
} break;

case gtEG: {
gtObjectString = "EG";
} break;
Expand Down
3 changes: 2 additions & 1 deletion L1Trigger/CSCTriggerPrimitives/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ Please refer to this important documentation:
* GEM, CSC, GEM-CSC, and HMT trigger algorithm https://gitlab.cern.ch/tdr/notes/DN-21-019/blob/master/temp/DN-21-019_temp.pdf
* CCLUT algorithm https://gitlab.cern.ch/tdr/notes/DN-19-059/blob/master/temp/DN-19-059_temp.pdf
* Hadronic shower trigger algorithm: https://gitlab.cern.ch/tdr/notes/DN-20-033/blob/master/temp/DN-20-033_temp.pdf
* Note describing the CSC firmware and CSC DAQ format https://github.com/csc-fw/otmb_fw_docs
* Note describing the TMB/OTMB firmware and CSC DAQ format https://github.com/csc-fw/otmb_fw_docs
* Note describing the ALCT Virtex-E and Spartan-6 firmware and DAQ format: http://www.phys.ufl.edu/~madorsky/alctv/firmware/2021-11-19/alct_firmware.pdf
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS
comp_token_ = consumes<CSCComparatorDigiCollection>(compDigiProducer_);
if (runILT_)
gem_pad_cluster_token_ = consumes<GEMPadDigiClusterCollection>(gemPadDigiClusterProducer_);

cscToken_ = esConsumes<CSCGeometry, MuonGeometryRecord>();
gemToken_ = esConsumes<GEMGeometry, MuonGeometryRecord>();
pBadChambersToken_ = esConsumes<CSCBadChambers, CSCBadChambersRcd>();
Expand Down Expand Up @@ -249,14 +250,8 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup
ev.getByToken(wire_token_, wireDigis);

// input GEM pad cluster collection for upgrade scenarios
edm::Handle<GEMPadDigiClusterCollection> gemPadDigiClusters;
const GEMPadDigiClusterCollection* gemPadClusters = nullptr;
if (runILT_) {
if (!gemPadDigiClusterProducer_.label().empty()) {
edm::Handle<GEMPadDigiClusterCollection> gemPadDigiClusters;
ev.getByToken(gem_pad_cluster_token_, gemPadDigiClusters);
gemPadClusters = gemPadDigiClusters.product();
}
}

// Create empty collections of ALCTs, CLCTs, and correlated LCTs upstream
// and downstream of MPC.
Expand Down Expand Up @@ -284,6 +279,23 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup
<< " requested in configuration, but not found in the event..."
<< " Skipping production of CSC TP digis +++\n";
}
// the GEM-CSC trigger flag is set, so GEM clusters are expected in the event data
if (runILT_) {
// no valid label, let the user know that GEM clusters are missing
// the algorithm should not crash. instead it should just produce the regular CSC LCTs
// in ME1/1 and/or ME2/1
ev.getByToken(gem_pad_cluster_token_, gemPadDigiClusters);
if (!gemPadDigiClusters.isValid()) {
edm::LogWarning("CSCTriggerPrimitivesProducer|NoInputCollection")
<< "+++ Warning: Collection of GEM clusters with label " << gemPadDigiClusterProducer_.label()
<< " requested in configuration, but not found in the event..."
<< " Running CSC-only trigger algorithm +++\n";
} else {
// when the GEM-CSC trigger should be run and the label is not empty, set a valid pointer
gemPadClusters = gemPadDigiClusters.product();
}
}

// Fill output collections if valid input collections are available.
if (wireDigis.isValid() && compDigis.isValid()) {
const CSCBadChambers* temp = checkBadChambers_ ? pBadChambers.product() : new CSCBadChambers;
Expand Down
5 changes: 5 additions & 0 deletions L1Trigger/CSCTriggerPrimitives/src/CSCGEMMatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ CSCGEMMatcher::CSCGEMMatcher(
: endcap_(endcap), station_(station), chamber_(chamber) {
isEven_ = (chamber_ % 2 == 0);

// These LogErrors are sanity checks and should not be printed
if (station_ == 3 or station_ == 4) {
edm::LogError("CSCGEMMatcher") << "Class constructed for a chamber in ME3 or ME4!";
};

maxDeltaBXALCTGEM_ = tmbParams.getParameter<unsigned>("maxDeltaBXALCTGEM");
maxDeltaBXCLCTGEM_ = tmbParams.getParameter<unsigned>("maxDeltaBXCLCTGEM");

Expand Down
58 changes: 39 additions & 19 deletions L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ CSCGEMMotherboard::CSCGEMMotherboard(unsigned endcap,
edm::LogError("CSCGEMMotherboard") << "TMB constructed while runME21ILT_ is not set!";
};

// These LogErrors are sanity checks and should not be printed
if (!isME11_ and !isME21_) {
edm::LogError("CSCGEMMotherboard") << "GEM-CSC OTMB constructed for a non-ME1/1 or a non-ME2/1 chamber!";
};

// super chamber has layer=0!
gemId = GEMDetId(theRegion, 1, theStation, 0, theChamber, 0).rawId();

Expand All @@ -59,18 +64,13 @@ void CSCGEMMotherboard::run(const CSCWireDigiCollection* wiredc,
// Step 1: Setup
clear();

// check for GEM geometry
if (gem_g == nullptr) {
edm::LogError("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger without valid GEM geometry! \n";
return;
}

// Check that the processors can deliver data
if (!(alctProc and clctProc)) {
edm::LogError("CSCGEMMotherboard") << "run() called for non-existing ALCT/CLCT processor! \n";
edm::LogError("CSCGEMMotherboard") << "run() called for non-existing ALCT/CLCT processor in " << theCSCName_;
return;
}

// set geometry
alctProc->setCSCGeometry(cscGeometry_);
clctProc->setCSCGeometry(cscGeometry_);

Expand All @@ -90,19 +90,39 @@ void CSCGEMMotherboard::run(const CSCWireDigiCollection* wiredc,
if (alctV.empty() and clctV.empty())
return;

// set the lookup tables for coordinate conversion and matching
if (isME11_) {
clusterProc_->setESLookupTables(lookupTableME11ILT_);
cscGEMMatcher_->setESLookupTables(lookupTableME11ILT_);
bool validClustersAndGeometry = true;

// Step 3a: check for GEM geometry
if (gem_g == nullptr) {
edm::LogWarning("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger"
<< " without valid GEM geometry! Running CSC-only"
<< " trigger algorithm in " << theCSCName_;
validClustersAndGeometry = false;
}
if (isME21_) {
clusterProc_->setESLookupTables(lookupTableME21ILT_);
cscGEMMatcher_->setESLookupTables(lookupTableME21ILT_);

// Step 3b: check that the GEM cluster collection is a valid pointer
if (gemClusters == nullptr) {
edm::LogWarning("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger"
<< " without valid GEM clusters! Running CSC-only"
<< " trigger algorithm in " << theCSCName_;
validClustersAndGeometry = false;
}

// Step 3: run the GEM cluster processor to get the internal clusters
clusterProc_->run(gemClusters);
hasGE21Geometry16Partitions_ = clusterProc_->hasGE21Geometry16Partitions();
if (validClustersAndGeometry) {
// Step 3c: set the lookup tables for coordinate conversion and matching
if (isME11_) {
clusterProc_->setESLookupTables(lookupTableME11ILT_);
cscGEMMatcher_->setESLookupTables(lookupTableME11ILT_);
}
if (isME21_) {
clusterProc_->setESLookupTables(lookupTableME21ILT_);
cscGEMMatcher_->setESLookupTables(lookupTableME21ILT_);
}

// Step 3d: run the GEM cluster processor to get the internal clusters
clusterProc_->run(gemClusters);
hasGE21Geometry16Partitions_ = clusterProc_->hasGE21Geometry16Partitions();
}

/*
Mask for bunch crossings were LCTs were previously found
Expand All @@ -122,12 +142,12 @@ void CSCGEMMotherboard::run(const CSCWireDigiCollection* wiredc,
CSCMotherboard::matchALCTCLCT(bunch_crossing_mask);

// Step 6: CLCT-2GEM matching for BX's that were not previously masked
if (build_lct_from_clct_gem_) {
if (build_lct_from_clct_gem_ and validClustersAndGeometry) {
matchCLCT2GEM(bunch_crossing_mask);
}

// Step 7: ALCT-2GEM matching for BX's that were not previously masked
if (build_lct_from_alct_gem_) {
if (build_lct_from_alct_gem_ and validClustersAndGeometry) {
matchALCT2GEM(bunch_crossing_mask);
}

Expand Down
6 changes: 6 additions & 0 deletions L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ GEMClusterProcessor::GEMClusterProcessor(int region, unsigned station, unsigned
: region_(region), station_(station), chamber_(chamber) {
isEven_ = chamber_ % 2 == 0;

// These LogErrors are sanity checks and should not be printed
if (station_ == 3 or station_ == 4) {
edm::LogError("GEMClusterProcessor") << "Class constructed for a chamber in ME3 or ME4!";
};

if (station_ == 1) {
const edm::ParameterSet copad(conf.getParameter<edm::ParameterSet>("copadParamGE11"));
maxDeltaPad_ = copad.getParameter<unsigned int>("maxDeltaPad");
Expand Down Expand Up @@ -36,6 +41,7 @@ void GEMClusterProcessor::run(const GEMPadDigiClusterCollection* in_clusters) {
// Step 1: clear the GEMInternalCluster vector
clear();

// check that the GEM cluster collection is a valid pointer
if (in_clusters == nullptr) {
edm::LogWarning("GEMClusterProcessor") << "Attempt to run without valid in_clusters pointer.";
return;
Expand Down
13 changes: 13 additions & 0 deletions L1Trigger/L1TGlobal/interface/GlobalBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
// Trigger Objects
#include "DataFormats/L1Trigger/interface/EGamma.h"
#include "DataFormats/L1Trigger/interface/Muon.h"
#include "DataFormats/L1Trigger/interface/MuonShower.h"
#include "DataFormats/L1Trigger/interface/Tau.h"
#include "DataFormats/L1Trigger/interface/Jet.h"
#include "DataFormats/L1Trigger/interface/EtSum.h"
Expand Down Expand Up @@ -77,11 +78,17 @@ namespace l1t {
const bool receiveMu,
const int nrL1Mu);

void receiveMuonShowerObjectData(edm::Event&,
const edm::EDGetTokenT<BXVector<l1t::MuonShower>>&,
const bool receiveMuShower,
const int nrL1MuShower);

void receiveExternalData(edm::Event&, const edm::EDGetTokenT<BXVector<GlobalExtBlk>>&, const bool receiveExt);

/// initialize the class (mainly reserve)
void init(const int numberPhysTriggers,
const int nrL1Mu,
const int nrL1MuShower,
const int nrL1EG,
const int nrL1Tau,
const int nrL1Jet,
Expand All @@ -97,6 +104,7 @@ namespace l1t {
std::unique_ptr<GlobalObjectMapRecord>& gtObjectMapRecord, //GTO
const unsigned int numberPhysTriggers,
const int nrL1Mu,
const int nrL1MuShower,
const int nrL1EG,
const int nrL1Tau,
const int nrL1Jet);
Expand All @@ -122,6 +130,7 @@ namespace l1t {
/// clear uGT
void reset();
void resetMu();
void resetMuonShower();
void resetCalo();
void resetExternal();

Expand All @@ -137,6 +146,9 @@ namespace l1t {
/// return global muon trigger candidate
inline const BXVector<const l1t::Muon*>* getCandL1Mu() const { return m_candL1Mu; }

/// return global muon trigger candidate
inline const BXVector<const l1t::MuonShower*>* getCandL1MuShower() const { return m_candL1MuShower; }

/// pointer to EG data list
inline const BXVector<const l1t::L1Candidate*>* getCandL1EG() const { return m_candL1EG; }

Expand Down Expand Up @@ -203,6 +215,7 @@ namespace l1t {

private:
BXVector<const l1t::Muon*>* m_candL1Mu;
BXVector<const l1t::MuonShower*>* m_candL1MuShower;
BXVector<const l1t::L1Candidate*>* m_candL1EG;
BXVector<const l1t::L1Candidate*>* m_candL1Tau;
BXVector<const l1t::L1Candidate*>* m_candL1Jet;
Expand Down
3 changes: 2 additions & 1 deletion L1Trigger/L1TGlobal/interface/GlobalDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ namespace l1t {
CondCorrelation,
CondExternal,
CondCorrelationWithOverlapRemoval,
CondCorrelationThreeBody
CondCorrelationThreeBody,
CondMuonShower,
};

struct GtConditionCategoryStringToEnum {
Expand Down
81 changes: 81 additions & 0 deletions L1Trigger/L1TGlobal/interface/MuonShowerCondition.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef L1Trigger_L1TGlobal_MuonShowerCondition_h
#define L1Trigger_L1TGlobal_MuonShowerCondition_h

/**
* \class MuonShowerCondition
*
* Description: evaluation of a CondMuonShower condition.
*/

// system include files
#include <iosfwd>
#include <string>

// user include files
// base classes
#include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h"

#include "DataFormats/L1Trigger/interface/MuonShower.h"

// forward declarations
class GlobalCondition;
class MuonShowerTemplate;

namespace l1t {

class GlobalBoard;

// class declaration
class MuonShowerCondition : public ConditionEvaluation {
public:
/// constructors
/// default
MuonShowerCondition();

/// from base template condition (from event setup usually)
MuonShowerCondition(const GlobalCondition*, const GlobalBoard*, const int nrL1MuShower);

// copy constructor
MuonShowerCondition(const MuonShowerCondition&);

// destructor
~MuonShowerCondition() override;

// assign operator
MuonShowerCondition& operator=(const MuonShowerCondition&);

/// the core function to check if the condition matches
const bool evaluateCondition(const int bxEval) const override;

/// print condition
void print(std::ostream& myCout) const override;

/// get / set the pointer to a Condition
inline const MuonShowerTemplate* gtMuonShowerTemplate() const { return m_gtMuonShowerTemplate; }

void setGtMuonShowerTemplate(const MuonShowerTemplate*);

/// get / set the pointer to GTL
inline const GlobalBoard* gtGTL() const { return m_gtGTL; }

void setGtGTL(const GlobalBoard*);

private:
/// copy function for copy constructor and operator=
void copy(const MuonShowerCondition& cp);

/// load muon candidates
const l1t::MuonShower* getCandidate(const int bx, const int indexCand) const;

/// function to check a single object if it matches a condition
const bool checkObjectParameter(const int iCondition, const l1t::MuonShower& cand, const unsigned int index) const;

/// pointer to a MuonShowerTemplate
const MuonShowerTemplate* m_gtMuonShowerTemplate;

/// pointer to GTL, to be able to get the trigger objects
const GlobalBoard* m_gtGTL;
};

} // namespace l1t
#endif
Loading