ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ClusteringAlgo.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ClusteringAlgo.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // This example is provided by the Geant4-DNA collaboration
27 // Any report or published results obtained using the Geant4-DNA software
28 // shall cite the following Geant4-DNA collaboration publication:
29 // Med. Phys. 37 (2010) 4692-4708
30 // The Geant4-DNA web site is available at http://geant4-dna.org
31 //
32 // Authors: Henri Payno and Yann Perrot
33 //
34 //
37 
38 #include "ClusteringAlgo.hh"
40 
41 #include "G4SystemOfUnits.hh"
42 #include "Randomize.hh"
43 
44 #include <map>
45 
46 using namespace std;
47 
48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
49 
51  G4double pSPointsProb,G4double pEMinDamage, G4double pEMaxDamage)
52 :fEps(pEps),fMinPts(pMinPts),
53  fSPointsProb(pSPointsProb),fEMinDamage(pEMinDamage),fEMaxDamage(pEMaxDamage)
54 {
55  fNextSBPointID = 0;
57 }
58 
59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
60 
62 {
63  delete fpClustAlgoMessenger;
64  Purge();
65 }
66 
67 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
68 
69 // Random sampling in space
71 {
72  return fSPointsProb > G4UniformRand();
73 }
74 
75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
76 
77 // Random sampling in energy
79 {
80  if(pEdep<fEMinDamage)
81  {
82  return false;
83  }
84 
85  else if(pEdep>fEMaxDamage)
86  {
87  return true;
88  }
89  else
90  {
91  G4double proba = (pEdep/eV - fEMinDamage/eV)/
93  return (proba>G4UniformRand());
94  }
95 
96 }
97 
98 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
99 
100 // Add an event interaction to the unregistered damage if
101 // good conditions (pos and energy) are met
102 //
103 
105 {
106  if(IsEdepSufficient(pEdep))
107  {
108  if(IsInSensitiveArea())
109  {
110  fpSetOfPoints.push_back( new SBPoint(fNextSBPointID++, pPos, pEdep));
111  }
112  }
113 }
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
116 
118 {
119 
120  // quick sort style
121  // create cluster
122  std::vector<SBPoint*>::iterator itVisitorPt, itObservedPt;
123  for(itVisitorPt = fpSetOfPoints.begin();
124  itVisitorPt != fpSetOfPoints.end();
125  ++itVisitorPt )
126  {
127  itObservedPt = itVisitorPt;
128  itObservedPt ++;
129  while(itObservedPt != fpSetOfPoints.end() )
130  {
131  // if at least one of the two points has not a cluster
132  if(!((*itObservedPt)->HasCluster() && (*itVisitorPt)->HasCluster()))
133  {
134  if(AreOnTheSameCluster( (*itObservedPt)->GetPosition(),
135  (*itVisitorPt)->GetPosition(),fEps))
136  {
137  // if none has a cluster. Create a new one
138  if(!(*itObservedPt)->HasCluster() && !(*itVisitorPt)->HasCluster())
139  {
140  // create the new cluster
141  set<SBPoint*> clusterPoints;
142  clusterPoints.insert((*itObservedPt));
143  clusterPoints.insert((*itVisitorPt));
144  ClusterSBPoints* lCluster = new ClusterSBPoints(clusterPoints);
145  assert(lCluster);
146  fpClusters.push_back(lCluster);
147  assert(lCluster);
148  // inform SB point that they are part of a cluster now
149  assert(lCluster);
150  (*itObservedPt)->SetCluster(lCluster);
151  assert(lCluster);
152  (*itVisitorPt)->SetCluster(lCluster);
153  }else
154  {
155  // add the point to the existing cluster
156  if((*itObservedPt)->HasCluster())
157  {
158  (*itObservedPt)->GetCluster()->AddSBPoint((*itVisitorPt));
159  (*itVisitorPt)->SetCluster((*itObservedPt)->GetCluster());
160  }
161 
162  if((*itVisitorPt)->HasCluster())
163  {
164  (*itVisitorPt)->GetCluster()->AddSBPoint((*itObservedPt));
165  (*itObservedPt)->SetCluster((*itVisitorPt)->GetCluster());
166  }
167  }
168  }
169  }
170  ++itObservedPt;
171  }
172  }
173 
174  // associate isolated points and merge clusters
176  MergeClusters();
177 
178  // return cluster size distribution
180 }
181 
182 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
183 
184 // try to merge cluster between them, based on the distance between barycenters
186 {
187  std::vector<ClusterSBPoints*>::iterator itCluster1, itCluster2;
188  for(itCluster1 = fpClusters.begin();
189  itCluster1 != fpClusters.end();
190  ++itCluster1)
191  {
192  G4ThreeVector baryCenterClust1 = (*itCluster1)->GetBarycenter();
193  itCluster2 = itCluster1;
194  itCluster2++;
195  while(itCluster2 != fpClusters.end())
196  {
197  G4ThreeVector baryCenterClust2 = (*itCluster2)->GetBarycenter();
198  // if we can merge both cluster
199  if(AreOnTheSameCluster(baryCenterClust1, baryCenterClust2,fEps))
200  {
201  (*itCluster1)->MergeWith(*itCluster2);
202  delete *itCluster2;
203  fpClusters.erase(itCluster2);
204  return MergeClusters();
205  }else
206  {
207  itCluster2++;
208  }
209  }
210  }
211 }
212 
213 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
214 
216 {
217  std::vector<SBPoint*>::iterator itVisitorPt;
218  int nbPtSansCluster = 0;
219  // Associate all point not in a cluster if possible ( to the first found cluster)
220  for(itVisitorPt = fpSetOfPoints.begin();
221  itVisitorPt != fpSetOfPoints.end();
222  ++itVisitorPt)
223  {
224  if(!(*itVisitorPt)->HasCluster())
225  {
226  nbPtSansCluster ++;
227  FindCluster(*itVisitorPt);
228  }
229  }
230 }
231 
232 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
233 
235 {
236  assert(!pPt->HasCluster());
237  std::vector<ClusterSBPoints*>::iterator itCluster;
238  for(itCluster = fpClusters.begin();
239  itCluster != fpClusters.end();
240  ++itCluster)
241  {
242  //if((*itCluster)->hasIn(pPt, fEps))
243  if((*itCluster)->HasInBarycenter(pPt, fEps))
244  {
245  (*itCluster)->AddSBPoint(pPt);
246  return true;
247  }
248  }
249  return false;
250 }
251 
252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
253 
255  G4ThreeVector pPt2, G4double pMinDist)
256 {
257  G4double x1=pPt1.x()/nm;
258  G4double y1=pPt1.y()/nm;
259  G4double z1=pPt1.z()/nm;
260 
261  G4double x2=pPt2.x()/nm;
262  G4double y2=pPt2.y()/nm;
263  G4double z2=pPt2.z()/nm;
264 
265  // if the two points are closed enough
266  if(((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))<=
267  (pMinDist/nm*pMinDist/nm))
268  {
269  return true;
270  }else
271  {
272  return false;
273  }
274 }
275 
276 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
277 
279 {
280  G4int nbSSB = 0;
281  std::vector<SBPoint*>::const_iterator itSDSPt;
282  for(itSDSPt = fpSetOfPoints.begin();
283  itSDSPt != fpSetOfPoints.end();
284  ++itSDSPt)
285  {
286  if(!(*itSDSPt)->HasCluster())
287  {
288  nbSSB++;
289  }
290  }
291  return nbSSB;
292 }
293 
294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
295 
297 {
298  G4int nbSSB = 0;
299  std::vector<ClusterSBPoints*>::const_iterator itCluster;
300  for(itCluster = fpClusters.begin();
301  itCluster != fpClusters.end();
302  ++itCluster)
303  {
304  if((*itCluster)->IsSSB())
305  {
306  nbSSB ++;
307  }
308  }
309  return nbSSB;
310 }
311 
312 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
313 
315 {
316  G4int nbDSB = 0;
317  std::vector<ClusterSBPoints*>::const_iterator itCluster;
318  for(itCluster = fpClusters.begin();
319  itCluster != fpClusters.end();
320  ++itCluster)
321  {
322  if((*itCluster)->IsDSB())
323  {
324  nbDSB ++;
325  }
326  }
327  return nbDSB;
328 }
329 
330 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
331 
333 {
334  std::map<G4int,G4int> sizeDistribution;
335  sizeDistribution[1]=GetSSB();
336  std::vector<ClusterSBPoints*>::const_iterator itCluster;
337  for(itCluster = fpClusters.begin();
338  itCluster != fpClusters.end();
339  itCluster++)
340  {
341  sizeDistribution[(*itCluster)->GetSize()]++;
342  }
343  return sizeDistribution;
344 }
345 
346 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
347 
349 {
350  fNextSBPointID = 0;
351  std::vector<ClusterSBPoints*>::iterator itCluster;
352  for(itCluster = fpClusters.begin();
353  itCluster != fpClusters.end();
354  ++itCluster)
355  {
356  delete *itCluster;
357  *itCluster = NULL;
358  }
359  fpClusters.clear();
360  std::vector<SBPoint*>::iterator itPt;
361  for(itPt = fpSetOfPoints.begin();
362  itPt != fpSetOfPoints.end();
363  ++itPt)
364  {
365  delete *itPt;
366  *itPt = NULL;
367  }
368  fpSetOfPoints.clear();
369 }
370