Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4_Input.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4_Input.C
1 #ifndef MACRO_G4INPUT_C
2 #define MACRO_G4INPUT_C
3 
4 #include <GlobalVariables.C>
5 #include <G4_TrkrVariables.C>
6 
7 #include <phpythia6/PHPythia6.h>
8 
9 #include <phpythia8/PHPythia8.h>
10 
11 #include <g4main/CosmicSpray.h>
12 #include <g4main/HepMCNodeReader.h>
13 #include <g4main/PHG4IonGun.h>
17 #include <g4main/PHG4ParticleGun.h>
19 #include <g4main/ReadEICFiles.h>
20 
21 #include <fermimotionafterburner/FermimotionAfterburner.h>
22 #include <hijingflipafterburner/HIJINGFlipAfterburner.h>
23 #include <reactionplaneafterburner/ReactionPlaneAfterburner.h>
24 
29 
34 #include <fun4all/Fun4AllServer.h>
35 
36 #include <set>
37 
38 R__LOAD_LIBRARY(libfun4all.so)
39 R__LOAD_LIBRARY(libg4testbench.so)
40 R__LOAD_LIBRARY(libPHPythia6.so)
41 R__LOAD_LIBRARY(libPHPythia8.so)
42 R__LOAD_LIBRARY(libFermimotionAfterburner.so)
43 R__LOAD_LIBRARY(libHIJINGFlipAfterburner.so)
44 R__LOAD_LIBRARY(libReactionPlaneAfterburner.so)
45 
46 namespace Input
47 {
48  // Real Event generators
49  bool PYTHIA6 = false;
50  int PYTHIA6_EmbedId = 0;
51 
52  bool PYTHIA8 = false;
53  int PYTHIA8_EmbedId = 0;
54 
55  // Single/multiple particle generators
56  bool DZERO = false;
57  int DZERO_NUMBER = 1;
58  int DZERO_VERBOSITY = 0;
59  std::set<int> DZERO_EmbedIds;
60 
61  bool GUN = false;
62  int GUN_NUMBER = 1;
63  int GUN_VERBOSITY = 0;
64  std::set<int> GUN_EmbedIds;
65 
66  bool IONGUN = false;
67  int IONGUN_NUMBER = 1;
69  std::set<int> IONGUN_EmbedIds;
70 
71  bool PGEN = false;
72  int PGEN_NUMBER = 1;
73  int PGEN_VERBOSITY = 0;
74  std::set<int> PGEN_EmbedIds;
75 
76  bool SIMPLE = false;
77  int SIMPLE_NUMBER = 1;
79 
80  int UPSILON_NUMBER = 1;
82  // other UPSILON settings which are also used elsewhere are in GlobalVariables.C
83 
84  double PILEUPRATE = 0.;
85  bool READHITS = false;
86  int VERBOSITY = 0;
87  int EmbedId = 1;
88 
89  bool COSMIC = false;
90  double COSMIC_R = 650.;
91 
96  {
97  if (HepMCGen == nullptr)
98  {
99  std::cout << "ApplysPHENIXBeamParameter(): Fatal Error - null input pointer HepMCGen" << std::endl;
100  exit(1);
101  }
102  HepMCGen->set_beam_direction_theta_phi(1e-3, 0, M_PI - 1e-3, 0); //2mrad x-ing of sPHENIX per sPH-TRG-2022-001
103 
104  switch (beam_config)
105  {
106  case AA_COLLISION:
107  // heavy ion mode
108 
110  100e-4, // approximation from past STAR/Run16 AuAu data
111  100e-4, // approximation from past STAR/Run16 AuAu data
112  7, // sPH-TRG-2022-001. Fig B.2
113  20 / 29.9792); // 20cm collision length / speed of light in cm/ns
114 
115  break;
116  case pA_COLLISION:
117 
118  // pA mode
119 
121  100e-4, // set to be similar to AA
122  100e-4, // set to be similar to AA
123  8, // sPH-TRG-2022-001. Fig B.4
124  20 / 29.9792); // 20cm collision length / speed of light in cm/ns
125 
126  break;
127  case pp_COLLISION:
128 
129  // pp mode
130 
132  120e-4, // approximation from past PHENIX data
133  120e-4, // approximation from past PHENIX data
134  10, // sPH-TRG-2022-001. Fig B.3
135  20 / 29.9792); // 20cm collision length / speed of light in cm/ns
136 
137  break;
138  default:
139  std::cout <<"ApplysPHENIXBeamParameter: invalid beam_config = "<<beam_config<<std::endl;
140 
141  exit(1);
142 
143  }
144 
150  }
151 
155  {
157  }
158 
163  {
164  if (HepMCGen == nullptr)
165  {
166  std::cout << "ApplyEICBeamParameter(): Fatal Error - null input pointer HepMCGen" << std::endl;
167  exit(1);
168  }
169 
170  //25mrad x-ing as in EIC CDR
171  const double EIC_hadron_crossing_angle = 25e-3;
172 
174  EIC_hadron_crossing_angle, // beamA_theta
175  0, // beamA_phi
176  M_PI, // beamB_theta
177  0 // beamB_phi
178  );
180  119e-6, 119e-6, // proton beam divergence horizontal & vertical, as in EIC CDR Table 1.1
181  211e-6, 152e-6 // electron beam divergence horizontal & vertical, as in EIC CDR Table 1.1
182  );
183 
184  // angular kick within a bunch as result of crab cavity
185  // using an naive assumption of transfer matrix from the cavity to IP,
186  // which is NOT yet validated with accelerator optics simulations!
187  const double z_hadron_cavity = 52e2; // CDR Fig 3.3
188  const double z_e_cavity = 38e2; // CDR Fig 3.2
190  -EIC_hadron_crossing_angle / 2. / z_hadron_cavity, 0,
191  -EIC_hadron_crossing_angle / 2. / z_e_cavity, 0);
192 
193  // calculate beam sigma width at IP as in EIC CDR table 1.1
194  const double sigma_p_h = sqrt(80 * 11.3e-7);
195  const double sigma_p_v = sqrt(7.2 * 1.0e-7);
196  const double sigma_p_l = 6;
197  const double sigma_e_h = sqrt(45 * 20.0e-7);
198  const double sigma_e_v = sqrt(5.6 * 1.3e-7);
199  const double sigma_e_l = 2;
200 
201  // combine two beam gives the collision sigma in z
202  const double collision_sigma_z = sqrt(sigma_p_l * sigma_p_l + sigma_e_l * sigma_e_l) / 2;
203  const double collision_sigma_t = collision_sigma_z / 29.9792; // speed of light in cm/ns
204 
206  sigma_p_h * sigma_e_h / sqrt(sigma_p_h * sigma_p_h + sigma_e_h * sigma_e_h), //x
207  sigma_p_v * sigma_e_v / sqrt(sigma_p_v * sigma_p_v + sigma_e_v * sigma_e_v), //y
208  collision_sigma_z, //z
209  collision_sigma_t); //t
215  }
216 } // namespace Input
217 
218 namespace INPUTHEPMC
219 {
220  string filename;
221  string listfile;
222  bool FLOW = false;
223  int FLOW_VERBOSITY = 0;
224  bool FERMIMOTION = false;
225  bool HIJINGFLIP = false;
226  bool REACTIONPLANERAND = false;
227 
228 } // namespace INPUTHEPMC
229 
230 namespace INPUTREADEIC
231 {
232  string filename;
233 } // namespace INPUTREADEIC
234 
235 namespace INPUTREADHITS
236 {
237  map<unsigned int, std::string> filename;
238  map<unsigned int, std::string> listfile;
239 } // namespace INPUTREADHITS
240 
241 namespace INPUTEMBED
242 {
243  map<unsigned int, std::string> filename;
244  map<unsigned int, std::string> listfile;
245  bool REPEAT = true;
246 } // namespace INPUTEMBED
247 
248 namespace PYTHIA6
249 {
250  string config_file = string(getenv("CALIBRATIONROOT")) + "/Generators/phpythia6.cfg";
251 }
252 
253 namespace PYTHIA8
254 {
255  string config_file = string(getenv("CALIBRATIONROOT")) + "/Generators/phpythia8.cfg";
256 }
257 
258 namespace PILEUP
259 {
260  string pileupfile = "/sphenix/sim/sim01/sphnxpro/MDC1/sHijing_HepMC/data/sHijing_0_20fm-0000000001-00000.dat";
262 } // namespace PILEUP
263 
264 // collection of pointers to particle generators we can grab in the Fun4All macro
265 namespace INPUTGENERATOR
266 {
267  std::vector<PHG4IonGun *> IonGun;
268  std::vector<PHG4ParticleGenerator *> ParticleGenerator;
269  std::vector<PHG4ParticleGeneratorD0 *> DZeroMesonGenerator;
270  std::vector<PHG4ParticleGeneratorVectorMeson *> VectorMesonGenerator;
271  std::vector<PHG4SimpleEventGenerator *> SimpleEventGenerator;
272  std::vector<PHG4ParticleGun *> Gun;
273  PHPythia6 *Pythia6 = nullptr;
274  PHPythia8 *Pythia8 = nullptr;
276  CosmicSpray *Cosmic = nullptr;
277 } // namespace INPUTGENERATOR
278 
279 namespace INPUTMANAGER
280 {
283 } // namespace INPUTMANAGER
284 
285 void InputInit()
286 {
287  // for pileup sims embed id is 1, to distinguish particles
288  // which will be embedded (when Input::EMBED = true) into pileup sims
289  // we need to start at embedid = 2
290  if (Input::EMBED)
291  {
292  Input::EmbedId = 2;
293  }
294  // first consistency checks - not all input generators play nice
295  // with each other
297  {
298  cout << "Reading Hits and Embedding into background at the same time is not supported" << endl;
299  gSystem->Exit(1);
300  }
302  {
303  cout << "Reading Hits and running G4 simultanously is not supported" << endl;
304  gSystem->Exit(1);
305  }
307  {
308  cout << "Pythia6 and Pythia8 cannot be run together - might be possible but needs R&D" << endl;
309  gSystem->Exit(1);
310  }
311 
313  {
314  cout << "Flow Afterburner and Pileup cannot be run simultanously" << endl;
315  gSystem->Exit(1);
316  }
317  // done with consistency checks, create generators in no specific order
318 
320  if (Input::PYTHIA6)
321  {
324 
327  Input::EmbedId++;
328  }
329  if (Input::PYTHIA8)
330  {
332  // see coresoftware/generators/PHPythia8 for example config
334 
337  Input::EmbedId++;
338  }
339  // single particle generators
340  if (Input::DZERO)
341  {
342  for (int i = 0; i < Input::DZERO_NUMBER; ++i)
343  {
344  std::string name = "DZERO_" + std::to_string(i);
346  dzero->Embed(Input::EmbedId);
348  Input::EmbedId++;
349  INPUTGENERATOR::DZeroMesonGenerator.push_back(dzero);
350  }
351  }
352  if (Input::GUN)
353  {
354  for (int i = 0; i < Input::GUN_NUMBER; ++i)
355  {
356  std::string name = "GUN_" + std::to_string(i);
357  PHG4ParticleGun *gun = new PHG4ParticleGun(name);
358  gun->Embed(Input::EmbedId);
360  Input::EmbedId++;
361  INPUTGENERATOR::Gun.push_back(gun);
362  }
363  }
364  if (Input::IONGUN)
365  {
366  for (int i = 0; i < Input::IONGUN_NUMBER; ++i)
367  {
368  std::string name = "IONGUN_" + std::to_string(i);
369  PHG4IonGun *iongun = new PHG4IonGun(name);
370  iongun->Embed(Input::EmbedId);
372  Input::EmbedId++;
373  INPUTGENERATOR::IonGun.push_back(iongun);
374  }
375  }
376  if (Input::PGEN)
377  {
378  for (int i = 0; i < Input::PGEN_NUMBER; ++i)
379  {
380  std::string name = "PGEN_" + std::to_string(i);
382  pgen->Embed(Input::EmbedId);
384  Input::EmbedId++;
385  INPUTGENERATOR::ParticleGenerator.push_back(pgen);
386  }
387  }
388  if (Input::SIMPLE)
389  {
390  for (int i = 0; i < Input::SIMPLE_NUMBER; ++i)
391  {
392  std::string name = "EVTGENERATOR_" + std::to_string(i);
394  simple->Embed(Input::EmbedId);
396  Input::EmbedId++;
397  INPUTGENERATOR::SimpleEventGenerator.push_back(simple);
398  }
399  }
400  if (Input::UPSILON)
401  {
402  for (int i = 0; i < Input::UPSILON_NUMBER; ++i)
403  {
404  std::string name = "UPSILON_" + std::to_string(i);
406  upsilon->Embed(Input::EmbedId);
408  Input::EmbedId++;
409  INPUTGENERATOR::VectorMesonGenerator.push_back(upsilon);
410  }
411  }
412 
413  // input managers for which we might need to set options
414  if (Input::HEPMC)
415  {
417  }
418  if (Input::PILEUPRATE > 0)
419  {
421  }
422 }
423 
425 {
427  if (Input::PYTHIA6)
428  {
430  }
431  if (Input::PYTHIA8)
432  {
434  }
435  if (Input::DZERO)
436  {
438  for (size_t icnt = 0; icnt < INPUTGENERATOR::DZeroMesonGenerator.size(); ++icnt)
439  {
440  INPUTGENERATOR::DZeroMesonGenerator[icnt]->Verbosity(verbosity);
442  }
443  }
444  if (Input::GUN)
445  {
447  for (size_t icnt = 0; icnt < INPUTGENERATOR::Gun.size(); ++icnt)
448  {
449  INPUTGENERATOR::Gun[icnt]->Verbosity(verbosity);
451  }
452  }
453  if (Input::IONGUN)
454  {
456  for (size_t icnt = 0; icnt < INPUTGENERATOR::IonGun.size(); ++icnt)
457  {
458  INPUTGENERATOR::IonGun[icnt]->Verbosity(verbosity);
460  }
461  }
462  if (Input::PGEN)
463  {
465  for (size_t icnt = 0; icnt < INPUTGENERATOR::ParticleGenerator.size(); ++icnt)
466  {
467  INPUTGENERATOR::ParticleGenerator[icnt]->Verbosity(verbosity);
469  }
470  }
471  if (Input::SIMPLE)
472  {
474  for (size_t icnt = 0; icnt < INPUTGENERATOR::SimpleEventGenerator.size(); ++icnt)
475  {
476  INPUTGENERATOR::SimpleEventGenerator[icnt]->Verbosity(verbosity);
478  }
479  }
480  if (Input::UPSILON)
481  {
482  for (size_t icnt = 0; icnt < INPUTGENERATOR::VectorMesonGenerator.size(); ++icnt)
483  {
486  {
487  INPUTGENERATOR::VectorMesonGenerator[icnt]->set_reuse_existing_vertex(true);
488  }
489  INPUTGENERATOR::VectorMesonGenerator[icnt]->Verbosity(verbosity);
491  }
492  }
493  if (Input::READEIC)
494  {
499  }
500  if (Input::COSMIC)
501  {
504  }
505  // here are the various utility modules which read particles and
506  // put them onto the G4 particle stack
508  {
509  if (Input::HEPMC)
510  {
512  {
514  se->registerSubsystem(rp);
515  }
516 
518  {
520  se->registerSubsystem(flip);
521  }
522  // these need to be applied before the HepMCNodeReader since they
523  // work on the hepmc records
524  if (INPUTHEPMC::FLOW)
525  {
528  se->registerSubsystem(burn);
529  }
531  {
533  se->registerSubsystem(fermi);
534  }
535  }
536  // copy HepMC records into G4
537  HepMCNodeReader *hr = new HepMCNodeReader();
538  se->registerSubsystem(hr);
539  }
540 }
541 
543 {
545  if (Input::EMBED)
546  {
547  gSystem->Load("libg4dst.so");
548  if (!INPUTEMBED::filename.empty() && !INPUTEMBED::listfile.empty())
549  {
550  cout << "only filenames or filelists are supported, not mixtures" << endl;
551  gSystem->Exit(1);
552  }
553  if (INPUTEMBED::filename.empty() && INPUTEMBED::listfile.empty())
554  {
555  cout << "you need to give an input filenames or filelist" << endl;
556  gSystem->Exit(1);
557  }
558  for (auto iter = INPUTEMBED::filename.begin(); iter != INPUTEMBED::filename.end(); ++iter)
559  {
560  string mgrname = "DSTin" + to_string(iter->first);
561  Fun4AllInputManager *hitsin = new Fun4AllDstInputManager(mgrname);
562  hitsin->fileopen(iter->second);
563  hitsin->Verbosity(Input::VERBOSITY);
564  if (INPUTEMBED::REPEAT)
565  {
566  hitsin->Repeat();
567  }
568  se->registerInputManager(hitsin);
569  }
570  for (auto iter = INPUTEMBED::listfile.begin(); iter != INPUTEMBED::listfile.end(); ++iter)
571  {
572  string mgrname = "DSTin" + to_string(iter->first);
573  Fun4AllInputManager *hitsin = new Fun4AllDstInputManager(mgrname);
574  hitsin->AddListFile(iter->second);
575  hitsin->Verbosity(Input::VERBOSITY);
576  if (INPUTEMBED::REPEAT)
577  {
578  hitsin->Repeat();
579  }
580  se->registerInputManager(hitsin);
581  }
582  }
583  if (Input::HEPMC)
584  {
587  if (!INPUTHEPMC::filename.empty() && INPUTHEPMC::listfile.empty())
588  {
590  }
591  else if (!INPUTHEPMC::listfile.empty())
592  {
594  }
595  else
596  {
597  cout << "no filename INPUTHEPMC::filename or listfile INPUTHEPMC::listfile given" << endl;
598  gSystem->Exit(1);
599  }
600  }
601  else if (Input::READHITS)
602  {
603  gSystem->Load("libg4dst.so");
604  if (!INPUTREADHITS::filename.empty() && !INPUTREADHITS::listfile.empty())
605  {
606  cout << "only filenames or filelists are supported, not mixtures" << endl;
607  gSystem->Exit(1);
608  }
609  if (INPUTREADHITS::filename.empty() && INPUTREADHITS::listfile.empty())
610  {
611  cout << "you need to give an input filenames or filelist" << endl;
612  gSystem->Exit(1);
613  }
614  for (auto iter = INPUTREADHITS::filename.begin(); iter != INPUTREADHITS::filename.end(); ++iter)
615  {
616  string mgrname = "DSTin" + to_string(iter->first);
617  Fun4AllInputManager *hitsin = new Fun4AllDstInputManager(mgrname);
618  hitsin->fileopen(iter->second);
619  hitsin->Verbosity(Input::VERBOSITY);
620  se->registerInputManager(hitsin);
621  }
622  for (auto iter = INPUTREADHITS::listfile.begin(); iter != INPUTREADHITS::listfile.end(); ++iter)
623  {
624  string mgrname = "DSTin" + to_string(iter->first);
625  Fun4AllInputManager *hitsin = new Fun4AllDstInputManager(mgrname);
626  hitsin->AddListFile(iter->second);
627  hitsin->Verbosity(Input::VERBOSITY);
628  se->registerInputManager(hitsin);
629  }
630  }
631  else
632  {
635  se->registerInputManager(in);
636  }
637  if (Input::PILEUPRATE > 0)
638  {
643  double time_window = 105.5 / PILEUP::TpcDriftVelocity;
644  double extended_readout_time = 0.0;
645  if(TRACKING::pp_mode) extended_readout_time = TRACKING::pp_extended_readout_time;
646  INPUTMANAGER::HepMCPileupInputManager->set_time_window(-time_window, time_window + extended_readout_time);
647  cout << "Pileup window is from " << -time_window << " to " << time_window + extended_readout_time << endl;
649  }
650 }
651 #endif