CMS 3D CMS Logo

InitialGrouping.cc
Go to the documentation of this file.
1 #include <memory>
2 
4 
6 
7 using namespace edm;
8 using namespace std;
9 using namespace cmsdt;
10 using namespace dtamgrouping;
11 // ============================================================================
12 // Constructors and destructor
13 // ============================================================================
15  : MotherGrouping(pset, iC), debug_(pset.getUntrackedParameter<bool>("debug")), currentBaseChannel_(-1) {
16  // Obtention of parameters
17  if (debug_)
18  LogDebug("InitialGrouping") << "InitialGrouping: constructor";
19 
20  // Initialisation of channelIn array
21  chInDummy_.push_back(DTPrimitive());
22  for (int lay = 0; lay < NUM_LAYERS; lay++) {
23  for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
24  channelIn_[lay][ch] = {chInDummy_};
25  channelIn_[lay][ch].clear();
26  }
27  }
28 }
29 
31  if (debug_)
32  LogDebug("InitialGrouping") << "InitialGrouping: destructor";
33 }
34 
35 // ============================================================================
36 // Main methods (initialise, run, finish)
37 // ============================================================================
38 void InitialGrouping::initialise(const edm::EventSetup &iEventSetup) {
39  if (debug_)
40  LogDebug("InitialGrouping") << "InitialGrouping::initialiase";
41 }
42 
44  const EventSetup &iEventSetup,
45  const DTDigiCollection &digis,
46  MuonPathPtrs &mpaths) {
47  // This function returns the analyzable mpath collection back to the the main function
48  // so it can be fitted. This is in fact doing the so-called grouping.
49 
50  for (int supLayer = 0; supLayer < NUM_SUPERLAYERS; supLayer++) { // for each SL:
51  if (debug_)
52  LogDebug("InitialGrouping") << "InitialGrouping::run Reading SL" << supLayer;
53  setInChannels(&digis, supLayer);
54 
55  for (int baseCh = 0; baseCh < TOTAL_BTI; baseCh++) {
56  currentBaseChannel_ = baseCh;
57  selectInChannels(currentBaseChannel_); //map a number of wires for a given base channel
59  continue;
60 
61  if (debug_)
62  LogDebug("InitialGrouping") << "InitialGrouping::run --> now check pathId";
63  for (int pathId = 0; pathId < 8; pathId++) {
65  if (debug_)
66  LogDebug("InitialGrouping") << "[InitialGrouping::run] mixChannels calling";
67  mixChannels(supLayer, pathId, mpaths);
68  if (debug_)
69  LogDebug("InitialGrouping") << "[InitialGrouping::run] mixChannels end";
70  }
71  }
72  }
73  if (debug_)
74  LogDebug("InitialGrouping") << "[InitialGrouping::run] end";
75 }
76 
77 void InitialGrouping::finish() { return; };
78 
79 // ============================================================================
80 // Other methods
81 // ============================================================================
83  // before setting channels we need to clear
84  for (int lay = 0; lay < NUM_LAYERS; lay++) {
85  for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
86  channelIn_[lay][ch].clear();
87  }
88  }
89 
90  // now fill with those primitives that makes sense:
91  for (const auto &dtLayerId_It : *digis) {
92  const DTLayerId dtLId = dtLayerId_It.first;
93  if (dtLId.superlayer() != sl + 1)
94  continue; //skip digis not in SL...
95 
96  for (DTDigiCollection::const_iterator digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second;
97  ++digiIt) {
98  int layer = dtLId.layer() - 1;
99  int wire = (*digiIt).wire() - 1;
100  int digiTIME = (*digiIt).time();
101  int digiTIMEPhase2 = digiTIME;
102 
103  if (debug_)
104  LogDebug("InitialGrouping") << "[InitialGrouping::setInChannels] SL" << sl << " L" << layer << " : " << wire
105  << " " << digiTIMEPhase2;
106  auto dtpAux = DTPrimitive();
107  dtpAux.setTDCTimeStamp(digiTIMEPhase2);
108  dtpAux.setChannelId(wire);
109  dtpAux.setLayerId(layer); // L=0,1,2,3
110  dtpAux.setSuperLayerId(sl); // SL=0,1,2
111  dtpAux.setCameraId(dtLId.rawId());
112  channelIn_[layer][wire].push_back(dtpAux);
113  }
114  }
115 }
116 
117 void InitialGrouping::selectInChannels(int baseChannel) {
118  // Channels are labeled following next schema:
119  // Input Muxer Indexes
120  // ---------------------------------
121  // | 6 | 7 | 8 | 9 |
122  // ---------------------------------
123  // | 3 | 4 | 5 |
124  // -------------------------
125  // | 1 | 2 |
126  // -----------------
127  // | 0 |
128  // ---------
129 
130  // ****** LAYER 0 ******
131  muxInChannels_[0] = channelIn_[0][baseChannel];
132 
133  // ****** LAYER 1 ******
134  muxInChannels_[1] = channelIn_[1][baseChannel];
135 
136  if (baseChannel + 1 < NUM_CH_PER_LAYER)
137  muxInChannels_[2] = channelIn_[1][baseChannel + 1];
138  else
140 
141  // ****** LAYER 2 ******
142  if (baseChannel - 1 >= 0)
143  muxInChannels_[3] = channelIn_[2][baseChannel - 1];
144  else
146 
147  muxInChannels_[4] = channelIn_[2][baseChannel];
148 
149  if (baseChannel + 1 < NUM_CH_PER_LAYER)
150  muxInChannels_[5] = channelIn_[2][baseChannel + 1];
151  else
153 
154  // ****** LAYER 3 ******
155  if (baseChannel - 1 >= 0)
156  muxInChannels_[6] = channelIn_[3][baseChannel - 1];
157  else
159 
160  muxInChannels_[7] = channelIn_[3][baseChannel];
161 
162  if (baseChannel + 1 < NUM_CH_PER_LAYER)
163  muxInChannels_[8] = channelIn_[3][baseChannel + 1];
164  else
166 
167  if (baseChannel + 2 < NUM_CH_PER_LAYER)
168  muxInChannels_[9] = channelIn_[3][baseChannel + 2];
169  else
171 }
172 
174  // Empty layer indicators
175  bool lEmpty[4];
176 
177  lEmpty[0] = muxInChannels_[0].empty();
178 
179  lEmpty[1] = muxInChannels_[1].empty() && muxInChannels_[2].empty();
180 
181  lEmpty[2] = muxInChannels_[3].empty() && muxInChannels_[4].empty() && muxInChannels_[5].empty();
182 
183  lEmpty[3] =
184  muxInChannels_[6].empty() && muxInChannels_[7].empty() && muxInChannels_[8].empty() && muxInChannels_[9].empty();
185 
186  // If there are at least two empty layers, you cannot link it to a possible trace
187  if ((lEmpty[0] && lEmpty[1]) or (lEmpty[0] && lEmpty[2]) or (lEmpty[0] && lEmpty[3]) or (lEmpty[1] && lEmpty[2]) or
188  (lEmpty[1] && lEmpty[3]) or (lEmpty[2] && lEmpty[3])) {
189  return true;
190  } else {
191  return false;
192  }
193 }
194 
196  for (int i = 0; i < NUM_LAYERS; i++)
197  prevTDCTimeStamps_[i] = -1;
198 }
199 
201  bool answer = true;
202 
203  for (int i = 0; i < NUM_LAYERS; i++) {
204  if (prevTDCTimeStamps_[i] != dtPrims[i].tdcTimeStamp()) {
205  answer = false;
206  for (int j = 0; j < NUM_LAYERS; j++) {
207  prevTDCTimeStamps_[j] = dtPrims[j].tdcTimeStamp();
208  }
209  break;
210  }
211  }
212  return answer;
213 }
214 
215 void InitialGrouping::mixChannels(int supLayer, int pathId, MuonPathPtrs &outMuonPath) {
216  if (debug_)
217  LogDebug("InitialGrouping") << "[InitialGrouping::mixChannel] begin";
218  DTPrimitives data[4];
219 
220  // Real amount of values extracted from each channel.
221  int numPrimsPerLayer[4] = {0, 0, 0, 0};
222  unsigned int canal;
223  int channelEmptyCnt = 0;
224  for (int layer = 0; layer <= 3; layer++) {
225  canal = CHANNELS_PATH_ARRANGEMENTS[pathId][layer];
226  if (muxInChannels_[canal].empty())
227  channelEmptyCnt++;
228  }
229 
230  if (channelEmptyCnt >= 2)
231  return;
232  //
233 
234  // We extract the number of elements necesary from each channel as the combination requires
235  for (int layer = 0; layer < NUM_LAYERS; layer++) {
236  canal = CHANNELS_PATH_ARRANGEMENTS[pathId][layer];
237  unsigned int maxPrimsToBeRetrieved = muxInChannels_[canal].size();
238  /*
239  If the number of primitives is zero, in order to avoid that only one
240  empty channel avoids mixing data from the other three, we, at least,
241  consider one dummy element from this channel.
242  In other cases, where two or more channels has zero elements, the final
243  combination will be not analyzable (the condition for being analyzable is
244  that it has at least three good TDC time values, not dummy), so it will
245  be discarded and not sent to the analyzer.
246  */
247  if (maxPrimsToBeRetrieved == 0)
248  maxPrimsToBeRetrieved = 1;
249 
250  for (unsigned int items = 0; items < maxPrimsToBeRetrieved; items++) {
251  auto dtpAux = DTPrimitive();
252  if (!muxInChannels_[canal].empty())
253  dtpAux = DTPrimitive(&(muxInChannels_[canal].at(items)));
254 
255  /*
256  I won't allow a whole loop cycle. When a DTPrimitive has an invalid
257  time-stamp (TDC value = -1) it means that the buffer is empty or the
258  buffer has reached the last element within the configurable time window.
259  In this case the loop is broken, but only if there is, at least, one
260  DTPrim (even invalid) on the outgoing array. This is mandatory to cope
261  with the idea explained in the previous comment block
262  */
263  if (dtpAux.tdcTimeStamp() < 0 && items > 0)
264  break;
265 
266  // In this new schema, if the hit corresponds with the SL over which
267  // you are doing the mixings, it is sent to the intermediate mixing
268  // buffer. In the opposite case, a blank and invalid copy is sent to
269  // allow them mixing to be complete, as it was done in the one SL case.
270 
271  // This is a kind of quick solution in which there will be no few cases
272  // where you will have invalid mixings. Because of that, the verification
273  // that is done later, where the segment is analysed to check whether it
274  // can be analysed is essential.
275  if (dtpAux.superLayerId() == supLayer)
276  data[layer].push_back(dtpAux); // values are 0, 1, 2
277  else
278  data[layer].push_back(DTPrimitive());
279  numPrimsPerLayer[layer]++;
280  }
281  }
282 
283  if (debug_)
284  LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] filled data";
285 
286  // Here we do the different combinations and send them to the output FIFO.
287  DTPrimitives ptrPrimitive;
288  int chIdx[4];
289  for (chIdx[0] = 0; chIdx[0] < numPrimsPerLayer[0]; chIdx[0]++) {
290  for (chIdx[1] = 0; chIdx[1] < numPrimsPerLayer[1]; chIdx[1]++) {
291  for (chIdx[2] = 0; chIdx[2] < numPrimsPerLayer[2]; chIdx[2]++) {
292  for (chIdx[3] = 0; chIdx[3] < numPrimsPerLayer[3]; chIdx[3]++) {
293  // We build a copy of the object so that we can manipulate each one
294  // in each thread of the process independently, allowing us also to
295  // delete them whenever it is necessary, without relying upon a
296  // unique reference all over the code.
297 
298  for (int i = 0; i < NUM_LAYERS; i++) {
299  ptrPrimitive.push_back((data[i])[chIdx[i]]);
300  if (debug_)
301  LogDebug("InitialGrouping")
302  << "[InitialGrouping::mixChannels] reading " << ptrPrimitive[i].tdcTimeStamp();
303  }
304 
305  auto ptrMuonPath = std::make_shared<MuonPath>(ptrPrimitive);
306  ptrMuonPath->setCellHorizontalLayout(CELL_HORIZONTAL_LAYOUTS[pathId]);
307 
308  /*
309  This new version of this code is redundant with PathAnalyzer code,
310  where every MuonPath not analyzable is discarded.
311  I insert this discarding mechanism here, as well, to avoid inserting
312  not-analyzable MuonPath into the candidate FIFO.
313  Equivalent code must be removed in the future from PathAnalyzer, but
314  it the mean time, at least during the testing state, I'll preserve
315  both.
316  Code in the PathAnalyzer should be doing nothing now.
317  */
318  if (debug_)
319  LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] muonPath is analyzable? " << ptrMuonPath;
320  if (ptrMuonPath->isAnalyzable()) {
321  if (debug_)
322  LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] YES";
323  /*
324  This is a very simple filter because, during the tests, it has been
325  detected that many consecutive MuonPaths are duplicated mainly due
326  to buffers empty (or dummy) that give a TDC time-stamp = -1
327  With this filter, I'm removing those consecutive identical
328  combinations.
329 
330  If duplicated combinations are not consecutive, they won't be
331  detected here
332  */
333  if (!isEqualComb2Previous(ptrPrimitive)) {
334  if (debug_)
335  LogDebug("InitialGrouping") << "[InitialGrouping::mixChannels] isNOT equal to previous";
336  ptrMuonPath->setBaseChannelId(currentBaseChannel_);
337  outMuonPath.push_back(std::move(ptrMuonPath));
338  }
339  ptrPrimitive.clear();
340  }
341  }
342  }
343  }
344  }
345  for (int layer = 0; layer < NUM_LAYERS; layer++) {
346  data[layer].clear();
347  }
348 }
void selectInChannels(int baseCh)
const bool debug_
int prevTDCTimeStamps_[4]
constexpr int CELL_HORIZONTAL_LAYOUTS[8][4]
std::vector< MuonPathPtr > MuonPathPtrs
Definition: MuonPath.h:128
DTPrimitives channelIn_[cmsdt::NUM_LAYERS][cmsdt::NUM_CH_PER_LAYER]
bool isEqualComb2Previous(DTPrimitives &ptr)
DTPrimitives muxInChannels_[cmsdt::NUM_CELLS_PER_BLOCK]
InitialGrouping(const edm::ParameterSet &pset, edm::ConsumesCollector &iC)
constexpr std::array< uint8_t, layerIndexSize > layer
U second(std::pair< T, U > const &p)
int iEvent
Definition: GenABIO.cc:224
constexpr int NUM_SUPERLAYERS
Definition: constants.h:223
DTPrimitives chInDummy_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void resetPrvTDCTStamp(void)
constexpr int CHANNELS_PATH_ARRANGEMENTS[8][4]
constexpr int TOTAL_BTI
Definition: constants.h:217
void initialise(const edm::EventSetup &iEventSetup) override
int superlayer() const
Return the superlayer number (deprecated method name)
constexpr int NUM_CH_PER_LAYER
Definition: constants.h:218
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
bool notEnoughDataInChannels(void)
void run(edm::Event &iEvent, const edm::EventSetup &iEventSetup, const DTDigiCollection &digis, MuonPathPtrs &outMpath) override
std::vector< DigiType >::const_iterator const_iterator
void finish() override
int layer() const
Return the layer number.
Definition: DTLayerId.h:42
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
HLT enums.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
std::vector< DTPrimitive > DTPrimitives
Definition: DTprimitive.h:53
~InitialGrouping() override
def move(src, dest)
Definition: eostools.py:511
void setInChannels(const DTDigiCollection *digi, int sl)
#define LogDebug(id)
void mixChannels(int sl, int pathId, MuonPathPtrs &outMpath)