diff --git a/Processes/Sibyll/NuclearInteraction.cc b/Processes/Sibyll/NuclearInteraction.cc index 64013f05468b0d0aea1a776f1dd75aa21ae65800..4b944a48597ab940de8f357a43971eae50fd206f 100644 --- a/Processes/Sibyll/NuclearInteraction.cc +++ b/Processes/Sibyll/NuclearInteraction.cc @@ -41,6 +41,7 @@ namespace corsika::process::sibyll { NuclearInteraction::~NuclearInteraction() { cout << "Nuclib::NuclearInteraction n=" << fCount << " Nnuc=" << fNucCount << endl; + fTargetComponentsIndex.clear(); } void NuclearInteraction::Init() { @@ -67,10 +68,8 @@ namespace corsika::process::sibyll { // now: hard coded list for air constexpr Code target_nuclei[] = { Code::Oxygen, Code::Nitrogen }; - int fNSample = 500; // number of samples in MC estimation of cross section - cout << "NuclearInteraction: initializing nuclear cross sections..." << endl; - + // loop over target components, at most 4!! int k =-1; for(auto &ptarg: target_nuclei){ @@ -78,7 +77,7 @@ namespace corsika::process::sibyll { cout << "NuclearInteraction: init target component: " << ptarg << endl; const int ib = GetNucleusA( ptarg ); // fill map,list or what ever - // TODO + fTargetComponentsIndex.insert( std::pair<Code,int>(ptarg, k) ); // loop over energies, 6 log. energy bins for(int i=0; i<6; ++i){ // hard coded energy grid, has to be aligned to definition in signuc2!!, no comment.. @@ -89,71 +88,70 @@ namespace corsika::process::sibyll { fHadronicInteraction.GetCrossSection(protonId, protonId, Ecm); const double dsig = siginel / 1_mbarn; const double dsigela = sigela / 1_mbarn; - // loop over projectiles - for(int j=0; j<56; ++j){ + // loop over projectiles, mass numbers from 2 to 56 + for(int j=1; j<56; ++j){ const int jj = j+1; double sig_out, dsig_out, sigqe_out, dsigqe_out; - // cout << "energy="<< Ecm/1_GeV << " sig_pp=" << dsig - // << " (A,B)=" << jj << "," << ib - // << " sig="<<sig_out << " err(%)=" << dsig_out/sig_out*100. - // << endl; - sigma_mc_(jj,ib,dsig,dsigela,fNSample, sig_out, dsig_out, sigqe_out, dsigqe_out); + sigma_mc_(jj,ib,dsig,dsigela,fNSample,sig_out,dsig_out,sigqe_out,dsigqe_out); // write to table cnucsignuc_.sigma[j][k][i] = sig_out; cnucsignuc_.sigqe[j][k][i] = sigqe_out; } } } - cout << "NuclearInteraction: cross sections initialized!" << endl; - PrintCrossSectionTable(0); - PrintCrossSectionTable(1); - PrintCrossSectionTable(2); - throw std::runtime_error("stop here"); + cout << "NuclearInteraction: cross sections for " << fTargetComponentsIndex.size() << " components initialized!" << endl; + for(auto &ptarg: target_nuclei){ + cout << "cross section table: " << ptarg << endl; + PrintCrossSectionTable( ptarg ); + } + } - void NuclearInteraction::PrintCrossSectionTable(int k) + void NuclearInteraction::PrintCrossSectionTable( corsika::particles::Code pCode) { - int nuclA [] = {2,4,8,20,35,56}; + using namespace corsika::particles; + const int k = fTargetComponentsIndex.at( pCode ); + Code pNuclei [] = {Code::Helium, Code::Lithium7, Code::Oxygen, Code::Neon, Code::Argon, Code::Iron}; cout << "en/A "; - for(int j=0; j<6; ++j) - cout << std::setw(8) << nuclA[j]; + for(auto &j: pNuclei) + cout << std::setw(9) << j; cout << endl; for(int i=0; i<6; ++i){ cout << " " << i << " "; - for(int j=0; j<6; ++j){ - cout << " " << std::setprecision(5) << std::setw(7) << cnucsignuc_.sigma[nuclA[j]-1][k][i]; + for(auto &n: pNuclei){ + auto const j= GetNucleusA( n ); + cout << " " << std::setprecision(5) << std::setw(8) << cnucsignuc_.sigma[j-1][k][i]; } cout << endl; } } - units::si::CrossSectionType NuclearInteraction::ReadCrossSectionTable(particles::Code pBeam, particles::Code pTarget, units::si::HEPEnergyType elabnuc) + units::si::CrossSectionType NuclearInteraction::ReadCrossSectionTable(const int ia, particles::Code pTarget, units::si::HEPEnergyType elabnuc) { using namespace corsika::particles; using namespace units::si; - const int ia = GetNucleusA(pBeam); - const int ib = GetNucleusA(pTarget); - const double e0 = elabnuc/ 1_GeV; + const int ib = fTargetComponentsIndex.at( pTarget )+1; // table index in fortran + const double e0 = elabnuc / 1_GeV; double sig; + cout << "ReadCrossSectionTable: " << ia << " " << ib << " " << e0 << endl; signuc2_(ia,ib,e0,sig); + cout << "ReadCrossSectionTable: sig=" << sig << endl; return sig * 1_mbarn; } - // TODO: remove number of nucleons, avg target mass is available in environment + // TODO: remove elastic cross section? template <> tuple<units::si::CrossSectionType, units::si::CrossSectionType> NuclearInteraction::GetCrossSection(Particle& p, const particles::Code TargetId) { using namespace units::si; - double sigProd; - auto const pCode = p.GetPID(); - if (pCode != particles::Code::Nucleus) + if ( p.GetPID() != particles::Code::Nucleus) throw std::runtime_error( "NuclearInteraction: GetCrossSection: particle not a nucleus!"); - auto const iBeam = p.GetNuclearA(); - HEPEnergyType LabEnergyPerNuc = p.GetEnergy() / iBeam; - cout << "NuclearInteraction: GetCrossSection: called with: beamNuclA= " << iBeam + auto const iBeamA = p.GetNuclearA(); + HEPEnergyType LabEnergyPerNuc = p.GetEnergy() / iBeamA; + cout << "NuclearInteraction: GetCrossSection: called with: beamNuclA= " << iBeamA << " TargetId= " << TargetId << " LabEnergyPerNuc= " << LabEnergyPerNuc / 1_GeV << endl; @@ -161,38 +159,32 @@ namespace corsika::process::sibyll { // TODO: for now assumes air with hard coded composition // extend to arbitrary mixtures, requires smarter initialization // get nuclib projectile code: nucleon number - if (iBeam > 56 || iBeam < 2) { + if (iBeamA > 56 || iBeamA < 2) { cout << "NuclearInteraction: beam nucleus outside allowed range for NUCLIB!" << endl - << "A=" << iBeam << endl; + << "A=" << iBeamA << endl; throw std::runtime_error( "NuclearInteraction: GetCrossSection: beam nucleus outside allowed range for " "NUCLIB!"); } - const double dElabNuc = LabEnergyPerNuc / 1_GeV; // TODO: these limitations are still sibyll specific. // available target nuclei depends on the hadronic interaction model and the // initialization - if (dElabNuc < 10.) + if ( LabEnergyPerNuc < 10.0_GeV) throw std::runtime_error("NuclearInteraction: GetCrossSection: energy too low!"); // TODO: these limitations are still sibyll specific. // available target nuclei depends on the hadronic interaction model and the // initialization if (particles::IsNucleus(TargetId)) { - const int iTarget = particles::GetNucleusA(TargetId); - if (iTarget > 18 || iTarget == 0) + const int iTargetA = particles::GetNucleusA(TargetId); + if (iTargetA > 18 || iTargetA == 0) throw std::runtime_error( "Sibyll target outside range. Only nuclei with A<18 are allowed."); cout << "NuclearInteraction: calling signuc.." << endl; - cout << "WARNING: using hard coded cross section for Nucleus-Air with " - "SIBYLL! (fix me!)" - << endl; - // TODO: target id is not used because cross section is still hard coded and fixed - // to air. - signuc_(iBeam, dElabNuc, sigProd); - cout << "cross section: " << sigProd << endl; - return std::make_tuple(sigProd * 1_mbarn, 0_mbarn); + auto const sigProd = ReadCrossSectionTable( iBeamA, TargetId, LabEnergyPerNuc ); + cout << "cross section: " << sigProd / 1_mbarn << endl; + return std::make_tuple(sigProd, 0_mbarn); } return std::make_tuple(std::numeric_limits<double>::infinity() * 1_mbarn, std::numeric_limits<double>::infinity() * 1_mbarn); diff --git a/Processes/Sibyll/NuclearInteraction.h b/Processes/Sibyll/NuclearInteraction.h index 0653a0526b087220bb0792304c93787221faeb62..a2ef4abe55b4a0e62ca53c4eecedd7df81ac18fd 100644 --- a/Processes/Sibyll/NuclearInteraction.h +++ b/Processes/Sibyll/NuclearInteraction.h @@ -41,8 +41,8 @@ namespace corsika::process::sibyll { ~NuclearInteraction(); void Init(); void InitializeNuclearCrossSections(); - void PrintCrossSectionTable(int); - corsika::units::si::CrossSectionType ReadCrossSectionTable(corsika::particles::Code, corsika::particles::Code, corsika::units::si::HEPEnergyType); + void PrintCrossSectionTable(corsika::particles::Code); + corsika::units::si::CrossSectionType ReadCrossSectionTable(const int, corsika::particles::Code, corsika::units::si::HEPEnergyType); template <typename Particle> std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType> @@ -57,8 +57,10 @@ namespace corsika::process::sibyll { private: corsika::environment::Environment const& fEnvironment; corsika::process::sibyll::Interaction& fHadronicInteraction; + std::map<corsika::particles::Code,int> fTargetComponentsIndex; corsika::random::RNG& fRNG = corsika::random::RNGManager::GetInstance().GetRandomStream("s_rndm"); + const int fNSample = 500; // number of samples in MC estimation of cross section }; } // namespace corsika::process::sibyll