Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Fun4All_G4_sPHENIX.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Fun4All_G4_sPHENIX.C
1 #ifndef MACRO_FUN4ALLG4SPHENIX_C
2 #define MACRO_FUN4ALLG4SPHENIX_C
3 
4 // -- c++ includes --
5 #include <fstream>
6 // c++ includes --
7 // -- root includes --
8 #include <TSystem.h>
9 #include <TROOT.h>
10 // -- root includes --
11 
12 #include <GlobalVariables.C>
13 #include <DisplayOn.C>
14 #include <G4_Bbc.C>
15 #include <G4_CaloTrigger.C>
16 #include <G4_Centrality.C>
17 #include <G4_DSTReader.C>
18 #include <G4_Global.C>
19 #include <G4_HIJetReco.C>
20 #include <G4_Input.C>
21 #include <G4_Jets.C>
22 #include <G4_KFParticle.C>
23 #include <G4_ParticleFlow.C>
24 #include <G4_Production.C>
25 #include <G4_TopoClusterReco.C>
26 #include <G4_Tracking.C>
27 #include <G4_User.C>
28 #include <QA.C>
29 
30 #include <ffamodules/FlagHandler.h>
31 #include <ffamodules/HeadReco.h>
32 #include <ffamodules/SyncReco.h>
33 #include <ffamodules/XploadInterface.h>
34 
37 #include <fun4all/Fun4AllServer.h>
38 
39 #include <phool/PHRandomSeed.h>
40 #include <phool/recoConsts.h>
41 
42 #include "G4Setup_sPHENIX.C"
43 #include "../../macro/CEmc_Spacal.C"
44 
45 R__LOAD_LIBRARY(libfun4all.so)
46 R__LOAD_LIBRARY(libffamodules.so)
47 R__LOAD_LIBRARY(libEMCalPositionDependentCalibration.so)
48 // For HepMC Hijing
49 // try inputFile = /sphenix/sim/sim01/sphnxpro/sHijing_HepMC/sHijing_0-12fm.dat
50 
52  const int nEvents = 1,
53  const int seed = 0,
54  const string &calib_path="CEMC/PositionRecalibrationFull/",
55  const string &outdir = ".",
56  const string &inputFile = "https://www.phenix.bnl.gov/WWW/publish/phnxbld/sPHENIX/files/sPHENIX_G4Hits_sHijing_9-11fm_00000_00010.root",
57  const string &outputFile = "G4sPHENIX.root",
58  const string &embed_input_file = "https://www.phenix.bnl.gov/WWW/publish/phnxbld/sPHENIX/files/sPHENIX_G4Hits_sHijing_9-11fm_00000_00010.root",
59  const int skip = 0)
60 {
62  se->Verbosity(1);
63 
64  //Opt to print all random seed used for debugging reproducibility. Comment out to reduce stdout prints.
66 
67  // just if we set some flags somewhere in this macro
69  // By default every random number generator uses
70  // PHRandomSeed() which reads /dev/urandom to get its seed
71  // if the RANDOMSEED flag is set its value is taken as seed
72  // You can either set this to a random value using PHRandomSeed()
73  // which will make all seeds identical (not sure what the point of
74  // this would be:
75  // rc->set_IntFlag("RANDOMSEED",PHRandomSeed());
76  // or set it to a fixed value so you can debug your code
77  // rc->set_IntFlag("RANDOMSEED", 12345);
78 
79  if(seed > 0) {
80  rc->set_IntFlag("RANDOMSEED", seed);
81  }
82 
83  //===============
84  // Input options
85  //===============
86  // verbosity setting (applies to all input managers)
87  Input::VERBOSITY = 0;
88  // First enable the input generators
89  // Either:
90  // read previously generated g4-hits files, in this case it opens a DST and skips
91  // the simulations step completely. The G4Setup macro is only loaded to get information
92  // about the number of layers used for the cell reco code
93  // Input::READHITS = true;
94  INPUTREADHITS::filename[0] = inputFile;
95  // if you use a filelist
96  // INPUTREADHITS::listfile[0] = inputFile;
97  // Or:
98  // Use particle generator
99  // And
100  // Further choose to embed newly simulated events to a previous simulation. Not compatible with `readhits = true`
101  // In case embedding into a production output, please double check your G4Setup_sPHENIX.C and G4_*.C consistent with those in the production macro folder
102  // E.g. /sphenix/sim//sim01/production/2016-07-21/single_particle/spacal2d/
103  // Input::EMBED = true;
104  INPUTEMBED::filename[0] = embed_input_file;
105  // if you use a filelist
106  //INPUTEMBED::listfile[0] = embed_input_file;
107 
108  Input::SIMPLE = true;
109  // Input::SIMPLE_NUMBER = 2; // if you need 2 of them
110  // Input::SIMPLE_VERBOSITY = 1;
111 
112  // Input::PYTHIA6 = true;
113 
114  // Input::PYTHIA8 = true;
115 
116  // Input::GUN = true;
117  // Input::GUN_NUMBER = 3; // if you need 3 of them
118  // Input::GUN_VERBOSITY = 1;
119 
120  //D0 generator
121  //Input::DZERO = false;
122  //Input::DZERO_VERBOSITY = 0;
123  //Lambda_c generator //Not ready yet
124  //Input::LAMBDAC = false;
125  //Input::LAMBDAC_VERBOSITY = 0;
126  // Upsilon generator
127  //Input::UPSILON = true;
128  //Input::UPSILON_NUMBER = 3; // if you need 3 of them
129  //Input::UPSILON_VERBOSITY = 0;
130 
131  // Input::HEPMC = true;
132  INPUTHEPMC::filename = inputFile;
133 
134  // Event pile up simulation with collision rate in Hz MB collisions.
135  //Input::PILEUPRATE = 100e3;
136 
137  //-----------------
138  // Initialize the selected Input/Event generation
139  //-----------------
140  // This creates the input generator(s)
141  InputInit();
142 
143  //--------------
144  // Set generator specific options
145  //--------------
146  // can only be set after InputInit() is called
147 
148  // Simple Input generator:
149  // if you run more than one of these Input::SIMPLE_NUMBER > 1
150  // add the settings for other with [1], next with [2]...
151  if (Input::SIMPLE)
152  {
153  // particle id: https://pdg.lbl.gov/2020/reviews/rpp2020-rev-monte-carlo-numbering.pdf
154  // photon id: 22
155  INPUTGENERATOR::SimpleEventGenerator[0]->add_particles(22, 1);
156  if (Input::HEPMC || Input::EMBED)
157  {
158  INPUTGENERATOR::SimpleEventGenerator[0]->set_reuse_existing_vertex(true);
159  INPUTGENERATOR::SimpleEventGenerator[0]->set_existing_vertex_offset_vector(0.0, 0.0, 0.0);
160  }
161  else
162  {
163  INPUTGENERATOR::SimpleEventGenerator[0]->set_vertex_distribution_function(PHG4SimpleEventGenerator::Gaus,
166  INPUTGENERATOR::SimpleEventGenerator[0]->set_vertex_distribution_mean(0., 0., 0.);
167  INPUTGENERATOR::SimpleEventGenerator[0]->set_vertex_distribution_width(0.01, 0.01, 5.);
168  }
169  INPUTGENERATOR::SimpleEventGenerator[0]->set_eta_range(0, 1.1);
170  INPUTGENERATOR::SimpleEventGenerator[0]->set_phi_range(-M_PI/32.0 - 0.02, M_PI/32.0 + 0.02);
171  INPUTGENERATOR::SimpleEventGenerator[0]->set_pt_range(20, 21.);
172 
173  // for testing use full range
174  // INPUTGENERATOR::SimpleEventGenerator[0]->set_eta_range(-1, 1);
175  // INPUTGENERATOR::SimpleEventGenerator[0]->set_phi_range(-M_PI, M_PI);
176  // INPUTGENERATOR::SimpleEventGenerator[0]->set_pt_range(5, 5);
177  }
178  // Upsilons
179  // if you run more than one of these Input::UPSILON_NUMBER > 1
180  // add the settings for other with [1], next with [2]...
181  if (Input::UPSILON)
182  {
183  INPUTGENERATOR::VectorMesonGenerator[0]->add_decay_particles("e", 0);
184  INPUTGENERATOR::VectorMesonGenerator[0]->set_rapidity_range(-1, 1);
185  INPUTGENERATOR::VectorMesonGenerator[0]->set_pt_range(0., 10.);
186  // Y species - select only one, last one wins
187  INPUTGENERATOR::VectorMesonGenerator[0]->set_upsilon_1s();
188  if (Input::HEPMC || Input::EMBED)
189  {
190  INPUTGENERATOR::VectorMesonGenerator[0]->set_reuse_existing_vertex(true);
191  INPUTGENERATOR::VectorMesonGenerator[0]->set_existing_vertex_offset_vector(0.0, 0.0, 0.0);
192  }
193  }
194  // particle gun
195  // if you run more than one of these Input::GUN_NUMBER > 1
196  // add the settings for other with [1], next with [2]...
197  if (Input::GUN)
198  {
199  INPUTGENERATOR::Gun[0]->AddParticle("pi-", 0, 1, 0);
200  INPUTGENERATOR::Gun[0]->set_vtx(0, 0, 0);
201  }
202 
203  // pythia6
204  if (Input::PYTHIA6)
205  {
208  }
209  // pythia8
210  if (Input::PYTHIA8)
211  {
214  }
215 
216  //--------------
217  // Set Input Manager specific options
218  //--------------
219  // can only be set after InputInit() is called
220 
221  if (Input::HEPMC)
222  {
225 
226  // optional overriding beam parameters
227  //INPUTMANAGER::HepMCInputManager->set_vertex_distribution_width(100e-4, 100e-4, 8, 0); //optional collision smear in space, time
228  // INPUTMANAGER::HepMCInputManager->set_vertex_distribution_mean(0,0,0,0);//optional collision central position shift in space, time
229  // //optional choice of vertex distribution function in space, time
230  //INPUTMANAGER::HepMCInputManager->set_vertex_distribution_function(PHHepMCGenHelper::Gaus, PHHepMCGenHelper::Gaus, PHHepMCGenHelper::Gaus, PHHepMCGenHelper::Gaus);
235  //INPUTMANAGER::HepMCInputManager->set_embedding_id(Input::EmbedID);
236  if (Input::PILEUPRATE > 0)
237  {
238  // Copy vertex settings from foreground hepmc input
240  // and then modify the ones you want to be different
241  // INPUTMANAGER::HepMCPileupInputManager->set_vertex_distribution_width(100e-4,100e-4,8,0);
242  }
243  }
244  if (Input::PILEUPRATE > 0)
245  {
248  }
249  // register all input generators with Fun4All
250  InputRegister();
251 
252  if (! Input::READHITS)
253  {
254  rc->set_IntFlag("RUNNUMBER",1);
255 
256  SyncReco *sync = new SyncReco();
257  se->registerSubsystem(sync);
258 
259  HeadReco *head = new HeadReco();
260  se->registerSubsystem(head);
261  }
262 // Flag Handler is always needed to read flags from input (if used)
263 // and update our rc flags with them. At the end it saves all flags
264 // again on the DST in the Flags node under the RUN node
265  FlagHandler *flag = new FlagHandler();
266  se->registerSubsystem(flag);
267 
268  // set up production relatedstuff
269  // Enable::PRODUCTION = true;
270 
271  //======================
272  // Write the DST
273  //======================
274 
275  //Enable::DSTOUT = true;
276  Enable::DSTOUT_COMPRESS = false;
277  DstOut::OutputDir = outdir;
278  DstOut::OutputFile = outputFile;
279 
280  //Option to convert DST to human command readable TTree for quick poke around the outputs
281  // Enable::DSTREADER = true;
282 
283  // turn the display on (default off)
284  //Enable::DISPLAY = true;
285 
286  //======================
287  // What to run
288  //======================
289 
290  // QA, main switch
291  Enable::QA = false;
292 
293  // Global options (enabled for all enables subsystems - if implemented)
294  // Enable::ABSORBER = true;
295  // Enable::OVERLAPCHECK = true;
296  // Enable::VERBOSITY = 1;
297 
298  // Enable::BBC = true;
299  // Enable::BBC_SUPPORT = true; // save hist in bbc support structure
300  Enable::BBCFAKE = true; // Smeared vtx and t0, use if you don't want real BBC in simulation
301 
302  Enable::PIPE = true;
303  Enable::PIPE_ABSORBER = true;
304 
305  // central tracking
306  Enable::MVTX = false;
310 
311  Enable::INTT = false;
312 // Enable::INTT_ABSORBER = true; // enables layerwise support structure readout
313 // Enable::INTT_SUPPORT = true; // enable global support structure readout
316  Enable::INTT_QA = Enable::INTT_CLUSTER && Enable::QA && true;
317 
318  Enable::TPC = false;
319  Enable::TPC_ABSORBER = true;
320  Enable::TPC_CELL = Enable::TPC && true;
322  Enable::TPC_QA = Enable::TPC_CLUSTER && Enable::QA && true;
323 
324  Enable::MICROMEGAS = false;
327  Enable::MICROMEGAS_QA = Enable::MICROMEGAS_CLUSTER && Enable::QA && true;
328 
331  Enable::TRACKING_QA = Enable::TRACKING_TRACK && Enable::QA && true;
332 
333  // cemc electronics + thin layer of W-epoxy to get albedo from cemc
334  // into the tracking, cannot run together with CEMC
335  // Enable::CEMCALBEDO = true;
336 
337  Enable::CEMC = true;
338  Enable::CEMC_ABSORBER = true;
342  Enable::CEMC_CLUSTER_FULL = Enable::CEMC_TOWER && true;
344  Enable::CEMC_EVAL_POSITION_CORRECTION = Enable::CEMC_CLUSTER_FULL && true;
345  Enable::CEMC_QA = (Enable::CEMC_CLUSTER || Enable::CEMC_CLUSTER_FULL) && Enable::QA && true;
346 
347  Enable::HCALIN = false;
353  Enable::HCALIN_QA = Enable::HCALIN_CLUSTER && Enable::QA && true;
354 
355  Enable::MAGNET = true;
357 
358  Enable::HCALOUT = false;
364  Enable::HCALOUT_QA = Enable::HCALOUT_CLUSTER && Enable::QA && true;
365 
366  Enable::EPD = true;
367 
368  Enable::BEAMLINE = true;
369 // Enable::BEAMLINE_ABSORBER = true; // makes the beam line magnets sensitive volumes
370 // Enable::BEAMLINE_BLACKHOLE = true; // turns the beamline magnets into black holes
371  Enable::ZDC = true;
372 // Enable::ZDC_ABSORBER = true;
373 // Enable::ZDC_SUPPORT = true;
374  Enable::ZDC_TOWER = Enable::ZDC && true;
376 
378  //Enable::PLUGDOOR = true;
380 
381  Enable::GLOBAL_RECO = (Enable::BBCFAKE || Enable::TRACKING_TRACK) && true;
382  //Enable::GLOBAL_FASTSIM = true;
383 
384  //Enable::KFPARTICLE = true;
385  //Enable::KFPARTICLE_VERBOSITY = 1;
386  //Enable::KFPARTICLE_TRUTH_MATCH = true;
387  //Enable::KFPARTICLE_SAVE_NTUPLE = true;
388 
390 
393  Enable::JETS_QA = Enable::JETS && Enable::QA && true;
394 
395  // HI Jet Reco for p+Au / Au+Au collisions (default is false for
396  // single particle / p+p-only simulations, or for p+Au / Au+Au
397  // simulations which don't particularly care about jets)
398  Enable::HIJETS = Enable::JETS && Enable::CEMC_TOWER && Enable::HCALIN_TOWER && Enable::HCALOUT_TOWER && false;
399 
400  // 3-D topoCluster reconstruction, potentially in all calorimeter layers
401  Enable::TOPOCLUSTER = Enable::CEMC_TOWER && Enable::HCALIN_TOWER && Enable::HCALOUT_TOWER && false;
402  // particle flow jet reconstruction - needs topoClusters!
404  // centrality reconstruction
405  Enable::CENTRALITY = true;
406 
407  // new settings using Enable namespace in GlobalVariables.C
408  Enable::BLACKHOLE = true;
409  //Enable::BLACKHOLE_SAVEHITS = false; // turn off saving of bh hits
410  //Enable::BLACKHOLE_FORWARD_SAVEHITS = false; // disable forward/backward hits
411  //BlackHoleGeometry::visible = true;
412 
413  // run user provided code (from local G4_User.C)
414  //Enable::USER = true;
415 
416  //===============
417  // conditions DB flags
418  //===============
419  //Enable::XPLOAD = true;
420  // tag
421  rc->set_StringFlag("XPLOAD_TAG",XPLOAD::tag);
422  // database config
423  rc->set_StringFlag("XPLOAD_CONFIG",XPLOAD::config);
424  // 64 bit timestamp
425  rc->set_uint64Flag("TIMESTAMP",XPLOAD::timestamp);
426 
427  //---------------
428  // World Settings
429  //---------------
430  // G4WORLD::PhysicsList = "FTFP_BERT"; //FTFP_BERT_HP best for calo
431  // G4WORLD::WorldMaterial = "G4_AIR"; // set to G4_GALACTIC for material scans
432 
433  //---------------
434  // Magnet Settings
435  //---------------
436 
437  // G4MAGNET::magfield = string(getenv("CALIBRATIONROOT"))+ string("/Field/Map/sphenix3dbigmapxyz.root"); // default map from the calibration database
438  // G4MAGNET::magfield = "1.5"; // alternatively to specify a constant magnetic field, give a float number, which will be translated to solenoidal field in T, if string use as fieldmap name (including path)
439 // G4MAGNET::magfield_rescale = 1.; // make consistent with expected Babar field strength of 1.4T
440 
441  //---------------
442  // Pythia Decayer
443  //---------------
444  // list of decay types in
445  // $OFFLINE_MAIN/include/g4decayer/EDecayType.hh
446  // default is All:
447  // G4P6DECAYER::decayType = EDecayType::kAll;
448 
449  // Initialize the selected subsystems
450  G4Init();
451 
452  //---------------------
453  // GEANT4 Detector description
454  //---------------------
455  if (!Input::READHITS)
456  {
457  G4Setup();
458  }
459 
460  //------------------
461  // Detector Division
462  //------------------
463 
464  if (Enable::BBC || Enable::BBCFAKE) Bbc_Reco();
465 
470 
472 
474 
476 
477  //-----------------------------
478  // CEMC towering and clustering
479  //-----------------------------
480 
483  if (Enable::CEMC_CLUSTER_FULL) CEMC_Clusters_Full(calib_path);
484 
485  //-----------------------------
486  // HCAL towering and clustering
487  //-----------------------------
488 
491 
492  if (Enable::HCALOUT_TOWER) HCALOuter_Towers();
494 
495  // if enabled, do topoClustering early, upstream of any possible jet reconstruction
497 
498  //--------------
499  // SVTX tracking
500  //--------------
502  {
503  TrackingInit();
504  }
509 
511  {
512  Tracking_Reco();
513  }
514  //-----------------
515  // Global Vertexing
516  //-----------------
517 
519  {
520  cout << "You can only enable Enable::GLOBAL_RECO or Enable::GLOBAL_FASTSIM, not both" << endl;
521  gSystem->Exit(1);
522  }
524  {
525  Global_Reco();
526  }
527  else if (Enable::GLOBAL_FASTSIM)
528  {
529  Global_FastSim();
530  }
531 
532  //-----------------
533  // Centrality Determination
534  //-----------------
535 
536  if (Enable::CENTRALITY)
537  {
538  Centrality();
539  }
540 
541  //-----------------
542  // Calo Trigger Simulation
543  //-----------------
544 
546  {
547  CaloTrigger_Sim();
548  }
549 
550  //---------
551  // Jet reco
552  //---------
553 
554  if (Enable::JETS) Jet_Reco();
555  if (Enable::HIJETS) HIJetReco();
556 
558 
559  //----------------------
560  // Simulation evaluation
561  //----------------------
562  string outputroot = outputFile;
563  string remove_this = ".root";
564  size_t pos = outputroot.find(remove_this);
565  if (pos != string::npos)
566  {
567  outputroot.erase(pos, remove_this.length());
568  }
569 
570  if (Enable::TRACKING_EVAL) Tracking_Eval(outputroot + "_g4svtx_eval.root");
571 
572  if (Enable::CEMC_EVAL) CEMC_Eval(outputroot + "_g4cemc_eval.root");
573 
574  if (Enable::CEMC_EVAL_POSITION_CORRECTION) CEMC_Eval_Position_Correction(outputroot + "_g4cemc_eval.root");
575 
576  if (Enable::HCALIN_EVAL) HCALInner_Eval(outputroot + "_g4hcalin_eval.root");
577 
578  if (Enable::HCALOUT_EVAL) HCALOuter_Eval(outputroot + "_g4hcalout_eval.root");
579 
580  if (Enable::JETS_EVAL) Jet_Eval(outputroot + "_g4jet_eval.root");
581 
582  if (Enable::DSTREADER) G4DSTreader(outputroot + "_DSTReader.root");
583 
585 
586  //======================
587  // Run KFParticle on evt
588  //======================
591 
592  //----------------------
593  // Standard QAs
594  //----------------------
595 
596  if (Enable::CEMC_QA) CEMC_QA();
599 
600  if (Enable::JETS_QA) Jet_QA();
601 
602  if (Enable::MVTX_QA) Mvtx_QA();
603  if (Enable::INTT_QA) Intt_QA();
604  if (Enable::TPC_QA) TPC_QA();
607 
609 
610  //--------------
611  // Set up Input Managers
612  //--------------
613 
614  InputManagers();
615 
616  if (Enable::PRODUCTION)
617  {
619  }
620 
621  if (Enable::DSTOUT)
622  {
623  string FullOutFile = DstOut::OutputDir + "/" + DstOut::OutputFile;
624  Fun4AllDstOutputManager *out = new Fun4AllDstOutputManager("DSTOUT", FullOutFile);
626  {
627  ShowerCompress();
628  DstCompress(out);
629  }
630  se->registerOutputManager(out);
631  }
632  //-----------------
633  // Event processing
634  //-----------------
635  if (Enable::DISPLAY)
636  {
637  DisplayOn();
638 
639  gROOT->ProcessLine("Fun4AllServer *se = Fun4AllServer::instance();");
640  gROOT->ProcessLine("PHG4Reco *g4 = (PHG4Reco *) se->getSubsysReco(\"PHG4RECO\");");
641 
642  cout << "-------------------------------------------------" << endl;
643  cout << "You are in event display mode. Run one event with" << endl;
644  cout << "se->run(1)" << endl;
645  cout << "Run Geant4 command with following examples" << endl;
646  gROOT->ProcessLine("displaycmd()");
647 
648  return 0;
649  }
650 
651  // if we use a negative number of events we go back to the command line here
652  if (nEvents < 0)
653  {
654  return 0;
655  }
656  // if we run the particle generator and use 0 it'll run forever
657  // for embedding it runs forever if the repeat flag is set
658  if (nEvents == 0 && !Input::HEPMC && !Input::READHITS && INPUTEMBED::REPEAT)
659  {
660  cout << "using 0 for number of events is a bad idea when using particle generators" << endl;
661  cout << "it will run forever, so I just return without running anything" << endl;
662  return 0;
663  }
664 
665  se->skip(skip);
666  se->run(nEvents);
667 
668  //-----
669  // QA output
670  //-----
671 
672  if (Enable::QA) QA_Output(outputroot + "_qa.root");
673 
674  //-----
675  // Exit
676  //-----
677 
678  se->End();
679  std::cout << "All done" << std::endl;
680  delete se;
681  if (Enable::PRODUCTION)
682  {
684  }
685 
686  gSystem->Exit(0);
687  return 0;
688 }
689 #endif