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