FairRoot/PandaRoot
PndEmcClusterProperties.cxx
Go to the documentation of this file.
1 //---------------------------------------------------------------------
2 // Software developed for the BaBar Detector at the SLAC B-Factory.
3 // Adapted for the PANDA experiment at GSI
4 //
5 // Author List:
6 // Xiaorong Shi Lawrence Livermore National Lab
7 // Steve Playfer University of Edinburgh
8 // Stephen Gowdy University of Edinburgh
9 // Helmut Marsiske SLAC
10 //---------------------------------------------------------------------
11 
13 
14 #include "PndEmcClusterMoments.h"
15 #include "PndEmcCluster.h"
16 #include "PndEmcDigi.h"
17 #include "PndEmcXtal.h"
18 #include "PndEmcStructure.h"
19 #include "TVector3.h"
20 #include "TClonesArray.h"
21 
22 #include <iostream>
23 #include <iomanip>
24 #include <cmath>
25 #include <algorithm>
26 #include <cfloat>
27 #include <vector>
28 #include "assert.h"
29 
30 using std::endl;
31 using std::vector;
32 
33 
34 //----------------
35 // Constructors --
36 //----------------
37 
38 PndEmcClusterProperties::PndEmcClusterProperties(const PndEmcCluster &cluster, const TClonesArray *digiArray):
39 PndEmcAbsClusterProperty(cluster, digiArray)
40 {
41 }
42 
43 //--------------
44 // Destructor --
45 //--------------
46 
48 {}
49 
52 {
53  Double_t sum=0;
54  std::vector<Int_t>::const_iterator digi_iter;
55  const std::vector<Int_t> digiList = MyCluster().DigiList();
56 
57  for (digi_iter=digiList.begin();digi_iter!=digiList.end();++digi_iter)
58  {
59  PndEmcDigi *digi = (PndEmcDigi *) DigiArray()->At(*digi_iter);
60  sum+=digi->GetEnergy();
61  }
62 
63  return sum;
64 }
65 
67 {
68  Double_t mass2;
69  TVector3 clusterMomentum(0,0,0);
70  vector<Int_t>::const_iterator digi_iter;
71  TVector3 digiDirection;
72  Double_t digiEnergy;
73  std::vector<Int_t> digiList = MyCluster().DigiList();
74 
75  for (digi_iter=digiList.begin();digi_iter!=digiList.end();++digi_iter)
76  {
77  PndEmcDigi *digi = (PndEmcDigi *) DigiArray()->At(*digi_iter);
78  digiDirection=digi->where().Unit();
79  digiEnergy=digi->GetEnergy();
80  clusterMomentum=clusterMomentum+digiDirection*digiEnergy;
81  }
82 
83  Double_t clEnergy=Energy();
84 
85  mass2=clEnergy*clEnergy-clusterMomentum.Mag2();
86 
87  if (mass2 < 0.0)
88  return 0.0;
89  else
90  return sqrt(mass2);
91 }
92 
95 {
96  // Angle of major axis wrt phi
97 
98  Double_t maj=0.,st2=0.;
99 
100  std::vector<Int_t>::const_iterator current;
101  std::vector<Int_t> digiList = MyCluster().DigiList();
102 
103  Double_t n=digiList.size();
104  if ( n==1 ) return( -999. );
105 
107 
108  Double_t phi_wtd=moments->Phi1();
109  Double_t phi_clu=MyCluster().phi();
110  Double_t theta_clu=MyCluster().theta();
111  Double_t theta_wtd = moments->Theta1();
112 
113 
114  for (current=digiList.begin();current!=digiList.end();++current)
115  {
116  PndEmcDigi *digi = (PndEmcDigi *) DigiArray()->At(*current);
117  Double_t xx=0.,yy=0.,e=0.,t=0.;
118  xx=PndEmcCluster::FindPhiDiff(digi->GetPhi(),phi_clu);
119  yy=digi->GetTheta()-theta_clu;
120  e=digi->GetEnergy();
121  e*=e; // Will use e squared
122  t=(xx-phi_wtd)*e;
123  st2+=t*t;
124  maj+=t*(yy-theta_wtd)*e;
125  }
126 
127  // The major axis is found by the slope of a line through
128  // the coordinates or the Digis with respect to the centre
129  // of the cluster. (Or just the coordinates, but I'll be consistent.)
130 
131  if ( !st2 ) return( TMath::Pi()/2.0 );
132 
133  maj/=st2;
134 
135  return( atan( maj ) );
136 }
137 
138 TVector3 PndEmcClusterProperties::Where(TString method, std::vector<Double_t> params)
139 {
140  TVector3 pos;
141  if (!strcmp(method,"lilo"))
142  {
143  pos=LiloWhere(params);
144  } else if (!strcmp(method,"linear"))
145  {
146  pos=LinearWhere();
147  }
148  else
149  {
150  std::cout<<"Incorrect cluster position method: " << method.Data() <<std::endl;
151  abort();
152  }
153  return pos;
154 }
155 
156 TVector3
158 {
159  TVector3 aVector(0,0,0);
160 
161  std::vector<Int_t>::const_iterator current;
162  std::vector<Int_t> digiList = MyCluster().DigiList();
163 
164  for (current=digiList.begin();current!=digiList.end();++current)
165  {
166  PndEmcDigi *digi = (PndEmcDigi *) DigiArray()->At(*current);
167  aVector += digi->where()* digi->GetEnergy();
168  }
169 
170  aVector *= 1./MyCluster().energy();
171 
172  PndEmcTwoCoordIndex *theTCI=PndEmcStructure::Instance()->locateIndex(aVector.Theta(),aVector.Phi());
173 
174  assert(theTCI != 0);
175 
177  const PndEmcXtal *theGeom=tciXtalMap.find(theTCI)->second;
178 
179  const TVector3 normal = theGeom->normalToFrontFace();
180 
181  TVector3 centre(theGeom->frontCentre() - TVector3(0.0,0.0,0.0));
182 
183  double distanceOfPlane = normal.Dot(centre);
184 
185  double amplitude = distanceOfPlane / normal.Dot(aVector.Unit());
186 
187  aVector.SetMag(amplitude);
188 
189  return TVector3( aVector.x(), aVector.y(), aVector.z() );
190 }
191 
192 TVector3
194 {
195  const double lClusEnergy=Energy();
196 
197  assert(lClusEnergy!=0);
198 
199  TVector3 lLinSum( 0, 0, 0 );
200 
202 
203  std::vector<Int_t>::const_iterator current;
204  std::vector<Int_t> digiList = MyCluster().DigiList();
205 
206  for (current=digiList.begin();current!=digiList.end();++current)
207  {
208  PndEmcDigi *lDigi = (PndEmcDigi *) DigiArray()->At(*current);
209  //PndEmcTwoCoordIndex *tci = lDigi->GetTCI(); //[R.K. 03/2017] unused variable?
210  //PndEmcXtal* xtal = tciXtalMap.find(tci)->second; //[R.K. 01/2017] unused variable?
211 
212  const TVector3 lDigiWhere=lDigi->where();
213 
214  const double lDigiEnergy=lDigi->GetEnergy();
215  const double lLinWeight=lDigiEnergy/lClusEnergy;
216 
217  lLinSum+=lLinWeight*lDigiWhere;
218  }
219 
220  PndEmcTwoCoordIndex *lTCI=PndEmcStructure::Instance()->locateIndex(lLinSum.Theta(),lLinSum.Phi());
221 
222  assert(lTCI!=0);
223 
224  const PndEmcXtal *lGeom=tciXtalMap.find(lTCI)->second;
225 
226  // First, find out if the point is outside the crystal.
227 
228  const TVector3 lCentre = lGeom->frontCentre();
229  const TVector3 lNormal = lGeom->normalToFrontFace();
230  const TVector3 lVector = lCentre - lLinSum;
231  const double lLength = lNormal.Dot(lVector);
232 
233  if (lLength < 0.0)
234  {
235  // Point is outside crystal
236  // Project point back onto front-face.
237  const TVector3 lUnit = lLinSum.Unit();
238  const double lMag = (lNormal.Dot(lCentre)/lNormal.Dot(lUnit));
239  lLinSum.SetMag(lMag);
240  }
241 
242  return lLinSum;
243 }
244 
245 TVector3
246 PndEmcClusterProperties::LiloWhere(std::vector<Double_t> params)
247 {
248  Double_t offsetParmA=params[0];
249  Double_t offsetParmB=params[1];
250  Double_t offsetParmC=params[2];
251 
252  const double lClusEnergy=Energy();
253 
254  assert(lClusEnergy!=0);
255 
256  const double lOffset=
257  offsetParmA-offsetParmB*exp(-offsetParmC*pow(lClusEnergy,1.171)) * pow(lClusEnergy,-0.534);
258 
259  TVector3 lLiloPoint( 1, 1, 1 );
260 
261  TVector3 lLinSum( 0, 0, 0 );
262  TVector3 lLogSum( 0, 0, 0 );
263 
264  double lLogWeightSum=0;
265  int lLogNum=0;
266 
267  bool lLogSecondTheta = false;
268  bool lLogSecondPhi = false;
269  int lLogFirstTheta = -666;
270  int lLogFirstPhi = -666;
271 
272  std::vector<Int_t>::const_iterator current;
273  std::vector<Int_t> digiList = MyCluster().DigiList();
275 
276  for (current=digiList.begin();current!=digiList.end();++current)
277  {
278  PndEmcDigi *lDigi = (PndEmcDigi *) DigiArray()->At(*current);
279  PndEmcXtal* xtal = tciXtalMap.find(lDigi->GetTCI())->second;
280  const TVector3 tNormal=xtal->normalToFrontFace();
281 
282 
283  // TODO Consider forwars endcup separetly
284  //TVector3 tmpPoint=lDigi->where();
285  // if(lDigi->theta() > 3000)
286  //tmpPoint += *tNormal * 7.0 * 6.2;
287  //else
288  //tmpPoint += tNormal * 6.2;
289 
290  const TVector3 lDigiWhere=lDigi->where();
291 
292  const int lDigiTheta=lDigi->GetThetaInt();
293  const int lDigiPhi=lDigi->GetPhiInt();
294  const double lDigiEnergy=lDigi->GetEnergy();
295  const double lLinWeight=lDigiEnergy/lClusEnergy;
296  const double lLogWeight=lOffset+log(lLinWeight);
297 
298  lLinSum+=lLinWeight*lDigiWhere;
299  if(lLogWeight>0)
300  {
301  lLogSum+=lLogWeight*lDigiWhere;
302  lLogWeightSum+=lLogWeight;
303  lLogNum++;
304 
305  if(lLogNum==1)
306  {
307  lLogFirstTheta=lDigiTheta;
308  lLogFirstPhi=lDigiPhi;
309  }
310  else
311  {
312  if(!lLogSecondTheta&&lDigiTheta!=lLogFirstTheta)
313  lLogSecondTheta=true;
314  if(!lLogSecondPhi&&lDigiPhi!=lLogFirstPhi)
315  lLogSecondPhi=true;
316  }
317  }
318  }
319 
320  if(lLogNum>0) lLogSum*=1./lLogWeightSum;
321 
322 
323  lLiloPoint.SetTheta(lLogSecondTheta?lLogSum.Theta():lLinSum.Theta());
324  lLiloPoint.SetPhi(lLogSecondPhi?lLogSum.Phi():lLinSum.Phi());
325 
326 
327  PndEmcTwoCoordIndex *lTCI=PndEmcStructure::Instance()->locateIndex(lLiloPoint.Theta(),lLiloPoint.Phi());
328 
329  assert(lTCI!=0);
330 
331  const PndEmcXtal *lGeom=tciXtalMap.find(lTCI)->second;
332 
333  // First, find out if the point is outside the crystal.
334 
335  const TVector3 lLiloVector = lLiloPoint;
336  const TVector3 lCentre = lGeom->frontCentre();
337 
338  const TVector3 lNormal = lGeom->normalToFrontFace();
339  const TVector3 lVector = lCentre - lLiloVector;
340  const double lLength = lNormal.Dot(lVector);
341  //const Hep3Vector lUnit = lLiloVector.unit();
342  //const double lMag = (lNormal->dot(lCentre)/lNormal->dot(lUnit));
343  //cout<<" With original code, lilo-position "<<float(lMag)<<endl;
344 
345  if (lLength < 0.0)
346  {
347  // Point is outside crystal (not sure its correct for all cases?).
348  // Anyhow, project point back onto front-face.
349  const TVector3 lUnit = lLiloVector.Unit();
350  const double lMag = (lNormal.Dot(lCentre)/lNormal.Dot(lUnit));
351  lLiloPoint.SetMag(lMag);
352  }
353  else
354  {
355  // Don't project onto front-face. Keep the centroid inside the crytal.
356  //cout<<" Point is inside crystal, keep as it is "<<endl;
357  if (lLogNum > 1)
358  {
359  // Use logarithmic centroid position
360  lLiloPoint.SetMag(lLogSum.Mag());
361  //cout<<" With log centroid method, lilo-position "<<lLiloPoint.Mag()<<endl;
362  }
363  else
364  {
365  // Use linear centroid position
366  lLiloPoint.SetMag(lLinSum.Mag());
367  //cout<<" Use lin centroid method, lilo-position "<<lLiloPoint.Mag()<<endl;
368  }
369 
370  }
371 
372  return lLiloPoint;
373 }
374 
TVector3 pos
TClonesArray * digi
virtual Double_t GetEnergy() const
Definition: PndEmcDigi.cxx:296
represents the reconstructed hit of one emc crystal
Definition: PndEmcDigi.h:40
friend F32vec4 exp(const F32vec4 &a)
Definition: P4_F32vec4.h:109
Int_t GetThetaInt() const
Definition: PndEmcDigi.h:99
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
int n
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:110
const TVector3 & frontCentre() const
Definition: PndEmcXtal.cxx:145
represents coordinates of one crystal
Definition: PndEmcXtal.h:36
TVector3 Where(TString method, std::vector< Double_t > params)
const std::vector< Int_t > & DigiList() const
Definition: PndEmcCluster.h:40
stores crystal index coordinates (x,y) or (theta,phi)
PndEmcClusterProperties(const PndEmcCluster &cluster, const TClonesArray *digiArray)
Double_t GetTheta() const
Definition: PndEmcDigi.h:101
const TVector3 & normalToFrontFace() const
Definition: PndEmcXtal.cxx:151
const PndEmcCluster & MyCluster() const
Double_t
virtual Double_t Major_axis() const
const PndEmcTciXtalMap & GetTciXtalMap() const
a cluster (group of neighboring crystals) of hit emc crystals
Definition: PndEmcCluster.h:29
PndEmcTwoCoordIndex * locateIndex(double theta, double phi) const
const TClonesArray * DigiArray() const
virtual double Phi1() const
virtual double Theta1() const
virtual Double_t Energy() const
TVector3 LiloWhere(std::vector< Double_t > params)
Double_t GetPhi() const
Definition: PndEmcDigi.h:102
std::map< PndEmcTwoCoordIndex *, PndEmcXtal * > PndEmcTciXtalMap
virtual Double_t energy() const
ClassImp(PndAnaContFact)
const TVector3 & where() const
Definition: PndEmcDigi.h:111
TTree * t
Definition: bump_analys.C:13
Double_t theta() const
static PndEmcStructure * Instance()
Double_t Pi
Double_t phi() const
PndEmcTwoCoordIndex * GetTCI() const
Definition: PndEmcDigi.cxx:216
static Double_t FindPhiDiff(Double_t, Double_t)
virtual Double_t Mass() const
Int_t GetPhiInt() const
Definition: PndEmcDigi.h:100