Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-02-18 08:23:38

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   // group TCs per (r/z, phi) bins
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   // apply sorting and trunction in each (r/z, phi) bin
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 }