7 #include "Math/GenVector/VectorUtil.h"
21 namespace MK = reco::MustacheKernel;
31 typedef std::binary_function<
const CalibClusterPtr&,
32 const CalibClusterPtr&,
33 bool> ClusBinaryFunction;
35 typedef std::unary_function<
const CalibClusterPtr&,
36 bool> ClusUnaryFunction;
38 struct SumPSEnergy :
public std::binary_function<double,
43 double operator()(
double a,
44 const PFClusterPtr&
b) {
45 return a + (_thelayer == b->layer())*b->energy();
49 struct GreaterByE :
public ClusBinaryFunction {
50 bool operator()(
const CalibClusterPtr&
x,
51 const CalibClusterPtr&
y) {
52 return x->energy() > y->energy() ;
56 struct GreaterByEt :
public ClusBinaryFunction {
57 bool operator()(
const CalibClusterPtr& x,
58 const CalibClusterPtr& y) {
59 return x->energy()/std::cosh(x->eta()) > y->energy()/std::cosh(y->eta());
63 struct IsASeed :
public ClusUnaryFunction {
66 bool operator()(
const CalibClusterPtr& x) {
71 struct IsLinkedByRecHit :
public ClusUnaryFunction {
72 const CalibClusterPtr the_seed;
73 const double _threshold, _majority;
74 const double _maxSatelliteDEta, _maxSatelliteDPhi;
75 double x_rechits_tot, x_rechits_match;
76 IsLinkedByRecHit(
const CalibClusterPtr&
s,
const double threshold,
77 const double majority,
const double maxDEta,
78 const double maxDPhi) :
79 the_seed(s),_threshold(threshold),_majority(majority),
80 _maxSatelliteDEta(maxDEta), _maxSatelliteDPhi(maxDPhi) {}
81 bool operator()(
const CalibClusterPtr& x) {
82 if( the_seed->energy_nocalib() < _threshold )
return false;
83 const double dEta =
std::abs(the_seed->eta()-x->eta());
86 if( _maxSatelliteDEta < dEta || _maxSatelliteDPhi < dPhi)
return false;
88 const auto& seedHitsAndFractions =
89 the_seed->the_ptr()->hitsAndFractions();
90 const auto& xHitsAndFractions =
91 x->the_ptr()->hitsAndFractions();
92 x_rechits_tot = xHitsAndFractions.size();
93 x_rechits_match = 0.0;
94 for(
const std::pair<DetId, float>& seedHit : seedHitsAndFractions ) {
95 for(
const std::pair<DetId, float>& xHit : xHitsAndFractions ) {
96 if( seedHit.first == xHit.first ) {
97 x_rechits_match += 1.0;
101 return x_rechits_match/x_rechits_tot > _majority;
105 struct IsClustered :
public ClusUnaryFunction {
106 const CalibClusterPtr the_seed;
109 double etawidthSuperCluster_, phiwidthSuperCluster_;
110 IsClustered(
const CalibClusterPtr
s,
112 const bool dyn_dphi) :
113 the_seed(s), _type(ct), dynamic_dphi(dyn_dphi) {}
114 bool operator()(
const CalibClusterPtr& x) {
118 const bool passes_dphi =
119 ( (!dynamic_dphi && dphi < phiwidthSuperCluster_ ) ||
127 return (
std::abs(the_seed->eta()-x->eta())<etawidthSuperCluster_ &&
131 return ( passes_dphi &&
162 if( eeclus->z()*psclus->z() < 0 )
return -1.0;
165 if( dphi > 0.6 )
return -1.0;
166 const double deta=
std::abs(eepos.eta() - pspos.eta());
167 if( deta > 0.3 )
return -1.0;
176 _pfEnergyCalibration =
calib;
181 const PFClusterView& psclusters) {
187 _psclustersforee.clear();
189 auto clusterPtrs = clusters.ptrVector();
191 for (
auto& cluster : clusterPtrs ){
193 <<
"Loading PFCluster i="<<cluster.key()
194 <<
" energy="<<cluster->energy()<<std::endl;
196 double Ecorr = _pfEnergyCalibration->energyEm(*cluster,
198 applyCrackCorrections_);
200 switch( cluster->layer() ) {
202 if( calib_cluster->energy() > threshPFClusterBarrel_ ) {
203 _clustersEB.push_back(calib_cluster);
207 if( calib_cluster->energy() > threshPFClusterEndcap_ ) {
208 _clustersEE.push_back(calib_cluster);
209 _psclustersforee.emplace(calib_cluster->the_ptr(),
219 double dist = -1.0, min_dist = -1.0;
222 for(
const auto& psclus : clusterPtrsPS ) {
223 if( psclus->energy() < threshPFClusterES_ )
continue;
224 switch( psclus->layer() ) {
232 dist = min_dist = -1.0;
233 for(
const auto& eeclus : _clustersEE ) {
234 dist = testPreshowerDistance(eeclus->the_ptr(),psclus);
235 if( dist == -1.0 || (min_dist != -1.0 && dist > min_dist) )
continue;
236 if( dist < min_dist || min_dist == -1.0 ) {
237 eematch = eeclus->the_ptr();
241 if( eematch.
isNonnull() ) _psclustersforee[eematch].push_back(psclus);
247 std::sort(_clustersEB.begin(), _clustersEB.end(), greater);
248 std::sort(_clustersEE.begin(), _clustersEE.end(), greater);
253 buildAllSuperClusters(_clustersEB, threshPFClusterSeedBarrel_);
255 buildAllSuperClusters(_clustersEE, threshPFClusterSeedEndcap_);
261 IsASeed seedable(seedthresh);
263 std::stable_partition(clusters.begin(),clusters.end(),seedable);
268 while( std::any_of(clusters.cbegin(), clusters.cend(), seedable) ) {
269 buildSuperCluster(clusters.front(),clusters);
275 CalibClusterPtrVector& clusters) {
276 IsClustered IsClusteredWithSeed(seed,_clustype,_useDynamicDPhi);
277 IsLinkedByRecHit MatchesSeedByRecHit(seed,satelliteThreshold_,
278 fractionForMajority_,0.1,0.2);
281 switch( seed->the_ptr()->layer() ) {
283 IsClusteredWithSeed.phiwidthSuperCluster_ = phiwidthSuperClusterBarrel_;
284 IsClusteredWithSeed.etawidthSuperCluster_ = etawidthSuperClusterBarrel_;
286 << superClustersEB_->size() + 1
287 <<
" in the ECAL barrel!";
290 IsClusteredWithSeed.phiwidthSuperCluster_ = phiwidthSuperClusterEndcap_;
291 IsClusteredWithSeed.etawidthSuperCluster_ = etawidthSuperClusterEndcap_;
293 << superClustersEE_->size() + 1
294 <<
" in the ECAL endcap!" << std::endl;
306 auto not_clustered = std::stable_partition(clusters.begin(),clusters.end(),
307 IsClusteredWithSeed);
310 if( doSatelliteClusterMerge_ ) {
311 not_clustered = std::stable_partition(not_clustered,clusters.end(),
312 MatchesSeedByRecHit);
316 edm::LogInfo(
"PFClustering") <<
"Dumping cluster detail";
318 <<
"\tPassed seed: e = " << seed->energy_nocalib()
319 <<
" eta = " << seed->eta() <<
" phi = " << seed->phi()
321 for(
auto clus = clusters.cbegin(); clus != not_clustered; ++clus ) {
323 <<
"\t\tClustered cluster: e = " << (*clus)->energy_nocalib()
324 <<
" eta = " << (*clus)->eta() <<
" phi = " << (*clus)->phi()
327 for(
auto clus = not_clustered; clus != clusters.end(); ++clus ) {
329 <<
"\tNon-Clustered cluster: e = " << (*clus)->energy_nocalib()
330 <<
" eta = " << (*clus)->eta() <<
" phi = " << (*clus)->phi()
337 clusters.erase(clusters.begin(),not_clustered);
339 std::vector<const reco::PFCluster*> bare_ptrs;
341 double posX(0), posY(0), posZ(0),
342 rawSCEnergy(0), corrSCEnergy(0), clusterCorrEE(0),
343 PS1_clus_sum(0), PS2_clus_sum(0);
344 for(
auto& clus : clustered ) {
345 bare_ptrs.push_back(clus->the_ptr().get());
347 const double cluseraw = clus->energy_nocalib();
349 posX += cluseraw * cluspos.X();
350 posY += cluseraw * cluspos.Y();
351 posZ += cluseraw * cluspos.Z();
354 const auto& psclusters = _psclustersforee[clus->the_ptr()];
355 PS1_clus_sum = std::accumulate(psclusters.begin(),psclusters.end(),
357 PS2_clus_sum = std::accumulate(psclusters.begin(),psclusters.end(),
360 _pfEnergyCalibration->energyEm(*(clus->the_ptr()),
361 PS1_clus_sum,PS2_clus_sum,
362 applyCrackCorrections_);
363 clus->resetCalibratedEnergy(clusterCorrEE);
366 rawSCEnergy += cluseraw;
367 corrSCEnergy += clus->energy();
375 double ps1_energy(0.0), ps2_energy(0.0), ps_energy(0.0);
376 new_sc.
setSeed(clustered.front()->the_ptr());
377 for(
const auto& clus : clustered ) {
379 auto& hits_and_fractions = clus->the_ptr()->hitsAndFractions();
380 for(
auto& hit_and_fraction : hits_and_fractions ) {
383 const auto& cluspsassociation = _psclustersforee[clus->the_ptr()];
386 for(
const auto& psclus : cluspsassociation ) {
391 const double psenergy = psclus->energy();
393 ps1_energy += (
PFLayer::PS1 == psclus->layer())*psenergy;
394 ps2_energy += (
PFLayer::PS2 == psclus->layer())*psenergy;
395 ps_energy += psenergy;
398 <<
"Found a PS cluster matched to more than one EE cluster!"
399 << std::endl << std::hex << psclus.
get() <<
" == "
400 << found_pscluster->get() << std::dec << std::endl;
417 switch( seed->the_ptr()->layer() ) {
419 superClustersEB_->push_back(new_sc);
422 superClustersEE_->push_back(new_sc);
CaloCluster_iterator preshowerClustersBegin() const
fist iterator over PreshowerCluster constituents
PFECALSuperClusterAlgo()
constructor
void addHitAndFraction(DetId id, float fraction)
bool inDynamicDPhiWindow(const bool isEE, const float seedPhi, const float ClustE, const float ClusEta, const float clusPhi)
static double testECALAndPSByRecHit(const reco::PFCluster &clusterECAL, const reco::PFCluster &clusterPS, bool debug=false)
void setPreshowerEnergyPlane2(double preshowerEnergy2)
ROOT::Math::PositionVector3D< ROOT::Math::CylindricalEta3D< Double32_t > > REPPoint
double pflowPhiWidth() const
double Phi_mpi_pi(double x)
void setSeed(const CaloClusterPtr &r)
list of used xtals by DetId // now inherited by CaloCluster
edm::Ptr< CaloCluster > CaloClusterPtr
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
void setPhiWidth(double pw)
double pflowEtaWidth() const
void setEtaWidth(double ew)
std::vector< CalibratedClusterPtr > CalibratedClusterPtrVector
std::shared_ptr< CalibratedPFCluster > CalibratedClusterPtr
bool isNonnull() const
Checks for non-null.
MVATrainerComputer * calib
void buildAllSuperClusters(CalibratedClusterPtrVector &, double seedthresh)
T const * get() const
Returns C++ pointer to the item.
double dPhi(double phi1, double phi2)
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
void loadAndSortPFClusters(const edm::View< reco::PFCluster > &ecalclusters, const edm::View< reco::PFCluster > &psclusters)
double rawEnergy() const
raw uncorrected energy (sum of energies of component BasicClusters)
XYZPointD XYZPoint
point in space with cartesian internal representation
void addPreshowerCluster(const CaloClusterPtr &r)
add reference to constituent BasicCluster
void buildSuperCluster(CalibratedClusterPtr &, CalibratedClusterPtrVector &)
bool GreaterByE(const T &a1, const T &a2)
void addCluster(const CaloClusterPtr &r)
add reference to constituent BasicCluster
bool isNull() const
Checks for null.
void setPreshowerEnergyPlane1(double preshowerEnergy1)
void setPFClusterCalibration(const std::shared_ptr< PFEnergyCalibration > &)
bool inMustache(const float maxEta, const float maxPhi, const float ClustE, const float ClusEta, const float ClusPhi)
CaloCluster_iterator preshowerClustersEnd() const
last iterator over PreshowerCluster constituents
void setPreshowerEnergy(double preshowerEnergy)