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