IAP GITLAB

Skip to content
Snippets Groups Projects
Commit def128eb authored by Nikos Karastathis's avatar Nikos Karastathis :ocean:
Browse files

first try of synchnotron radiation example (need to tweak StraightPropagator.hpp first)

parent 55dc75f4
No related branches found
No related tags found
1 merge request!329Radio interface
......@@ -6,48 +6,25 @@
* the license.
*/
/* clang-format off */
// InteractionCounter used boost/histogram, which
// fails if boost/type_traits have been included before. Thus, we have
// to include it first...
#include <corsika/framework/process/InteractionCounter.hpp>
/* clang-format on */
#include <corsika/framework/geometry/Plane.hpp>
#include <corsika/framework/geometry/Sphere.hpp>
#include <corsika/framework/core/Logging.hpp>
#include <corsika/framework/utility/SaveBoostHistogram.hpp>
#include <corsika/framework/core/Cascade.hpp>
#include <corsika/framework/process/ProcessSequence.hpp>
#include <corsika/framework/process/SwitchProcessSequence.hpp>
#include <corsika/framework/process/InteractionCounter.hpp>
#include <corsika/framework/random/RNGManager.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
#include <corsika/framework/random/RNGManager.hpp>
#include <corsika/framework/geometry/Sphere.hpp>
#include <corsika/framework/utility/CorsikaFenv.hpp>
#include <corsika/framework/core/Cascade.hpp>
#include <corsika/framework/geometry/PhysicalGeometry.hpp>
#include <corsika/framework/core/Logging.hpp>
#include <corsika/media/Environment.hpp>
#include <corsika/media/FlatExponential.hpp>
#include <corsika/media/HomogeneousMedium.hpp>
#include <corsika/media/IMagneticFieldModel.hpp>
#include <corsika/media/LayeredSphericalAtmosphereBuilder.hpp>
#include <corsika/media/NuclearComposition.hpp>
#include <corsika/media/ShowerAxis.hpp>
#include <corsika/media/MediumPropertyModel.hpp>
#include <corsika/media/UniformMagneticField.hpp>
#include <corsika/media/UniformRefractiveIndex.hpp>
#include <corsika/media/ShowerAxis.hpp>
#include <corsika/media/SlidingPlanarExponential.hpp>
#include <corsika/modules/BetheBlochPDG.hpp>
#include <corsika/modules/LongitudinalProfile.hpp>
#include <corsika/modules/ObservationPlane.hpp>
#include <corsika/modules/OnShellCheck.hpp>
#include <corsika/modules/StackInspector.hpp>
#include <corsika/modules/TrackWriter.hpp>
#include <corsika/modules/ParticleCut.hpp>
#include <corsika/modules/Pythia8.hpp>
#include <corsika/modules/Sibyll.hpp>
#include <corsika/modules/UrQMD.hpp>
#include <corsika/modules/PROPOSAL.hpp>
#include <corsika/setup/SetupEnvironment.hpp>
#include <corsika/setup/SetupStack.hpp>
#include <corsika/setup/SetupTrajectory.hpp>
#include <corsika/modules/radio/RadioProcess.hpp>
#include <corsika/modules/radio/CoREAS.hpp>
......@@ -58,14 +35,13 @@
#include <corsika/modules/radio/propagators/SignalPath.hpp>
#include <corsika/modules/radio/propagators/RadioPropagator.hpp>
#include <corsika/setup/SetupStack.hpp>
#include <corsika/setup/SetupTrajectory.hpp>
#include <iomanip>
#include <iostream>
#include <limits>
#include <string>
#include <corsika/modules/BetheBlochPDG.hpp>
#include <corsika/modules/StackInspector.hpp>
#include <corsika/modules/Sibyll.hpp>
#include <corsika/modules/ParticleCut.hpp>
#include <corsika/modules/TrackWriter.hpp>
#include <corsika/modules/HadronicElasticModel.hpp>
#include <corsika/modules/Pythia8.hpp>
/*
NOTE, WARNING, ATTENTION
......@@ -78,241 +54,127 @@
#include <corsika/modules/sibyll/Random.hpp>
#include <corsika/modules/urqmd/Random.hpp>
#include <iostream>
#include <limits>
#include <typeinfo>
using namespace corsika;
using namespace std;
using Particle = setup::Stack::particle_type;
void registerRandomStreams(const int seed) {
RNGManager::getInstance().registerRandomStream("cascade");
RNGManager::getInstance().registerRandomStream("qgsjet");
RNGManager::getInstance().registerRandomStream("sibyll");
RNGManager::getInstance().registerRandomStream("pythia");
RNGManager::getInstance().registerRandomStream("urqmd");
RNGManager::getInstance().registerRandomStream("proposal");
if (seed == 0)
RNGManager::getInstance().seedAll();
else
RNGManager::getInstance().seedAll(seed);
}
//
// The example main program for a particle cascade
//
int main() {
int main(int argc, char** argv) {
logging::set_level(logging::level::info);
corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v");
corsika_logger->set_pattern("[%n:%^%-8l%$] %s:%#: %v");
logging::set_level(logging::level::trace);
std::cout << "cascade_proton_example" << std::endl;
CORSIKA_LOG_INFO("vertical_EAS");
if (argc < 4) {
std::cerr << "usage: vertical_EAS <A> <Z> <energy/GeV> [seed]" << std::endl;
std::cerr << " if no seed is given, a random seed is chosen" << std::endl;
return 1;
}
feenableexcept(FE_INVALID);
int seed = 0;
if (argc > 4) seed = std::stoi(std::string(argv[4]));
// initialize random number sequence(s)
registerRandomStreams(seed);
RNGManager::getInstance().registerRandomStream("cascade");
// setup environment
using IModelInterface = IRefractiveIndexModel<IMediumPropertyModel<IMagneticFieldModel<IMediumModel>>>;
using AtmModel = UniformRefractiveIndex<MediumPropertyModel<UniformMagneticField<HomogeneousMedium
<IModelInterface>>>>;
using EnvType = Environment<AtmModel>;
// setup environment, geometry
using EnvType = setup::Environment;
EnvType env;
auto& universe = *(env.getUniverse());
CoordinateSystemPtr const& rootCS = env.getCoordinateSystem();
Point const center{rootCS, 0_m, 0_m, 0_m};
// the antenna location
const auto point1{Point(env.getCoordinateSystem(), 50_m, 50_m, 50_m)};
const auto point2{Point(env.getCoordinateSystem(), 25_m, 25_m, 25_m)};
const auto point1{Point(rootCS, 50_m, 50_m, 0_m)};
const auto point2{Point(rootCS, 50_m, -50_m, 0_m)};
const auto point3{Point(rootCS, -50_m, 50_m, 0_m)};
const auto point4{Point(rootCS, -50_m, -50_m, 0_m)};
// the antennas
TimeDomainAntenna ant1("antenna1", point1, 0_s, 100_s, 1/1e-8_s);
TimeDomainAntenna ant2("antenna2", point2, 0_s, 100_s, 1/1e-8_s);
TimeDomainAntenna ant1("antenna1", point1, 0_s, 1_s, 1/1e+6_s);
TimeDomainAntenna ant2("antenna2", point2, 0_s, 1_s, 1/1e+6_s);
TimeDomainAntenna ant3("antenna3", point3, 0_s, 1_s, 1/1e+6_s);
TimeDomainAntenna ant4("antenna4", point4, 0_s, 1_s, 1/1e+6_s);
// the detector
AntennaCollection<TimeDomainAntenna> detector;
detector.addAntenna(ant1);
detector.addAntenna(ant2);
// a refractive index
const double ri_{1.000327};
// the constant density
const auto density{19.2_g / cube(1_cm)};
// the composition we use for the homogeneous medium
NuclearComposition const protonComposition(std::vector<Code>{Code::Proton},
std::vector<float>{1.f});
// create magnetic field vector
Vector B0(rootCS, 0_T,50_uT, 0_T);
// create the medium
auto Medium = EnvType::createNode<Sphere>(
center, 1_km * std::numeric_limits<double>::infinity());
// set the properties
auto const props = Medium->setModelProperties<AtmModel>(ri_,
Medium::AirDry1Atm, B0, density, protonComposition);
env.getUniverse()->addChild(std::move(Medium));
detector.addAntenna(ant3);
detector.addAntenna(ant4);
auto world = EnvType::createNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 150_km);
using MyHomogeneousModel = MediumPropertyModel<
UniformMagneticField<HomogeneousMedium<setup::EnvironmentInterface>>>;
world->setModelProperties<MyHomogeneousModel>(
Medium::AirDry1Atm, MagneticFieldVector(rootCS, 0_T, 0_T, 1_T),
1_kg / (1_m * 1_m * 1_m),
NuclearComposition(std::vector<Code>{Code::Hydrogen},
std::vector<float>{(float)1.}));
universe.addChild(std::move(world));
// setup particle stack, and add primary particle
setup::Stack stack;
stack.clear();
const Code beamCode = Code::Nucleus;
unsigned short const A = std::stoi(std::string(argv[1]));
unsigned short Z = std::stoi(std::string(argv[2]));
auto const mass = get_nucleus_mass(A, Z);
const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3]));
const Code beamCode = Code::Electron;
const HEPMassType mass = Electron::mass;
const HEPEnergyType E0 = 1000_GeV;
double theta = 0.;
auto const thetaRad = theta / 180. * M_PI;
auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
return sqrt((Elab - m) * (Elab + m));
};
HEPMomentumType P0 = elab2plab(E0, mass);
auto momentumComponents = [](double thetaRad, HEPMomentumType ptot) {
return std::make_tuple(ptot * sin(thetaRad), 0_eV, -ptot * cos(thetaRad));
};
auto const [px, py, pz] = momentumComponents(thetaRad, P0);
auto plab = MomentumVector(rootCS, {px, py, pz});
cout << "input particle: " << beamCode << endl;
cout << "input angles: theta=" << theta << endl;
cout << "input momentum: " << plab.getComponents() / 1_GeV
<< ", norm = " << plab.getNorm() << endl;
auto const observationHeight = 0_km + builder.getEarthRadius();
auto const injectionHeight = 112.75_km + builder.getEarthRadius();
auto const t = -observationHeight * cos(thetaRad) +
sqrt(-static_pow<2>(sin(thetaRad) * observationHeight) +
static_pow<2>(injectionHeight));
Point const showerCore{rootCS, 0_m, 0_m, observationHeight};
Point const injectionPos =
showerCore + DirectionVector{rootCS, {-sin(thetaRad), 0, cos(thetaRad)}} * t;
std::cout << "point of injection: " << injectionPos.getCoordinates() << std::endl;
if (A != 1) {
stack.addParticle(std::make_tuple(beamCode, E0, plab, injectionPos, 0_ns, A, Z));
} else {
if (Z == 1) {
stack.addParticle(std::make_tuple(Code::Proton, E0, plab, injectionPos, 0_ns));
} else if (Z == 0) {
stack.addParticle(std::make_tuple(Code::Neutron, E0, plab, injectionPos, 0_ns));
} else {
std::cerr << "illegal parameters" << std::endl;
return EXIT_FAILURE;
}
double phi = 0.;
Point injectionPos(rootCS, 0_m, 0_m, 0_m);
{
auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
return sqrt(Elab * Elab - m * m);
};
HEPMomentumType P0 = elab2plab(E0, mass);
auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) {
return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi),
-ptot * cos(theta));
};
auto const [px, py, pz] =
momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
auto plab = MomentumVector(rootCS, {px, py, pz});
cout << "input particle: " << beamCode << endl;
cout << "input angles: theta=" << theta << " phi=" << phi << endl;
cout << "input momentum: " << plab.getComponents() / 1_GeV << endl;
stack.addParticle(std::make_tuple(beamCode, E0, plab, injectionPos, 0_ns));
}
// we make the axis much longer than the inj-core distance since the
// profile will go beyond the core, depending on zenith angle
std::cout << "shower axis length: " << (showerCore - injectionPos).getNorm() * 1.5
<< std::endl;
ShowerAxis const showerAxis{injectionPos, (showerCore - injectionPos) * 1.5, env};
// setup processes, decays and interactions
setup::Tracking tracking;
StackInspector<setup::Stack> stackInspect(1, true, E0);
corsika::sibyll::Interaction sibyll;
InteractionCounter sibyllCounted(sibyll);
corsika::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
InteractionCounter sibyllNucCounted(sibyllNuc);
corsika::pythia8::Decay decayPythia;
// use sibyll decay routine for decays of particles unknown to pythia
corsika::sibyll::Decay decaySibyll{{
Code::N1440Plus,
Code::N1440MinusBar,
Code::N1440_0,
Code::N1440_0Bar,
Code::N1710Plus,
Code::N1710MinusBar,
Code::N1710_0,
Code::N1710_0Bar,
Code::Pi1300Plus,
Code::Pi1300Minus,
Code::Pi1300_0,
Code::KStar0_1430_0,
Code::KStar0_1430_0Bar,
Code::KStar0_1430_Plus,
Code::KStar0_1430_MinusBar,
}};
decaySibyll.printDecayConfig();
ParticleCut cut{60_GeV, 60_GeV, 60_GeV, 60_GeV, true};
corsika::proposal::Interaction emCascade(env);
corsika::proposal::ContinuousProcess emContinuous(env);
InteractionCounter emCascadeCounted(emCascade);
// ParticleCut cut(60_GeV, true, true);
// put radio process here
RadioProcess<decltype(detector), CoREAS<decltype(detector),
decltype(StraightPropagator(env))>, decltype(StraightPropagator(env))>
coreas(detector, env);
OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false);
TrackWriter trackWriter("tracks.dat");
LongitudinalProfile longprof{showerAxis};
Plane const obsPlane(showerCore, DirectionVector(rootCS, {0., 0., 1.}));
ObservationPlane observationLevel(obsPlane, DirectionVector(rootCS, {1., 0., 0.}),
"particles.dat");
corsika::urqmd::UrQMD urqmd;
InteractionCounter urqmdCounted{urqmd};
StackInspector<setup::Stack> stackInspect(1000, false, E0);
TrackWriter trackWriter("tracks.dat");
ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env};
// BetheBlochPDG eLoss{showerAxis};
// assemble all processes into an ordered process list
struct EnergySwitch {
HEPEnergyType cutE_;
EnergySwitch(HEPEnergyType cutE)
: cutE_(cutE) {}
SwitchResult operator()(const Particle& p) {
if (p.getEnergy() < cutE_)
return SwitchResult::First;
else
return SwitchResult::Second;
}
};
auto hadronSequence = make_select(
urqmdCounted, make_sequence(sibyllNucCounted, sibyllCounted), EnergySwitch(55_GeV));
auto decaySequence = make_sequence(decayPythia, decaySibyll);
auto sequence =
make_sequence(stackInspect, hadronSequence, reset_particle_mass, decaySequence,
emContinuous, cut, coreas, trackWriter, observationLevel, longprof);
// auto sequence = make_sequence(sibyll, sibyllNuc, decay, eLoss, cut, trackWriter,
// stackInspect); auto sequence = make_sequence(sibyll, decay, eLoss, cut, trackWriter,
// stackInspect);
auto sequence = make_sequence(coreas, trackWriter, stackInspect);
// define air shower object, run simulation
setup::Tracking tracking;
Cascade EAS(env, tracking, sequence, stack);
// to fix the point of first interaction, uncomment the following two lines:
// EAS.forceInteraction();
EAS.run();
cout << "Result: E0=" << E0 / 1_GeV << endl;
cut.showResults();
emContinuous.showResults();
observationLevel.showResults();
const HEPEnergyType Efinal = cut.getCutEnergy() + cut.getInvEnergy() +
cut.getEmEnergy() + emContinuous.getEnergyLost() +
observationLevel.getEnergyGround();
cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl
<< "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl;
observationLevel.reset();
cut.reset();
emContinuous.reset();
const HEPEnergyType Efinal =
cut.getCutEnergy() + cut.getInvEnergy() + cut.getEmEnergy();
cout << "total energy (GeV): " << Efinal / 1_GeV << endl
<< "relative difference (%): " << (Efinal / E0 - 1.) * 100 << endl;
// get radio output
coreas.writeOutput();
auto const hists = sibyllCounted.getHistogram() + sibyllNucCounted.getHistogram() +
urqmdCounted.getHistogram();
save_hist(hists.labHist(), "inthist_lab_verticalEAS.npz", true);
save_hist(hists.CMSHist(), "inthist_cms_verticalEAS.npz", true);
longprof.save("longprof_verticalEAS.txt");
}
\ No newline at end of file
}
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