diff --git a/documentation/conf.py b/documentation/conf.py index b0a15a6f281ce7008fea14840657803c94f7b6ae..d281602e9bc083acc9046491a7bfcb952303b945 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -25,13 +25,12 @@ def configureDoxyLayout(template_file, output_file, page_url, page_tile): -read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' -build_version = os.environ.get('READTHEDOCS_VERSION', None) +read_the_docs_build = os.environ.get('READTHEDOCS', None) != None breathe_projects = {} -doc_url = 'https://corsika-8.readthedocs.io/en/'+build_version - if read_the_docs_build: + build_version = os.environ.get('READTHEDOCS_VERSION', None) + doc_url = 'https://corsika-8.readthedocs.io/en/'+build_version configureDoxyfile("Doxyfile.in", "Doxyfile", "../", "_build/workdir/doxygen") configureDoxyLayout("DoxyLayout.in", "DoxyLayout.xml", doc_url , "CORSIKA 8 Webpage") subprocess.call('mkdir -p _build/workdir/doxygen; doxygen Doxyfile', shell=True) diff --git a/documentation/howto_create_module.rst b/documentation/howto_create_module.rst index 416abb5374324f70efddd091d3bbe926dce701a5..596bf723c545dc2b2af83418a99f0d1469c0c02b 100644 --- a/documentation/howto_create_module.rst +++ b/documentation/howto_create_module.rst @@ -15,7 +15,7 @@ how to use units, and use the loggers from the very beginning. Furthermore, get Let's consider the case of an "InteractionProcess" which will remove the projectile particle and create secondary particles on the stack instead. It also has a cross section in order to evaulate the probability -with respect to other InteractionProcesses. Create a header file "SimpleProcess.hpp", which is conceptually +with respect to other InteractionProcesses. Create a header file `SimpleProcess.hpp`, which is conceptually based to resemble (roughly) a Matthew-Heitler model: .. code-block:: c++ @@ -25,13 +25,14 @@ based to resemble (roughly) a Matthew-Heitler model: #include <corsika/framework/core/ParticleProperties.hpp> #include <corsika/framework/core/PhysicalConstants.hpp> #include <corsika/framework/core/PhysicalUnits.hpp> + #include <corsika/framework/core/Logging.hpp> #include <corsika/framework/process/InteractionProcess.hpp> #include <corsika/framework/random/RNGManager.hpp> namespace corsika::simple_process { class SimpleProcess : public corsika::InteractionProcess<SimpleProcess> { - + public: SimpleProcess(); @@ -39,27 +40,27 @@ based to resemble (roughly) a Matthew-Heitler model: GrammageType getInteractionLength(TParticle const&) const; template <typename TSecondaryView> - void doInteraction(TSecondaryView& view) const; + void doInteraction(TSecondaryView& view) const; private: // the random number stream corsika::default_prng_type& rng_ = - corsika::RNGManager::getInstance().getRandomStream("simple_process"); - // the logger + corsika::RNGManager<>::getInstance().getRandomStream("simple_process"); + // the logger + std::shared_ptr<spdlog::logger> logger_ = get_logger("corsika_SimpleProcess"); }; - } + } #include <SimpleProcess.inl> - - -And the corresponding "SimpleProcess.inl" as: + +And the corresponding `SimpleProcess.inl` as: .. code-block:: c++ - - namespace corsika::simple_process + + Namespace corsika::simple_process { inline SimpleProcess::SimpleProcess() {} @@ -68,12 +69,12 @@ And the corresponding "SimpleProcess.inl" as: inline GrammageType SimpleProcess::getInteractionLength( TParticle const &particle) const { - // this process only applies to hadrons above Ekin=100GeV - if (is_hadron(particle.getPID() && particle.getKineticEnergy()>100_GeV) { - return 2_g/square(1_cm); + // this process only applies to hadrons above Ekin=100GeV + if (is_hadron(particle.getPID()) && particle.getKineticEnergy()>100_GeV) { + return 2_g/square(1_cm); } // otherwise its cross section is 0 - return std::numeric_limits<double>::infitiny * 1_g/square(1_cm); + return std::numeric_limits<double>::infinity() * 1_g/square(1_cm); } template <typename TSecondaryView> @@ -84,26 +85,51 @@ And the corresponding "SimpleProcess.inl" as: int const nMult = 15; auto pionEnergy = projectile.getEnergy() / nMult; - auto const pOrig = proton.getPosition(); - auto const tOrig = proton.getTime(); + auto const pOrig = projectile.getPosition(); + auto const tOrig = projectile.getTime(); + auto const projectileMomentum = projectile.getMomentum(); auto const &cs = projectileMomentum.getCoordinateSystem(); for (int iMult=0; iMult<nMult; ++iMult) { - proton.addSecondary(std::make_tuple(Code::PiPlus, - pionEnergy, + projectile.addSecondary(std::make_tuple(Code::PiPlus, projectileMomentum.normalized() * sqrt(square(pionEnergy) + square(PiPlus::mass)), pOrig, tOrig)); - } + CORSIKA_LOGGER_INFO(logger_, "Created {} new secondaries of energy {}.", nMult, pionEnergy); } } - + +In this example, `TParticle` as used here in the SimpleModule is one +particle on the CORSIKA8 particle stack. It has all methods you expect +as `getPosition()`, `getEnergy()`, `getKineticEnergy()`, etc. + +The `TSecondaryView` provides special access to the CORSIKA8 particle +stack as needed for a particle interaction with a projectile and +secondaries. For example, `getProjectil()` will return the actual +projectile particle, `addSecondary(...)` will produce a secondary of +the projectil. The advantage of addSecondary wrt. addParticle is that +there exists a direct reference to the projectile allowing to +automatically copy weights, keep the cascade history, +etc. Furthermore, you can define subsequent `SeoncariesProcesses` +which can further process all the newly created secondaries. This +could perform energy threshold cuts, or also calculate new weights, +etc. + The SimpleProcess is not necessarily useful for anything and its sole purpuse is to illustrate the mechanism to -create your process. +create your own processes. + +You can then include such a process in your programm (e.g. in vertical_EAS) with + - add: `#include <SimpleProcess.hpp>` + - register the new random stream: `RNGManager<>::getInstance().registerRandomStream("simple_process");` + - initialize it with `simple_process::SimpleProcess simple; ` + - add it to the physiscs sequence i.e. via `auto extended_sequence = make_sequence(old_sequence, simple);` + +Please follow the style and guidelines for programming CORSIKA 8 code +even for private project. Your code will be GPLv3, too, and thus +should be made public to the community. Any discussion or eventual +bug-fixing is much more complicated if there are deviations from the +guideline. -You can then include such a process in your programm (e.g. in vertical_EAS) with `#include <SimpleProcess.hpp>` -and just initialize it `simple_process::SimpleProcess simple; ` as your wish and add it to the physiscs sequence -e.g. via `auto extended_sequence = make_sequence(old_sequence, simple);`