KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVFlowTensor.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Tue Jun 30 12:41:37 2015
2 //Author: John Frankland,,,
3 
4 #include "KVFlowTensor.h"
5 #include "TMatrixDUtils.h"
6 #include "TMatrixDSymEigen.h"
7 
9 
10 
11 
12 
15 KVFlowTensor::KVFlowTensor(void): KVVarGlob(), fTensor(3), fEVal(3)
16 {
17  // Default constructor
18  init_KVFlowTensor();
19  SetName("KVFlowTensor");
20  SetTitle("Kinetic energy flow tensor of Gyulassy et al.");
21 }
22 
23 
24 
27 
28 KVFlowTensor::KVFlowTensor(const Char_t* nom): KVVarGlob(nom), fTensor(3), fEVal(3)
29 {
30  // Constructor with a name for the global variable
32 }
33 
34 
35 
38 
39 KVFlowTensor::KVFlowTensor(const KVFlowTensor& a): KVVarGlob(), fTensor(3), fEVal(3)
40 {
41  // Copy constructor
42  a.Copy(*this);
43 }
44 
45 
46 
49 
51 {
52  // Destructor
53 }
54 
55 
56 
59 
61 {
62  // Copy properties of 'this' object into the KVVarGlob object referenced by 'a'
63 
64  KVFlowTensor& aglob = (KVFlowTensor&)a;
65  KVVarGlob::Copy(a);// copy attributes of KVVarGlob base object
66  aglob.Init();
67  aglob.fTensor = fTensor;
68  aglob.fNParts = fNParts;
69  if (fCalculated) aglob.Calculate();
70 }
71 
72 
73 
76 
78 {
79  // Operateur =
80 
81  if (&a != this) a.Copy(*this);
82  return *this;
83 }
84 
85 
86 
89 
91 {
92  // Initialisation of internal variables, called once before beginning treatment
93 
94  Reset();
95  TString wgt = GetOptionString("weight");
96  if (wgt == "RKE") weight = kRKE;
97  else if (wgt == "ONE" || wgt == "" || wgt == "1") weight = kONE;
98  else weight = kNRKE;
99 }
100 
101 
102 
105 
107 {
108  // Reset internal variables, called before treatment of each event
109  fTensor.Zero();
110  fNParts = 0;
111  fCalculated = false;
112 }
113 
114 
115 
132 
134 {
135  // \param index one of the following values:
136  //
137  // Name | Index | Definition
138  // ---------------|-----------------------------|---------------------------------------------
139  // "FlowAngle" |KVFlowTensor::kFlowAngle |polar angle of \f$\vec{e_1}\f$
140  // "Sphericity" |KVFlowTensor::kSphericity |\f$\frac{3}{2}(1-\lambda_1)\f$
141  // "Coplanarity" |KVFlowTensor::kCoplanarity |\f$\frac{\sqrt{3}}{2}(\lambda_2-\lambda_3)\f$
142  // "KinFlowRatio13"|KVFlowTensor::kKinFlowRatio13|\f$\sqrt{\frac{\lambda_1}{\lambda_3}}\f$
143  // "KinFlowRatio23"|KVFlowTensor::kKinFlowRatio23|\f$\sqrt{\frac{\lambda_2}{\lambda_3}}\f$
144  // "PhiReacPlane" |KVFlowTensor::kPhiReacPlane |\f$\phi\f$ angle of \f$\vec{e_1}\f$
145  // "SqueezeAngle" |KVFlowTensor::kSqueezeAngle |see Gyulassy et al
146  // "SqueezeRatio" |KVFlowTensor::kSqueezeRatio |see Gyulassy et al
147  // "NumberParts" |KVFlowTensor::kNumberParts |number of particles used in tensor
148  //
149  // \return value associated with given index
150  switch (index) {
151  case kFlowAngle:
152  return TMath::RadToDeg() * e(1).Theta();
153  break;
154 
155  case kSphericity:
156  return fSphericity;
157  break;
158 
159  case kCoplanarity:
160  return fCoplanarity;
161  break;
162 
163  case kKinFlowRatio13: {
164  if (f(3) <= 0.) return -1.;
165  if (f(1) <= 0.) return -1.;
166  return TMath::Min(1e+03, pow(f(1) / f(3), 0.5));
167  }
168  break;
169 
170  case kKinFlowRatio23: {
171  if (f(3) <= 0.) return -1.;
172  if (f(2) <= 0.) return -1.;
173  return TMath::Min(1e+03, pow(f(2) / f(3), 0.5));
174  }
175  break;
176 
177  case kPhiReacPlane: {
178  Double_t phi = TMath::RadToDeg() * e(1).Phi();
179  return (phi < 0 ? 360 + phi : phi);
180  }
181  break;
182 
183  case kSqueezeAngle:
184  return fSqueezeAngle;
185  break;
186 
187  case kSqueezeRatio:
188  return fSqOutRatio;
189  break;
190 
191  case kNumberParts:
192  return fNParts;
193  break;
194 
195  default:
196  break;
197  }
198 
199  return 0;
200 }
201 
202 
203 
206 
208 {
209  // Calculate eigenvalues & eigenvectors of tensor
210 
211  TMatrixDSymEigen diagonalize(fTensor);
212  TMatrixD evectors = diagonalize.GetEigenVectors();
213  fEVal = diagonalize.GetEigenValues();
214 
215  for (int i = 0; i < 3; i++) {
216  TMatrixDColumn col(evectors, i);
217  fEVec[i].SetXYZ(col[0], col[1], col[2]);
218  }
219 
220  // check orientation of flow axis
221  // by symmetry/convention, we allow FlowAngle between 0 & 90° i.e. flow vector always
222  // points in the forward beam direction.
223  if (fEVec[0].Theta() > TMath::PiOver2()) {
224  fEVec[0] = -fEVec[0];
225  }
226 
227  // check we have an orthonormal basis
228  // we choose evec[0]=>'z' evec[1]=>'y' evec[2]=>'x'
229  // therefore we should have evec[2].Cross(evec[1])=evec[0]
230  // if not we change the sign of evec[2]
231  if (fEVec[2].Cross(fEVec[1]) != fEVec[0]) fEVec[2] = -fEVec[2];
232 
233  // set up azimuthal rotation of CM axes around beam axis in order to put new 'X'-axis in reaction plane
234  // we use the phi of the major axis (largest eigenvector)
236  fAziReacPlane.RotateZ(e(1).Phi());
237 
239  fFlowReacPlane.RotateY(e(1).Theta());
240  fFlowReacPlane.RotateZ(e(1).Phi());
241 
242  // calculate Gutbrod squeeze angle (PRC42(1990)640
243  // defined as the angle by which the middle eigenvector e2
244  // needs to be rotated around the e1 flow axis
245  // in order to be brought in to the reaction plane
246  TVector3 normReac = e(1).Cross(TVector3(0, 0, 1)); //normal to reaction plane: e1 x z
247  Double_t angle = TMath::RadToDeg() * e(2).Angle(normReac);
248  // on the contrary to Gutbrod et al, we define this angle between 0 and 90 degrees.
249  // see Fig. 3 of paper: only 0-90 angles can be defined
250  fSqueezeAngle = (angle < 90 ? 90 - angle : angle - 90);
251 
252  // now calculate the in-plane and out-of-plane flow according to Fig. 5 of Gutbrod et al
253  Double_t a = pow(f(2), 0.5); //semi-axes of ellipsoid given by square roots of eigenvalues
254  Double_t b = pow(f(3), 0.5);
256  Double_t t0 = TMath::ATan(tan_t);
257  Double_t inPlane = a * cos(t0) * cos(fSqueezeAngle * TMath::DegToRad()) - b * sin(t0) * sin(fSqueezeAngle * TMath::DegToRad());
258  tan_t = a / (b * tan(fSqueezeAngle * TMath::DegToRad()));
259  t0 = atan(tan_t);
260  Double_t outOfPlane = a * cos(t0) * sin(fSqueezeAngle * TMath::DegToRad()) + b * sin(t0) * cos(fSqueezeAngle * TMath::DegToRad());
261  if (inPlane <= 0.) fSqOutRatio = -1.;
262  else fSqOutRatio = TMath::Min(1.e+03, outOfPlane / inPlane);
263 
264  // calculate sphericity & coplanarity
265  sum_val_prop = f(1) + f(2) + f(3);
266  if (sum_val_prop > .1) {
267  fSphericity = 1.5 * (1. - f(1) / sum_val_prop);
268  fCoplanarity = sqrt(3.) * (f(2) - f(3)) / sum_val_prop / 2.;
269  }
270  else {
271  fSphericity = fCoplanarity = -1;
272  }
273  fCalculated = kTRUE;
274 }
275 
276 
277 
278 
294 
296 {
297  //Common initialisation for all constructors
298  //
299  // Default frame is set to "CM".
300  //
301  // Default weight is set to NRKE if none was given
302  // by calling method SetOption("weight","[your choice]")
303  // with one of the following choices:
304  // Option | Name | Weight
305  // ------------|--------------------------------------|---------------------------------------------------
306  // "NRKE" | non-relativistic KE tensor (default) | \f$w_{\nu}=(2m_{\nu})^{-1}\f$
307  // "RKE" | relativistic KE tensor | \f$w_{\nu}={1 \over {m_{\nu}(\gamma_{\nu}+1)}}\f$
308  // "ONE","1",""| sphericity tensor | \f$w=1\f$
309  //
310  // Default maximum number of branches for TTree is 3: FlowAngle, Sphericity, and Coplanarity
311 
312  fType = KVVarGlob::kOneBody; // this is a 1-body variable
313 
314  SetFrame("CM");
315  SetOption("weight", "NRKE");
316 
317  fTensor.Zero();
318 
319  SetNameIndex("FlowAngle", kFlowAngle);
320  SetNameIndex("Sphericity", kSphericity);
321  SetNameIndex("Coplanarity", kCoplanarity);
322  SetNameIndex("KinFlowRatio13", kKinFlowRatio13);
323  SetNameIndex("KinFlowRatio23", kKinFlowRatio23);
324  SetNameIndex("PhiReacPlane", kPhiReacPlane);
325  SetNameIndex("SqueezeAngle", kSqueezeAngle);
326  SetNameIndex("SqueezeRatio", kSqueezeRatio);
327  SetNameIndex("NumberParts", kNumberParts);
328 
330 
331  fNParts = 0;
332 }
333 
334 
335 
341 
343 {
344  // Fill tensor components with nucleus' momentum components using the required weight
345  //
346  // If option "DOUBLE" is set, the chosen weight will be doubled
347  // (this is for the case where e.g. only forward hemisphere particles are included)
348 
349  Double_t W;
350  switch (weight) {
351  case kONE:
352  W = 1;
353  break;
354  case kRKE:
355  W = 1. / (n->GetMass() * (1 + n->Gamma()));
356  break;
357  default:
358  case kNRKE:
359  W = 1. / (2.*n->GetMass());
360  break;
361  }
362  if (IsOptionGiven("DOUBLE")) W *= 2.;
363  for (int i = 0; i < 3; i++) {
364  for (int j = i; j < 3; j++) {
365  Double_t xx = W * n->GetMomentum()[i] * n->GetMomentum()[j];
366  fTensor(i, j) += xx;
367  if (i != j) fTensor(j, i) += xx;
368  }
369  }
370  ++fNParts;
371 }
372 
373 
374 
385 
387 {
388  // Returns the azimuthal rotation around the beam axis required
389  // to put the \f$x\f$-axis in the reaction plane defined by the beam axis
390  // and the major axis (largest eigenvalue) of the ellipsoid.
391  //
392  // The azimuthal angle of the rotation is that of the major axis
393  // in the forward direction.
394  //
395  // Note that this rotation applies to whatever frame was used to calculate
396  // the tensor (default: "CM")
397 
398  return fAziReacPlane;
399 }
400 
401 
402 
413 
415 {
416  // Returns composition of two rotations:
417  // - around \f$z\f$-axis to put \f$x\f$-axis in reaction plane (see GetAziReacPlaneRotation())
418  // - around \f$y\f$-axis to align \f$z\f$-axis with flow (major) axis
419  //
420  // In this rotated frame, \f$\theta\f$ is polar angle with respect to flow axis
421  // and \f$\phi\f$ is azimuthal angle around flow axis (\f$\phi\f$=0,180 => in-plane)
422  //
423  // Note that this rotation applies to whatever frame was used to calculate
424  // the tensor (default: "CM")
425 
426  return fFlowReacPlane;
427 }
428 
429 
430 
433 
435 {
436  // if opt="tensor", just print contents of tensor
437 
438  if (strcmp(opt, "tensor")) KVVarGlob::Print();
439  std::cout << "Number of particles = " << fNParts << std::endl;
440  fTensor.Print();
441 }
442 
443 
444 
int Int_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define b(i)
char Char_t
double Double_t
const Bool_t kTRUE
const char Option_t
double cos(double)
double pow(double, double)
double atan(double)
double tan(double)
double sin(double)
Kinetic energy flow tensor of Gyulassy et al and associated shape variables.
Definition: KVFlowTensor.h:77
const TVector3 & e(int i) const
Definition: KVFlowTensor.h:91
Double_t fCoplanarity
Definition: KVFlowTensor.h:100
TVectorD fEVal
the 3 eigenvalues
Definition: KVFlowTensor.h:85
Double_t sum_val_prop
Definition: KVFlowTensor.h:103
Int_t fNParts
number of particles included in tensor
Definition: KVFlowTensor.h:101
virtual ~KVFlowTensor(void)
Destructor.
Double_t fSphericity
Definition: KVFlowTensor.h:99
KVFlowTensor & operator=(const KVFlowTensor &a)
Operateur =.
void Print(Option_t *="") const
if opt="tensor", just print contents of tensor
const TRotation & GetFlowReacPlaneRotation() const
virtual void Init()
Initialisation of internal variables, called once before beginning treatment.
void init_KVFlowTensor()
Double_t f(int i) const
Definition: KVFlowTensor.h:87
Double_t getvalue_int(Int_t) const
KVFlowTensor()
Default constructor.
Double_t fSqOutRatio
Gutbrod squeeze-out ratio.
Definition: KVFlowTensor.h:98
enum KVFlowTensor::@19 weight
Double_t fSqueezeAngle
Gutbrod squeeze angle.
Definition: KVFlowTensor.h:97
TVector3 fEVec[3]
the 3 eigenvectors
Definition: KVFlowTensor.h:86
void fill(const KVNucleus *n)
void Calculate()
Calculate eigenvalues & eigenvectors of tensor.
Bool_t fCalculated
Definition: KVFlowTensor.h:102
virtual void Reset()
Reset internal variables, called before treatment of each event.
virtual void Copy(TObject &obj) const
Copy properties of 'this' object into the KVVarGlob object referenced by 'a'.
const TRotation & GetAziReacPlaneRotation() const
TMatrixDSym fTensor
the tensor
Definition: KVFlowTensor.h:79
TRotation fAziReacPlane
azimuthal rotation around beam axis to reaction plane
Definition: KVFlowTensor.h:95
TRotation fFlowReacPlane
rotate XZ to reaction plane, then align Z with flow axis
Definition: KVFlowTensor.h:96
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:125
Base class for all global variable implementations.
Definition: KVVarGlob.h:217
void SetOption(const Char_t *option, const Char_t *value)
Definition: KVVarGlob.h:490
void Print(Option_t *="") const
Definition: KVVarGlob.cpp:276
void Copy(TObject &obj) const
Make a copy of this object.
Definition: KVVarGlob.h:328
void SetNameIndex(const Char_t *name, Int_t index)
Definition: KVVarGlob.cpp:223
void SetMaxNumBranches(Int_t n)
Definition: KVVarGlob.h:640
TString GetOptionString(const Char_t *opt) const
Definition: KVVarGlob.h:505
Bool_t IsOptionGiven(const Char_t *opt)
Definition: KVVarGlob.h:498
void SetFrame(const Char_t *ref)
Definition: KVVarGlob.h:474
Int_t fType
type of variable global; = kOneBody, kTwoBody or kNBody
Definition: KVVarGlob.h:227
const TMatrixD & GetEigenVectors() const
const TVectorD & GetEigenValues() const
void Print(Option_t *name="") const
virtual TMatrixTBase< Element > & Zero()
TRotation & SetToIdentity()
TRotation & RotateY(Double_t)
TRotation & RotateZ(Double_t)
void SetXYZ(Double_t x, Double_t y, Double_t z)
Double_t Phi() const
Double_t Angle(const TVector3 &) const
Double_t Theta() const
TVector3 Cross(const TVector3 &) const
VecExpr< UnaryOp< Sqrt< T >, SVector< T, D >, T >, T, D > sqrt(const SVector< T, D > &rhs)
SVector< T, 3 > Cross(const SVector< T, 3 > &lhs, const SVector< T, 3 > &rhs)
const Int_t n
gr SetName("gr")
Double_t Min(Double_t a, Double_t b)
Double_t ATan(Double_t)
constexpr Double_t PiOver2()
constexpr Double_t DegToRad()
Double_t Tan(Double_t)
constexpr Double_t RadToDeg()
auto * a