1+ // Parameterized generator for muons
2+ // Adaptation of the Run 2 generator by P. Pillot:
3+ // https://github.com/alisw/AliDPG/blob/master/MC/CustomGenerators/PWGDQ/Muon_GenParamSingle_PbPb5TeV_1.C
4+
5+ #include "FairGenerator.h"
6+ #include "TF1.h"
7+ #include "TRandom.h"
8+ #include "TDatabasePDG.h"
9+ #include "TParticlePDG.h"
10+
11+ class O2_GeneratorParamMuon : public FairGenerator
12+ {
13+ public :
14+ O2_GeneratorParamMuon (int npart = 2 , int pdg = 13 , double ymin = -4.3 , double ymax = -2.3 , double ptmin = 0.1 , double ptmax = 999. )
15+ : FairGenerator ("ParaMuon" ), fNParticles (npart ), fPDGCode (pdg ), fYMin (ymin ), fYMax (ymax ), fPtMin (ptmin ), fPtMax (ptmax )
16+ {
17+ TParticlePDG * particle = TDatabasePDG ::Instance ()-> GetParticle (fPDGCode );
18+ fMass = particle -> Mass ();
19+ fMass2 = fMass * fMass ;
20+ }
21+
22+ ~O2_GeneratorParamMuon () = default ;
23+
24+ void SetRandomCharge (bool flag ) { fRandomizeCharge = flag ; }
25+
26+ void SetPtPars (double p0 , double p1 , double p2 , double p3 , double p4 , double p5 )
27+ {
28+ fPtP0 = p0 ;
29+ fPtP1 = p1 ;
30+ fPtP2 = p2 ;
31+ fPtP3 = p3 ;
32+ fPtP4 = p4 ;
33+ fPtP5 = p5 ;
34+ }
35+
36+ void SetYPars (double p0 , double p1 , double p2 , double p3 , double p4 )
37+ {
38+ fYP0 = p0 ;
39+ fYP1 = p1 ;
40+ fYP2 = p2 ;
41+ fYP3 = p3 ;
42+ fYP4 = p4 ;
43+ }
44+
45+ void InitParaFuncs ()
46+ {
47+ fPtPara = new TF1 ("pt-para" , PtMuon , fPtMin , fPtMax , 6 );
48+ fPtPara -> SetParameter (0 , fPtP0 );
49+ fPtPara -> SetParameter (1 , fPtP1 );
50+ fPtPara -> SetParameter (2 , fPtP2 );
51+ fPtPara -> SetParameter (3 , fPtP3 );
52+ fPtPara -> SetParameter (4 , fPtP4 );
53+ fPtPara -> SetParameter (5 , fPtP5 );
54+ fYPara = new TF1 ("y-para" , YMuon , fYMin , fYMax , 5 );
55+ fYPara -> SetParameter (0 , fYP0 );
56+ fYPara -> SetParameter (1 , fYP1 );
57+ fYPara -> SetParameter (2 , fYP2 );
58+ fYPara -> SetParameter (3 , fYP3 );
59+ fYPara -> SetParameter (4 , fYP4 );
60+ }
61+
62+ static double PtMuon (const double * xx , const double * par )
63+ {
64+ double x = xx [0 ];
65+ double p0 = par [0 ];
66+ double p1 = par [1 ];
67+ double p2 = par [2 ];
68+ double p3 = par [3 ];
69+ double p4 = par [4 ];
70+ double p5 = par [5 ];
71+ return p0 * (1. / std ::pow (p1 + std ::pow (x , p2 ), p3 ) + p4 * std ::exp (p5 * x ));
72+ }
73+
74+ static double YMuon (const double * xx , const double * par )
75+ {
76+ double x = xx [0 ];
77+ double p0 = par [0 ];
78+ double p1 = par [1 ];
79+ double p2 = par [2 ];
80+ double p3 = par [3 ];
81+ double p4 = par [4 ];
82+ double x2 = x * x ;
83+ return p0 * (1. + p1 * x + p2 * x2 + p3 * x2 * x + p4 * x2 * x2 );
84+ }
85+
86+ bool ReadEvent (FairPrimaryGenerator * primGen ) override
87+ {
88+ // no kinematic cuts -> accepting all
89+ for (int i = 0 ; i < fNParticles ; ++ i ) {
90+ double pt = fPtPara -> GetRandom ();
91+ double ty = std ::tanh (fYPara -> GetRandom ());
92+ double xmt = std ::sqrt (pt * pt + fMass2 );
93+ double pl = xmt * ty / std ::sqrt ((1. - ty * ty ));
94+ double phi = gRandom -> Uniform (0. , 2. * M_PI );
95+ double px = pt * std ::cos (phi );
96+ double py = pt * std ::sin (phi );
97+ int pdg = fPDGCode ;
98+ if (fRandomizeCharge ) {
99+ int charge ;
100+ if (gRandom -> Rndm () < 0.5 ) {
101+ charge = 1 ;
102+ } else {
103+ charge = -1 ;
104+ }
105+ pdg = std ::abs (pdg ) * charge ;
106+ }
107+ primGen -> AddTrack (pdg , px , py , pl , 0 , 0 , 0 );
108+ printf ("Add track %d %.2f %.2f %.2f \n" , pdg , px , py , pl );
109+ }
110+ return kTRUE ;
111+ }
112+
113+ private :
114+ TF1 * fPtPara {nullptr};
115+ TF1 * fYPara {nullptr };
116+ TF1 * fdNdPhi {nullptr };
117+
118+ // parameters tuned to Pb-Pb @ 5.02 TeV
119+ double fPtP0 {797.446 };
120+ double fPtP1 {0.830278 };
121+ double fPtP2 {0.632177 };
122+ double fPtP3 {10.2202 };
123+ double fPtP4 {-0.000614809 };
124+ double fPtP5 {-1.70993 };
125+
126+ double fYP0 {1.87732 };
127+ double fYP1 {0.00658212 };
128+ double fYP2 {-0.0988071 };
129+ double fYP3 {-0.000452746 };
130+ double fYP4 {0.00269782 };
131+
132+ // configuration
133+ int fPDGCode {13 };
134+ int fNParticles {2 };
135+ double fYMin {-4.3 };
136+ double fYMax {-2.3 };
137+ double fPtMin {0.1 };
138+ double fPtMax {999. };
139+ bool fRandomizeCharge {true};
140+ double fMass {0.10566 };
141+ double fMass2 {0 };
142+ };
143+
144+ FairGenerator * paramMuGen (double ptP0 = 797.446 , double ptP1 = 0.830278 ,
145+ double ptP2 = 0.632177 , double ptP3 = 10.2202 ,
146+ double ptP4 = -0.000614809 , double ptP5 = -1.70993 ,
147+ double yP0 = 1.87732 , double yP1 = 0.00658212 ,
148+ double yP2 = -0.0988071 , double yP3 = -0.000452746 ,
149+ double yP4 = 0.00269782 ,
150+ int nPart = 2 , int pdg = 13 ,
151+ double ymin = -4.3 , double ymax = -2.3 ,
152+ double ptmin = 0.1 , float ptmax = 999. ,
153+ int randCharge = 1 )
154+ {
155+ auto * gen = new O2_GeneratorParamMuon (nPart , pdg , ymin , ymax , ptmin , ptmax );
156+ gen -> SetPtPars (ptP0 , ptP1 , ptP2 , ptP3 , ptP4 , ptP5 );
157+ gen -> SetYPars (yP0 , yP1 , yP2 , yP3 , yP4 );
158+ gen -> InitParaFuncs ();
159+ gen -> SetRandomCharge (randCharge );
160+ return gen ;
161+ }
0 commit comments