CMS 3D CMS Logo

HGCalTriggerGeometryHexImp2.cc
Go to the documentation of this file.
2 
6 
7 #include <vector>
8 #include <iostream>
9 #include <fstream>
10 #include <regex>
11 
12 
14 {
15  public:
17 
18  virtual void initialize(const es_info& ) override final;
19  virtual void reset() override final;
20 
21  virtual unsigned getTriggerCellFromCell( const unsigned ) const override final;
22  virtual unsigned getModuleFromCell( const unsigned ) const override final;
23  virtual unsigned getModuleFromTriggerCell( const unsigned ) const override final;
24 
25  virtual geom_set getCellsFromTriggerCell( const unsigned ) const override final;
26  virtual geom_set getCellsFromModule( const unsigned ) const override final;
27  virtual geom_set getTriggerCellsFromModule( const unsigned ) const override final;
28 
29  virtual geom_ordered_set getOrderedCellsFromModule( const unsigned ) const override final;
30  virtual geom_ordered_set getOrderedTriggerCellsFromModule( const unsigned ) const override final;
31 
32  virtual geom_set getNeighborsFromTriggerCell( const unsigned ) const override final;
33 
34  virtual GlobalPoint getTriggerCellPosition(const unsigned ) const override final;
35  virtual GlobalPoint getModulePosition(const unsigned ) const override final;
36 
37  virtual bool validTriggerCell( const unsigned ) const override final;
38 
39  private:
44 
45  es_info es_info_;
46 
47  // module related maps
48  std::unordered_map<short, short> wafer_to_module_ee_;
49  std::unordered_map<short, short> wafer_to_module_fh_;
50  std::unordered_multimap<short, short> module_to_wafers_ee_;
51  std::unordered_multimap<short, short> module_to_wafers_fh_;
52 
53  // trigger cell related maps
54  std::map<std::pair<short,short>, short> cells_to_trigger_cells_; // FIXME: something else than map<pair,short>?
55  std::multimap<std::pair<short,short>, short> trigger_cells_to_cells_;// FIXME: something else than map<pair,short>?
56  std::unordered_map<short, short> number_trigger_cells_in_wafers_; // the map key is the wafer type
57  std::unordered_map<short, short> number_cells_in_wafers_; // the map key is the wafer type
58  std::unordered_set<unsigned> invalid_triggercells_;
59 
60  // neighbor related maps
61  // trigger cell neighbors:
62  // - The key includes the trigger cell id and the wafer configuration.
63  // The wafer configuration is a 7 bits word encoding the type
64  // (small or large cells) of the wafer containing the trigger cell
65  // (central wafer) as well as the type of the 6 surrounding wafers
66  // - The value is a set of (wafer_idx, trigger_cell_id)
67  // wafer_idx is a number between 0 and 7. 0=central wafer, 1..7=surrounding
68  // wafers
69  std::unordered_map<int, std::set<std::pair<short,short>>> trigger_cell_neighbors_;
70  // wafer neighbors:
71  // List of the 6 surrounding neighbors around each wafer
72  std::unordered_map<short, std::vector<short>> wafer_neighbors_ee_;
73  std::unordered_map<short, std::vector<short>> wafer_neighbors_fh_;
74 
75  void fillMaps(const es_info&);
76  void fillNeighborMaps(const es_info&);
77  void fillInvalidTriggerCells(const es_info&);
78  unsigned packTriggerCell(unsigned, const std::vector<int>&) const;
79  // returns transverse wafer type: -1=coarse, 1=fine, 0=undefined
80  int detIdWaferType(unsigned subdet, short wafer) const;
81  bool validCellId(unsigned subdet, unsigned cell_id) const;
82  bool validTriggerCellFromCells( const unsigned ) const;
83 };
84 
85 
89  l1tCellsMapping_(conf.getParameter<edm::FileInPath>("L1TCellsMapping")),
90  l1tCellNeighborsMapping_(conf.getParameter<edm::FileInPath>("L1TCellNeighborsMapping")),
91  l1tWaferNeighborsMapping_(conf.getParameter<edm::FileInPath>("L1TWaferNeighborsMapping")),
92  l1tModulesMapping_(conf.getParameter<edm::FileInPath>("L1TModulesMapping"))
93 {
94 }
95 
96 void
99 {
100  wafer_to_module_ee_.clear();
101  wafer_to_module_fh_.clear();
102  module_to_wafers_ee_.clear();
103  module_to_wafers_fh_.clear();
104  cells_to_trigger_cells_.clear();
105  trigger_cells_to_cells_.clear();
107  number_cells_in_wafers_.clear();
108 }
109 
110 void
112 initialize(const es_info& esInfo)
113 {
114  es_info_ = esInfo;
115  fillMaps(esInfo);
116  fillNeighborMaps(esInfo);
117  fillInvalidTriggerCells(esInfo);
118 
119 }
120 
121 unsigned
123 getTriggerCellFromCell( const unsigned cell_id ) const
124 {
125  HGCalDetId cell_det_id(cell_id);
126  int wafer_type = cell_det_id.waferType();
127  unsigned cell = cell_det_id.cell();
128  // FIXME: better way to do this cell->TC mapping?
129  auto trigger_cell_itr = cells_to_trigger_cells_.find(std::make_pair(wafer_type,cell));
130  if(trigger_cell_itr==cells_to_trigger_cells_.end())
131  {
132  throw cms::Exception("BadGeometry")
133  << "HGCalTriggerGeometry: HGCal cell " << cell << " is not mapped to any trigger cell for the wafer type " << wafer_type
134  << ". The trigger cell mapping should be modified.\n";
135  }
136  unsigned trigger_cell = trigger_cell_itr->second;
137  return HGCalDetId((ForwardSubdetector)cell_det_id.subdetId(), cell_det_id.zside(), cell_det_id.layer(), cell_det_id.waferType(), cell_det_id.wafer(), trigger_cell).rawId();
138 }
139 
140 unsigned
142 getModuleFromCell( const unsigned cell_id ) const
143 {
144  HGCalDetId cell_det_id(cell_id);
145  unsigned wafer = cell_det_id.wafer();
146  unsigned subdet = cell_det_id.subdetId();
147  std::unordered_map<short, short>::const_iterator module_itr;
148  bool out_of_range_error = false;
149  switch(subdet)
150  {
152  module_itr = wafer_to_module_ee_.find(wafer);
153  if(module_itr==wafer_to_module_ee_.end()) out_of_range_error = true;
154  break;
156  module_itr = wafer_to_module_fh_.find(wafer);
157  if(module_itr==wafer_to_module_fh_.end()) out_of_range_error = true;
158  break;
159  default:
160  edm::LogError("HGCalTriggerGeometry") << "Unknown wafer->module mapping for subdet "<<subdet<<"\n";
161  return 0;
162  };
163  if(out_of_range_error)
164  {
165  throw cms::Exception("BadGeometry")
166  << "HGCalTriggerGeometry: Wafer " << wafer << " is not mapped to any trigger module for subdetector " << subdet
167  << ". The module mapping should be modified. See https://twiki.cern.ch/twiki/bin/viewauth/CMS/HGCALTriggerPrimitivesSimulation#Trigger_geometry for details.\n";
168  }
169  unsigned module = module_itr->second;
170  return HGCalDetId((ForwardSubdetector)cell_det_id.subdetId(), cell_det_id.zside(), cell_det_id.layer(), cell_det_id.waferType(), module, HGCalDetId::kHGCalCellMask).rawId();
171 }
172 
173 unsigned
175 getModuleFromTriggerCell( const unsigned trigger_cell_id ) const
176 {
177  HGCalDetId trigger_cell_det_id(trigger_cell_id);
178  unsigned wafer = trigger_cell_det_id.wafer();
179  unsigned subdet = trigger_cell_det_id.subdetId();
180  std::unordered_map<short, short>::const_iterator module_itr;
181  bool out_of_range_error = false;
182  switch(subdet)
183  {
185  module_itr = wafer_to_module_ee_.find(wafer);
186  if(module_itr==wafer_to_module_ee_.end()) out_of_range_error = true;
187  break;
189  module_itr = wafer_to_module_fh_.find(wafer);
190  if(module_itr==wafer_to_module_fh_.end()) out_of_range_error = true;
191  break;
192  default:
193  edm::LogError("HGCalTriggerGeometry") << "Unknown wafer->module mapping for subdet "<<subdet<<"\n";
194  return 0;
195  };
196  if(out_of_range_error)
197  {
198  throw cms::Exception("BadGeometry")
199  << "HGCalTriggerGeometry: Wafer " << wafer << " is not mapped to any trigger module for subdetector " << subdet
200  << ". The module mapping should be modified. See https://twiki.cern.ch/twiki/bin/viewauth/CMS/HGCALTriggerPrimitivesSimulation#Trigger_geometry for details.\n";
201  }
202  unsigned module = module_itr->second;
203  return HGCalDetId((ForwardSubdetector)trigger_cell_det_id.subdetId(), trigger_cell_det_id.zside(), trigger_cell_det_id.layer(), trigger_cell_det_id.waferType(), module, HGCalDetId::kHGCalCellMask).rawId();
204 }
205 
208 getCellsFromTriggerCell( const unsigned trigger_cell_id ) const
209 {
210  HGCalDetId trigger_cell_det_id(trigger_cell_id);
211  int wafer_type = trigger_cell_det_id.waferType();
212  unsigned trigger_cell = trigger_cell_det_id.cell();
213  // FIXME: better way to do this TC->cell mapping?
214  const auto& cell_range = trigger_cells_to_cells_.equal_range(std::make_pair(wafer_type,trigger_cell));
215  geom_set cell_det_ids;
216  for(auto tc_c_itr=cell_range.first; tc_c_itr!=cell_range.second; tc_c_itr++)
217  {
218  cell_det_ids.emplace(HGCalDetId((ForwardSubdetector)trigger_cell_det_id.subdetId(), trigger_cell_det_id.zside(), trigger_cell_det_id.layer(), trigger_cell_det_id.waferType(), trigger_cell_det_id.wafer(), tc_c_itr->second).rawId());
219  }
220  return cell_det_ids;
221 }
222 
225 getCellsFromModule( const unsigned module_id ) const
226 {
227 
228  HGCalDetId module_det_id(module_id);
229  unsigned module = module_det_id.wafer();
230  unsigned subdet = module_det_id.subdetId();
231  std::pair<std::unordered_multimap<short, short>::const_iterator,
232  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
233  switch(subdet)
234  {
236  wafer_itrs = module_to_wafers_ee_.equal_range(module);
237  break;
239  wafer_itrs = module_to_wafers_fh_.equal_range(module);
240  break;
241  default:
242  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
243  return geom_set();
244  };
245  geom_set cell_det_ids;
246  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
247  {
248  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
249  if(wafer_type==0) wafer_type = module_det_id.waferType();
250  // loop on the cells in each wafer and return valid ones
251  for(int cell=0; cell<number_cells_in_wafers_.at(wafer_type); cell++)
252  {
253  HGCalDetId cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, cell);
254  if(validCellId(subdet, cell_id)) cell_det_ids.emplace(cell_id.rawId());
255  }
256  }
257  return cell_det_ids;
258 }
259 
262 getOrderedCellsFromModule( const unsigned module_id ) const
263 {
264  HGCalDetId module_det_id(module_id);
265  unsigned module = module_det_id.wafer();
266  unsigned subdet = module_det_id.subdetId();
267  std::pair<std::unordered_multimap<short, short>::const_iterator,
268  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
269  switch(subdet)
270  {
272  wafer_itrs = module_to_wafers_ee_.equal_range(module);
273  break;
275  wafer_itrs = module_to_wafers_fh_.equal_range(module);
276  break;
277  default:
278  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
279  return geom_ordered_set();
280  };
281  geom_ordered_set cell_det_ids;
282  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
283  {
284  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
285  if(wafer_type==0) wafer_type = module_det_id.waferType();
286  // loop on the cells in each wafer
287  for(int cell=0; cell<number_cells_in_wafers_.at(wafer_type); cell++)
288  {
289  HGCalDetId cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, cell);
290  if(validCellId(subdet, cell_id)) cell_det_ids.emplace(cell_id.rawId());
291  }
292  }
293  return cell_det_ids;
294 }
295 
298 getTriggerCellsFromModule( const unsigned module_id ) const
299 {
300  HGCalDetId module_det_id(module_id);
301  unsigned module = module_det_id.wafer();
302  unsigned subdet = module_det_id.subdetId();
303  std::pair<std::unordered_multimap<short, short>::const_iterator,
304  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
305  switch(subdet)
306  {
308  wafer_itrs = module_to_wafers_ee_.equal_range(module);
309  break;
311  wafer_itrs = module_to_wafers_fh_.equal_range(module);
312  break;
313  default:
314  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
315  return geom_set();
316  };
317  geom_set trigger_cell_det_ids;
318  // loop on the wafers included in the module
319  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
320  {
321  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
322  if(wafer_type==0) wafer_type = module_det_id.waferType();
323  // loop on the trigger cells in each wafer
324  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
325  {
326  HGCalDetId trigger_cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, trigger_cell);
327  if(validTriggerCell(trigger_cell_id)) trigger_cell_det_ids.emplace(trigger_cell_id.rawId());
328  }
329  }
330  return trigger_cell_det_ids;
331 }
332 
335 getOrderedTriggerCellsFromModule( const unsigned module_id ) const
336 {
337  HGCalDetId module_det_id(module_id);
338  unsigned module = module_det_id.wafer();
339  unsigned subdet = module_det_id.subdetId();
340  std::pair<std::unordered_multimap<short, short>::const_iterator,
341  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
342  switch(subdet)
343  {
345  wafer_itrs = module_to_wafers_ee_.equal_range(module);
346  break;
348  wafer_itrs = module_to_wafers_fh_.equal_range(module);
349  break;
350  default:
351  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
352  return geom_ordered_set();
353  };
354  geom_ordered_set trigger_cell_det_ids;
355  // loop on the wafers included in the module
356  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
357  {
358  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
359  if(wafer_type==0) wafer_type = module_det_id.waferType();
360  // loop on the trigger cells in each wafer
361  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
362  {
363  HGCalDetId trigger_cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, trigger_cell);
364  if(validTriggerCell(trigger_cell_id)) trigger_cell_det_ids.emplace(trigger_cell_id.rawId());
365  }
366  }
367  return trigger_cell_det_ids;
368 }
369 
370 
371 
374 getNeighborsFromTriggerCell( const unsigned trigger_cell_id ) const
375 {
376  HGCalDetId trigger_cell_det_id(trigger_cell_id);
377  unsigned wafer = trigger_cell_det_id.wafer();
378  int wafer_type = trigger_cell_det_id.waferType();
379  unsigned subdet = trigger_cell_det_id.subdetId();
380  unsigned trigger_cell = trigger_cell_det_id.cell();
381  // Retrieve surrounding wafers (around the wafer containing
382  // the trigger cell)
383  std::unordered_map<short, std::vector<short>>::const_iterator surrounding_wafers_itr;
384  bool out_of_range_error = false;
385  switch(subdet)
386  {
388  surrounding_wafers_itr = wafer_neighbors_ee_.find(wafer);
389  if(surrounding_wafers_itr==wafer_neighbors_ee_.end()) out_of_range_error = true;
390  break;
392  surrounding_wafers_itr = wafer_neighbors_fh_.find(wafer);
393  if(surrounding_wafers_itr==wafer_neighbors_fh_.end()) out_of_range_error = true;
394  break;
395  default:
396  edm::LogError("HGCalTriggerGeometry") << "Unknown wafer neighbours for subdet "<<subdet<<"\n";
397  return geom_set();
398  }
399  if(out_of_range_error)
400  {
401  throw cms::Exception("BadGeometry")
402  << "HGCalTriggerGeometry: Neighbors are not defined for wafer " << wafer << " in subdetector " << subdet
403  << ". The wafer neighbor mapping should be modified. \n";
404  };
405  const std::vector<short>& surrounding_wafers = surrounding_wafers_itr->second;
406  // Find the types of the surrounding wafers
407  std::vector<int> types;
408  types.reserve(surrounding_wafers.size()+1); // includes the central wafer -> +1
409  types.emplace_back(wafer_type);
410  for(const auto w : surrounding_wafers)
411  {
412  // if no neighbor, use the same type as the central one
413  // to create the wafer configuration
414  int wt = wafer_type;
415  if(w!=-1) wt = detIdWaferType(subdet, w);
416  if(wt==0) return geom_set(); // invalid wafer type
417  types.emplace_back(wt);
418  }
419  // retrieve neighbors
420  unsigned trigger_cell_key = packTriggerCell(trigger_cell, types);
421  geom_set neighbor_detids;
422  auto neighbors_itr = trigger_cell_neighbors_.find(trigger_cell_key);
423  if(neighbors_itr==trigger_cell_neighbors_.end())
424  {
425  throw cms::Exception("BadGeometry")
426  << "HGCalTriggerGeometry: Neighbors are not defined for trigger cell " << trigger_cell << " with wafer configuration "
427  << std::bitset<7>(trigger_cell_key >> 8) << ". The trigger cell neighbor mapping should be modified. \n";
428  }
429  const auto& neighbors = neighbors_itr->second;
430  // create HGCalDetId of neighbors and check their validity
431  neighbor_detids.reserve(neighbors.size());
432  for(const auto& wafer_tc : neighbors)
433  {
434  if(wafer_tc.first-1>=(int)surrounding_wafers.size())
435  {
436  throw cms::Exception("BadGeometry")
437  << "HGCalTriggerGeometry: Undefined wafer neighbor number "<<wafer_tc.first
438  << " for wafer " << wafer << " and trigger cell " << trigger_cell
439  << ". The neighbor mapping files should be modified.";
440  }
441  int neighbor_wafer = (wafer_tc.first==0 ? wafer : surrounding_wafers.at(wafer_tc.first-1));
442  if(neighbor_wafer==-1) continue; // non-existing wafer
443  int type = types.at(wafer_tc.first);
444  HGCalDetId neighbor_det_id((ForwardSubdetector)trigger_cell_det_id.subdetId(), trigger_cell_det_id.zside(), trigger_cell_det_id.layer(), type, neighbor_wafer, wafer_tc.second);
445  if(validTriggerCell(neighbor_det_id.rawId()))
446  {
447  neighbor_detids.emplace(neighbor_det_id.rawId());
448  }
449  }
450  return neighbor_detids;
451 }
452 
453 
456 getTriggerCellPosition(const unsigned trigger_cell_det_id) const
457 {
458  // Position: barycenter of the trigger cell.
459  Basic3DVector<float> triggerCellVector(0.,0.,0.);
460  const auto cell_ids = getCellsFromTriggerCell(trigger_cell_det_id);
461  for(const auto& cell : cell_ids)
462  {
463  HGCalDetId cellDetId(cell);
464  triggerCellVector += (cellDetId.subdetId()==ForwardSubdetector::HGCEE ? es_info_.geom_ee->getPosition(cellDetId) : es_info_.geom_fh->getPosition(cellDetId)).basicVector();
465  }
466  return GlobalPoint( triggerCellVector/cell_ids.size() );
467 
468 }
469 
472 getModulePosition(const unsigned module_det_id) const
473 {
474  // Position: barycenter of the module.
475  Basic3DVector<float> moduleVector(0.,0.,0.);
476  const auto cell_ids = getCellsFromModule(module_det_id);
477  for(const auto& cell : cell_ids)
478  {
479  HGCalDetId cellDetId(cell);
480  moduleVector += (cellDetId.subdetId()==ForwardSubdetector::HGCEE ? es_info_.geom_ee->getPosition(cellDetId) : es_info_.geom_fh->getPosition(cellDetId)).basicVector();
481  }
482  return GlobalPoint( moduleVector/cell_ids.size() );
483 }
484 
485 
486 void
488 fillMaps(const es_info& esInfo)
489 {
490  //
491  // read module mapping file
492  std::ifstream l1tModulesMappingStream(l1tModulesMapping_.fullPath());
493  if(!l1tModulesMappingStream.is_open()) edm::LogError("HGCalTriggerGeometry") << "Cannot open L1TModulesMapping file\n";
494  short subdet = 0;
495  short wafer = 0;
496  short module = 0;
497  for(; l1tModulesMappingStream>>subdet>>wafer>>module; )
498  {
499  int wafer_type = detIdWaferType(subdet, wafer);
500  switch(subdet)
501  {
503  {
504  // fill module <-> wafers mappings
505  wafer_to_module_ee_.emplace(wafer,module);
506  module_to_wafers_ee_.emplace(module, wafer);
507  // fill number of cells for a given wafer type
508  number_cells_in_wafers_.emplace(wafer_type, esInfo.topo_ee->dddConstants().numberCellsHexagon(wafer));
509  break;
510  }
512  {
513  // fill module <-> wafers mappings
514  wafer_to_module_fh_.emplace(wafer,module);
515  module_to_wafers_fh_.emplace(module, wafer);
516  // fill number of cells for a given wafer type
517  number_cells_in_wafers_.emplace(wafer_type, esInfo.topo_fh->dddConstants().numberCellsHexagon(wafer));
518  break;
519  }
520  default:
521  edm::LogWarning("HGCalTriggerGeometry") << "Unsupported subdetector number ("<<subdet<<") in L1TModulesMapping file\n";
522  break;
523  }
524  }
525  if(!l1tModulesMappingStream.eof()) edm::LogWarning("HGCalTriggerGeometry") << "Error reading L1TModulesMapping '"<<wafer<<" "<<module<<"' \n";
526  l1tModulesMappingStream.close();
527  // read trigger cell mapping file
528  std::ifstream l1tCellsMappingStream(l1tCellsMapping_.fullPath());
529  if(!l1tCellsMappingStream.is_open()) edm::LogError("HGCalTriggerGeometry") << "Cannot open L1TCellsMapping file\n";
530  short waferType = 0;
531  short cell = 0;
532  short triggerCell = 0;
533  for(; l1tCellsMappingStream>>waferType>>cell>>triggerCell; )
534  {
535  // fill cell <-> trigger cell mappings
536  cells_to_trigger_cells_.emplace(std::make_pair((waferType?1:-1),cell), triggerCell);
537  trigger_cells_to_cells_.emplace(std::make_pair((waferType?1:-1),triggerCell), cell);
538  // fill number of cells for a given wafer type
539  auto itr_insert = number_trigger_cells_in_wafers_.emplace((waferType?1:-1), 0);
540  if(triggerCell+1 > itr_insert.first->second) itr_insert.first->second = triggerCell+1;
541  }
542  if(!l1tCellsMappingStream.eof()) edm::LogWarning("HGCalTriggerGeometry") << "Error reading L1TCellsMapping'"<<waferType<<" "<<cell<<" "<<triggerCell<<"' \n";
543  l1tCellsMappingStream.close();
544 }
545 
546 void
548 fillNeighborMaps(const es_info& esInfo)
549 {
550  // Fill trigger neighbor map
551  std::ifstream l1tCellNeighborsMappingStream(l1tCellNeighborsMapping_.fullPath());
552  if(!l1tCellNeighborsMappingStream.is_open()) edm::LogError("HGCalTriggerGeometry") << "Cannot open L1TCellNeighborsMapping file\n";
553  for(std::array<char,512> buffer; l1tCellNeighborsMappingStream.getline(&buffer[0], 512); )
554  {
555  std::string line(&buffer[0]);
556  // Extract keys consisting of the wafer configuration
557  // and of the trigger cell id
558  // Match patterns (X,Y)
559  // where X is a set of 7 bits
560  // and Y is a number with less than 4 digits
561  std::regex key_regex("\\(\\s*[01]{7}\\s*,\\s*\\d{1,3}\\s*\\)");
562  std::vector<std::string> key_tokens {
563  std::sregex_token_iterator(line.begin(), line.end(), key_regex), {}
564  };
565  if(key_tokens.size()!=1)
566  {
567  throw cms::Exception("BadGeometry")
568  << "Syntax error in the L1TCellNeighborsMapping:\n"
569  << " Cannot find the trigger cell key in line:\n"
570  << " '"<<&buffer[0]<<"'\n";
571  }
572  std::regex digits_regex("([01]{7})|(\\d{1,3})");
573  std::vector<std::string> type_tc {
574  std::sregex_token_iterator(key_tokens[0].begin(), key_tokens[0].end(), digits_regex), {}
575  };
576  // get cell id and wafer configuration
577  int trigger_cell = std::stoi(type_tc[1]);
578  std::vector<int> wafer_types;
579  wafer_types.reserve(type_tc[0].size());
580  // Convert waferType coarse=0, fine=1 to coarse=-1, fine=1
581  for(const char c : type_tc[0]) wafer_types.emplace_back( (std::stoi(std::string(&c))?1:-1) );
582  unsigned map_key = packTriggerCell(trigger_cell, wafer_types);
583  // Extract neighbors
584  // Match patterns (X,Y)
585  // where X is a number with less than 4 digits
586  // and Y is one single digit (the neighbor wafer, between 0 and 6)
587  std::regex neighbors_regex("\\(\\s*\\d{1,3}\\s*,\\s*\\d\\s*\\)");
588  std::vector<std::string> neighbors_tokens {
589  std::sregex_token_iterator(line.begin(), line.end(), neighbors_regex), {}
590  };
591  if(neighbors_tokens.size()==0)
592  {
593  throw cms::Exception("BadGeometry")
594  << "Syntax error in the L1TCellNeighborsMapping:\n"
595  << " Cannot find any neighbor in line:\n"
596  << " '"<<&buffer[0]<<"'\n";
597  }
598  auto itr_insert = trigger_cell_neighbors_.emplace(map_key, std::set<std::pair<short,short>>());
599  for(const auto& neighbor : neighbors_tokens)
600  {
601  std::vector<std::string> pair_neighbor {
602  std::sregex_token_iterator(neighbor.begin(), neighbor.end(), digits_regex), {}
603  };
604  short neighbor_wafer(std::stoi(pair_neighbor[1]));
605  short neighbor_cell(std::stoi(pair_neighbor[0]));
606  itr_insert.first->second.emplace(neighbor_wafer, neighbor_cell);
607  }
608  }
609  if(!l1tCellNeighborsMappingStream.eof()) edm::LogWarning("HGCalTriggerGeometry") << "Error reading L1TCellNeighborsMapping'\n";
610  l1tCellNeighborsMappingStream.close();
611 
612  // Fill wafer neighbor map
613  std::ifstream l1tWaferNeighborsMappingStream(l1tWaferNeighborsMapping_.fullPath());
614  if(!l1tWaferNeighborsMappingStream.is_open()) edm::LogError("HGCalTriggerGeometry") << "Cannot open L1TWaferNeighborsMapping file\n";
615  for(std::array<char,512> buffer; l1tWaferNeighborsMappingStream.getline(&buffer[0], 512); )
616  {
617  std::string line(&buffer[0]);
618  // split line using spaces as delimiter
619  std::regex delimiter("\\s+");
620  std::vector<std::string> tokens {
621  std::sregex_token_iterator(line.begin(), line.end(), delimiter, -1), {}
622  };
623  if(tokens.size()!=8)
624  {
625  throw cms::Exception("BadGeometry")
626  << "Syntax error in the L1TWaferNeighborsMapping in line:\n"
627  << " '"<<&buffer[0]<<"'\n"
628  << " A line should be composed of 8 integers separated by spaces:\n"
629  << " subdet waferid neighbor1 neighbor2 neighbor3 neighbor4 neighbor5 neighbor6\n";
630  }
631  short subdet(std::stoi(tokens[0]));
632  short wafer(std::stoi(tokens[1]));
633 
634  std::unordered_map<short, std::vector<short>>* wafer_neighbors;
635  switch(subdet)
636  {
638  wafer_neighbors = &wafer_neighbors_ee_;
639  break;
641  wafer_neighbors = &wafer_neighbors_fh_;
642  break;
643  default:
644  throw cms::Exception("BadGeometry")
645  << "Unknown subdet " << subdet << " in L1TWaferNeighborsMapping:\n"
646  << " '"<<&buffer[0]<<"'\n";
647  };
648  auto wafer_itr = wafer_neighbors->emplace(wafer, std::vector<short>());
649  for(auto neighbor_itr=tokens.cbegin()+2; neighbor_itr!=tokens.cend(); ++neighbor_itr)
650  {
651  wafer_itr.first->second.emplace_back(std::stoi(*neighbor_itr));
652  }
653  }
654 }
655 
656 
657 void
659 fillInvalidTriggerCells(const es_info& esInfo)
660 {
661  unsigned n_layers_ee = es_info_.topo_ee->dddConstants().layers(true);
662  for(unsigned layer=1; layer<=n_layers_ee; layer++)
663  {
664  for(const auto& wafer_module : wafer_to_module_ee_)
665  {
666  unsigned wafer = wafer_module.first;
667  int wafer_type = detIdWaferType(ForwardSubdetector::HGCEE, wafer);
668  // loop on the trigger cells in each wafer
669  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
670  {
671  HGCalDetId trigger_cell_id_neg(ForwardSubdetector::HGCEE, -1, layer, wafer_type, wafer, trigger_cell);
672  HGCalDetId trigger_cell_id_pos(ForwardSubdetector::HGCEE, 1, layer, wafer_type, wafer, trigger_cell);
673  if(!validTriggerCellFromCells(trigger_cell_id_neg)) invalid_triggercells_.emplace(trigger_cell_id_neg.rawId());
674  if(!validTriggerCellFromCells(trigger_cell_id_pos)) invalid_triggercells_.emplace(trigger_cell_id_pos.rawId());
675  }
676  }
677  }
678  unsigned n_layers_fh = es_info_.topo_fh->dddConstants().layers(true);
679  for(unsigned layer=1; layer<=n_layers_fh; layer++)
680  {
681  for(const auto& wafer_module : wafer_to_module_fh_)
682  {
683  unsigned wafer = wafer_module.first;
684  int wafer_type = detIdWaferType(ForwardSubdetector::HGCHEF, wafer);
685  // loop on the trigger cells in each wafer
686  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
687  {
688  HGCalDetId trigger_cell_id_neg(ForwardSubdetector::HGCHEF, -1, layer, wafer_type, wafer, trigger_cell);
689  HGCalDetId trigger_cell_id_pos(ForwardSubdetector::HGCHEF, 1, layer, wafer_type, wafer, trigger_cell);
690  if(!validTriggerCellFromCells(trigger_cell_id_neg)) invalid_triggercells_.emplace(trigger_cell_id_neg.rawId());
691  if(!validTriggerCellFromCells(trigger_cell_id_pos)) invalid_triggercells_.emplace(trigger_cell_id_pos.rawId());
692  }
693  }
694  }
695 }
696 
697 unsigned
699 packTriggerCell(unsigned trigger_cell, const std::vector<int>& wafer_types) const
700 {
701  unsigned packed_value = trigger_cell;
702  for(unsigned i=0; i<wafer_types.size(); i++)
703  {
704  // trigger cell id on 8 bits
705  // wafer configuration bits: 0=coarse, 1=fine
706  if(wafer_types.at(i)==1) packed_value += (0x1<<(8+i));
707  }
708  return packed_value;
709 }
710 
711 
712 int
714 detIdWaferType(unsigned subdet, short wafer) const
715 {
716  int wafer_type = 0;
717  switch(subdet)
718  {
719  // HGCalDDDConstants::waferTypeT() returns 2=coarse, 1=fine
720  // HGCalDetId::waferType() returns -1=coarse, 1=fine
721  // Convert to HGCalDetId waferType
723  wafer_type = (es_info_.topo_ee->dddConstants().waferTypeT(wafer)==2?-1:1);
724  break;
726  wafer_type = (es_info_.topo_fh->dddConstants().waferTypeT(wafer)==2?-1:1);
727  break;
728  default:
729  break;
730  };
731  return wafer_type;
732 }
733 
734 bool
736 validTriggerCell(const unsigned trigger_cell_id) const
737 {
738  return invalid_triggercells_.find(trigger_cell_id)==invalid_triggercells_.end();
739 }
740 
741 bool
743 validTriggerCellFromCells(const unsigned trigger_cell_id) const
744 {
745  // Check the validity of a trigger cell with the
746  // validity of the cells. One valid cell in the
747  // trigger cell is enough to make the trigger cell
748  // valid.
749  HGCalDetId trigger_cell_det_id(trigger_cell_id);
750  unsigned subdet = trigger_cell_det_id.subdetId();
751  const geom_set cells = getCellsFromTriggerCell(trigger_cell_id);
752  bool is_valid = false;
753  for(const auto cell_id : cells)
754  {
755  is_valid |= validCellId(subdet, cell_id);
756  if(is_valid) break;
757  }
758  return is_valid;
759 }
760 
761 bool
763 validCellId(unsigned subdet, unsigned cell_id) const
764 {
765  bool is_valid = false;
766  switch(subdet)
767  {
769  is_valid = es_info_.topo_ee->valid(cell_id);
770  break;
772  is_valid = es_info_.topo_fh->valid(cell_id);
773  break;
774  default:
775  is_valid = false;
776  break;
777  }
778  return is_valid;
779 }
780 
781 
782 
783 
786  "HGCalTriggerGeometryHexImp2");
size
Write out results.
virtual geom_set getCellsFromTriggerCell(const unsigned) const override final
type
Definition: HCALResponse.h:21
std::unordered_map< short, short > number_cells_in_wafers_
const double w
Definition: UKUtility.cc:23
std::unordered_map< short, short > number_trigger_cells_in_wafers_
bool is_valid(const Digi &d)
Definition: GenericDigi.h:44
edm::ESHandle< HGCalTopology > topo_ee
virtual GlobalPoint getModulePosition(const unsigned) const override final
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
unsigned packTriggerCell(unsigned, const std::vector< int > &) const
virtual geom_ordered_set getOrderedCellsFromModule(const unsigned) const override final
GlobalPoint getPosition(const DetId &id) const
std::unordered_multimap< short, short > module_to_wafers_fh_
bool neighbor(int endcap, int sector, int SectIndex, int id, int sub, int station)
std::unordered_set< unsigned > invalid_triggercells_
ForwardSubdetector
virtual void initialize(const es_info &) override final
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
bool validCellId(unsigned subdet, unsigned cell_id) const
static const int kHGCalCellMask
Definition: HGCalDetId.h:13
unsigned int layers(bool reco) const
int zside() const
get the z-side of the cell (1/-1)
Definition: HGCalDetId.h:51
std::unordered_map< short, std::vector< short > > wafer_neighbors_fh_
edm::ESHandle< HGCalGeometry > geom_ee
std::unordered_map< short, std::vector< short > > wafer_neighbors_ee_
virtual bool valid(const DetId &id) const
Is this a valid cell id.
edm::ESHandle< HGCalGeometry > geom_fh
virtual void reset() override final
std::unordered_multimap< short, short > module_to_wafers_ee_
virtual GlobalPoint getTriggerCellPosition(const unsigned) const override final
#define end
Definition: vmac.h:37
int wafer() const
get the wafer #
Definition: HGCalDetId.h:42
virtual unsigned getTriggerCellFromCell(const unsigned) const override final
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
virtual geom_set getNeighborsFromTriggerCell(const unsigned) const override final
edm::ESHandle< HGCalTopology > topo_fh
std::unordered_map< short, short > wafer_to_module_ee_
int cell() const
get the absolute value of the cell #&#39;s in x and y
Definition: HGCalDetId.h:39
const HGCalDDDConstants & dddConstants() const
virtual unsigned getModuleFromCell(const unsigned) const override final
std::unordered_map< short, short > wafer_to_module_fh_
std::set< unsigned > geom_ordered_set
#define begin
Definition: vmac.h:30
HLT enums.
virtual geom_ordered_set getOrderedTriggerCellsFromModule(const unsigned) const override final
std::unordered_set< unsigned > geom_set
virtual geom_set getTriggerCellsFromModule(const unsigned) const override final
int detIdWaferType(unsigned subdet, short wafer) const
int waferType() const
get the wafer type
Definition: HGCalDetId.h:45
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::map< std::pair< short, short >, short > cells_to_trigger_cells_
virtual bool validTriggerCell(const unsigned) const override final
std::unordered_map< int, std::set< std::pair< short, short > > > trigger_cell_neighbors_
virtual unsigned getModuleFromTriggerCell(const unsigned) const override final
std::string fullPath() const
Definition: FileInPath.cc:184
bool validTriggerCellFromCells(const unsigned) const
std::multimap< std::pair< short, short >, short > trigger_cells_to_cells_
virtual geom_set getCellsFromModule(const unsigned) const override final
int waferTypeT(int wafer) const
Definition: vlib.h:208
int layer() const
get the layer #
Definition: HGCalDetId.h:48
HGCalTriggerGeometryHexImp2(const edm::ParameterSet &conf)