67 #include "TDatabasePDG.h"
68 #include "TParticle.h"
69 #include "TObjArray.h"
78 #include "TGeVSimParticle.h"
79 #include "TGeVSimEvent.h"
80 #include "TGeVSimParams.h"
83 #include <sys/times.h>
102 for (Int_t i=0; i<4; i++)
108 TGeVSim::TGeVSim(
const char *name)
120 fIsMultTotal = kTRUE;
125 fPartTypes =
new TObjArray();
126 fPartBuffer =
new TClonesArray(
"TParticle", 5000, kTRUE);
134 TGeVSim::TGeVSim(
const char *name, Float_t psi, Bool_t isMultTotal)
153 if (psi < 0 || psi > 360 )
154 Error (
"TGeVSim",
"Event plane angle ( %d )out of range [0..360]", psi);
156 fPsi = psi * TMath::Pi() / 180. ;
157 fIsMultTotal = isMultTotal;
161 fPartTypes =
new TObjArray();
162 fPartBuffer =
new TClonesArray(
"TParticle", 1000);
178 if (fPartTypes)
delete fPartTypes;
179 if (fPartBuffer)
delete fPartBuffer;
205 p->SetEllipticSimple(0.05);
206 g->AddParticleType(p);
209 p->SetEllipticSimple(0.05);
210 g->AddParticleType(p);
213 g->AddParticleType(
new TGeVSimParticle(-321, kLevy, 200, 0.25, 1, 10));
215 g->SetEtaRange(-3, 3);
223 void TGeVSim::Print(Option_t* option)
const
230 const char *multType;
231 if (fIsMultTotal) multType =
"TOTAL";
232 else multType =
"DENSITY dN/dY";
234 printf(
"\n*******************************************************\n**\n");
235 printf(
"** WELCOME to GeVSim\n");
236 printf(
"** NAME: %s TITLE: %s\n**\n", GetName(), GetTitle());
237 printf(
"** Multiplicity type = %s\n", multType);
238 printf(
"** Event Plane %3.2f [deg]\n**\n", fPsi*180/3.14);
239 printf(
"** Registered Particle Types:\n**\n");
242 for (Int_t i=0; i<fPartTypes->GetEntries(); i++)
246 printf(
"**\n*******************************************************\n\n");
252 void TGeVSim::InitFormula()
267 const char* ptNames[2] = {
"gevsimPt1",
"gevsimPt2"};
269 const char* ptForm[2] = {
270 " x * exp( -sqrt([0]*[0] + x*x) / [1] )",
271 " x * ( 1+ (sqrt([0]*[0]+x*x)*[2])/[1] )^(-1./[2]) "
274 for(Int_t i=0; i<2; i++) {
275 fPtFormula[i] =
new TF1(ptNames[i], ptForm[i], 0, 4);
276 fPtFormula[i]->SetNpx(100);
279 fPtFormula[0]->SetParNames(
"mass",
"temperature");
280 fPtFormula[0]->SetParameters(1., 1.);
282 fPtFormula[1]->SetParNames(
"mass",
"temperature",
"sigmaTemp");
283 fPtFormula[1]->SetParameters(1., 1., 1.);
292 const char *formE =
" ( sqrt([0]*[0] + x*x) * cosh(y) ) ";
293 const char *formG =
" ( 1 / sqrt( 1 - [2]*[2] ) ) ";
294 const char *formYp =
"( [2]*sqrt(([0]*[0]+x*x)*cosh(y)*cosh(y)-[0]*[0])/([1]*sqrt(1-[2]*[2]))) ";
296 const char* formula[3] = {
297 " x * %s * exp( -%s / [1]) ",
298 " (x * %s) / ( exp( %s / [1]) - 1 ) ",
299 " x*%s*exp(-%s*%s/[1])*((sinh(%s)/%s)+([1]/(%s*%s))*(sinh(%s)/%s-cosh(%s)))"
302 const char* paramNames[3] = {
"mass",
"temperature",
"expVel"};
306 sprintf(buffer, formula[0], formE, formE);
307 fPtYFormula[0] =
new TF2(
"gevsimPtY_2", buffer, 0, 3, -2, 2);
309 sprintf(buffer, formula[1], formE, formE);
310 fPtYFormula[1] =
new TF2(
"gevsimPtY_3", buffer, 0, 3, -2, 2);
312 sprintf(buffer, formula[2], formE, formG, formE, formYp, formYp, formG, formE, formYp, formYp, formYp);
313 fPtYFormula[2] =
new TF2(
"gevsimPtY_4", buffer, 0, 3, -2, 2);
321 for (i=0; i<3; i++) {
323 fPtYFormula[i]->SetNpx(100);
324 fPtYFormula[i]->SetNpy(100);
326 for (j=0; j<3; j++) {
328 if ( i != 2 && j == 2 )
continue;
329 fPtYFormula[i]->SetParName(j, paramNames[j]);
330 fPtYFormula[i]->SetParameter(j, 0.5);
339 const char* phiForm =
" 1 + 2*[1]*cos(x-[0]) + 2*[2]*cos(2*(x-[0])) ";
340 fPhiFormula =
new TF1(
"gevsimPhi", phiForm, 0, 2*TMath::Pi());
342 fPhiFormula->SetParNames(
"psi",
"directed",
"elliptic");
343 fPhiFormula->SetParameters(0., 0., 0.);
345 fPhiFormula->SetNpx(180);
360 if (!fPartTypes) fPartTypes =
new TObjArray();
361 fPartTypes->Add(part);
366 void TGeVSim::SetMultTotal(Bool_t isTotal)
376 fIsMultTotal = isTotal;
381 Float_t TGeVSim::FindScaler(Int_t paramId, Int_t pdg)
410 static const char*
params[] = {
"Temp",
"SigmaY",
"ExpVel",
"SigmaTemp",
"V1",
"V2",
"Mult"};
411 static const char* ending[] = {
"",
"Rndm"};
413 static const char* patt1 =
"gevsim%s%s";
414 static const char* patt2 =
"gevsim%d%s%s";
425 for (i=0; i<2; i++) {
426 for (j=0; j<2; j++) {
430 if (i == 0) sprintf(buffer, patt1, params[paramId], ending[j]);
431 else sprintf(buffer, patt2, pdg, params[paramId], ending[j]);
433 form = (TF1 *)gROOT->GetFunction(buffer);
436 if (j == 0) scaler *= form->Eval(fEventNumber);
438 form->SetParameter(0, fEventNumber);
439 scaler *= form->GetRandom();
450 void TGeVSim::DetermineReactionPlane()
469 form = (TF1 *)gROOT->GetFunction(
"gevsimPsi");
470 if (form) fPsi = form->Eval(fEventNumber) * TMath::Pi() / 180;
473 form = (TF1 *)gROOT->GetFunction(
"gevsimPsiRndm");
474 if (form) fPsi = form->GetRandom() * TMath::Pi() / 180;
478 fPhiFormula->SetParameter(0, fPsi);
483 Float_t TGeVSim::GetdNdYToTotal()
493 const Double_t maxPt = 3.0, maxY = 2.;
500 return TMath::Sqrt(2*TMath::Pi()) * fSigmaY;
507 integ = fCurrentForm2D->Integral(0,maxPt, -maxY, maxY);
508 mag = fCurrentForm2D->Integral(0, maxPt, -0.1, 0.1) / 0.2;
513 integ = fHist[1]->Integral();
514 mag = fHist[1]->GetBinContent(fHist[0]->FindBin(0.));
515 mag /= fHist[1]->GetBinWidth(fHist[0]->FindBin(0.));
520 Int_t yBins = fPtYHist->GetNbinsY();
521 Int_t
ptBins = fPtYHist->GetNbinsX();
523 integ = fPtYHist->Integral(0, ptBins, 0, yBins);
524 mag = fPtYHist->Integral(0, ptBins, (yBins/2)-1, (yBins/2)+1 ) / 2;
533 void TGeVSim::SetFormula(Int_t pdg)
546 const char* msg[4] = {
547 "Custom Formula for Pt Y distribution not found [pdg = %d]",
548 "Histogram for Pt distribution not found [pdg = %d]",
549 "Histogram for Y distribution not found [pdg = %d]",
550 "HIstogram for Pt Y dostribution not found [pdg = %d]"
553 const char* pattern[8] = {
554 "gevsimDistPtY",
"gevsimDist%dPtY",
555 "gevsimHistPt",
"gevsimHist%dPt",
556 "gevsimHistY",
"gevsimHist%dY",
557 "gevsimHistPtY",
"gevsimHist%dPtY"
560 const char *where =
"SetFormula";
562 fCurrentForm1D = fCurrentForm2D = 0;
570 fCurrentForm1D = fPtFormula[fModel-1];
577 fCurrentForm2D = fPtYFormula[fModel-3];
582 sprintf(buff, pattern[1], pdg);
583 fCurrentForm2D = (TF2*)gROOT->GetFunction(buff);
586 fCurrentForm2D = (TF2*)gROOT->GetFunction(pattern[0]);
588 if (!fCurrentForm2D)
Error(where, msg[0], pdg);
593 for (Int_t i=0; i<2; i++) {
596 sprintf(buff, pattern[3+2*i], pdg);
597 fHist[i] = (TH1D*)gROOT->FindObject(buff);
600 fHist[i] = (TH1D*)gROOT->FindObject(pattern[2+2*i]);
602 if (!fHist[i])
Error(where, msg[1+i], pdg);
609 sprintf(buff, pattern[7], pdg);
610 fPtYHist = (TH2D*)gROOT->FindObject(buff);
613 fPtYHist = (TH2D*)gROOT->FindObject(pattern[6]);
615 if (!fPtYHist)
Error(where, msg[4], pdg);
622 void TGeVSim:: AdjustFormula()
635 const Double_t kCutMaxPt = 5.0;
636 const Double_t kCutMaxY = 6.0;
637 Double_t minPt, maxPt, minY, maxY;
640 const Int_t NPART = 20;
641 const Float_t dX = 1./NPART;
642 const Int_t NBINS = 30;
644 if (fModel > kExpansion)
return;
647 if (TestBit(kPtRange) && fPtCutMax < kCutMaxPt ) maxPt = fPtCutMax;
648 else maxPt = kCutMaxPt;
651 if (TestBit(kPtRange)) minPt = fPtCutMin;
655 if (TestBit(kPRange) && maxPt > fPCutMax) maxPt = fPCutMax;
658 if (TestBit(kYRange)) {
669 if (fModel < kPratt) {
671 Float_t maxValue = 0, value;
673 fCurrentForm1D->SetRange(minPt, maxPt);
677 for(Int_t part=NPART; part>1; part--) {
678 Float_t x = dX * (maxPt-minPt) * part + minPt;
679 value = fCurrentForm1D->Eval(x);
680 maxValue = (value>maxValue)? value : maxValue;
684 for(Int_t part=NPART; part>1; part--) {
685 Float_t x = dX * (maxPt-minPt) * part + minPt;
686 value = fCurrentForm1D->Eval(x);
687 if (value> 0.001*maxValue) {
693 fCurrentForm1D->SetRange(minPt, maxPt);
694 fCurrentForm1D->SetNpx((
int)((maxPt-minPt)*NBINS));
699 if (fModel > kLevy) {
701 fCurrentForm2D->SetRange(minPt, minY, maxPt, maxY);
703 Float_t maxValue = 0, midPt = 0.1, value;
706 for(Int_t part=NPART; part>1; part--) {
707 Float_t x = dX * (maxPt-minPt) * part + minPt;
708 value = fCurrentForm2D->Eval(x, 0);
709 if (value>maxValue) {
715 for(Int_t part=NPART; part>1; part--) {
716 Float_t x = dX * maxPt * part;
717 value = fCurrentForm2D->Eval(x, 0);
718 if (value > 0.01 * maxValue) {
726 for (Int_t part=NPART; part>1; part--) {
727 Float_t y = -dX * minY * part;
728 value = fCurrentForm2D->Eval(midPt, y);
729 if (value > 0.005 * maxValue) {
735 for (Int_t part=NPART; part>1; part--) {
736 Float_t y = dX * maxY * part;
737 value = fCurrentForm2D->Eval(midPt, y);
738 if (value > 0.005 * maxValue) {
744 fCurrentForm2D->SetRange(minPt, minY, maxPt, maxY);
745 fCurrentForm2D->SetNpx((
int)((maxPt-minPt)*NBINS));
746 fCurrentForm2D->SetNpy((
int)((maxY-minY)*NBINS));
751 if (TestBit(kPhiRange)) {
752 fPhiFormula->SetRange(fPhiCutMin, fPhiCutMax);
753 fPhiFormula->SetNpx((
int)((fPhiCutMax-fPhiCutMin)*2*NBINS));
759 void TGeVSim::GetRandomPtY(Double_t &pt, Double_t &y)
773 pt = fCurrentForm1D->GetRandom();
774 y = gRandom->Gaus(0, fSigmaY);
782 fCurrentForm2D->GetRandom2(pt, y);
787 pt = fHist[0]->GetRandom();
788 y = fHist[1]->GetRandom();
793 fPtYHist->GetRandom2(pt, y);
804 void TGeVSim::GenerateEvent()
815 fPartBuffer->Clear();
821 Int_t TGeVSim::ImportParticles(TClonesArray *particles, Option_t *option)
831 fPartBuffer = particles;
832 fPartBuffer->Clear();
840 TObjArray* TGeVSim::ImportParticles(Option_t *option)
852 if (fPartBuffer) fPartBuffer = 0;
862 void TGeVSim::Generate(Bool_t clones)
878 Float_t multiplicity = 0;
879 Bool_t isMultTotal = kTRUE;
881 Int_t nPartTotal = 0;
884 Float_t directedScaller = 1., ellipticScaller = 1.;
886 TLorentzVector *v =
new TLorentzVector(0,0,0,0);
887 TLorentzVector *orgin =
new TLorentzVector(0,0,0,fEventNumber);
891 TDatabasePDG *db = TDatabasePDG::Instance();
896 Int_t nType, nParticle, nParam;
899 DetermineReactionPlane();
904 Warning(
"Generate",
"No event initialized");
909 fEvent->SetEventNumber(fEventNumber);
910 fEvent->SetPsi(fPsi);
916 if (fIsVerbose) Info(
"Generate",
"Generating Event = %d \t Event Plane = %3.2f deg", fEventNumber, fPsi*180/3.14);
920 for (nType = 0; nType < fPartTypes->GetEntries(); nType++) {
922 points[npoint++] = times(0);
926 pdg = partType->GetPdgCode();
927 type = db->GetParticle(pdg);
930 fModel = partType->GetModel();
937 evpars->Model = fModel;
940 if (fCurrentForm1D) fCurrentForm1D->SetParameter(
"mass", mass);
941 if (fCurrentForm2D) fCurrentForm2D->SetParameter(
"mass", mass);
945 for (nParam = kTemp; nParam <= kMult; nParam++) {
949 paramScaler = FindScaler(nParam, pdg);
954 tmp = paramScaler * partType->GetTemperature();
955 if (fCurrentForm1D) fCurrentForm1D->SetParameter(
"temperature", tmp);
956 if (fCurrentForm2D) fCurrentForm2D->SetParameter(
"temperature", tmp);
961 fSigmaY = paramScaler * partType->GetSigmaY();
962 evpars->SigmaY = fSigmaY;
966 if (fModel == kExpansion) {
967 tmp = paramScaler * partType->GetExpansionVelocity();
968 if (tmp == 0.0) tmp = 0.0001;
969 if (tmp == 1.0) tmp = 0.9999;
970 fCurrentForm2D->SetParameter(
"expVel", tmp);
971 evpars->ExpVel = tmp;
976 if (fModel == kLevy) {
977 tmp =paramScaler*partType->GetSigmaTemp();
978 fCurrentForm1D->SetParameter(
"sigmaTemp", tmp);
979 evpars->SigmaTemp = tmp;
984 directedScaller = paramScaler;
985 evpars->V1Scalar = paramScaler;
989 ellipticScaller = paramScaler;
990 evpars->V2Scalar = paramScaler;
994 multiplicity = paramScaler * partType->GetMultiplicity();
1000 if (partType->IsFlowSimple()) {
1001 fPhiFormula->SetParameter(1, partType->GetDirectedFlow(0,0) * directedScaller);
1002 fPhiFormula->SetParameter(2, partType->GetEllipticFlow(0,0) * ellipticScaller);
1007 if (partType->IsMultForced()) isMultTotal = partType->IsMultTotal();
1008 else isMultTotal = fIsMultTotal;
1010 multiplicity *= (isMultTotal)? 1 : GetdNdYToTotal();
1011 evpars->Mult = (Int_t)multiplicity+1;
1015 printf(
"Generating PDG = %5d Mult = %d\n", pdg, (Int_t)multiplicity+1 );
1025 fEvent->evParams->Add(foo);
1030 points[npoint++] = times(0);
1033 while (nParticle < multiplicity) {
1035 Double_t pt, y, phi;
1036 Float_t p[3] = {0,0,0};
1038 GetRandomPtY(pt, y);
1043 if (!partType->IsFlowSimple()) {
1044 fPhiFormula->SetParameter(1, partType->GetDirectedFlow(pt,y) * directedScaller);
1045 fPhiFormula->SetParameter(2, partType->GetEllipticFlow(pt,y) * ellipticScaller);
1048 phi = fPhiFormula->GetRandom();
1050 if (!isMultTotal) nParticle++;
1051 if (!CheckPtYPhi(pt,y,phi))
continue;
1054 p[0] = pt * TMath::Cos(phi);
1055 p[1] = pt * TMath::Sin(phi);
1056 p[2] = TMath::Sqrt(mass*mass + pt*pt) * TMath::SinH(y);
1059 if ( !CheckPXYZ(p) )
continue;
1062 energy = TMath::Sqrt(mass*mass + p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
1063 v->SetPxPyPzE(p[0], p[1], p[2], energy);
1066 new ((*fEvent->evParts)[nPartTotal]) TParticle(pdg, 0, -1, -1, -1, -1, *v, *orgin);
1067 new ((*fPartBuffer)[nPartTotal++]) TParticle(pdg, 0, -1, -1, -1, -1, *v, *orgin);
1070 fParticles->Add(
new TParticle(pdg, 0, -1, -1, -1, -1, *v, *orgin));
1072 if (isMultTotal) nParticle++;
1075 points[npoint++] = times(0);