Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new ALCT-CLCT match algorithm for high pt muon showers #40572

Merged
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
22 changes: 20 additions & 2 deletions L1Trigger/CSCTriggerPrimitives/interface/CSCCathodeLCTProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class CSCCathodeLCTProcessor : public CSCBaseboard {
CSCCLCTDigi getBestCLCT(int bx) const;
CSCCLCTDigi getSecondCLCT(int bx) const;

/* get the flag of local shower around best CLCT at bx */
bool getLocalShowerFlag(int bx) const;

std::vector<int> preTriggerBXs() const { return thePreTriggerBXs; }

/** read out CLCTs in ME1a , ME1b */
Expand All @@ -105,6 +108,9 @@ class CSCCathodeLCTProcessor : public CSCBaseboard {
CSCShowerDigi cathode_showers_[CSCConstants::MAX_CLCT_TBINS];
//CSCShowerDigi shower_;

/* flag of shower around best CLCT in each BX */
bool localShowerFlag[CSCConstants::MAX_CLCT_TBINS];

/** Access routines to comparator digis. */
bool getDigis(const CSCComparatorDigiCollection* compdc);
void getDigis(const CSCComparatorDigiCollection* compdc, const CSCDetId& id);
Expand Down Expand Up @@ -160,7 +166,14 @@ class CSCCathodeLCTProcessor : public CSCBaseboard {

/** Dump half-strip digis */
void dumpDigis(
const std::vector<int> strip[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER]) const;
const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER]) const;

/* check whether there is a shower around best CLCT */
void checkLocalShower(
int zone,
const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER]);

void encodeHighMultiplicityBits();

//--------------------------- Member variables -----------------------------

Expand Down Expand Up @@ -191,7 +204,6 @@ class CSCCathodeLCTProcessor : public CSCBaseboard {
std::vector<CSCCLCTPreTriggerDigi> thePreTriggerDigis;

/* data members for high multiplicity triggers */
void encodeHighMultiplicityBits();
std::vector<unsigned> thresholds_;
unsigned showerNumTBins_;
unsigned minLayersCentralTBin_;
Expand All @@ -210,6 +222,12 @@ class CSCCathodeLCTProcessor : public CSCBaseboard {
/** VK: some quick and dirty fix to reduce CLCT deadtime */
int start_bx_shift;

/* define the region around best CLCT to check local shower */
int localShowerZone;

/* threshold of total hits for local shower */
int localShowerThresh;

/** VK: separate handle for early time bins */
int early_tbins;

Expand Down
7 changes: 7 additions & 0 deletions L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ class CSCMotherboard : public CSCBaseboard {
*/
std::vector<int> preferred_bx_match_;

/* sort CLCT by bx if true, otherwise sort CLCT by quality+bending */
bool sort_clct_bx_;

/** Default values of configuration parameters. */
static const unsigned int def_mpc_block_me1a;
static const unsigned int def_alct_trig_enable, def_clct_trig_enable;
Expand All @@ -184,6 +187,10 @@ class CSCMotherboard : public CSCBaseboard {
/** Make sure that the parameter values are within the allowed range. */
void checkConfigParameters();

/*sort CLCT by quality+bending and if CLCTs from different BX have
same quality+bending, then rank CLCT by timing
*/
void sortCLCTByQualBend(int alct_bx, std::vector<unsigned>& clctBxVector);
/*
For valid ALCTs in the trigger time window, look for CLCTs within the
match-time window. Valid CLCTs are matched in-time. If a match was found
Expand Down
4 changes: 4 additions & 0 deletions L1Trigger/CSCTriggerPrimitives/python/params/clctParams.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@

# BX to start CLCT finding (poor man's dead-time shortening):
clctStartBxShift = cms.int32(0),
# local shower zone
clctLocalShowerZone = cms.int32(25),
# local shower thresh
clctLocalShowerThresh = cms.int32(12),
)

# Parameters for upgrade CLCT processors
Expand Down
4 changes: 4 additions & 0 deletions L1Trigger/CSCTriggerPrimitives/python/params/tmbParams.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# perfectly in-time CLCTs are preferred, followed by
# first-early, first-late, second-early, second late, etc.
preferredBxMatch = cms.vint32(0, -1, 1, -2, 2, -3, 3),
#use CLCT sorted by Bx only for ALCT-CLCTmatch
sortClctBx = cms.bool(True),
# readout window for the DAQ
# LCTs found in the window [5, 6, 7, 8, 9, 10, 11] are good
tmbL1aWindowSize = cms.uint32(7),
Expand Down Expand Up @@ -49,6 +51,8 @@
tmbPhase2 = tmbPhase1.clone(
# ALCT-CLCT stays at 7 for the moment
matchTrigWindowSize = 7,
#use CLCT sorted by Bx only for ALCT-CLCTmatch for now
sortClctBx = True,
# LCTs found in the window [5, 6, 7, 8, 9, 10, 11] are good
tmbL1aWindowSize = 7,
tmbDropUsedClcts = False,
Expand Down
12 changes: 10 additions & 2 deletions L1Trigger/CSCTriggerPrimitives/src/CSCAnodeLCTProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1278,9 +1278,17 @@ std::vector<CSCALCTDigi> CSCAnodeLCTProcessor::getALCTs() const {
return tmpV;
}

CSCALCTDigi CSCAnodeLCTProcessor::getBestALCT(int bx) const { return bestALCT[bx]; }
CSCALCTDigi CSCAnodeLCTProcessor::getBestALCT(int bx) const {
if (bx >= CSCConstants::MAX_CLCT_TBINS or bx < 0)
return CSCALCTDigi();
return bestALCT[bx];
}

CSCALCTDigi CSCAnodeLCTProcessor::getSecondALCT(int bx) const { return secondALCT[bx]; }
CSCALCTDigi CSCAnodeLCTProcessor::getSecondALCT(int bx) const {
if (bx >= CSCConstants::MAX_CLCT_TBINS or bx < 0)
return CSCALCTDigi();
return secondALCT[bx];
}

/** return vector of CSCShower digi **/
std::vector<CSCShowerDigi> CSCAnodeLCTProcessor::getAllShower() const {
Expand Down
48 changes: 48 additions & 0 deletions L1Trigger/CSCTriggerPrimitives/src/CSCCathodeLCTProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ CSCCathodeLCTProcessor::CSCCathodeLCTProcessor(unsigned endcap,

start_bx_shift = clctParams_.getParameter<int>("clctStartBxShift");

localShowerZone = clctParams_.getParameter<int>("clctLocalShowerZone");

localShowerThresh = clctParams_.getParameter<int>("clctLocalShowerThresh");

// Motherboard parameters: common for all configurations.
tmb_l1a_window_size = // Common to CLCT and TMB
tmbParams_.getParameter<unsigned int>("tmbL1aWindowSize");
Expand Down Expand Up @@ -186,6 +190,7 @@ void CSCCathodeLCTProcessor::clear() {
bestCLCT[bx].clear();
secondCLCT[bx].clear();
cathode_showers_[bx].clear();
localShowerFlag[bx] = false; //init with no shower around CLCT
}
}

Expand Down Expand Up @@ -384,10 +389,43 @@ void CSCCathodeLCTProcessor::run(
<< "\n";
}
}
checkLocalShower(localShowerZone, halfstrip);
// Now that we have our best CLCTs, they get correlated with the best
// ALCTs and then get sent to the MotherBoard. -JM
}

void CSCCathodeLCTProcessor::checkLocalShower(
int zone,
const std::vector<int> halfstrip[CSCConstants::NUM_LAYERS][CSCConstants::MAX_NUM_HALF_STRIPS_RUN2_TRIGGER]) {
// Fire half-strip one-shots for hit_persist bx's (4 bx's by default).
//check local shower after pulse extension
pulseExtension(halfstrip);

for (int bx = 0; bx < CSCConstants::MAX_CLCT_TBINS; bx++) {
if (not bestCLCT[bx].isValid())
continue;

//only check the region around best CLCT
int keyHS = bestCLCT[bx].getKeyStrip();
int minHS = (keyHS - zone) >= stagger[CSCConstants::KEY_CLCT_LAYER - 1] ? keyHS - zone
: stagger[CSCConstants::KEY_CLCT_LAYER - 1];
int maxHS = (keyHS + zone) >= numHalfStrips_ ? numHalfStrips_ : keyHS + zone;
int totalHits = 0;
for (int hstrip = minHS; hstrip < maxHS; hstrip++) {
for (int this_layer = 0; this_layer < CSCConstants::NUM_LAYERS; this_layer++)
if (pulse_.isOneShotHighAtBX(this_layer, hstrip, bx + drift_delay))
totalHits++;
}

localShowerFlag[bx] = totalHits >= localShowerThresh;
if (infoV > 1)
LogDebug("CSCCathodeLCTProcessor") << " bx " << bx << " bestCLCT key HS " << keyHS
<< " localshower zone: " << minHS << ", " << maxHS << " totalHits "
<< totalHits
<< (localShowerFlag[bx] ? " Validlocalshower " : " NolocalShower ");
}
}

bool CSCCathodeLCTProcessor::getDigis(const CSCComparatorDigiCollection* compdc) {
bool hasDigis = false;

Expand Down Expand Up @@ -1197,17 +1235,27 @@ std::vector<CSCCLCTDigi> CSCCathodeLCTProcessor::getCLCTs() const {
// to make a proper comparison with ALCTs we need
// CLCT and ALCT to have the central BX in the same bin
CSCCLCTDigi CSCCathodeLCTProcessor::getBestCLCT(int bx) const {
if (bx >= CSCConstants::MAX_CLCT_TBINS or bx < 0)
return CSCCLCTDigi();
CSCCLCTDigi lct = bestCLCT[bx];
lct.setBX(lct.getBX() + CSCConstants::ALCT_CLCT_OFFSET);
return lct;
}

CSCCLCTDigi CSCCathodeLCTProcessor::getSecondCLCT(int bx) const {
if (bx >= CSCConstants::MAX_CLCT_TBINS or bx < 0)
return CSCCLCTDigi();
CSCCLCTDigi lct = secondCLCT[bx];
lct.setBX(lct.getBX() + CSCConstants::ALCT_CLCT_OFFSET);
return lct;
}

bool CSCCathodeLCTProcessor::getLocalShowerFlag(int bx) const {
if (bx >= CSCConstants::MAX_CLCT_TBINS or bx < 0)
return false;
return localShowerFlag[bx];
}

/** return vector of CSCShower digi **/
std::vector<CSCShowerDigi> CSCCathodeLCTProcessor::getAllShower() const {
std::vector<CSCShowerDigi> vshowers(cathode_showers_, cathode_showers_ + CSCConstants::MAX_CLCT_TBINS);
Expand Down
28 changes: 24 additions & 4 deletions L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,46 @@ void CSCGEMMotherboard::matchALCTCLCTGEM() {
// Find best and second CLCTs by preferred CLCT BX, taking into account that there is an offset in the simulation

unsigned matchingBX = 0;
unsigned matching_clctbx = 0;
unsigned bx_clct = 0;

std::vector<unsigned> clctBx_qualbend_match;
sortCLCTByQualBend(bx_alct, clctBx_qualbend_match);

bool hasLocalShower = false;
for (unsigned ibx = 1; ibx <= match_trig_window_size / 2; ibx++)
hasLocalShower = (hasLocalShower or clctProc->getLocalShowerFlag(bx_alct - CSCConstants::ALCT_CLCT_OFFSET - ibx));
// BestCLCT and secondCLCT
for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) {
unsigned bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
//bx_clct_run2 would be overflow when bx_alct is small but it is okay
unsigned bx_clct_run2 = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
unsigned bx_clct_qualbend = clctBx_qualbend_match[mbx];
bx_clct = (sort_clct_bx_ or not(hasLocalShower)) ? bx_clct_run2 : bx_clct_qualbend;

if (bx_clct >= CSCConstants::MAX_CLCT_TBINS)
continue;
bestCLCT = clctProc->getBestCLCT(bx_clct);
secondCLCT = clctProc->getSecondCLCT(bx_clct);
matchingBX = mbx;
if (bestCLCT.isValid())
matching_clctbx = mbx;

if ((clctProc->getBestCLCT(bx_clct)).isValid())
break;
}

bestCLCT = clctProc->getBestCLCT(bx_clct);
secondCLCT = clctProc->getSecondCLCT(bx_clct);

if (!bestALCT.isValid() and !secondALCT.isValid() and !bestCLCT.isValid() and !secondCLCT.isValid())
continue;
if (!build_lct_from_clct_gem_ and !bestALCT.isValid())
continue;
if (!build_lct_from_alct_gem_ and !bestCLCT.isValid())
continue;

if (infoV > 1)
LogTrace("CSCGEMMotherboard") << "GEMCSCOTMB: Successful ALCT-CLCT match: bx_alct = " << bx_alct
<< "; bx_clct = " << matching_clctbx << "; mbx = " << matchingBX << " bestALCT "
<< bestALCT << " secondALCT " << secondALCT << " bestCLCT " << bestCLCT
<< " secondCLCT " << secondCLCT;
// ALCT + CLCT + GEM

for (unsigned gmbx = 0; gmbx < alct_gem_bx_window_size_; gmbx++) {
Expand Down
57 changes: 55 additions & 2 deletions L1Trigger/CSCTriggerPrimitives/src/CSCMotherboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ CSCMotherboard::CSCMotherboard(unsigned endcap,
// get the preferred CLCT BX match array
preferred_bx_match_ = tmbParams_.getParameter<std::vector<int>>("preferredBxMatch");

// sort CLCT only by bx or by quality+bending for ALCT-CLCT match
sort_clct_bx_ = tmbParams_.getParameter<bool>("sortClctBx");

// quality assignment
qualityAssignment_ = std::make_unique<LCTQualityAssignment>(endcap, station, sector, subsector, chamber, conf);

Expand Down Expand Up @@ -198,12 +201,25 @@ void CSCMotherboard::matchALCTCLCT() {
// need to access "full BX" words, which are not readily
// available.
bool is_matched = false;
// we can use single value to best CLCT but here use vector to keep the
// the future option to do multiple ALCT-CLCT matches wiht CLCT from different bx
std::vector<unsigned> clctBx_qualbend_match;
sortCLCTByQualBend(bx_alct, clctBx_qualbend_match);

bool hasLocalShower = false;
for (unsigned ibx = 1; ibx <= match_trig_window_size / 2; ibx++)
hasLocalShower =
(hasLocalShower or clctProc->getLocalShowerFlag(bx_alct - CSCConstants::ALCT_CLCT_OFFSET - ibx));

// loop on the preferred "delta BX" array
for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) {
// evaluate the preffered CLCT BX, taking into account that there is an offset in the simulation
int bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
//bx_clct_run2 would be overflow when bx_alct is small but it is okay
unsigned bx_clct_run2 = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
unsigned bx_clct_qualbend = clctBx_qualbend_match[mbx];
unsigned bx_clct = (sort_clct_bx_ or not(hasLocalShower)) ? bx_clct_run2 : bx_clct_qualbend;
// check that the CLCT BX is valid
if (bx_clct >= CSCConstants::MAX_CLCT_TBINS or bx_clct < 0)
if (bx_clct >= CSCConstants::MAX_CLCT_TBINS)
continue;
// do not consider previously matched CLCTs
if (drop_used_clcts && used_clct_mask[bx_clct])
Expand Down Expand Up @@ -555,6 +571,43 @@ void CSCMotherboard::selectLCTs() {
}
}

void CSCMotherboard::sortCLCTByQualBend(int bx_alct, std::vector<unsigned>& clctBxVector) {
//find clct bx range in [centerbx-window_size/2, center_bx+window_size/2]
//Then sort CLCT based quality+bend within the match window
//if two CLCTs from different BX has same qual+bend, the in-time one has higher priority
clctBxVector.clear();
int clctQualBendArray[CSCConstants::MAX_CLCT_TBINS + 1] = {0};
for (unsigned mbx = 0; mbx < match_trig_window_size; mbx++) {
unsigned bx_clct = bx_alct + preferred_bx_match_[mbx] - CSCConstants::ALCT_CLCT_OFFSET;
int tempQualBend = 0;
if (bx_clct >= CSCConstants::MAX_CLCT_TBINS)
continue;
if (!clctProc->getBestCLCT(bx_clct).isValid()) {
clctQualBendArray[bx_clct] = tempQualBend;
continue;
}
CSCCLCTDigi bestCLCT = clctProc->getBestCLCT(bx_clct);
//for run2 pattern, ignore direction and use &0xe
//for run3, slope=0 is straighest pattern
int clctBend = bestCLCT.isRun3() ? (16 - bestCLCT.getSlope()) : (bestCLCT.getPattern() & 0xe);
//shift quality to left for 4 bits
int clctQualBend = clctBend | (bestCLCT.getQuality() << 5);
clctQualBendArray[bx_clct] = clctQualBend;
if (clctBxVector.empty())
clctBxVector.push_back(bx_clct);
else {
for (auto it = clctBxVector.begin(); it != clctBxVector.end(); it++)
if (clctQualBend > clctQualBendArray[*it]) { //insert the Bx with better clct
clctBxVector.insert(it, bx_clct);
break;
}
}
}
//fill rest of vector with MAX_CLCT_TBINS
for (unsigned bx = clctBxVector.size(); bx < match_trig_window_size; bx++)
clctBxVector.push_back(CSCConstants::MAX_CLCT_TBINS);
}

void CSCMotherboard::checkConfigParameters() {
// Make sure that the parameter values are within the allowed range.

Expand Down