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