3 #include <Math/Vector3D.h> 13 std::shared_ptr<const hgcal::RecHitTools> recHitTools,
14 std::shared_ptr<
const std::unordered_map<uint32_t, const reco::PFRecHit *>> pfRecHitPtrMap,
15 const std::vector<std::pair<DetId, float>> &hitsAndFracs,
16 const double rawEnergy,
18 const double minHitET,
22 : recHitTools_(recHitTools),
23 pfRecHitPtrMap_(pfRecHitPtrMap),
24 rawEnergy_(rawEnergy),
27 minHitET2_(minHitET * minHitET),
29 maxLayer_(maxLayer <= 0 ? recHitTools_->lastLayerEE() : maxLayer),
30 nLayer_(maxLayer_ - minLayer_ + 1),
42 if (hitsAndFracs_.empty()) {
46 if (rawEnergy_ <= 0.0) {
48 <<
"Encountered negative or zero energy for HGCal R-variable denominator: " << rawEnergy_ << std::endl;
51 double cylinderR2 = cylinderR * cylinderR;
55 auto hitEnergyIter = useFractions ? hitEnergiesWithFracs_.begin() : hitEnergies_.begin();
59 for (
const auto &hnf : hitsAndFracs_) {
62 DetId hitId = hnf.first;
69 auto distXYZ = hitXYZ - layerCentroids_[hitLayer];
71 double r2 = distXYZ.x() * distXYZ.x() + distXYZ.y() * distXYZ.y();
75 if (
std::sqrt(
r2) > cylinderR + getCellSize(hitId)) {
80 else if (
r2 > cylinderR2) {
84 rVar += *hitEnergyIter;
93 bool useFractions)
const {
94 if (hitsAndFracs_.empty()) {
98 double cylinderR2 = cylinderR * cylinderR;
100 TMatrixD covMat(3, 3);
112 auto hitEnergyIter = useFractions ? hitEnergiesWithFracs_.begin() : hitEnergies_.begin();
117 for (
const auto &hnf : hitsAndFracs_) {
120 DetId hitId = hnf.first;
129 double r2 = radXYZ.x() * radXYZ.x() + radXYZ.y() * radXYZ.y();
131 if (
r2 > cylinderR2) {
137 double weight = *hitEnergyIter;
140 dxdx +=
weight * dXYZ.x() * dXYZ.x();
141 dydy +=
weight * dXYZ.y() * dXYZ.y();
142 dzdz +=
weight * dXYZ.z() * dXYZ.z();
144 dxdy +=
weight * dXYZ.x() * dXYZ.y();
146 dzdx +=
weight * dXYZ.z() * dXYZ.x();
151 if (!totalW || nHit < 2) {
167 covMat(0, 1) = covMat(1, 0) = dxdy;
168 covMat(0, 2) = covMat(2, 0) = dzdx;
169 covMat(1, 2) = covMat(2, 1) =
dydz;
177 TMatrixD eigVecMat(3, 3);
179 eigVecMat = covMat.EigenVectors(eigVals);
199 bool useFractions)
const {
200 std::vector<double> sortedEnergies(nrHits, 0.);
201 const auto &
hits = useFractions ? hitEnergiesWithFracs_ : hitEnergies_;
202 std::partial_sort_copy(
203 hits.begin(),
hits.end(), sortedEnergies.begin(), sortedEnergies.end(), std::greater<double>());
204 return sortedEnergies;
208 const std::vector<std::pair<DetId, float>> &hitsAndFracs) {
209 hitsAndFracs_.clear();
210 hitEnergies_.clear();
211 hitEnergiesWithFracs_.clear();
213 for (
const auto &hnf : hitsAndFracs) {
214 DetId hitId = hnf.first;
215 float hitEfrac = hnf.second;
219 if (hitLayer > nLayer_) {
223 if (hitId.
det() != subDet_) {
233 if (
recHit.energy() < minHitE_) {
237 if (
recHit.pt2() < minHitET2_) {
242 hitsAndFracs_.push_back(hnf);
243 hitEnergies_.push_back(
recHit.energy());
244 hitEnergiesWithFracs_.push_back(
recHit.energy() * hitEfrac);
249 layerEnergies_.clear();
250 layerEnergies_.resize(nLayer_);
252 layerCentroids_.clear();
253 layerCentroids_.resize(nLayer_);
255 centroid_.SetXYZ(0, 0, 0);
261 for (
const auto &hnf : hitsAndFracs_) {
264 DetId hitId = hnf.first;
266 double weight = hitEnergies_[iHit];
272 centroid_ +=
weight * hitXYZ;
276 layerEnergies_[hitLayer] +=
weight;
277 layerCentroids_[hitLayer] +=
weight * hitXYZ;
282 for (
auto ¢roid : layerCentroids_) {
285 if (layerEnergies_[iLayer]) {
286 centroid /= layerEnergies_[iLayer];
300 : recHitTools_(
std::make_shared<
hgcal::RecHitTools>()),
301 pfRecHitPtrMap_(
std::make_shared<
std::unordered_map<uint32_t,
const reco::PFRecHit *>>()) {
319 const std::vector<std::pair<DetId, float>> &hitsAndFracs,
326 return ShowerShapeCalc(
std::shared_ptr< std::unordered_map< uint32_t, const reco::PFRecHit * > > pfRecHitPtrMap_
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
double getRvar(double cylinderR, bool useFractions=true, bool useCellSize=true) const
static const double kHDWaferCellSize_
constexpr Detector det() const
get the detector field from this detid
ShowerShapeCalc(std::shared_ptr< const hgcal::RecHitTools > recHitTools, std::shared_ptr< const std::unordered_map< uint32_t, const reco::PFRecHit *> > pfRecHitPtrMap, const std::vector< std::pair< DetId, float > > &hitsAndFracs, const double rawEnergy, const double minHitE=0, const double minHitET=0, const int minLayer=1, const int maxLayer=-1, DetId::Detector subDet=DetId::HGCalEE)
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
void initPerSetup(const edm::EventSetup &iSetup)
void setFilteredHitsAndFractions(const std::vector< std::pair< DetId, float > > &hitsAndFracs)
void initPerEvent(const std::vector< reco::PFRecHit > &recHits)
static const double kLDWaferCellSize_
std::vector< double > getEnergyHighestHits(unsigned int nrHits, bool useFractions=true) const
std::shared_ptr< hgcal::RecHitTools > recHitTools_
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryToken_
Transform3DPJ::Vector XYZVector
constexpr uint32_t rawId() const
get the raw id
void setTokens(edm::ConsumesCollector consumesCollector)
void setPFRecHitPtrMap(const std::vector< reco::PFRecHit > &recHits)
Log< level::Warning, false > LogWarning
double getCellSize(DetId detId) const
ShowerWidths getPCAWidths(double cylinderR, bool useFractions=false) const
HGCalShowerShapeHelper::ShowerShapeCalc createCalc(const std::vector< std::pair< DetId, float > > &hitsAndFracs, double rawEnergy, double minHitE=0, double minHitET=0, int minLayer=1, int maxLayer=-1, DetId::Detector subDet=DetId::HGCalEE) const