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