File indexing completed on 2024-04-06 12:20:43
0001
0002 #include "L1Trigger/L1THGCal/interface/HGCalTriggerTowerGeometryHelper.h"
0003 #include "FWCore/Utilities/interface/Exception.h"
0004 #include "FWCore/Utilities/interface/EDMException.h"
0005 #include "DataFormats/DetId/interface/DetId.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007
0008 #include <cmath>
0009 #include <iostream>
0010 #include <fstream>
0011 #include <algorithm>
0012
0013 HGCalTriggerTowerGeometryHelper::HGCalTriggerTowerGeometryHelper(const edm::ParameterSet& conf)
0014 : doNose_(conf.getParameter<bool>("doNose")),
0015 minEta_(conf.getParameter<double>("minEta")),
0016 maxEta_(conf.getParameter<double>("maxEta")),
0017 minPhi_(conf.getParameter<double>("minPhi")),
0018 maxPhi_(conf.getParameter<double>("maxPhi")),
0019 nBinsEta_(conf.getParameter<int>("nBinsEta")),
0020 nBinsPhi_(conf.getParameter<int>("nBinsPhi")),
0021 binsEta_(conf.getParameter<std::vector<double> >("binsEta")),
0022 binsPhi_(conf.getParameter<std::vector<double> >("binsPhi")),
0023 splitModuleSum_(conf.getParameter<bool>("splitModuleSum")) {
0024 if (!binsEta_.empty() && ((unsigned int)(binsEta_.size()) != nBinsEta_ + 1)) {
0025 throw edm::Exception(edm::errors::Configuration, "Configuration")
0026 << "HGCalTriggerTowerGeometryHelper nBinsEta for the tower map not consistent with binsEta size" << std::endl;
0027 }
0028
0029 if (!binsPhi_.empty() && ((unsigned int)(binsPhi_.size()) != nBinsPhi_ + 1)) {
0030 throw edm::Exception(edm::errors::Configuration, "Configuration")
0031 << "HGCalTriggerTowerGeometryHelper nBinsPhi for the tower map not consistent with binsPhi size" << std::endl;
0032 }
0033
0034
0035 if (binsEta_.empty()) {
0036 for (unsigned int bin1 = 0; bin1 != nBinsEta_ + 1; bin1++) {
0037 binsEta_.push_back(minEta_ + bin1 * ((maxEta_ - minEta_) / nBinsEta_));
0038 }
0039 }
0040
0041
0042 if (binsPhi_.empty()) {
0043 for (unsigned int bin2 = 0; bin2 != nBinsPhi_ + 1; bin2++) {
0044 binsPhi_.push_back(minPhi_ + bin2 * ((maxPhi_ - minPhi_) / nBinsPhi_));
0045 }
0046 }
0047
0048 for (int zside = -1; zside <= 1; zside += 2) {
0049 for (unsigned int bin1 = 0; bin1 != nBinsEta_; bin1++) {
0050 for (unsigned int bin2 = 0; bin2 != nBinsPhi_; bin2++) {
0051 l1t::HGCalTowerID towerId(doNose_, zside, bin1, bin2);
0052 tower_coords_.emplace_back(towerId.rawId(),
0053 zside * ((binsEta_[bin1 + 1] + binsEta_[bin1]) / 2),
0054 (binsPhi_[bin2 + 1] + binsPhi_[bin2]) / 2);
0055 }
0056 }
0057 }
0058
0059 if (conf.getParameter<bool>("readMappingFile")) {
0060
0061
0062 std::ifstream l1tTriggerTowerMappingStream(conf.getParameter<edm::FileInPath>("L1TTriggerTowerMapping").fullPath());
0063 if (!l1tTriggerTowerMappingStream.is_open()) {
0064 throw cms::Exception("MissingDataFile") << "Cannot open HGCalTriggerGeometry L1TTriggerTowerMapping file\n";
0065 }
0066
0067 unsigned trigger_cell_id = 0;
0068 unsigned short iEta = 0;
0069 unsigned short iPhi = 0;
0070
0071 for (; l1tTriggerTowerMappingStream >> trigger_cell_id >> iEta >> iPhi;) {
0072 if (iEta >= nBinsEta_ || iPhi >= nBinsPhi_) {
0073 throw edm::Exception(edm::errors::Configuration, "Configuration")
0074 << "HGCalTriggerTowerGeometryHelper warning inconsistent mapping TC : " << trigger_cell_id
0075 << " to TT iEta: " << iEta << " iPhi: " << iPhi << " when max #bins eta: " << nBinsEta_
0076 << " phi: " << nBinsPhi_ << std::endl;
0077 }
0078 l1t::HGCalTowerID towerId(doNose_, triggerTools_.zside(DetId(trigger_cell_id)), iEta, iPhi);
0079 cells_to_trigger_towers_[trigger_cell_id] = towerId.rawId();
0080 }
0081 l1tTriggerTowerMappingStream.close();
0082 }
0083
0084 if (splitModuleSum_) {
0085
0086 rotate180Deg_ = int(nBinsPhi_) / 2;
0087 rotate120Deg_ = int(nBinsPhi_) / 3;
0088 reverseX_ = int(nBinsPhi_) / 2 - 1;
0089
0090 std::ifstream moduleTowerMappingStream(conf.getParameter<edm::FileInPath>("moduleTowerMapping").fullPath());
0091 if (!moduleTowerMappingStream.is_open()) {
0092 throw cms::Exception("MissingDataFile") << "Cannot open HGCalTowerMapProducer moduleTowerMapping file\n";
0093 }
0094
0095 std::string line;
0096 std::getline(moduleTowerMappingStream, line);
0097 std::getline(moduleTowerMappingStream, line);
0098 std::stringstream ss(line);
0099 ss >> splitDivisorSilic_ >> splitDivisorScint_;
0100
0101
0102 std::getline(moduleTowerMappingStream, line);
0103 std::getline(moduleTowerMappingStream, line);
0104 const int minNumOfWordsPerRow = 5;
0105 const int numOfWordsPerTower = 3;
0106 for (std::string line; std::getline(moduleTowerMappingStream, line);) {
0107 int numOfWordsInThisRow = 0;
0108 for (std::string::size_type i = 0; i < line.size(); i++) {
0109 if (line[i] != ' ' && line[i + 1] == ' ') {
0110 numOfWordsInThisRow++;
0111 }
0112 }
0113 if (numOfWordsInThisRow < minNumOfWordsPerRow) {
0114 throw edm::Exception(edm::errors::Configuration, "Configuration")
0115 << "HGCalTriggerTowerGeometryHelper warning: Incorrect/incomplete values for module ID in the mapping "
0116 "file.\n"
0117 << "The incorrect line is:" << line << std::endl;
0118 }
0119 int subdet = 0;
0120 int layer = 0;
0121 int moduleU = 0;
0122 int moduleV = 0;
0123 int numTowers = 0;
0124 std::stringstream ss(line);
0125 ss >> subdet >> layer >> moduleU >> moduleV >> numTowers;
0126 if (numOfWordsInThisRow != (numTowers * numOfWordsPerTower + minNumOfWordsPerRow)) {
0127 throw edm::Exception(edm::errors::Configuration, "Configuration")
0128 << "HGCalTriggerTowerGeometryHelper warning: Incorrect/incomplete values for module ID or tower "
0129 "share/eta/phi in the mapping file.\n"
0130 << "The incorrect line is:" << line << std::endl;
0131 }
0132 unsigned packed_modID = packLayerSubdetWaferId(subdet, layer, moduleU, moduleV);
0133 std::vector<unsigned> towers;
0134 for (int itr_tower = 0; itr_tower < numTowers; itr_tower++) {
0135 int iEta_raw = 0;
0136 int iPhi_raw = 0;
0137 int towerShare = 0;
0138 ss >> iEta_raw >> iPhi_raw >> towerShare;
0139 int splitDivisor = (subdet == 2) ? splitDivisorScint_ : splitDivisorSilic_;
0140 if ((towerShare > splitDivisor) || (towerShare < 1)) {
0141 throw edm::Exception(edm::errors::Configuration, "Configuration")
0142 << "HGCalTriggerTowerGeometryHelper warning: invalid tower share in the mapping file.\n"
0143 << "Tower share must be a positive integer and less than splitDivisor. The incorrect values found for "
0144 "module ID:"
0145 << std::endl
0146 << "subdet=" << subdet << ", l=" << layer << ", u=" << moduleU << ", v=" << moduleV << std::endl;
0147 }
0148 towers.push_back(packTowerIDandShare(iEta_raw, iPhi_raw, towerShare));
0149 }
0150 modules_to_trigger_towers_[packed_modID] = towers;
0151 }
0152 moduleTowerMappingStream.close();
0153 }
0154 }
0155
0156 unsigned HGCalTriggerTowerGeometryHelper::packLayerSubdetWaferId(int subdet, int layer, int moduleU, int moduleV) const {
0157 unsigned packed_modID = 0;
0158 packed_modID |= ((subdet & HGCalTriggerModuleDetId::kHGCalTriggerSubdetMask)
0159 << HGCalTriggerModuleDetId::kHGCalTriggerSubdetOffset);
0160 packed_modID |= ((layer & HGCalTriggerModuleDetId::kHGCalLayerMask) << HGCalTriggerModuleDetId::kHGCalLayerOffset);
0161 packed_modID |=
0162 ((moduleU & HGCalTriggerModuleDetId::kHGCalModuleUMask) << HGCalTriggerModuleDetId::kHGCalModuleUOffset);
0163 packed_modID |=
0164 ((moduleV & HGCalTriggerModuleDetId::kHGCalModuleVMask) << HGCalTriggerModuleDetId::kHGCalModuleVOffset);
0165 return packed_modID;
0166 }
0167
0168 unsigned HGCalTriggerTowerGeometryHelper::packTowerIDandShare(int iEta_raw, int iPhi_raw, int towerShare) const {
0169 unsigned packed_towerIDandShare = 0;
0170 unsigned iEtaAbs = std::abs(iEta_raw);
0171 unsigned iEtaSign = std::signbit(iEta_raw);
0172 unsigned iPhiAbs = std::abs(iPhi_raw);
0173 unsigned iPhiSign = std::signbit(iPhi_raw);
0174 packed_towerIDandShare |= ((iEtaAbs & l1t::HGCalTowerID::coordMask) << l1t::HGCalTowerID::coord1Shift);
0175 packed_towerIDandShare |= ((iEtaSign & signMask) << sign1Shift);
0176 packed_towerIDandShare |= ((iPhiAbs & l1t::HGCalTowerID::coordMask) << l1t::HGCalTowerID::coord2Shift);
0177 packed_towerIDandShare |= ((iPhiSign & signMask) << sign2Shift);
0178 packed_towerIDandShare |= ((towerShare & towerShareMask) << towerShareShift);
0179 return packed_towerIDandShare;
0180 }
0181
0182 void HGCalTriggerTowerGeometryHelper::unpackTowerIDandShare(unsigned towerIDandShare,
0183 int& iEta_raw,
0184 int& iPhi_raw,
0185 int& towerShare) const {
0186
0187 iEta_raw = (towerIDandShare >> l1t::HGCalTowerID::coord1Shift) & l1t::HGCalTowerID::coordMask;
0188 unsigned iEtaSign = (towerIDandShare >> sign1Shift) & signMask;
0189 iEta_raw = (iEtaSign) ? -1 * iEta_raw : iEta_raw;
0190
0191 iPhi_raw = (towerIDandShare >> l1t::HGCalTowerID::coord2Shift) & l1t::HGCalTowerID::coordMask;
0192 unsigned iPhiSign = (towerIDandShare >> sign2Shift) & signMask;
0193 iPhi_raw = (iPhiSign) ? -1 * iPhi_raw : iPhi_raw;
0194
0195 towerShare = (towerIDandShare >> towerShareShift) & towerShareMask;
0196 }
0197
0198 int HGCalTriggerTowerGeometryHelper::moveToCorrectSector(int iPhi_raw, int sector) const {
0199 int iPhi = (iPhi_raw + sector * rotate120Deg_ + rotate180Deg_) % int(nBinsPhi_);
0200 return iPhi;
0201 }
0202
0203 void HGCalTriggerTowerGeometryHelper::reverseXaxis(int& iPhi) const {
0204 iPhi = reverseX_ - iPhi;
0205 iPhi = (int(nBinsPhi_) + iPhi) % int(nBinsPhi_);
0206 }
0207
0208 const std::vector<l1t::HGCalTowerCoord>& HGCalTriggerTowerGeometryHelper::getTowerCoordinates() const {
0209 return tower_coords_;
0210 }
0211
0212 unsigned short HGCalTriggerTowerGeometryHelper::getTriggerTowerFromEtaPhi(const float& eta, const float& phi) const {
0213 auto bin_eta_l = std::lower_bound(binsEta_.begin(), binsEta_.end(), fabs(eta));
0214 unsigned int bin_eta = 0;
0215
0216 if (bin_eta_l == binsEta_.end()) {
0217 if (fabs(eta) < minEta_) {
0218 bin_eta = 0;
0219 } else if (fabs(eta) >= maxEta_) {
0220 bin_eta = nBinsEta_;
0221 } else {
0222 edm::LogError("HGCalTriggerTowerGeometryHelper")
0223 << " did not manage to map eta " << eta << " to any Trigger Tower\n";
0224 }
0225 } else {
0226 bin_eta = bin_eta_l - binsEta_.begin() - 1;
0227 }
0228
0229 auto bin_phi_l = std::lower_bound(binsPhi_.begin(), binsPhi_.end(), phi);
0230 unsigned int bin_phi = 0;
0231 if (bin_phi_l == binsPhi_.end()) {
0232 if (phi < minPhi_) {
0233 bin_phi = nBinsPhi_;
0234 } else if (phi >= maxPhi_) {
0235 bin_phi = 0;
0236 } else {
0237 edm::LogError("HGCalTriggerTowerGeometryHelper")
0238 << " did not manage to map phi " << phi << " to any Trigger Tower\n";
0239 }
0240 } else {
0241 bin_phi = bin_phi_l - binsPhi_.begin() - 1;
0242 }
0243 int zside = eta < 0 ? -1 : 1;
0244 return l1t::HGCalTowerID(doNose_, zside, bin_eta, bin_phi).rawId();
0245 }
0246
0247 std::unordered_map<unsigned short, float> HGCalTriggerTowerGeometryHelper::getTriggerTower(
0248 const l1t::HGCalTriggerCell& thecell) const {
0249 std::unordered_map<unsigned short, float> towerIDandShares = {};
0250 unsigned int trigger_cell_id = thecell.detId();
0251
0252
0253
0254 auto tower_id_itr = cells_to_trigger_towers_.find(trigger_cell_id);
0255 if (tower_id_itr != cells_to_trigger_towers_.end()) {
0256 towerIDandShares.insert({tower_id_itr->second, 1.0});
0257 return towerIDandShares;
0258 }
0259 towerIDandShares.insert({getTriggerTowerFromEtaPhi(thecell.position().eta(), thecell.position().phi()), 1.0});
0260 return towerIDandShares;
0261 }
0262
0263 std::unordered_map<unsigned short, float> HGCalTriggerTowerGeometryHelper::getTriggerTower(
0264 const l1t::HGCalTriggerSums& thesum) const {
0265 std::unordered_map<unsigned short, float> towerIDandShares = {};
0266 if (!splitModuleSum_) {
0267 towerIDandShares.insert({getTriggerTowerFromEtaPhi(thesum.position().eta(), thesum.position().phi()), 1.0});
0268 return towerIDandShares;
0269 } else {
0270 HGCalTriggerModuleDetId detid(thesum.detId());
0271 int moduleU = detid.moduleU();
0272 int moduleV = detid.moduleV();
0273 int layer = detid.layer();
0274 int sector = detid.sector();
0275 int zside = detid.zside();
0276 int subdet = 0;
0277 int splitDivisor;
0278 if (detid.isHScintillator()) {
0279 subdet = 2;
0280 splitDivisor = splitDivisorScint_;
0281 } else if (detid.isEE()) {
0282 subdet = 0;
0283 splitDivisor = splitDivisorSilic_;
0284 } else if (detid.isHSilicon()) {
0285 subdet = 1;
0286 splitDivisor = splitDivisorSilic_;
0287 } else {
0288 towerIDandShares.insert({getTriggerTowerFromEtaPhi(thesum.position().eta(), thesum.position().phi()), 1.0});
0289 return towerIDandShares;
0290 }
0291
0292 unsigned packed_modID = packLayerSubdetWaferId(subdet, layer, moduleU, moduleV);
0293 auto module_id_itr = modules_to_trigger_towers_.find(packed_modID);
0294 if (module_id_itr != modules_to_trigger_towers_.end()) {
0295
0296 int iEta = -999;
0297 int iEta_raw = -999;
0298 int offsetEta = 2;
0299
0300 int iPhi = -999;
0301 int iPhi_raw = -999;
0302 int towerShare = -999;
0303 for (auto towerIDandShare : module_id_itr->second) {
0304 unpackTowerIDandShare(towerIDandShare, iEta_raw, iPhi_raw, towerShare);
0305 iEta = offsetEta + iEta_raw;
0306 iPhi = moveToCorrectSector(iPhi_raw, sector);
0307 if (zside == 1) {
0308 reverseXaxis(iPhi);
0309 }
0310 towerIDandShares.insert(
0311 {l1t::HGCalTowerID(doNose_, zside, iEta, iPhi).rawId(), double(towerShare) / splitDivisor});
0312 }
0313 return towerIDandShares;
0314 } else {
0315 towerIDandShares.insert({getTriggerTowerFromEtaPhi(thesum.position().eta(), thesum.position().phi()), 1.0});
0316 return towerIDandShares;
0317 }
0318 }
0319 }