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