Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:30:31

0001 #include "CondFormats/L1TObjects/interface/L1RCTParameters.h"
0002 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTElectronIsolationCard.h"
0003 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTLookupTables.h"
0004 
0005 #include <iomanip>
0006 #include <iostream>
0007 
0008 L1RCTElectronIsolationCard::L1RCTElectronIsolationCard(int crateNumber,
0009                                                        int cardNumber,
0010                                                        const L1RCTLookupTables *rctLookupTables)
0011     : crtNo(crateNumber),
0012       cardNo(cardNumber),
0013       rctLookupTables_(rctLookupTables),
0014       isoElectrons(2),
0015       nonIsoElectrons(2),
0016       regions(2) {
0017   regions.push_back(L1RCTRegion());
0018   regions.push_back(L1RCTRegion());
0019 }
0020 
0021 L1RCTElectronIsolationCard::~L1RCTElectronIsolationCard() { regions.clear(); }
0022 
0023 void L1RCTElectronIsolationCard::fillElectronCandidates() {
0024   std::vector<unsigned short> region0Electrons = calcElectronCandidates(regions.at(0), 0);
0025   std::vector<unsigned short> region1Electrons = calcElectronCandidates(regions.at(1), 1);
0026   isoElectrons.at(0) = region0Electrons.at(0);
0027   isoElectrons.at(1) = region1Electrons.at(0);
0028   nonIsoElectrons.at(0) = region0Electrons.at(1);
0029   nonIsoElectrons.at(1) = region1Electrons.at(1);
0030 }
0031 
0032 // This method is the bulk of this class.  It finds the electrons given a
0033 // pointer to a region.  It will return the largest nonIsoElectron candidate and
0034 // the largest isoElectron candidate.  A deposit is an electron candidate if the
0035 // h/e||fg bit is not on and it is higher energy than it's direct four
0036 // neighbors. An electron candidate is *always* a non-isolated electron. If it
0037 // also passes the neighbor cuts then it is an isolated electron as well.
0038 std::vector<unsigned short> L1RCTElectronIsolationCard::calcElectronCandidates(const L1RCTRegion &region,
0039                                                                                int regionNum) {
0040   unsigned short nonIsoElectron = 0;
0041   unsigned short isoElectron = 0;
0042 
0043   // i is row and j is column
0044   for (int i = 0; i < 4; i++) {
0045     for (int j = 0; j < 4; j++) {
0046       unsigned short primaryEt = region.getEtIn7Bits(i, j);
0047       unsigned short primaryHE_FG = region.getHE_FGBit(i, j);
0048 
0049       unsigned short northEt = region.getEtIn7Bits(i - 1, j);
0050       unsigned short southEt = region.getEtIn7Bits(i + 1, j);
0051       unsigned short westEt = region.getEtIn7Bits(i, j - 1);
0052       unsigned short eastEt = region.getEtIn7Bits(i, j + 1);
0053       unsigned short neEt = region.getEtIn7Bits(i - 1, j + 1);
0054       unsigned short nwEt = region.getEtIn7Bits(i - 1, j - 1);
0055       unsigned short seEt = region.getEtIn7Bits(i + 1, j + 1);
0056       unsigned short swEt = region.getEtIn7Bits(i + 1, j - 1);
0057 
0058       unsigned short northHE_FG = region.getHE_FGBit(i - 1, j);
0059       unsigned short southHE_FG = region.getHE_FGBit(i + 1, j);
0060       unsigned short westHE_FG = region.getHE_FGBit(i, j - 1);
0061       unsigned short eastHE_FG = region.getHE_FGBit(i, j + 1);
0062       unsigned short neHE_FG = region.getHE_FGBit(i - 1, j + 1);
0063       unsigned short nwHE_FG = region.getHE_FGBit(i - 1, j - 1);
0064       unsigned short seHE_FG = region.getHE_FGBit(i + 1, j + 1);
0065       unsigned short swHE_FG = region.getHE_FGBit(i + 1, j - 1);
0066 
0067       bool top = false;
0068 
0069       int nCrate = crateNumber();
0070       int nCard = cardNumber();
0071       int nRegion = regionNum;
0072 
0073       // top row of crate
0074       if (nCard == 0 || nCard == 2 || nCard == 4 || (nCard == 6 && nRegion == 0)) {
0075         top = true;
0076       }
0077       // bottom row of crate
0078       else if (nCard == 1 || nCard == 3 || nCard == 5 || (nCard == 6 && nRegion == 1)) {
0079       }  // top already false
0080       else {
0081         std::cerr << "Error! EIC top assignment" << std::endl;  // this shouldn't happen!
0082       }
0083 
0084       // The following values are used for zeroing and determining whether or
0085       // not a tower is a "candidate".  The original primaryEt, northEt, neEt,
0086       // etc. are used to calculate vetoes and must not be zeroed.
0087 
0088       unsigned short primaryTowerEt = primaryEt;
0089       unsigned short northTowerEt = northEt;
0090       unsigned short southTowerEt = southEt;
0091       unsigned short eastTowerEt = eastEt;
0092       unsigned short westTowerEt = westEt;
0093 
0094       // In order to ensure proper selection of candidate tower and neighbor,
0095       // if two neighbor energies are equal, one is set to zero (in the
0096       // appropriate regions, those for which tp_lf bit is set to 0 in
0097       // Pam's JCCTest/EGWithShare.cc).
0098 
0099       if (primaryEt > 0)  // this value should maybe be customizable?
0100       {
0101         if (nCard != 6)  // all cards except 6
0102         {
0103           if (top && nCrate >= 9)  // top row of regions in positive-eta crate
0104           {
0105             if (westTowerEt == eastTowerEt)
0106               westTowerEt = 0;
0107             if (southTowerEt == northTowerEt)
0108               southTowerEt = 0;
0109             if (southTowerEt == eastTowerEt)
0110               southTowerEt = 0;
0111             if (westTowerEt == northTowerEt)
0112               westTowerEt = 0;
0113           } else if ((!top) && nCrate < 9)  // bottom row of regions in negative-eta crate
0114           {
0115             if (eastTowerEt == westTowerEt)
0116               eastTowerEt = 0;
0117             if (northTowerEt == southTowerEt)
0118               northTowerEt = 0;
0119             if (northTowerEt == westTowerEt)
0120               northTowerEt = 0;
0121             if (eastTowerEt == southTowerEt)
0122               eastTowerEt = 0;
0123           }
0124         } else  // card 6
0125         {
0126           // only +eta card 6 needs to have zeroing.  Pam sez.
0127           // -eta card 6 does what it's supposed to even w/o zeroing.
0128           if (nRegion == 0 && nCrate >= 9) {
0129             if (westTowerEt == eastTowerEt)
0130               westTowerEt = 0;
0131             if (southTowerEt == northTowerEt)
0132               southTowerEt = 0;
0133             if (southTowerEt == eastTowerEt)
0134               southTowerEt = 0;
0135             if (westTowerEt == northTowerEt)
0136               westTowerEt = 0;
0137           }
0138         }
0139       }
0140 
0141       // This section compares the energies in the primary tower with the
0142       // surrounding towers to determine whether or not the primary tower
0143       // should be considered a "candidate".
0144 
0145       bool candidate = false;
0146 
0147       // for case where primary tower et greater than all neighbors -> candidate
0148       if (primaryEt > northEt && primaryEt > southEt && primaryEt > eastEt && primaryEt > westEt && !primaryHE_FG) {
0149         candidate = true;
0150       }
0151 
0152       // if primary et less than any neighbors (or HE_FG veto set) NOT a
0153       // candidate!
0154       else if (primaryEt < northEt || primaryEt < southEt || primaryEt < eastEt || primaryEt < westEt || primaryHE_FG) {
0155       }  // candidate already false
0156 
0157       else  // Case of primary tower et being equal to any of its neighbors.
0158             // This section determines which tower gets the candidate.
0159             // See AboutTP.pdf document, figure on p. 4, for clarification.
0160             // Zeroed values are used in this calculation.
0161       {
0162         if (primaryEt > 0) {
0163           if (nCrate >= 9)  // positive eta
0164           {
0165             if (top)  // top row of regions in crate.  tp_lf == 0
0166                       // priority order: east < south < north < west
0167             {
0168               if (westTowerEt == primaryTowerEt)
0169                 candidate = true;
0170               else if (northTowerEt == primaryTowerEt)
0171                 candidate = false;
0172               else if (southTowerEt == primaryTowerEt)
0173                 candidate = true;
0174               else if (eastTowerEt == primaryTowerEt)
0175                 candidate = false;
0176             }
0177 
0178             else  // bottom row of regions in crate.  tp_lf == 1
0179                   // priority order: west < north < south < east
0180             {
0181               if (eastTowerEt == primaryTowerEt)
0182                 candidate = true;
0183               else if (southTowerEt == primaryTowerEt)
0184                 candidate = true;
0185               else if (northTowerEt == primaryTowerEt)
0186                 candidate = false;
0187               else if (westTowerEt == primaryTowerEt)
0188                 candidate = false;
0189               if (nCard == 6)  // card 6. tp_lf == 1
0190               {
0191                 // priority order: east < north < south < west
0192                 if (westTowerEt == primaryTowerEt)
0193                   candidate = true;
0194                 else if (southTowerEt == primaryTowerEt)
0195                   candidate = true;
0196                 else if (northTowerEt == primaryTowerEt)
0197                   candidate = false;
0198                 else if (eastTowerEt == primaryTowerEt)
0199                   candidate = false;
0200               }
0201             }
0202           } else  // negative eta
0203           {
0204             if (top)  // top row of regions in crate.  tp_lf == 1
0205                       // priority order: east < south < north < west
0206             {
0207               if (westTowerEt == primaryTowerEt)
0208                 candidate = true;
0209               else if (northTowerEt == primaryTowerEt)
0210                 candidate = true;
0211               else if (southTowerEt == primaryTowerEt)
0212                 candidate = false;
0213               else if (eastTowerEt == primaryTowerEt)
0214                 candidate = false;
0215               if (nCard == 6)  // card 6.  tp_lf == 0
0216                                // east < south < north < west
0217               {
0218                 if (westTowerEt == primaryTowerEt)
0219                   candidate = false;
0220                 else if (northTowerEt == primaryTowerEt)
0221                   candidate = false;
0222                 else if (southTowerEt == primaryTowerEt)
0223                   candidate = true;
0224                 else if (eastTowerEt == primaryTowerEt)
0225                   candidate = true;
0226               }
0227             } else  // bottom row of regions.  tp_lf == 0
0228                     // west < north < south < east
0229             {
0230               if (eastTowerEt == primaryTowerEt)
0231                 candidate = true;
0232               else if (southTowerEt == primaryTowerEt)
0233                 candidate = false;
0234               else if (northTowerEt == primaryTowerEt)
0235                 candidate = true;
0236               else if (westTowerEt == primaryTowerEt)
0237                 candidate = false;
0238 
0239               if (nCard == 6)  // card 6.  tp_lf == 1
0240                                // west < north < south < east
0241               {
0242                 if (eastTowerEt == primaryTowerEt)
0243                   candidate = true;
0244                 else if (southTowerEt == primaryTowerEt)
0245                   candidate = true;
0246                 else if (northTowerEt == primaryTowerEt)
0247                   candidate = false;
0248                 else if (westTowerEt == primaryTowerEt)
0249                   candidate = false;
0250               }
0251             }
0252           }
0253         }
0254       }  // end of if (primary == neighbors)
0255 
0256       if (candidate) {
0257         // Either zeroed or non-zeroed set of values can be used here --
0258         // neighbor tower only zeroed if another neighbor tower of same
0259         // energy.  Max sum calculated from primary and only one neighbor
0260         // tower, and always one neighbor tower left over, so value of sum
0261         // is not affected.  Currently using non-zeroed.
0262         unsigned short candidateEt = calcMaxSum(primaryEt, northEt, southEt, eastEt, westEt);
0263 
0264         // neighbor HE_FG veto true if neighbor has HE_FG set
0265         bool neighborVeto =
0266             (nwHE_FG || northHE_FG || neHE_FG || westHE_FG || eastHE_FG || swHE_FG || southHE_FG || seHE_FG);
0267 
0268         // threshold for five-tower corner quiet veto
0269         // int quietThreshold = 3;   // 3 - loose isolation 0 - very tight
0270         // isolation int quietThreshold = 7; // ECALGREN int quietThreshold = 0;
0271         // // HCALGREN
0272         unsigned quietThreshold = rctLookupTables_->rctParameters()->eicIsolationThreshold();
0273 
0274         bool nw = false;
0275         bool ne = false;
0276         bool sw = false;
0277         bool se = false;
0278         bool n = false;
0279         bool w = false;
0280         bool s = false;
0281         bool e = false;
0282 
0283         // individual neighbor vetoes set if neighbor is over threshold
0284         if (nwEt >= quietThreshold)
0285           nw = true;
0286         if (neEt >= quietThreshold)
0287           ne = true;
0288         if (swEt >= quietThreshold)
0289           sw = true;
0290         if (seEt >= quietThreshold)
0291           se = true;
0292         if (northEt >= quietThreshold)
0293           n = true;
0294         if (southEt >= quietThreshold)
0295           s = true;
0296         if (westEt >= quietThreshold)
0297           w = true;
0298         if (eastEt >= quietThreshold)
0299           e = true;
0300 
0301         // veto TRUE for each corner set if any individual tower in each set is
0302         // over threshold
0303         bool nwC = (sw || w || nw || n || ne);
0304         bool neC = (nw || n || ne || e || se);
0305         bool seC = (ne || e || se || s || sw);
0306         bool swC = (se || s || sw || w || nw);
0307 
0308         // overall quiet veto TRUE only if NO corner sets are quiet
0309         // (all are "loud") -> non-isolated
0310         bool quietVeto = (nwC && neC && seC && swC);
0311 
0312         // only isolated if both vetoes are false
0313         // Note: quietThreshold = 0 forces all candidates to be non-iso
0314         if (!(quietVeto || neighborVeto)) {
0315           if (candidateEt > isoElectron)
0316             isoElectron = candidateEt;
0317         }
0318         // otherwise, non-isolated
0319         else if (candidateEt > nonIsoElectron)
0320           nonIsoElectron = candidateEt;
0321       }
0322     }
0323   }
0324 
0325   std::vector<unsigned short> candidates;
0326   unsigned short fullIsoElectron =
0327       isoElectron * 16 + cardNo * 2;  // leaves room for last bit -- region number, added in Crate.cc
0328   candidates.push_back(fullIsoElectron);
0329   unsigned short fullNonIsoElectron = nonIsoElectron * 16 + cardNo * 2;  // leaves room for region info in last bit
0330   candidates.push_back(fullNonIsoElectron);
0331 
0332   return candidates;
0333 }
0334 
0335 unsigned short L1RCTElectronIsolationCard::calcMaxSum(unsigned short primaryEt,
0336                                                       unsigned short northEt,
0337                                                       unsigned short southEt,
0338                                                       unsigned short eastEt,
0339                                                       unsigned short westEt) {
0340   unsigned short cardinals[4] = {northEt, southEt, eastEt, westEt};
0341   unsigned short max = 0;
0342   for (int i = 0; i < 4; i++) {
0343     unsigned short test = primaryEt + cardinals[i];
0344     if (test > max)
0345       max = test;
0346   }
0347   return max;
0348 }
0349 
0350 void L1RCTElectronIsolationCard::print() {
0351   std::cout << "Electron isolation card " << cardNo << std::endl;
0352   std::cout << "Region 0 Information" << std::endl;
0353   regions.at(0).print();
0354 
0355   std::cout << "IsoElectron Candidate " << isoElectrons.at(0) << std::endl;
0356   std::cout << "NonIsoElectron Candidate " << nonIsoElectrons.at(0) << std::endl << std::endl;
0357 
0358   std::cout << "Region 1 Information" << std::endl;
0359   regions.at(1).print();
0360 
0361   std::cout << "IsoElectron Candidate " << isoElectrons.at(1) << std::endl;
0362   std::cout << "NonIsoElectron Candidate " << nonIsoElectrons.at(1) << std::endl;
0363 }