1 #ifndef RecoEcal_EgammaCoreTools_EcalClusterTools_h
2 #define RecoEcal_EgammaCoreTools_EcalClusterTools_h
52 #include "CLHEP/Geometry/Transform3D.h"
217 double phiCorrectionFactor = 0.8,
219 bool useLogWeights =
true);
223 double phiCorrectionFactor = 0.8,
225 bool useLogWeights =
true);
227 double phiCorrectionFactor = 0.8,
229 bool useLogWeights =
true);
275 int weightedPositionMethod = 0,
281 float energyRHThresh = 0.00000,
282 int weightedPositionMethod = 0);
284 const std::vector<std::pair<const EcalRecHit *, float>> &rhVector,
int weightedPositionMethod = 0);
317 static double f00(
double r) {
return 1; }
318 static double f11(
double r) {
return r; }
319 static double f20(
double r) {
return 2.0 * r * r - 1.0; }
320 static double f22(
double r) {
return r *
r; }
321 static double f31(
double r) {
return 3.0 * r * r * r - 2.0 *
r; }
322 static double f33(
double r) {
return r * r *
r; }
323 static double f40(
double r) {
return 6.0 * r * r * r * r - 6.0 * r * r + 1.0; }
324 static double f42(
double r) {
return 4.0 * r * r * r * r - 3.0 * r *
r; }
325 static double f44(
double r) {
return r * r * r *
r; }
326 static double f51(
double r) {
return 10.0 *
pow(r, 5) - 12.0 *
pow(r, 3) + 3.0 *
r; }
327 static double f53(
double r) {
return 5.0 *
pow(r, 5) - 4.0 *
pow(r, 3); }
328 static double f55(
double r) {
return pow(r, 5); }
357 for (
int i = 2;
i <=
n; ++
i)
372 static int deltaIEta(
int seed_ieta,
int rh_ieta);
373 static int deltaIPhi(
int seed_iphi,
int rh_iphi);
376 static float computeWeight(
float eRH,
float energyTotal,
int weightedPositionMethod);
385 for (
size_t i = 0;
i < v_id.size(); ++
i) {
386 if (v_id[
i].
first.rawId() ==
id.rawId()) {
387 frac = v_id[
i].second;
399 for (
size_t i = 0;
i < v_id.size(); ++
i) {
400 float energy = recHitEnergy(v_id[
i].
first, recHits) * (noZS ? 1.0 : v_id[
i].second);
406 return std::pair<DetId, float>(
id,
max);
417 if (
id ==
DetId(0)) {
421 if (it != recHits->
end()) {
457 for (
auto const &detId : rectangle(
id, *topology)) {
458 energy += recHitEnergy(detId, recHits) * getFraction(vId, detId);
472 for (
auto const &detId : rectangle(
id, *topology)) {
473 const float energy = recHitEnergy(detId, recHits);
475 if (energy * frac > 0)
485 std::vector<DetId>
v;
486 for (
auto const &detId : rectangle(
id, *topology)) {
487 if (detId !=
DetId(0))
498 std::list<float> energies;
499 float max_E = matrixEnergy(cluster, recHits, topology,
id, {-1, 0, -1, 0});
500 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {-1, 0, 0, 1}));
501 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {0, 1, 0, 1}));
502 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {0, 1, -1, 0}));
511 float max_E = matrixEnergy(cluster, recHits, topology,
id, {-1, 1, -1, 0});
512 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {0, 1, -1, 1}));
513 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {-1, 1, 0, 1}));
514 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {-1, 0, -1, 1}));
523 return matrixEnergy(cluster, recHits, topology,
id, {-1, 1, -1, 1});
531 float max_E = matrixEnergy(cluster, recHits, topology,
id, {-1, 2, -2, 1});
532 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {-2, 1, -2, 1}));
533 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {-2, 1, -1, 2}));
534 max_E =
std::max(max_E, matrixEnergy(cluster, recHits, topology,
id, {-1, 2, -1, 2}));
543 return matrixEnergy(cluster, recHits, topology,
id, {-2, 2, -2, 2});
551 return matrixSize(cluster, recHits, topology,
id, {-2, 2, -2, 2});
561 std::vector<float> energies;
562 const std::vector<std::pair<DetId, float>> &v_id = cluster.
hitsAndFractions();
563 energies.reserve(v_id.size());
566 for (
size_t i = 0;
i < v_id.size(); ++
i) {
567 energies.push_back(recHitEnergy(v_id[
i].
first, recHits) * (noZS ? 1.0 : v_id[
i].
second));
569 std::partial_sort(energies.begin(), energies.begin() + 2, energies.end(), std::greater<float>());
578 return matrixEnergy(cluster, recHits, topology,
id, {1, 2, -2, 2});
586 return matrixEnergy(cluster, recHits, topology,
id, {-2, -1, -2, 2});
594 return matrixEnergy(cluster, recHits, topology,
id, {-2, 2, 1, 2});
602 return matrixEnergy(cluster, recHits, topology,
id, {-2, 2, -2, -1});
614 float left = matrixEnergy(cluster, recHits, topology,
id, {-1, -1, -2, 2});
616 float right = matrixEnergy(cluster, recHits, topology,
id, {1, 1, -2, 2});
618 float centre = matrixEnergy(cluster, recHits, topology,
id, {0, 0, -2, 2});
621 return left > right ? left + centre : right + centre;
629 return matrixEnergy(cluster, recHits, topology,
id, {0, 0, -2, 2});
637 return matrixEnergy(cluster, recHits, topology,
id, {-2, 2, 0, 0});
645 return matrixEnergy(cluster, recHits, topology,
id, {0, 0, -1, 1});
653 return matrixEnergy(cluster, recHits, topology,
id, {-1, 1, 0, 0});
661 return matrixEnergy(cluster, recHits, topology,
id, {-1, -1, 0, 0});
669 return matrixEnergy(cluster, recHits, topology,
id, {1, 1, 0, 0});
677 return matrixEnergy(cluster, recHits, topology,
id, {0, 0, 1, 1});
685 return matrixEnergy(cluster, recHits, topology,
id, {0, 0, -1, -1});
692 float clusterEnergy = cluster.
energy();
693 const std::vector<std::pair<DetId, float>> &v_id = cluster.
hitsAndFractions();
696 <<
"Trying to get basket fraction for endcap basic-clusters. Basket fractions can be obtained ONLY for barrel "
697 "basic-clusters. Returning empty vector.";
698 return basketFraction;
700 for (
size_t i = 0;
i < v_id.size(); ++
i) {
702 recHitEnergy(v_id[
i].first, recHits) * v_id[
i].second / clusterEnergy;
704 std::sort(basketFraction.rbegin(), basketFraction.rend());
705 return basketFraction;
712 float clusterEnergy = cluster.
energy();
713 const std::vector<std::pair<DetId, float>> &v_id = cluster.
hitsAndFractions();
716 <<
"Trying to get basket fraction for endcap basic-clusters. Basket fractions can be obtained ONLY for barrel "
717 "basic-clusters. Returning empty vector.";
718 return basketFraction;
720 for (
size_t i = 0;
i < v_id.size(); ++
i) {
723 recHitEnergy(v_id[
i].first, recHits) * (noZS ? 1.0 : v_id[
i].second) / clusterEnergy;
725 std::sort(basketFraction.rbegin(), basketFraction.rend());
726 return basketFraction;
730 std::vector<typename EcalClusterToolsT<noZS>::EcalClusterEnergyDeposition>
736 std::vector<typename EcalClusterToolsT<noZS>::EcalClusterEnergyDeposition> energyDistribution;
740 CLHEP::Hep3Vector clDir(clVect);
741 clDir *= 1.0 / clDir.mag();
743 CLHEP::Hep3Vector theta_axis(clDir.y(), -clDir.x(), 0.0);
744 theta_axis *= 1.0 / theta_axis.mag();
745 CLHEP::Hep3Vector phi_axis = theta_axis.cross(clDir);
747 const std::vector<std::pair<DetId, float>> &clusterDetIds = cluster.
hitsAndFractions();
751 std::vector<std::pair<DetId, float>>::const_iterator posCurrent;
753 for (posCurrent = clusterDetIds.begin(); posCurrent != clusterDetIds.end(); ++posCurrent) {
755 testEcalRecHit = *itt;
757 if (((*posCurrent).first !=
DetId(0)) && (recHits->
find((*posCurrent).first) != recHits->
end())) {
766 <<
" GeV; skipping... ";
771 DetId id_ = (*posCurrent).first;
774 const GlobalPoint &cellPos = this_cell->getPosition();
775 CLHEP::Hep3Vector gblPos(cellPos.
x(), cellPos.
y(), cellPos.
z());
777 CLHEP::Hep3Vector
diff = gblPos - clVect;
781 CLHEP::Hep3Vector DigiVect = diff - diff.dot(clDir) * clDir;
782 clEdep.
r = DigiVect.mag();
784 <<
"\tr = " << clEdep.
r;
785 clEdep.
phi = DigiVect.angle(theta_axis);
786 if (DigiVect.dot(phi_axis) < 0)
788 energyDistribution.push_back(clEdep);
791 return energyDistribution;
800 std::vector<EcalClusterToolsT::EcalClusterEnergyDeposition> energyDistribution =
801 getEnergyDepTopology(cluster, recHits, geometry, logW, w0);
803 std::vector<float> lat;
804 double r, redmoment = 0;
805 double phiRedmoment = 0;
806 double etaRedmoment = 0;
808 int clusterSize = energyDistribution.size();
809 float etaLat_, phiLat_, lat_;
810 if (clusterSize < 3) {
821 if (energyDistribution[1].deposited_energy > energyDistribution[0].deposited_energy) {
826 for (
int i = 2;
i < clusterSize;
i++) {
828 if (energyDistribution[
i].deposited_energy > energyDistribution[n1].deposited_energy) {
834 if (energyDistribution[
i].deposited_energy > energyDistribution[n2].deposited_energy) {
841 r = energyDistribution[
n].r;
842 redmoment += r * r * energyDistribution[
n].deposited_energy;
843 double rphi = r *
cos(energyDistribution[n].
phi);
844 phiRedmoment += rphi * rphi * energyDistribution[
n].deposited_energy;
845 double reta = r *
sin(energyDistribution[n].phi);
846 etaRedmoment += reta * reta * energyDistribution[
n].deposited_energy;
848 double e1 = energyDistribution[n1].deposited_energy;
849 double e2 = energyDistribution[n2].deposited_energy;
851 lat_ = redmoment / (redmoment + 2.19 * 2.19 * (e1 + e2));
852 phiLat_ = phiRedmoment / (phiRedmoment + 2.19 * 2.19 * (e1 + e2));
853 etaLat_ = etaRedmoment / (etaRedmoment + 2.19 * 2.19 * (e1 + e2));
855 lat.push_back(etaLat_);
856 lat.push_back(phiLat_);
868 const std::vector<std::pair<DetId, float>> &hsAndFs = cluster.
hitsAndFractions();
869 std::vector<DetId> v_id = matrixDetId(topology, getMaximum(cluster, recHits).
first, 2);
870 for (
const std::pair<DetId, float> &hitAndFrac : hsAndFs) {
871 for (std::vector<DetId>::const_iterator it = v_id.begin(); it != v_id.end(); ++it) {
872 if (hitAndFrac.first != *it && !noZS)
877 meanPosition = meanPosition + recHitEnergy(*it, recHits) *
position * hitAndFrac.second;
882 return meanPosition / e5x5(cluster, recHits, topology);
896 DetId seedId = getMaximum(cluster, recHits).first;
901 const std::vector<std::pair<DetId, float>> &hsAndFs = cluster.
hitsAndFractions();
902 std::vector<DetId> v_id = matrixDetId(topology, seedId, 2);
903 for (
const std::pair<DetId, float> &hAndF : hsAndFs) {
904 for (std::vector<DetId>::const_iterator it = v_id.begin(); it != v_id.end(); ++it) {
905 if (hAndF.first != *it && !noZS)
907 float energy = recHitEnergy(*it, recHits) * hAndF.second;
910 meanDEta += energy * getNrCrysDiffInEta(*it, seedId);
911 meanDPhi += energy * getNrCrysDiffInPhi(*it, seedId);
919 return std::pair<float, float>(meanDEta, meanDPhi);
932 DetId seedId = getMaximum(cluster, recHits).first;
934 std::pair<float, float> meanXY(0., 0.);
940 const std::vector<std::pair<DetId, float>> &hsAndFs = cluster.
hitsAndFractions();
941 std::vector<DetId> v_id = matrixDetId(topology, seedId, 2);
942 for (
const std::pair<DetId, float> &hAndF : hsAndFs) {
943 for (std::vector<DetId>::const_iterator it = v_id.begin(); it != v_id.end(); ++it) {
944 if (hAndF.first != *it && !noZS)
946 float energy = recHitEnergy(*it, recHits) * hAndF.second;
949 meanXY.first += energy * getNormedIX(*it);
950 meanXY.second += energy * getNormedIY(*it);
967 float e_5x5 = e5x5(cluster, recHits, topology);
968 float covEtaEta, covEtaPhi, covPhiPhi;
971 const std::vector<std::pair<DetId, float>> &v_id = cluster.
hitsAndFractions();
972 math::XYZVector meanPosition = meanClusterPosition(cluster, recHits, topology, geometry);
975 double numeratorEtaEta = 0;
976 double numeratorEtaPhi = 0;
977 double numeratorPhiPhi = 0;
980 DetId id = getMaximum(v_id, recHits).first;
982 for (
auto const &detId : rectangle(
id, *topology)) {
983 float frac = getFraction(v_id, detId);
984 float energy = recHitEnergy(detId, recHits) *
frac;
992 double dPhi = position.
phi() - meanPosition.
phi();
1000 double dEta = position.
eta() - meanPosition.eta();
1005 numeratorEtaEta += w * dEta * dEta;
1006 numeratorEtaPhi += w * dEta * dPhi;
1007 numeratorPhiPhi += w * dPhi * dPhi;
1010 if (denominator != 0.0) {
1027 std::array<float, 3>
v{{covEtaEta, covEtaPhi, covPhiPhi}};
1035 template <
bool noZS>
1043 float e_5x5 = e5x5(cluster, recHits, topology);
1044 float covEtaEta, covEtaPhi, covPhiPhi;
1048 const std::vector<std::pair<DetId, float>> &v_id = cluster.
hitsAndFractions();
1049 std::pair<float, float> mean5x5PosInNrCrysFromSeed = mean5x5PositionInLocalCrysCoord(cluster, recHits, topology);
1050 std::pair<float, float> mean5x5XYPos = mean5x5PositionInXY(cluster, recHits, topology);
1053 double numeratorEtaEta = 0;
1054 double numeratorEtaPhi = 0;
1055 double numeratorPhiPhi = 0;
1060 const double barrelCrysSize = 0.01745;
1061 const double endcapCrysSize = 0.0447;
1063 DetId seedId = getMaximum(v_id, recHits).first;
1066 const double crysSize = isBarrel ? barrelCrysSize : endcapCrysSize;
1067 float mult = isBarrel ? multEB : multEE;
1073 for (
auto const &detId : rectangle(seedId, *topology)) {
1074 float frac = getFraction(v_id, detId);
1075 float energy = recHitEnergy(detId, recHits) *
frac;
1077 if ((thresholds ==
nullptr) && (mult != 0.0)) {
1079 <<
"In EcalClusterTools::localCovariances, if EcalPFRecHitThresholds==nulptr, then multEB and multEE "
1080 "should be 0 as well.";
1082 float rhThres = 0.0;
1083 if (thresholds !=
nullptr) {
1084 rhThres = (*thresholds)[detId];
1087 if (energy <= (rhThres * mult))
1090 float dEta = getNrCrysDiffInEta(detId, seedId) - mean5x5PosInNrCrysFromSeed.first;
1094 dPhi = getNrCrysDiffInPhi(detId, seedId) - mean5x5PosInNrCrysFromSeed.second;
1096 dPhi = getDPhiEndcap(detId, mean5x5XYPos.first, mean5x5XYPos.second);
1101 numeratorEtaEta += w * dEta * dEta;
1102 numeratorEtaPhi += w * dEta * dPhi;
1103 numeratorPhiPhi += w * dPhi * dPhi;
1107 if (denominator != 0.0) {
1108 covEtaEta = crysSize * crysSize * numeratorEtaEta /
denominator;
1109 covEtaPhi = crysSize * crysSize * numeratorEtaPhi /
denominator;
1110 covPhiPhi = crysSize * crysSize * numeratorPhiPhi /
denominator;
1124 std::array<float, 3>
v{{covEtaEta, covEtaPhi, covPhiPhi}};
1128 template <
bool noZS>
1135 return absZernikeMoment(cluster, recHits, geometry, 2, 0, R0, logW, w0);
1138 template <
bool noZS>
1145 return absZernikeMoment(cluster, recHits, geometry, 4, 2, R0, logW, w0);
1148 template <
bool noZS>
1158 if ((m > n) || ((n - m) % 2 != 0) || (n < 0) || (m < 0))
1163 if ((n > 20) || (R0 <= 2.19))
1166 return fast_AbsZernikeMoment(cluster, recHits, geometry, n, m, R0, logW, w0);
1168 return calc_AbsZernikeMoment(cluster, recHits, geometry, n, m, R0, logW, w0);
1171 template <
bool noZS>
1180 double r, ph,
e, Re = 0, Im = 0;
1181 double TotalEnergy = cluster.
energy();
1182 int index = (n / 2) * (n / 2) + (n / 2) + m;
1183 std::vector<EcalClusterEnergyDeposition> energyDistribution =
1184 getEnergyDepTopology(cluster, recHits, geometry, logW, w0);
1185 int clusterSize = energyDistribution.size();
1186 if (clusterSize < 3)
1189 for (
int i = 0;
i < clusterSize;
i++) {
1190 r = energyDistribution[
i].r /
R0;
1192 std::vector<double> pol;
1193 pol.push_back(f00(r));
1194 pol.push_back(f11(r));
1195 pol.push_back(f20(r));
1196 pol.push_back(f22(r));
1197 pol.push_back(f31(r));
1198 pol.push_back(f33(r));
1199 pol.push_back(f40(r));
1200 pol.push_back(f42(r));
1201 pol.push_back(f44(r));
1202 pol.push_back(f51(r));
1203 pol.push_back(f53(r));
1204 pol.push_back(f55(r));
1205 ph = (energyDistribution[
i]).
phi;
1206 e = energyDistribution[
i].deposited_energy;
1207 Re = Re + e / TotalEnergy * pol[
index] *
cos((
double)m * ph);
1208 Im = Im - e / TotalEnergy * pol[
index] *
sin((
double)m * ph);
1211 return sqrt(Re * Re + Im * Im);
1214 template <
bool noZS>
1223 double r, ph,
e, Re = 0, Im = 0, f_nm;
1224 double TotalEnergy = cluster.
energy();
1225 std::vector<EcalClusterEnergyDeposition> energyDistribution =
1226 getEnergyDepTopology(cluster, recHits, geometry, logW, w0);
1227 int clusterSize = energyDistribution.size();
1228 if (clusterSize < 3)
1231 for (
int i = 0;
i < clusterSize; ++
i) {
1232 r = energyDistribution[
i].r /
R0;
1234 ph = energyDistribution[
i].phi;
1235 e = energyDistribution[
i].deposited_energy;
1237 for (
int s = 0;
s <= (n -
m) / 2;
s++) {
1246 Re = Re + e / TotalEnergy * f_nm *
cos((
double)m * ph);
1247 Im = Im - e / TotalEnergy * f_nm *
sin((
double)m * ph);
1250 return sqrt(Re * Re + Im * Im);
1257 template <
bool noZS>
1264 float iXNorm = getNormedIX(
id);
1265 float iYNorm = getNormedIY(
id);
1267 return std::sqrt(iXNorm * iXNorm + iYNorm * iYNorm);
1277 template <
bool noZS>
1289 template <
bool noZS>
1293 int iXNorm = eeId.
ix() - 50;
1302 template <
bool noZS>
1306 int iYNorm = eeId.
iy() - 50;
1315 template <
bool noZS>
1317 float crysIEta = getIEta(crysId);
1318 float orginIEta = getIEta(orginId);
1321 float nrCrysDiff = crysIEta - orginIEta;
1326 if (crysIEta * orginIEta < 0) {
1337 template <
bool noZS>
1339 float crysIPhi = getIPhi(crysId);
1340 float orginIPhi = getIPhi(orginId);
1343 float nrCrysDiff = crysIPhi - orginIPhi;
1346 if (nrCrysDiff > +180) {
1347 nrCrysDiff = nrCrysDiff - 360;
1349 if (nrCrysDiff < -180) {
1350 nrCrysDiff = nrCrysDiff + 360;
1357 template <
bool noZS>
1359 float iXNorm = getNormedIX(crysId);
1360 float iYNorm = getNormedIY(crysId);
1362 float hitLocalR2 = (iXNorm - meanX) * (iXNorm - meanX) + (iYNorm - meanY) * (iYNorm - meanY);
1363 float hitR2 = iXNorm * iXNorm + iYNorm * iYNorm;
1364 float meanR2 = meanX * meanX + meanY * meanY;
1365 float hitR =
sqrt(hitR2);
1366 float meanR =
sqrt(meanR2);
1368 float tmp = (hitR2 + meanR2 - hitLocalR2) / (2 * hitR * meanR);
1373 float phi = acos(tmp);
1374 float dPhi = hitR *
phi;
1379 template <
bool noZS>
1386 float e_5x5 = e5x5(bcluster, recHits, topology);
1387 float covEtaEta, covEtaPhi, covPhiPhi;
1390 const std::vector<std::pair<DetId, float>> &v_id = cluster.
hitsAndFractions();
1391 std::pair<float, float> mean5x5PosInNrCrysFromSeed = mean5x5PositionInLocalCrysCoord(bcluster, recHits, topology);
1392 std::pair<float, float> mean5x5XYPos = mean5x5PositionInXY(cluster, recHits, topology);
1394 double numeratorEtaEta = 0;
1395 double numeratorEtaPhi = 0;
1396 double numeratorPhiPhi = 0;
1399 const double barrelCrysSize = 0.01745;
1400 const double endcapCrysSize = 0.0447;
1402 DetId seedId = getMaximum(v_id, recHits).first;
1405 const double crysSize = isBarrel ? barrelCrysSize : endcapCrysSize;
1407 for (
size_t i = 0;
i < v_id.size(); ++
i) {
1408 float frac = getFraction(v_id, v_id[
i].
first);
1409 float energy = recHitEnergy(v_id[
i].first, recHits) *
frac;
1414 float dEta = getNrCrysDiffInEta(v_id[
i].first, seedId) - mean5x5PosInNrCrysFromSeed.first;
1417 dPhi = getNrCrysDiffInPhi(v_id[
i].first, seedId) - mean5x5PosInNrCrysFromSeed.second;
1419 dPhi = getDPhiEndcap(v_id[
i].first, mean5x5XYPos.first, mean5x5XYPos.second);
1425 numeratorEtaEta += w * dEta * dEta;
1426 numeratorEtaPhi += w * dEta * dPhi;
1427 numeratorPhiPhi += w * dPhi * dPhi;
1431 if (denominator != 0.0) {
1432 covEtaEta = crysSize * crysSize * numeratorEtaEta /
denominator;
1433 covEtaPhi = crysSize * crysSize * numeratorEtaPhi /
denominator;
1434 covPhiPhi = crysSize * crysSize * numeratorPhiPhi /
denominator;
1449 std::array<float, 3>
v{{covEtaEta, covEtaPhi, covPhiPhi}};
1458 template <
bool noZS>
1461 double phiCorrectionFactor,
1463 bool useLogWeights) {
1464 if (recHits.
empty())
1467 std::vector<std::pair<const EcalRecHit *, float>> RH_ptrs_fracs;
1469 const std::vector<std::pair<DetId, float>> &myHitsPair = basicCluster.
hitsAndFractions();
1471 for (
unsigned int i = 0;
i < myHitsPair.size();
i++) {
1474 if (myRH != recHits.
end()) {
1475 RH_ptrs_fracs.push_back(std::make_pair(&(*myRH), myHitsPair[
i].
second));
1482 template <
bool noZS>
1485 double phiCorrectionFactor,
1487 bool useLogWeights) {
1489 *(superCluster.
seed()), recHits, phiCorrectionFactor, w0, useLogWeights);
1492 template <
bool noZS>
1494 const std::vector<std::pair<const EcalRecHit *, float>> &RH_ptrs_fracs,
1495 double phiCorrectionFactor,
1497 bool useLogWeights) {
1498 if (RH_ptrs_fracs.empty())
1501 double mid_eta(0), mid_phi(0), mid_x(0), mid_y(0);
1505 double max_phi = -10.;
1506 double min_phi = 100.;
1508 std::vector<double> etaDetId;
1509 std::vector<double> phiDetId;
1510 std::vector<double> xDetId;
1511 std::vector<double> yDetId;
1512 std::vector<double> wiDetId;
1514 unsigned int nCry = 0;
1519 for (
std::vector<std::pair<const EcalRecHit *, float>>::const_iterator rhf_ptr = RH_ptrs_fracs.begin();
1520 rhf_ptr != RH_ptrs_fracs.end();
1525 double temp_eta(0), temp_phi(0), temp_x(0), temp_y(0);
1529 temp_eta = (getIEta(rh_ptr->
detid()) > 0. ? getIEta(rh_ptr->
detid()) + 84.5 : getIEta(rh_ptr->
detid()) + 85.5);
1530 temp_phi = getIPhi(rh_ptr->
detid()) - 0.5;
1532 temp_eta = getIEta(rh_ptr->
detid());
1533 temp_x = getNormedIX(rh_ptr->
detid());
1534 temp_y = getNormedIY(rh_ptr->
detid());
1537 double temp_ene = rh_ptr->
energy() * (noZS ? 1.0 : rhf_ptr->second);
1541 if (temp_phi > max_phi)
1543 if (temp_phi < min_phi)
1545 etaDetId.push_back(temp_eta);
1546 phiDetId.push_back(temp_phi);
1547 xDetId.push_back(temp_x);
1548 yDetId.push_back(temp_y);
1549 wiDetId.push_back(temp_wi);
1550 denominator += temp_wi;
1556 if (max_phi == 359.5 && min_phi == 0.5) {
1557 for (
unsigned int i = 0;
i < nCry;
i++) {
1558 if (phiDetId[
i] - 179. > 0.)
1559 phiDetId[
i] -= 360.;
1560 mid_phi += phiDetId[
i] * wiDetId[
i];
1561 mid_eta += etaDetId[
i] * wiDetId[
i];
1564 for (
unsigned int i = 0;
i < nCry;
i++) {
1565 mid_phi += phiDetId[
i] * wiDetId[
i];
1566 mid_eta += etaDetId[
i] * wiDetId[
i];
1570 for (
unsigned int i = 0;
i < nCry;
i++) {
1571 mid_eta += etaDetId[
i] * wiDetId[
i];
1572 mid_x += xDetId[
i] * wiDetId[
i];
1573 mid_y += yDetId[
i] * wiDetId[
i];
1588 double deta(0), dphi(0);
1590 for (
unsigned int i = 0;
i < nCry;
i++) {
1592 deta = etaDetId[
i] - mid_eta;
1593 dphi = phiDetId[
i] - mid_phi;
1595 deta = etaDetId[
i] - mid_eta;
1596 float hitLocalR2 = (xDetId[
i] - mid_x) * (xDetId[
i] - mid_x) + (yDetId[
i] - mid_y) * (yDetId[
i] - mid_y);
1597 float hitR2 = xDetId[
i] * xDetId[
i] + yDetId[
i] * yDetId[
i];
1598 float meanR2 = mid_x * mid_x + mid_y * mid_y;
1599 float hitR =
sqrt(hitR2);
1600 float meanR =
sqrt(meanR2);
1601 float phi = acos((hitR2 + meanR2 - hitLocalR2) / (2 * hitR * meanR));
1604 See += (wiDetId[
i] * deta * deta) / denominator;
1605 Spp += phiCorrectionFactor * (wiDetId[
i] * dphi * dphi) / denominator;
1606 Sep +=
sqrt(phiCorrectionFactor) * (wiDetId[
i] * deta * dphi) / denominator;
1612 returnMoments.
sMaj = ((See + Spp) +
sqrt((See - Spp) * (See - Spp) + 4. * Sep * Sep)) / 2.;
1613 returnMoments.
sMin = ((See + Spp) -
sqrt((See - Spp) * (See - Spp) + 4. * Sep * Sep)) / 2.;
1615 returnMoments.
alpha = atan((See - Spp +
sqrt((Spp - See) * (Spp - See) + 4. * Sep * Sep)) / (2. * Sep));
1617 return returnMoments;
1627 template <
bool noZS>
1631 int weightedPositionMethod,
1633 std::vector<std::pair<const EcalRecHit *, float>> RH_ptrs_fracs;
1634 const std::vector<std::pair<DetId, float>> &myHitsPair = superCluster.
hitsAndFractions();
1635 for (
unsigned int i = 0;
i < myHitsPair.size(); ++
i) {
1638 if (myRH != recHits.
end() && myRH->energy() * (noZS ? 1.0 : myHitsPair[
i].second) > energyThreshold) {
1640 RH_ptrs_fracs.push_back(std::make_pair(&(*myRH), myHitsPair[
i].
second));
1643 std::vector<float>
temp =
1652 template <
bool noZS>
1658 float energyRHThresh,
1659 int weightedPositionMethod) {
1660 std::vector<std::pair<const EcalRecHit *, float>> RH_ptrs_fracs;
1661 const std::vector<std::pair<DetId, float>> &myHitsPair = superCluster.
hitsAndFractions();
1662 for (
unsigned int i = 0;
i < myHitsPair.size(); ++
i) {
1665 if (myRH != recHits.
end() && myRH->energy() * (noZS ? 1.0 : myHitsPair[
i].second) > energyRHThresh)
1666 RH_ptrs_fracs.push_back(std::make_pair(&(*myRH), myHitsPair[
i].
second));
1672 EBDetId EBdetIdi(rh->detid());
1673 float the_fraction = 0;
1675 bool inEtaWindow = (
abs(deltaIEta(seedPosition[0], EBdetIdi.ieta())) <= ieta_delta);
1676 bool inPhiWindow = (
abs(deltaIPhi(seedPosition[1], EBdetIdi.iphi())) <= iphi_delta);
1677 bool passEThresh = (rh->energy() > energyRHThresh);
1678 bool alreadyCounted =
false;
1681 bool is_SCrh_inside_recHits =
false;
1682 for (
unsigned int i = 0;
i < myHitsPair.size();
i++) {
1684 if (SCrh != recHits.
end()) {
1685 the_fraction = myHitsPair[
i].second;
1686 is_SCrh_inside_recHits =
true;
1687 if (rh->detid() == SCrh->detid())
1688 alreadyCounted =
true;
1692 if (is_SCrh_inside_recHits && !alreadyCounted && passEThresh && inEtaWindow && inPhiWindow) {
1693 RH_ptrs_fracs.push_back(std::make_pair(&(*rh), the_fraction));
1703 template <
bool noZS>
1705 const std::vector<std::pair<const EcalRecHit *, float>> &RH_ptrs_fracs,
1706 int weightedPositionMethod) {
1709 std::vector<float> shapes;
1712 if (RH_ptrs_fracs.size() < 2) {
1713 shapes.push_back(-3);
1714 shapes.push_back(-3);
1720 int tempInt = seedPosition[0];
1726 float centerIEta = 0.;
1727 float centerIPhi = 0.;
1730 for (
std::vector<std::pair<const EcalRecHit *, float>>::const_iterator rhf_ptr = RH_ptrs_fracs.begin();
1731 rhf_ptr != RH_ptrs_fracs.end();
1736 if (fabs(energyTotal) < 0.0001) {
1738 shapes.push_back(-2);
1739 shapes.push_back(-2);
1742 float rh_energy = rh_ptr->
energy() * (noZS ? 1.0 : rhf_ptr->second);
1744 if (
std::abs(weightedPositionMethod) < 0.0001) {
1745 weight = rh_energy / energyTotal;
1747 weight =
std::max(0.0, 4.2 +
log(rh_energy / energyTotal));
1750 centerIEta += weight * deltaIEta(seedPosition[0], EBdetIdi.ieta());
1751 centerIPhi += weight * deltaIPhi(seedPosition[1], EBdetIdi.iphi());
1753 if (fabs(denominator) < 0.0001) {
1755 shapes.push_back(-2);
1756 shapes.push_back(-2);
1763 TMatrixDSym inertia(2);
1764 double inertia00 = 0.;
1765 double inertia01 = 0.;
1766 double inertia11 = 0.;
1768 for (
std::vector<std::pair<const EcalRecHit *, float>>::const_iterator rhf_ptr = RH_ptrs_fracs.begin();
1769 rhf_ptr != RH_ptrs_fracs.end();
1775 if (fabs(energyTotal) < 0.0001) {
1777 shapes.push_back(-2);
1778 shapes.push_back(-2);
1781 float rh_energy = rh_ptr->
energy() * (noZS ? 1.0 : rhf_ptr->second);
1783 if (
std::abs(weightedPositionMethod) < 0.0001) {
1784 weight = rh_energy / energyTotal;
1786 weight =
std::max(0.0, 4.2 +
log(rh_energy / energyTotal));
1789 float ieta_rh_to_center = deltaIEta(seedPosition[0], EBdetIdi.ieta()) - centerIEta;
1790 float iphi_rh_to_center = deltaIPhi(seedPosition[1], EBdetIdi.iphi()) - centerIPhi;
1792 inertia00 += weight * iphi_rh_to_center * iphi_rh_to_center;
1793 inertia01 -= weight * iphi_rh_to_center * ieta_rh_to_center;
1794 inertia11 += weight * ieta_rh_to_center * ieta_rh_to_center;
1798 inertia[0][0] = inertia00;
1799 inertia[0][1] = inertia01;
1800 inertia[1][0] = inertia01;
1801 inertia[1][1] = inertia11;
1804 TMatrixD eVectors(2, 2);
1805 TVectorD eValues(2);
1807 eVectors = inertia.EigenVectors(eValues);
1812 TVectorD smallerAxis(2);
1813 smallerAxis[0] = eVectors[0][1];
1814 smallerAxis[1] = eVectors[1][1];
1817 Double_t
temp = fabs(smallerAxis[0]);
1818 if (fabs(eValues[0]) < 0.0001) {
1820 shapes.push_back(-2);
1821 shapes.push_back(-2);
1825 float Roundness = eValues[1] / eValues[0];
1826 float Angle = acos(temp);
1828 if (-0.00001 < Roundness && Roundness < 0)
1830 if (-0.00001 < Angle && Angle < 0)
1833 shapes.push_back(Roundness);
1834 shapes.push_back(Angle);
1838 template <
bool noZS>
1844 for (
auto const &detId : rectangle(
id, *topology)) {
1845 auto recHitIt = recHits->
find(detId);
1857 template <
bool noZS>
1859 int rel_iphi = rh_iphi - seed_iphi;
1862 rel_iphi = rel_iphi - 360;
1863 if (rel_iphi < -180)
1864 rel_iphi = rel_iphi + 360;
1871 template <
bool noZS>
1878 int rel_ieta = rh_ieta - seed_ieta;
1883 template <
bool noZS>
1885 const std::vector<std::pair<const EcalRecHit *, float>> &RH_ptrs_fracs) {
1886 std::vector<int> seedPosition;
1891 for (
auto const &rhf : RH_ptrs_fracs) {
1895 float rh_energy = rh_ptr->
energy() * (noZS ? 1.0 : rhf.second);
1897 if (eSeedRH < rh_energy) {
1898 eSeedRH = rh_energy;
1899 iEtaSeedRH = EBdetIdi.ieta();
1900 iPhiSeedRH = EBdetIdi.iphi();
1905 seedPosition.push_back(iEtaSeedRH);
1906 seedPosition.push_back(iPhiSeedRH);
1907 return seedPosition;
1911 template <
bool noZS>
1914 for (
const auto &hAndF : RH_ptrs_fracs) {
1915 sumE += hAndF.first->energy() * (noZS ? 1.0 : hAndF.second);
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
const math::XYZPoint & position() const
cluster centroid position
static std::vector< std::string > checklist log
static constexpr float kRelEnCut
uint16_t *__restrict__ id
Sin< T >::type sin(const T &t)
Geom::Phi< T > phi() const
const DetId & detid() const
std::vector< EcalRecHit >::const_iterator const_iterator
static const int kTowersInPhi
int iphi() const
get the crystal iphi
U second(std::pair< T, U > const &p)
int im() const
get the number of module inside the SM (1-4)
static const int kCrystalsInPhi
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Cos< T >::type cos(const T &t)
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
static const int kModulesPerSM
Abs< T >::type abs(const T &t)
double energy() const
cluster energy
int ieta() const
get the crystal ieta
const_iterator end() const
static const int MAX_IPHI
EcalClusterToolsT< true > EcalClusterTools
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
XYZVectorD XYZVector
spatial vector with cartesian internal representation
iterator find(key_type k)
static int position[264][3]
int factorial(int n)
factorial function
const CaloClusterPtr & seed() const
seed BasicCluster
double energySum(const DataFrame &df, int fs, int ls)
Log< level::Warning, false > LogWarning
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)
const_iterator begin() const