File indexing completed on 2025-10-31 08:23:30
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 
0017 
0018 
0019 
0020 
0021 
0022 
0023 
0024 
0025 
0026 
0027 
0028 
0029 
0030 
0031 
0032 
0033 
0034 
0035 
0036 
0037 
0038 
0039 
0040 
0041 
0042 
0043 
0044 
0045 
0046 
0047 
0048 
0049 
0050 
0051 
0052 
0053 
0054 
0055 
0056 
0057 
0058 
0059 
0060 
0061 
0062 
0063 
0064 
0065 
0066 
0067 
0068 
0069 
0070 
0071 
0072 
0073 
0074 #include "CLHEP/Random/Randomize.h"
0075 #include "CLHEP/Random/Ranlux64Engine.h"
0076 #include "HadronicGenerator.hh"
0077 
0078 #include "G4GenericIon.hh"
0079 #include "G4HadronicParameters.hh"
0080 #include "G4IonTable.hh"
0081 #include "G4Material.hh"
0082 #include "G4NistManager.hh"
0083 #include "G4ParticleTable.hh"
0084 #include "G4PhysicalConstants.hh"
0085 #include "G4ProcessManager.hh"
0086 #include "G4SystemOfUnits.hh"
0087 #include "G4UnitsTable.hh"
0088 #include "G4VParticleChange.hh"
0089 #include "G4ios.hh"
0090 #include "globals.hh"
0091 
0092 #include <iomanip>
0093 
0094 
0095 
0096 int main(int, char**)
0097 {
0098   G4cout << "=== Test of the HadronicGenerator ===" << G4endl;
0099 
0100   
0101   G4HadronicParameters::Instance()->SetEnableHyperNuclei(true);
0102 
0103   
0104   
0105   
0106   
0107   const G4String namePhysics = "FTFP_BERT";  
0108   
0109   
0110   
0111   
0112   
0113   
0114   
0115   
0116   
0117   
0118 
0119   
0120   
0121   G4double minEnergy = 1.0 * CLHEP::GeV;  
0122   G4double maxEnergy = 30.0 * CLHEP::GeV;  
0123 
0124   const G4int numCollisions = 1000;  
0125 
0126   
0127   
0128   
0129   const G4bool isPrintingEnabled = true;  
0130   const G4int printingGap = 100;  
0131 
0132   
0133   
0134   
0135   
0136   
0137   std::vector<G4String> vecProjectiles;  
0138   vecProjectiles.push_back("pi-");
0139   
0140   vecProjectiles.push_back("pi+");
0141   vecProjectiles.push_back("kaon-");
0142   vecProjectiles.push_back("kaon+");
0143   vecProjectiles.push_back("kaon0L");
0144   vecProjectiles.push_back("kaon0S");
0145   
0146   
0147   vecProjectiles.push_back("proton");
0148   vecProjectiles.push_back("neutron");
0149   vecProjectiles.push_back("deuteron");
0150   vecProjectiles.push_back("triton");
0151   vecProjectiles.push_back("He3");
0152   vecProjectiles.push_back("alpha");
0153   vecProjectiles.push_back("lambda");
0154   vecProjectiles.push_back("sigma-");
0155   
0156   vecProjectiles.push_back("sigma+");
0157   vecProjectiles.push_back("xi-");
0158   vecProjectiles.push_back("xi0");
0159   vecProjectiles.push_back("omega-");
0160   vecProjectiles.push_back("anti_proton");
0161   vecProjectiles.push_back("anti_neutron");
0162   vecProjectiles.push_back("anti_lambda");
0163   vecProjectiles.push_back("anti_sigma-");
0164   
0165   vecProjectiles.push_back("anti_sigma+");
0166   vecProjectiles.push_back("anti_xi-");
0167   vecProjectiles.push_back("anti_xi0");
0168   vecProjectiles.push_back("anti_omega-");
0169   vecProjectiles.push_back("anti_deuteron");
0170   vecProjectiles.push_back("anti_triton");
0171   vecProjectiles.push_back("anti_He3");
0172   vecProjectiles.push_back("anti_alpha");
0173 
0174   
0175   if (namePhysics == "FTFP_BERT" || namePhysics == "FTFP_BERT_ATL" || namePhysics == "QGSP_BERT"
0176       || namePhysics == "QGSP_BIC" || namePhysics == "FTFP" || namePhysics == "QGSP")
0177   {
0178     
0179     vecProjectiles.push_back("D+");
0180     vecProjectiles.push_back("D-");
0181     vecProjectiles.push_back("D0");
0182     vecProjectiles.push_back("anti_D0");
0183     vecProjectiles.push_back("Ds+");
0184     vecProjectiles.push_back("Ds-");
0185     
0186     
0187     vecProjectiles.push_back("B+");
0188     vecProjectiles.push_back("B-");
0189     vecProjectiles.push_back("B0");
0190     vecProjectiles.push_back("anti_B0");
0191     vecProjectiles.push_back("Bs0");
0192     vecProjectiles.push_back("anti_Bs0");
0193     vecProjectiles.push_back("Bc+");
0194     vecProjectiles.push_back("Bc-");
0195     
0196     vecProjectiles.push_back("lambda_c+");
0197     vecProjectiles.push_back("anti_lambda_c+");
0198     
0199     
0200     
0201     
0202     
0203     
0204     vecProjectiles.push_back("xi_c+");
0205     vecProjectiles.push_back("anti_xi_c+");
0206     vecProjectiles.push_back("xi_c0");
0207     vecProjectiles.push_back("anti_xi_c0");
0208     vecProjectiles.push_back("omega_c0");
0209     vecProjectiles.push_back("anti_omega_c0");
0210     vecProjectiles.push_back("lambda_b");
0211     vecProjectiles.push_back("anti_lambda_b");
0212     
0213     
0214     
0215     
0216     
0217     
0218     vecProjectiles.push_back("xi_b0");
0219     vecProjectiles.push_back("anti_xi_b0");
0220     vecProjectiles.push_back("xi_b-");
0221     vecProjectiles.push_back("anti_xi_b-");
0222     vecProjectiles.push_back("omega_b-");
0223     vecProjectiles.push_back("anti_omega_b-");
0224   }
0225 
0226   
0227   
0228   
0229   
0230   if (G4HadronicParameters::Instance()->EnableHyperNuclei()) {
0231     if (namePhysics == "FTFP_BERT" || namePhysics == "FTFP_INCLXX" || namePhysics == "FTFP"
0232         || namePhysics == "INCL")
0233     {
0234       
0235       vecProjectiles.push_back("hypertriton");
0236       vecProjectiles.push_back("hyperalpha");
0237       vecProjectiles.push_back("hyperH4");
0238       vecProjectiles.push_back("doublehyperH4");
0239       vecProjectiles.push_back("doublehyperdoubleneutron");
0240       vecProjectiles.push_back("hyperHe5");
0241     }
0242     if (namePhysics == "FTFP_BERT" || namePhysics == "FTFP_INCLXX" || namePhysics == "FTFP") {
0243       
0244       vecProjectiles.push_back("anti_hypertriton");
0245       vecProjectiles.push_back("anti_hyperalpha");
0246       vecProjectiles.push_back("anti_hyperH4");
0247       vecProjectiles.push_back("anti_doublehyperH4");
0248       vecProjectiles.push_back("anti_doublehyperdoubleneutron");
0249       vecProjectiles.push_back("anti_hyperHe5");
0250     }
0251   }
0252 
0253   G4ParticleDefinition* projectileNucleus = nullptr;
0254   G4GenericIon* gion = G4GenericIon::GenericIon();
0255   gion->SetProcessManager(new G4ProcessManager(gion));
0256   G4ParticleTable* partTable = G4ParticleTable::GetParticleTable();
0257   G4IonTable* ions = partTable->GetIonTable();
0258   partTable->SetReadiness();
0259   ions->CreateAllIon();
0260   ions->CreateAllIsomer();
0261 
0262   const G4bool isProjectileIon = false;  
0263   if (isProjectileIon) {
0264     minEnergy = 40.0 * 13.0 * CLHEP::GeV;  
0265     maxEnergy = 40.0 * 13.0 * CLHEP::GeV;  
0266     G4int ionZ = 18, ionA = 40;  
0267     projectileNucleus = partTable->GetIonTable()->GetIon(ionZ, ionA, 0.0);
0268   }
0269 
0270   
0271   
0272   
0273   
0274   std::vector<G4String> vecMaterials;  
0275   vecMaterials.push_back("G4_H");
0276   vecMaterials.push_back("G4_He");
0277   vecMaterials.push_back("G4_Be");
0278   vecMaterials.push_back("G4_C");
0279   vecMaterials.push_back("G4_Al");
0280   vecMaterials.push_back("G4_Si");
0281   
0282   vecMaterials.push_back("G4_Ar");
0283   vecMaterials.push_back("G4_Fe");
0284   vecMaterials.push_back("G4_Cu");
0285   vecMaterials.push_back("G4_W");
0286   vecMaterials.push_back("G4_Pb");
0287 
0288   const G4int numProjectiles = vecProjectiles.size();
0289   const G4int numMaterials = vecMaterials.size();
0290 
0291   G4cout << G4endl << "=================  Configuration ==================" << G4endl
0292          << "Model: " << namePhysics << G4endl << "Ekin: [ " << minEnergy / CLHEP::GeV << " , "
0293          << maxEnergy / CLHEP::GeV << " ] GeV" << G4endl
0294          << "Number of collisions:  " << numCollisions << G4endl
0295          << "Number of hadron projectiles: " << numProjectiles << G4endl
0296          << "Number of materials:   " << numMaterials << G4endl
0297          << "IsIonProjectile: " << (projectileNucleus != nullptr ? "true \t" : "false")
0298          << (projectileNucleus != nullptr ? projectileNucleus->GetParticleName() : G4String(""))
0299          << G4endl << "===================================================" << G4endl << G4endl;
0300 
0301   CLHEP::Ranlux64Engine defaultEngine(1234567, 4);
0302   CLHEP::HepRandom::setTheEngine(&defaultEngine);
0303   G4int seed = time(NULL);
0304   CLHEP::HepRandom::setTheSeed(seed);
0305   G4cout << G4endl << " Initial seed = " << seed << G4endl << G4endl;
0306 
0307   
0308   HadronicGenerator* theHadronicGenerator = new HadronicGenerator(namePhysics);
0309   
0310 
0311   if (theHadronicGenerator == nullptr) {
0312     G4cerr << "ERROR: theHadronicGenerator is NULL !" << G4endl;
0313     return 1;
0314   }
0315   else if (!theHadronicGenerator->IsPhysicsCaseSupported()) {
0316     G4cerr << "ERROR: this physics case is NOT supported !" << G4endl;
0317     return 2;
0318   }
0319 
0320   
0321   G4double rnd1, rnd2, rnd3, rnd4, rnd5, rnd6, normalization, projectileEnergy;
0322   G4VParticleChange* aChange = nullptr;
0323   for (G4int i = 0; i < numCollisions; ++i) {
0324     
0325     
0326     rnd1 = CLHEP::HepRandom::getTheEngine()->flat();
0327     rnd2 = CLHEP::HepRandom::getTheEngine()->flat();
0328     rnd3 = CLHEP::HepRandom::getTheEngine()->flat();
0329     rnd4 = CLHEP::HepRandom::getTheEngine()->flat();
0330     rnd5 = CLHEP::HepRandom::getTheEngine()->flat();
0331     rnd6 = CLHEP::HepRandom::getTheEngine()->flat();
0332     
0333     projectileEnergy = minEnergy + rnd1 * (maxEnergy - minEnergy);
0334     if (projectileEnergy <= 0.0) projectileEnergy = minEnergy;
0335     
0336     normalization = 1.0 / std::sqrt(rnd2 * rnd2 + rnd3 * rnd3 + rnd4 * rnd4);
0337     const G4bool isOnSmearingDirection = true;  
0338     G4ThreeVector aDirection = G4ThreeVector(0.0, 0.0, 1.0);  
0339     if (isOnSmearingDirection) {
0340       aDirection = G4ThreeVector(normalization * rnd2, normalization * rnd3, normalization * rnd4);
0341     }
0342     
0343     G4int index_projectile = std::trunc(rnd5 * numProjectiles);
0344     G4String nameProjectile = vecProjectiles[index_projectile];
0345     G4ParticleDefinition* projectile = partTable->FindParticle(nameProjectile);
0346     if (projectileNucleus) {
0347       nameProjectile = projectileNucleus->GetParticleName();
0348       projectile = projectileNucleus;
0349     }
0350     
0351     
0352     G4int index_material = std::trunc(rnd6 * numMaterials);
0353     G4String nameMaterial = vecMaterials[index_material];
0354     G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(nameMaterial);
0355     if (material == nullptr) {
0356       G4cerr << "ERROR: Material " << nameMaterial << " is not found !" << G4endl;
0357       return 3;
0358     }
0359     if (isPrintingEnabled) {
0360       G4cout << "\t Collision " << i << " ; projectile=" << nameProjectile;
0361       if (projectileNucleus) {
0362         G4cout << " ; Ekin[MeV]/nucleon="
0363                << projectileEnergy
0364                     / static_cast<G4double>(std::abs(projectileNucleus->GetBaryonNumber()));
0365       }
0366       else {
0367         G4cout << " ; Ekin[MeV]=" << projectileEnergy;
0368       }
0369       G4cout << " ; direction=" << aDirection << " ; material=" << nameMaterial;
0370     }
0371 
0372     
0373     aChange = theHadronicGenerator->GenerateInteraction(
0374       projectile, projectileEnergy,
0375        aDirection, material);
0376 
0377     G4int nsec = aChange ? aChange->GetNumberOfSecondaries() : 0;
0378     G4bool isPrintingOfSecondariesEnabled = false;
0379     if (isPrintingEnabled) {
0380       G4cout << G4endl << "\t --> #secondaries=" << nsec
0381              << " ; impactParameter[fm]=" << theHadronicGenerator->GetImpactParameter() / fermi
0382              << " ; #projectileSpectatorNucleons="
0383              << theHadronicGenerator->GetNumberOfProjectileSpectatorNucleons()
0384              << " ; #targetSpectatorNucleons="
0385              << theHadronicGenerator->GetNumberOfTargetSpectatorNucleons()
0386              << " ; #NNcollisions=" << theHadronicGenerator->GetNumberOfNNcollisions() << G4endl;
0387       if (i % printingGap == 0) {
0388         isPrintingOfSecondariesEnabled = true;
0389         G4cout << "\t \t List of produced secondaries: " << G4endl;
0390       }
0391     }
0392     
0393     for (G4int j = 0; j < nsec; ++j) {
0394       const G4DynamicParticle* sec = aChange->GetSecondary(j)->GetDynamicParticle();
0395       if (isPrintingOfSecondariesEnabled) {
0396         G4cout << "\t \t \t j=" << j << "\t" << sec->GetDefinition()->GetParticleName()
0397                << "\t p=" << sec->Get4Momentum() << " MeV" << G4endl;
0398       }
0399       delete aChange->GetSecondary(j);
0400     }
0401     if (aChange) aChange->Clear();
0402   }
0403 
0404   G4cout << G4endl << " Final random number = " << CLHEP::HepRandom::getTheEngine()->flat()
0405          << G4endl << "=== End of test ===" << G4endl;
0406 }
0407 
0408