Skip to content

Commit

Permalink
Merge pull request #40572 from tahuang1991/from-CMSSW_12_6_0_pre2_new…
Browse files Browse the repository at this point in the history
…CLCTSorting

Add new ALCT-CLCT match algorithm for high pt muon  showers
  • Loading branch information
cmsbuild authored Jan 27, 2023
2 parents 5904ea7 + d6a1755 commit ae444b6
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 10 deletions.
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

0 comments on commit ae444b6

Please sign in to comment.