File indexing completed on 2024-04-06 12:20:42
0001 #include "L1Trigger/L1THGCal/interface/backend/HGCalStage1TruncationImpl.h"
0002 #include "DataFormats/ForwardDetId/interface/HGCalTriggerBackendDetId.h"
0003 #include <cmath>
0004
0005 HGCalStage1TruncationImpl::HGCalStage1TruncationImpl(const edm::ParameterSet& conf)
0006 : do_truncate_(conf.getParameter<bool>("doTruncation")),
0007 roz_min_(conf.getParameter<double>("rozMin")),
0008 roz_max_(conf.getParameter<double>("rozMax")),
0009 roz_bins_(conf.getParameter<unsigned>("rozBins")),
0010 max_tcs_per_bin_(conf.getParameter<std::vector<unsigned>>("maxTcsPerBin")),
0011 phi_edges_(conf.getParameter<std::vector<double>>("phiSectorEdges")) {
0012 if (max_tcs_per_bin_.size() != roz_bins_)
0013 throw cms::Exception("HGCalStage1TruncationImpl::BadConfig") << "Inconsistent sizes of maxTcsPerBin and rozBins";
0014 if (phi_edges_.size() != roz_bins_)
0015 throw cms::Exception("HGCalStage1TruncationImpl::BadConfig") << "Inconsistent sizes of phiSectorEdges and rozBins";
0016
0017 constexpr double margin = 1.001;
0018 roz_bin_size_ = (roz_bins_ > 0 ? (roz_max_ - roz_min_) * margin / double(roz_bins_) : 0.);
0019 }
0020
0021 void HGCalStage1TruncationImpl::run(uint32_t fpga_id,
0022 const std::vector<edm::Ptr<l1t::HGCalTriggerCell>>& tcs_in,
0023 std::vector<edm::Ptr<l1t::HGCalTriggerCell>>& tcs_out) {
0024 unsigned sector120 = HGCalTriggerBackendDetId(fpga_id).sector();
0025 std::unordered_map<unsigned, std::vector<edm::Ptr<l1t::HGCalTriggerCell>>> tcs_per_bin;
0026
0027
0028 for (const auto& tc : tcs_in) {
0029 const GlobalPoint& position = tc->position();
0030 double x = position.x();
0031 double y = position.y();
0032 double z = position.z();
0033 unsigned roverzbin = 0;
0034 if (roz_bin_size_ > 0.) {
0035 double roverz = std::sqrt(x * x + y * y) / std::abs(z) - roz_min_;
0036 roverz = std::clamp(roverz, 0., roz_max_ - roz_min_);
0037 roverzbin = unsigned(roverz / roz_bin_size_);
0038 }
0039 double phi = rotatedphi(x, y, z, sector120);
0040 unsigned phibin = phiBin(roverzbin, phi);
0041 unsigned packed_bin = packBin(roverzbin, phibin);
0042
0043 tcs_per_bin[packed_bin].push_back(tc);
0044 }
0045
0046 for (auto& bin_tcs : tcs_per_bin) {
0047 std::sort(bin_tcs.second.begin(),
0048 bin_tcs.second.end(),
0049 [](const edm::Ptr<l1t::HGCalTriggerCell>& a, const edm::Ptr<l1t::HGCalTriggerCell>& b) -> bool {
0050 return a->mipPt() > b->mipPt();
0051 });
0052
0053 unsigned roverzbin = 0;
0054 unsigned phibin = 0;
0055 unpackBin(bin_tcs.first, roverzbin, phibin);
0056 if (roverzbin >= max_tcs_per_bin_.size())
0057 throw cms::Exception("HGCalStage1TruncationImpl::OutOfRange")
0058 << "roverzbin index " << roverzbin << "out of range";
0059 unsigned max_tc = max_tcs_per_bin_[roverzbin];
0060 if (do_truncate_ && bin_tcs.second.size() > max_tc) {
0061 bin_tcs.second.resize(max_tc);
0062 }
0063 for (const auto& tc : bin_tcs.second) {
0064 tcs_out.push_back(tc);
0065 }
0066 }
0067 }
0068
0069 unsigned HGCalStage1TruncationImpl::packBin(unsigned roverzbin, unsigned phibin) const {
0070 unsigned packed_bin = 0;
0071 packed_bin |= ((roverzbin & mask_roz_) << offset_roz_);
0072 packed_bin |= (phibin & mask_phi_);
0073 return packed_bin;
0074 }
0075
0076 void HGCalStage1TruncationImpl::unpackBin(unsigned packedbin, unsigned& roverzbin, unsigned& phibin) const {
0077 roverzbin = ((packedbin >> offset_roz_) & mask_roz_);
0078 phibin = (packedbin & mask_phi_);
0079 }
0080
0081 unsigned HGCalStage1TruncationImpl::phiBin(unsigned roverzbin, double phi) const {
0082 unsigned phi_bin = 0;
0083 if (roverzbin >= phi_edges_.size())
0084 throw cms::Exception("HGCalStage1TruncationImpl::OutOfRange") << "roverzbin index " << roverzbin << "out of range";
0085 double phi_edge = phi_edges_[roverzbin];
0086 if (phi > phi_edge)
0087 phi_bin = 1;
0088 return phi_bin;
0089 }
0090
0091 double HGCalStage1TruncationImpl::rotatedphi(double x, double y, double z, int sector) const {
0092 if (z > 0)
0093 x = -x;
0094 double phi = std::atan2(y, x);
0095
0096 if (sector == 1) {
0097 if (phi < M_PI and phi > 0)
0098 phi = phi - (2. * M_PI / 3.);
0099 else
0100 phi = phi + (4. * M_PI / 3.);
0101 } else if (sector == 2) {
0102 phi = phi + (2. * M_PI / 3.);
0103 }
0104 return phi;
0105 }