From def128ebebbc23607b85c03795b4e840e5c7b714 Mon Sep 17 00:00:00 2001 From: Nikos Karastathis <n.karastathis@kit.edu> Date: Mon, 22 Mar 2021 16:46:11 +0100 Subject: [PATCH] first try of synchnotron radiation example (need to tweak StraightPropagator.hpp first) --- examples/radio_shower2.cpp | 330 +++++++++++-------------------------- 1 file changed, 96 insertions(+), 234 deletions(-) diff --git a/examples/radio_shower2.cpp b/examples/radio_shower2.cpp index e7620cc88..e7c3e0398 100644 --- a/examples/radio_shower2.cpp +++ b/examples/radio_shower2.cpp @@ -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 +} -- GitLab