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  void initialize(const edm::ESHandle<CaloGeometry>& ) final;
19  void reset() final;
20 
21  unsigned getTriggerCellFromCell( const unsigned ) const final;
22  unsigned getModuleFromCell( const unsigned ) const final;
23  unsigned getModuleFromTriggerCell( const unsigned ) const final;
24 
25  geom_set getCellsFromTriggerCell( const unsigned ) const final;
26  geom_set getCellsFromModule( const unsigned ) const final;
27  geom_set getTriggerCellsFromModule( const unsigned ) const final;
28 
29  geom_ordered_set getOrderedCellsFromModule( const unsigned ) const final;
30  geom_ordered_set getOrderedTriggerCellsFromModule( const unsigned ) const final;
31 
32  geom_set getNeighborsFromTriggerCell( const unsigned ) const final;
33 
34  GlobalPoint getTriggerCellPosition(const unsigned ) const final;
35  GlobalPoint getModulePosition(const unsigned ) const final;
36 
37  bool validTriggerCell( const unsigned ) const final;
38  bool disconnectedModule(const unsigned) const final;
39  unsigned triggerLayer(const unsigned) const final;
40 
41  private:
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();
76  void fillNeighborMaps();
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
113 {
114  setCaloGeometry(calo_geometry);
115  fillMaps();
118 
119 }
120 
121 unsigned
123 getTriggerCellFromCell( const unsigned cell_id ) const
124 {
125  if(DetId(cell_id).det() == DetId::Hcal) return 0;
126  HGCalDetId cell_det_id(cell_id);
127  int wafer_type = cell_det_id.waferType();
128  unsigned cell = cell_det_id.cell();
129  // FIXME: better way to do this cell->TC mapping?
130  auto trigger_cell_itr = cells_to_trigger_cells_.find(std::make_pair(wafer_type,cell));
131  if(trigger_cell_itr==cells_to_trigger_cells_.end())
132  {
133  throw cms::Exception("BadGeometry")
134  << "HGCalTriggerGeometry: HGCal cell " << cell << " is not mapped to any trigger cell for the wafer type " << wafer_type
135  << ". The trigger cell mapping should be modified.\n";
136  }
137  unsigned trigger_cell = trigger_cell_itr->second;
138  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();
139 }
140 
141 unsigned
143 getModuleFromCell( const unsigned cell_id ) const
144 {
145  if(DetId(cell_id).det() == DetId::Hcal) return 0;
146  HGCalDetId cell_det_id(cell_id);
147  unsigned wafer = cell_det_id.wafer();
148  unsigned subdet = cell_det_id.subdetId();
149  std::unordered_map<short, short>::const_iterator module_itr;
150  bool out_of_range_error = false;
151  switch(subdet)
152  {
154  module_itr = wafer_to_module_ee_.find(wafer);
155  if(module_itr==wafer_to_module_ee_.end()) out_of_range_error = true;
156  break;
158  module_itr = wafer_to_module_fh_.find(wafer);
159  if(module_itr==wafer_to_module_fh_.end()) out_of_range_error = true;
160  break;
161  default:
162  edm::LogError("HGCalTriggerGeometry") << "Unknown wafer->module mapping for subdet "<<subdet<<"\n";
163  return 0;
164  };
165  if(out_of_range_error)
166  {
167  throw cms::Exception("BadGeometry")
168  << "HGCalTriggerGeometry: Wafer " << wafer << " is not mapped to any trigger module for subdetector " << subdet
169  << ". The module mapping should be modified. See https://twiki.cern.ch/twiki/bin/viewauth/CMS/HGCALTriggerPrimitivesSimulation#Trigger_geometry for details.\n";
170  }
171  unsigned module = module_itr->second;
172  return HGCalDetId((ForwardSubdetector)cell_det_id.subdetId(), cell_det_id.zside(), cell_det_id.layer(), cell_det_id.waferType(), module, HGCalDetId::kHGCalCellMask).rawId();
173 }
174 
175 unsigned
177 getModuleFromTriggerCell( const unsigned trigger_cell_id ) const
178 {
179  HGCalDetId trigger_cell_det_id(trigger_cell_id);
180  unsigned wafer = trigger_cell_det_id.wafer();
181  unsigned subdet = trigger_cell_det_id.subdetId();
182  if(subdet==ForwardSubdetector::HGCHEB) return 0;
183  std::unordered_map<short, short>::const_iterator module_itr;
184  bool out_of_range_error = false;
185  switch(subdet)
186  {
188  module_itr = wafer_to_module_ee_.find(wafer);
189  if(module_itr==wafer_to_module_ee_.end()) out_of_range_error = true;
190  break;
192  module_itr = wafer_to_module_fh_.find(wafer);
193  if(module_itr==wafer_to_module_fh_.end()) out_of_range_error = true;
194  break;
195  default:
196  edm::LogError("HGCalTriggerGeometry") << "Unknown wafer->module mapping for subdet "<<subdet<<"\n";
197  return 0;
198  };
199  if(out_of_range_error)
200  {
201  throw cms::Exception("BadGeometry")
202  << "HGCalTriggerGeometry: Wafer " << wafer << " is not mapped to any trigger module for subdetector " << subdet
203  << ". The module mapping should be modified. See https://twiki.cern.ch/twiki/bin/viewauth/CMS/HGCALTriggerPrimitivesSimulation#Trigger_geometry for details.\n";
204  }
205  unsigned module = module_itr->second;
206  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();
207 }
208 
211 getCellsFromTriggerCell( const unsigned trigger_cell_id ) const
212 {
213  HGCalDetId trigger_cell_det_id(trigger_cell_id);
214  unsigned subdet = trigger_cell_det_id.subdetId();
215  if(subdet==ForwardSubdetector::HGCHEB) return geom_set();
216  int wafer_type = trigger_cell_det_id.waferType();
217  unsigned trigger_cell = trigger_cell_det_id.cell();
218  // FIXME: better way to do this TC->cell mapping?
219  const auto& cell_range = trigger_cells_to_cells_.equal_range(std::make_pair(wafer_type,trigger_cell));
220  geom_set cell_det_ids;
221  for(auto tc_c_itr=cell_range.first; tc_c_itr!=cell_range.second; tc_c_itr++)
222  {
223  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());
224  }
225  return cell_det_ids;
226 }
227 
230 getCellsFromModule( const unsigned module_id ) const
231 {
232 
233  HGCalDetId module_det_id(module_id);
234  unsigned subdet = module_det_id.subdetId();
235  if(subdet==ForwardSubdetector::HGCHEB) return geom_set();
236  unsigned module = module_det_id.wafer();
237  std::pair<std::unordered_multimap<short, short>::const_iterator,
238  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
239  switch(subdet)
240  {
242  wafer_itrs = module_to_wafers_ee_.equal_range(module);
243  break;
245  wafer_itrs = module_to_wafers_fh_.equal_range(module);
246  break;
247  default:
248  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
249  return geom_set();
250  };
251  geom_set cell_det_ids;
252  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
253  {
254  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
255  if(wafer_type==0) wafer_type = module_det_id.waferType();
256  // loop on the cells in each wafer and return valid ones
257  for(int cell=0; cell<number_cells_in_wafers_.at(wafer_type); cell++)
258  {
259  HGCalDetId cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, cell);
260  if(validCellId(subdet, cell_id)) cell_det_ids.emplace(cell_id.rawId());
261  }
262  }
263  return cell_det_ids;
264 }
265 
268 getOrderedCellsFromModule( const unsigned module_id ) const
269 {
270  HGCalDetId module_det_id(module_id);
271  unsigned subdet = module_det_id.subdetId();
272  if(subdet==ForwardSubdetector::HGCHEB) return geom_ordered_set();
273  unsigned module = module_det_id.wafer();
274  std::pair<std::unordered_multimap<short, short>::const_iterator,
275  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
276  switch(subdet)
277  {
279  wafer_itrs = module_to_wafers_ee_.equal_range(module);
280  break;
282  wafer_itrs = module_to_wafers_fh_.equal_range(module);
283  break;
284  default:
285  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
286  return geom_ordered_set();
287  };
288  geom_ordered_set cell_det_ids;
289  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
290  {
291  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
292  if(wafer_type==0) wafer_type = module_det_id.waferType();
293  // loop on the cells in each wafer
294  for(int cell=0; cell<number_cells_in_wafers_.at(wafer_type); cell++)
295  {
296  HGCalDetId cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, cell);
297  if(validCellId(subdet, cell_id)) cell_det_ids.emplace(cell_id.rawId());
298  }
299  }
300  return cell_det_ids;
301 }
302 
305 getTriggerCellsFromModule( const unsigned module_id ) const
306 {
307  HGCalDetId module_det_id(module_id);
308  unsigned subdet = module_det_id.subdetId();
309  if(subdet==ForwardSubdetector::HGCHEB) return geom_set();
310  unsigned module = module_det_id.wafer();
311  std::pair<std::unordered_multimap<short, short>::const_iterator,
312  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
313  switch(subdet)
314  {
316  wafer_itrs = module_to_wafers_ee_.equal_range(module);
317  break;
319  wafer_itrs = module_to_wafers_fh_.equal_range(module);
320  break;
321  default:
322  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
323  return geom_set();
324  };
325  geom_set trigger_cell_det_ids;
326  // loop on the wafers included in the module
327  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
328  {
329  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
330  if(wafer_type==0) wafer_type = module_det_id.waferType();
331  // loop on the trigger cells in each wafer
332  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
333  {
334  HGCalDetId trigger_cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, trigger_cell);
335  if(validTriggerCell(trigger_cell_id)) trigger_cell_det_ids.emplace(trigger_cell_id.rawId());
336  }
337  }
338  return trigger_cell_det_ids;
339 }
340 
343 getOrderedTriggerCellsFromModule( const unsigned module_id ) const
344 {
345  HGCalDetId module_det_id(module_id);
346  unsigned subdet = module_det_id.subdetId();
347  if(subdet==ForwardSubdetector::HGCHEB) return geom_ordered_set();
348  unsigned module = module_det_id.wafer();
349  std::pair<std::unordered_multimap<short, short>::const_iterator,
350  std::unordered_multimap<short, short>::const_iterator> wafer_itrs;
351  switch(subdet)
352  {
354  wafer_itrs = module_to_wafers_ee_.equal_range(module);
355  break;
357  wafer_itrs = module_to_wafers_fh_.equal_range(module);
358  break;
359  default:
360  edm::LogError("HGCalTriggerGeometry") << "Unknown module->wafers mapping for subdet "<<subdet<<"\n";
361  return geom_ordered_set();
362  };
363  geom_ordered_set trigger_cell_det_ids;
364  // loop on the wafers included in the module
365  for(auto wafer_itr=wafer_itrs.first; wafer_itr!=wafer_itrs.second; wafer_itr++)
366  {
367  int wafer_type = detIdWaferType(subdet, wafer_itr->second);
368  if(wafer_type==0) wafer_type = module_det_id.waferType();
369  // loop on the trigger cells in each wafer
370  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
371  {
372  HGCalDetId trigger_cell_id((ForwardSubdetector)module_det_id.subdetId(), module_det_id.zside(), module_det_id.layer(), wafer_type, wafer_itr->second, trigger_cell);
373  if(validTriggerCell(trigger_cell_id)) trigger_cell_det_ids.emplace(trigger_cell_id.rawId());
374  }
375  }
376  return trigger_cell_det_ids;
377 }
378 
379 
380 
383 getNeighborsFromTriggerCell( const unsigned trigger_cell_id ) const
384 {
385  HGCalDetId trigger_cell_det_id(trigger_cell_id);
386  unsigned wafer = trigger_cell_det_id.wafer();
387  int wafer_type = trigger_cell_det_id.waferType();
388  unsigned subdet = trigger_cell_det_id.subdetId();
389  unsigned trigger_cell = trigger_cell_det_id.cell();
390  if(subdet==ForwardSubdetector::HGCHEB) return geom_set();
391  // Retrieve surrounding wafers (around the wafer containing
392  // the trigger cell)
393  std::unordered_map<short, std::vector<short>>::const_iterator surrounding_wafers_itr;
394  bool out_of_range_error = false;
395  switch(subdet)
396  {
398  surrounding_wafers_itr = wafer_neighbors_ee_.find(wafer);
399  if(surrounding_wafers_itr==wafer_neighbors_ee_.end()) out_of_range_error = true;
400  break;
402  surrounding_wafers_itr = wafer_neighbors_fh_.find(wafer);
403  if(surrounding_wafers_itr==wafer_neighbors_fh_.end()) out_of_range_error = true;
404  break;
405  default:
406  edm::LogError("HGCalTriggerGeometry") << "Unknown wafer neighbours for subdet "<<subdet<<"\n";
407  return geom_set();
408  }
409  if(out_of_range_error)
410  {
411  throw cms::Exception("BadGeometry")
412  << "HGCalTriggerGeometry: Neighbors are not defined for wafer " << wafer << " in subdetector " << subdet
413  << ". The wafer neighbor mapping should be modified. \n";
414  };
415  const std::vector<short>& surrounding_wafers = surrounding_wafers_itr->second;
416  // Find the types of the surrounding wafers
417  std::vector<int> types;
418  types.reserve(surrounding_wafers.size()+1); // includes the central wafer -> +1
419  types.emplace_back(wafer_type);
420  for(const auto w : surrounding_wafers)
421  {
422  // if no neighbor, use the same type as the central one
423  // to create the wafer configuration
424  int wt = wafer_type;
425  if(w!=-1) wt = detIdWaferType(subdet, w);
426  if(wt==0) return geom_set(); // invalid wafer type
427  types.emplace_back(wt);
428  }
429  // retrieve neighbors
430  unsigned trigger_cell_key = packTriggerCell(trigger_cell, types);
431  geom_set neighbor_detids;
432  auto neighbors_itr = trigger_cell_neighbors_.find(trigger_cell_key);
433  if(neighbors_itr==trigger_cell_neighbors_.end())
434  {
435  throw cms::Exception("BadGeometry")
436  << "HGCalTriggerGeometry: Neighbors are not defined for trigger cell " << trigger_cell << " with wafer configuration "
437  << std::bitset<7>(trigger_cell_key >> 8) << ". The trigger cell neighbor mapping should be modified. \n";
438  }
439  const auto& neighbors = neighbors_itr->second;
440  // create HGCalDetId of neighbors and check their validity
441  neighbor_detids.reserve(neighbors.size());
442  for(const auto& wafer_tc : neighbors)
443  {
444  if(wafer_tc.first-1>=(int)surrounding_wafers.size())
445  {
446  throw cms::Exception("BadGeometry")
447  << "HGCalTriggerGeometry: Undefined wafer neighbor number "<<wafer_tc.first
448  << " for wafer " << wafer << " and trigger cell " << trigger_cell
449  << ". The neighbor mapping files should be modified.";
450  }
451  int neighbor_wafer = (wafer_tc.first==0 ? wafer : surrounding_wafers.at(wafer_tc.first-1));
452  if(neighbor_wafer==-1) continue; // non-existing wafer
453  int type = types.at(wafer_tc.first);
454  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);
455  if(validTriggerCell(neighbor_det_id.rawId()))
456  {
457  neighbor_detids.emplace(neighbor_det_id.rawId());
458  }
459  }
460  return neighbor_detids;
461 }
462 
463 
466 getTriggerCellPosition(const unsigned trigger_cell_det_id) const
467 {
468  // Position: barycenter of the trigger cell.
469  Basic3DVector<float> triggerCellVector(0.,0.,0.);
470  const auto cell_ids = getCellsFromTriggerCell(trigger_cell_det_id);
471  if(cell_ids.empty()) return GlobalPoint(0,0,0);
472  for(const auto& cell : cell_ids)
473  {
474  HGCalDetId cellDetId(cell);
475  triggerCellVector += (cellDetId.subdetId()==ForwardSubdetector::HGCEE ? eeGeometry()->getPosition(cellDetId) : fhGeometry()->getPosition(cellDetId)).basicVector();
476  }
477  return GlobalPoint( triggerCellVector/cell_ids.size() );
478 
479 }
480 
483 getModulePosition(const unsigned module_det_id) const
484 {
485  // Position: barycenter of the module.
486  Basic3DVector<float> moduleVector(0.,0.,0.);
487  const auto cell_ids = getCellsFromModule(module_det_id);
488  if(cell_ids.empty()) return GlobalPoint(0,0,0);
489  for(const auto& cell : cell_ids)
490  {
491  HGCalDetId cellDetId(cell);
492  moduleVector += (cellDetId.subdetId()==ForwardSubdetector::HGCEE ? eeGeometry()->getPosition(cellDetId) : fhGeometry()->getPosition(cellDetId)).basicVector();
493  }
494  return GlobalPoint( moduleVector/cell_ids.size() );
495 }
496 
497 
498 void
501 {
502  //
503  // read module mapping file
504  std::ifstream l1tModulesMappingStream(l1tModulesMapping_.fullPath());
505  if(!l1tModulesMappingStream.is_open())
506  {
507  throw cms::Exception("MissingDataFile")
508  << "Cannot open HGCalTriggerGeometry L1TModulesMapping file\n";
509  }
510  short subdet = 0;
511  short wafer = 0;
512  short module = 0;
513  for(; l1tModulesMappingStream>>subdet>>wafer>>module; )
514  {
515  int wafer_type = detIdWaferType(subdet, wafer);
516  switch(subdet)
517  {
519  {
520  // fill module <-> wafers mappings
521  wafer_to_module_ee_.emplace(wafer,module);
522  module_to_wafers_ee_.emplace(module, wafer);
523  // fill number of cells for a given wafer type
524  number_cells_in_wafers_.emplace(wafer_type, eeTopology().dddConstants().numberCellsHexagon(wafer));
525  break;
526  }
528  {
529  // fill module <-> wafers mappings
530  wafer_to_module_fh_.emplace(wafer,module);
531  module_to_wafers_fh_.emplace(module, wafer);
532  // fill number of cells for a given wafer type
533  number_cells_in_wafers_.emplace(wafer_type, fhTopology().dddConstants().numberCellsHexagon(wafer));
534  break;
535  }
536  default:
537  edm::LogWarning("HGCalTriggerGeometry") << "Unsupported subdetector number ("<<subdet<<") in L1TModulesMapping file\n";
538  break;
539  }
540  }
541  if(!l1tModulesMappingStream.eof()) edm::LogWarning("HGCalTriggerGeometry") << "Error reading L1TModulesMapping '"<<wafer<<" "<<module<<"' \n";
542  l1tModulesMappingStream.close();
543  // read trigger cell mapping file
544  std::ifstream l1tCellsMappingStream(l1tCellsMapping_.fullPath());
545  if(!l1tCellsMappingStream.is_open())
546  {
547  throw cms::Exception("MissingDataFile")
548  << "Cannot open HGCalTriggerGeometry L1TCellsMapping file\n";
549  }
550  short waferType = 0;
551  short cell = 0;
552  short triggerCell = 0;
553  for(; l1tCellsMappingStream>>waferType>>cell>>triggerCell; )
554  {
555  // fill cell <-> trigger cell mappings
556  cells_to_trigger_cells_.emplace(std::make_pair((waferType?1:-1),cell), triggerCell);
557  trigger_cells_to_cells_.emplace(std::make_pair((waferType?1:-1),triggerCell), cell);
558  // fill number of cells for a given wafer type
559  auto itr_insert = number_trigger_cells_in_wafers_.emplace((waferType?1:-1), 0);
560  if(triggerCell+1 > itr_insert.first->second) itr_insert.first->second = triggerCell+1;
561  }
562  if(!l1tCellsMappingStream.eof()) edm::LogWarning("HGCalTriggerGeometry") << "Error reading L1TCellsMapping'"<<waferType<<" "<<cell<<" "<<triggerCell<<"' \n";
563  l1tCellsMappingStream.close();
564 }
565 
566 void
569 {
570  // Fill trigger neighbor map
571  std::ifstream l1tCellNeighborsMappingStream(l1tCellNeighborsMapping_.fullPath());
572  if(!l1tCellNeighborsMappingStream.is_open())
573  {
574  throw cms::Exception("MissingDataFile")
575  << "Cannot open HGCalTriggerGeometry L1TCellNeighborsMapping file\n";
576  }
577  for(std::array<char,512> buffer; l1tCellNeighborsMappingStream.getline(&buffer[0], 512); )
578  {
579  std::string line(&buffer[0]);
580  // Extract keys consisting of the wafer configuration
581  // and of the trigger cell id
582  // Match patterns (X,Y)
583  // where X is a set of 7 bits
584  // and Y is a number with less than 4 digits
585  std::regex key_regex("\\(\\s*[01]{7}\\s*,\\s*\\d{1,3}\\s*\\)");
586  std::vector<std::string> key_tokens {
587  std::sregex_token_iterator(line.begin(), line.end(), key_regex), {}
588  };
589  if(key_tokens.size()!=1)
590  {
591  throw cms::Exception("BadGeometry")
592  << "Syntax error in the L1TCellNeighborsMapping:\n"
593  << " Cannot find the trigger cell key in line:\n"
594  << " '"<<&buffer[0]<<"'\n";
595  }
596  std::regex digits_regex("([01]{7})|(\\d{1,3})");
597  std::vector<std::string> type_tc {
598  std::sregex_token_iterator(key_tokens[0].begin(), key_tokens[0].end(), digits_regex), {}
599  };
600  // get cell id and wafer configuration
601  int trigger_cell = std::stoi(type_tc[1]);
602  std::vector<int> wafer_types;
603  wafer_types.reserve(type_tc[0].size());
604  // Convert waferType coarse=0, fine=1 to coarse=-1, fine=1
605  for(const char c : type_tc[0]) wafer_types.emplace_back( (std::stoi(std::string(&c))?1:-1) );
606  unsigned map_key = packTriggerCell(trigger_cell, wafer_types);
607  // Extract neighbors
608  // Match patterns (X,Y)
609  // where X is a number with less than 4 digits
610  // and Y is one single digit (the neighbor wafer, between 0 and 6)
611  std::regex neighbors_regex("\\(\\s*\\d{1,3}\\s*,\\s*\\d\\s*\\)");
612  std::vector<std::string> neighbors_tokens {
613  std::sregex_token_iterator(line.begin(), line.end(), neighbors_regex), {}
614  };
615  if(neighbors_tokens.empty())
616  {
617  throw cms::Exception("BadGeometry")
618  << "Syntax error in the L1TCellNeighborsMapping:\n"
619  << " Cannot find any neighbor in line:\n"
620  << " '"<<&buffer[0]<<"'\n";
621  }
622  auto itr_insert = trigger_cell_neighbors_.emplace(map_key, std::set<std::pair<short,short>>());
623  for(const auto& neighbor : neighbors_tokens)
624  {
625  std::vector<std::string> pair_neighbor {
626  std::sregex_token_iterator(neighbor.begin(), neighbor.end(), digits_regex), {}
627  };
628  short neighbor_wafer(std::stoi(pair_neighbor[1]));
629  short neighbor_cell(std::stoi(pair_neighbor[0]));
630  itr_insert.first->second.emplace(neighbor_wafer, neighbor_cell);
631  }
632  }
633  if(!l1tCellNeighborsMappingStream.eof()) edm::LogWarning("HGCalTriggerGeometry") << "Error reading L1TCellNeighborsMapping'\n";
634  l1tCellNeighborsMappingStream.close();
635 
636  // Fill wafer neighbor map
637  std::ifstream l1tWaferNeighborsMappingStream(l1tWaferNeighborsMapping_.fullPath());
638  if(!l1tWaferNeighborsMappingStream.is_open())
639  {
640  throw cms::Exception("MissingDataFile")
641  << "Cannot open HGCalTriggerGeometry L1TWaferNeighborsMapping file\n";
642  }
643  for(std::array<char,512> buffer; l1tWaferNeighborsMappingStream.getline(&buffer[0], 512); )
644  {
645  std::string line(&buffer[0]);
646  // split line using spaces as delimiter
647  std::regex delimiter("\\s+");
648  std::vector<std::string> tokens {
649  std::sregex_token_iterator(line.begin(), line.end(), delimiter, -1), {}
650  };
651  if(tokens.size()!=8)
652  {
653  throw cms::Exception("BadGeometry")
654  << "Syntax error in the L1TWaferNeighborsMapping in line:\n"
655  << " '"<<&buffer[0]<<"'\n"
656  << " A line should be composed of 8 integers separated by spaces:\n"
657  << " subdet waferid neighbor1 neighbor2 neighbor3 neighbor4 neighbor5 neighbor6\n";
658  }
659  short subdet(std::stoi(tokens[0]));
660  short wafer(std::stoi(tokens[1]));
661 
662  std::unordered_map<short, std::vector<short>>* wafer_neighbors;
663  switch(subdet)
664  {
666  wafer_neighbors = &wafer_neighbors_ee_;
667  break;
669  wafer_neighbors = &wafer_neighbors_fh_;
670  break;
671  default:
672  throw cms::Exception("BadGeometry")
673  << "Unknown subdet " << subdet << " in L1TWaferNeighborsMapping:\n"
674  << " '"<<&buffer[0]<<"'\n";
675  };
676  auto wafer_itr = wafer_neighbors->emplace(wafer, std::vector<short>());
677  for(auto neighbor_itr=tokens.cbegin()+2; neighbor_itr!=tokens.cend(); ++neighbor_itr)
678  {
679  wafer_itr.first->second.emplace_back(std::stoi(*neighbor_itr));
680  }
681  }
682 }
683 
684 
685 void
688 {
689  unsigned n_layers_ee = eeTopology().dddConstants().layers(true);
690  for(unsigned layer=1; layer<=n_layers_ee; layer++)
691  {
692  for(const auto& wafer_module : wafer_to_module_ee_)
693  {
694  unsigned wafer = wafer_module.first;
695  int wafer_type = detIdWaferType(ForwardSubdetector::HGCEE, wafer);
696  // loop on the trigger cells in each wafer
697  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
698  {
699  HGCalDetId trigger_cell_id_neg(ForwardSubdetector::HGCEE, -1, layer, wafer_type, wafer, trigger_cell);
700  HGCalDetId trigger_cell_id_pos(ForwardSubdetector::HGCEE, 1, layer, wafer_type, wafer, trigger_cell);
701  if(!validTriggerCellFromCells(trigger_cell_id_neg)) invalid_triggercells_.emplace(trigger_cell_id_neg.rawId());
702  if(!validTriggerCellFromCells(trigger_cell_id_pos)) invalid_triggercells_.emplace(trigger_cell_id_pos.rawId());
703  }
704  }
705  }
706  unsigned n_layers_fh = fhTopology().dddConstants().layers(true);
707  for(unsigned layer=1; layer<=n_layers_fh; layer++)
708  {
709  for(const auto& wafer_module : wafer_to_module_fh_)
710  {
711  unsigned wafer = wafer_module.first;
712  int wafer_type = detIdWaferType(ForwardSubdetector::HGCHEF, wafer);
713  // loop on the trigger cells in each wafer
714  for(int trigger_cell=0; trigger_cell<number_trigger_cells_in_wafers_.at(wafer_type); trigger_cell++)
715  {
716  HGCalDetId trigger_cell_id_neg(ForwardSubdetector::HGCHEF, -1, layer, wafer_type, wafer, trigger_cell);
717  HGCalDetId trigger_cell_id_pos(ForwardSubdetector::HGCHEF, 1, layer, wafer_type, wafer, trigger_cell);
718  if(!validTriggerCellFromCells(trigger_cell_id_neg)) invalid_triggercells_.emplace(trigger_cell_id_neg.rawId());
719  if(!validTriggerCellFromCells(trigger_cell_id_pos)) invalid_triggercells_.emplace(trigger_cell_id_pos.rawId());
720  }
721  }
722  }
723 }
724 
725 unsigned
727 packTriggerCell(unsigned trigger_cell, const std::vector<int>& wafer_types) const
728 {
729  unsigned packed_value = trigger_cell;
730  for(unsigned i=0; i<wafer_types.size(); i++)
731  {
732  // trigger cell id on 8 bits
733  // wafer configuration bits: 0=coarse, 1=fine
734  if(wafer_types.at(i)==1) packed_value += (0x1<<(8+i));
735  }
736  return packed_value;
737 }
738 
739 
740 int
742 detIdWaferType(unsigned subdet, short wafer) const
743 {
744  int wafer_type = 0;
745  switch(subdet)
746  {
747  // HGCalDDDConstants::waferTypeT() returns 2=coarse, 1=fine
748  // HGCalDetId::waferType() returns -1=coarse, 1=fine
749  // Convert to HGCalDetId waferType
751  wafer_type = (eeTopology().dddConstants().waferTypeT(wafer)==2?-1:1);
752  break;
754  wafer_type = (fhTopology().dddConstants().waferTypeT(wafer)==2?-1:1);
755  break;
756  default:
757  break;
758  };
759  return wafer_type;
760 }
761 
762 bool
764 validTriggerCell(const unsigned trigger_cell_id) const
765 {
766  return invalid_triggercells_.find(trigger_cell_id)==invalid_triggercells_.end();
767 }
768 
769 
770 bool
772 disconnectedModule(const unsigned module_id) const
773 {
774  return false;
775 }
776 
777 
778 unsigned
780 triggerLayer(const unsigned id) const
781 {
782  return HGCalDetId(id).layer();
783 }
784 
785 bool
787 validTriggerCellFromCells(const unsigned trigger_cell_id) const
788 {
789  // Check the validity of a trigger cell with the
790  // validity of the cells. One valid cell in the
791  // trigger cell is enough to make the trigger cell
792  // valid.
793  HGCalDetId trigger_cell_det_id(trigger_cell_id);
794  unsigned subdet = trigger_cell_det_id.subdetId();
795  const geom_set cells = getCellsFromTriggerCell(trigger_cell_id);
796  bool is_valid = false;
797  for(const auto cell_id : cells)
798  {
799  is_valid |= validCellId(subdet, cell_id);
800  if(is_valid) break;
801  }
802  return is_valid;
803 }
804 
805 bool
807 validCellId(unsigned subdet, unsigned cell_id) const
808 {
809  bool is_valid = false;
810  switch(subdet)
811  {
813  is_valid = eeTopology().valid(cell_id);
814  break;
816  is_valid = fhTopology().valid(cell_id);
817  break;
818  default:
819  is_valid = false;
820  break;
821  }
822  return is_valid;
823 }
824 
825 
826 
827 
830  "HGCalTriggerGeometryHexImp2");
size
Write out results.
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
const HGCalGeometry * eeGeometry() const
const HGCalTopology & eeTopology() const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:47
unsigned packTriggerCell(unsigned, const std::vector< int > &) const
void initialize(const edm::ESHandle< CaloGeometry > &) final
GlobalPoint getPosition(const DetId &id) const
std::unordered_multimap< short, short > module_to_wafers_fh_
std::unordered_set< unsigned > invalid_triggercells_
ForwardSubdetector
GlobalPoint getTriggerCellPosition(const unsigned) const final
geom_set getNeighborsFromTriggerCell(const unsigned) const final
bool disconnectedModule(const unsigned) const final
bool validCellId(unsigned subdet, unsigned cell_id) const
static const int kHGCalCellMask
Definition: HGCalDetId.h:13
unsigned getTriggerCellFromCell(const unsigned) const final
unsigned int layers(bool reco) const
int zside() const
get the z-side of the cell (1/-1)
Definition: HGCalDetId.h:51
const HGCalGeometry * fhGeometry() const
std::unordered_map< short, std::vector< short > > wafer_neighbors_fh_
std::unordered_map< short, std::vector< short > > wafer_neighbors_ee_
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
std::unordered_multimap< short, short > module_to_wafers_ee_
#define end
Definition: vmac.h:39
int wafer() const
get the wafer #
Definition: HGCalDetId.h:42
void setCaloGeometry(const edm::ESHandle< CaloGeometry > &geom)
geom_set getCellsFromModule(const unsigned) const final
std::unordered_map< short, short > wafer_to_module_ee_
geom_set getCellsFromTriggerCell(const unsigned) const final
geom_ordered_set getOrderedTriggerCellsFromModule(const unsigned) const final
unsigned getModuleFromCell(const unsigned) const final
Definition: DetId.h:18
int cell() const
get the absolute value of the cell #&#39;s in x and y
Definition: HGCalDetId.h:39
const HGCalDDDConstants & dddConstants() const
std::unordered_map< short, short > wafer_to_module_fh_
std::set< unsigned > geom_ordered_set
bool validTriggerCell(const unsigned) const final
#define begin
Definition: vmac.h:32
HLT enums.
std::unordered_set< unsigned > geom_set
std::string fullPath() const
Definition: FileInPath.cc:197
int detIdWaferType(unsigned subdet, short wafer) const
int waferType() const
get the wafer type
Definition: HGCalDetId.h:45
geom_set getTriggerCellsFromModule(const unsigned) const final
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::map< std::pair< short, short >, short > cells_to_trigger_cells_
unsigned getModuleFromTriggerCell(const unsigned) const final
std::unordered_map< int, std::set< std::pair< short, short > > > trigger_cell_neighbors_
unsigned triggerLayer(const unsigned) const final
bool valid(const DetId &id) const override
Is this a valid cell id.
bool validTriggerCellFromCells(const unsigned) const
std::multimap< std::pair< short, short >, short > trigger_cells_to_cells_
int waferTypeT(int wafer) const
Definition: vlib.h:208
GlobalPoint getModulePosition(const unsigned) const final
geom_ordered_set getOrderedCellsFromModule(const unsigned) const final
const HGCalTopology & fhTopology() const
int layer() const
get the layer #
Definition: HGCalDetId.h:48
HGCalTriggerGeometryHexImp2(const edm::ParameterSet &conf)