Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:47

0001 #include "L1Trigger/DTTriggerPhase2/interface/MPSLFilter.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003 
0004 using namespace edm;
0005 using namespace std;
0006 using namespace cmsdt;
0007 
0008 // ============================================================================
0009 // Constructors and destructor
0010 // ============================================================================
0011 MPSLFilter::MPSLFilter(const ParameterSet &pset) : MPFilter(pset), debug_(pset.getUntrackedParameter<bool>("debug")) {}
0012 
0013 // ============================================================================
0014 // Main methods (initialise, run, finish)
0015 // ============================================================================
0016 void MPSLFilter::initialise(const edm::EventSetup &iEventSetup) {}
0017 
0018 void MPSLFilter::run(edm::Event &iEvent,
0019                      const edm::EventSetup &iEventSetup,
0020                      std::vector<metaPrimitive> &inMPaths,
0021                      std::vector<metaPrimitive> &outMPaths) {
0022   if (debug_)
0023     LogDebug("MPSLFilter") << "MPSLFilter: run";
0024   if (!inMPaths.empty()) {
0025     int dum_sl_rawid = inMPaths[0].rawId;
0026     DTSuperLayerId dumSlId(dum_sl_rawid);
0027     DTChamberId ChId(dumSlId.wheel(), dumSlId.station(), dumSlId.sector());
0028     max_drift_tdc = maxdriftinfo_[dumSlId.wheel() + 2][dumSlId.station() - 1][dumSlId.sector() - 1];
0029     DTSuperLayerId sl1Id(ChId.rawId(), 1);
0030     DTSuperLayerId sl2Id(ChId.rawId(), 2);
0031     DTSuperLayerId sl3Id(ChId.rawId(), 3);
0032 
0033     std::vector<metaPrimitive> SL1metaPrimitives;
0034     std::vector<metaPrimitive> SL2metaPrimitives;
0035     std::vector<metaPrimitive> SL3metaPrimitives;
0036     for (const auto &metaprimitiveIt : inMPaths) {
0037       // int BX = metaprimitiveIt.t0 / 25;
0038       if (metaprimitiveIt.rawId == sl1Id.rawId())
0039         SL1metaPrimitives.push_back(metaprimitiveIt);
0040       else if (metaprimitiveIt.rawId == sl3Id.rawId())
0041         SL3metaPrimitives.push_back(metaprimitiveIt);
0042       else if (metaprimitiveIt.rawId == sl2Id.rawId())
0043         SL2metaPrimitives.push_back(metaprimitiveIt);
0044     }
0045 
0046     auto filteredSL1MPs = filter(SL1metaPrimitives);
0047     auto filteredSL2MPs = filter(SL2metaPrimitives);
0048     auto filteredSL3MPs = filter(SL3metaPrimitives);
0049 
0050     for (auto &mp : filteredSL1MPs)
0051       outMPaths.push_back(mp);
0052     for (auto &mp : filteredSL2MPs)
0053       outMPaths.push_back(mp);
0054     for (auto &mp : filteredSL3MPs)
0055       outMPaths.push_back(mp);
0056   }
0057 }
0058 
0059 void MPSLFilter::finish(){};
0060 
0061 ///////////////////////////
0062 ///  OTHER METHODS
0063 
0064 std::vector<metaPrimitive> MPSLFilter::filter(std::vector<metaPrimitive> mps) {
0065   std::map<int, valid_tp_arr_t> mp_valid_per_bx;
0066   for (auto &mp : mps) {
0067     int BX = mp.t0 / 25;
0068     if (mp_valid_per_bx.find(BX) == mp_valid_per_bx.end())
0069       mp_valid_per_bx[BX] = valid_tp_arr_t(6);
0070 
0071     // is this mp getting killed?
0072     if (isDead(mp, mp_valid_per_bx))
0073       continue;
0074     // if not, let's kill other mps
0075     auto index = killTps(mp, BX, mp_valid_per_bx);
0076     if (index == -1)
0077       continue;
0078     mp_valid_per_bx[BX][index] = valid_tp_t({true, mp});
0079   }
0080 
0081   std::vector<metaPrimitive> outTPs;
0082   for (auto &elem : mp_valid_per_bx) {
0083     for (auto &mp_valid : elem.second) {
0084       if (mp_valid.valid)
0085         outTPs.push_back(mp_valid.mp);
0086     }
0087   }
0088 
0089   return outTPs;
0090 }
0091 
0092 int MPSLFilter::match(cmsdt::metaPrimitive mp, cmsdt::metaPrimitive mp2) {
0093   if ((mp.quality == mp2.quality) && (mp.quality == LOWQ || mp2.quality == CLOWQ))
0094     return 1;
0095 
0096   // CONFIRMATION, FIXME ///////////////////////////
0097   // if (mp.quality == CLOWQ && mp2.quality == HIGHQ) {
0098   // if (share_hit(mp, mp2)) return 2;
0099   // return 3;
0100   // }
0101   // if (mp.quality == HIGHQ && mp2.quality == CLOWQ) {
0102   // if (share_hit(mp, mp2)) return 4;
0103   // return 5;
0104   // }
0105   //////////////////////////////////////////////////
0106 
0107   if (mp.quality > mp2.quality) {
0108     if (share_hit(mp, mp2))
0109       return 2;
0110     return 3;
0111   }
0112   if (mp.quality < mp2.quality) {
0113     if (share_hit(mp, mp2))
0114       return 4;
0115     return 5;
0116   }
0117   if (share_hit(mp, mp2)) {
0118     if (smaller_chi2(mp, mp2) == 0)
0119       return 6;
0120     return 7;
0121   }
0122   if (smaller_chi2(mp, mp2) == 0)
0123     return 8;
0124   return 9;
0125 }
0126 
0127 bool MPSLFilter::isDead(cmsdt::metaPrimitive mp, std::map<int, valid_tp_arr_t> tps_per_bx) {
0128   for (auto &elem : tps_per_bx) {
0129     for (auto &mp_valid : elem.second) {
0130       if (!mp_valid.valid)
0131         continue;
0132       int isMatched = match(mp, mp_valid.mp);
0133       if (isMatched == 4 || isMatched == 7)
0134         return true;
0135     }
0136   }
0137   return false;
0138 }
0139 
0140 int MPSLFilter::smaller_chi2(cmsdt::metaPrimitive mp, cmsdt::metaPrimitive mp2) {
0141   auto chi2_1 = get_chi2(mp);
0142   auto chi2_2 = get_chi2(mp2);
0143   if (chi2_1 < chi2_2)
0144     return 0;
0145   return 1;
0146 }
0147 
0148 int MPSLFilter::get_chi2(cmsdt::metaPrimitive mp) {
0149   // CHI2 is converted to an unsigned in which 4 msb are the exponent
0150   // of a float-like value and the rest of the bits are the mantissa
0151   // (without the first 1). So comparing these reduced-width unsigned
0152   // values is equivalent to comparing rounded versions of the chi2
0153 
0154   int chi2 = (int)round(mp.chi2 / (std::pow(((float)CELL_SEMILENGTH / (float)max_drift_tdc), 2) / 100));
0155 
0156   std::vector<int> chi2_unsigned, chi2_unsigned_msb;
0157   vhdl_int_to_unsigned(chi2, chi2_unsigned);
0158 
0159   if (chi2_unsigned.size() > 2) {
0160     for (int i = (int)chi2_unsigned.size() - 1; i >= 2; i--) {
0161       if (chi2_unsigned[i] == 1) {
0162         vhdl_int_to_unsigned(i - 1, chi2_unsigned_msb);
0163 
0164         for (int j = i - 1; j > i - 3; j--) {
0165           chi2_unsigned_msb.insert(chi2_unsigned_msb.begin(), chi2_unsigned[j]);
0166         }
0167         return vhdl_unsigned_to_int(chi2_unsigned_msb);
0168       }
0169     }
0170   }
0171   vhdl_resize_unsigned(chi2_unsigned, 2);
0172   return vhdl_unsigned_to_int(vhdl_slice(chi2_unsigned, 1, 0));
0173 }
0174 
0175 int MPSLFilter::killTps(cmsdt::metaPrimitive mp, int bx, std::map<int, valid_tp_arr_t> &tps_per_bx) {
0176   int index_to_occupy = -1;
0177   int index_to_kill = -1;
0178   for (auto &elem : tps_per_bx) {
0179     if (abs(bx - elem.first) > 16)
0180       continue;
0181     for (size_t i = 0; i < elem.second.size(); i++) {
0182       if (elem.second[i].valid == 1) {
0183         int isMatched = match(mp, elem.second[i].mp);
0184         if (isMatched == 2 || isMatched == 6) {
0185           elem.second[i].valid = false;
0186           if (elem.first == bx && index_to_kill == -1)
0187             index_to_kill = i;
0188         }
0189       } else if (elem.first == bx && index_to_occupy == -1)
0190         index_to_occupy = i;
0191     }
0192   }
0193   // My first option is to replace the one from my BX that I killed first
0194   if (index_to_kill != -1)
0195     return index_to_kill;
0196   // If I wasn't able to kill anyone from my BX, I fill the first empty space
0197   if (index_to_occupy != -1)
0198     return index_to_occupy;
0199   // If I'm a 3h and there were no empty spaces, I don't replace any tp
0200   if (mp.quality == LOWQ)
0201     return -1;
0202   // If I'm a 4h, I replace the first 3h or the 4h with the biggest chi2.
0203   // Let's try to find both
0204   int biggest_chi2 = 0;
0205   int clowq_index = -1;
0206   for (size_t i = 0; i < tps_per_bx[bx].size(); i++) {
0207     if (tps_per_bx[bx][i].mp.quality == LOWQ)
0208       return i;
0209     if (tps_per_bx[bx][i].mp.quality == CLOWQ && clowq_index == -1) {
0210       clowq_index = i;
0211       continue;
0212     }
0213     auto chi2 = get_chi2(tps_per_bx[bx][i].mp);
0214     if (chi2 > biggest_chi2) {
0215       index_to_kill = i;
0216       biggest_chi2 = chi2;
0217     }
0218   }
0219   // If I found a confirmed 3h, I replace that one
0220   if (clowq_index != -1)
0221     return clowq_index;
0222   // If all stored tps are 4h and their chi2 is smaller than mine, I don't replace any
0223   if (biggest_chi2 < get_chi2(mp))
0224     return -1;
0225   // If at least one chi2 is bigger than mine, I replace the corresponding tp
0226   return index_to_kill;
0227 }
0228 
0229 int MPSLFilter::share_hit(cmsdt::metaPrimitive mp, cmsdt::metaPrimitive mp2) {
0230   // This function returns the layer % 4 (1 to 4) of the hit that is shared between TPs
0231   // If they don't share any hits or the last hit of the latest one differs in more than
0232   // SLFILT_MAX_SEG1T0_TO_SEG2ARRIVAL w.r.t. the t0 of the other, returns 0
0233 
0234   // checking that they are from the same SL
0235   if (mp.rawId != mp2.rawId)
0236     return 0;
0237 
0238   bool isSL1 = ((int)(mp2.wi1 != -1) + (int)(mp2.wi2 != -1) + (int)(mp2.wi3 != -1) + (int)(mp2.wi4 != -1)) >= 3;
0239 
0240   int tdc_mp[NUM_LAYERS_2SL] = {mp.tdc1, mp.tdc2, mp.tdc3, mp.tdc4, mp.tdc5, mp.tdc6, mp.tdc7, mp.tdc8};
0241   int tdc_mp2[NUM_LAYERS_2SL] = {mp2.tdc1, mp2.tdc2, mp2.tdc3, mp2.tdc4, mp2.tdc5, mp2.tdc6, mp2.tdc7, mp2.tdc8};
0242   int max_tdc_mp = -999, max_tdc_mp2 = -999;
0243 
0244   for (size_t i = 0; i < NUM_LAYERS_2SL; i++) {
0245     if (tdc_mp[i] > max_tdc_mp)
0246       max_tdc_mp = tdc_mp[i];
0247     if (tdc_mp2[i] > max_tdc_mp2)
0248       max_tdc_mp2 = tdc_mp2[i];
0249   }
0250 
0251   if (mp.t0 / LHC_CLK_FREQ + SLFILT_MAX_SEG1T0_TO_SEG2ARRIVAL < max_tdc_mp2 / LHC_CLK_FREQ ||
0252       mp2.t0 / LHC_CLK_FREQ + SLFILT_MAX_SEG1T0_TO_SEG2ARRIVAL < max_tdc_mp / LHC_CLK_FREQ)
0253     return 0;
0254 
0255   if ((isSL1 && (mp.wi1 == mp2.wi1 and mp.tdc1 == mp2.tdc1 and mp.wi1 != -1 and mp.tdc1 != -1)) ||
0256       (!isSL1 && (mp.wi5 == mp2.wi5 and mp.tdc5 == mp2.tdc5 and mp.wi5 != -1 and mp.tdc5 != -1)))
0257     return 1;
0258   if ((isSL1 && (mp.wi2 == mp2.wi2 and mp.tdc2 == mp2.tdc2 and mp.wi2 != -1 and mp.tdc2 != -1)) ||
0259       (!isSL1 && (mp.wi6 == mp2.wi6 and mp.tdc6 == mp2.tdc6 and mp.wi6 != -1 and mp.tdc6 != -1)))
0260     return 2;
0261   if ((isSL1 && (mp.wi3 == mp2.wi3 and mp.tdc3 == mp2.tdc3 and mp.wi3 != -1 and mp.tdc3 != -1)) ||
0262       (!isSL1 && (mp.wi7 == mp2.wi7 and mp.tdc7 == mp2.tdc7 and mp.wi7 != -1 and mp.tdc7 != -1)))
0263     return 3;
0264   if ((isSL1 && (mp.wi4 == mp2.wi4 and mp.tdc4 == mp2.tdc4 and mp.wi4 != -1 and mp.tdc4 != -1)) ||
0265       (!isSL1 && (mp.wi8 == mp2.wi8 and mp.tdc8 == mp2.tdc8 and mp.wi8 != -1 and mp.tdc8 != -1)))
0266     return 4;
0267   return 0;
0268 }
0269 
0270 void MPSLFilter::printmP(metaPrimitive mP) {
0271   DTSuperLayerId slId(mP.rawId);
0272   LogDebug("MPSLFilter") << slId << "\t"
0273                          << " " << setw(2) << left << mP.wi1 << " " << setw(2) << left << mP.wi2 << " " << setw(2)
0274                          << left << mP.wi3 << " " << setw(2) << left << mP.wi4 << " " << setw(5) << left << mP.tdc1
0275                          << " " << setw(5) << left << mP.tdc2 << " " << setw(5) << left << mP.tdc3 << " " << setw(5)
0276                          << left << mP.tdc4 << " " << setw(10) << right << mP.x << " " << setw(9) << left << mP.tanPhi
0277                          << " " << setw(5) << left << mP.t0 << " " << setw(13) << left << mP.chi2;
0278 }