CMS 3D CMS Logo

EcalClustersGraph.cc
Go to the documentation of this file.
2 #include <cmath>
3 
4 using namespace std;
5 using namespace reco;
6 using namespace reco::DeepSCInputs;
7 
8 typedef std::vector<CalibratedPFCluster> CalibratedPFClusterVector;
9 
10 EcalClustersGraph::EcalClustersGraph(CalibratedPFClusterVector clusters,
11  int nSeeds,
12  const CaloTopology* topology,
13  const CaloSubdetectorGeometry* ebGeom,
14  const CaloSubdetectorGeometry* eeGeom,
17  const SCProducerCache* cache)
18  : clusters_(clusters),
19  nSeeds_(nSeeds),
20  nCls_(clusters_.size()),
21  topology_(topology),
22  ebGeom_(ebGeom),
23  eeGeom_(eeGeom),
24  recHitsEB_(recHitsEB),
25  recHitsEE_(recHitsEE),
26  scProducerCache_(cache),
27  graphMap_(clusters.size()) {
28  // Prepare the batch size of the tensor inputs == number of windows
29  inputs_.clustersX.resize(nSeeds_);
30  inputs_.windowX.resize(nSeeds_);
31  inputs_.hitsX.resize(nSeeds_);
32  inputs_.isSeed.resize(nSeeds_);
33 
34  // Init the graph nodes
35  for (size_t i = 0; i < nCls_; i++) {
36  if (i < nSeeds_)
37  graphMap_.addNode(i, GraphMap::NodeCategory::kSeed);
38  else
39  graphMap_.addNode(i, GraphMap::NodeCategory::kNode);
40  }
41 
42  // Select the collection strategy from the config
43  if (scProducerCache_->config.collectionStrategy == "Cascade") {
44  strategy_ = GraphMap::CollectionStrategy::Cascade;
45  } else if (scProducerCache_->config.collectionStrategy == "CollectAndMerge") {
46  strategy_ = GraphMap::CollectionStrategy::CollectAndMerge;
47  } else if (scProducerCache_->config.collectionStrategy == "SeedsFirst") {
48  strategy_ = GraphMap::CollectionStrategy::SeedsFirst;
49  } else if (scProducerCache_->config.collectionStrategy == "CascadeHighest") {
50  strategy_ = GraphMap::CollectionStrategy::CascadeHighest;
51  } else {
52  edm::LogWarning("EcalClustersGraph") << "GraphMap::CollectionStrategy not recognized. Default to Cascade";
53  strategy_ = GraphMap::CollectionStrategy::Cascade;
54  }
55 
56  LogTrace("EcalClustersGraph") << "EcalClustersGraph created. nSeeds " << nSeeds_ << ", nClusters " << nCls_ << endl;
57 }
58 
59 std::array<int, 3> EcalClustersGraph::clusterPosition(const CaloCluster* cluster) const {
60  std::array<int, 3> coordinates;
61  int ieta = -999;
62  int iphi = -999;
63  int iz = -99;
64 
65  const math::XYZPoint& caloPos = cluster->position();
66  if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_BARREL) {
67  EBDetId eb_id(ebGeom_->getClosestCell(GlobalPoint(caloPos.x(), caloPos.y(), caloPos.z())));
68  ieta = eb_id.ieta();
69  iphi = eb_id.iphi();
70  iz = 0;
71  } else if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_ENDCAP) {
72  EEDetId ee_id(eeGeom_->getClosestCell(GlobalPoint(caloPos.x(), caloPos.y(), caloPos.z())));
73  ieta = ee_id.ix();
74  iphi = ee_id.iy();
75  if (ee_id.zside() < 0)
76  iz = -1;
77  if (ee_id.zside() > 0)
78  iz = 1;
79  }
80 
81  coordinates[0] = ieta;
82  coordinates[1] = iphi;
83  coordinates[2] = iz;
84  return coordinates;
85 }
86 
87 std::array<double, 3> EcalClustersGraph::dynamicWindow(double seedEta) const {
88  // The dEta-dPhi detector window dimension is chosen to that the algorithm is always larger than
89  // the Mustache dimension
90  std::array<double, 3> window;
91 
92  double eta = std::abs(seedEta);
93  double deta_down = 0.;
94  double deta_up = 0.;
95  double dphi = 0.;
96 
97  //deta_down
98  constexpr float deta_down_bins[2] = {2.1, 2.5};
99  if (eta < deta_down_bins[0])
100  deta_down = -0.075;
101  else if (eta >= deta_down_bins[0] && eta < deta_down_bins[1])
102  deta_down = -0.1875 * eta + 0.31875;
103  else if (eta >= deta_down_bins[1])
104  deta_down = -0.15;
105 
106  //deta_up
107  constexpr float deta_up_bins[4] = {0.1, 1.3, 1.7, 1.9};
108  if (eta < deta_up_bins[0])
109  deta_up = 0.075;
110  else if (eta >= deta_up_bins[0] && eta < deta_up_bins[1])
111  deta_up = 0.0758929 - 0.0178571 * eta + 0.0892857 * (eta * eta);
112  else if (eta >= deta_up_bins[1] && eta < deta_up_bins[2])
113  deta_up = 0.2;
114  else if (eta >= deta_up_bins[2] && eta < deta_up_bins[3])
115  deta_up = 0.625 - 0.25 * eta;
116  else if (eta >= deta_up_bins[3])
117  deta_up = 0.15;
118 
119  //dphi
120  constexpr float dphi_bins[2] = {1.9, 2.7};
121  if (eta < dphi_bins[0])
122  dphi = 0.6;
123  else if (eta >= dphi_bins[0] && eta < dphi_bins[1])
124  dphi = 1.075 - 0.25 * eta;
125  else if (eta >= dphi_bins[1])
126  dphi = 0.4;
127 
128  window[0] = deta_down;
129  window[1] = deta_up;
130  window[2] = dphi;
131 
132  return window;
133 }
134 
136  for (uint is = 0; is < nSeeds_; is++) {
137  const auto& seedLocal = clusterPosition((clusters_[is]).ptr().get());
138  double seed_eta = clusters_[is].eta();
139  double seed_phi = clusters_[is].phi();
140  const auto& width = dynamicWindow(seed_eta);
141  // Add a self loop on the seed node
142  graphMap_.addEdge(is, is);
143 
144  // The graph associated to each seed includes only other seeds if they have a smaller energy.
145  // This is imposed to be consistent with the current trained model, which has been training on "non-overalapping windows".
146  // The effect of connecting all the seeds, and not only the smaller energy ones has been already tested: the reconstruction
147  // differences are negligible (tested with Cascade collection algo).
148  // In the next version of the training this requirement will be relaxed to have a model that fully matches the reconstruction
149  // mechanism in terms of overlapping seeds.
150  for (uint icl = is + 1; icl < nCls_; icl++) {
151  if (is == icl)
152  continue;
153  const auto& clusterLocal = clusterPosition((clusters_[icl]).ptr().get());
154  double cl_eta = clusters_[icl].eta();
155  double cl_phi = clusters_[icl].phi();
156  double dphi = deltaPhi(seed_phi, cl_phi);
157  double deta = deltaEta(seed_eta, cl_eta);
158 
159  if (seedLocal[2] == clusterLocal[2] && deta >= width[0] && deta <= width[1] && std::abs(dphi) <= width[2]) {
160  graphMap_.addEdge(is, icl);
161  }
162  }
163  }
164 }
165 
166 std::vector<std::vector<float>> EcalClustersGraph::fillHits(const CaloCluster* cluster) const {
167  const std::vector<std::pair<DetId, float>>& hitsAndFractions = cluster->hitsAndFractions();
168  std::vector<std::vector<float>> out(hitsAndFractions.size());
169  if (hitsAndFractions.empty()) {
170  edm::LogError("EcalClustersGraph") << "No hits in cluster!!";
171  }
172  // Map containing the available features for the rechits
173  DeepSCInputs::FeaturesMap rechitsFeatures;
174  for (unsigned int i = 0; i < hitsAndFractions.size(); i++) {
175  rechitsFeatures.clear();
176  if (hitsAndFractions[i].first.subdetId() == EcalBarrel) {
177  double energy = (*recHitsEB_->find(hitsAndFractions[i].first)).energy();
178  EBDetId eb_id(hitsAndFractions[i].first);
179  rechitsFeatures["ieta"] = eb_id.ieta(); //ieta
180  rechitsFeatures["iphi"] = eb_id.iphi(); //iphi
181  rechitsFeatures["iz"] = 0.; //iz
182  rechitsFeatures["en_withfrac"] = energy * hitsAndFractions[i].second; //energy * fraction
183  } else if (hitsAndFractions[i].first.subdetId() == EcalEndcap) {
184  double energy = (*recHitsEE_->find(hitsAndFractions[i].first)).energy();
185  EEDetId ee_id(hitsAndFractions[i].first);
186  rechitsFeatures["ieta"] = ee_id.ix(); //ix
187  rechitsFeatures["iphi"] = ee_id.iy(); //iy
188  if (ee_id.zside() < 0)
189  rechitsFeatures["iz"] = -1.; //iz
190  if (ee_id.zside() > 0)
191  rechitsFeatures["iz"] = +1.; //iz
192  rechitsFeatures["en_withfrac"] = energy * hitsAndFractions[i].second; //energy * fraction
193  } else {
194  edm::LogError("EcalClustersGraph") << "Rechit is not either EB or EE!!";
195  }
196  // Use the method in DeepSCGraphEvaluation to get only the requested variables and possible a rescaling
197  // (depends on configuration)
198  out[i] = scProducerCache_->deepSCEvaluator->getScaledInputs(rechitsFeatures,
199  scProducerCache_->deepSCEvaluator->inputFeaturesHits);
200  }
201  return out;
202 }
203 
205  const CaloCluster* cluster) const {
206  DeepSCInputs::FeaturesMap clFeatures;
207  const auto& clusterLocal = clusterPosition(cluster);
208  double cl_energy = cluster->energy();
209  double cl_eta = cluster->eta();
210  double cl_phi = cluster->phi();
211  double seed_energy = seed->energy();
212  double seed_eta = seed->eta();
213  double seed_phi = seed->phi();
214  clFeatures["cl_energy"] = cl_energy; //cl_energy
215  clFeatures["cl_et"] = cl_energy / std::cosh(cl_eta); //cl_et
216  clFeatures["cl_eta"] = cl_eta; //cl_eta
217  clFeatures["cl_phi"] = cl_phi; //cl_phi
218  clFeatures["cl_ieta"] = clusterLocal[0]; //cl_ieta/ix
219  clFeatures["cl_iphi"] = clusterLocal[1]; //cl_iphi/iy
220  clFeatures["cl_iz"] = clusterLocal[2]; //cl_iz
221  clFeatures["cl_seed_dEta"] = deltaEta(seed_eta, cl_eta); //cl_dEta
222  clFeatures["cl_seed_dPhi"] = deltaPhi(seed_phi, cl_phi); //cl_dPhi
223  clFeatures["cl_seed_dEnergy"] = seed_energy - cl_energy; //cl_dEnergy
224  clFeatures["cl_seed_dEt"] = (seed_energy / std::cosh(seed_eta)) - (cl_energy / std::cosh(cl_eta)); //cl_dEt
225  clFeatures["cl_nxtals"] = cluster->hitsAndFractions().size(); // nxtals
226  return clFeatures;
227 }
228 
230  const std::vector<DeepSCInputs::FeaturesMap>& clusters) const {
231  size_t nCls = clusters.size();
232  std::map<std::string, float> min;
233  std::map<std::string, float> max;
234  std::map<std::string, float> avg;
235  for (const auto& clFeatures : clusters) {
236  for (auto const& [key, val] : clFeatures) {
237  avg[key] += (val / nCls);
238  if (val < min[key])
239  min[key] = val;
240  if (val > max[key])
241  max[key] = val;
242  }
243  }
244  DeepSCInputs::FeaturesMap windFeatures;
245  for (auto const& el : clusters.front()) {
246  windFeatures["max_" + el.first] = max[el.first];
247  windFeatures["min_" + el.first] = min[el.first];
248  windFeatures["avg_" + el.first] = avg[el.first];
249  }
250  return windFeatures;
251 }
252 
253 std::pair<double, double> EcalClustersGraph::computeCovariances(const CaloCluster* cluster) {
254  double numeratorEtaWidth = 0;
255  double numeratorPhiWidth = 0;
256  double denominator = cluster->energy();
257  double clEta = cluster->position().eta();
258  double clPhi = cluster->position().phi();
259  std::shared_ptr<const CaloCellGeometry> this_cell;
261 
262  const std::vector<std::pair<DetId, float>>& detId = cluster->hitsAndFractions();
263  // Loop over recHits associated with the given SuperCluster
264  for (const auto& hit : detId) {
265  if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_BARREL) {
266  rHit = recHitsEB_->find(hit.first);
267  if (rHit == recHitsEB_->end()) {
268  continue;
269  }
270  this_cell = ebGeom_->getGeometry(rHit->id());
271  } else if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_ENDCAP) {
272  rHit = recHitsEE_->find(hit.first);
273  if (rHit == recHitsEE_->end()) {
274  continue;
275  }
276  this_cell = eeGeom_->getGeometry(rHit->id());
277  } else {
278  continue;
279  }
280 
281  GlobalPoint position = this_cell->getPosition();
282  //take into account energy fractions
283  double energyHit = rHit->energy() * hit.second;
284  //form differences
285  double dPhi = deltaPhi(position.phi(), clPhi);
286  double dEta = position.eta() - clEta;
287  if (energyHit > 0) {
288  numeratorEtaWidth += energyHit * dEta * dEta;
289  numeratorPhiWidth += energyHit * dPhi * dPhi;
290  }
291  }
292  double etaWidth = sqrt(numeratorEtaWidth / denominator);
293  double phiWidth = sqrt(numeratorPhiWidth / denominator);
294 
295  return std::make_pair(etaWidth, phiWidth);
296 }
297 
298 std::vector<double> EcalClustersGraph::computeShowerShapes(const CaloCluster* cluster, bool full5x5 = false) {
299  std::vector<double> showerVars_;
300  showerVars_.resize(8);
301  widths_ = computeCovariances(cluster);
302  float e1 = 1.;
303  float e4 = 0.;
304  float r9 = 0.;
305 
306  if (full5x5) {
307  if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_BARREL) {
314  r9 = noZS::EcalClusterTools::e3x3(*cluster, recHitsEB_, topology_) / cluster->energy(); //r9
315 
316  } else if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_ENDCAP) {
323  r9 = noZS::EcalClusterTools::e3x3(*cluster, recHitsEE_, topology_) / cluster->energy(); //r9
324  }
325  } else {
326  if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_BARREL) {
327  locCov_ = EcalClusterTools::localCovariances(*cluster, recHitsEB_, topology_);
328  e1 = EcalClusterTools::eMax(*cluster, recHitsEB_);
333  r9 = EcalClusterTools::e3x3(*cluster, recHitsEB_, topology_) / cluster->energy(); //r9
334  } else if (PFLayer::fromCaloID(cluster->caloID()) == PFLayer::ECAL_ENDCAP) {
335  locCov_ = EcalClusterTools::localCovariances(*cluster, recHitsEE_, topology_);
336  e1 = EcalClusterTools::eMax(*cluster, recHitsEE_);
341  r9 = EcalClusterTools::e3x3(*cluster, recHitsEE_, topology_) / cluster->energy();
342  }
343  }
344  showerVars_[0] = r9;
345  showerVars_[1] = sqrt(locCov_[0]); //sigmaietaieta
346  showerVars_[2] = locCov_[1]; //sigmaietaiphi
347  showerVars_[3] = (!edm::isFinite(locCov_[2])) ? 0. : sqrt(locCov_[2]); //sigmaiphiiphi
348  showerVars_[4] = (e1 != 0.) ? 1. - e4 / e1 : -999.; //swiss_cross
349  showerVars_[5] = cluster->hitsAndFractions().size(); //nXtals
350  showerVars_[6] = widths_.first; //etaWidth
351  showerVars_[7] = widths_.second; //phiWidth
352 
353  return showerVars_;
354 }
355 
357  LogDebug("EcalClustersGraph") << "Fill tensorflow input vector";
358  const auto& deepSCEval = scProducerCache_->deepSCEvaluator;
359  // Reserving the batch dimension
360  inputs_.clustersX.reserve(nSeeds_);
361  inputs_.hitsX.reserve(nSeeds_);
362  inputs_.windowX.reserve(nSeeds_);
363  inputs_.isSeed.reserve(nSeeds_);
364 
365  // Looping on all the seeds (window)
366  for (uint is = 0; is < nSeeds_; is++) {
367  const auto seedPointer = (clusters_[is]).ptr().get();
368  std::vector<DeepSCInputs::FeaturesMap> unscaledClusterFeatures;
369  const auto& outEdges = graphMap_.getOutEdges(is);
370  size_t ncls = outEdges.size();
371  // Reserve the vector size
372  inputs_.clustersX[is].reserve(ncls);
373  inputs_.hitsX[is].reserve(ncls);
374  inputs_.isSeed[is].reserve(ncls);
375  unscaledClusterFeatures.reserve(ncls);
376  // Loop on all the clusters
377  for (const auto ic : outEdges) {
378  LogTrace("EcalClustersGraph") << "seed: " << is << ", out edge --> " << ic;
379  const auto clPointer = (clusters_[ic]).ptr().get();
380  const auto& clusterFeatures = computeVariables(seedPointer, clPointer);
381  for (const auto& [key, val] : clusterFeatures) {
382  LogTrace("EcalCluster") << key << "=" << val;
383  }
384  unscaledClusterFeatures.push_back(clusterFeatures);
385  // Select and scale only the requested variables for the tensorflow model input
386  inputs_.clustersX[is].push_back(deepSCEval->getScaledInputs(clusterFeatures, deepSCEval->inputFeaturesClusters));
387  // The scaling and feature selection on hits is performed inside the function for each hit
388  inputs_.hitsX[is].push_back(fillHits(clPointer));
389  inputs_.isSeed[is].push_back(ic == is);
390  }
391  // For window we need the unscaled cluster features and then we select them
392  inputs_.windowX[is] =
393  deepSCEval->getScaledInputs(computeWindowVariables(unscaledClusterFeatures), deepSCEval->inputFeaturesWindows);
394  }
395  LogTrace("EcalClustersGraph") << "N. Windows: " << inputs_.clustersX.size();
396 }
397 
399  // Evaluate model
400  const auto& scores = scProducerCache_->deepSCEvaluator->evaluate(inputs_);
401  for (uint i = 0; i < nSeeds_; ++i) {
402  uint k = 0;
403  LogTrace("EcalClustersGraph") << "Score) seed: " << i << ":";
404  for (auto const& j : graphMap_.getOutEdges(i)) {
405  // Fill the scores from seed --> node (i --> j)
406  // Not symmetrically, in order to save multiple values for seeds in other
407  // seeds windows.
408  graphMap_.setAdjMatrix(i, j, scores[i][k]);
409  LogTrace("EcalClustersGraph") << "\t" << i << "-->" << j << ": " << scores[i][k];
410  k++;
411  }
412  }
413 }
414 
416  // Simple global threshold for the moment
417  threshold_ = 0.5;
418 }
419 
421  // Collect the final superClusters as subgraphs
423 }
424 
427  const auto& finalSuperClusters_ = graphMap_.getGraphOutput();
428  for (const auto& [is, cls] : finalSuperClusters_) {
430  CalibratedPFClusterVector clusters_inWindow;
431  for (const auto& ic : cls) {
432  clusters_inWindow.push_back(clusters_[ic]);
433  }
434  finalWindows_.push_back({seed, clusters_inWindow});
435  }
436  return finalWindows_;
437 }
reco::DeepSCConfiguration config
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:154
std::array< double, 3 > dynamicWindow(double seedEta) const
std::vector< std::vector< float > > windowX
const GraphOutput & getGraphOutput()
Definition: GraphMap.h:60
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:210
const CaloTopology * topology_
CalibratedPFClusterVector clusters_
const EcalRecHitCollection * recHitsEB_
const EcalRecHitCollection * recHitsEE_
reco::DeepSCInputs::Inputs inputs_
EcalGraphOutput getGraphOutput()
static float eMax(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits)
DeepSCInputs::FeaturesMap computeWindowVariables(const std::vector< DeepSCInputs::FeaturesMap > &clusters) const
const reco::SCProducerCache * scProducerCache_
int iphi() const
get the crystal iphi
Definition: EBDetId.h:51
std::pair< double, double > widths_
int ix() const
Definition: EEDetId.h:77
std::vector< EcalRecHit >::const_iterator const_iterator
const CaloSubdetectorGeometry * eeGeom_
reco::GraphMap::CollectionStrategy strategy_
void addNode(const uint index, const NodeCategory category)
Definition: GraphMap.cc:15
Log< level::Error, false > LogError
constexpr bool isFinite(T x)
const CaloID & caloID() const
Definition: CaloCluster.h:201
std::vector< double > computeShowerShapes(const CaloCluster *cluster, bool full5x5)
double phi() const
azimuthal angle of cluster centroid
Definition: CaloCluster.h:184
std::array< float, 3 > locCov_
#define LogTrace(id)
double deltaEta(double seed_eta, double cluster_eta) const
int ieta() const
get the crystal ieta
Definition: EBDetId.h:49
std::map< std::string, double > FeaturesMap
static std::array< float, 3 > localCovariances(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology, float w0=EgammaLocalCovParamDefaults::kRelEnCut, const EcalPFRecHitThresholds *thresholds=nullptr, float multEB=0.0, float multEE=0.0)
const std::vector< uint > & getOutEdges(const uint i) const
Definition: GraphMap.cc:41
void collectNodes(GraphMap::CollectionStrategy strategy, float threshold)
Definition: GraphMap.cc:97
std::vector< CalibratedPFCluster > CalibratedPFClusterVector
T sqrt(T t)
Definition: SSEVec.h:23
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void setAdjMatrix(const uint i, const uint j, const float score)
Definition: GraphMap.cc:34
key
prepare the HTCondor submission files and eventually submit them
static float eBottom(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
def window(xmin, xmax, ymin, ymax, x=0, y=0, width=100, height=100, xlogbase=None, ylogbase=None, minusInfinity=-1000, flipx=False, flipy=True)
Definition: svgfig.py:643
DeepSCInputs::FeaturesMap computeVariables(const CaloCluster *seed, const CaloCluster *cluster) const
std::array< int, 3 > clusterPosition(const CaloCluster *cluster) const
const CaloSubdetectorGeometry * ebGeom_
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.
virtual DetId getClosestCell(const GlobalPoint &r) const
const_iterator end() const
double energy() const
cluster energy
Definition: CaloCluster.h:149
static float eTop(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
std::vector< std::vector< std::vector< float > > > clustersX
void addEdge(const uint i, const uint j)
Definition: GraphMap.cc:26
int zside() const
Definition: EEDetId.h:71
std::vector< std::vector< float > > fillHits(const CaloCluster *cluster) const
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float >, ROOT::Math::GlobalCoordinateSystemTag > GlobalPoint
point in global coordinate system
Definition: Point3D.h:18
iterator find(key_type k)
fixed size matrix
static int position[264][3]
Definition: ReadPGInfo.cc:289
def cache(function)
Definition: utilities.py:3
static Layer fromCaloID(const reco::CaloID &id)
Definition: PFLayer.cc:38
static float eRight(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
std::vector< CalibratedPFCluster > CalibratedPFClusterVector
static float e3x3(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:181
std::vector< std::vector< bool > > isSeed
Log< level::Warning, false > LogWarning
std::vector< std::pair< CalibratedPFCluster, CalibratedPFClusterVector > > EcalGraphOutput
static float eLeft(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
std::unique_ptr< const DeepSCGraphEvaluation > deepSCEvaluator
std::vector< std::vector< std::vector< std::vector< float > > > > hitsX
std::pair< double, double > computeCovariances(const CaloCluster *cluster)
int iy() const
Definition: EEDetId.h:83
#define LogDebug(id)