CMS 3D CMS Logo

PFMultiDepthClusterizer.cc
Go to the documentation of this file.
6 #include "Math/GenVector/VectorUtil.h"
7 
8 #include "vdt/vdtMath.h"
9 
10 #include <iterator>
11 
12 
13 
17 {
18 
19  if( conf.exists("allCellsPositionCalc") ) {
20  const edm::ParameterSet& acConf =
21  conf.getParameterSet("allCellsPositionCalc");
22  const std::string& algoac =
23  acConf.getParameter<std::string>("algoName");
24  _allCellsPosCalc = std::unique_ptr<PosCalc>{PFCPositionCalculatorFactory::get()->create(algoac, acConf)};
25  }
26 
27  nSigmaEta_ = pow(conf.getParameter<double>("nSigmaEta"),2);
28  nSigmaPhi_ = pow(conf.getParameter<double>("nSigmaPhi"),2);
29 
30 }
31 
34  const std::vector<bool>& seedable,
36 
37  std::vector<double> etaRMS2(input.size(),0.0);
38  std::vector<double> phiRMS2(input.size(),0.0);
39 
40  //We need to sort the clusters for smaller to larger depth
41  // for (unsigned int i=0;i<input.size();++i)
42  // printf(" cluster%f %f \n",input[i].depth(),input[i].energy());
43 
44 
45 
46  //calculate cluster shapes
47  calculateShowerShapes(input,etaRMS2,phiRMS2);
48 
49  //link
50  auto && links = link(input,etaRMS2,phiRMS2);
51  // for (const auto& link: links)
52  // printf("link %d %d %f %f\n",link.from(),link.to(),link.dR(),link.dZ());
53 
54 
55 
56  std::vector<bool> mask(input.size(),false);
57  std::vector<bool> linked(input.size(),false);
58 
59  //prune
60  auto && prunedLinks = prune(links,linked);
61 
62  //printf("Pruned links\n")
63  // for (const auto& link: prunedLinks)
64  // printf("link %d %d %f %f\n",link.from(),link.to(),link.dR(),link.dZ());
65 
66 
67 
68  //now we need to build clusters
69  for (unsigned int i=0;i<input.size();++i) {
70  //if not masked
71  if( mask[i])
72  continue;
73  //if not linked just spit it out
74  if (!linked[i]) {
75  output.push_back(input[i]);
76  // printf("Added single cluster with energy =%f \n",input[i].energy());
77  mask[i] = true;
78  continue;
79  }
80 
81 
82  //now business: if linked and not masked gather clusters
83  reco::PFCluster cluster = input[i];
84  mask[i] = true;
85  expandCluster(cluster,i, mask,input,prunedLinks);
86  _allCellsPosCalc->calculateAndSetPosition(cluster);
87  output.push_back(cluster);
88  // printf("Added linked cluster with energy =%f\n",cluster.energy());
89 
90  }
91 }
92 
93 
95 calculateShowerShapes(const reco::PFClusterCollection& clusters,std::vector<double>& etaRMS2,std::vector<double>& phiRMS2) {
96 
97  //shower shapes. here do not use the fractions
98 
99  for( unsigned int i=0;i<clusters.size();++i ) {
100  const reco::PFCluster& cluster = clusters[i];
101  double etaSum=0.0; double phiSum=0.0;
102  auto const & crep = cluster.positionREP();
103  for (const auto& frac : cluster.recHitFractions()) {
104  auto const & h = *frac.recHitRef();
105  auto const & rep = h.positionREP();
106  etaSum += (frac.fraction()*h.energy())*std::abs(rep.eta()-crep.eta());
107  phiSum += (frac.fraction()*h.energy())*std::abs(deltaPhi(rep.phi(),crep.phi()));
108  }
109  //protection for single line : assign ~ tower
110  etaRMS2[i] = std::max(etaSum/cluster.energy(),0.1);
111  etaRMS2[i]*= etaRMS2[i];
112  phiRMS2[i] = std::max(phiSum/cluster.energy(),0.1);
113  phiRMS2[i]*=phiRMS2[i];
114  }
115 
116 }
117 
118 
119 std::vector<PFMultiDepthClusterizer::ClusterLink> PFMultiDepthClusterizer::
120 link(const reco::PFClusterCollection& clusters ,const std::vector<double>& etaRMS2,const std::vector<double>& phiRMS2) {
121 
122  std::vector<ClusterLink> links;
123  //loop on all pairs
124  for (unsigned int i=0;i<clusters.size();++i)
125  for (unsigned int j=0;j<clusters.size();++j) {
126  if (i==j ) continue;
127 
128  const reco::PFCluster& cluster1 = clusters[i];
129  const reco::PFCluster& cluster2 = clusters[j];
130 
131  auto dz = (cluster2.depth() - cluster1.depth());
132 
133  //Do not link at the same layer and only link inside out!
134  if (dz<0.0f || std::abs(dz)<0.2f) continue;
135 
136  auto const & crep1 = cluster1.positionREP();
137  auto const & crep2 = cluster2.positionREP();
138 
139  auto deta = crep1.eta()-crep2.eta();
140  deta = deta*deta/(etaRMS2[i]+etaRMS2[j]);
141  auto dphi = deltaPhi(crep1.phi(),crep2.phi());
142  dphi = dphi*dphi/(phiRMS2[i]+phiRMS2[j]);
143 
144  // printf("Testing Link %d -> %d (%f %f %f %f ) \n",i,j,deta,dphi,cluster1.position().Eta()-cluster2.position().Eta(),deltaPhi(cluster1.position().Phi(),cluster2.position().Phi()));
145 
146  if ( (deta<nSigmaEta_) & (dphi<nSigmaPhi_ ) )
147  links.push_back(ClusterLink(i,j,deta+dphi,std::abs(dz),cluster1.energy()+cluster2.energy()));
148  }
149 
150  return links;
151 }
152 
153 std::vector<PFMultiDepthClusterizer::ClusterLink> PFMultiDepthClusterizer::
154 prune(std::vector<ClusterLink>& links,std::vector<bool>& linkedClusters) {
155  std::vector<ClusterLink> goodLinks ;
156  std::vector<bool> mask(links.size(),false);
157  if (links.empty()) return goodLinks;
158 
159  for (unsigned int i=0;i<links.size()-1;++i) {
160  if (mask[i])
161  continue;
162  for (unsigned int j=i+1;j<links.size();++j) {
163  if (mask[j])
164  continue;
165 
166  const ClusterLink& link1 = links[i];
167  const ClusterLink& link2 = links[j];
168 
169  if (link1.to() == link2.to()) {//found two links going to the same spot,kill one
170  //first prefer nearby layers
171  if (link1.dZ() < link2.dZ()) {
172  mask[j]=true;
173  }
174  else if (link1.dZ() > link2.dZ()) {
175  mask[i] = true;
176  }
177  else if (fabs(link1.dZ()-link2.dZ())<0.2) { //if same layer-pick based on transverse compatibility
178  if (link1.dR()<link2.dR()) {
179  mask[j]=true;
180  }
181  else if (link1.dR()>link2.dR()) {
182  mask[i] = true;
183  }
184  else {
185  //same distance as well -> can happen !!!!! Pick the highest SUME
186  if (link1.energy()<link2.energy())
187  mask[i] = true;
188  else
189  mask[j] = true;
190 
191  }
192  }
193  }
194  }
195  }
196 
197  for (unsigned int i=0;i<links.size();++i) {
198  if (mask[i])
199  continue;
200  goodLinks.push_back(links[i]);
201  linkedClusters[links[i].from()]=true;
202  linkedClusters[links[i].to()]=true;
203  }
204 
205 
206  return goodLinks;
207 }
208 
209 
210 void
213 
214  double e1=0.0;
215  double e2=0.0;
216 
217  //find seeds
218  for ( const auto& fraction : main.recHitFractions())
219  if (fraction.recHitRef()->detId() == main.seed()) {
220  e1=fraction.recHitRef()->energy();
221  }
222 
223  for ( const auto& fraction : added.recHitFractions()) {
225  if (fraction.recHitRef()->detId() == added.seed()) {
226  e2=fraction.recHitRef()->energy();
227  }
228  }
229  if (e2>e1)
230  main.setSeed(added.seed());
231 
232 }
233 
234 
235 void
237 expandCluster(reco::PFCluster& cluster,unsigned int point,std::vector<bool>& mask,const reco::PFClusterCollection& clusters, const std::vector<ClusterLink>& links) {
238  for (const auto& link : links) {
239  if (link.from() == point) {
240  //found link that starts from this guy if not masked absorb
241  if (!mask[link.from()]) {
242  absorbCluster(cluster,clusters[link.from()]);
243  mask[link.from()] = true;
244  }
245 
246  if (!mask[link.to()]) {
247  absorbCluster(cluster,clusters[link.to()]);
248  mask[link.to()]=true;
249  expandCluster(cluster,link.to(),mask,clusters,links);
250  }
251  }
252  if (link.to() == point) {
253  //found link that starts from this guy if not masked absorb
254  if (!mask[link.to()]) {
255  absorbCluster(cluster,clusters[link.to()]);
256  mask[link.to()] = true;
257  }
258 
259  if (!mask[link.from()]) {
260  absorbCluster(cluster,clusters[link.from()]);
261  mask[link.from()]=true;
262  expandCluster(cluster,link.from(),mask,clusters,links);
263  }
264  }
265 
266 
267 
268  }
269 
270 }
T getParameter(std::string const &) const
void calculateShowerShapes(const reco::PFClusterCollection &, std::vector< double > &, std::vector< double > &)
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< ClusterLink > prune(std::vector< ClusterLink > &, std::vector< bool > &linkedClusters)
static std::string const input
Definition: EdmProvDump.cc:48
void setSeed(const DetId &id)
Definition: CaloCluster.h:123
std::unique_ptr< PFCPositionCalculatorBase > _allCellsPosCalc
void absorbCluster(reco::PFCluster &, const reco::PFCluster &)
PFMultiDepthClusterizer(const edm::ParameterSet &conf)
const REPPoint & positionREP() const
cluster position: rho, eta, phi
Definition: PFCluster.h:97
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
std::vector< ClusterLink > link(const reco::PFClusterCollection &, const std::vector< double > &, const std::vector< double > &)
rep
Definition: cuy.py:1190
double energy() const
cluster energy
Definition: PFCluster.h:82
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:207
ParameterSet const & getParameterSet(std::string const &) const
void addRecHitFraction(const reco::PFRecHitFraction &frac)
add a given fraction of the rechit
Definition: PFCluster.cc:91
Definition: main.py:1
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
Definition: PFCluster.h:72
void buildClusters(const reco::PFClusterCollection &, const std::vector< bool > &, reco::PFClusterCollection &outclus) override
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
T get(const Candidate &c)
Definition: component.h:55
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
void expandCluster(reco::PFCluster &, unsigned int point, std::vector< bool > &mask, const reco::PFClusterCollection &, const std::vector< ClusterLink > &links)
double depth() const
cluster depth
Definition: PFCluster.h:90