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