ClusterShapes.cxx
Go to the documentation of this file.
1 #include "ClusterShapes.h"
2 
3 #include <gsl/gsl_vector.h>
4 #include <gsl/gsl_matrix.h>
5 #include <gsl/gsl_linalg.h>
6 #include <gsl/gsl_eigen.h>
7 #include <gsl/gsl_multifit_nlin.h>
8 #include <gsl/gsl_sf_gamma.h>
9 #include <gsl/gsl_integration.h>
10 
11 namespace util{
12 
13  ClusterShapes::ClusterShapes(int nhits, float* a, float* x, float* y, float* z)
14  : _nHits(nhits), _aHit(nhits, 0.0), _tHit(nhits, 0.0), _xHit(nhits, 0.0), _yHit(nhits, 0.0), _zHit(nhits, 0.0), _ifNotGravity(1), _ifNotWidth(1), _ifNotInertia(1), _ifNotElipsoid(1)
15  {
16  for (int i(0); i < nhits; ++i)
17  {
18  _aHit[i] = a[i];
19  _tHit[i] = 0.;
20  _xHit[i] = x[i];
21  _yHit[i] = y[i];
22  _zHit[i] = z[i];
23  }
24  }
25 
26  ClusterShapes::ClusterShapes(int nhits, float* a, float* t, float* x, float* y, float* z)
27  : _nHits(nhits), _aHit(nhits, 0.0), _tHit(nhits, 0.0), _xHit(nhits, 0.0), _yHit(nhits, 0.0), _zHit(nhits, 0.0), _ifNotGravity(1), _ifNotWidth(1), _ifNotInertia(1), _ifNotElipsoid(1)
28  {
29  for (int i(0); i < nhits; ++i)
30  {
31  _aHit[i] = a[i];
32  _tHit[i] = t[i];
33  _xHit[i] = x[i];
34  _yHit[i] = y[i];
35  _zHit[i] = z[i];
36  }
37  }
38 
39  //----------------------------------------------------------------------------
40 
41  ClusterShapes::ClusterShapes(int nhits, std::vector<float> a, std::vector<float> x, std::vector<float> y, std::vector<float> z)
42  : _nHits(nhits), _aHit(nhits, 0.0), _xHit(nhits, 0.0), _yHit(nhits, 0.0), _zHit(nhits, 0.0), _ifNotGravity(1), _ifNotWidth(1), _ifNotInertia(1), _ifNotElipsoid(1)
43  {
44  for (int i(0); i < nhits; ++i)
45  {
46  _aHit[i] = a[i];
47  _tHit[i] = 0.;
48  _xHit[i] = x[i];
49  _yHit[i] = y[i];
50  _zHit[i] = z[i];
51  }
52  }
53 
54  ClusterShapes::ClusterShapes(int nhits, std::vector<float> a, std::vector<float> t, std::vector<float> x, std::vector<float> y, std::vector<float> z)
55  : _nHits(nhits), _aHit(nhits, 0.0), _tHit(nhits, 0.0), _xHit(nhits, 0.0), _yHit(nhits, 0.0), _zHit(nhits, 0.0), _ifNotGravity(1), _ifNotWidth(1), _ifNotInertia(1), _ifNotElipsoid(1)
56  {
57  for (int i(0); i < nhits; ++i)
58  {
59  _aHit[i] = a[i];
60  _tHit[i] = t[i];
61  _xHit[i] = x[i];
62  _yHit[i] = y[i];
63  _zHit[i] = z[i];
64  }
65  }
66 
67 
68  //----------------------------------------------------------------------------
69 
71 
72  }
73 
74  //----------------------------------------------------------------------------
75 
77  return _nHits;
78  }
79 
80  //----------------------------------------------------------------------------
81 
83  if (_ifNotGravity == 1) findGravity();
84  return _totAmpl;
85  }
86 
87  //----------------------------------------------------------------------------
88 
90  if (_ifNotGravity == 1) findGravity();
91  return _totTime/_nHits;
92  }
93 
94  //----------------------------------------------------------------------------
95 
97  if (_ifNotGravity == 1) findGravity() ;
98  return &_analogGravity[0] ;
99  }
100 
101  //----------------------------------------------------------------------------
102 
104  if (_ifNotInertia == 1) findInertia();
105  return &_ValAnalogInertia[0] ;
106  }
107 
108  //----------------------------------------------------------------------------
109 
111  if (_ifNotInertia == 1) findInertia();
112  return &_VecAnalogInertia[0] ;
113  }
114 
115  //----------------------------------------------------------------------------
116 
118  if (_ifNotWidth == 1) findWidth();
119  return _analogWidth;
120  }
121 
123 
124  /** Elipsoid parameter calculations see cluster_proper.f */
125  float cx,cy,cz ;
126  float dx,dy,dz ;
127  float r_hit_max, d_begn, d_last, r_max, proj;
128 
129  if (_ifNotInertia == 1) findInertia() ;
130 
131  // Normalize the eigen values of inertia tensor
132  float wr1 = sqrt(_ValAnalogInertia[0]/_totAmpl);
133  float wr2 = sqrt(_ValAnalogInertia[1]/_totAmpl);
134  float wr3 = sqrt(_ValAnalogInertia[2]/_totAmpl);
135 
136  _r1 = sqrt(wr2*wr3); // spatial axis length -- the largest
137  _r2 = sqrt(wr1*wr3); // spatial axis length -- less
138  _r3 = sqrt(wr1*wr2); // spatial axis length -- even more less
139  _vol = 4.*M_PI*_r1*_r2*_r3/3.; // ellipsoid volume
140  _r_ave = pow(_vol,1/3); // average radius (quibc root)
141  _density = _totAmpl/_vol; // density
142  _eccentricity =_analogWidth/_r1; // Cluster Eccentricity
143 
144  // Find Minumal and Maximal Lenght for Principal axis
145  r_hit_max = -100000.;
146  d_begn = 100000.;
147  d_last = -100000.;
148  cx = _VecAnalogInertia[0] ;
149  cy = _VecAnalogInertia[1] ;
150  cz = _VecAnalogInertia[2] ;
151 
152  for (int i(0); i < _nHits; ++i)
153  {
154  dx = _xHit[i] - _xgr;
155  dy = _yHit[i] - _ygr;
156  dz = _zHit[i] - _zgr;
157  r_max = sqrt(dx*dx + dy*dy + dz*dz);
158 
159  if(r_max > r_hit_max) r_hit_max = r_max;
160  proj = dx*cx + dy*cy + dz*cz;
161 
162  if(proj < d_begn)
163  d_begn = proj;
164 
165  if(proj > d_last)
166  d_last = proj;
167  }
168 
169  _r1_forw = fabs(d_last);
170  _r1_back = fabs(d_begn);
171 
172  _ifNotElipsoid = 0;
173  }
174 
175  //----------------------------------------------------------------------------
176 
178 
179  _totAmpl = 0. ;
180 
181  for (int i(0); i < 3; ++i)
182  _analogGravity[i] = 0.0 ;
183 
184  for (int i(0); i < _nHits; ++i)
185  {
186  _totAmpl+=_aHit[i] ;
187  _totTime+=_tHit[i] ;
188  _analogGravity[0]+=_aHit[i]*_xHit[i] ;
189  _analogGravity[1]+=_aHit[i]*_yHit[i] ;
190  _analogGravity[2]+=_aHit[i]*_zHit[i] ;
191  }
192 
193  for (int i(0); i < 3; ++i)
195 
196  _xgr = _analogGravity[0];
197  _ygr = _analogGravity[1];
198  _zgr = _analogGravity[2];
199 
200  _ifNotGravity = 0;
201  }
202 
203  //----------------------------------------------------------------------------
204 
206 
207  double aIne[3][3];
208  float radius2 = 0.0;
209 
210  findGravity();
211 
212  for (int i(0); i < 3; ++i) {
213  for (int j(0); j < 3; ++j) {
214  aIne[i][j] = 0.0;
215  }
216  }
217 
218  for (int i(0); i < _nHits; ++i)
219  {
220  float dX = _xHit[i] - _analogGravity[0];
221  float dY = _yHit[i] - _analogGravity[1];
222  float dZ = _zHit[i] - _analogGravity[2];
223  aIne[0][0] += _aHit[i]*(dY*dY+dZ*dZ);
224  aIne[1][1] += _aHit[i]*(dX*dX+dZ*dZ);
225  aIne[2][2] += _aHit[i]*(dX*dX+dY*dY);
226  aIne[0][1] -= _aHit[i]*dX*dY;
227  aIne[0][2] -= _aHit[i]*dX*dZ;
228  aIne[1][2] -= _aHit[i]*dY*dZ;
229  }
230 
231  for (int i(0); i < 2; ++i) {
232  for (int j = i+1; j < 3; ++j) {
233  aIne[j][i] = aIne[i][j];
234  }
235  }
236  //****************************************
237  // analog Inertia
238  //****************************************
239 
240  gsl_matrix_view aMatrix = gsl_matrix_view_array((double*)aIne,3,3);
241  gsl_vector* aVector = gsl_vector_alloc(3);
242  gsl_matrix* aEigenVec = gsl_matrix_alloc(3,3);
243  gsl_eigen_symmv_workspace* wa = gsl_eigen_symmv_alloc(3);
244  gsl_eigen_symmv(&aMatrix.matrix,aVector,aEigenVec,wa);
245  gsl_eigen_symmv_free(wa);
246  gsl_eigen_symmv_sort(aVector,aEigenVec,GSL_EIGEN_SORT_ABS_ASC);
247 
248  for (int i(0); i < 3; i++) {
249  _ValAnalogInertia[i] = gsl_vector_get(aVector,i);
250  for (int j(0); j < 3; j++) {
251  _VecAnalogInertia[i+3*j] = gsl_matrix_get(aEigenVec,i,j);
252  }
253  }
254 
255  // Main principal points away from IP
256  _radius = 0.;
257  radius2 = 0.;
258 
259  for (int i(0); i < 3; ++i) {
261  radius2 += (_analogGravity[i]+_VecAnalogInertia[i])*(_analogGravity[i]+_VecAnalogInertia[i]);
262  }
263 
264  if ( radius2 < _radius) {
265  for (int i(0); i < 3; ++i)
267  }
268 
269  _radius = sqrt(_radius);
270  _ifNotInertia = 0;
271 
272  // The final job
273  findWidth();
274  findElipsoid();
275 
276  gsl_vector_free(aVector);
277  gsl_matrix_free(aEigenVec);
278 
279  }
280 
281  //----------------------------------------------------------------------------
282 
284 
285  float dist = 0.0;
286 
287  if (_ifNotInertia == 1) findInertia() ;
288 
289  _analogWidth = 0.0 ;
290 
291  for (int i(0); i < _nHits; ++i)
292  {
293  dist = findDistance(i) ;
294  _analogWidth+=_aHit[i]*dist*dist ;
295  }
296 
298 
299  _ifNotWidth = 0 ;
300  }
301 
302  //----------------------------------------------------------------------------
303 
305 
306  float cx = 0.0;
307  float cy = 0.0;
308  float cz = 0.0;
309  float dx = 0.0;
310  float dy = 0.0;
311  float dz = 0.0;
312 
313  cx = _VecAnalogInertia[0] ;
314  cy = _VecAnalogInertia[1] ;
315  cz = _VecAnalogInertia[2] ;
316  dx = _analogGravity[0] - _xHit[i] ;
317  dy = _analogGravity[1] - _yHit[i] ;
318  dz = _analogGravity[2] - _zHit[i] ;
319 
320  float tx = cy*dz - cz*dy ;
321  float ty = cz*dx - cx*dz ;
322  float tz = cx*dy - cy*dx ;
323  float tt = sqrt(tx*tx+ty*ty+tz*tz) ;
324  float ti = sqrt(cx*cx+cy*cy+cz*cz) ;
325  float f = tt / ti ;
326 
327  return f ;
328  }
329 }
Namespace for general, non-LArSoft-specific utilities.
std::vector< float > _aHit
constexpr T pow(T x)
Definition: pow.h:72
std::vector< float > _zHit
std::vector< float > _tHit
std::vector< float > _yHit
float * getEigenValInertia()
Definition: type_traits.h:61
float _ValAnalogInertia[3]
float findDistance(int i)
const double a
float _VecAnalogInertia[9]
ClusterShapes(int nhits, float *a, float *x, float *y, float *z)
float * getEigenVecInertia()
#define M_PI
Definition: includeROOT.h:54
std::vector< float > _xHit
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
list x
Definition: train.py:276
float * getCenterOfGravity()