Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:14:29

0001 #include <iostream>
0002 using namespace std;
0003 int Fun4All_G4_sPHENIX_photons(
0004     const int nEvents = 2,
0005     const int jobnum = 0,
0006     const float photenergy = 10,
0007     const int doembedding = 0,
0008     const char *inputFile = "/sphenix/data/data02/review_2017-08-02/single_particle/spacal2d/fieldmap/G4Hits_sPHENIX_e-_eta0_8GeV-0002.root",
0009     const char *outputFile = "G4sPHENIX.root",
0010     const char *embed_input_file = "/sphenix/data/data02/review_2017-08-02/sHijing/fm_0-4.list")
0011 {
0012   // Set the number of TPC layer
0013   const int n_TPC_layers = 40;  // use 60 for backward compatibility only
0014 
0015   //===============
0016   // Input options
0017   //===============
0018 
0019   // Either:
0020   // read previously generated g4-hits files, in this case it opens a DST and skips
0021   // the simulations step completely. The G4Setup macro is only loaded to get information
0022   // about the number of layers used for the cell reco code
0023   //
0024   // In case reading production output, please double check your G4Setup_sPHENIX.C and G4_*.C consistent with those in the production macro folder
0025   // E.g. /sphenix/sim//sim01/production/2016-07-21/single_particle/spacal2d/
0026   const bool readhits = false;
0027   // Or:
0028   // read files in HepMC format (typically output from event generators like hijing or pythia)
0029   const bool readhepmc = false && doembedding;  // read HepMC files
0030   // Or:
0031   // Use pythia
0032   const bool runpythia8 = false;
0033   const bool runpythia6 = false;
0034   //
0035   // **** And ****
0036   // Further choose to embed newly simulated events to a previous simulation. Not compatible with `readhits = true`
0037   // 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
0038   // E.g. /sphenix/data/data02/review_2017-08-02/
0039   const bool do_embedding = doembedding && false;
0040 
0041   // Besides the above flags. One can further choose to further put in following particles in Geant4 simulation
0042   // Use multi-particle generator (PHG4SimpleEventGenerator), see the code block below to choose particle species and kinematics
0043   const bool particles = true && !readhits;
0044   // or gun/ very simple single particle gun generator
0045   const bool usegun = false && !readhits;
0046   // Throw single Upsilons, may be embedded in Hijing by setting readhepmc flag also  (note, careful to set Z vertex equal to Hijing events)
0047   const bool upsilons = false && !readhits;
0048   // Event pile up simulation with collision rate in Hz MB collisions.
0049   // Note please follow up the macro to verify the settings for beam parameters
0050   const double pileup_collision_rate = 0;  // 100e3 for 100kHz nominal AuAu collision rate.
0051 
0052   //======================
0053   // What to run
0054   //======================
0055 
0056   bool do_bbc = true;
0057 
0058   bool do_pipe = true;
0059 
0060   bool do_svtx = true;
0061   bool do_svtx_cell = do_svtx && true;
0062   bool do_svtx_track = do_svtx_cell && false;
0063   bool do_svtx_eval = do_svtx_track && false;
0064 
0065   bool do_pstof = false;
0066 
0067   bool do_cemc = true;
0068   bool do_cemc_cell = do_cemc && true;
0069   bool do_cemc_twr = do_cemc_cell && true;
0070   bool do_cemc_cluster = do_cemc_twr && true;
0071   bool do_cemc_eval = do_cemc_cluster && false;
0072 
0073   bool do_hcalin = true;
0074   bool do_hcalin_cell = do_hcalin && true;
0075   bool do_hcalin_twr = do_hcalin_cell && true;
0076   bool do_hcalin_cluster = do_hcalin_twr && true;
0077   bool do_hcalin_eval = do_hcalin_cluster && false;
0078 
0079   bool do_magnet = true;
0080 
0081   bool do_hcalout = true;
0082   bool do_hcalout_cell = do_hcalout && true;
0083   bool do_hcalout_twr = do_hcalout_cell && true;
0084   bool do_hcalout_cluster = do_hcalout_twr && true;
0085   bool do_hcalout_eval = do_hcalout_cluster && false;
0086 
0087   //! forward flux return plug door. Out of acceptance and off by default.
0088   bool do_plugdoor = false;
0089 
0090   bool do_global = true;
0091   bool do_global_fastsim = true;
0092 
0093   bool do_calotrigger = true && do_cemc_twr && do_hcalin_twr && do_hcalout_twr;
0094 
0095   bool do_jet_reco = false;
0096   bool do_jet_eval = do_jet_reco && false;
0097 
0098   // HI Jet Reco for p+Au / Au+Au collisions (default is false for
0099   // single particle / p+p-only simulations, or for p+Au / Au+Au
0100   // simulations which don't particularly care about jets)
0101   bool do_HIjetreco = false && do_cemc_twr && do_hcalin_twr && do_hcalout_twr;
0102 
0103   bool do_dst_compress = false;
0104 
0105   //Option to convert DST to human command readable TTree for quick poke around the outputs
0106   bool do_DSTReader = false;
0107   //---------------
0108   // Load libraries
0109   //---------------
0110 
0111   gSystem->Load("libfun4all.so");
0112   gSystem->Load("libg4detectors.so");
0113   gSystem->Load("libphhepmc.so");
0114   gSystem->Load("libg4testbench.so");
0115   gSystem->Load("libg4hough.so");
0116   gSystem->Load("libg4eval.so");
0117 
0118   // establish the geometry and reconstruction setup
0119   gROOT->LoadMacro("G4Setup_sPHENIX.C");
0120   G4Init(do_svtx, do_pstof, do_cemc, do_hcalin, do_magnet, do_hcalout, do_pipe, do_plugdoor, n_TPC_layers);
0121 
0122   int absorberactive = 1;  // set to 1 to make all absorbers active volumes
0123   //  const string magfield = "1.5"; // if like float -> solenoidal field in T, if string use as fieldmap name (including path)
0124   const string magfield = "/phenix/upgrades/decadal/fieldmaps/sPHENIX.2d.root";  // if like float -> solenoidal field in T, if string use as fieldmap name (including path)
0125   const float magfield_rescale = -1.4 / 1.5;                                     // scale the map to a 1.4 T field
0126 
0127   //---------------
0128   // Fun4All server
0129   //---------------
0130 
0131   Fun4AllServer *se = Fun4AllServer::instance();
0132   se->Verbosity(0);
0133   // just if we set some flags somewhere in this macro
0134   recoConsts *rc = recoConsts::instance();
0135   // By default every random number generator uses
0136   // PHRandomSeed() which reads /dev/urandom to get its seed
0137   // if the RANDOMSEED flag is set its value is taken as seed
0138   // You ca neither set this to a random value using PHRandomSeed()
0139   // which will make all seeds identical (not sure what the point of
0140   // this would be:
0141   //  rc->set_IntFlag("RANDOMSEED",PHRandomSeed());
0142   // or set it to a fixed value so you can debug your code
0143   //  rc->set_IntFlag("RANDOMSEED", 12345);
0144 
0145   //-----------------
0146   // Event generation
0147   //-----------------
0148 
0149   if (readhits)
0150   {
0151     // Get the hits from a file
0152     // The input manager is declared later
0153 
0154     if (do_embedding)
0155     {
0156       cout << "Do not support read hits and embed background at the same time." << endl;
0157       exit(1);
0158     }
0159   }
0160   else
0161   {
0162     // running Geant4 stage. First load event generators.
0163 
0164     if (readhepmc)
0165     {
0166       // place holder. Additional action is performed in later stage at the input manager level
0167     }
0168 
0169     if (runpythia8)
0170     {
0171       gSystem->Load("libPHPythia8.so");
0172 
0173       PHPythia8 *pythia8 = new PHPythia8();
0174       // see coresoftware/generators/PHPythia8 for example config
0175       pythia8->set_config_file("phpythia8.cfg");
0176       if (readhepmc)
0177         pythia8->set_reuse_vertex(0);  // reuse vertex of subevent with embedding ID of 0
0178       // pythia8->set_vertex_distribution_width(0,0,10,0); // additional vertex smearing if needed, more vertex options available
0179       se->registerSubsystem(pythia8);
0180     }
0181 
0182     if (runpythia6)
0183     {
0184       gSystem->Load("libPHPythia6.so");
0185 
0186       PHPythia6 *pythia6 = new PHPythia6();
0187       pythia6->set_config_file("phpythia6.cfg");
0188       if (readhepmc)
0189         pythia6->set_reuse_vertex(0);  // reuse vertex of subevent with embedding ID of 0
0190       // pythia6->set_vertex_distribution_width(0,0,10,0); // additional vertex smearing if needed, more vertex options available
0191       se->registerSubsystem(pythia6);
0192     }
0193 
0194     // If "readhepMC" is also set, the particles will be embedded in Hijing events
0195     if (particles)
0196     {
0197       // toss low multiplicity dummy events
0198       PHG4SimpleEventGenerator *gen = new PHG4SimpleEventGenerator();
0199       gen->add_particles(22, 1);  // mu+,e+,proton,pi+,Upsilon
0200       //gen->add_particles("pi+",100); // 100 pion option
0201       if (readhepmc || do_embedding || runpythia8 || runpythia6)
0202       {
0203         gen->set_reuse_existing_vertex(true);
0204         gen->set_existing_vertex_offset_vector(0.0, 0.0, 0.0);
0205       }
0206       else
0207       {
0208         gen->set_vertex_distribution_function(PHG4SimpleEventGenerator::Uniform,
0209                                               PHG4SimpleEventGenerator::Uniform,
0210                                               PHG4SimpleEventGenerator::Uniform);
0211         gen->set_vertex_distribution_mean(0.0, 0.0, 0.0);
0212         gen->set_vertex_distribution_width(0.0, 0.0, 5.0);
0213       }
0214       gen->set_vertex_size_function(PHG4SimpleEventGenerator::Uniform);
0215       gen->set_vertex_size_parameters(0.0, 0.0);
0216       gen->set_eta_range(0.5, 0.7);
0217       gen->set_phi_range(0.2,0.4);
0218  
0219       gen->set_p_range(photenergy, photenergy);
0220       if(doembedding)
0221     gen->Embed(1);
0222       gen->Verbosity(0);
0223 
0224       se->registerSubsystem(gen);
0225     }
0226 
0227     if (usegun)
0228     {
0229       PHG4ParticleGun *gun = new PHG4ParticleGun();
0230       //  gun->set_name("anti_proton");
0231       gun->set_name("geantino");
0232       gun->set_vtx(0, 0, 0);
0233       gun->set_mom(10, 0, 0.01);
0234       // gun->AddParticle("geantino",1.7776,-0.4335,0.);
0235       // gun->AddParticle("geantino",1.7709,-0.4598,0.);
0236       // gun->AddParticle("geantino",2.5621,0.60964,0.);
0237       // gun->AddParticle("geantino",1.8121,0.253,0.);
0238       //      se->registerSubsystem(gun);
0239       PHG4ParticleGenerator *pgen = new PHG4ParticleGenerator();
0240       pgen->set_name("geantino");
0241       pgen->set_z_range(0, 0);
0242       pgen->set_eta_range(0.01, 0.01);
0243       pgen->set_mom_range(10, 10);
0244       pgen->set_phi_range(5.3 / 180. * TMath::Pi(), 5.7 / 180. * TMath::Pi());
0245       se->registerSubsystem(pgen);
0246     }
0247 
0248     // If "readhepMC" is also set, the Upsilons will be embedded in Hijing events, if 'particles" is set, the Upsilons will be embedded in whatever particles are thrown
0249     if (upsilons)
0250     {
0251       // run upsilons for momentum, dca performance, alone or embedded in Hijing
0252 
0253       PHG4ParticleGeneratorVectorMeson *vgen = new PHG4ParticleGeneratorVectorMeson();
0254       vgen->add_decay_particles("e+", "e-", 0);  // i = decay id
0255       // event vertex
0256       if (readhepmc || do_embedding || particles || runpythia8 || runpythia6)
0257       {
0258         vgen->set_reuse_existing_vertex(true);
0259       }
0260       else
0261       {
0262         vgen->set_vtx_zrange(-10.0, +10.0);
0263       }
0264 
0265       // Note: this rapidity range completely fills the acceptance of eta = +/- 1 unit
0266       vgen->set_rapidity_range(-1.0, +1.0);
0267       vgen->set_pt_range(0.0, 10.0);
0268 
0269       int istate = 1;
0270 
0271       if (istate == 1)
0272       {
0273         // Upsilon(1S)
0274         vgen->set_mass(9.46);
0275         vgen->set_width(54.02e-6);
0276       }
0277       else if (istate == 2)
0278       {
0279         // Upsilon(2S)
0280         vgen->set_mass(10.0233);
0281         vgen->set_width(31.98e-6);
0282       }
0283       else
0284       {
0285         // Upsilon(3S)
0286         vgen->set_mass(10.3552);
0287         vgen->set_width(20.32e-6);
0288       }
0289 
0290       vgen->Verbosity(0);
0291       vgen->Embed(3);
0292       se->registerSubsystem(vgen);
0293 
0294       cout << "Upsilon generator for istate = " << istate << " created and registered " << endl;
0295     }
0296   }
0297 
0298   if (!readhits)
0299   {
0300     //---------------------
0301     // Detector description
0302     //---------------------
0303 
0304     G4Setup(absorberactive, magfield, TPythia6Decayer::kAll,
0305             do_svtx, do_pstof, do_cemc, do_hcalin, do_magnet, do_hcalout, do_pipe,do_plugdoor, magfield_rescale);
0306   }
0307 
0308   //---------
0309   // BBC Reco
0310   //---------
0311 
0312   if (do_bbc)
0313   {
0314     gROOT->LoadMacro("G4_Bbc.C");
0315     BbcInit();
0316     Bbc_Reco();
0317   }
0318   //------------------
0319   // Detector Division
0320   //------------------
0321 
0322   if (do_svtx_cell) Svtx_Cells();
0323 
0324   if (do_cemc_cell) CEMC_Cells();
0325 
0326   if (do_hcalin_cell) HCALInner_Cells();
0327 
0328   if (do_hcalout_cell) HCALOuter_Cells();
0329 
0330   //-----------------------------
0331   // CEMC towering and clustering
0332   //-----------------------------
0333 
0334   if (do_cemc_twr) CEMC_Towers();
0335   if (do_cemc_cluster) CEMC_Clusters();
0336 
0337   //-----------------------------
0338   // HCAL towering and clustering
0339   //-----------------------------
0340 
0341   if (do_hcalin_twr) HCALInner_Towers();
0342   if (do_hcalin_cluster) HCALInner_Clusters();
0343 
0344   if (do_hcalout_twr) HCALOuter_Towers();
0345   if (do_hcalout_cluster) HCALOuter_Clusters();
0346 
0347   if (do_dst_compress) ShowerCompress();
0348 
0349   //--------------
0350   // SVTX tracking
0351   //--------------
0352 
0353   if (do_svtx_track) Svtx_Reco();
0354 
0355   //-----------------
0356   // Global Vertexing
0357   //-----------------
0358 
0359   if (do_global)
0360   {
0361     gROOT->LoadMacro("G4_Global.C");
0362     Global_Reco();
0363   }
0364 
0365   else if (do_global_fastsim)
0366   {
0367     gROOT->LoadMacro("G4_Global.C");
0368     Global_FastSim();
0369   }
0370 
0371   //-----------------
0372   // Calo Trigger Simulation
0373   //-----------------
0374 
0375   if (do_calotrigger)
0376   {
0377     gROOT->LoadMacro("G4_CaloTrigger.C");
0378     CaloTrigger_Sim();
0379   }
0380 
0381   //---------
0382   // Jet reco
0383   //---------
0384 
0385   if (do_jet_reco)
0386   {
0387     gROOT->LoadMacro("G4_Jets.C");
0388     Jet_Reco();
0389   }
0390 
0391   if (do_HIjetreco)
0392   {
0393     gROOT->LoadMacro("G4_HIJetReco.C");
0394     HIJetReco();
0395   }
0396 
0397   //----------------------
0398   // Simulation evaluation
0399   //----------------------
0400 
0401   if (do_svtx_eval) Svtx_Eval(string(outputFile) + "_g4svtx_eval.root");
0402 
0403   if (do_cemc_eval) CEMC_Eval(string(outputFile) + "_g4cemc_eval.root");
0404 
0405   if (do_hcalin_eval) HCALInner_Eval(string(outputFile) + "_g4hcalin_eval.root");
0406 
0407   if (do_hcalout_eval) HCALOuter_Eval(string(outputFile) + "_g4hcalout_eval.root");
0408 
0409   if (do_jet_eval) Jet_Eval(string(outputFile) + "_g4jet_eval.root");
0410 
0411   gSystem->Load("libPhotons.so");
0412   Photons *photons = new Photons(outputFile);
0413   photons->Verbosity(0);
0414 
0415   photons->set_cluspt_mincut(0.5);
0416   photons->set_eta_lowhigh(-1.05,1.05);
0417   if(doembedding)
0418     photons->use_embedding(1);
0419   if(!doembedding)
0420     photons->use_embedding(0);
0421   se->registerSubsystem(photons);
0422 
0423 
0424   gSystem->ListLibraries();
0425 
0426 
0427 
0428   //--------------
0429   // IO management
0430   //--------------
0431 
0432   if (readhits)
0433   {
0434     //meta-lib for DST objects used in simulation outputs
0435     gSystem->Load("libg4dst.so");
0436 
0437     // Hits file
0438     Fun4AllInputManager *hitsin = new Fun4AllDstInputManager("DSTin");
0439     hitsin->fileopen(inputFile);
0440     se->registerInputManager(hitsin);
0441   }
0442 
0443   if (do_embedding)
0444   {
0445     if (embed_input_file == NULL)
0446     {
0447       cout << "Missing embed_input_file! Exit";
0448       exit(3);
0449     }
0450 
0451     //meta-lib for DST objects used in simulation outputs
0452     gSystem->Load("libg4dst.so");
0453 
0454     Fun4AllDstInputManager *in1 = new Fun4AllNoSyncDstInputManager("DSTinEmbed");
0455     //      in1->AddFile(embed_input_file); // if one use a single input file
0456     in1->AddListFile(embed_input_file);  // RecommendedL: if one use a text list of many input files
0457     se->registerInputManager(in1);
0458   }
0459 
0460   if (readhepmc)
0461   {
0462     //meta-lib for DST objects used in simulation outputs
0463     gSystem->Load("libg4dst.so");
0464 
0465     Fun4AllHepMCInputManager *in = new Fun4AllHepMCInputManager("HepMCInput_1");
0466     se->registerInputManager(in);
0467     se->fileopen(in->Name().c_str(), inputFile);
0468     //in->set_vertex_distribution_width(100e-4,100e-4,30,0);//optional collision smear in space, time
0469     //in->set_vertex_distribution_mean(0,0,1,0);//optional collision central position shift in space, time
0470     // //optional choice of vertex distribution function in space, time
0471     //in->set_vertex_distribution_function(PHHepMCGenHelper::Gaus,PHHepMCGenHelper::Gaus,PHHepMCGenHelper::Uniform,PHHepMCGenHelper::Gaus);
0472     //! embedding ID for the event
0473     //! positive ID is the embedded event of interest, e.g. jetty event from pythia
0474     //! negative IDs are backgrounds, .e.g out of time pile up collisions
0475     //! Usually, ID = 0 means the primary Au+Au collision background
0476     //in->set_embedding_id(2);
0477   }
0478   else
0479   {
0480     // for single particle generators we just need something which drives
0481     // the event loop, the Dummy Input Mgr does just that
0482     Fun4AllInputManager *in = new Fun4AllDummyInputManager("JADE");
0483     se->registerInputManager(in);
0484   }
0485 
0486   if (pileup_collision_rate > 0)
0487   {
0488     // pile up simulation.
0489     // add random beam collisions following a collision diamond and rate from a HepMC stream
0490     Fun4AllHepMCPileupInputManager *pileup = new Fun4AllHepMCPileupInputManager("HepMCPileupInput");
0491     se->registerInputManager(pileup);
0492 
0493     const string pileupfile("/sphenix/sim/sim01/sHijing/sHijing_0-12fm.dat");
0494     pileup->AddFile(pileupfile);  // HepMC events used in pile up collisions. You can add multiple files, and the file list will be reused.
0495     //pileup->set_vertex_distribution_width(100e-4,100e-4,30,5);//override collision smear in space time
0496     //pileup->set_vertex_distribution_mean(0,0,0,0);//override collision central position shift in space time
0497     pileup->set_collision_rate(pileup_collision_rate);
0498 
0499     double time_window_minus = -35000;
0500     double time_window_plus = 35000;
0501 
0502     if (do_svtx)
0503     {
0504       // double TPCDriftVelocity = 6.0 / 1000.0; // cm/ns, which is loaded from G4_SVTX*.C macros
0505       time_window_minus = -105.5 / TPCDriftVelocity;  // ns
0506       time_window_plus = 105.5 / TPCDriftVelocity;    // ns;
0507     }
0508     pileup->set_time_window(time_window_minus, time_window_plus);  // override timing window in ns
0509     cout << "Collision pileup enabled using file " << pileupfile << " with collision rate " << pileup_collision_rate
0510          << " and time window " << time_window_minus << " to " << time_window_plus << endl;
0511   }
0512 
0513   if (do_DSTReader)
0514   {
0515     //Convert DST to human command readable TTree for quick poke around the outputs
0516     gROOT->LoadMacro("G4_DSTReader.C");
0517 
0518     G4DSTreader(outputFile,  //
0519                 /*int*/ absorberactive,
0520                 /*bool*/ do_svtx,
0521                 /*bool*/ do_pstof,
0522                 /*bool*/ do_cemc,
0523                 /*bool*/ do_hcalin,
0524                 /*bool*/ do_magnet,
0525                 /*bool*/ do_hcalout,
0526                 /*bool*/ do_cemc_twr,
0527                 /*bool*/ do_hcalin_twr,
0528                 /*bool*/ do_magnet,
0529                 /*bool*/ do_hcalout_twr);
0530   }
0531 
0532   //  Fun4AllDstOutputManager *out = new Fun4AllDstOutputManager("DSTOUT", outputFile);
0533   // if (do_dst_compress) DstCompress(out);
0534   //  se->registerOutputManager(out);
0535 
0536   //-----------------
0537   // Event processing
0538   //-----------------
0539   if (nEvents < 0)
0540   {
0541     return;
0542   }
0543   // if we run the particle generator and use 0 it'll run forever
0544   if (nEvents == 0 && !readhits && !readhepmc)
0545   {
0546     cout << "using 0 for number of events is a bad idea when using particle generators" << endl;
0547     cout << "it will run forever, so I just return without running anything" << endl;
0548     return;
0549   }
0550 
0551   se->run(nEvents);
0552 
0553   //-----
0554   // Exit
0555   //-----
0556 
0557   se->End();
0558   std::cout << "All done" << std::endl;
0559   delete se;
0560   gSystem->Exit(0);
0561 }