CMS 3D CMS Logo

HGCalTriggerTowerGeometryHelper.cc
Go to the documentation of this file.
1 
7 
8 #include <cmath>
9 #include <iostream>
10 #include <fstream>
11 #include <algorithm>
12 
14  : doNose_(conf.getParameter<bool>("doNose")),
15  minEta_(conf.getParameter<double>("minEta")),
16  maxEta_(conf.getParameter<double>("maxEta")),
17  minPhi_(conf.getParameter<double>("minPhi")),
18  maxPhi_(conf.getParameter<double>("maxPhi")),
19  nBinsEta_(conf.getParameter<int>("nBinsEta")),
20  nBinsPhi_(conf.getParameter<int>("nBinsPhi")),
21  binsEta_(conf.getParameter<std::vector<double> >("binsEta")),
22  binsPhi_(conf.getParameter<std::vector<double> >("binsPhi")),
23  splitModuleSum_(conf.getParameter<bool>("splitModuleSum")) {
24  if (!binsEta_.empty() && ((unsigned int)(binsEta_.size()) != nBinsEta_ + 1)) {
25  throw edm::Exception(edm::errors::Configuration, "Configuration")
26  << "HGCalTriggerTowerGeometryHelper nBinsEta for the tower map not consistent with binsEta size" << std::endl;
27  }
28 
29  if (!binsPhi_.empty() && ((unsigned int)(binsPhi_.size()) != nBinsPhi_ + 1)) {
30  throw edm::Exception(edm::errors::Configuration, "Configuration")
31  << "HGCalTriggerTowerGeometryHelper nBinsPhi for the tower map not consistent with binsPhi size" << std::endl;
32  }
33 
34  // if the bin vecctor is empty we assume the bins to be regularly spaced
35  if (binsEta_.empty()) {
36  for (unsigned int bin1 = 0; bin1 != nBinsEta_ + 1; bin1++) {
37  binsEta_.push_back(minEta_ + bin1 * ((maxEta_ - minEta_) / nBinsEta_));
38  }
39  }
40 
41  // if the bin vecctor is empty we assume the bins to be regularly spaced
42  if (binsPhi_.empty()) {
43  for (unsigned int bin2 = 0; bin2 != nBinsPhi_ + 1; bin2++) {
44  binsPhi_.push_back(minPhi_ + bin2 * ((maxPhi_ - minPhi_) / nBinsPhi_));
45  }
46  }
47 
48  for (int zside = -1; zside <= 1; zside += 2) {
49  for (unsigned int bin1 = 0; bin1 != nBinsEta_; bin1++) {
50  for (unsigned int bin2 = 0; bin2 != nBinsPhi_; bin2++) {
51  l1t::HGCalTowerID towerId(doNose_, zside, bin1, bin2);
52  tower_coords_.emplace_back(towerId.rawId(),
53  zside * ((binsEta_[bin1 + 1] + binsEta_[bin1]) / 2),
54  (binsPhi_[bin2 + 1] + binsPhi_[bin2]) / 2);
55  }
56  }
57  }
58 
59  if (conf.getParameter<bool>("readMappingFile")) {
60  // We read the TC to TT mapping from file,
61  // otherwise we derive the TC to TT mapping on the fly from eta-phi coord. of the TCs
62  std::ifstream l1tTriggerTowerMappingStream(conf.getParameter<edm::FileInPath>("L1TTriggerTowerMapping").fullPath());
63  if (!l1tTriggerTowerMappingStream.is_open()) {
64  throw cms::Exception("MissingDataFile") << "Cannot open HGCalTriggerGeometry L1TTriggerTowerMapping file\n";
65  }
66 
67  unsigned trigger_cell_id = 0;
68  unsigned short iEta = 0;
69  unsigned short iPhi = 0;
70 
71  for (; l1tTriggerTowerMappingStream >> trigger_cell_id >> iEta >> iPhi;) {
72  if (iEta >= nBinsEta_ || iPhi >= nBinsPhi_) {
73  throw edm::Exception(edm::errors::Configuration, "Configuration")
74  << "HGCalTriggerTowerGeometryHelper warning inconsistent mapping TC : " << trigger_cell_id
75  << " to TT iEta: " << iEta << " iPhi: " << iPhi << " when max #bins eta: " << nBinsEta_
76  << " phi: " << nBinsPhi_ << std::endl;
77  }
78  l1t::HGCalTowerID towerId(doNose_, triggerTools_.zside(DetId(trigger_cell_id)), iEta, iPhi);
79  cells_to_trigger_towers_[trigger_cell_id] = towerId.rawId();
80  }
81  l1tTriggerTowerMappingStream.close();
82  }
83 
84  if (splitModuleSum_) {
85  //variables for transforming towers
88  reverseX_ = int(nBinsPhi_) / 2 - 1;
89 
90  std::ifstream moduleTowerMappingStream(conf.getParameter<edm::FileInPath>("moduleTowerMapping").fullPath());
91  if (!moduleTowerMappingStream.is_open()) {
92  throw cms::Exception("MissingDataFile") << "Cannot open HGCalTowerMapProducer moduleTowerMapping file\n";
93  }
94  //get split divisors
96  std::getline(moduleTowerMappingStream, line); //Skip row
97  std::getline(moduleTowerMappingStream, line);
98  std::stringstream ss(line);
100 
101  //get towers and module sum shares
102  std::getline(moduleTowerMappingStream, line); //Skip row
103  std::getline(moduleTowerMappingStream, line); //Skip row
104  const int minNumOfWordsPerRow = 5;
105  const int numOfWordsPerTower = 3;
106  for (std::string line; std::getline(moduleTowerMappingStream, line);) {
107  int numOfWordsInThisRow = 0;
108  for (std::string::size_type i = 0; i < line.size(); i++) {
109  if (line[i] != ' ' && line[i + 1] == ' ') {
110  numOfWordsInThisRow++;
111  }
112  }
113  if (numOfWordsInThisRow < minNumOfWordsPerRow) {
114  throw edm::Exception(edm::errors::Configuration, "Configuration")
115  << "HGCalTriggerTowerGeometryHelper warning: Incorrect/incomplete values for module ID in the mapping "
116  "file.\n"
117  << "The incorrect line is:" << line << std::endl;
118  }
119  int subdet = 0;
120  int layer = 0;
121  int moduleU = 0;
122  int moduleV = 0;
123  int numTowers = 0;
124  std::stringstream ss(line);
125  ss >> subdet >> layer >> moduleU >> moduleV >> numTowers;
126  if (numOfWordsInThisRow != (numTowers * numOfWordsPerTower + minNumOfWordsPerRow)) {
127  throw edm::Exception(edm::errors::Configuration, "Configuration")
128  << "HGCalTriggerTowerGeometryHelper warning: Incorrect/incomplete values for module ID or tower "
129  "share/eta/phi in the mapping file.\n"
130  << "The incorrect line is:" << line << std::endl;
131  }
132  unsigned packed_modID = packLayerSubdetWaferId(subdet, layer, moduleU, moduleV);
133  std::vector<unsigned> towers;
134  for (int itr_tower = 0; itr_tower < numTowers; itr_tower++) {
135  int iEta_raw = 0;
136  int iPhi_raw = 0;
137  int towerShare = 0;
138  ss >> iEta_raw >> iPhi_raw >> towerShare;
139  int splitDivisor = (subdet == 2) ? splitDivisorScint_ : splitDivisorSilic_;
140  if ((towerShare > splitDivisor) || (towerShare < 1)) {
141  throw edm::Exception(edm::errors::Configuration, "Configuration")
142  << "HGCalTriggerTowerGeometryHelper warning: invalid tower share in the mapping file.\n"
143  << "Tower share must be a positive integer and less than splitDivisor. The incorrect values found for "
144  "module ID:"
145  << std::endl
146  << "subdet=" << subdet << ", l=" << layer << ", u=" << moduleU << ", v=" << moduleV << std::endl;
147  }
148  towers.push_back(packTowerIDandShare(iEta_raw, iPhi_raw, towerShare));
149  }
150  modules_to_trigger_towers_[packed_modID] = towers;
151  }
152  moduleTowerMappingStream.close();
153  }
154 }
155 
156 unsigned HGCalTriggerTowerGeometryHelper::packLayerSubdetWaferId(int subdet, int layer, int moduleU, int moduleV) const {
157  unsigned packed_modID = 0;
158  packed_modID |= ((subdet & HGCalTriggerModuleDetId::kHGCalTriggerSubdetMask)
161  packed_modID |=
163  packed_modID |=
165  return packed_modID;
166 }
167 
168 unsigned HGCalTriggerTowerGeometryHelper::packTowerIDandShare(int iEta_raw, int iPhi_raw, int towerShare) const {
169  unsigned packed_towerIDandShare = 0;
170  unsigned iEtaAbs = std::abs(iEta_raw);
171  unsigned iEtaSign = std::signbit(iEta_raw);
172  unsigned iPhiAbs = std::abs(iPhi_raw);
173  unsigned iPhiSign = std::signbit(iPhi_raw);
174  packed_towerIDandShare |= ((iEtaAbs & l1t::HGCalTowerID::coordMask) << l1t::HGCalTowerID::coord1Shift);
175  packed_towerIDandShare |= ((iEtaSign & signMask) << sign1Shift);
176  packed_towerIDandShare |= ((iPhiAbs & l1t::HGCalTowerID::coordMask) << l1t::HGCalTowerID::coord2Shift);
177  packed_towerIDandShare |= ((iPhiSign & signMask) << sign2Shift);
178  packed_towerIDandShare |= ((towerShare & towerShareMask) << towerShareShift);
179  return packed_towerIDandShare;
180 }
181 
183  int& iEta_raw,
184  int& iPhi_raw,
185  int& towerShare) const {
186  //eta
187  iEta_raw = (towerIDandShare >> l1t::HGCalTowerID::coord1Shift) & l1t::HGCalTowerID::coordMask;
188  unsigned iEtaSign = (towerIDandShare >> sign1Shift) & signMask;
189  iEta_raw = (iEtaSign) ? -1 * iEta_raw : iEta_raw;
190  //phi
191  iPhi_raw = (towerIDandShare >> l1t::HGCalTowerID::coord2Shift) & l1t::HGCalTowerID::coordMask;
192  unsigned iPhiSign = (towerIDandShare >> sign2Shift) & signMask;
193  iPhi_raw = (iPhiSign) ? -1 * iPhi_raw : iPhi_raw;
194  //tower share
195  towerShare = (towerIDandShare >> towerShareShift) & towerShareMask;
196 }
197 
199  int iPhi = (iPhi_raw + sector * rotate120Deg_ + rotate180Deg_) % int(nBinsPhi_);
200  return iPhi;
201 }
202 
204  iPhi = reverseX_ - iPhi; //correct x -> -x in z>0
205  iPhi = (int(nBinsPhi_) + iPhi) % int(nBinsPhi_); // make all phi between 0 to nBinsPhi_-1
206 }
207 
208 const std::vector<l1t::HGCalTowerCoord>& HGCalTriggerTowerGeometryHelper::getTowerCoordinates() const {
209  return tower_coords_;
210 }
211 
212 unsigned short HGCalTriggerTowerGeometryHelper::getTriggerTowerFromEtaPhi(const float& eta, const float& phi) const {
213  auto bin_eta_l = std::lower_bound(binsEta_.begin(), binsEta_.end(), fabs(eta));
214  unsigned int bin_eta = 0;
215  // we add a protection for TCs in Hadron part which are outside the boundaries and possible rounding effects
216  if (bin_eta_l == binsEta_.end()) {
217  if (fabs(eta) < minEta_) {
218  bin_eta = 0;
219  } else if (fabs(eta) >= maxEta_) {
220  bin_eta = nBinsEta_;
221  } else {
222  edm::LogError("HGCalTriggerTowerGeometryHelper")
223  << " did not manage to map eta " << eta << " to any Trigger Tower\n";
224  }
225  } else {
226  bin_eta = bin_eta_l - binsEta_.begin() - 1;
227  }
228 
229  auto bin_phi_l = std::lower_bound(binsPhi_.begin(), binsPhi_.end(), phi);
230  unsigned int bin_phi = 0;
231  if (bin_phi_l == binsPhi_.end()) {
232  if (phi < minPhi_) {
233  bin_phi = nBinsPhi_;
234  } else if (phi >= maxPhi_) {
235  bin_phi = 0;
236  } else {
237  edm::LogError("HGCalTriggerTowerGeometryHelper")
238  << " did not manage to map phi " << phi << " to any Trigger Tower\n";
239  }
240  } else {
241  bin_phi = bin_phi_l - binsPhi_.begin() - 1;
242  }
243  int zside = eta < 0 ? -1 : 1;
244  return l1t::HGCalTowerID(doNose_, zside, bin_eta, bin_phi).rawId();
245 }
246 
247 std::unordered_map<unsigned short, float> HGCalTriggerTowerGeometryHelper::getTriggerTower(
248  const l1t::HGCalTriggerCell& thecell) const {
249  std::unordered_map<unsigned short, float> towerIDandShares = {};
250  unsigned int trigger_cell_id = thecell.detId();
251  // NOTE: if the TC is not found in the map than it is mapped via eta-phi coords.
252  // this can be considered dangerous (silent failure of the map) but it actually allows to save
253  // memory mapping explicitly only what is actually needed
254  auto tower_id_itr = cells_to_trigger_towers_.find(trigger_cell_id);
255  if (tower_id_itr != cells_to_trigger_towers_.end()) {
256  towerIDandShares.insert({tower_id_itr->second, 1.0});
257  return towerIDandShares;
258  }
259  towerIDandShares.insert({getTriggerTowerFromEtaPhi(thecell.position().eta(), thecell.position().phi()), 1.0});
260  return towerIDandShares;
261 }
262 
263 std::unordered_map<unsigned short, float> HGCalTriggerTowerGeometryHelper::getTriggerTower(
264  const l1t::HGCalTriggerSums& thesum) const {
265  std::unordered_map<unsigned short, float> towerIDandShares = {};
266  if (!splitModuleSum_) {
267  towerIDandShares.insert({getTriggerTowerFromEtaPhi(thesum.position().eta(), thesum.position().phi()), 1.0});
268  return towerIDandShares;
269  } else {
271  int moduleU = detid.moduleU();
272  int moduleV = detid.moduleV();
273  int layer = detid.layer();
274  int sector = detid.sector();
275  int zside = detid.zside();
276  int subdet = 0;
277  int splitDivisor;
278  if (detid.isHScintillator()) {
279  subdet = 2;
280  splitDivisor = splitDivisorScint_;
281  } else if (detid.isEE()) {
282  subdet = 0;
283  splitDivisor = splitDivisorSilic_;
284  } else if (detid.isHSilicon()) {
285  subdet = 1;
286  splitDivisor = splitDivisorSilic_;
287  } else { //HFNose
288  towerIDandShares.insert({getTriggerTowerFromEtaPhi(thesum.position().eta(), thesum.position().phi()), 1.0});
289  return towerIDandShares;
290  }
291 
292  unsigned packed_modID = packLayerSubdetWaferId(subdet, layer, moduleU, moduleV);
293  auto module_id_itr = modules_to_trigger_towers_.find(packed_modID);
294  if (module_id_itr != modules_to_trigger_towers_.end()) {
295  //eta variables
296  int iEta = -999;
297  int iEta_raw = -999;
298  int offsetEta = 2;
299  //phi variables
300  int iPhi = -999;
301  int iPhi_raw = -999;
302  int towerShare = -999; //the share each tower gets from module sum
303  for (auto towerIDandShare : module_id_itr->second) {
304  unpackTowerIDandShare(towerIDandShare, iEta_raw, iPhi_raw, towerShare);
305  iEta = offsetEta + iEta_raw;
306  iPhi = moveToCorrectSector(iPhi_raw, sector);
307  if (zside == 1) {
308  reverseXaxis(iPhi);
309  }
310  towerIDandShares.insert(
311  {l1t::HGCalTowerID(doNose_, zside, iEta, iPhi).rawId(), double(towerShare) / splitDivisor});
312  }
313  return towerIDandShares;
314  } else { // for modules not found in the mapping file (currently a few partial modules) use the traditional method.
315  towerIDandShares.insert({getTriggerTowerFromEtaPhi(thesum.position().eta(), thesum.position().phi()), 1.0});
316  return towerIDandShares;
317  }
318  }
319 }
const float maxPhi_
Definition: Constants.h:80
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static const int kHGCalTriggerSubdetMask
const std::vector< l1t::HGCalTowerCoord > & getTowerCoordinates() const
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
static const int coord1Shift
Definition: HGCalTowerID.h:36
T eta() const
Definition: PV3DBase.h:73
static const int kHGCalModuleVOffset
int zside(DetId const &)
Log< level::Error, false > LogError
uint16_t size_type
std::unordered_map< unsigned, std::vector< unsigned > > modules_to_trigger_towers_
static const int kHGCalModuleUOffset
int zside(const DetId &) const
unsigned towerId(DetId const &, EcalElectronicsMapping const *)
std::vector< l1t::HGCalTowerCoord > tower_coords_
uint32_t detId() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
uint32_t detId() const
unsigned packTowerIDandShare(int towerEta, int towerPhi, int towerShare) const
const GlobalPoint & position() const
std::unordered_map< unsigned short, float > getTriggerTower(const l1t::HGCalTriggerCell &) const
Definition: DetId.h:17
static const int coord2Shift
Definition: HGCalTowerID.h:37
const GlobalPoint & position() const
int moveToCorrectSector(int towerPhi_raw, int sector) const
static const int coordMask
Definition: HGCalTowerID.h:35
const std::string & fullPath() const
Definition: FileInPath.cc:144
std::unordered_map< unsigned, short > cells_to_trigger_towers_
unsigned short rawId() const
Definition: HGCalTowerID.h:29
HGCalTriggerTowerGeometryHelper(const edm::ParameterSet &conf)
unsigned packLayerSubdetWaferId(int subdet, int layer, int moduleU, int moduleV) const
void unpackTowerIDandShare(unsigned towerIDandShare, int &towerEta_raw, int &towerPhi_raw, int &towerShare) const
unsigned short getTriggerTowerFromEtaPhi(const float &eta, const float &phi) const
static const int kHGCalTriggerSubdetOffset