KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
mdweight.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Thu May 7 11:02:24 2015
2 //Author: John Frankland,,,
3 
4 #include "mdweight.h"
5 #include "TMath.h"
6 
8 
9 namespace MicroStat {
10 
11 
17 
19  {
20  // energy distribution of particle in gas
21  // arg[0] = energy/available energy
22  // par[0] = number of particles in gas
23  // par[1] = mass ratio = massTot/(massTot-mPart)
24  Double_t e = arg[0];
25  Double_t N = par[0];
26  Double_t massRat = par[1];
27 
28  Double_t val = 0.;
29  if ((e > 0) && (e * massRat < 1) && (N > 2)) {
30  val = TMath::Sqrt(e) * TMath::Power(1. - massRat * e, (3.*N - 8.) / 2.);
31  }
32  return val;
33  }
34 
35 
36 
40 
42  {
43  // find/create energy distribution for given number of particles
44  // N and mass ratio R.
45 
46  TString fn = Form("fKE_N%d_R%f", N, R);
47  TF1* f = (TF1*)fKEDist.FindObject(fn);
48  if (!f) {
49  f = new TF1("mdweight::SPKEDist", mdweight::edist, 0, 1, 2);
50  f->SetRange(0, 1.);
51  f->SetParameters((Double_t)N, R);
52  f->SetNpx(100);
53  f->SetName(fn);
54  fKEDist.Add(f);
55  }
56  return f;
57  }
58 
59 
60 
67 
68  double CosThetaDist(double* x, double* par)
69  {
70  // parameterise angular distribution as function of ratio between
71  // P(cos theta=+/-1) and P(cos theta=0)
72  // par[0] = a = P(cos theta=+/-1)
73  // par[1] = b = P(cos theta=0)
74  // x = cosTheta
75  if (abs(par[0] - par[1]) < 1.e-6) return par[1];
76 
77  double a = par[0];
78  double b = par[1];
79  double cosTheta = x[0];
80  double alpha = TMath::Pi() * cosTheta;
81  return (a - b) / 2.*(1. - TMath::Cos(alpha)) + b;
82  }
83 
84 
85 
87 
89  : fCosTheta("CosTheta", CosThetaDist, -1, 1, 2)
90  {
91  fKEDist.SetOwner();
93  log10twelve = TMath::Log(1e+12);
94  eDisp = 0.0;
95  massTot = 0.0;
96  massTot0 = 0.0;
97  px = 0.0;
98  py = 0.0;
99  pz = 0.0;
100  SetAnisotropy(1, 1);
101  }
102 
103 
104 
107 
109  {
110  // Destructor
111  }
112 
113 
114 
118 
120  {
121  // Set available energy, E, and calculate statistical weight
122  // for this event
123 
124  if (E <= 0) {
125  setAvailableEnergy(0.);
126  setWeight(0.);
127  return;
128  }
130  Double_t N = e->GetMult();
131  Double_t logmass_sum, mass_sum;
132  logmass_sum = mass_sum = 0.;
133  KVNucleus* n;
134  while ((n = e->GetNextParticle())) {
135  Double_t m = n->GetMass();
136  logmass_sum += TMath::Log(m);
137  mass_sum += m;
138  }
139  A = (3 * (N - 1) / 2.) * log2pi - TMath::LnGamma(3 * (N - 1) / 2.)
140  + 1.5 * (logmass_sum - TMath::Log(mass_sum));
141  B = (3 * N - 5) / 2.;
142 
143  Double_t w = TMath::Exp((A + B * TMath::Log(E)) - log10twelve);
144  setWeight(w);
145  }
146 
147 
148 
152 
154  {
155  // Call before generating an event with StatWeight::GenerateEvent
156  // using the given partition and available energy
157 
158  massTot0 = 0;
159 #ifdef WITH_CPP11
160  for (auto& e : *partition) massTot0 += e.GetMass();
161 #else
162  for (KVEvent::Iterator it = partition->begin(); it != partition->end(); ++it) massTot0 += (*it).GetMass();
163 #endif
165  }
166 
167 
168 
172 
174  {
175  // Called by StatWeight::GenerateEvent before generating another
176  // event using the same partition as the last
178  massTot = massTot0;
179  px = py = pz = 0.0;
180  }
181 
182 
183 
189 
191  {
192  // Called by StatWeight::GenerateEvent when adding a particle to the event
193  // N is the number of particles still to add including this one
194  //
195  // The algorithm was written by Daniel Cussol (LPC Caen, France).
196 
197  Double_t mPart = part->GetMass();
198  Double_t rR = mPart / massTot;
199  Double_t ratio;
200  if (rR < 1.) ratio = 1. / (1. - rR);
201  else ratio = 1.;
202  Double_t ec = 0.; // kinetic energy of particle
203  Double_t ppx, ppy, ppz; // components of particle momentum
204  ppx = ppy = ppz = 0;
205  if (N >= 2) {
206  Double_t p = 0.; //momentum to give particle
207  if (N > 2) {
208  // draw random KE from 1-particle distribution for given N & ratio
209  ec = eDisp * getKEdist(N, ratio)->GetRandom();
210  p = sqrt(2.*mPart * ec);
211  }
212  else {
213  // last 2 particles: share remaining available energy
214  p = sqrt(2.*(massTot - mPart) * mPart * eDisp / massTot);
215  ec = p * p / 2. / mPart;
216  }
217  Double_t ct = fCosTheta.GetRandom(-1, 1); //1. - 2.*gRandom->Rndm();
218  Double_t st = TMath::Sqrt(1. - ct * ct);
219  Double_t phi = gRandom->Rndm() * 2.*TMath::Pi();
220  ppz = ct * p;
221  ppx = st * TMath::Cos(phi) * p;
222  ppy = st * TMath::Sin(phi) * p;
223  ppx += px * rR;
224  ppy += py * rR;
225  ppz += pz * rR;
226  }
227  else if (N == 1) {
228  ppx = px;
229  ppy = py;
230  ppz = pz;
231  ec = 0;
232  }
233  part->SetMomentum(ppx, ppy, ppz);
234 
235  eDisp -= ec * ratio;
236  massTot -= mPart;
237  px -= ppx;
238  py -= ppy;
239  pz -= ppz;
240  }
241 
242 
243 }/* namespace MicroStat */
244 
int Int_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define b(i)
#define f(i)
#define e(i)
double Double_t
#define N
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
Base class container for multi-particle events.
Definition: KVEvent.h:176
Iterator begin() const
Definition: KVEvent.h:423
Iterator end() const
Definition: KVEvent.h:428
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:125
void SetMomentum(const TVector3 &v)
Definition: KVParticle.h:535
Double_t GetMass() const
Definition: KVParticle.h:531
virtual void SetOwner(Bool_t enable=kTRUE)
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
void setAvailableEnergy(Double_t e)
Definition: StatWeight.h:30
Double_t GetAvailableEnergy() const
Definition: StatWeight.h:44
void setWeight(Double_t w)
Definition: StatWeight.h:26
Calculate molecular dynamics ensemble weights for events .
Definition: mdweight.h:19
void resetGenerateEvent()
Definition: mdweight.cpp:173
Double_t log10twelve
Definition: mdweight.h:21
void initGenerateEvent(KVEvent *partition)
Definition: mdweight.cpp:153
virtual void SetWeight(KVEvent *e, Double_t E)
Definition: mdweight.cpp:119
Double_t eDisp
Definition: mdweight.h:22
TF1 * getKEdist(Int_t, Double_t)
function used to draw random CosTheta values
Definition: mdweight.cpp:41
Double_t massTot
Definition: mdweight.h:22
static Double_t edist(Double_t *, Double_t *)
Definition: mdweight.cpp:18
Double_t massTot0
Definition: mdweight.h:22
virtual ~mdweight()
Destructor.
Definition: mdweight.cpp:108
virtual void nextparticleGenerateEvent(Int_t, KVNucleus *)
Definition: mdweight.cpp:190
void SetAnisotropy(double a, double b)
Definition: mdweight.h:37
KVHashList fKEDist
Definition: mdweight.h:23
Double_t log2pi
Definition: mdweight.h:21
virtual Double_t GetRandom(Double_t xmin, Double_t xmax, TRandom *rng=nullptr, Option_t *opt=nullptr)
virtual Double_t Rndm()
VecExpr< UnaryOp< Sqrt< T >, SVector< T, D >, T >, T, D > sqrt(const SVector< T, D > &rhs)
Double_t x[n]
const Int_t n
const long double m
Definition: KVUnits.h:70
double CosThetaDist(double *x, double *par)
Definition: mdweight.cpp:68
Double_t Exp(Double_t x)
Double_t Power(Double_t x, Double_t y)
constexpr Double_t E()
Double_t Log(Double_t x)
Double_t Sqrt(Double_t x)
Double_t Cos(Double_t)
constexpr Double_t Pi()
constexpr Double_t R()
Double_t LnGamma(Double_t z)
Double_t Sin(Double_t)
constexpr Double_t TwoPi()
auto * a