Skip to content

Commit bc0582c

Browse files
authored
Adding GeneratorSpectator: generator for spectator protons (#8)
1 parent d5652e1 commit bc0582c

File tree

5 files changed

+424
-0
lines changed

5 files changed

+424
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ add_subdirectory(GeneratorParam)
1212

1313
add_subdirectory(GeneratorSlowNucleons)
1414

15+
add_subdirectory(GeneratorSpectators)
16+
1517
if (DEFINED ENV{HIJING_ROOT})
1618
add_subdirectory(THijing)
1719
endif (DEFINED ENV{HIJING_ROOT})

GeneratorSpectators/CMakeLists.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
2+
project(GeneratorSpectators)
3+
4+
# You need to tell CMake where to find the ROOT installation. This can be done in a number of ways:
5+
# - ROOT built with classic configure/make use the provided $ROOTSYS/etc/cmake/FindROOT.cmake
6+
# - ROOT built with CMake. Add in CMAKE_PREFIX_PATH the installation prefix for ROOT
7+
list(APPEND CMAKE_PREFIX_PATH $ENV{ROOTSYS})
8+
9+
#---Locate the ROOT package and defines a number of variables (e.g. ROOT_INCLUDE_DIRS)
10+
find_package(ROOT REQUIRED COMPONENTS EG)
11+
12+
#---Define useful ROOT functions and macros (e.g. ROOT_GENERATE_DICTIONARY)
13+
include(${ROOT_USE_FILE})
14+
15+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.)
16+
17+
set(HEADERS GeneratorSpectators.h)
18+
19+
ROOT_GENERATE_DICTIONARY(G__GeneratorSpectators ${HEADERS} LINKDEF GeneratorSpectatorsLinkDef.h)
20+
21+
#---Create a shared library with generated dictionary
22+
add_library(GeneratorSpectators SHARED GeneratorSpectators.cxx G__GeneratorSpectators.cxx)
23+
target_link_libraries(GeneratorSpectators ${ROOT_LIBRARIES})
24+
25+
26+
set_target_properties(GeneratorSpectators
27+
PROPERTIES
28+
PUBLIC_HEADER "${HEADERS}" )
29+
30+
31+
install(TARGETS GeneratorSpectators
32+
LIBRARY DESTINATION lib
33+
PUBLIC_HEADER DESTINATION include)
34+
35+
if (${ROOT_VERSION} VERSION_GREATER "6.0")
36+
install(
37+
FILES
38+
${CMAKE_CURRENT_BINARY_DIR}/libGeneratorSpectators_rdict.pcm
39+
${CMAKE_CURRENT_BINARY_DIR}/libGeneratorSpectators.rootmap
40+
DESTINATION lib)
41+
endif (${ROOT_VERSION} VERSION_GREATER "6.0")
42+
43+
if(${CMAKE_SYSTEM} MATCHES Darwin)
44+
set_target_properties(GeneratorSpectators PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
45+
endif(${CMAKE_SYSTEM} MATCHES Darwin)
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
// Class to generate spectators for ZDC simulations
12+
13+
#include <TCanvas.h>
14+
#include <TClonesArray.h>
15+
#include <TDatabasePDG.h>
16+
#include <TLorentzVector.h>
17+
#include <TMath.h>
18+
#include <TPDGCode.h>
19+
#include <TParticle.h>
20+
#include <TParticlePDG.h>
21+
#include <TRandom.h>
22+
#include <assert.h>
23+
24+
#include "GeneratorSpectators.h"
25+
26+
ClassImp(GeneratorSpectators)
27+
28+
//_____________________________________________________________________________
29+
GeneratorSpectators::GeneratorSpectators()
30+
:TGenerator("GeneratorSpectators", "GeneratorSpectators"), fDebug(0),
31+
fPDGcode(0), fPmax(0), fPseudoRapidity(0), fCosx(0), fCosy(0), fCosz(0),
32+
fFermiflag(1),fBeamDiv(0), fBeamCrossAngle(0), fBeamCrossPlane(0) {
33+
//
34+
// Default constructor
35+
}
36+
37+
//_____________________________________________________________________________
38+
GeneratorSpectators::GeneratorSpectators(Int_t npart)
39+
:TGenerator("GeneratorSpectators", "GeneratorSpectators"){
40+
//
41+
// Standard constructor
42+
//
43+
fName = "GeneratorSpectators";
44+
fTitle = "Generation of Test Particles for ZDCs";
45+
fDebug = 0;
46+
SetParticle();
47+
SetMomentum();
48+
SetDirection();
49+
SetFermi();
50+
SetDivergence();
51+
SetCrossing();
52+
53+
for(Int_t i=0; i<201; i++){
54+
fProbintp[i] = 0;
55+
fProbintn[i] = 0;
56+
fPp[i] = 0;
57+
}
58+
}
59+
60+
//_____________________________________________________________________________
61+
void GeneratorSpectators::Init()
62+
{
63+
//Initialize Fermi momentum distributions for Pb-Pb
64+
//
65+
printf("\n **** GeneratorSpectators initialization:\n");
66+
printf(" ParticlePDG: %d, Track: cosx = %f cosy = %f cosz = %f \n", fPDGcode, fCosx, fCosy, fCosz);
67+
printf(" Fermi flag: %d, Beam divergence: %f, Crossing angle: %f, plane: %d\n\n",
68+
fFermiflag, fBeamDiv, fBeamCrossAngle, fBeamCrossPlane);
69+
70+
FermiTwoGaussian(208.);
71+
}
72+
73+
//_____________________________________________________________________________
74+
void GeneratorSpectators::GenerateEvent()
75+
{
76+
//
77+
// Generate one trigger particle (n or p)
78+
//
79+
//printf("GeneratorSpectators::GenerateEvent()\n");
80+
fParticles->Clear();
81+
82+
Double_t pLab[3] = {0.,0.,0.};
83+
Double_t fP[3] = {0.,0.,0.}, fBoostP[3] = {0.,0.,0.};
84+
Double_t ptot = fPmax;
85+
if(fPseudoRapidity==0.){
86+
pLab[0] = ptot*fCosx;
87+
pLab[1] = ptot*fCosy;
88+
pLab[2] = ptot*fCosz;
89+
}
90+
else{
91+
Float_t scang = 2*TMath::ATan(TMath::Exp(-(fPseudoRapidity)));
92+
pLab[0] = -ptot*TMath::Sin(scang);
93+
pLab[1] = 0.;
94+
pLab[2] = ptot*TMath::Cos(scang);
95+
}
96+
for(int i=0; i<3; i++) fP[i] = pLab[i];
97+
if(fDebug==1) printf("\n Particle momentum before divergence and crossing: ");
98+
if(fDebug==1) printf(" pLab = (%f, %f, %f)\n", pLab[0], pLab[1], pLab[2]);
99+
100+
// Beam divergence and crossing angle
101+
if(TMath::Abs(fBeamCrossAngle)>0.) {
102+
BeamCrossing(pLab);
103+
for(int i=0; i<3; i++) fP[i] = pLab[i];
104+
}
105+
if(TMath::Abs(fBeamDiv)>0.) {
106+
BeamDivergence(pLab);
107+
for(int i=0; i<3; i++) fP[i] = pLab[i];
108+
}
109+
110+
Double_t mass = TDatabasePDG::Instance()->GetParticle(fPDGcode)->Mass();
111+
Double_t ddp[3] = {0.,0.,0.}, dddp[3] = {0.,0.,0.};
112+
Double_t fP0 = 0., dddp0 = 0.;
113+
// If required apply the Fermi momentum
114+
if(fFermiflag==1){
115+
if((fPDGcode==kProton) || (fPDGcode==kNeutron)) ExtractFermi(fPDGcode, ddp);
116+
fP0 = TMath::Sqrt(fP[0]*fP[0] + fP[1]*fP[1] + fP[2]*fP[2] + mass*mass);
117+
for(int i=0; i<3; i++) dddp[i] = ddp[i];
118+
dddp0 = TMath::Sqrt(dddp[0]*dddp[0] + dddp[1]*dddp[1] + dddp[2]*dddp[2] + mass*mass);
119+
120+
TVector3 b(fP[0]/fP0, fP[1]/fP0, fP[2]/fP0);
121+
TLorentzVector pFermi(dddp[0], dddp[1], dddp[2], dddp0);
122+
123+
pFermi.Boost(b);
124+
for(int i=0; i<3; i++){
125+
fBoostP[i] = pFermi[i];
126+
fP[i] = pFermi[i];
127+
}
128+
129+
}
130+
if(fDebug==1) printf(" ### Particle momentum = (%f, %f, %f)\n", fP[0], fP[1], fP[2]);
131+
132+
Double_t energy = TMath::Sqrt(fP[0]*fP[0]+fP[1]*fP[1]+fP[2]*fP[2]+mass*mass);
133+
134+
auto part = new TParticle(fPDGcode, 1, -1, -1, -1, -1, fP[0], fP[1], fP[2], energy,
135+
0., 0., 0., 0.);
136+
fParticles->Add(part);
137+
}
138+
139+
// -----------------------------------------------------------------------
140+
int GeneratorSpectators::ImportParticles(TClonesArray *particles, Option_t *option) {
141+
if (particles == 0) return 0;
142+
TClonesArray &clonesParticles = *particles;
143+
clonesParticles.Clear();
144+
Int_t numpart = fParticles->GetEntries();
145+
for (int i = 0; i < numpart; i++) {
146+
TParticle *particle = (TParticle *)fParticles->At(i);
147+
new (clonesParticles[i]) TParticle(*particle);
148+
}
149+
return numpart;
150+
}
151+
152+
//_____________________________________________________________________________
153+
void GeneratorSpectators::FermiTwoGaussian(Float_t A)
154+
{
155+
//
156+
// Momenta distributions according to the "double-gaussian"
157+
// distribution (Ilinov) - equal for protons and neutrons
158+
//
159+
Double_t sig1 = 0.113;
160+
Double_t sig2 = 0.250;
161+
Double_t alfa = 0.18*(TMath::Power((A/12.), (Float_t)1/3));
162+
Double_t xk = (2*TMath::TwoPi())/((1.+alfa)*(TMath::Power(TMath::TwoPi(),1.5)));
163+
164+
for(Int_t i=1; i<201; i++){
165+
Double_t p = i*0.005;
166+
fPp[i] = p;
167+
Double_t e1 = (p*p)/(2.*sig1*sig1);
168+
Double_t e2 = (p*p)/(2.*sig2*sig2);
169+
Double_t f1 = TMath::Exp(-(e1));
170+
Double_t f2 = TMath::Exp(-(e2));
171+
Double_t probp = xk*p*p*(f1/(TMath::Power(sig1,3.))+
172+
alfa*f2/(TMath::Power(sig2,3.)))*0.005;
173+
fProbintp[i] = fProbintp[i-1] + probp;
174+
fProbintn[i] = fProbintp[i];
175+
}
176+
if(fDebug==1) printf(" Initialization of Fermi momenta distribution \n");
177+
}
178+
//_____________________________________________________________________________
179+
void GeneratorSpectators::ExtractFermi(Int_t id, Double_t *ddp)
180+
{
181+
//
182+
// Compute Fermi momentum for spectator nucleons
183+
//
184+
Int_t index=0;
185+
Float_t xx = gRandom->Rndm();
186+
assert ( id==kProton || id==kNeutron );
187+
if(id==kProton){
188+
for(Int_t i=1; i<201; i++){
189+
if((xx>=fProbintp[i-1]) && (xx<fProbintp[i])) break;
190+
index = i;
191+
}
192+
}
193+
else {
194+
for(Int_t i=1; i<201; i++){
195+
if((xx>=fProbintn[i-1]) && (xx<fProbintn[i])) break;
196+
index = i;
197+
}
198+
}
199+
Float_t pext = fPp[index]+0.001;
200+
Float_t phi = TMath::TwoPi()*(gRandom->Rndm());
201+
Float_t cost = (1.-2.*(gRandom->Rndm()));
202+
Float_t tet = TMath::ACos(cost);
203+
ddp[0] = pext*TMath::Sin(tet)*TMath::Cos(phi);
204+
ddp[1] = pext*TMath::Sin(tet)*TMath::Sin(phi);
205+
ddp[2] = pext*cost;
206+
207+
if(fDebug==1) printf(" Fermi momentum: p = (%f, %f, %f )\n\n",ddp[0],ddp[1],ddp[2]);
208+
}
209+
//_____________________________________________________________________________
210+
void GeneratorSpectators::BeamCrossing(Double_t *pLab)
211+
{
212+
// Applying beam crossing angle
213+
//
214+
pLab[1] = pLab[2]*TMath::Sin(fBeamCrossAngle)+pLab[1]*TMath::Cos(fBeamCrossAngle);
215+
pLab[2] = pLab[2]*TMath::Cos(fBeamCrossAngle)-pLab[1]*TMath::Sin(fBeamCrossAngle);
216+
//
217+
if(fDebug==1) printf(" Beam crossing angle = %f mrad -> ", fBeamCrossAngle*1000.);
218+
if(fDebug==1) printf(" p = (%f, %f, %f)\n",pLab[0],pLab[1],pLab[2]);
219+
220+
}
221+
//_____________________________________________________________________________
222+
void GeneratorSpectators::BeamDivergence(Double_t *pLab)
223+
{
224+
// Applying beam divergence and crossing angle
225+
//
226+
Double_t pmq = 0.;
227+
for(int i=0; i<3; i++) pmq = pmq+pLab[i]*pLab[i];
228+
Double_t pmod = TMath::Sqrt(pmq);
229+
230+
Double_t rvec = gRandom->Gaus(0.0,1.0);
231+
Double_t tetdiv = fBeamDiv * TMath::Abs(rvec);
232+
Double_t fidiv = (gRandom->Rndm())*TMath::TwoPi();
233+
234+
Double_t tetpart = TMath::ATan2(TMath::Sqrt(pLab[0]*pLab[0]+pLab[1]*pLab[1]),pLab[2]);
235+
Double_t fipart = 0.;
236+
if(pLab[1]!=0. || pLab[0]!=0.) fipart = TMath::ATan2(pLab[1],pLab[0]);
237+
else fipart = 0.;
238+
if(fipart<0.) {fipart = fipart+TMath::TwoPi();}
239+
tetdiv = tetdiv*TMath::RadToDeg();
240+
fidiv = fidiv*TMath::RadToDeg();
241+
tetpart = tetpart*TMath::RadToDeg();
242+
fipart = fipart*TMath::RadToDeg();
243+
Double_t angleSum[2] = {0., 0.};
244+
AddAngle(tetpart,fipart,tetdiv,fidiv,angleSum);
245+
Double_t tetsum = angleSum[0];
246+
Double_t fisum = angleSum[1];
247+
tetsum = tetsum*TMath::DegToRad();
248+
fisum = fisum*TMath::DegToRad();
249+
pLab[0] = pmod*TMath::Sin(tetsum)*TMath::Cos(fisum);
250+
pLab[1] = pmod*TMath::Sin(tetsum)*TMath::Sin(fisum);
251+
pLab[2] = pmod*TMath::Cos(tetsum);
252+
//
253+
if(fDebug==1) printf(" Beam divergence = %f mrad -> ", fBeamDiv*1000.);
254+
if(fDebug==1) printf(" p = (%f, %f, %f)\n",pLab[0],pLab[1],pLab[2]);
255+
}
256+
257+
//_____________________________________________________________________________
258+
void GeneratorSpectators::AddAngle(Double_t theta1, Double_t phi1, Double_t theta2,
259+
Double_t phi2, Double_t *angleSum)
260+
{
261+
// Calculating the sum of 2 angles
262+
Double_t temp = -1.;
263+
Double_t conv = 180./TMath::ACos(temp);
264+
Double_t ct1 = TMath::Cos(theta1/conv);
265+
Double_t st1 = TMath::Sin(theta1/conv);
266+
Double_t cp1 = TMath::Cos(phi1/conv);
267+
Double_t sp1 = TMath::Sin(phi1/conv);
268+
Double_t ct2 = TMath::Cos(theta2/conv);
269+
Double_t st2 = TMath::Sin(theta2/conv);
270+
Double_t cp2 = TMath::Cos(phi2/conv);
271+
Double_t sp2 = TMath::Sin(phi2/conv);
272+
Double_t cx = ct1*cp1*st2*cp2+st1*cp1*ct2-sp1*st2*sp2;
273+
Double_t cy = ct1*sp1*st2*cp2+st1*sp1*ct2+cp1*st2*sp2;
274+
Double_t cz = ct1*ct2-st1*st2*cp2;
275+
276+
Double_t rtetsum = TMath::ACos(cz);
277+
Double_t tetsum = conv*rtetsum;
278+
Double_t fisum = 0;
279+
if (tetsum == 0. || tetsum == 180.)
280+
{
281+
fisum = 0.;
282+
return;
283+
}
284+
temp = cx/TMath::Sin(rtetsum);
285+
if(temp>1.) temp=1.;
286+
else if (temp < -1.) temp = -1.;
287+
fisum = conv*TMath::ACos(temp);
288+
if(cy<0) {fisum = 360.-fisum;}
289+
angleSum[0] = tetsum;
290+
angleSum[1] = fisum;
291+
}

0 commit comments

Comments
 (0)