Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include <memory>
0002 
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 
0005 #include "L1Trigger/DTTriggerPhase2/interface/InitialGrouping.h"
0006 
0007 using namespace edm;
0008 using namespace std;
0009 using namespace cmsdt;
0010 using namespace dtamgrouping;
0011 // ============================================================================
0012 // Constructors and destructor
0013 // ============================================================================
0014 InitialGrouping::InitialGrouping(const ParameterSet &pset, edm::ConsumesCollector &iC)
0015     : MotherGrouping(pset, iC), debug_(pset.getUntrackedParameter<bool>("debug")), currentBaseChannel_(-1) {
0016   // Obtention of parameters
0017   if (debug_)
0018     LogDebug("InitialGrouping") << "InitialGrouping: constructor";
0019 
0020   // Initialisation of channelIn array
0021   chInDummy_.push_back(DTPrimitive());
0022   for (int lay = 0; lay < NUM_LAYERS; lay++) {
0023     for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
0024       channelIn_[lay][ch] = {chInDummy_};
0025       channelIn_[lay][ch].clear();
0026     }
0027   }
0028 }
0029 
0030 InitialGrouping::~InitialGrouping() {
0031   if (debug_)
0032     LogDebug("InitialGrouping") << "InitialGrouping: destructor";
0033 }
0034 
0035 // ============================================================================
0036 // Main methods (initialise, run, finish)
0037 // ============================================================================
0038 void InitialGrouping::initialise(const edm::EventSetup &iEventSetup) {
0039   if (debug_)
0040     LogDebug("InitialGrouping") << "InitialGrouping::initialiase";
0041 }
0042 
0043 void InitialGrouping::run(Event &iEvent,
0044                           const EventSetup &iEventSetup,
0045                           const DTDigiCollection &digis,
0046                           MuonPathPtrs &mpaths) {
0047   //   This function returns the analyzable mpath collection back to the the main function
0048   //   so it can be fitted. This is in fact doing the so-called grouping.
0049 
0050   for (int supLayer = 0; supLayer < NUM_SUPERLAYERS; supLayer++) {  // for each SL:
0051     if (debug_)
0052       LogDebug("InitialGrouping") << "InitialGrouping::run Reading SL" << supLayer;
0053     setInChannels(&digis, supLayer);
0054 
0055     for (int baseCh = 0; baseCh < TOTAL_BTI; baseCh++) {
0056       currentBaseChannel_ = baseCh;
0057       selectInChannels(currentBaseChannel_);  //map a number of wires for a given base channel
0058       if (notEnoughDataInChannels())
0059         continue;
0060 
0061       if (debug_)
0062         LogDebug("InitialGrouping") << "InitialGrouping::run --> now check pathId";
0063       for (int pathId = 0; pathId < 8; pathId++) {
0064         resetPrvTDCTStamp();
0065         if (debug_)
0066           LogDebug("InitialGrouping") << "[InitialGrouping::run] mixChannels calling";
0067         mixChannels(supLayer, pathId, mpaths);
0068         if (debug_)
0069           LogDebug("InitialGrouping") << "[InitialGrouping::run] mixChannels end";
0070       }
0071     }
0072   }
0073   if (debug_)
0074     LogDebug("InitialGrouping") << "[InitialGrouping::run] end";
0075 }
0076 
0077 void InitialGrouping::finish() { return; };
0078 
0079 // ============================================================================
0080 // Other methods
0081 // ============================================================================
0082 void InitialGrouping::setInChannels(const DTDigiCollection *digis, int sl) {
0083   //   before setting channels we need to clear
0084   for (int lay = 0; lay < NUM_LAYERS; lay++) {
0085     for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
0086       channelIn_[lay][ch].clear();
0087     }
0088   }
0089 
0090   // now fill with those primitives that makes sense:
0091   for (const auto &dtLayerId_It : *digis) {
0092     const DTLayerId dtLId = dtLayerId_It.first;
0093     if (dtLId.superlayer() != sl + 1)
0094       continue;  //skip digis not in SL...
0095 
0096     for (DTDigiCollection::const_iterator digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second;
0097          ++digiIt) {
0098       int layer = dtLId.layer() - 1;
0099       int wire = (*digiIt).wire() - 1;
0100       int digiTIME = (*digiIt).time();
0101       int digiTIMEPhase2 = digiTIME;
0102 
0103       if (debug_)
0104         LogDebug("InitialGrouping") << "[InitialGrouping::setInChannels] SL" << sl << " L" << layer << " : " << wire
0105                                     << " " << digiTIMEPhase2;
0106       auto dtpAux = DTPrimitive();
0107       dtpAux.setTDCTimeStamp(digiTIMEPhase2);
0108       dtpAux.setChannelId(wire);
0109       dtpAux.setLayerId(layer);    //  L=0,1,2,3
0110       dtpAux.setSuperLayerId(sl);  // SL=0,1,2
0111       dtpAux.setCameraId(dtLId.rawId());
0112       channelIn_[layer][wire].push_back(dtpAux);
0113     }
0114   }
0115 }
0116 
0117 void InitialGrouping::selectInChannels(int baseChannel) {
0118   // Channels are labeled following next schema:
0119   // Input Muxer Indexes
0120   // ---------------------------------
0121   // |   6   |   7   |   8   |   9   |
0122   // ---------------------------------
0123   // |   3   |   4   |   5   |
0124   // -------------------------
0125   // |   1   |   2   |
0126   // -----------------
0127   // |   0   |
0128   // ---------
0129 
0130   // ****** LAYER 0 ******
0131   muxInChannels_[0] = channelIn_[0][baseChannel];
0132 
0133   // ****** LAYER 1 ******
0134   muxInChannels_[1] = channelIn_[1][baseChannel];
0135 
0136   if (baseChannel + 1 < NUM_CH_PER_LAYER)
0137     muxInChannels_[2] = channelIn_[1][baseChannel + 1];
0138   else
0139     muxInChannels_[2] = chInDummy_;
0140 
0141   // ****** LAYER 2 ******
0142   if (baseChannel - 1 >= 0)
0143     muxInChannels_[3] = channelIn_[2][baseChannel - 1];
0144   else
0145     muxInChannels_[3] = chInDummy_;
0146 
0147   muxInChannels_[4] = channelIn_[2][baseChannel];
0148 
0149   if (baseChannel + 1 < NUM_CH_PER_LAYER)
0150     muxInChannels_[5] = channelIn_[2][baseChannel + 1];
0151   else
0152     muxInChannels_[5] = chInDummy_;
0153 
0154   // ****** LAYER 3 ******
0155   if (baseChannel - 1 >= 0)
0156     muxInChannels_[6] = channelIn_[3][baseChannel - 1];
0157   else
0158     muxInChannels_[6] = chInDummy_;
0159 
0160   muxInChannels_[7] = channelIn_[3][baseChannel];
0161 
0162   if (baseChannel + 1 < NUM_CH_PER_LAYER)
0163     muxInChannels_[8] = channelIn_[3][baseChannel + 1];
0164   else
0165     muxInChannels_[8] = chInDummy_;
0166 
0167   if (baseChannel + 2 < NUM_CH_PER_LAYER)
0168     muxInChannels_[9] = channelIn_[3][baseChannel + 2];
0169   else
0170     muxInChannels_[9] = chInDummy_;
0171 }
0172 
0173 bool InitialGrouping::notEnoughDataInChannels(void) {
0174   // Empty layer indicators
0175   bool lEmpty[4];
0176 
0177   lEmpty[0] = muxInChannels_[0].empty();
0178 
0179   lEmpty[1] = muxInChannels_[1].empty() && muxInChannels_[2].empty();
0180 
0181   lEmpty[2] = muxInChannels_[3].empty() && muxInChannels_[4].empty() && muxInChannels_[5].empty();
0182 
0183   lEmpty[3] =
0184       muxInChannels_[6].empty() && muxInChannels_[7].empty() && muxInChannels_[8].empty() && muxInChannels_[9].empty();
0185 
0186   // If there are at least two empty layers, you cannot link it to a possible trace
0187   if ((lEmpty[0] && lEmpty[1]) or (lEmpty[0] && lEmpty[2]) or (lEmpty[0] && lEmpty[3]) or (lEmpty[1] && lEmpty[2]) or
0188       (lEmpty[1] && lEmpty[3]) or (lEmpty[2] && lEmpty[3])) {
0189     return true;
0190   } else {
0191     return false;
0192   }
0193 }
0194 
0195 void InitialGrouping::resetPrvTDCTStamp(void) {
0196   for (int i = 0; i < NUM_LAYERS; i++)
0197     prevTDCTimeStamps_[i] = -1;
0198 }
0199 
0200 bool InitialGrouping::isEqualComb2Previous(DTPrimitives &dtPrims) {
0201   bool answer = true;
0202 
0203   for (int i = 0; i < NUM_LAYERS; i++) {
0204     if (prevTDCTimeStamps_[i] != dtPrims[i].tdcTimeStamp()) {
0205       answer = false;
0206       for (int j = 0; j < NUM_LAYERS; j++) {
0207         prevTDCTimeStamps_[j] = dtPrims[j].tdcTimeStamp();
0208       }
0209       break;
0210     }
0211   }
0212   return answer;
0213 }
0214 
0215 void InitialGrouping::mixChannels(int supLayer, int pathId, MuonPathPtrs &outMuonPath) {
0216   if (debug_)
0217     LogDebug("InitialGrouping") << "[InitialGrouping::mixChannel] begin";
0218   DTPrimitives data[4];
0219 
0220   // Real amount of values extracted from each channel.
0221   int numPrimsPerLayer[4] = {0, 0, 0, 0};
0222   unsigned int canal;
0223   int channelEmptyCnt = 0;
0224   for (int layer = 0; layer <= 3; layer++) {
0225     canal = CHANNELS_PATH_ARRANGEMENTS[pathId][layer];
0226     if (muxInChannels_[canal].empty())
0227       channelEmptyCnt++;
0228   }
0229 
0230   if (channelEmptyCnt >= 2)
0231     return;
0232   //
0233 
0234   // We extract the number of elements necesary from each channel as the combination requires
0235   for (int layer = 0; layer < NUM_LAYERS; layer++) {
0236     canal = CHANNELS_PATH_ARRANGEMENTS[pathId][layer];
0237     unsigned int maxPrimsToBeRetrieved = muxInChannels_[canal].size();
0238     /*
0239     If the number of primitives is zero, in order to avoid that only one
0240     empty channel avoids mixing data from the other three, we, at least,
0241     consider one dummy element from this channel.
0242     In other cases, where two or more channels has zero elements, the final
0243     combination will be not analyzable (the condition for being analyzable is
0244     that it has at least three good TDC time values, not dummy), so it will
0245     be discarded and not sent to the analyzer.
0246   */
0247     if (maxPrimsToBeRetrieved == 0)
0248       maxPrimsToBeRetrieved = 1;
0249 
0250     for (unsigned int items = 0; items < maxPrimsToBeRetrieved; items++) {
0251       auto dtpAux = DTPrimitive();
0252       if (!muxInChannels_[canal].empty())
0253         dtpAux = DTPrimitive(&(muxInChannels_[canal].at(items)));
0254 
0255       /*
0256     I won't allow a whole loop cycle. When a DTPrimitive has an invalid
0257     time-stamp (TDC value = -1) it means that the buffer is empty or the
0258     buffer has reached the last element within the configurable time window.
0259     In this case the loop is broken, but only if there is, at least, one
0260     DTPrim (even invalid) on the outgoing array. This is mandatory to cope
0261         with the idea explained in the previous comment block
0262       */
0263       if (dtpAux.tdcTimeStamp() < 0 && items > 0)
0264         break;
0265 
0266       // In this new schema, if the hit corresponds with the SL over which
0267       // you are doing the mixings, it is sent to the intermediate mixing
0268       // buffer. In the opposite case, a blank and invalid copy is sent to
0269       // allow them mixing to be complete, as it was done in the one SL case.
0270 
0271       // This is a kind of quick solution in which there will be no few cases
0272       // where you will have invalid mixings. Because of that, the verification
0273       // that is done later, where the segment is analysed to check whether it
0274       // can be analysed is essential.
0275       if (dtpAux.superLayerId() == supLayer)
0276         data[layer].push_back(dtpAux);  // values are 0, 1, 2
0277       else
0278         data[layer].push_back(DTPrimitive());
0279       numPrimsPerLayer[layer]++;
0280     }
0281   }
0282 
0283   if (debug_)
0284     LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] filled data";
0285 
0286   // Here we do the different combinations and send them to the output FIFO.
0287   DTPrimitives ptrPrimitive;
0288   int chIdx[4];
0289   for (chIdx[0] = 0; chIdx[0] < numPrimsPerLayer[0]; chIdx[0]++) {
0290     for (chIdx[1] = 0; chIdx[1] < numPrimsPerLayer[1]; chIdx[1]++) {
0291       for (chIdx[2] = 0; chIdx[2] < numPrimsPerLayer[2]; chIdx[2]++) {
0292         for (chIdx[3] = 0; chIdx[3] < numPrimsPerLayer[3]; chIdx[3]++) {
0293           // We build a copy of the object so that we can manipulate each one
0294           // in each thread of the process independently, allowing us also to
0295           // delete them whenever it is necessary, without relying upon a
0296           // unique reference all over the code.
0297 
0298           for (int i = 0; i < NUM_LAYERS; i++) {
0299             ptrPrimitive.push_back((data[i])[chIdx[i]]);
0300             if (debug_)
0301               LogDebug("InitialGrouping")
0302                   << "[InitialGrouping::mixChannels] reading " << ptrPrimitive[i].tdcTimeStamp();
0303           }
0304 
0305           auto ptrMuonPath = std::make_shared<MuonPath>(ptrPrimitive);
0306           ptrMuonPath->setCellHorizontalLayout(CELL_HORIZONTAL_LAYOUTS[pathId]);
0307 
0308           /*
0309             This new version of this code is redundant with PathAnalyzer code,
0310             where every MuonPath not analyzable is discarded.
0311             I insert this discarding mechanism here, as well, to avoid inserting
0312             not-analyzable MuonPath into the candidate FIFO.
0313             Equivalent code must be removed in the future from PathAnalyzer, but
0314             it the mean time, at least during the testing state, I'll preserve
0315             both.
0316             Code in the PathAnalyzer should be doing nothing now.
0317           */
0318           if (debug_)
0319             LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] muonPath is analyzable? " << ptrMuonPath;
0320           if (ptrMuonPath->isAnalyzable()) {
0321             if (debug_)
0322               LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] YES";
0323             /*
0324             This is a very simple filter because, during the tests, it has been
0325             detected that many consecutive MuonPaths are duplicated mainly due
0326             to buffers empty (or dummy) that give a TDC time-stamp = -1
0327             With this filter, I'm removing those consecutive identical
0328             combinations.
0329             
0330             If duplicated combinations are not consecutive, they won't be
0331             detected here
0332         */
0333             if (!isEqualComb2Previous(ptrPrimitive)) {
0334               if (debug_)
0335                 LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] isNOT equal to previous";
0336               ptrMuonPath->setBaseChannelId(currentBaseChannel_);
0337               outMuonPath.push_back(std::move(ptrMuonPath));
0338             }
0339             ptrPrimitive.clear();
0340           }
0341         }
0342       }
0343     }
0344   }
0345   for (int layer = 0; layer < NUM_LAYERS; layer++) {
0346     data[layer].clear();
0347   }
0348 }