CMS 3D CMS Logo

HGCalImagingAlgo.cc
Go to the documentation of this file.
2 
3 // Geometry
8 
10 //
12 
14  //loop over all hits and create the Hexel structure, skip energies below ecut
15 
16  if (dependSensor) {
17  // for each layer and wafer calculate the thresholds (sigmaNoise and energy) once
19  }
20 
21  for (unsigned int i=0;i<hits.size();++i) {
22 
23  const HGCRecHit& hgrh = hits[i];
24  DetId detid = hgrh.detid();
25  unsigned int layer = rhtools_.getLayerWithOffset(detid);
26  float thickness = 0.;
27  // set sigmaNoise default value 1 to use kappa value directly in case of sensor-independent thresholds
28  float sigmaNoise = 1.;
29  if(dependSensor){
30  if (layer<= lastLayerFH) // only EE and FH have silicon sensors
31  thickness = rhtools_.getSiThickness(detid);
32  double storedThreshold=thresholds[layer-1][layer<=lastLayerFH ? rhtools_.getWafer(detid) : 0];
33  sigmaNoise = v_sigmaNoise[layer-1][layer<=lastLayerFH ? rhtools_.getWafer(detid) : 0];
34 
35  if(hgrh.energy() < storedThreshold)
36  continue; //this sets the ZS threshold at ecut times the sigma noise for the sensor
37  }
38  if(!dependSensor && hgrh.energy() < ecut) continue;
39 
40  // map layers from positive endcap (z) to layer + maxlayer+1 to prevent mixing up hits from different sides
41  layer += int(rhtools_.zside(detid)>0)*(maxlayer+1);
42 
43  // determine whether this is a half-hexagon
44  bool isHalf = rhtools_.isHalfCell(detid);
45  const GlobalPoint position( std::move( rhtools_.getPosition( detid ) ) );
46 
47  //here's were the KDNode is passed its dims arguments - note that these are *copied* from the Hexel
48  points[layer].emplace_back(Hexel(hgrh,detid,isHalf,sigmaNoise,thickness,&rhtools_),position.x(),position.y());
49 
50  // for each layer, store the minimum and maximum x and y coordinates for the KDTreeBox boundaries
51  if(minpos[layer][0] == 0.0f){
52  minpos[layer][0] = position.x(); minpos[layer][1] = position.y();
53  maxpos[layer][0] = position.x(); maxpos[layer][1] = position.y();
54  }else{
55  minpos[layer][0] = std::min((float)position.x(),minpos[layer][0]);
56  minpos[layer][1] = std::min((float)position.y(),minpos[layer][1]);
57  maxpos[layer][0] = std::max((float)position.x(),maxpos[layer][0]);
58  maxpos[layer][1] = std::max((float)position.y(),maxpos[layer][1]);
59  }
60 
61  } // end loop hits
62 
63 }
64 // Create a vector of Hexels associated to one cluster from a collection of HGCalRecHits - this can be used
65 // directly to make the final cluster list - this method can be invoked multiple times for the same event
66 // with different input (reset should be called between events)
68 {
69 
70  // used for speedy search
71  std::vector<KDTree> hit_kdtree(2*(maxlayer+1));
72 
73  //assign all hits in each layer to a cluster core or halo
74  for (unsigned int i = 0; i <= 2*maxlayer+1; ++i) {
75  KDTreeBox bounds(minpos[i][0],maxpos[i][0],
76  minpos[i][1],maxpos[i][1]);
77 
78  hit_kdtree[i].build(points[i],bounds);
79 
80  unsigned int actualLayer = i > maxlayer ? (i-(maxlayer+1)) : i; // maps back from index used for KD trees to actual layer
81 
82  double maxdensity = calculateLocalDensity(points[i],hit_kdtree[i], actualLayer); // also stores rho (energy density) for each point (node)
83  // calculate distance to nearest point with higher density storing distance (delta) and point's index
85  findAndAssignClusters(points[i],hit_kdtree[i],maxdensity,bounds,actualLayer);
86  }
87  //make the cluster vector
88 }
89 
90 std::vector<reco::BasicCluster> HGCalImagingAlgo::getClusters(bool doSharing){
91 
93  std::vector< std::pair<DetId, float> > thisCluster;
94  for (unsigned int i = 0; i < current_v.size(); ++i){
95  double energy = 0;
97 
98  if( doSharing ) {
99 
100  std::vector<unsigned> seeds = findLocalMaximaInCluster(current_v[i]);
101  // sharing found seeds.size() sub-cluster seeds in cluster i
102 
103  std::vector<std::vector<double> > fractions;
104  // first pass can have noise it in
105  shareEnergy(current_v[i],seeds,fractions);
106 
107  // reset and run second pass after vetoing seeds
108  // that result in trivial clusters (less than 2 effective cells)
109 
110 
111  for( unsigned isub = 0; isub < fractions.size(); ++isub ) {
112  double effective_hits = 0.0;
113  double energy = calculateEnergyWithFraction(current_v[i],fractions[isub]);
114  Point position = calculatePositionWithFraction(current_v[i],fractions[isub]);
115 
116  for( unsigned ihit = 0; ihit < fractions[isub].size(); ++ihit ) {
117  const double fraction = fractions[isub][ihit];
118  if( fraction > 1e-7 ) {
119  effective_hits += fraction;
120  thisCluster.emplace_back(current_v[i][ihit].data.detid,fraction);
121  }
122  }
123 
124  if (verbosity < pINFO)
125  {
126  std::cout << "\t******** NEW CLUSTER (SHARING) ********" << std::endl;
127  std::cout << "\tEff. No. of cells = " << effective_hits << std::endl;
128  std::cout << "\t Energy = " << energy << std::endl;
129  std::cout << "\t Phi = " << position.phi() << std::endl;
130  std::cout << "\t Eta = " << position.eta() << std::endl;
131  std::cout << "\t*****************************" << std::endl;
132  }
133  clusters_v.push_back(reco::BasicCluster(energy, position, caloID, thisCluster,
134  algoId));
135  thisCluster.clear();
136  }
137  }else{
138  position = calculatePosition(current_v[i]); // energy-weighted position
139  // std::vector< KDNode >::iterator it;
140  for (auto& it: current_v[i])
141  {
142  energy += it.data.isHalo ? 0. : it.data.weight;
143  // use fraction to store whether this is a Halo hit or not
144  thisCluster.emplace_back(std::pair<DetId, float>(it.data.detid,(it.data.isHalo?0.:1.)));
145  };
146  if (verbosity < pINFO)
147  {
148  std::cout << "******** NEW CLUSTER (HGCIA) ********" << std::endl;
149  std::cout << "Index " << i << std::endl;
150  std::cout << "No. of cells = " << current_v[i].size() << std::endl;
151  std::cout << " Energy = " << energy << std::endl;
152  std::cout << " Phi = " << position.phi() << std::endl;
153  std::cout << " Eta = " << position.eta() << std::endl;
154  std::cout << "*****************************" << std::endl;
155  }
156  clusters_v.push_back(reco::BasicCluster(energy, position, caloID, thisCluster,
157  algoId));
158  thisCluster.clear();
159  }
160  }
161  return clusters_v;
162 }
163 
165  float total_weight = 0.;
166  float x = 0.;
167  float y = 0.;
168  float z = 0.;
169  unsigned int v_size = v.size();
170 
171  for (unsigned int i = 0; i < v_size; i++){
172  if(!v[i].data.isHalo){
173  total_weight += v[i].data.weight;
174  x += v[i].data.x*v[i].data.weight;
175  y += v[i].data.y*v[i].data.weight;
176  z += v[i].data.z*v[i].data.weight;
177  }
178  }
179 
180  if (total_weight != 0) {
181  return math::XYZPoint( x/total_weight,
182  y/total_weight,
183  z/total_weight );
184  }
185  return math::XYZPoint(0, 0, 0);
186 }
187 
188 double HGCalImagingAlgo::calculateLocalDensity(std::vector<KDNode> &nd, KDTree &lp, const unsigned int layer){
189 
190  double maxdensity = 0.;
191  float delta_c; // maximum search distance (critical distance) for local density calculation
192  if( layer<= lastLayerEE ) delta_c = vecDeltas[0];
193  else if( layer <= lastLayerFH) delta_c = vecDeltas[1];
194  else delta_c = vecDeltas[2];
195 
196  // for each node calculate local density rho and store it
197  for(unsigned int i = 0; i < nd.size(); ++i){
198  // speec up search by looking within +/- delta_c window only
199  KDTreeBox search_box(nd[i].dims[0]-delta_c,nd[i].dims[0]+delta_c,
200  nd[i].dims[1]-delta_c,nd[i].dims[1]+delta_c);
201  std::vector<KDNode> found;
202  lp.search(search_box,found);
203  const unsigned int found_size = found.size();
204  for(unsigned int j = 0; j < found_size; j++){
205  if(distance(nd[i].data,found[j].data) < delta_c){
206  nd[i].data.rho += found[j].data.weight;
207  if(nd[i].data.rho > maxdensity) maxdensity = nd[i].data.rho;
208  }
209  } // end loop found
210  } // end loop nodes
211  return maxdensity;
212 }
213 
214 double HGCalImagingAlgo::calculateDistanceToHigher(std::vector<KDNode> &nd){
215 
216 
217  //sort vector of Hexels by decreasing local density
218  std::vector<size_t> rs = sorted_indices(nd);
219 
220  double maxdensity = 0.0;
221  int nearestHigher = -1;
222 
223 
224  if(rs.size()>0)
225  maxdensity = nd[rs[0]].data.rho;
226  else
227  return maxdensity; // there are no hits
228  double dist2 = 0.;
229  //start by setting delta for the highest density hit to
230  //the most distant hit - this is a convention
231 
232  for (auto& j: nd) {
233  double tmp = distance2(nd[rs[0]].data, j.data);
234  if (tmp > dist2)
235  dist2 = tmp;
236  }
237  nd[rs[0]].data.delta = std::sqrt(dist2);
238  nd[rs[0]].data.nearestHigher = nearestHigher;
239 
240  //now we save the largest distance as a starting point
241  const double max_dist2 = dist2;
242  const unsigned int nd_size = nd.size();
243 
244  for(unsigned int oi = 1; oi < nd_size; ++oi){ // start from second-highest density
245  dist2 = max_dist2;
246  unsigned int i = rs[oi];
247  // we only need to check up to oi since hits
248  // are ordered by decreasing density
249  // and all points coming BEFORE oi are guaranteed to have higher rho
250  // and the ones AFTER to have lower rho
251  for(unsigned int oj = 0; oj < oi; ++oj){
252  unsigned int j = rs[oj];
253  double tmp = distance2(nd[i].data, nd[j].data);
254  if(tmp <= dist2){ //this "<=" instead of "<" addresses the (rare) case when there are only two hits
255  dist2 = tmp;
256  nearestHigher = j;
257  }
258  }
259  nd[i].data.delta = std::sqrt(dist2);
260  nd[i].data.nearestHigher = nearestHigher; //this uses the original unsorted hitlist
261  }
262  return maxdensity;
263 }
264 
265 int HGCalImagingAlgo::findAndAssignClusters(std::vector<KDNode> &nd,KDTree &lp, double maxdensity, KDTreeBox &bounds, const unsigned int layer){
266 
267  //this is called once per layer and endcap...
268  //so when filling the cluster temporary vector of Hexels we resize each time by the number
269  //of clusters found. This is always equal to the number of cluster centers...
270 
271  unsigned int clusterIndex = 0;
272  float delta_c; // critical distance
273  if( layer<=lastLayerEE ) delta_c = vecDeltas[0];
274  else if( layer<=lastLayerFH ) delta_c = vecDeltas[1];
275  else delta_c = vecDeltas[2];
276 
277  std::vector<size_t> rs = sorted_indices(nd); // indices sorted by decreasing rho
278  std::vector<size_t> ds = sort_by_delta(nd); // sort in decreasing distance to higher
279 
280  const unsigned int nd_size = nd.size();
281  for(unsigned int i=0; i < nd_size; ++i){
282 
283  if(nd[ds[i]].data.delta < delta_c) break; // no more cluster centers to be looked at
284  if(dependSensor){
285 
286  float rho_c = kappa*nd[ds[i]].data.sigmaNoise;
287  if(nd[ds[i]].data.rho < rho_c ) continue; // set equal to kappa times noise threshold
288 
289  }
290  else if(nd[ds[i]].data.rho*kappa < maxdensity)
291  continue;
292 
293 
294  nd[ds[i]].data.clusterIndex = clusterIndex;
295  if (verbosity < pINFO)
296  {
297  std::cout << "Adding new cluster with index " << clusterIndex+cluster_offset << std::endl;
298  std::cout << "Cluster center is hit " << ds[i] << std::endl;
299  }
300  clusterIndex++;
301  }
302 
303  //at this point clusterIndex is equal to the number of cluster centers - if it is zero we are
304  //done
305  if(clusterIndex==0) return clusterIndex;
306 
307  //assign remaining points to clusters, using the nearestHigher set from previous step (always set except
308  // for top density hit that is skipped...)
309  for(unsigned int oi =1; oi < nd_size; ++oi){
310  unsigned int i = rs[oi];
311  int ci = nd[i].data.clusterIndex;
312  if(ci == -1){ // clusterIndex is initialised with -1 if not yet used in cluster
313  nd[i].data.clusterIndex = nd[nd[i].data.nearestHigher].data.clusterIndex;
314  }
315  }
316 
317  //make room in the temporary cluster vector for the additional clusterIndex clusters
318  // from this layer
319  if (verbosity < pINFO)
320  {
321  std::cout << "resizing cluster vector by "<< clusterIndex << std::endl;
322  }
323  current_v.resize(cluster_offset+clusterIndex);
324 
325  //assign points closer than dc to other clusters to border region
326  //and find critical border density
327  std::vector<double> rho_b(clusterIndex,0.);
328  lp.clear();
329  lp.build(nd,bounds);
330  //now loop on all hits again :( and check: if there are hits from another cluster within d_c -> flag as border hit
331  for(unsigned int i = 0; i < nd_size; ++i){
332  int ci = nd[i].data.clusterIndex;
333  bool flag_isolated = true;
334  if(ci != -1){
335  KDTreeBox search_box(nd[i].dims[0]-delta_c,nd[i].dims[0]+delta_c,
336  nd[i].dims[1]-delta_c,nd[i].dims[1]+delta_c);
337  std::vector<KDNode> found;
338  lp.search(search_box,found);
339 
340  const unsigned int found_size = found.size();
341  for(unsigned int j = 0; j < found_size; j++){ // start from 0 here instead of 1
342  //check if the hit is not within d_c of another cluster
343  if(found[j].data.clusterIndex!=-1){
344  float dist = distance(found[j].data,nd[i].data);
345  if(dist < delta_c && found[j].data.clusterIndex!=ci){
346  //in which case we assign it to the border
347  nd[i].data.isBorder = true;
348  break;
349  }
350  //because we are using two different containers, we have to make sure that we don't unflag the
351  // hit when it finds *itself* closer than delta_c
352  if(dist < delta_c && dist != 0. && found[j].data.clusterIndex==ci){
353  // in this case it is not an isolated hit
354  // the dist!=0 is because the hit being looked at is also inside the search box and at dist==0
355  flag_isolated = false;
356  }
357  }
358  }
359  if(flag_isolated) nd[i].data.isBorder = true; //the hit is more than delta_c from any of its brethren
360  }
361  //check if this border hit has density larger than the current rho_b and update
362  if(nd[i].data.isBorder && rho_b[ci] < nd[i].data.rho)
363  rho_b[ci] = nd[i].data.rho;
364  } // end loop all hits
365 
366  //flag points in cluster with density < rho_b as halo points, then fill the cluster vector
367  for(unsigned int i = 0; i < nd_size; ++i){
368  int ci = nd[i].data.clusterIndex;
369  if(ci!=-1 && nd[i].data.rho < rho_b[ci])
370  nd[i].data.isHalo = true;
371  if(nd[i].data.clusterIndex!=-1){
372  current_v[ci+cluster_offset].push_back(nd[i]);
373  if (verbosity < pINFO)
374  {
375  std::cout << "Pushing hit " << i << " into cluster with index " << ci+cluster_offset << std::endl;
376  std::cout << "Size now " << current_v[ci+cluster_offset].size() << std::endl;
377  }
378  }
379  }
380 
381  //prepare the offset for the next layer if there is one
382  if (verbosity < pINFO)
383  {
384  std::cout << "moving cluster offset by " << clusterIndex << std::endl;
385  }
386  cluster_offset += clusterIndex;
387  return clusterIndex;
388 }
389 
390 // find local maxima within delta_c, marking the indices in the cluster
391 std::vector<unsigned> HGCalImagingAlgo::findLocalMaximaInCluster(const std::vector<KDNode>& cluster) {
392  std::vector<unsigned> result;
393  std::vector<bool> seed(cluster.size(),true);
394  float delta_c = 2.;
395 
396  for( unsigned i = 0; i < cluster.size(); ++i ) {
397  for( unsigned j = 0; j < cluster.size(); ++j ) {
398  if( distance(cluster[i].data,cluster[j].data) < delta_c && i != j) {
399  if( cluster[i].data.weight < cluster[j].data.weight ) {
400  seed[i] = false;
401  break;
402  }
403  }
404  }
405  }
406 
407  for( unsigned i = 0 ; i < cluster.size(); ++i ) {
408  if( seed[i] && cluster[i].data.weight > 5e-4) {
409  // seed at i with energy cluster[i].weight
410  result.push_back(i);
411  }
412  }
413 
414  // Found result.size() sub-clusters in input cluster of length cluster.size()
415 
416  return result;
417 }
418 
420  const std::vector<double>& fractions) {
421  double norm(0.0), x(0.0), y(0.0), z(0.0);
422  for( unsigned i = 0; i < hits.size(); ++i ) {
423  const double weight = fractions[i]*hits[i].data.weight;
424  norm += weight;
425  x += weight*hits[i].data.x;
426  y += weight*hits[i].data.y;
427  z += weight*hits[i].data.z;
428  }
430  double norm_inv = 1.0/norm;
431  result *= norm_inv;
432  return result;
433 }
434 
435 double HGCalImagingAlgo::calculateEnergyWithFraction(const std::vector<KDNode>& hits,
436  const std::vector<double>& fractions) {
437  double result = 0.0;
438  for( unsigned i = 0 ; i < hits.size(); ++i ) {
439  result += fractions[i]*hits[i].data.weight;
440  }
441  return result;
442 }
443 
444 void HGCalImagingAlgo::shareEnergy(const std::vector<KDNode>& incluster,
445  const std::vector<unsigned>& seeds,
446  std::vector<std::vector<double> >& outclusters) {
447  std::vector<bool> isaseed(incluster.size(),false);
448  outclusters.clear();
449  outclusters.resize(seeds.size());
450  std::vector<Point> centroids(seeds.size());
451  std::vector<double> energies(seeds.size());
452 
453  if( seeds.size() == 1 ) { // short circuit the case of a lone cluster
454  outclusters[0].clear();
455  outclusters[0].resize(incluster.size(),1.0);
456  return;
457  }
458 
459  // saving seeds
460 
461  // create quick seed lookup
462  for( unsigned i = 0; i < seeds.size(); ++i ) {
463  isaseed[seeds[i]] = true;
464  }
465 
466  // initialize clusters to be shared
467  // centroids start off at seed positions
468  // seeds always have fraction 1.0, to stabilize fit
469  // initializing fit
470  for( unsigned i = 0; i < seeds.size(); ++i ) {
471  outclusters[i].resize(incluster.size(),0.0);
472  for( unsigned j = 0; j < incluster.size(); ++j ) {
473  if( j == seeds[i] ) {
474  outclusters[i][j] = 1.0;
475  centroids[i] = math::XYZPoint(incluster[j].data.x,incluster[j].data.y,incluster[j].data.z);
476  energies[i] = incluster[j].data.weight;
477  }
478  }
479  }
480 
481  // run the fit while we are less than max iterations, and clusters are still moving
482  const double minFracTot = 1e-20;
483  unsigned iter = 0;
484  const unsigned iterMax = 50;
486  const double stoppingTolerance = 1e-8;
487  const double toleranceScaling = std::pow(std::max(1.0,seeds.size()-1.0),2.0);
488  std::vector<Point> prevCentroids;
489  std::vector<double> frac(seeds.size()), dist2(seeds.size());
490  while( iter++ < iterMax && diff > stoppingTolerance*toleranceScaling ) {
491  for( unsigned i = 0; i < incluster.size(); ++i ) {
492  const Hexel& ihit = incluster[i].data;
493  double fracTot(0.0);
494  for( unsigned j = 0; j < seeds.size(); ++j ) {
495  double fraction = 0.0;
496  double d2 = ( std::pow(ihit.x - centroids[j].x(),2.0) +
497  std::pow(ihit.y - centroids[j].y(),2.0) +
498  std::pow(ihit.z - centroids[j].z(),2.0) )/sigma2;
499  dist2[j] = d2;
500  // now we set the fractions up based on hit type
501  if( i == seeds[j] ) { // this cluster's seed
502  fraction = 1.0;
503  } else if( isaseed[i] ) {
504  fraction = 0.0;
505  } else {
506  fraction = energies[j]*std::exp( -0.5*d2 );
507  }
508  fracTot += fraction;
509  frac[j] = fraction;
510  }
511  // now that we have calculated all fractions for all hits
512  // assign the new fractions
513  for( unsigned j = 0; j < seeds.size(); ++j ) {
514  if( fracTot > minFracTot ||
515  ( i == seeds[j] && fracTot > 0.0 ) ) {
516  outclusters[j][i] = frac[j]/fracTot;
517  } else {
518  outclusters[j][i] = 0.0;
519  }
520  }
521  }
522 
523  // save previous centroids
524  prevCentroids = std::move(centroids);
525  // finally update the position of the centroids from the last iteration
526  centroids.resize(seeds.size());
527  double diff2 = 0.0;
528  for( unsigned i = 0; i < seeds.size(); ++i ) {
529  centroids[i] = calculatePositionWithFraction(incluster,outclusters[i]);
530  energies[i] = calculateEnergyWithFraction(incluster,outclusters[i]);
531  // calculate convergence parameters
532  const double delta2 = (prevCentroids[i]-centroids[i]).perp2();
533  if( delta2 > diff2 ) diff2 = delta2;
534  }
535  //update convergance parameter outside loop
536  diff = std::sqrt(diff2);
537  }
538 }
539 
541 
542  if(initialized) return; // only need to calculate thresholds once
543  const std::vector<DetId>& listee(rhtools_.getGeometry()->getValidDetIds(DetId::Forward,ForwardSubdetector::HGCEE));
544  const std::vector<DetId>& listfh(rhtools_.getGeometry()->getValidDetIds(DetId::Forward,ForwardSubdetector::HGCHEF));
545 
546  std::vector<double> dummy;
547  dummy.resize(maxNumberOfWafersPerLayer, 0);
548  thresholds.resize(maxlayer, dummy);
549  v_sigmaNoise.resize(maxlayer, dummy);
550  int previouswafer=-999;
551 
552  for(unsigned icalo=0;icalo<2;++icalo)
553  {
554  const std::vector<DetId>& listDetId( icalo==0 ? listee : listfh);
555 
556  for(auto& detid: listDetId)
557  {
558  int wafer = rhtools_.getWafer(detid);
559  if(wafer==previouswafer) continue;
560  previouswafer = wafer;
561  // no need to do it twice
562  if(rhtools_.zside(detid)<0) continue;
563  int layer = rhtools_.getLayerWithOffset(detid);
564  float thickness = rhtools_.getSiThickness(detid);
565  int thickIndex = -1;
566  if( thickness>99. && thickness<101.) thickIndex=0;
567  else if( thickness>199. && thickness<201. ) thickIndex=1;
568  else if( thickness>299. && thickness<301. ) thickIndex=2;
569  else assert( thickIndex>0 && "ERROR - silicon thickness has a nonsensical value" );
570  float sigmaNoise = 0.001 * fcPerEle * nonAgedNoises[thickIndex] * dEdXweights[layer] / (fcPerMip[thickIndex] * thicknessCorrection[thickIndex]);
571  thresholds[layer-1][wafer]=sigmaNoise*ecut;
572  v_sigmaNoise[layer-1][wafer] = sigmaNoise;
573  }
574  }
575 
576  // now BH, much faster
577  for ( unsigned ilayer=lastLayerFH+1;ilayer<=maxlayer;++ilayer)
578  {
579  float sigmaNoise = 0.001 * noiseMip * dEdXweights[ilayer];
580  std::vector<double> bhDummy_thresholds;
581  std::vector<double> bhDummy_sigmaNoise;
582  bhDummy_thresholds.push_back(sigmaNoise*ecut);
583  bhDummy_sigmaNoise.push_back(sigmaNoise);
584  thresholds[ilayer-1]=bhDummy_thresholds;
585  v_sigmaNoise[ilayer-1]=bhDummy_sigmaNoise;
586  }
587  initialized=true;
588 }
bool isHalfCell(const DetId &) const
Definition: RecHitTools.cc:171
unsigned int getWafer(const DetId &) const
Definition: RecHitTools.cc:149
double calculateEnergyWithFraction(const std::vector< KDNode > &, const std::vector< double > &)
hgcal::RecHitTools rhtools_
std::vector< std::vector< KDNode > > current_v
math::XYZPoint calculatePositionWithFraction(const std::vector< KDNode > &, const std::vector< double > &)
double distance(const Hexel &pt1, const Hexel &pt2)
std::vector< double > dEdXweights
reco::CaloCluster::AlgoId algoId
double calculateDistanceToHigher(std::vector< KDNode > &)
static const unsigned int maxlayer
int zside(const DetId &id) const
Definition: RecHitTools.cc:87
std::vector< std::array< float, 2 > > minpos
static const unsigned int maxNumberOfWafersPerLayer
std::vector< double > vecDeltas
std::vector< std::vector< double > > thresholds
const DetId & detid() const
Definition: CaloRecHit.h:21
std::vector< std::array< float, 2 > > maxpos
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > &region)
T y() const
Definition: PV3DBase.h:63
math::XYZPoint Point
point in the space
std::vector< double > thicknessCorrection
std::vector< double > nonAgedNoises
Definition: weight.py:1
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
std::vector< size_t > sort_by_delta(const std::vector< KDNode > &v)
void shareEnergy(const std::vector< KDNode > &, const std::vector< unsigned > &, std::vector< std::vector< double > > &)
static const unsigned int lastLayerEE
float energy() const
Definition: CaloRecHit.h:17
T sqrt(T t)
Definition: SSEVec.h:18
static const unsigned int lastLayerFH
unsigned int cluster_offset
VerbosityLevel verbosity
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< size_t > sorted_indices(const std::vector< T > &v)
std::vector< reco::BasicCluster > getClusters(bool)
std::vector< unsigned > findLocalMaximaInCluster(const std::vector< KDNode > &)
std::float_t getSiThickness(const DetId &) const
Definition: RecHitTools.cc:99
double calculateLocalDensity(std::vector< KDNode > &, KDTree &, const unsigned int)
Definition: DetId.h:18
int findAndAssignClusters(std::vector< KDNode > &, KDTree &, double, KDTreeBox &, const unsigned int)
std::vector< std::vector< KDNode > > points
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:139
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
T perp2() const
Squared magnitude of transverse component.
GlobalPoint getPosition(const DetId &id) const
Definition: RecHitTools.cc:73
math::XYZPoint calculatePosition(std::vector< KDNode > &)
std::vector< std::vector< double > > v_sigmaNoise
std::vector< DetId > getValidDetIds() const
Get the list of all valid detector ids.
Definition: CaloGeometry.cc:92
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
size_type size() const
double distance2(const Hexel &pt1, const Hexel &pt2)
static int position[264][3]
Definition: ReadPGInfo.cc:509
T x() const
Definition: PV3DBase.h:62
const CaloGeometry * getGeometry() const
Definition: RecHitTools.h:49
std::vector< double > fcPerMip
void populate(const HGCRecHitCollection &hits)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
def move(src, dest)
Definition: eostools.py:510
std::vector< reco::BasicCluster > clusters_v