KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVFlowTensor.cpp
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
14
15KVFlowTensor::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
28KVFlowTensor::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
39KVFlowTensor::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 {
272 }
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
char Char_t
double Double_t
constexpr Bool_t kTRUE
const char Option_t
TGLVector3 Cross(const TGLVector3 &v1, const TGLVector3 &v2)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint angle
Kinetic energy flow tensor of Gyulassy et al and associated shape variables.
Double_t fCoplanarity
TVectorD fEVal
the 3 eigenvalues
Double_t sum_val_prop
Int_t fNParts
number of particles included in tensor
virtual ~KVFlowTensor(void)
Destructor.
Double_t fSphericity
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
Double_t getvalue_int(Int_t) const
const TVector3 & e(int i) const
KVFlowTensor()
Default constructor.
Double_t fSqOutRatio
Gutbrod squeeze-out ratio.
enum KVFlowTensor::@19 weight
Double_t fSqueezeAngle
Gutbrod squeeze angle.
TVector3 fEVec[3]
the 3 eigenvectors
void fill(const KVNucleus *n)
void Calculate()
Calculate eigenvalues & eigenvectors of tensor.
Bool_t fCalculated
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
TRotation fAziReacPlane
azimuthal rotation around beam axis to reaction plane
TRotation fFlowReacPlane
rotate XZ to reaction plane, then align Z with flow axis
Description of properties and kinematics of atomic nuclei.
Definition KVNucleus.h:126
Base class for all global variable implementations.
Definition KVVarGlob.h:233
void SetOption(const Char_t *option, const Char_t *value)
Definition KVVarGlob.h:521
void Print(Option_t *="") const
void Copy(TObject &obj) const
Definition KVVarGlob.h:346
void SetNameIndex(const Char_t *name, Int_t index)
void SetMaxNumBranches(Int_t n)
Definition KVVarGlob.h:683
TString GetOptionString(const Char_t *opt) const
Definition KVVarGlob.h:536
Bool_t IsOptionGiven(const Char_t *opt)
Definition KVVarGlob.h:529
void SetFrame(const Char_t *ref)
Definition KVVarGlob.h:505
Int_t fType
type of variable global; = kOneBody, kTwoBody or kNBody
Definition KVVarGlob.h:243
void Copy(TObject &arc) const override
const TVectorD & GetEigenValues() const
const TMatrixD & GetEigenVectors() const
virtual TMatrixTBase< Element > & Zero()
void Print(Option_t *name="") const override
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
RVec< PromoteType< T > > tan(const RVec< T > &v)
RVec< PromoteType< T > > cos(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > pow(const RVec< T0 > &v, const T1 &y)
RVec< PromoteType< T > > atan(const RVec< T > &v)
RVec< PromoteType< T > > sin(const RVec< T > &v)
gr SetName("gr")
const Int_t n
Expr< UnaryOp< Sqrt< T >, Expr< A, T, D, D2, R >, T >, T, D, D2, R > sqrt(const Expr< A, T, D, D2, R > &rhs)
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()
TArc a
ClassImp(TPyArg)