CMS 3D CMS Logo

EgammaPCAHelper.cc
Go to the documentation of this file.
1 
3 
8 
10 
11 // To retrieve HGCalImagingAlgo::maxlayer
12 // Also available as HGCal3DClustering::lastLayerBH and HGCalDepthPreClusterer::lastLayerBH
14 
15 #include <algorithm>
16 #include <iostream>
17 
18 using namespace hgcal;
19 
21  // Thickness correction to dEdx weights
22  // (100um, 200um, 300um silicon)
23  // See RecoLocalCalo.HGCalRecProducers.HGCalRecHit_cfi
24  invThicknessCorrection_({1. / 1.132, 1. / 1.092, 1. / 1.084}),
25  pca_(new TPrincipal(3, "D")) {
26  hitMapOrigin_ = 0;
27  hitMap_ = new std::map<DetId, const HGCRecHit *>();
28  debug_ = false;
29 }
30 
32  if (hitMapOrigin_ == 2) delete hitMap_;
33 }
34 
35 void EGammaPCAHelper::setHitMap( std::map<DetId,const HGCRecHit *> * hitMap) {
36  hitMapOrigin_ = 1;
37  hitMap_ = hitMap ;
38  pcaIteration_ = 0;
39 }
40 
42  recHitTools_ = recHitTools;
43 }
44 
46  const HGCRecHitCollection & rechitsFH,
47  const HGCRecHitCollection & rechitsBH) {
48  hitMap_->clear();
49  for (const auto& hit : rechitsEE) {
50  hitMap_->emplace_hint(hitMap_->end(), hit.detid(), &hit);
51  }
52 
53  for (const auto& hit : rechitsFH) {
54  hitMap_->emplace_hint(hitMap_->end(), hit.detid(), &hit);
55  }
56 
57  for (const auto& hit : rechitsBH) {
58  hitMap_->emplace_hint(hitMap_->end(), hit.detid(), &hit);
59  }
60 
61  pcaIteration_ = 0;
62  hitMapOrigin_ = 2;
63 }
64 
66  theCluster_ = &cluster;
67  std::vector<std::pair<DetId, float>> result;
68  for (reco::HGCalMultiCluster::component_iterator it = cluster.begin(); it != cluster.end();
69  it++) {
70  const std::vector<std::pair<DetId, float>> &hf = (*it)->hitsAndFractions();
71  result.insert(result.end(),hf.begin(),hf.end());
72  }
73  storeRecHits(result);
74 }
75 
77  theCluster_ = &cluster;
78  storeRecHits(cluster.hitsAndFractions());
79 }
80 
81 void EGammaPCAHelper::storeRecHits(const std::vector<std::pair<DetId, float>> &hf) {
82  std::vector<double> pcavars;
83  pcavars.resize(3,0.);
84  theSpots_.clear();
85  pcaIteration_ = 0;
86 
87  sigu_ = 0.;
88  sigv_ = 0.;
89  sigp_ = 0.;
90  sige_ = 0.;
91 
92  unsigned hfsize = hf.size();
93  if (debug_)
94  std::cout << "The seed cluster constains " << hfsize << " hits " << std::endl;
95 
96  if (hfsize == 0) return;
97 
98 
99  for (unsigned int j = 0; j < hfsize; j++) {
100  unsigned int layer = recHitTools_->getLayerWithOffset(hf[j].first);
101 
102  const DetId rh_detid = hf[j].first;
103  std::map<DetId,const HGCRecHit *>::const_iterator itcheck= hitMap_->find(rh_detid);
104  if (itcheck == hitMap_->end()) {
105  edm::LogWarning("EgammaPCAHelper") << " Big problem, unable to find a hit " << rh_detid.rawId() << " " << rh_detid.det() << " " << HGCalDetId(rh_detid) << std::endl;
106  continue;
107  }
108  if (debug_) {
109  std::cout << "DetId " << rh_detid.rawId() << " " << layer << " " << itcheck->second->energy() <<std::endl;
110  std::cout << " Hit " << itcheck->second << " " << itcheck->second->energy() << std::endl;
111  }
112  float fraction = hf[j].second;
113 
114  int thickIndex = recHitTools_->getSiThickIndex(rh_detid);
115  double mip = dEdXWeights_[layer] * 0.001; // convert in GeV
116  if(thickIndex>-1 and thickIndex<3) mip *= invThicknessCorrection_[thickIndex];
117 
118  pcavars[0] = recHitTools_->getPosition(rh_detid).x();
119  pcavars[1] = recHitTools_->getPosition(rh_detid).y();
120  pcavars[2] = recHitTools_->getPosition(rh_detid).z();
121  if (pcavars[2] == 0.)
122  edm::LogWarning("EgammaPCAHelper") << " Problem, hit with z =0 ";
123  else {
124  Spot mySpot(rh_detid,itcheck->second->energy(),pcavars,layer,fraction,mip);
125  theSpots_.push_back(mySpot);
126  }
127  }
128  if (debug_) {
129  std::cout << " Stored " << theSpots_.size() << " hits " << std::endl;
130  }
131 }
132 
133 void EGammaPCAHelper::computePCA(float radius , bool withHalo) {
134  // very important - to reset
135  pca_.reset(new TPrincipal(3, "D"));
136  bool initialCalculation = radius < 0;
137  if (debug_)
138  std::cout << " Initial calculation " << initialCalculation << std::endl;
139  if (initialCalculation && withHalo) {
140  edm::LogWarning("EGammaPCAHelper") << "Warning - in the first iteration, the halo hits are excluded " << std::endl;
141  withHalo=false;
142  }
143 
144  float radius2 = radius*radius;
145  if (! initialCalculation) {
146  math::XYZVector mainAxis(axis_);
147  mainAxis.unit();
148  math::XYZVector phiAxis(barycenter_.x(), barycenter_.y(), 0);
149  math::XYZVector udir(mainAxis.Cross(phiAxis));
150  udir = udir.unit();
152  Point(0., 0., 1.), Point(1., 0., 0.));
153  }
154 
155  std::set<int> layers;
156  for (const auto& spot : theSpots_) {
157  if (spot.layer() > recHitTools_->lastLayerEE()) continue;
158  if (!withHalo && (! spot.isCore() ))
159  continue;
160  if (initialCalculation) {
161  // initial calculation, take only core hits
162  if ( ! spot.isCore() ) continue;
163  layers.insert(spot.layer());
164  for (int i = 0; i < spot.multiplicity(); ++i)
165  pca_->AddRow(spot.row());
166  }
167  else {
168  // use a cylinder, include all hits
169  math::XYZPoint local = trans_(Point( spot.row()[0],spot.row()[1],spot.row()[2]));
170  if (local.Perp2() > radius2) continue;
171  layers.insert(spot.layer());
172  for (int i = 0; i < spot.multiplicity(); ++i)
173  pca_->AddRow(spot.row());
174  }
175  }
176  if (debug_)
177  std::cout << " Nlayers " << layers.size() << std::endl;
178  if (layers.size() < 3) {
179  pcaIteration_ = -1;
180  return;
181  }
182  pca_->MakePrincipals();
183  ++pcaIteration_;
184  const TVectorD& means = *(pca_->GetMeanValues());
185  const TMatrixD& eigens = *(pca_->GetEigenVectors());
186 
187  barycenter_ = math::XYZPoint(means[0], means[1], means[2]);
188  axis_ = math::XYZVector(eigens(0, 0), eigens(1, 0), eigens(2, 0));
189  if (axis_.z() * barycenter_.z() < 0.0) {
190  axis_ = -1. * axis_;
191  }
192 }
193 
194  void EGammaPCAHelper::computeShowerWidth(float radius, bool withHalo){
195  sigu_ = 0.;
196  sigv_ = 0.;
197  sigp_ = 0.;
198  sige_ = 0.;
199  double cyl_ene = 0.;
200 
201  float radius2 = radius * radius;
202  for (const auto& spot : theSpots_) {
203  Point globalPoint(spot.row()[0],spot.row()[1],spot.row()[2]);
204  math::XYZPoint local = trans_(globalPoint);
205  if (local.Perp2() > radius2) continue;
206 
207  // Select halo hits or not
208  if (withHalo && spot.fraction() < 0) continue;
209  if (!withHalo && !(spot.isCore())) continue;
210 
211  sige_ += (globalPoint.eta() - theCluster_->eta()) * (globalPoint.eta() - theCluster_->eta()) * spot.energy();
212  sigp_ += deltaPhi(globalPoint.phi(), theCluster_->phi()) * deltaPhi(globalPoint.phi(), theCluster_->phi()) *
213  spot.energy();
214 
215  sigu_ += local.x() * local.x() * spot.energy();
216  sigv_ += local.y() * local.y() * spot.energy();
217  cyl_ene += spot.energy();
218  }
219 
220  if (cyl_ene > 0.) {
221  const double inv_cyl_ene = 1. / cyl_ene;
222  sigu_ = sigu_ * inv_cyl_ene;
223  sigv_ = sigv_ * inv_cyl_ene;
224  sigp_ = sigp_ * inv_cyl_ene;
225  sige_ = sige_ * inv_cyl_ene;
226  }
227  sigu_ = std::sqrt(sigu_);
228  sigv_ = std::sqrt(sigv_);
229  sigp_ = std::sqrt(sigp_);
230  sige_ = std::sqrt(sige_);
231 }
232 
234  if (pcaIteration_ == 0) {
235  if(debug_)
236  std::cout << " The PCA has not been run yet " << std::endl;
237  return false;
238  } else if (pcaIteration_ == 1) {
239  if (debug_)
240  std::cout << " The PCA has been run only once - careful " << std::endl;
241  return false;
242  } else if (pcaIteration_ == -1){
243  if (debug_)
244  std::cout << " Not enough layers to perform PCA " << std::endl;
245  return false;
246  }
247  return true;
248 }
249 
251  theSpots_.clear();
252  pcaIteration_ = 0;
253  sigu_ = 0.;
254  sigv_ = 0.;
255  sigp_ = 0.;
256  sige_ = 0.;
257 }
258 
260  if (debug_) checkIteration();
261  std::set<int> layers;
262  float radius2 = radius*radius;
263  std::vector<float> energyPerLayer(HGCalClusteringAlgoBase::maxlayer+1, 0.f);
264  math::XYZVector mainAxis(axis_);
265  mainAxis.unit();
266  math::XYZVector phiAxis(barycenter_.x(), barycenter_.y(), 0);
267  math::XYZVector udir(mainAxis.Cross(phiAxis));
268  udir = udir.unit();
270  Point(0., 0., 1.), Point(1., 0., 0.));
271  float energyEE = 0.;
272  float energyFH = 0.;
273  float energyBH = 0.;
274 
275  for (const auto& spot : theSpots_) {
276  if (!withHalo && ! spot.isCore())
277  continue;
278  math::XYZPoint local = trans_(Point( spot.row()[0],spot.row()[1],spot.row()[2]));
279  if (local.Perp2() > radius2) continue;
280  energyPerLayer[spot.layer()] += spot.energy();
281  layers.insert(spot.layer());
282  if (spot.detId().det() == DetId::HGCalEE or spot.subdet() == HGCEE) { energyEE += spot.energy();}
283  else if (spot.detId().det() == DetId::HGCalHSi or spot.subdet() == HGCHEF) { energyFH += spot.energy();}
284  else if (spot.detId().det() == DetId::HGCalHSc or spot.subdet() == HGCHEB) { energyBH += spot.energy();}
285 
286  }
287  return LongDeps(radius,energyPerLayer,energyEE,energyFH,energyBH,layers);
288 }
289 
291  unsigned nSpots = theSpots_.size();
292  float radius2=radius*radius;
293  for ( unsigned i =0; i< nSpots ; ++i) {
294  Spot spot(theSpots_[i]);
295  math::XYZPoint local = trans_(Point( spot.row()[0],spot.row()[1],spot.row()[2]));
296  if (local.Perp2() < radius2 ) {
297  std::cout << i << " " << theSpots_[i].detId().rawId() << " " << theSpots_[i].layer() << " " << theSpots_[i].energy() << " " <<theSpots_[i].isCore() ;
298  std::cout << " " << std::sqrt(local.Perp2()) << std::endl;
299  }
300  }
301 }
302 
304  unsigned int firstLayer = 0;
305  for(unsigned il=1;il<=HGCalClusteringAlgoBase::maxlayer;++il) {
306  if (ld.energyPerLayer()[il] > 0.) {
307  firstLayer = il;
308  break;
309  }
310  }
311  // Make dummy DetId to get abs(z) for layer
312  return recHitTools_->getPositionLayer(firstLayer).z();
313 }
314 
315 float EGammaPCAHelper::clusterDepthCompatibility(const LongDeps & ld, float & measuredDepth, float& expectedDepth, float&expectedSigma) {
316  expectedDepth = -999.;
317  expectedSigma = -999.;
318  measuredDepth = -999.;
319  if (!checkIteration()) return -999.;
320 
321  float z = findZFirstLayer(ld);
322  math::XYZVector dir=axis_.unit();
323  measuredDepth = std::abs((z-std::abs(barycenter_.z()))/dir.z());
324  return showerDepth_.getClusterDepthCompatibility(measuredDepth,ld.energyEE(), expectedDepth,expectedSigma);
325 }
void computeShowerWidth(float radius, bool withHalo=true)
GlobalPoint getPositionLayer(int layer) const
Definition: RecHitTools.cc:124
math::XYZPoint barycenter_
float energyEE() const
Definition: LongDeps.h:20
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
void computePCA(float radius, bool withHalo=true)
std::map< DetId, const HGCRecHit * > * hitMap_
LongDeps energyPerLayer(float radius, bool withHalo=true)
float findZFirstLayer(const LongDeps &) const
std::unique_ptr< TPrincipal > pca_
component_iterator begin() const
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
T y() const
Definition: PV3DBase.h:63
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:197
float getClusterDepthCompatibility(float measuredDepth, float emEnergy, float &expectedDepth, float &expectedSigma) const
Definition: ShowerDepth.cc:6
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:168
void storeRecHits(const reco::CaloCluster &theCluster)
T sqrt(T t)
Definition: SSEVec.h:18
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
T z() const
Definition: PV3DBase.h:64
void setHitMap(std::map< DetId, const HGCRecHit * > *hitMap)
to set from outside - once per event
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
std::vector< Spot > theSpots_
unsigned int lastLayerEE() const
Definition: RecHitTools.h:58
ROOT::Math::Transform3D Transform3D
component_iterator end() const
Definition: DetId.h:18
void setRecHitTools(const hgcal::RecHitTools *recHitTools)
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:283
float clusterDepthCompatibility(const LongDeps &, float &measuredDepth, float &expectedDepth, float &expectedSigma)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
int getSiThickIndex(const DetId &) const
Definition: RecHitTools.cc:168
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
const std::vector< float > & energyPerLayer() const
Definition: LongDeps.h:23
void printHits(float radius) const
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:112
static const unsigned int maxlayer
Structure Point Contains parameters of Gaussian fits to DMRs.
Definition: DMRtrends.cc:55
const double * row() const
Definition: Spot.h:17
std::vector< double > invThicknessCorrection_
void fillHitMap(const HGCRecHitCollection &HGCEERecHits, const HGCRecHitCollection &HGCFHRecHits, const HGCRecHitCollection &HGCBHRecHits)
to compute from inside - once per event
std::vector< double > dEdXWeights_
const reco::CaloCluster * theCluster_
bool checkIteration() const
dbl *** dir
Definition: mlp_gen.cc:35
double phi() const
azimuthal angle of cluster centroid
Definition: CaloCluster.h:171
ROOT::Math::Transform3D::Point Point
T x() const
Definition: PV3DBase.h:62
const hgcal::RecHitTools * recHitTools_
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:39