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