IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 08b452c4 authored by Felix Riehn's avatar Felix Riehn
Browse files

moved target sampling to DoInteraction, calculate interaction length from...

moved target sampling to DoInteraction, calculate interaction length from weighted production cross section in GetInteractionLength
parent 6ac477d7
No related branches found
No related tags found
1 merge request!55Resolve "use target composition from environment in sibyll interface"
...@@ -211,13 +211,15 @@ int main() { ...@@ -211,13 +211,15 @@ int main() {
Point{env.GetCoordinateSystem(), 0_m, 0_m, 0_m}, Point{env.GetCoordinateSystem(), 0_m, 0_m, 0_m},
1_km * std::numeric_limits<double>::infinity()); 1_km * std::numeric_limits<double>::infinity());
// fraction of oxygen
const float fox = 0.20946;
using MyHomogeneousModel = using MyHomogeneousModel =
corsika::environment::HomogeneousMedium<corsika::environment::IMediumModel>; corsika::environment::HomogeneousMedium<corsika::environment::IMediumModel>;
theMedium->SetModelProperties<MyHomogeneousModel>( theMedium->SetModelProperties<MyHomogeneousModel>(
1_kg / (1_m * 1_m * 1_m), 1_kg / (1_m * 1_m * 1_m),
corsika::environment::NuclearComposition( corsika::environment::NuclearComposition(
std::vector<corsika::particles::Code>{corsika::particles::Code::Nitrogen,corsika::particles::Code::Oxygen,corsika::particles::Code::Proton}, std::vector<corsika::particles::Code>{corsika::particles::Code::Nitrogen,corsika::particles::Code::Oxygen},
std::vector<float>{0.5,0.3,0.2})); std::vector<float>{(float)1.-fox, fox}));
universe.AddChild(std::move(theMedium)); universe.AddChild(std::move(theMedium));
......
...@@ -30,7 +30,6 @@ namespace corsika::process::sibyll { ...@@ -30,7 +30,6 @@ namespace corsika::process::sibyll {
int fCount = 0; int fCount = 0;
int fNucCount = 0; int fNucCount = 0;
int kTarget = 0;
public: public:
Interaction(corsika::environment::Environment const& env) : fEnvironment(env) { } Interaction(corsika::environment::Environment const& env) : fEnvironment(env) { }
~Interaction() { ~Interaction() {
...@@ -70,54 +69,6 @@ namespace corsika::process::sibyll { ...@@ -70,54 +69,6 @@ namespace corsika::process::sibyll {
// read from cross section code table // read from cross section code table
const int kBeam = process::sibyll::GetSibyllXSCode(corsikaBeamId); const int kBeam = process::sibyll::GetSibyllXSCode(corsikaBeamId);
const bool kInteraction = process::sibyll::CanInteract(corsikaBeamId); const bool kInteraction = process::sibyll::CanInteract(corsikaBeamId);
// get target from environment
/*
the target should be defined by the Environment,
ideally as full particle object so that the four momenta
and the boosts can be defined..
*/
const auto currentNode = fEnvironment.GetUniverse()->GetContainingNode(p.GetPosition());
const auto sample_target = [](const corsika::environment::NuclearComposition& comp)
{
double prev =0.;
std::vector<float> cumFrac;
for (auto f: comp.GetFractions()){
cumFrac.push_back(prev+f);
prev = cumFrac.back();
}
int a = 1;
const double r = s_rndm_(a);
int i = -1;
//cout << "rndm: " << r << endl;
for (auto cf: cumFrac){
++i;
//cout << "cf: " << cf << " " << comp.GetComponents()[i] << endl;
if(r<cf) break;
}
return comp.GetComponents()[i];
};
const auto compo = currentNode->GetModelProperties().GetNuclearComposition();
for (auto tid: compo.GetComponents()){
cout << "Interaction: possible targets: " << tid << endl;
}
const auto tg = sample_target( compo );
cout << "Interaction: target selected: " << tg << endl;
// test if valid in sibyll
// FOR NOW: throw error if not, may need workaround for atmosphere, contains small argon fraction
if(IsNucleus(tg))
kTarget = GetNucleusA(tg);
else
if(tg==corsika::particles::Proton::GetCode())
kTarget = 1;
else
throw std::runtime_error("Sibyll target particle unknown. Only nuclei with A<18 or protons are allowed.");
cout << "Interaction: kTarget: " << kTarget << endl;
// redundant check
if(kTarget>18||kTarget==0)
throw std::runtime_error("Sibyll target outside range. Only nuclei with A<18 are allowed.");
const HEPMassType nucleon_mass = 0.5 * (corsika::particles::Proton::GetMass() + const HEPMassType nucleon_mass = 0.5 * (corsika::particles::Proton::GetMass() +
corsika::particles::Neutron::GetMass()); corsika::particles::Neutron::GetMass());
...@@ -138,31 +89,66 @@ namespace corsika::process::sibyll { ...@@ -138,31 +89,66 @@ namespace corsika::process::sibyll {
<< " input energy: " << Elab / 1_GeV << endl << " input energy: " << Elab / 1_GeV << endl
<< " beam can interact:" << kBeam << endl << " beam can interact:" << kBeam << endl
<< " beam XS code:" << kBeam << endl << " beam XS code:" << kBeam << endl
<< " beam pid:" << p.GetPID() << endl << " beam pid:" << p.GetPID() << endl;
<< " target mass number:" << kTarget << std::endl;
if (kInteraction && Elab >= 8.5_GeV && sqs >= 10_GeV) { if (kInteraction && Elab >= 8.5_GeV && sqs >= 10_GeV) {
double prodCrossSection, dummy, dum1, dum2, dum3, dum4; // get target from environment
double dumdif[3]; /*
the target should be defined by the Environment,
if (kTarget == 1) ideally as full particle object so that the four momenta
sib_sigma_hp_(kBeam, Ecm, dum1, dum2, prodCrossSection, dumdif, dum3, dum4); and the boosts can be defined..
else */
sib_sigma_hnuc_(kBeam, kTarget, Ecm, prodCrossSection, dummy); const auto currentNode = fEnvironment.GetUniverse()->GetContainingNode(p.GetPosition());
const auto mediumComposition = currentNode->GetModelProperties().GetNuclearComposition();
std::cout << "Interaction: " // determine average interaction length
<< "MinStep: sibyll return: " << prodCrossSection << std::endl; // FOR NOW: weighted sum
si::CrossSectionType sig = prodCrossSection * 1_mbarn; int i =-1;
std::cout << "Interaction: " double avgTargetMassNumber = 0.;
<< "MinStep: CrossSection (mb): " << sig / 1_mbarn << std::endl; si::CrossSectionType weightedProdCrossSection = 0_mbarn;
int kTarget = 0;
std::cout << "Interaction: " // get weights of components from environment/medium
<< "nucleon mass " << nucleon_mass << std::endl; const auto w = mediumComposition.GetFractions();
// calculate interaction length in medium // loop over components in medium
GrammageType int_length = kTarget * corsika::units::constants::u / sig; for (auto targetId: mediumComposition.GetComponents() ){
std::cout << "Interaction: " i++;
<< "interaction length (g/cm2): " << int_length << std::endl; cout << "Interaction: get interaction lenght for target: " << targetId << endl;
if(IsNucleus(targetId))
kTarget = GetNucleusA(targetId);
else
if(targetId==corsika::particles::Proton::GetCode())
kTarget = 1;
else
throw std::runtime_error("GetInteractionLength: Sibyll target particle unknown. Only nuclei or protons are allowed.");
cout << "Interaction: kTarget: " << kTarget << endl;
// check if nuclei in range
if(kTarget>18||kTarget==0)
throw std::runtime_error("Sibyll target outside range. Only nuclei with A<18 are allowed.");
// get cross section from sibyll
double sigProd, dummy, dum1, dum2, dum3, dum4;
double dumdif[3];
if (kTarget == 1)
sib_sigma_hp_(kBeam, Ecm, dum1, dum2, sigProd, dumdif, dum3, dum4);
else
sib_sigma_hnuc_(kBeam, kTarget, Ecm, sigProd, dummy);
std::cout << "Interaction: "
<< " IntLength: sibyll return: " << sigProd << std::endl;
weightedProdCrossSection += w[i] * sigProd * 1_mbarn;
avgTargetMassNumber += w[i] * kTarget;
}
cout << "Interaction: "
<< "IntLength: weighted CrossSection (mb): " << weightedProdCrossSection / 1_mbarn
<< endl;
// calculate interaction length in medium
#warning check interaction length units
GrammageType int_length = avgTargetMassNumber * corsika::units::constants::u / weightedProdCrossSection;
std::cout << "Interaction: "
<< "interaction length (g/cm2): " << int_length / ( 0.001_kg ) * 1_cm * 1_cm << std::endl;
return int_length; return int_length;
} }
...@@ -215,10 +201,41 @@ namespace corsika::process::sibyll { ...@@ -215,10 +201,41 @@ namespace corsika::process::sibyll {
const CoordinateSystem tempCS = rootCS.rotate(zAxis, phi); const CoordinateSystem tempCS = rootCS.rotate(zAxis, phi);
const CoordinateSystem sibyllCS = tempCS.rotate(yAxis, theta); const CoordinateSystem sibyllCS = tempCS.rotate(yAxis, theta);
const auto sample_target = [](const corsika::environment::NuclearComposition& comp)
// redundant check if target code is valid {
if(kTarget>18||kTarget==0) double prev =0.;
throw std::runtime_error("Interaction: Sibyll target outside range. Only nuclei with A<18 are allowed."); std::vector<float> cumFrac;
for (auto f: comp.GetFractions()){
cumFrac.push_back(prev+f);
prev = cumFrac.back();
}
int a = 1;
const double r = s_rndm_(a);
int i = -1;
//cout << "rndm: " << r << endl;
for (auto cf: cumFrac){
++i;
//cout << "cf: " << cf << " " << comp.GetComponents()[i] << endl;
if(r<cf) break;
}
return comp.GetComponents()[i];
};
const auto currentNode = fEnvironment.GetUniverse()->GetContainingNode(p.GetPosition());
const auto mediumComposition = currentNode->GetModelProperties().GetNuclearComposition();
const auto tg = sample_target( mediumComposition );
cout << "Interaction: target selected: " << tg << endl;
// test if valid in sibyll
// FOR NOW: throw error if not, may need workaround for atmosphere, contains small argon fraction
int kTarget = 0;
if(IsNucleus(tg))
kTarget = GetNucleusA(tg);
else
if(tg==corsika::particles::Proton::GetCode())
kTarget = 1;
else
throw std::runtime_error("Sibyll target particle unknown. Only nuclei with A<18 or protons are allowed.");
// FOR NOW: target is always at rest // FOR NOW: target is always at rest
auto constexpr nucleon_mass = 0.5 * (corsika::particles::Proton::GetMass() + auto constexpr nucleon_mass = 0.5 * (corsika::particles::Proton::GetMass() +
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment