13 #include "Math/GenVector/VectorUtil.h"
25 using namespace std::placeholders;
33 typedef std::pair<reco::CaloClusterPtr::key_type, reco::CaloClusterPtr>
EEPSPair;
42 bool greaterByEt(
const CalibClusterPtr& x,
const CalibClusterPtr& y) {
44 const double xpt =
ptFast(
x->energy(),
x->the_ptr()->position(), zero);
45 const double ypt =
ptFast(
y->energy(),
y->the_ptr()->position(), zero);
49 bool isSeed(
const CalibClusterPtr& x,
double threshold,
bool useETcut) {
51 double e_or_et =
x->energy();
53 e_or_et =
ptFast(e_or_et,
x->the_ptr()->position(), zero);
57 bool isLinkedByRecHit(
const CalibClusterPtr& x,
58 const CalibClusterPtr&
seed,
60 const double majority,
72 const auto& seedHitsAndFractions =
seed->the_ptr()->hitsAndFractions();
73 const auto& xHitsAndFractions =
x->the_ptr()->hitsAndFractions();
74 double x_rechits_tot = xHitsAndFractions.size();
75 double x_rechits_match = 0.0;
76 for (
const std::pair<DetId, float>& seedHit : seedHitsAndFractions) {
77 for (
const std::pair<DetId, float>& xHit : xHitsAndFractions) {
78 if (seedHit.first == xHit.first) {
79 x_rechits_match += 1.0;
83 return x_rechits_match / x_rechits_tot > majority;
86 bool isClustered(
const CalibClusterPtr& x,
87 const CalibClusterPtr
seed,
90 const double etawidthSuperCluster,
91 const double phiwidthSuperCluster) {
92 const double dphi =
std::abs(TVector2::Phi_mpi_pi(
seed->phi() -
x->phi()));
93 const bool passes_dphi = ((!dyn_dphi && dphi < phiwidthSuperCluster) ||
95 seed->eta(),
seed->phi(),
x->energy_nocalib(),
x->eta(),
x->phi())));
98 return (
std::abs(
seed->eta() -
x->eta()) < etawidthSuperCluster && passes_dphi);
101 return (passes_dphi &&
180 LogDebug(
"PFClustering") <<
"Loading PFCluster i=" << cluster.key() <<
" energy=" << cluster->energy() << std::endl;
183 if (cluster->caloID().detectors() == 0 && cluster->hitsAndFractions().empty())
187 switch (cluster->layer()) {
212 if (!barrelRecHitsHandle.
isValid()) {
214 <<
"If you use OOT photons, need to specify proper barrel rec hit collection";
220 if (!endcapRecHitsHandle.
isValid()) {
222 <<
"If you use OOT photons, need to specify proper endcap rec hit collection";
236 auto seedable = std::bind(isSeed, _1, seedthresh,
threshIsET_);
249 double etawidthSuperCluster = 0.0;
250 double phiwidthSuperCluster = 0.0;
252 switch (
seed->the_ptr()->layer()) {
270 auto isClusteredWithSeed =
279 auto not_clustered = std::stable_partition(
clusters.begin(),
clusters.end(), isClusteredWithSeed);
283 not_clustered = std::stable_partition(not_clustered,
clusters.end(), matchesSeedByRecHit);
287 edm::LogInfo(
"PFClustering") <<
"Dumping cluster detail";
289 <<
" phi = " <<
seed->phi() << std::endl;
290 for (
auto clus =
clusters.cbegin(); clus != not_clustered; ++clus) {
291 edm::LogVerbatim(
"PFClustering") <<
"\t\tClustered cluster: e = " << (*clus)->energy_nocalib()
292 <<
" eta = " << (*clus)->eta() <<
" phi = " << (*clus)->phi() << std::endl;
294 for (
auto clus = not_clustered; clus !=
clusters.end(); ++clus) {
295 edm::LogVerbatim(
"PFClustering") <<
"\tNon-Clustered cluster: e = " << (*clus)->energy_nocalib()
296 <<
" eta = " << (*clus)->eta() <<
" phi = " << (*clus)->phi() << std::endl;
300 if (not_clustered ==
clusters.begin()) {
306 <<
"Cluster is not seedable!" << std::endl
307 <<
"\tNon-Clustered cluster: e = " << (*not_clustered)->energy_nocalib()
308 <<
" eta = " << (*not_clustered)->eta() <<
" phi = " << (*not_clustered)->phi() << std::endl;
317 std::vector<const reco::PFCluster*> bare_ptrs;
319 double posX(0),
posY(0), posZ(0), corrSCEnergy(0), corrPS1Energy(0), corrPS2Energy(0), energyweight(0),
321 for (
auto& clus : clustered) {
324 energyweight = clus->energy_nocalib();
325 bare_ptrs.push_back(clus->the_ptr().get());
330 std::vector<reco::PFCluster const*> psClusterPointers;
331 for (
auto i_ps = clustops.first; i_ps != clustops.second; ++i_ps) {
332 psClusterPointers.push_back(i_ps->second.get());
336 ePS1 = calibratedEnergies.ps1Energy;
337 ePS2 = calibratedEnergies.ps2Energy;
349 energyweight = clus->energy() - ePS1 - ePS2;
352 energyweight = clus->energy();
358 posX += energyweight * cluspos.X();
359 posY += energyweight * cluspos.Y();
360 posZ += energyweight * cluspos.Z();
362 energyweighttot += energyweight;
363 corrSCEnergy += clus->energy();
364 corrPS1Energy += ePS1;
365 corrPS2Energy += ePS2;
367 posX /= energyweighttot;
368 posY /= energyweighttot;
369 posZ /= energyweighttot;
374 new_sc.
setSeed(clustered.front()->the_ptr());
378 for (
const auto& clus : clustered) {
381 auto& hits_and_fractions = clus->the_ptr()->hitsAndFractions();
382 for (
auto& hit_and_fraction : hits_and_fractions) {
391 for (
auto i_ps = clustops.first; i_ps != clustops.second; ++i_ps) {
396 [&i_ps](
const auto&
i) {
return i.key() == i_ps->first; });
403 <<
"Found a PS cluster matched to more than one EE cluster!" << std::endl
404 << std::hex << psclus.
get() <<
" == " << found_pscluster->get() <<
std::dec << std::endl;
421 regr_->modifyObject(new_sc);
432 switch (
seed->the_ptr()->layer()) {