GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PhotonCOHGenerator.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2024, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5 
6  Alfonso Garcia <aagarciasoto \at km3net.de>
7  IFIC & Harvard University
8 */
9 //____________________________________________________________________________
10 
11 #include <cstring>
12 
13 #include <RVersion.h>
14 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,6)
15 #include <TMCParticle.h>
16 #else
17 #include <TMCParticle6.h>
18 #endif
19 #include <TClonesArray.h>
20 #include <TMath.h>
21 
35 
36 using namespace genie;
37 using namespace genie::constants;
38 using namespace genie::utils::math;
39 
40 //___________________________________________________________________________
42 EventRecordVisitorI("genie::PhotonCOHGenerator")
43 {
44  this->Initialize();
45 }
46 //___________________________________________________________________________
48 EventRecordVisitorI("genie::PhotonCOHGenerator", config)
49 {
50  this->Initialize();
51 }
52 //___________________________________________________________________________
54 {
55 
56 }
57 //____________________________________________________________________________
59 {
60  fPythia = TPythia6::Instance();
61 
62  // sync GENIE/PYTHIA6 seed number
64 }
65 //___________________________________________________________________________
67 {
68 
69  Interaction * interaction = evrec->Summary();
70  const InitialState & init_state = interaction->InitState();
71 
72  //incoming v & struck particle & remnant nucleus
73  GHepParticle * nu = evrec->Probe();
74 
75  GHepParticle * target = evrec -> TargetNucleus();
76  if(target) evrec->AddParticle(target->Pdg(), kIStFinalStateNuclearRemnant, 1,-1,-1,-1, *(target->P4()), *(target->X4()) );
77 
78  TVector3 unit_nu = nu->P4()->Vect().Unit();
79 
80  long double Ev = init_state.ProbeE(kRfLab);
81 
82  long double Mtgt = init_state.Tgt().Z()*kProtonMass + init_state.Tgt().N()*kNeutronMass;
83 
84  long double n1 = interaction->Kine().GetKV(kKVn1);
85  long double n2 = interaction->Kine().GetKV(kKVn2);
86  long double n3 = interaction->Kine().GetKV(kKVn3);
87 
88  long double costh = n1;
89  long double sinth = sqrtl(1-costh*costh);
90 
91  long double mlout = 0;
92  if (pdg::IsNuE (TMath::Abs(nu->Pdg()))) mlout = kElectronMass;
93  else if (pdg::IsNuMu (TMath::Abs(nu->Pdg()))) mlout = kMuonMass;
94  else if (pdg::IsNuTau(TMath::Abs(nu->Pdg()))) mlout = kTauMass;
95  long double mlout2 = mlout*mlout;
96 
97  long double mL = mlout+kMw;
98  long double Delta = sqrtl( powl(2.*Ev*Mtgt-mL*mL,2)-4.*powl(Mtgt*mL,2) );
99  long double s12_min = Ev/(2.*Ev+Mtgt)*(mL*mL+2.*Ev*Mtgt-Delta);
100  long double s12_max = Ev/(2.*Ev+Mtgt)*(mL*mL+2.*Ev*Mtgt+Delta);
101  long double s12 = expl( logl(s12_min)+(logl(s12_max)-logl(s12_min))*n2);
102  long double Q2_min = powl(s12,2)*Mtgt/(2.*Ev*(2.*Ev*Mtgt-s12));
103  long double Q2_max = s12 - mL*mL;
104  double Q2 = expl( logl(Q2_min) + (logl(Q2_max)-logl(Q2_min))*n3 );
105  double s_r = s12 - Q2;
106 
107  long double EW = (s_r+kMw2-mlout2)/sqrtl(s_r)/2.;
108  long double El = (s_r-kMw2+mlout2)/sqrtl(s_r)/2.;
109  long double p = sqrtl( EW*EW - kMw2 );
110  LongLorentzVector p4_lout( 0., -p*sinth, -p*costh, El );
111 
112  long double bz = 4.*Ev*Mtgt*Q2/(Q2+s_r)/(2.*Ev*Mtgt-Q2) - (2.*Ev*Mtgt+Q2)/(2.*Ev*Mtgt-Q2);
113  long double by = sqrtl(Mtgt*powl(Q2+s_r,2)/(2.*Ev*Q2*(s_r+Q2-2.*Ev*Mtgt))+1.);
114 
115  p4_lout.BoostZ(-bz);
116  p4_lout.BoostY(-by);
117 
118  TLorentzVector p4l_o(p4_lout.Px(),p4_lout.Py(),p4_lout.Pz(),p4_lout.E());
119  p4l_o.RotateX((double)acosl(by)-kPi/2.);
120 
121 
122  // Randomize transverse components
123  RandomGen * rnd = RandomGen::Instance();
124  double phi = 2 * kPi * rnd->RndLep().Rndm();
125 
126  p4l_o.RotateZ(phi);
127 
128  //rotate from LAB=[0,0,Ev,Ev]->[px,py,pz,E]
129  p4l_o.RotateUz(unit_nu);
130 
131  int pdglout = 0;
132  if (pdg::IsAntiNuE (nu->Pdg())) pdglout = kPdgPositron;
133  else if (pdg::IsNuE (nu->Pdg())) pdglout = kPdgElectron;
134  else if (pdg::IsAntiNuMu (nu->Pdg())) pdglout = kPdgAntiMuon;
135  else if (pdg::IsNuMu (nu->Pdg())) pdglout = kPdgMuon;
136  else if (pdg::IsAntiNuTau(nu->Pdg())) pdglout = kPdgAntiTau;
137  else if (pdg::IsNuTau (nu->Pdg())) pdglout = kPdgTau;
138 
139  // Create a GHepParticle and add it to the event record
140  evrec->AddParticle( pdglout, kIStStableFinalState, 0, -1, -1, -1, p4l_o, *(nu->X4()) );
141 
142  int pdgboson = pdg::IsNeutrino(init_state.ProbePdg()) ? kPdgWP : kPdgWM;
143 
144  int def61 = fPythia->GetMSTP(61);
145  int def71 = fPythia->GetMSTP(71);
146  fPythia->SetMSTP(61,0); // (Default=2) master switch for initial-state QCD and QED radiation.
147  fPythia->SetMSTP(71,0); // (Default=2) master switch for initial-state QCD and QED radiation.
148 
149  fPythia->Py1ent( -1, pdgboson, EW, acosl(costh), kPi/2. ); //k(1,2) = 2
150  fPythia->Pyexec();
151 
152  fPythia->SetMSTP(61,def61);
153  fPythia->SetMSTP(71,def71);
154 
155  fPythia->GetPrimaries();
156  TClonesArray * pythia_particles = (TClonesArray *) fPythia->ImportParticles("All");
157  int np = pythia_particles->GetEntries();
158  assert(np>0);
159 
160  TMCParticle * particle = 0;
161  TIter piter(pythia_particles);
162  while( (particle = (TMCParticle *) piter.Next()) ) {
163 
164  int pdgc = particle->GetKF();
165  int ks = particle->GetKS();
166 
167  LongLorentzVector p4longo(particle->GetPx(), particle->GetPy(), particle->GetPz(), particle->GetEnergy());
168  p4longo.BoostZ(-bz);
169  p4longo.BoostY(-by);
170 
171  TLorentzVector p4o(p4longo.Px(),p4longo.Py(),p4longo.Pz(),p4longo.E());
172  p4o.RotateX((double)acosl(by)-kPi/2.);
173  p4o.RotateZ(phi);
174  p4o.RotateUz(unit_nu);
175 
176  TParticlePDG * part = PDGLibrary::Instance()->Find(pdgc);
177  if ( (ks==1 || ks==4) && p4o.E() < part->Mass() ) {
178  LOG("PhotonCOHGenerator", pWARN) << "Putting at rest one stable particle generated by PYTHIA because E < m";
179  LOG("PhotonCOHGenerator", pWARN) << "PDG = " << pdgc << " // State = " << ks;
180  LOG("PhotonCOHGenerator", pWARN) << "E = " << p4o.E() << " // |p| = " << TMath::Sqrt(p4o.P());
181  LOG("PhotonCOHGenerator", pWARN) << "p = [ " << p4o.Px() << " , " << p4o.Py() << " , " << p4o.Pz() << " ]";
182  LOG("PhotonCOHGenerator", pWARN) << "m = " << p4o.M() << " // mpdg = " << part->Mass();
183  p4o.SetXYZT(0,0,0,part->Mass());
184  }
185 
186  // copy final state particles to the event record
188 
189  // fix numbering scheme used for mother/daughter assignments
190  int firstmother = -1;
191  int lastmother = -1;
192  int firstchild = -1;
193  int lastchild = -1;
194 
195  if (particle->GetParent()==0) {
196  firstmother = 0;
197  }
198  else {
199  firstmother = particle->GetParent() + 3;
200  if (particle->GetFirstChild()!=0) firstchild = particle->GetFirstChild() + 3;
201  if (particle->GetLastChild() !=0) lastchild = particle->GetLastChild() + 3;
202 
203  }
204 
205  double lightspeed = 299792458e3; //c in mm/s. Used for time in PYTHIA t[s]=t_pythia[mm]/c[mm/s]
206  double vx = nu->X4()->X() + particle->GetVx()*1e12; //pythia gives position in [mm] while genie uses [fm]
207  double vy = nu->X4()->Y() + particle->GetVy()*1e12;
208  double vz = nu->X4()->Z() + particle->GetVz()*1e12;
209  double vt = nu->X4()->T() + particle->GetTime()/lightspeed;
210  TLorentzVector pos( vx, vy, vz, vt );
211 
212  evrec->AddParticle(pdgc, ist, firstmother, lastmother, firstchild, lastchild, p4o, pos );
213 
214  }
215 
216  delete particle;
217  pythia_particles->Clear("C");
218 
219 }
220 //___________________________________________________________________________
222 {
223  Algorithm::Configure(config);
224  this->LoadConfig();
225 }
226 //____________________________________________________________________________
227 void PhotonCOHGenerator::Configure(string config)
228 {
229  Algorithm::Configure(config);
230  this->LoadConfig();
231 }
232 //____________________________________________________________________________
234 {
235 
236  // PYTHIA parameters only valid for HEDIS & HELepton
237  double wmin; GetParam( "Xsec-Wmin", wmin ) ;
238  int warnings; GetParam( "Warnings", warnings ) ;
239  int errors; GetParam( "Errors", errors ) ;
240  int qrk_mass; GetParam( "QuarkMass", qrk_mass ) ;
241  fPythia->SetPARP(2, wmin); //(D = 10. GeV) lowest c.m. energy for the event as a whole that the program will accept to simulate. (bellow 2GeV pythia crashes)
242  fPythia->SetMSTU(26, warnings); // (Default=10) maximum number of warnings that are printed
243  fPythia->SetMSTU(22, errors); // (Default=10) maximum number of errors that are printed
244  fPythia->SetMSTJ(93, qrk_mass); // light (d, u, s, c, b) quark masses are taken from PARF(101) - PARF(105) rather than PMAS(1,1) - PMAS(5,1). Diquark masses are given as sum of quark masses, without spin splitting term.
245 
246  fPythia->SetPMAS(24,1,kMw); //mass of the W boson (pythia=80.450 // genie=80.385)
247  fPythia->SetPMAS(24,2,0.); //set to 0 the width of the W boson to avoid problems with energy conservation
248  fPythia->SetPMAS(6,2,0.); //set to 0 the width of the top to avoid problems with energy conservation
249 
250 }
251 //____________________________________________________________________________
bool IsNuTau(int pdgc)
Definition: PDGUtils.cxx:168
bool IsNeutrino(int pdgc)
Definition: PDGUtils.cxx:110
TRandom3 & RndLep(void) const
rnd number generator used by final state primary lepton generators
Definition: RandomGen.h:62
double Q2(const Interaction *const i)
Definition: KineUtils.cxx:1077
virtual Interaction * Summary(void) const
Definition: GHepRecord.cxx:91
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:71
const TLorentzVector * P4(void) const
Definition: GHepParticle.h:78
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the &#39;Visito...
const int kPdgWM
Definition: PDGCodes.h:192
bool IsAntiNuTau(int pdgc)
Definition: PDGUtils.cxx:183
bool IsNuE(int pdgc)
Definition: PDGUtils.cxx:158
const int kPdgAntiMuon
Definition: PDGCodes.h:38
const int kPdgElectron
Definition: PDGCodes.h:35
static const double kElectronMass
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:29
TPythia6 * fPythia
PYTHIA6 wrapper class.
virtual GHepParticle * Probe(void) const
Definition: GHepRecord.cxx:284
int Pdg(void) const
Definition: GHepParticle.h:63
bool IsNuMu(int pdgc)
Definition: PDGUtils.cxx:163
Summary information for an interaction.
Definition: Interaction.h:56
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
const int kPdgTau
Definition: PDGCodes.h:39
void Configure(const Registry &config)
const Kinematics & Kine(void) const
Definition: Interaction.h:71
virtual void Configure(const Registry &config)
Definition: Algorithm.cxx:62
int ProbePdg(void) const
Definition: InitialState.h:64
static const double kNeutronMass
int Z(void) const
Definition: Target.h:68
void ProcessEventRecord(GHepRecord *evrec) const
double GetKV(KineVar_t kv) const
Definition: Kinematics.cxx:323
bool IsAntiNuMu(int pdgc)
Definition: PDGUtils.cxx:178
#define pWARN
Definition: Messenger.h:60
int N(void) const
Definition: Target.h:69
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:68
const TLorentzVector * X4(void) const
Definition: GHepParticle.h:79
A registry. Provides the container for algorithm configuration parameters.
Definition: Registry.h:65
const int kPdgAntiTau
Definition: PDGCodes.h:40
virtual void AddParticle(const GHepParticle &p)
Definition: GHepRecord.cxx:499
const InitialState & InitState(void) const
Definition: Interaction.h:69
TParticlePDG * Find(int pdgc, bool must_exist=true)
Definition: PDGLibrary.cxx:86
bool GetParam(const RgKey &name, T &p, bool is_top_call=true) const
const Target & Tgt(void) const
Definition: InitialState.h:66
const int kPdgMuon
Definition: PDGCodes.h:37
const int kPdgPositron
Definition: PDGCodes.h:36
double ProbeE(RefFrame_t rf) const
GENIE&#39;s GHEP MC event record.
Definition: GHepRecord.h:45
const int kPdgWP
Definition: PDGCodes.h:191
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:39
bool IsAntiNuE(int pdgc)
Definition: PDGUtils.cxx:173
enum genie::EGHepStatus GHepStatus_t
Initial State information.
Definition: InitialState.h:48