7 std::shared_ptr<const hgcal::RecHitTools> recHitTools,
8 std::shared_ptr<
const std::unordered_map<uint32_t, const reco::PFRecHit *>> pfRecHitPtrMap,
9 const std::vector<std::pair<DetId, float>> &hitsAndFracs,
10 const double rawEnergy,
12 const double minHitET,
16 : recHitTools_(recHitTools),
17 pfRecHitPtrMap_(pfRecHitPtrMap),
18 rawEnergy_(rawEnergy),
21 minHitET2_(minHitET * minHitET),
23 maxLayer_(maxLayer <= 0 ? recHitTools_->lastLayerEE() : maxLayer),
24 nLayer_(maxLayer_ - minLayer_ + 1),
36 if (hitsAndFracs_.empty()) {
40 if (rawEnergy_ <= 0.0) {
42 <<
"Encountered negative or zero energy for HGCal R-variable denominator: " << rawEnergy_ << std::endl;
45 double cylinderR2 = cylinderR * cylinderR;
49 auto hitEnergyIter = useFractions ? hitEnergiesWithFracs_.begin() : hitEnergies_.begin();
53 for (
const auto &hnf : hitsAndFracs_) {
56 DetId hitId = hnf.first;
63 auto distXYZ = hitXYZ - layerCentroids_[hitLayer];
65 double r2 = distXYZ.x() * distXYZ.x() + distXYZ.y() * distXYZ.y();
69 if (
std::sqrt(
r2) > cylinderR + getCellSize(hitId)) {
74 else if (
r2 > cylinderR2) {
78 rVar += *hitEnergyIter;
87 bool useFractions)
const {
88 if (hitsAndFracs_.empty()) {
92 double cylinderR2 = cylinderR * cylinderR;
94 TMatrixD covMat(3, 3);
106 auto hitEnergyIter = useFractions ? hitEnergiesWithFracs_.begin() : hitEnergies_.begin();
111 for (
const auto &hnf : hitsAndFracs_) {
114 DetId hitId = hnf.first;
123 double r2 = radXYZ.x() * radXYZ.x() + radXYZ.y() * radXYZ.y();
125 if (
r2 > cylinderR2) {
131 double weight = *hitEnergyIter;
134 dxdx +=
weight * dXYZ.x() * dXYZ.x();
135 dydy +=
weight * dXYZ.y() * dXYZ.y();
136 dzdz +=
weight * dXYZ.z() * dXYZ.z();
138 dxdy +=
weight * dXYZ.x() * dXYZ.y();
140 dzdx +=
weight * dXYZ.z() * dXYZ.x();
145 if (!totalW || nHit < 2) {
161 covMat(0, 1) = covMat(1, 0) = dxdy;
162 covMat(0, 2) = covMat(2, 0) = dzdx;
163 covMat(1, 2) = covMat(2, 1) =
dydz;
171 TMatrixD eigVecMat(3, 3);
173 eigVecMat = covMat.EigenVectors(eigVals);
193 bool useFractions)
const {
194 std::vector<double> sortedEnergies(nrHits, 0.);
195 const auto &
hits = useFractions ? hitEnergiesWithFracs_ : hitEnergies_;
196 std::partial_sort_copy(
197 hits.begin(),
hits.end(), sortedEnergies.begin(), sortedEnergies.end(), std::greater<double>());
198 return sortedEnergies;
202 const std::vector<std::pair<DetId, float>> &hitsAndFracs) {
203 hitsAndFracs_.clear();
204 hitEnergies_.clear();
205 hitEnergiesWithFracs_.clear();
207 for (
const auto &hnf : hitsAndFracs) {
208 DetId hitId = hnf.first;
209 float hitEfrac = hnf.second;
213 if (hitLayer > nLayer_) {
217 if (hitId.
det() != subDet_) {
227 if (
recHit.energy() < minHitE_) {
231 if (
recHit.pt2() < minHitET2_) {
236 hitsAndFracs_.push_back(hnf);
237 hitEnergies_.push_back(
recHit.energy());
238 hitEnergiesWithFracs_.push_back(
recHit.energy() * hitEfrac);
243 layerEnergies_.clear();
244 layerEnergies_.resize(nLayer_);
246 layerCentroids_.clear();
247 layerCentroids_.resize(nLayer_);
249 centroid_.SetXYZ(0, 0, 0);
255 for (
const auto &hnf : hitsAndFracs_) {
258 DetId hitId = hnf.first;
260 double weight = hitEnergies_[iHit];
266 centroid_ +=
weight * hitXYZ;
270 layerEnergies_[hitLayer] +=
weight;
271 layerCentroids_[hitLayer] +=
weight * hitXYZ;
276 for (
auto ¢roid : layerCentroids_) {
279 if (layerEnergies_[iLayer]) {
280 centroid /= layerEnergies_[iLayer];
294 : recHitTools_(
std::make_shared<
hgcal::RecHitTools>()),
295 pfRecHitPtrMap_(
std::make_shared<
std::unordered_map<uint32_t,
const reco::PFRecHit *>>()) {
313 const std::vector<std::pair<DetId, float>> &hitsAndFracs,
320 return ShowerShapeCalc(