diff --git a/CMakeLists.txt b/CMakeLists.txt index 2437c992d9ebf740b82b6607e829f3c7a8838fbe..95be0611f33458a5c28bb68ae4b5d0e0dff4ebe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.4.3) -project (corsika VERSION 8.0.0 DESCRIPTION "CORSIKA C++ PROJECT " LANGUAGES CXX) +project (corsika VERSION 8.0.0 DESCRIPTION "CORSIKA C++ project" LANGUAGES CXX) # ignore many irrelevant Up-to-date messages during install set (CMAKE_INSTALL_MESSAGE LAZY) diff --git a/Documentation/Doxygen/Doxyfile.in b/Documentation/Doxygen/Doxyfile.in index 400b6f2e0877f77709a7fdacbf9ba8ff370e6124..3083700bd447f1fbc0968c856846f4868544f668 100644 --- a/Documentation/Doxygen/Doxyfile.in +++ b/Documentation/Doxygen/Doxyfile.in @@ -1,12 +1,14 @@ -PROJECT_NAME = CORSIKA8 +PROJECT_NAME = CORSIKA +PROJECT_NUMBER = 8.0.0 OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/ INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../.. +EXCLUDE_PATTERN = "*/ThirdParty/*/*" GENERATE_HTML = YES GENERATE_LATEX = NO -FILE_PATTERNS = *.cc *.h +FILE_PATTERNS = *.cc *.cpp *.cxx *.h *.dox RECURSIVE = YES SOURCE_BROWSER = YES diff --git a/Documentation/Examples/logger_example.cc b/Documentation/Examples/logger_example.cc index 5455f7d5ea6295d7ec5cfcf118942db5ec71800d..d8212e6612dc2f45eb73990571d5d4c4125562ce 100644 --- a/Documentation/Examples/logger_example.cc +++ b/Documentation/Examples/logger_example.cc @@ -2,6 +2,7 @@ #include <string> #include <iostream> +#include <fstream> #include <boost/format.hpp> @@ -13,10 +14,10 @@ main() { cout << "writing to \"another.log\"" << endl; ofstream logfile("another.log"); - typedef Sink<ofstream, StdBuffer> SinkFile; - SinkFile sink(logfile, StdBuffer(10000)); - logger<SinkFile, messageconst> info("\033[32m", "info", sink); - logger<SinkFile, messageconst> err("\033[31m", "error", sink); + logger::sink::SinkStream unbuffered_sink(logfile); + logger::sink::BufferedSinkStream sink(logfile, logger::sink::StdBuffer(10000)); + logger::Logger<logger::MessageOn, logger::sink::BufferedSinkStream> info("\033[32m", "info", sink); + logger::Logger<logger::MessageOn, logger::sink::BufferedSinkStream> err("\033[31m", "error", sink); //logger<ostream,messageconst,StdBuffer> info(std::cout, StdBuffer(10000)); /* @@ -26,14 +27,14 @@ main() */ for (int i=0; i<100000; ++i) { - LOG(info, "irgendwas"," ", string("and more")," ", boost::format("error: %i message: %s. done."), i, "stupido"); - LOG(err, "Fehler"); + LOG(info, "irgendwas"," ", string("and more")," ", boost::format("error: %i message: %s. done."), i, "stupido"); + LOG(err, "Fehler"); } } - + { - NoSink off; - logger<NoSink, MessageOff> info("", "", off); + logger::sink::NoSink off; + logger::Logger<logger::MessageOff> info("", "", off); for (int i=0; i<100000; ++i) { LOG(info, "irgendwas", string("and more"), boost::format("error: %i message: %s. done."), i, "stupido", "a-number:", 8.99, "ENDE" ); diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt index a1f8a8bb6f6f6246edeb670288334a3736f3a8c4..eb7fb3650dfe3044ccabb4e79ab34c88fbea5e41 100644 --- a/Framework/Geometry/CMakeLists.txt +++ b/Framework/Geometry/CMakeLists.txt @@ -8,7 +8,7 @@ set_target_properties (CORSIKAgeometry PROPERTIES VERSION ${PROJECT_VERSION}) set_target_properties (CORSIKAgeometry PROPERTIES SOVERSION 1) set_target_properties (CORSIKAgeometry PROPERTIES PUBLIC_HEADER "${GEOMETRY_HEADERS}") - + # target dependencies on other libraries (also header only) target_link_libraries (CORSIKAgeometry CORSIKAunits) @@ -17,7 +17,7 @@ target_include_directories (CORSIKAgeometry INTERFACE ${EIGEN3_INCLUDE_DIR}) target_include_directories (CORSIKAgeometry INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Framework> $<INSTALL_INTERFACE:include/Framework> ) - + install (TARGETS CORSIKAgeometry LIBRARY DESTINATION lib ARCHIVE DESTINATION lib diff --git a/Framework/Geometry/testGeometry.cc b/Framework/Geometry/testGeometry.cc index d5a34b787708214f95b968f1329ecc75bdf513d8..b85d35327cf2796f1d690d3a33c5cc5e94c9a19c 100644 --- a/Framework/Geometry/testGeometry.cc +++ b/Framework/Geometry/testGeometry.cc @@ -1,11 +1,9 @@ #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file -#include <ThirdParty/catch2/catch.hpp> +#include <catch2/catch.hpp> #include <Units/PhysicalUnits.h> using namespace phys::units; -using namespace phys::units::io; -using namespace phys::units::literals; TEST_CASE( "PhysicalUnits", "[Units]" ) { diff --git a/Framework/Logging/BufferedSink.h b/Framework/Logging/BufferedSink.h new file mode 100644 index 0000000000000000000000000000000000000000..9934744dc1d069e603ec4f72f4ea25652eb97e4c --- /dev/null +++ b/Framework/Logging/BufferedSink.h @@ -0,0 +1,65 @@ +#ifndef _include_BufferedSink_h_ +#define _include_BufferedSink_h_ + +namespace logger { + + namespace sink { + + + /** + Output buffer template. NoBuffer does nothingk. + */ + /* + struct NoBuffer { + inline bool Test(const std::string&) const { return false; } + inline std::string GetString() const { return std::string(""); } + inline void Clear() {} + inline void Add(const std::string&) {} + }; + */ + /** + Output buffer template. StdBuffer records fSize characters in + local memeory before passing it on to further output stages. + */ + + struct StdBuffer { + StdBuffer(const int size) : fSize(size) {} + inline bool Test(const std::string& s) { return int(fBuffer.tellp())+s.length() < fSize; } + inline std::string GetString() const { return fBuffer.str(); } + inline void Clear() { fBuffer.str(""); } + inline void Add(const std::string& s) { fBuffer << s; } + private: + int fSize; + std::ostringstream fBuffer; + }; + + + /** + Definition of Sink for log output. + */ + template<typename TStream, typename TBuffer=StdBuffer> + class BufferedSink { + public: + BufferedSink(TStream& out, TBuffer buffer = {} ) : fOutput(out), fBuffer(std::move(buffer)) {} + void operator<<(const std::string& msg) { + if (!fBuffer.Test(msg)) { + fOutput << fBuffer.GetString(); + fBuffer.Clear(); + } + if (!fBuffer.Test(msg)) + fOutput << msg; + else + fBuffer.Add(msg); + } + void Close() { fOutput << fBuffer.GetString(); } + private: + TStream& fOutput; + TBuffer fBuffer; + }; + + typedef BufferedSink<std::ostream, StdBuffer> BufferedSinkStream; + + }// end namespace +} // end namespace + +#endif diff --git a/Framework/Logging/CMakeLists.txt b/Framework/Logging/CMakeLists.txt index 51da77cf702a67e44ecfa5ba810a086b147951dd..7b684deb1cff09f2d77db017cf27a58c59d91d71 100644 --- a/Framework/Logging/CMakeLists.txt +++ b/Framework/Logging/CMakeLists.txt @@ -8,6 +8,6 @@ target_include_directories (CORSIKAlogging INTERFACE $<BUILD_INTERFACE:${PROJECT $<INSTALL_INTERFACE:include/Framework> ) -install (FILES Logger.h +install (FILES Logger.h Sink.h MessageOn.h MessageOff.h NoSink.h Sink.h BufferedSink.h DESTINATION include/Logging) diff --git a/Framework/Logging/Logger.h b/Framework/Logging/Logger.h index 73275ceb130a01c1ca148c2040cfcb2566e287f9..b98654d3f224711bf1d3315564f316c63544759e 100644 --- a/Framework/Logging/Logger.h +++ b/Framework/Logging/Logger.h @@ -1,142 +1,66 @@ #ifndef _include_logger_h_ #define _include_logger_h_ +#include <iosfwd> #include <string> #include <sstream> -#include <iostream> #include <typeinfo> -#include <fstream> #include <boost/format.hpp> - -using namespace std; -using namespace boost; - - -class MessageOff { - protected: - template<typename First, typename ... Strings> std::string message(const First& arg, const Strings&... rest) { - return ""; - } -}; - -class messageconst { - protected: - std::string message() { return "\n"; } - - template<typename First, typename ... Strings> std::string message(const First& arg, const Strings&... rest) { - std::ostringstream ss; - ss << arg << message(rest...); - return ss.str(); - } - - template<typename ... Strings> std::string message(const int& arg, const Strings&... rest) { - return std::to_string(arg) + message(rest...); - } - - template<typename ... Strings> std::string message(const double& arg, const Strings&... rest) { - return std::to_string(arg) + message(rest...); - } - - template<typename ... Strings> std::string message(char const * arg, const Strings&... rest) { - return std::string(arg) + message(rest...); - } - - template<typename ... Strings> std::string message(const std::string& arg, const Strings&... rest) { - return arg + message(rest...); - } - - // ---------------------- - // boost format - template<typename ... Strings> std::string message(const boost::format& fmt, const Strings&... rest) { - boost::format FMT(fmt); - return bformat(FMT, rest...); - } - - template<typename Arg, typename ... Strings> std::string bformat(boost::format& fmt, const Arg& arg, const Strings&... rest) { - fmt % arg; - return bformat(fmt, rest...); - } - - std::string bformat(boost::format& fmt) { return fmt.str() + "\n"; } -}; - - -struct NoBuffer { - inline bool Test(const std::string&) const { return false; } - inline std::string GetString() const { return std::string(""); } - inline void Clear() {} - inline void Add(const std::string&) {} -}; - -struct StdBuffer { - StdBuffer(const int size) : fSize(size) {} - inline bool Test(const std::string& s) { return int(fBuffer.tellp())+s.length() < fSize; } - inline std::string GetString() const { return fBuffer.str(); } - inline void Clear() { fBuffer.str(""); } - inline void Add(const std::string& s) { fBuffer << s; } -private: - int fSize; - std::ostringstream fBuffer; -}; - - -template<typename TStream, typename TBuffer=StdBuffer> -class Sink { - public: - Sink(TStream& out, TBuffer buffer = {} ) : fOutput(out), fBuffer(std::move(buffer)) {} - void operator<<(const std::string& msg) { - if (!fBuffer.Test(msg)) { - fOutput << fBuffer.GetString(); - fBuffer.Clear(); - } - if (!fBuffer.Test(msg)) - fOutput << msg; - else - fBuffer.Add(msg); - } - void Close() { fOutput << fBuffer.GetString(); } - private: - TStream& fOutput; - TBuffer fBuffer; -}; +#include <Logging/MessageOn.h> +#include <Logging/MessageOff.h> +#include <Logging/Sink.h> +#include <Logging/NoSink.h> +#include <Logging/BufferedSink.h> -struct NoSink { inline void operator<<(const std::string&) {} inline void Close() {} }; - +using namespace std; +using namespace boost; -template<typename TSink=NoSink,typename M=messageconst> -class logger : private M { - - using M::message; +/** + Everything around logfile generation and text output. +*/ - public: - // logger() : fName("") {} - logger(const std::string color, const std::string name, TSink& sink) : fSink(sink), fName(color+"["+name+"]\033[39m ") {} - ~logger() { fSink.Close(); } +namespace logger { - // logger(const logger&) = delete; - - template<typename ... Strings> - void log(const Strings&... inputs) { - fSink << M::message(inputs...); - } - - const std::string& GetName() const { return fName; } - - private: - TSink& fSink; - std::string fName; -}; - - - -#define LOG(__LOGGER,...) \ - __LOGGER.log(__LOGGER.GetName(), __FILE__,":", __LINE__, " (", __func__, ") -> ", ##__VA_ARGS__); - - - + /** + Defines one stream to accept messages, and to wrote those into + TSink. The helper class MessageOn will convert input at + compile-time into message strings. The helper class MessageOff, + will just do nothing and will be optimized away at compile time. + */ + template<typename MSG=MessageOn, typename TSink=sink::NoSink> + class Logger : private MSG { + + using MSG::Message; + + public: + // Logger() : fName("") {} + Logger(const std::string color, const std::string name, TSink& sink) : fSink(sink), fName(color+"["+name+"]\033[39m ") {} + ~Logger() { fSink.Close(); } + // Logger(const Logger&) = delete; + + /** + Function to add string-concatenation of all inputs to output + sink. + */ + template<typename ... Strings> + void Log(const Strings&... inputs) { + fSink << MSG::Message(inputs...); + } + + const std::string& GetName() const { return fName; } + + private: + TSink& fSink; + std::string fName; + }; + +} // end namesapce + +#define LOG(__LOGGER,...) \ + __LOGGER.Log(__LOGGER.GetName(), __FILE__,":", __LINE__, " (", __func__, ") -> ", ##__VA_ARGS__); #endif diff --git a/Framework/Logging/Logging.h b/Framework/Logging/Logging.h deleted file mode 100644 index 548e508529a3358429ccdfc8d6cfeb0d9a33054c..0000000000000000000000000000000000000000 --- a/Framework/Logging/Logging.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _include_logging_h_ -#define _include_logging_h_ - -#include <logger.h> - -#include <map> -#include <string> -#include <any> - -class Logging { - - Logging() {} - - public: - - static Logging& GetInstance() { static Logging fgLog; return fgLog; } - - template<typename TLogger> - void AddLogger(const std::string& name, const TLogger& logger) { fLoggers[name] = logger; } - - auto& GetLogger(const std::string& name) { return fLoggers[name]; } - - private: - std::map<std::string, std::any> fLoggers; -}; - -#endif diff --git a/Framework/Logging/MessageOff.h b/Framework/Logging/MessageOff.h new file mode 100644 index 0000000000000000000000000000000000000000..ef62e2577eedae957767888156bbe04474e71c0b --- /dev/null +++ b/Framework/Logging/MessageOff.h @@ -0,0 +1,19 @@ +#ifndef _include_MessageOff_h_ +#define _include_MessageOff_h_ + +namespace logger { + + /** + Helper class to ignore all arguments to MessagesOn::Message and + always return empty string "". + */ + class MessageOff { + protected: + template<typename First, typename ... Strings> std::string Message(const First& arg, const Strings&... rest) { + return ""; + } + }; + +} // end namespace + +#endif diff --git a/Framework/Logging/MessageOn.h b/Framework/Logging/MessageOn.h new file mode 100644 index 0000000000000000000000000000000000000000..43b847448a5b92d3b3c48d5768db874663a9d8a1 --- /dev/null +++ b/Framework/Logging/MessageOn.h @@ -0,0 +1,54 @@ +#ifndef _include_MessageOn_h_ +#define _include_MessageOn_h_ + + +namespace logger { + + /** + Helper class to convert all input arguments of MessageOn::Message + into string-concatenated version and return this as string. + */ + class MessageOn { + protected: + std::string Message() { return "\n"; } + + template<typename First, typename ... Strings> std::string Message(const First& arg, const Strings&... rest) { + std::ostringstream ss; + ss << arg << Message(rest...); + return ss.str(); + } + + template<typename ... Strings> std::string Message(const int& arg, const Strings&... rest) { + return std::to_string(arg) + Message(rest...); + } + + template<typename ... Strings> std::string Message(const double& arg, const Strings&... rest) { + return std::to_string(arg) + Message(rest...); + } + + template<typename ... Strings> std::string Message(char const * arg, const Strings&... rest) { + return std::string(arg) + Message(rest...); + } + + template<typename ... Strings> std::string Message(const std::string& arg, const Strings&... rest) { + return arg + Message(rest...); + } + + // ---------------------- + // boost format + template<typename ... Strings> std::string Message(const boost::format& fmt, const Strings&... rest) { + boost::format FMT(fmt); + return bformat(FMT, rest...); + } + + template<typename Arg, typename ... Strings> std::string bformat(boost::format& fmt, const Arg& arg, const Strings&... rest) { + fmt % arg; + return bformat(fmt, rest...); + } + + std::string bformat(boost::format& fmt) { return fmt.str() + "\n"; } + }; + +}// end namesapce + +#endif diff --git a/Framework/Logging/NoSink.h b/Framework/Logging/NoSink.h new file mode 100644 index 0000000000000000000000000000000000000000..13e37f3b9a511182f792d81922e7dfba4c62d8ef --- /dev/null +++ b/Framework/Logging/NoSink.h @@ -0,0 +1,16 @@ +#ifndef _include_NoSink_h_ +#define _include_NoSink_h_ + +namespace logger { + + namespace sink { + + struct NoSink { + inline void operator<<(const std::string&) {} + inline void Close() {} + }; + + }// end namespace +} // end namespace + +#endif diff --git a/Framework/Logging/Sink.h b/Framework/Logging/Sink.h new file mode 100644 index 0000000000000000000000000000000000000000..6ee615176036f03c74a1deb50493bfdcd6cddd1b --- /dev/null +++ b/Framework/Logging/Sink.h @@ -0,0 +1,37 @@ +#ifndef _include_Sink_h_ +#define _include_Sink_h_ + +namespace logger { + + /** + a sink for the logger must implement the two functions + operator<<(const std::string&) + and + Close() + + See example: NoSink + */ + + namespace sink { + + /** + Definition of Sink for log output. + */ + template<typename TStream> + class Sink { + public: + Sink(TStream& out) : fOutput(out) {} + void operator<<(const std::string& msg) { + fOutput << msg; + } + void Close() {} + private: + TStream& fOutput; + }; + + typedef Sink<std::ostream> SinkStream; + + }// end namespace +} // end namespace + +#endif diff --git a/Framework/Units/CMakeLists.txt b/Framework/Units/CMakeLists.txt index d7d3af7ede19a82ed7805cdce046966beff922cb..7881afc4f9264391915ca73b5a71dd21b06f9054 100644 --- a/Framework/Units/CMakeLists.txt +++ b/Framework/Units/CMakeLists.txt @@ -5,7 +5,6 @@ target_include_directories (CORSIKAunits INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Framework> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/ThirdParty> - $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}> $<INSTALL_INTERFACE:include> ) diff --git a/Framework/Units/PhysicalUnits.h b/Framework/Units/PhysicalUnits.h index 91f741a7f09e6f633183b0b354027ac738ec1829..83ed903f9f2ffd7da290349f69daa059aa8d18e8 100644 --- a/Framework/Units/PhysicalUnits.h +++ b/Framework/Units/PhysicalUnits.h @@ -1,16 +1,19 @@ #ifndef _include_PhysicalUnits_h_ #define _include_PhysicalUnits_h_ -#include <ThirdParty/phys/units/quantity.hpp> -#include <ThirdParty/phys/units/io.hpp> -#include <ThirdParty/phys/units/physical_constants.hpp> +#include <phys/units/quantity.hpp> +#include <phys/units/io.hpp> +#include <phys/units/physical_constants.hpp> /** - /file PhysicalUnits + @file PhysicalUnits Define _XeV literals, alowing 10_GeV in the code. */ +using namespace phys::units::io; +using namespace phys::units::literals; + namespace phys { namespace units { namespace literals { diff --git a/Framework/Units/testUnits.cc b/Framework/Units/testUnits.cc index eeae88d0fafa133ef9afce1cc6ece2d8157e8dfc..3206c50951328502350614c244fd5e0e7e35c3b6 100644 --- a/Framework/Units/testUnits.cc +++ b/Framework/Units/testUnits.cc @@ -1,11 +1,9 @@ #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file -#include <ThirdParty/catch2/catch.hpp> +#include <catch2/catch.hpp> #include <Units/PhysicalUnits.h> using namespace phys::units; -using namespace phys::units::io; -using namespace phys::units::literals; TEST_CASE( "PhysicalUnits", "[Units]" ) { REQUIRE( 1_m/1_m == 1 ); diff --git a/Processes/NullModel/NullModel.cc b/Processes/NullModel/NullModel.cc index 7d2ab743cbc4cd4714476b4ea46b10ef538d83f2..96972982496c08a681e56b1a4cd68d604d266801 100644 --- a/Processes/NullModel/NullModel.cc +++ b/Processes/NullModel/NullModel.cc @@ -1 +1,2 @@ -#include _Physics_NullModel_NullModel_h_ +#include <Processes/NullModel/NullModel.h> + diff --git a/Processes/NullModel/NullModel.h b/Processes/NullModel/NullModel.h index 07cf2c0427fda7e1a6e8286f960ec36d9199b24c..a78e14d14eeeb8b9f7b1739e7d29860a4f506b05 100644 --- a/Processes/NullModel/NullModel.h +++ b/Processes/NullModel/NullModel.h @@ -1,22 +1,19 @@ #ifndef _Physics_NullModel_NullModel_h_ #define _Physics_NullModel_NullModel_h_ -namespace physics { +namespace processes { - namespace processes { + class NullModel { - class NullModel { - - public: - NullModel(); - ~NullModel(); - - void init(); - void run(); - double GetStepLength(); - }; + public: + NullModel(); + ~NullModel(); - } + void init(); + void run(); + double GetStepLength(); + }; + } #endif diff --git a/ThirdParty/CMakeLists.txt b/ThirdParty/CMakeLists.txt index 8279a64491b707f5eae89b0404f8ed2ab8cea4e4..c7f90c5b9bdb6ad21d4f918e22a8f973abd838eb 100644 --- a/ThirdParty/CMakeLists.txt +++ b/ThirdParty/CMakeLists.txt @@ -1,10 +1,10 @@ add_library (CORSIKAthirdparty INTERFACE) -target_include_directories (CORSIKAthirdparty +target_include_directories (CORSIKAthirdparty SYSTEM INTERFACE - $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/> - $<INSTALL_INTERFACE:include/> + $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/ThirdParty> + $<INSTALL_INTERFACE:include/ThirdParty> ) install (DIRECTORY phys DESTINATION include/ThirdParty/) diff --git a/ThirdParty/ThirdParty.dox b/ThirdParty/ThirdParty.dox new file mode 100644 index 0000000000000000000000000000000000000000..956b180f5c8936762d0083b75c9bc599314a7769 --- /dev/null +++ b/ThirdParty/ThirdParty.dox @@ -0,0 +1,28 @@ +/** +@page ThirdParty +@tableofcontents + +In the directory ThirdParty we provide simple dependencies. This +minimizes the need to install additional software for the user. Note +the individual copyrights and licences here! + + +@section PhysUnits + +The PhysUnits library is an external dependency included here just for +convenience: + +Original source code from: https://github.com/martinmoene/PhysUnits-CT-Cpp11#references + +Licence: BSL-1.0 (https://github.com/martinmoene/PhysUnits-CT-Cpp11/blob/master/LICENSE_1_0.txt) + +References: https://github.com/martinmoene/PhysUnits-CT-Cpp11#references + + +@section catch2 + +The catch2 unit testing library is from: https://github.com/catchorg/Catch2 +Licence: BSL-1.0 (https://github.com/martinmoene/PhysUnits-CT-Cpp11/blob/master/LICENSE_1_0.txt) +References: https://github.com/catchorg/Catch2 + +*/ diff --git a/corsika.dox b/corsika.dox new file mode 100644 index 0000000000000000000000000000000000000000..9416fcf60d97b199e6381bcb6defc58cad71c99a --- /dev/null +++ b/corsika.dox @@ -0,0 +1,8 @@ +/** +@mainpage CORSIKA air shower simulations + +Source code documentation and reference guide for the CORSIKA8 +software framework for air shower simulations. + + +*/