IAP GITLAB

Skip to content
Snippets Groups Projects

Sibyll

Merged Ralf Ulrich requested to merge sibyll into master
2 files
+ 222
114
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -24,6 +24,7 @@
@@ -24,6 +24,7 @@
#include <corsika/process/sibyll/ParticleConversion.h>
#include <corsika/process/sibyll/ParticleConversion.h>
#include <corsika/units/PhysicalUnits.h>
#include <corsika/units/PhysicalUnits.h>
 
using namespace corsika;
using namespace corsika;
using namespace corsika::process;
using namespace corsika::process;
using namespace corsika::units;
using namespace corsika::units;
@@ -43,46 +44,59 @@ public:
@@ -43,46 +44,59 @@ public:
template <typename Particle>
template <typename Particle>
double MinStepLength(Particle& p, setup::Trajectory&) const {
double MinStepLength(Particle& p, setup::Trajectory&) const {
 
const Code corsikaBeamId = p.GetPID();
 
// beam particles for sibyll : 1, 2, 3 for p, pi, k
// beam particles for sibyll : 1, 2, 3 for p, pi, k
// read from cross section code table
// read from cross section code table
int kBeam = 1;
int kBeam = process::sibyll::GetSibyllXSCode( corsikaBeamId );
/*
bool kInteraction = process::sibyll::CanInteract( corsikaBeamId );
 
 
/*
the target should be defined by the Environment,
the target should be defined by the Environment,
ideally as full particle object so that the four momenta
ideally as full particle object so that the four momenta
and the boosts can be defined..
and the boosts can be defined..
*/
*/
// target nuclei: A < 18
// target nuclei: A < 18
// FOR NOW: assume target is oxygen
// FOR NOW: assume target is oxygen
int kTarget = 1;
int kTarget = 16;
double beamEnergy = p.GetEnergy() / 1_GeV;
double beamEnergy = p.GetEnergy() / 1_GeV;
std::cout << "ProcessSplit: "
#warning boost to cm. still missing, sibyll cross section input is cm. energy!
<< "MinStep: en: " << beamEnergy << " pid:" << kBeam << std::endl;
double prodCrossSection, dummy, dum1, dum2, dum3, dum4;
std::cout << "ProcessSplit: " << "MinStep: input en: " << beamEnergy
double dumdif[3];
<< " beam can interact:" << kBeam
<< " beam XS code:" << kBeam
if (kTarget == 1)
<< " beam pid:" << p.GetPID()
sib_sigma_hp_(kBeam, beamEnergy, dum1, dum2, prodCrossSection, dumdif, dum3, dum4);
<< " target mass number:" << kTarget << std::endl;
else
sib_sigma_hnuc_(kBeam, kTarget, beamEnergy, prodCrossSection, dummy);
double next_step;
if(kInteraction){
std::cout << "ProcessSplit: "
<< "MinStep: sibyll return: " << prodCrossSection << std::endl;
double prodCrossSection,dummy,dum1,dum2,dum3,dum4;
CrossSectionType sig = prodCrossSection * 1_mbarn;
double dumdif[3];
std::cout << "ProcessSplit: "
<< "MinStep: CrossSection (mb): " << sig / 1_mbarn << std::endl;
if(kTarget==1)
sib_sigma_hp_(kBeam, beamEnergy, dum1, dum2, prodCrossSection, dumdif,dum3, dum4 );
const MassType nucleon_mass = 0.93827_GeV / corsika::units::si::constants::cSquared;
else
std::cout << "ProcessSplit: "
sib_sigma_hnuc_(kBeam, kTarget, beamEnergy, prodCrossSection, dummy );
<< "nucleon mass " << nucleon_mass << std::endl;
// calculate interaction length in medium
std::cout << "ProcessSplit: " << "MinStep: sibyll return: " << prodCrossSection << std::endl;
double int_length = kTarget * (nucleon_mass / 1_g) / (sig / 1_cmeter / 1_cmeter);
CrossSectionType sig = prodCrossSection * 1_mbarn;
// pick random step lenth
std::cout << "ProcessSplit: " << "MinStep: CrossSection (mb): " << sig / 1_mbarn << std::endl;
std::cout << "ProcessSplit: "
<< "interaction length (g/cm2): " << int_length << std::endl;
const MassType nucleon_mass = 0.93827_GeV / corsika::units::si::constants::cSquared;
// add exponential sampling
std::cout << "ProcessSplit: " << "nucleon mass " << nucleon_mass << std::endl;
int a = 0;
// calculate interaction length in medium
const double next_step = -int_length * log(s_rndm_(a));
double int_length = kTarget * ( nucleon_mass / 1_g ) / ( sig / 1_cmeter / 1_cmeter );
 
// pick random step lenth
 
std::cout << "ProcessSplit: " << "interaction length (g/cm2): " << int_length << std::endl;
 
// add exponential sampling
 
int a = 0;
 
next_step = -int_length * log(s_rndm_(a));
 
}else
 
#warning define infinite interaction length? then we can skip the test in DoDiscrete()
 
next_step = 1.e8;
 
/*
/*
what are the units of the output? slant depth or 3space length?
what are the units of the output? slant depth or 3space length?
@@ -93,86 +107,154 @@ public:
@@ -93,86 +107,154 @@ public:
}
}
template <typename Particle, typename Stack>
template <typename Particle, typename Stack>
EProcessReturn DoContinuous(Particle&, Trajectory&, Stack&) const {
EProcessReturn DoContinuous(Particle&, setup::Trajectory&, Stack&) const {
// corsika::utls::ignore(p);
// corsika::utls::ignore(p);
return EProcessReturn::eOk;
return EProcessReturn::eOk;
}
}
template <typename Particle, typename Stack>
template <typename Particle, typename Stack>
void DoDiscrete(Particle& p, Stack& s) const {
void DoDiscrete(Particle& p, Stack& s) const {
cout << "DoDiscrete: " << p.GetPID() << " interaction? "
cout << "DoDiscrete: " << p.GetPID() << " interaction? " << process::sibyll::CanInteract( p.GetPID() ) << endl;
<< process::sibyll::CanInteract(p.GetPID()) << endl;
if( process::sibyll::CanInteract( p.GetPID() ) ){
if (process::sibyll::CanInteract(p.GetPID())) {
cout << "defining coordinates" << endl;
// coordinate system, get global frame of reference
 
CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
 
 
QuantityVector<length_d> const coordinates{0_m, 0_m, 0_m};
 
Point pOrig(rootCS, coordinates);
 
 
/*
 
the target should be defined by the Environment,
 
ideally as full particle object so that the four momenta
 
and the boosts can be defined..
 
 
here we need: GetTargetMassNumber() or GetTargetPID()??
 
GetTargetMomentum() (zero in EAS)
 
*/
 
// FOR NOW: set target to proton
 
int kTarget = 1; //p.GetPID();
 
 
// proton mass in units of energy
 
const EnergyType proton_mass_en = 0.93827_GeV ; //0.93827_GeV / si::constants::cSquared ;
 
 
cout << "defining target momentum.." << endl;
 
// FOR NOW: target is always at rest
 
const EnergyType Etarget = 0. * 1_GeV + proton_mass_en;
 
const auto pTarget = super_stupid::MomentumVector(rootCS, 0. * 1_GeV / si::constants::c, 0. * 1_GeV / si::constants::c, 0. * 1_GeV / si::constants::c);
 
cout << "target momentum (GeV/c): " << pTarget.GetComponents() / 1_GeV * si::constants::c << endl;
 
// const auto pBeam = super_stupid::MomentumVector(rootCS, 0. * 1_GeV / si::constants::c, 0. * 1_GeV / si::constants::c, 0. * 1_GeV / si::constants::c);
 
// cout << "beam momentum: " << pBeam.GetComponents() << endl;
 
cout << "beam momentum (GeV/c): " << p.GetMomentum().GetComponents() / 1_GeV * si::constants::c << endl;
 
// get energy of particle from stack
// get energy of particle from stack
/*
/*
stack is in GeV in lab. frame
stack is in GeV in lab. frame
convert to GeV in cm. frame
convert to GeV in cm. frame
(assuming proton at rest as target AND
(assuming proton at rest as target AND
assuming no pT, i.e. shower frame-z is aligned with hadron-int-frame-z)
assuming no pT, i.e. shower frame-z is aligned with hadron-int-frame-z)
*/
*/
EnergyType E = p.GetEnergy();
// cout << "defining total energy" << endl;
EnergyType Ecm = sqrt(2. * E * 0.93827_GeV);
// total energy: E_beam + E_target
// in lab. frame: E_beam + m_target*c**2
int kBeam = process::sibyll::ConvertToSibyllRaw(p.GetPID());
EnergyType E = p.GetEnergy();
 
EnergyType Etot = E + Etarget;
 
// cout << "tot. energy: " << Etot / 1_GeV << endl;
 
// cout << "defining total momentum" << endl;
 
// total momentum
 
super_stupid::MomentumVector Ptot = p.GetMomentum(); // + pTarget;
 
// cout << "tot. momentum: " << Ptot.GetComponents() / 1_GeV * si::constants::c << endl;
 
// cout << "inv. mass.." << endl;
 
// invariant mass, i.e. cm. energy
 
EnergyType Ecm = sqrt( Etot * Etot - Ptot.squaredNorm() * si::constants::cSquared ); //sqrt( 2. * E * 0.93827_GeV );
 
// cout << "inv. mass: " << Ecm / 1_GeV << endl;
 
// cout << "boost parameters.." << endl;
 
/*
 
get transformation between Stack-frame and SibStack-frame
 
for EAS Stack-frame is lab. frame, could be different for CRMC-mode
 
the transformation should be derived from the input momenta
 
*/
 
// const double gamma = ( E + proton_mass * si::constants::cSquared ) / Ecm ;
 
// const double gambet = sqrt( E * E - proton_mass * proton_mass ) / Ecm;
 
const double gamma = Etot / Ecm ;
 
const auto gambet = Ptot / (Ecm / si::constants::c );
 
 
std::cout << "ProcessSplit: " << " DoDiscrete: gamma:" << gamma << endl;
 
std::cout << "ProcessSplit: " << " DoDiscrete: gambet:" << gambet.GetComponents() << endl;
 
 
int kBeam = process::sibyll::ConvertToSibyllRaw( p.GetPID() );
 
 
 
std::cout << "ProcessSplit: " << " DoDiscrete: E(GeV):" << E / 1_GeV << " Ecm(GeV): " << Ecm / 1_GeV << std::endl;
 
if (E < 8.5_GeV || Ecm < 10_GeV ) {
 
std::cout << "ProcessSplit: " << " DoDiscrete: dropping particle.." << std::endl;
 
p.Delete();
 
fCount++;
 
} else {
 
// Sibyll does not know about units..
 
double sqs = Ecm / 1_GeV;
 
// running sibyll, filling stack
 
sibyll_( kBeam, kTarget, sqs);
 
// running decays
 
//decsib_();
 
// print final state
 
int print_unit = 6;
 
sib_list_( print_unit );
 
 
// delete current particle
 
p.Delete();
/*
// add particles from sibyll to stack
the target should be defined by the Environment,
// link to sibyll stack
ideally as full particle object so that the four momenta
SibStack ss;
and the boosts can be defined..
*/
// SibStack does not know about momentum yet so we need counter to access momentum array in Sibyll
// FOR NOW: set target to proton
int i = -1;
int kTarget = 1; // p.GetPID();
super_stupid::MomentumVector Ptot_final(rootCS, {0.0_newton_second, 0.0_newton_second, 0.0_newton_second});
for (auto &psib: ss){
std::cout << "ProcessSplit: "
++i;
<< " DoDiscrete: E(GeV):" << E / 1_GeV << " Ecm(GeV): " << Ecm / 1_GeV
//transform energy to lab. frame, primitve
<< std::endl;
// compute beta_vec * p_vec
if (E < 8.5_GeV || Ecm < 10_GeV) {
// arbitrary Lorentz transformation based on sibyll routines
std::cout << "ProcessSplit: "
const auto gammaBetaComponents = gambet.GetComponents();
<< " DoDiscrete: dropping particle.." << std::endl;
const auto pSibyllComponents = psib.GetMomentum().GetComponents();
p.Delete();
EnergyType en_lab = 0. * 1_GeV;
fCount++;
MomentumType p_lab_components[3];
} else {
en_lab = psib.GetEnergy() * gamma;
// Sibyll does not know about units..
EnergyType pnorm = 0. * 1_GeV;
double sqs = Ecm / 1_GeV;
for(int j=0; j<3; ++j)
// running sibyll, filling stack
pnorm += ( pSibyllComponents[j] * gammaBetaComponents[j] * si::constants::c ) / ( gamma + 1.);
sibyll_(kBeam, kTarget, sqs);
pnorm += psib.GetEnergy();
// running decays
// decsib_();
for(int j=0; j<3; ++j){
// print final state
p_lab_components[j] = pSibyllComponents[j] - (-1) * pnorm * gammaBetaComponents[j] / si::constants::c;
int print_unit = 6;
// cout << "p:" << j << " pSib (GeV/c): " << pSibyllComponents[j] / 1_GeV * si::constants::c
sib_list_(print_unit);
// << " gb: " << gammaBetaComponents[j] << endl;
en_lab -= (-1) * pSibyllComponents[j] * gammaBetaComponents[j] * si::constants::c;
// delete current particle
}
p.Delete();
// const EnergyType en_lab = psib.GetEnergy()*gamma + gambet * psib.GetMomentum() * si::constants::c );
// cout << " en cm (GeV): " << psib.GetEnergy() / 1_GeV << endl
// add particles from sibyll to stack
// << " en lab (GeV): " << en_lab / 1_GeV << endl;
// link to sibyll stack
// cout << " pz cm (GeV/c): " << psib.GetMomentum().GetComponents()[2] / 1_GeV * si::constants::c << endl
SibStack ss;
// << " pz lab (GeV/c): " << p_lab_components[2] / 1_GeV * si::constants::c << endl;
/*
get transformation between Stack-frame and SibStack-frame
// add to corsika stack
for EAS Stack-frame is lab. frame, could be different for CRMC-mode
auto pnew = s.NewParticle();
the transformation should be derived from the input momenta
pnew.SetEnergy( en_lab );
in general transformation is rotation + boost
pnew.SetPID( process::sibyll::ConvertFromSibyll( psib.GetPID() ) );
*/
//cout << "momentum sib (cm): " << psib.GetMomentum().GetComponents() / 1_GeV * si::constants::c << endl;
const EnergyType proton_mass = 0.93827_GeV;
const double gamma = (E + proton_mass) / (Ecm);
corsika::geometry::QuantityVector<momentum_d> p_lab_c{ p_lab_components[0],
const double gambet = sqrt(E * E - proton_mass * proton_mass) / Ecm;
p_lab_components[1],
p_lab_components[2]};
// SibStack does not know about momentum yet so we need counter to access momentum
pnew.SetMomentum( super_stupid::MomentumVector( rootCS, p_lab_c) );
// array in Sibyll
//cout << "momentum sib (lab): " << pnew.GetMomentum().GetComponents() / 1_GeV * si::constants::c << endl;
int i = -1;
//cout << "s_cm (GeV2): " << (psib.GetEnergy() * psib.GetEnergy() - psib.GetMomentum().squaredNorm() * si::constants::cSquared ) / 1_GeV / 1_GeV << endl;
for (auto& p : ss) {
//cout << "s_lab (GeV2): " << (pnew.GetEnergy() * pnew.GetEnergy() - pnew.GetMomentum().squaredNorm() * si::constants::cSquared ) / 1_GeV / 1_GeV << endl;
++i;
Ptot_final += pnew.GetMomentum();
// transform to lab. frame, primitve
const double en_lab = gambet * s_plist_.p[2][i] + gamma * p.GetEnergy();
// add to corsika stack
auto pnew = s.NewParticle();
pnew.SetEnergy(en_lab * 1_GeV);
pnew.SetPID(process::sibyll::ConvertFromSibyll(p.GetPID()));
}
}
}
} else
//cout << "tot. momentum final (GeV/c): " << Ptot_final.GetComponents() / 1_GeV * si::constants::c << endl;
 
}
 
}else
p.Delete();
p.Delete();
}
}
@@ -238,6 +320,8 @@ double s_rndm_(int&) {
@@ -238,6 +320,8 @@ double s_rndm_(int&) {
int main() {
int main() {
 
CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
 
tracking_line::TrackingLine<setup::Stack> tracking;
tracking_line::TrackingLine<setup::Stack> tracking;
stack_inspector::StackInspector<setup::Stack> p0(true);
stack_inspector::StackInspector<setup::Stack> p0(true);
ProcessSplit p1;
ProcessSplit p1;
@@ -248,9 +332,15 @@ int main() {
@@ -248,9 +332,15 @@ int main() {
stack.Clear();
stack.Clear();
auto particle = stack.NewParticle();
auto particle = stack.NewParticle();
EnergyType E0 = 100_GeV;
EnergyType E0 = 500_GeV;
 
MomentumType P0 = sqrt( E0*E0 - 0.93827_GeV * 0.93827_GeV ) / si::constants::c;
 
auto plab = super_stupid::MomentumVector(rootCS,
 
0. * 1_GeV / si::constants::c,
 
0. * 1_GeV / si::constants::c,
 
P0);
particle.SetEnergy(E0);
particle.SetEnergy(E0);
particle.SetPID(Code::Proton);
particle.SetMomentum(plab);
 
particle.SetPID( Code::Proton );
EAS.Init();
EAS.Init();
EAS.Run();
EAS.Run();
cout << "Result: E0=" << E0 / 1_GeV << "GeV, count=" << p1.GetCount() << endl;
cout << "Result: E0=" << E0 / 1_GeV << "GeV, count=" << p1.GetCount() << endl;
Loading