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