File indexing completed on 2024-04-06 12:20:42
0001 #include "L1Trigger/L1THGCal/interface/backend/HGCalShowerShape.h"
0002 #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h"
0003 #include "DataFormats/L1THGCal/interface/HGCalCluster.h"
0004 #include "DataFormats/Math/interface/deltaPhi.h"
0005
0006 #include <unordered_map>
0007 #include <numeric>
0008
0009 HGCalShowerShape::HGCalShowerShape(const edm::ParameterSet& conf)
0010 : threshold_(conf.getParameter<double>("shape_threshold")),
0011 distance_(conf.getParameter<double>("shape_distance")) {}
0012
0013
0014
0015 float HGCalShowerShape::meanX(const std::vector<pair<float, float>>& energy_X_tc) const {
0016 float Etot = 0;
0017 float X_sum = 0;
0018
0019 for (const auto& energy_X : energy_X_tc) {
0020 X_sum += energy_X.first * energy_X.second;
0021 Etot += energy_X.first;
0022 }
0023
0024 float X_mean = 0;
0025 if (Etot > 0)
0026 X_mean = X_sum / Etot;
0027 return X_mean;
0028 }
0029
0030 int HGCalShowerShape::firstLayer(const l1t::HGCalMulticluster& c3d) const {
0031 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0032
0033 int firstLayer = 999;
0034
0035 for (const auto& id_clu : clustersPtrs) {
0036 if (!pass(*id_clu.second, c3d))
0037 continue;
0038 int layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0039 if (layer < firstLayer)
0040 firstLayer = layer;
0041 }
0042
0043 return firstLayer;
0044 }
0045
0046 int HGCalShowerShape::maxLayer(const l1t::HGCalMulticluster& c3d) const {
0047 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0048 std::unordered_map<int, float> layers_pt;
0049 float max_pt = 0.;
0050 int max_layer = 0;
0051 for (const auto& id_cluster : clustersPtrs) {
0052 if (!pass(*id_cluster.second, c3d))
0053 continue;
0054 unsigned layer = triggerTools_.layerWithOffset(id_cluster.second->detId());
0055 auto itr_insert = layers_pt.emplace(layer, 0.);
0056 itr_insert.first->second += id_cluster.second->pt();
0057 if (itr_insert.first->second > max_pt) {
0058 max_pt = itr_insert.first->second;
0059 max_layer = layer;
0060 }
0061 }
0062 return max_layer;
0063 }
0064
0065 int HGCalShowerShape::lastLayer(const l1t::HGCalMulticluster& c3d) const {
0066 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0067
0068 int lastLayer = -999;
0069
0070 for (const auto& id_clu : clustersPtrs) {
0071 if (!pass(*id_clu.second, c3d))
0072 continue;
0073 int layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0074 if (layer > lastLayer)
0075 lastLayer = layer;
0076 }
0077
0078 return lastLayer;
0079 }
0080
0081 int HGCalShowerShape::coreShowerLength(const l1t::HGCalMulticluster& c3d,
0082 const HGCalTriggerGeometryBase& triggerGeometry) const {
0083 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0084 unsigned nlayers = triggerTools_.layers(ForwardSubdetector::ForwardEmpty);
0085 std::vector<bool> layers(nlayers);
0086 for (const auto& id_cluster : clustersPtrs) {
0087 if (!pass(*id_cluster.second, c3d))
0088 continue;
0089 unsigned layer = triggerGeometry.triggerLayer(id_cluster.second->detId());
0090 if (triggerTools_.isNose(id_cluster.second->detId()))
0091 nlayers = triggerTools_.layers(ForwardSubdetector::HFNose);
0092 else {
0093 nlayers = triggerTools_.layers(ForwardSubdetector::ForwardEmpty);
0094 }
0095 if (layer == 0 || layer > nlayers)
0096 continue;
0097 layers[layer - 1] = true;
0098 }
0099 int length = 0;
0100 int maxlength = 0;
0101 for (bool layer : layers) {
0102 if (layer)
0103 length++;
0104 else
0105 length = 0;
0106 if (length > maxlength)
0107 maxlength = length;
0108 }
0109 return maxlength;
0110 }
0111
0112 float HGCalShowerShape::percentileLayer(const l1t::HGCalMulticluster& c3d,
0113 const HGCalTriggerGeometryBase& triggerGeometry,
0114 float quantile) const {
0115 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0116 unsigned nlayers = triggerTools_.layers(ForwardSubdetector::ForwardEmpty);
0117 std::vector<double> layers(nlayers, 0);
0118 for (const auto& id_clu : clustersPtrs) {
0119 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0120
0121 for (const auto& id_tc : triggerCells) {
0122 if (!pass(*id_tc.second, c3d))
0123 continue;
0124 unsigned layer = triggerGeometry.triggerLayer(id_tc.second->detId());
0125 if (triggerTools_.isNose(id_tc.second->detId()))
0126 nlayers = triggerTools_.layers(ForwardSubdetector::HFNose);
0127 else {
0128 nlayers = triggerTools_.layers(ForwardSubdetector::ForwardEmpty);
0129 }
0130 if (layer == 0 || layer > nlayers)
0131 continue;
0132 layers[layer - 1] += id_tc.second->pt();
0133 }
0134 }
0135 std::partial_sum(layers.begin(), layers.end(), layers.begin());
0136 double pt_threshold = layers.back() * quantile;
0137 unsigned percentile = 0;
0138 for (double pt : layers) {
0139 if (pt > pt_threshold) {
0140 break;
0141 }
0142 percentile++;
0143 }
0144
0145 double pt0 = (percentile > 0 ? layers[percentile - 1] : 0.);
0146 double pt1 = (percentile < layers.size() ? layers[percentile] : layers.back());
0147 return percentile + (pt1 - pt0 > 0. ? (pt_threshold - pt0) / (pt1 - pt0) : 0.);
0148 }
0149
0150 float HGCalShowerShape::percentileTriggerCells(const l1t::HGCalMulticluster& c3d, float quantile) const {
0151 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0152 std::set<double> ordered_tcs;
0153 double pt_sum = 0.;
0154 for (const auto& id_clu : clustersPtrs) {
0155 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0156
0157 for (const auto& id_tc : triggerCells) {
0158 if (!pass(*id_tc.second, c3d))
0159 continue;
0160 ordered_tcs.emplace(id_tc.second->pt());
0161 pt_sum += id_tc.second->pt();
0162 }
0163 }
0164 double pt_threshold = pt_sum * quantile;
0165 double partial_sum = 0.;
0166 double partial_sum_prev = 0.;
0167 int ntc = 0;
0168 for (auto itr = ordered_tcs.rbegin(); itr != ordered_tcs.rend(); ++itr) {
0169 partial_sum_prev = partial_sum;
0170 partial_sum += *itr;
0171 ntc++;
0172 if (partial_sum > pt_threshold) {
0173 break;
0174 }
0175 }
0176
0177 return ntc - 1 +
0178 (partial_sum - partial_sum_prev > 0. ? (pt_threshold - partial_sum_prev) / (partial_sum - partial_sum_prev)
0179 : 0.);
0180 }
0181
0182 float HGCalShowerShape::sigmaEtaEtaTot(const l1t::HGCalMulticluster& c3d) const { return sqrt(varEtaEta(c3d)); }
0183
0184 float HGCalShowerShape::varEtaEta(const l1t::HGCalMulticluster& c3d) const {
0185 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0186
0187 std::vector<std::pair<float, float>> tc_energy_eta;
0188
0189 for (const auto& id_clu : clustersPtrs) {
0190 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0191
0192 for (const auto& id_tc : triggerCells) {
0193 if (!pass(*id_tc.second, c3d))
0194 continue;
0195 tc_energy_eta.emplace_back(std::make_pair(id_tc.second->energy(), id_tc.second->eta()));
0196 }
0197 }
0198
0199 float varee = varXX(tc_energy_eta, c3d.eta());
0200
0201 return varee;
0202 }
0203
0204 float HGCalShowerShape::sigmaPhiPhiTot(const l1t::HGCalMulticluster& c3d) const { return sqrt(varPhiPhi(c3d)); }
0205
0206 float HGCalShowerShape::varPhiPhi(const l1t::HGCalMulticluster& c3d) const {
0207 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0208
0209 std::vector<std::pair<float, float>> tc_energy_phi;
0210
0211 for (const auto& id_clu : clustersPtrs) {
0212 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0213
0214 for (const auto& id_tc : triggerCells) {
0215 if (!pass(*id_tc.second, c3d))
0216 continue;
0217 tc_energy_phi.emplace_back(std::make_pair(id_tc.second->energy(), id_tc.second->phi()));
0218 }
0219 }
0220
0221 float varphiphi = varPhiPhi(tc_energy_phi, c3d.phi());
0222
0223 return varphiphi;
0224 }
0225
0226 float HGCalShowerShape::sigmaRRTot(const l1t::HGCalMulticluster& c3d) const { return sqrt(varRR(c3d)); }
0227
0228 float HGCalShowerShape::varRR(const l1t::HGCalMulticluster& c3d) const {
0229 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0230
0231 std::vector<std::pair<float, float>> tc_energy_r;
0232
0233 for (const auto& id_clu : clustersPtrs) {
0234 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0235
0236 for (const auto& id_tc : triggerCells) {
0237 if (!pass(*id_tc.second, c3d))
0238 continue;
0239 float r = (id_tc.second->position().z() != 0.
0240 ? std::sqrt(pow(id_tc.second->position().x(), 2) + pow(id_tc.second->position().y(), 2)) /
0241 std::abs(id_tc.second->position().z())
0242 : 0.);
0243 tc_energy_r.emplace_back(std::make_pair(id_tc.second->energy(), r));
0244 }
0245 }
0246
0247 float r_mean = meanX(tc_energy_r);
0248 float vrr = varXX(tc_energy_r, r_mean);
0249
0250 return vrr;
0251 }
0252
0253 float HGCalShowerShape::sigmaEtaEtaMax(const l1t::HGCalMulticluster& c3d) const {
0254 std::unordered_map<int, std::vector<std::pair<float, float>>> tc_layer_energy_eta;
0255 std::unordered_map<int, LorentzVector> layer_LV;
0256
0257 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0258
0259 for (const auto& id_clu : clustersPtrs) {
0260 unsigned layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0261
0262 layer_LV[layer] += id_clu.second->p4();
0263
0264 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0265
0266 for (const auto& id_tc : triggerCells) {
0267 if (!pass(*id_tc.second, c3d))
0268 continue;
0269 tc_layer_energy_eta[layer].emplace_back(std::make_pair(id_tc.second->energy(), id_tc.second->eta()));
0270 }
0271 }
0272
0273 float SigmaEtaEtaMax = 0;
0274
0275 for (auto& tc_iter : tc_layer_energy_eta) {
0276 const std::vector<std::pair<float, float>>& energy_eta_layer = tc_iter.second;
0277 const LorentzVector& LV_layer = layer_LV[tc_iter.first];
0278 float SigmaEtaEtaLayer = sigmaXX(energy_eta_layer, LV_layer.eta());
0279 if (SigmaEtaEtaLayer > SigmaEtaEtaMax)
0280 SigmaEtaEtaMax = SigmaEtaEtaLayer;
0281 }
0282
0283 return SigmaEtaEtaMax;
0284 }
0285
0286 float HGCalShowerShape::sigmaPhiPhiMax(const l1t::HGCalMulticluster& c3d) const {
0287 std::unordered_map<int, std::vector<std::pair<float, float>>> tc_layer_energy_phi;
0288 std::unordered_map<int, LorentzVector> layer_LV;
0289
0290 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0291
0292 for (const auto& id_clu : clustersPtrs) {
0293 unsigned layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0294
0295 layer_LV[layer] += id_clu.second->p4();
0296
0297 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0298
0299 for (const auto& id_tc : triggerCells) {
0300 if (!pass(*id_tc.second, c3d))
0301 continue;
0302 tc_layer_energy_phi[layer].emplace_back(std::make_pair(id_tc.second->energy(), id_tc.second->phi()));
0303 }
0304 }
0305
0306 float SigmaPhiPhiMax = 0;
0307
0308 for (auto& tc_iter : tc_layer_energy_phi) {
0309 const std::vector<std::pair<float, float>>& energy_phi_layer = tc_iter.second;
0310 const LorentzVector& LV_layer = layer_LV[tc_iter.first];
0311 float SigmaPhiPhiLayer = sigmaPhiPhi(energy_phi_layer, LV_layer.phi());
0312 if (SigmaPhiPhiLayer > SigmaPhiPhiMax)
0313 SigmaPhiPhiMax = SigmaPhiPhiLayer;
0314 }
0315
0316 return SigmaPhiPhiMax;
0317 }
0318
0319 float HGCalShowerShape::sigmaRRMax(const l1t::HGCalMulticluster& c3d) const {
0320 std::unordered_map<int, std::vector<std::pair<float, float>>> tc_layer_energy_r;
0321
0322 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0323
0324 for (const auto& id_clu : clustersPtrs) {
0325 unsigned layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0326
0327 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0328
0329 for (const auto& id_tc : triggerCells) {
0330 if (!pass(*id_tc.second, c3d))
0331 continue;
0332 float r = (id_tc.second->position().z() != 0.
0333 ? std::sqrt(pow(id_tc.second->position().x(), 2) + pow(id_tc.second->position().y(), 2)) /
0334 std::abs(id_tc.second->position().z())
0335 : 0.);
0336 tc_layer_energy_r[layer].emplace_back(std::make_pair(id_tc.second->energy(), r));
0337 }
0338 }
0339
0340 float SigmaRRMax = 0;
0341
0342 for (auto& tc_iter : tc_layer_energy_r) {
0343 const std::vector<std::pair<float, float>>& energy_r_layer = tc_iter.second;
0344 float r_mean_layer = meanX(energy_r_layer);
0345 float SigmaRRLayer = sigmaXX(energy_r_layer, r_mean_layer);
0346 if (SigmaRRLayer > SigmaRRMax)
0347 SigmaRRMax = SigmaRRLayer;
0348 }
0349
0350 return SigmaRRMax;
0351 }
0352
0353 float HGCalShowerShape::sigmaRRMean(const l1t::HGCalMulticluster& c3d, float radius) const {
0354 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0355
0356 std::unordered_map<int, std::vector<edm::Ptr<l1t::HGCalTriggerCell>>> layers_tcs;
0357 for (const auto& id_clu : clustersPtrs) {
0358 unsigned layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0359 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0360 for (const auto& id_tc : triggerCells) {
0361 if (!pass(*id_tc.second, c3d))
0362 continue;
0363 layers_tcs[layer].emplace_back(id_tc.second);
0364 }
0365 }
0366
0367
0368 std::unordered_map<int, std::vector<std::pair<float, float>>> tc_layers_energy_r;
0369 for (const auto& layer_tcs : layers_tcs) {
0370 int layer = layer_tcs.first;
0371 edm::Ptr<l1t::HGCalTriggerCell> max_tc = layer_tcs.second.front();
0372 for (const auto& tc : layer_tcs.second) {
0373 if (tc->energy() > max_tc->energy())
0374 max_tc = tc;
0375 }
0376 for (const auto& tc : layer_tcs.second) {
0377 double dx = tc->position().x() - max_tc->position().x();
0378 double dy = tc->position().y() - max_tc->position().y();
0379 double distance_to_max = std::sqrt(dx * dx + dy * dy);
0380 if (distance_to_max < radius) {
0381 float r = (tc->position().z() != 0.
0382 ? std::sqrt(tc->position().x() * tc->position().x() + tc->position().y() * tc->position().y()) /
0383 std::abs(tc->position().z())
0384 : 0.);
0385 tc_layers_energy_r[layer].emplace_back(std::make_pair(tc->energy(), r));
0386 }
0387 }
0388 }
0389
0390
0391 std::vector<std::pair<float, float>> layers_energy_srr2;
0392 for (const auto& layer_energy_r : tc_layers_energy_r) {
0393 const auto& energies_r = layer_energy_r.second;
0394 float r_mean_layer = meanX(energies_r);
0395 float srr = sigmaXX(energies_r, r_mean_layer);
0396 double energy_sum = 0.;
0397 for (const auto& energy_r : energies_r) {
0398 energy_sum += energy_r.first;
0399 }
0400 layers_energy_srr2.emplace_back(std::make_pair(energy_sum, srr * srr));
0401 }
0402
0403 float srr2_mean = meanX(layers_energy_srr2);
0404 return std::sqrt(srr2_mean);
0405 }
0406
0407 float HGCalShowerShape::eMax(const l1t::HGCalMulticluster& c3d) const {
0408 std::unordered_map<int, float> layer_energy;
0409
0410 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0411
0412 for (const auto& id_clu : clustersPtrs) {
0413 if (!pass(*id_clu.second, c3d))
0414 continue;
0415 unsigned layer = triggerTools_.layerWithOffset(id_clu.second->detId());
0416 layer_energy[layer] += id_clu.second->energy();
0417 }
0418
0419 float EMax = 0;
0420
0421 for (const auto& layer : layer_energy) {
0422 if (layer.second > EMax)
0423 EMax = layer.second;
0424 }
0425
0426 return EMax;
0427 }
0428
0429 float HGCalShowerShape::meanZ(const l1t::HGCalMulticluster& c3d) const {
0430 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0431
0432 std::vector<std::pair<float, float>> tc_energy_z;
0433
0434 for (const auto& id_clu : clustersPtrs) {
0435 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0436
0437 for (const auto& id_tc : triggerCells) {
0438 if (!pass(*id_tc.second, c3d))
0439 continue;
0440 tc_energy_z.emplace_back(id_tc.second->energy(), id_tc.second->position().z());
0441 }
0442 }
0443
0444 return meanX(tc_energy_z);
0445 }
0446
0447 float HGCalShowerShape::sigmaZZ(const l1t::HGCalMulticluster& c3d) const { return sqrt(varZZ(c3d)); }
0448 float HGCalShowerShape::varZZ(const l1t::HGCalMulticluster& c3d) const {
0449 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0450
0451 std::vector<std::pair<float, float>> tc_energy_z;
0452
0453 for (const auto& id_clu : clustersPtrs) {
0454 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0455
0456 for (const auto& id_tc : triggerCells) {
0457 if (!pass(*id_tc.second, c3d))
0458 continue;
0459 tc_energy_z.emplace_back(std::make_pair(id_tc.second->energy(), id_tc.second->position().z()));
0460 }
0461 }
0462
0463 float z_mean = meanX(tc_energy_z);
0464 float varzz = varXX(tc_energy_z, z_mean);
0465
0466 return varzz;
0467 }
0468 float HGCalShowerShape::sigmaEtaEtaTot(const l1t::HGCalCluster& c2d) const {
0469 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& cellsPtrs = c2d.constituents();
0470
0471 std::vector<std::pair<float, float>> tc_energy_eta;
0472
0473 for (const auto& id_cell : cellsPtrs) {
0474 if (!pass(*id_cell.second, c2d))
0475 continue;
0476 tc_energy_eta.emplace_back(std::make_pair(id_cell.second->energy(), id_cell.second->eta()));
0477 }
0478
0479 float See = sigmaXX(tc_energy_eta, c2d.eta());
0480
0481 return See;
0482 }
0483
0484 float HGCalShowerShape::sigmaPhiPhiTot(const l1t::HGCalCluster& c2d) const {
0485 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& cellsPtrs = c2d.constituents();
0486
0487 std::vector<std::pair<float, float>> tc_energy_phi;
0488
0489 for (const auto& id_cell : cellsPtrs) {
0490 if (!pass(*id_cell.second, c2d))
0491 continue;
0492 tc_energy_phi.emplace_back(std::make_pair(id_cell.second->energy(), id_cell.second->phi()));
0493 }
0494
0495 float Spp = sigmaPhiPhi(tc_energy_phi, c2d.phi());
0496
0497 return Spp;
0498 }
0499
0500 float HGCalShowerShape::sigmaRRTot(const l1t::HGCalCluster& c2d) const {
0501 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& cellsPtrs = c2d.constituents();
0502
0503 std::vector<std::pair<float, float>> tc_energy_r;
0504
0505 for (const auto& id_cell : cellsPtrs) {
0506 if (!pass(*id_cell.second, c2d))
0507 continue;
0508 float r = (id_cell.second->position().z() != 0.
0509 ? std::sqrt(pow(id_cell.second->position().x(), 2) + pow(id_cell.second->position().y(), 2)) /
0510 std::abs(id_cell.second->position().z())
0511 : 0.);
0512 tc_energy_r.emplace_back(std::make_pair(id_cell.second->energy(), r));
0513 }
0514
0515 float r_mean = meanX(tc_energy_r);
0516 float Srr = sigmaXX(tc_energy_r, r_mean);
0517
0518 return Srr;
0519 }
0520
0521 float HGCalShowerShape::sumLayers(const l1t::HGCalMulticluster& c3d, int start, int end) const {
0522 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0523 unsigned nlayers = triggerTools_.getTriggerGeometry()->lastTriggerLayer();
0524 std::vector<double> layers(nlayers, 0);
0525 for (const auto& id_clu : clustersPtrs) {
0526 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0527
0528 for (const auto& id_tc : triggerCells) {
0529 if (!pass(*id_tc.second, c3d))
0530 continue;
0531 unsigned layer = triggerTools_.triggerLayer(id_tc.second->detId());
0532 if (layer == 0 || layer > nlayers)
0533 continue;
0534 layers[layer - 1] += id_tc.second->pt();
0535 }
0536 }
0537 double sum_pt = 0;
0538 for (int i = start - 1; i <= end - 1; i++) {
0539 sum_pt += layers[i];
0540 }
0541 double tot = 0;
0542 for (unsigned i = 0; i < layers.size(); ++i) {
0543 tot += layers[i];
0544 }
0545 float frac = 0;
0546 if (tot > 0) {
0547 frac = sum_pt / tot;
0548 }
0549 return frac;
0550 }
0551
0552 int HGCalShowerShape::bitmap(const l1t::HGCalMulticluster& c3d, int start, int end, float threshold) const {
0553 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalCluster>>& clustersPtrs = c3d.constituents();
0554 unsigned nlayers = triggerTools_.getTriggerGeometry()->lastTriggerLayer();
0555 std::vector<double> layers(nlayers, 0);
0556 for (const auto& id_clu : clustersPtrs) {
0557 const std::unordered_map<uint32_t, edm::Ptr<l1t::HGCalTriggerCell>>& triggerCells = id_clu.second->constituents();
0558
0559 for (const auto& id_tc : triggerCells) {
0560 if (!pass(*id_tc.second, c3d))
0561 continue;
0562 unsigned layer = triggerTools_.triggerLayer(id_tc.second->detId());
0563 if (layer == 0 || layer > nlayers)
0564 continue;
0565 layers[layer - 1] += id_tc.second->pt();
0566 }
0567 }
0568 uint32_t bitmap = 0;
0569 const int bitmap_size = 32;
0570 if (start == 0) {
0571 edm::LogWarning("DataNotFound") << "Trying to read layer 0 that doesn't exist, defaulted start to layer 1";
0572 start = 1;
0573 }
0574 if ((end - start) + 1 > bitmap_size) {
0575 edm::LogWarning("TooMuchData") << " Specified bounds cannot fit into bitmap size, defaulting to 0.";
0576 } else {
0577 for (int i = start; i <= end; i++) {
0578 bitmap += (layers[i - 1] > threshold) << (end - (i));
0579 }
0580 }
0581 return bitmap;
0582 }
0583
0584 void HGCalShowerShape::fillShapes(l1t::HGCalMulticluster& c3d, const HGCalTriggerGeometryBase& triggerGeometry) const {
0585 unsigned hcal_offset = triggerTools_.layers(ForwardSubdetector::HGCEE) / 2;
0586 unsigned lastlayer = triggerGeometry.lastTriggerLayer();
0587 const unsigned showermaxlayer = 7;
0588 c3d.setShowerLength(showerLength(c3d));
0589 c3d.setCoreShowerLength(coreShowerLength(c3d, triggerGeometry));
0590 c3d.setFirstLayer(firstLayer(c3d));
0591 c3d.setMaxLayer(maxLayer(c3d));
0592 c3d.setSigmaEtaEtaTot(sigmaEtaEtaTot(c3d));
0593 c3d.setSigmaEtaEtaMax(sigmaEtaEtaMax(c3d));
0594 c3d.setVarEtaEta(varEtaEta(c3d));
0595 c3d.setSigmaPhiPhiTot(sigmaPhiPhiTot(c3d));
0596 c3d.setSigmaPhiPhiMax(sigmaPhiPhiMax(c3d));
0597 c3d.setVarPhiPhi(varPhiPhi(c3d));
0598 c3d.setSigmaZZ(sigmaZZ(c3d));
0599 c3d.setVarZZ(varZZ(c3d));
0600 c3d.setSigmaRRTot(sigmaRRTot(c3d));
0601 c3d.setVarRR(varRR(c3d));
0602 c3d.setSigmaRRMax(sigmaRRMax(c3d));
0603 c3d.setSigmaRRMean(sigmaRRMean(c3d));
0604 c3d.setEMax(eMax(c3d));
0605 c3d.setZBarycenter(meanZ(c3d));
0606 c3d.setLayer10percent(percentileLayer(c3d, triggerGeometry, 0.10));
0607 c3d.setLayer50percent(percentileLayer(c3d, triggerGeometry, 0.50));
0608 c3d.setLayer90percent(percentileLayer(c3d, triggerGeometry, 0.90));
0609 c3d.setTriggerCells67percent(percentileTriggerCells(c3d, 0.67));
0610 c3d.setTriggerCells90percent(percentileTriggerCells(c3d, 0.90));
0611 c3d.setFirst1layers(sumLayers(c3d, 1, 1));
0612 c3d.setFirst3layers(sumLayers(c3d, 1, 3));
0613 c3d.setFirst5layers(sumLayers(c3d, 1, 5));
0614 c3d.setFirstHcal1layers(sumLayers(c3d, hcal_offset, hcal_offset));
0615 c3d.setFirstHcal3layers(sumLayers(c3d, hcal_offset, hcal_offset + 2));
0616 c3d.setFirstHcal5layers(sumLayers(c3d, hcal_offset, hcal_offset + 4));
0617 c3d.setLast1layers(sumLayers(c3d, lastlayer, lastlayer));
0618 c3d.setLast3layers(sumLayers(c3d, lastlayer - 2, lastlayer));
0619 c3d.setLast5layers(sumLayers(c3d, lastlayer - 4, lastlayer));
0620 c3d.setEmax1layers(sumLayers(c3d, showermaxlayer, showermaxlayer));
0621 c3d.setEmax3layers(sumLayers(c3d, showermaxlayer - 1, showermaxlayer + 1));
0622 c3d.setEmax5layers(sumLayers(c3d, showermaxlayer - 2, showermaxlayer + 2));
0623 c3d.setEot(sumLayers(c3d, 1, hcal_offset));
0624 c3d.setEbm0(bitmap(c3d, 1, hcal_offset, 0));
0625 c3d.setEbm1(bitmap(c3d, 1, hcal_offset, 1));
0626 c3d.setHbm(bitmap(c3d, hcal_offset, lastlayer, 0));
0627 }