IAP GITLAB

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • AirShowerPhysics/corsika
  • rulrich/corsika
  • AAAlvesJr/corsika
  • Andre/corsika
  • arrabito/corsika
  • Nikos/corsika
  • olheiser73/corsika
  • AirShowerPhysics/papers/corsika
  • pranav/corsika
9 results
Show changes
Commits on Source (2167)
Showing
with 670 additions and 6781 deletions
*.inl gitlab-language=c++
\ No newline at end of file
......@@ -2,9 +2,23 @@
**/*~
**/*.bak
build/
install/
.vscode/
Framework/Particles/GeneratedParticleProperties.inc
flymd.html
flymd.md
Testing
tags
Environment/GeneratedMediaProperties.inc
CMakeUserPresets.json
corsika/framework/core/GeneratedParticleClasses.inc
corsika/framework/core/GeneratedParticleProperties.inc
corsika/framework/core/particle_db.pkl
corsika/media/GeneratedMediaProperties.inc
corsika/modules/epos/Generated.inc
corsika/modules/fluka/Generated.inc
corsika/modules/qgsjetII/Generated.inc
corsika/modules/sibyll/Generated.inc
corsika/modules/sophia/Generated.inc
conan_cmake/
corsika-cmake.sh
This diff is collapsed.
Issues: Closes #....
The code approval procedure is described in the wiki: [Code approval procedure wiki](https://gitlab.ikp.kit.edu/AirShowerPhysics/corsika/-/wikis/Code-Approval-Procedure)
The code approval procedure is described in the wiki: [Code approval procedure wiki](https://gitlab.iap.kit.edu/AirShowerPhysics/corsika/-/wikis/Code-Approval-Procedure)
- [ ] The MR is without `WIP/Draft` status
- [ ] Make sure the most recent CI jobs (config, quality, build_test_example) all run fine with no failures
- if "check clang-format" failed: the code contributor has to run `./do-clang-format.py --apply` eventually with the `--all` option
- if "check copyright" failed the code contributor has to run`./do-copyright.py --add=20xy`
- [ ] Make sure also the jobs with MR-label `ready for code review` succeed. This includes the optional jobs, in particular 'coverage', 'release-clang-8", "release-u-18.04" and make sure no problems occur. You may have to trigger a pipeline manually to check this.
- [ ] Make sure also the jobs with MR-label `ready for code review` succeed. This includes the optional jobs, in particular 'coverage', 'release-full-clang-14", "release-full-u-22_04" and make sure no problems occur. You may have to trigger a pipeline manually to check this.
- [ ] Check in the "coverage" job output that the coverage did not decrease. It should always stay, or increase. If it decreased --> ask contributor to add further needed unit tests, and check coverage report.
- On the MR page, open the "Open in Web IDE" tool
- [ ] Check if the provided solution solves the Issue, discuss on gitlab
......
[submodule "Data"]
path = Data
url = ../../AirShowerPhysics/corsika-data
[submodule "modules/data"]
path = modules/data
url = ../../AirShowerPhysics/corsika-data.git
branch = master
shallow = true
[submodule "modules/conex"]
path = modules/conex/cxroot
url = ../../AirShowerPhysics/cxroot.git
branch = master
[submodule "ThirdParty/spdlog"]
path = ThirdParty/spdlog
url = https://github.com/gabime/spdlog.git
shallow = true
[submodule "Processes/Proposal/PROPOSAL"]
path = Processes/Proposal/PROPOSAL
url = https://github.com/tudo-astroparticlephysics/PROPOSAL.git
shallow = true
* milestone1 release: So 7. Okt 15:51:07 CEST 2018
#
# (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
#
# See file AUTHORS for a list of contributors.
#
# This software is distributed under the terms of the 3-clause BSD license.
# See file LICENSE for a full version of the license.
#
cmake_minimum_required (VERSION 3.9)
# we would need 3.16 to have CMP0097 for external subproject submodule (non) support
#+++++++++++++++++++++++++++++
# project name
# version is: "8.major.minor.patch"
# major: API changes
# minor: no API changes
# patch: bug fix and small improvements
#
set (c8_version 8.0.0.0)
project (
corsika
VERSION ${c8_version}
DESCRIPTION "CORSIKA C++ project (alpha status)"
LANGUAGES CXX
)
#+++++++++++++++++++++++++++++
# for pre-defined standard path
#
project( CORSIKA8_Modules_Tests_Examples )
include (GNUInstallDirs)
#+++++++++++++++++++++++++++++
# prevent in-source builds and give warning message
#
if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
message (FATAL_ERROR "In-source builds are disabled.
Please create a build-dir and use `cmake <source-dir>` inside it.
NOTE: cmake will now create CMakeCache.txt and CMakeFiles/*.
You must delete them, or cmake will refuse to work.")
endif ()
#++++++++++++++++++++++++++++
# cmake version-specific settings
#
# https://cmake.org/cmake/help/latest/policy/CMP0079.html
if (POLICY CMP0079)
cmake_policy (SET CMP0079 NEW)
endif ()
# Download timestamp for external modules
if (POLICY CMP0135)
cmake_policy (SET CMP0135 OLD)
endif ()
# AUtomatically add extensions to filenames if needed (old behaviour)
if (POLICY CMP0115)
cmake_policy (SET CMP0115 OLD)
endif ()
#+++++++++++++++++++++++++++++
# warn user if system is not UNIX
#
if(NOT UNIX)
message(FATAL_ERROR "| CORSIKA8 > This is an unsupported system.")
endif()
if (NOT UNIX)
message (FATAL_ERROR "| CORSIKA8 > This is an unsupported system.")
endif ()
#+++++++++++++++++++++++++++++
# cmake path dir, and cmake config
#
set (CORSIKA8_CMAKE_DIR "${PROJECT_SOURCE_DIR}/cmake")
set (CMAKE_MODULE_PATH "${CORSIKA8_CMAKE_DIR}" ${CMAKE_MODULE_PATH})
if(DEFINED CONAN_CMAKE_DIR)
list(APPEND CMAKE_MODULE_PATH "${CONAN_CMAKE_DIR}")
endif(DEFINED CONAN_CMAKE_DIR)
set (CMAKE_VERBOSE_MAKEFILE OFF) # this can be done with `make VERBOSE=1`
# ignore many irrelevant Up-to-date messages during install
set (CMAKE_INSTALL_MESSAGE LAZY)
#+++++++++++++++++++++++++++++
# cmake path dir
# Extra cmake functions for registering and running tests
#
SET(CORSIKA8_CMAKE_DIR "${PROJECT_SOURCE_DIR}/cmake")
SET(CMAKE_MODULE_PATH "${CORSIKA8_CMAKE_DIR}" ${CMAKE_MODULE_PATH})
SET(CMAKE_VERBOSE_MAKEFILE ON)
include (corsikaUtilities) # extra cmake functions
#+++++++++++++++++++++++++++++
# Setup hardware and infrastructure dependent defines, and general settings
#
include (corsikaDefines)
#+++++++++++++++++++++++++++++
# check if compiler is C++17 compliant
#
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("--std=c++17" COMPILER_SUPPORTS_CXX17)
if(NOT COMPILER_SUPPORTS_CXX17)
message(FATAL "| CORSIKA8 > The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.")
endif()
include (CheckCXXCompilerFlag)
check_CXX_compiler_flag ("-std=c++17" COMPILER_SUPPORTS_CXX17)
if (NOT COMPILER_SUPPORTS_CXX17)
message (FATAL "| CORSIKA8 > The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler.")
endif ()
# set CXX compile flags and options and warning settings
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_EXTENSIONS OFF)
#+++++++++++++++++++++++++++++
# Compiler and linker flags, settings
#
# enable warnings and disallow non-standard language
# configure the various build types here, too
# FYI: optimizer flags: -O2 would not trade speed for size, neither O2/3 use fast-math
# debug: O0, relwithdebinfo: 02, release: O3, minsizerel: Os (all defaults)
set (CMAKE_CXX_FLAGS "-Wall -pedantic -Wextra -Wno-ignored-qualifiers")
set (CMAKE_Fortran_FLAGS "-std=legacy -Wfunction-elimination")
if (CORSIKA_SCL_CXX)
add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0)
endif()
# clang produces a lot of unecessary warnings without this:
add_compile_options ("$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-nonportable-include-path>")
# ctest config
enable_testing ()
set (CTEST_OUTPUT_ON_FAILURE 1)
add_compile_options (
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-nonportable-include-path>
)
#+++++++++++++++++++++++++++++
# get CORSIKA8
# Setup external dependencies.
#
find_package(CORSIKA8 REQUIRED)
include_directories(${CORSIKA8_INCLUDE_DIR})
# those are needed, since some headers (namely GeneratedParticleProperties.inc) are produced by python script from ParticleData.xml
add_subdirectory(corsika/framework)
add_subdirectory(corsika/modules/sibyll)
###
#
#+++++++++++++++++++++++++++++
# get Eigen3
# add cnpy temporarily. As long as SaveBoostHistogram does not save to parquet directly
#
find_package( Eigen3 REQUIRED )
include_directories(${EIGEN3_INCLUDE_DIR})
add_subdirectory (externals/cnpy)
#+++++++++++++++++++++++++++++
# get catch2
# Coverage
#
find_package( Catch2 REQUIRED )
# targets and settings needed to generate coverage reports
#if (CMAKE_BUILD_TYPE STREQUAL Coverage)
SET(COVERAGE_BUILD OFF CACHE BOOL "Activate coverage build")
if( COVERAGE_BUILD AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
message(INFO "\n|==========> COVERAGE TARGET ACTIVATED.\n")
set (c8_lcov_download_url "https://github.com/linux-test-project/lcov/releases/download")
set (c8_lcov_version "1.16")
set (c8_lcov_install_dir "${CMAKE_BINARY_DIR}/lcov")
include(ExternalProject)
ExternalProject_Add(lcov
URL ${c8_lcov_download_url}/v${c8_lcov_version}/lcov-${c8_lcov_version}.tar.gz
DOWNLOAD_NO_EXTRACT 0
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND make -C <SOURCE_DIR> install PREFIX=${c8_lcov_install_dir}
)
find_package (Perl REQUIRED)
# compile coverage under -O0 to avoid any optimization, function elimation etc.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 --coverage")
# search for local lcov
find_program (c8_lcov_bin lcov)
if (NOT c8_lcov_bin)
set (c8_lcov_bin "${c8_lcov_install_dir}/bin/lcov")
message ("use C8 version of lcov ${c8_lcov_bin}")
endif ()
# search for local genhtml
find_program (c8_genhtml_bin genhtml)
if (NOT c8_genhtml_bin)
set (c8_genhtml_bin "${c8_lcov_install_dir}/bin/genhtml")
message ("use C8 version of genhtml ${c8_genhtml_bin}")
endif ()
set (GCOV gcov CACHE STRING "gcov executable" FORCE)
# collect coverage data
add_custom_command (
OUTPUT raw-coverage.info
COMMAND ${CMAKE_COMMAND} -E echo "Note: you need to run ctest at least once to generate the coverage data"
COMMAND ${c8_lcov_bin} --gcov-tool=${GCOV} --rc lcov_branch_coverage=1
--directory . --capture --output-file raw-coverage.info
)
# remove uninteresting entries
add_custom_command (
OUTPUT coverage.info
COMMAND ${c8_lcov_bin} -q --remove raw-coverage.info "*/usr/*" "/usr/*" --output-file coverage2.info
COMMAND ${c8_lcov_bin} --remove coverage2.info
"*/externals/*" "*/tests/*" "*/sibyll2.3d.cpp" "*/.conan/*"
"*/include/Pythia8/*" "*/install/*"
"${CMAKE_SOURCE_DIR}/modules/*" "${CMAKE_BINARY_DIR}/modules/*"
"*/cxroot/*" "*/.conan2/*" "/boost/*"
--output-file coverage.info
COMMAND ${CMAKE_COMMAND} -E remove coverage2.info
DEPENDS raw-coverage.info
)
# generate html report
add_custom_command (
OUTPUT coverage-report
COMMAND ${c8_genhtml_bin} --branch-coverage --show-details --title "CORSIKA 8 test coverage" --legend --demangle-cpp coverage.info -o coverage-report
DEPENDS coverage.info
)
add_custom_target (coverage DEPENDS coverage-report)
endif ()
#+++++++++++++++++++++++++++++
# use spdlog
# CTest config
#
add_subdirectory(externals/spdlog)
add_dependencies(CORSIKA8 spdlog::spdlog)
enable_testing ()
if (${CMAKE_VERSION} VERSION_LESS "3.12.0")
list (APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure")
else (${CMAKE_VERSION} VERSION_LESS "3.12.0")
set (CTEST_OUTPUT_ON_FAILURE 1) # this is for new versions of cmake
endif (${CMAKE_VERSION} VERSION_LESS "3.12.0")
set (CTEST_CUSTOM_COVERAGE_EXCLUDE "./tests/" "./examples/" "./modules/" "test*.(hpp/cpp)$")
# include this test only if NOT run on gitlab-ci; On CI this is a dedicated job:
if (NOT DEFINED ENV{CI})
# add call to ./do-copyright.py to run as unit-test-case
add_test (NAME copyright_notices COMMAND ./do-copyright.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
endif (NOT DEFINED ENV{CI})
#+++++++++++++++++++++++++++++
# get phys_units
# Externals
#
find_package( PhysUnits REQUIRED )
set (Python_ADDITIONAL_VERSIONS 3)
find_package (PythonInterp 3 REQUIRED)
#+++++++++++++++++++++++++++++++
# exporting of CMake targets
#
include (CMakePackageConfigHelpers)
# list of targets that will be INSTALLed and EXPORTed
# Important: all those targets must be individually INSTALLed with "EXPORT CORSIKA8PublicTargets"
set (public_CORSIKA8_targets CORSIKA8)
#+++++++++++++++++++++++++++++
# get Pythia
# CORSIKA8
#
#find_package( Pythia8 REQUIRED )
add_subdirectory(dependencies/pythia)
if(Pythia_FOUND)
include_directories(${Pythia_INCLUDE_DIR})
endif(Pythia_FOUND)
add_library (CORSIKA8 INTERFACE)
set_target_properties (
CORSIKA8
PROPERTIES
INTERFACE_CORSIKA8_MAJOR_VERSION 0
COMPATIBLE_INTERFACE_STRING CORSIKA8_MAJOR_VERSION
)
target_include_directories (
CORSIKA8
INTERFACE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
$<INSTALL_INTERFACE:include>
)
# since CORSIKA8 is a header only library we must specify all link dependencies here:
find_package(Boost COMPONENTS filesystem REQUIRED)
find_package(CLI11 REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(spdlog REQUIRED)
find_package(yaml-cpp REQUIRED)
find_package(Arrow REQUIRED)
find_package(PROPOSAL REQUIRED)
find_package(Catch2 REQUIRED)
target_link_libraries (
CORSIKA8
INTERFACE
BZip2::BZip2
Boost::filesystem
CLI11::CLI11
Eigen3::Eigen
spdlog::spdlog
yaml-cpp::yaml-cpp
Parquet::parquet_static
PROPOSAL::PROPOSAL
cnpy # for SaveBoostHistogram
)
# "src" is needed, since some headers (namely GeneratedParticleProperties.inc ec.) are produced by python script from e.g. ParticleData.xml
add_subdirectory (src)
add_subdirectory (documentation)
#+++++++++++++++++++++++++++++
# = Add of subdirectories =
#
#+++++++++++++++++++++++++++++
# get UrQMD
# modules
#
#find_package( UrQMD REQUIRED )
add_subdirectory(dependencies/urqmd)
if(UrQMD_FOUND)
include_directories(${UrQMD_INCLUDE_DIR})
endif(UrQMD_FOUND)
set (CORSIKA_DATA_WITH_TEST ON) # we want to run the corsika-data unit test
add_subdirectory (modules/data) # this is corsika-data (submodule)
add_subdirectory (modules/common)
add_subdirectory (modules/pythia8)
add_subdirectory (modules/sibyll)
add_subdirectory (modules/sophia)
add_subdirectory (modules/qgsjetII)
add_subdirectory (modules/urqmd)
add_subdirectory (modules/conex)
add_subdirectory (modules/epos)
add_subdirectory (modules/tauola)
add_subdirectory (modules/fluka)
#
#+++++++++++++++++++++++++++++
# get Sybill
#+++++++++++++++++++++++++++++++
# standard applications
#
# find_package( Sibyll REQUIRED )
add_subdirectory (dependencies/sibyll)
if(Sibyll_FOUND)
include_directories(${Sibyll_INCLUDE_DIR})
endif(Sibyll_FOUND)
add_subdirectory(applications)
#+++++++++++++++++++++++++++++++
# unit testing
#
#+++++++++++++++++++++++++++++
# get QGSJETII
add_subdirectory (tests)
#+++++++++++++++++++++++++++++++
# installation
#
#find_package( QGSJETII REQUIRED )
if(QGSJETII_FOUND)
include_directories(${QGSJETII_INCLUDE_DIR})
endif(QGSJETII_FOUND)
install (
TARGETS CORSIKA8
EXPORT CORSIKA8PublicTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}
)
#
# header only part, just copy entire directory tree
#
#+++++++++++++++++++++++++++++
# =~~~~~~~~~~~~~~~~~~~~~~~~~=
# = Add of subdirectories =
# =~~~~~~~~~~~~~~~~~~~~~~~~~=
#+++++++++++++++++++++++++++++
install (DIRECTORY corsika DESTINATION include)
#
# modules
#
#add_subdirectory (dependencies/Pythia)
#add_subdirectory (dependencies/Sibyll)
#add_subdirectory (dependencies/QGSJetII)
#add_subdirectory (dependencies/UrQMD)
# generate cmake config package version (for find_package)
#
#+++++++++++++++++++++++++++++++
# tests
#
add_subdirectory (tests/framework)
add_subdirectory (tests/media)
add_subdirectory (tests/stack)
add_subdirectory (tests/modules)
write_basic_package_version_file (
${PROJECT_BINARY_DIR}/corsikaConfigVersion.cmake
VERSION ${c8_version}
COMPATIBILITY SameMajorVersion
)
#
# export targets in build tree (for find_package)
#
export (
EXPORT CORSIKA8PublicTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/corsikaTargets.cmake"
NAMESPACE CORSIKA8::
)
#
# export targets in install tree (for find_package)
#
install (
EXPORT CORSIKA8PublicTargets
FILE corsikaTargets.cmake
NAMESPACE CORSIKA8::
DESTINATION lib/cmake/corsika
)
if(DEFINED CONAN_CMAKE_DIR)
install (
DIRECTORY conan_cmake/
DESTINATION lib/cmake/dependencies
)
endif(DEFINED CONAN_CMAKE_DIR)
#
# config for build tree (for find_package)
#
configure_package_config_file (
cmake/corsikaConfig.cmake.in
${PROJECT_BINARY_DIR}/corsikaConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}
)
#
# corsikaDefines
#
configure_package_config_file (
cmake/corsikaDefines.cmake
${PROJECT_BINARY_DIR}/corsikaDefines.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}
)
#
# config for install tree (for find_package)
# overwrite with install locations (if it was build as part of corsika)
#
set (Pythia8_INCDIR ${Pythia8_INCDIR_INSTALL})
set (Pythia8_LIBDIR ${Pythia8_LIBDIR_INSTALL})
configure_package_config_file (
cmake/corsikaConfig.cmake.in
${PROJECT_BINARY_DIR}/corsikaConfig.cmake-install
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}
)
#
# generate "corsika/corsika.hpp" file with cmake-level details and paths
# first for build-tree
#
# the location of the "corsika-data" is of fundamental importance
set (CORSIKA_CMAKE_DATA_DIR ${CMAKE_SOURCE_DIR}/modules/data)
configure_file (
src/corsika.hpp.in
${PROJECT_BINARY_DIR}/corsika/corsika.hpp
)
#
# second also for install-tree
#
set (CORSIKA_CMAKE_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/corsika/data")
configure_file (
src/corsika.hpp.in
${PROJECT_BINARY_DIR}/corsika.hpp-install
)
#
# installation of cmake and config files
#
install (
FILES
${CMAKE_BINARY_DIR}/corsikaDefines.cmake
${CMAKE_BINARY_DIR}/corsikaConfigVersion.cmake
DESTINATION lib/cmake/corsika
)
#
# install and rename install-level corsikaConfig.cmake
#
install (
FILES
${CMAKE_BINARY_DIR}/corsikaConfig.cmake-install
RENAME corsikaConfig.cmake
DESTINATION lib/cmake/corsika
)
#
# also install-level config.hpp
#
install (FILES
${PROJECT_BINARY_DIR}/corsika.hpp-install
RENAME corsika.hpp
DESTINATION include/corsika
)
#
#+++++++++++++++++++++++++++++++
# examples
#
add_subdirectory (examples)
#
install (DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DATADIR}/corsika)
#
# data
#
install (DIRECTORY modules/data DESTINATION ${CMAKE_INSTALL_DATADIR}/corsika)
#
# tools
#
add_subdirectory (tools)
#+++++++++++++++++++++++++++++++
#
# final summary output
#
include (FeatureSummary)
feature_summary (WHAT ALL)
# Collaboration agreement
The CORSIKA project very much welcomes all collaboration and
contributions. The aim of the CORSIKA project is to create a
scientific software framework as a fundamental tool for research. The
collaboration agreement and the licensing model are based on the
guidelines layed out by HSF
[[1]](https://hepsoftwarefoundation.org/activities/licensing.html) or
CERN
[[2]](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwiLqKG00dXdAhUOZFAKHdIwAh4QFjAAegQIARAC&url=https%3A%2F%2Findico.cern.ch%2Fcategory%2F4251%2Fattachments%2F101%2F505%2FOSL-2012-01-Open_Source_Licences_at_CERN-Short_version.pdf&usg=AOvVaw1n4S0PQCSeE6wbdfdhKDqF),
[[3]](http://legal.web.cern.ch/licensing/software), and follow the
examples of other big scientific software projects.
The CORSIKA project consists of the contributions from the scientific
community and individuals in a best effort to deliver the best
possible performance and physics output.
The MCnet guidelines developed by [www.montecarlonet.org](www.montecarlonet.org)
are copied in [MCNET_GUIDELINES](MCNET_GUIDELINES) -- they provide a very good
additional scope that contributors should read and consider.
All possible
liability and licensing question are only handled by the adopted
software license.
## The software license of the CORSIKA project
The license adopted for the CORSIKA project is the explicit copyleft
license GPLv3, as copied in full in the file
[LICENSE](LICENSE). Each source file of the CORSIKA project contains a
short statement of the copyright and this license. Each binary or
source code release of CORSIKA contains the file LICENSE. The
code, documentation and content in the folder [ThirdParty](ThirdParty)
is not integral part of the CORSIKA project and can be based on, or
include, other licenses, which must be compatible with GPLv3. Check the
content of this folder for details and additional license information. It depends on the configuration of
the build system to what extend this code is used to build CORSIKA.
## Contributing
If you want to contribute, you need to read
[the GUIDELINES](CONTRIBUTING.md) and comply with these rules, or help to
improve them.
## The CORSIKA Projects Maintainers
The CORSIKA Project mainters make all decisions for the CORSIKA
Project. They can also change the
[COLLABORATION\_AGREEMENT](COLLABORATION\_AGREEMENT.md), the
[GUIDELINES](CONTRIBUTING.md) or any other structure or document relevant for the CORSIKA Project.
The current CORSIKA Project maintainers are listed in the file [MAINTAINERS](MAINTAINERS.md).
and can be contacted via corsika-project@lists.kit.edu. The chair
person of the CORSIKA Project is Ralf Ulrich (KIT). Maintainers have special
responsibilities for specific parts of the project.
### Planning and performing releases
The CORSIKA maintainers decide on releases of the software, and about the content of it.
# Guidelines for code development, structure, formating etc.
The CORSIKA Project very much welcomes contributions. Here we outlined
The CORSIKA Project very much welcomes contributions. Here we outline
how you can find the right place to contribute, and how to do that.
Connect to https://gitlab.ikp.kit.edu and corsika-devel@lists.kit.edu (self-register at https://www.lists.kit.edu/sympa/subscribe/corsika-devel) to get in touch with the project.
The CORSIKA Project decides on the [GUIDELINES](CONTRIBUTING.md) and can decide to
Connect to https://gitlab.iap.kit.edu and corsika-devel@lists.kit.edu (self-register at https://www.lists.kit.edu/sympa/subscribe/corsika-devel) to get in touch with the project.
The CORSIKA Project decides on the [contributing guidelines](CONTRIBUTING.md) and can decide to
change/improve them.
# How to contribute
- We organize all development via `Issues` that may be feature requests,
- We organize all development via gitlab `Issues` that may be feature requests,
ideas, discussions, or bugs fix requests.
- New issues can be created, or existing issues
picked up or contributed to.
......@@ -19,8 +19,8 @@ change/improve them.
created directly via the gitlab web interface.
- Proposed code to close one issue (located in a specific git
branch) is reviewed, discussed, and eventually merged
into the master branch to close the issue.
- all merge request will undergo a code review, and must be approved before merge, in order to ensure high code qualtiy: [Code Approval Procedure](https://gitlab.ikp.kit.edu/AirShowerPhysics/corsika/-/wikis/Code-Approval-Procedure)
into the master branch via a merge-request (MR) to close the issue.
- all merge request will undergo a code review, and must be approved before merge, in order to ensure high code qualtiy: [Code Approval Procedure](https://gitlab.iap.kit.edu/AirShowerPhysics/corsika/-/wikis/Code-Approval-Procedure)
## Code formatting
......@@ -32,9 +32,9 @@ formatting. We provide a script `do-clang-format.sh`, which can be
very useful. But we urge everybody to integrate `clang-format` already
on the level of your source code editor. See [the official
page](https://clang.llvm.org/docs/ClangFormat.html) for information
about `clang-format` and its editor integration. At least: run
`do-clang-format.sh` prior to any `git add` command. Code with
improper formatting will not be accepted for merging.
about `clang-format` and its editor integrations. At least: run
`do-clang-format.sh` prior to any `git add/commit` command. Code with
improper formatting will not be accepted for merging. It will trigger automatic warnings by the continuous integration (CI) system.
The definition of source code format is written down in the file
[.clang-format](.clang-format) and can be changed, if the CORSIKA
......@@ -43,138 +43,35 @@ e.g. [link1](https://clangformat.com/) or
[link2](https://zed0.co.uk/clang-format-configurator/).
## Naming conventions
While `clang-format` does the structural formatting, we still need to agree on naming conventions:
- Classes and structs start with capital letters ```LikeThis```
- Class member variables start non-captial and have a trailing "_" ```likeThis_```
- Class member functions start with small letters ```LikeThis::doSomething(...)``` or ```LikeThis::do_something(...)```
- Any class setter begins with "set_" ```LikeThis::set_something(...)```
- Any class getter is named accoring to its property: ```LikeThis::something()```
- Logical getters may start with ```is_``` or ```has_```
- enums should be ```enum class```
- Named variables start with small letter ```likeThis```
- types in template definitions start with "T" ```TLikeThis```
- use names that explain and document the code, thus for example
```
TimeType TimeOfIntersection(Line const& line, Plane const& plane) {
auto const line_direction = line.GetDirection();
auto const plane_normal = plane.GetNormal();
return plane_normal.dot(plane.GetCenter()-line.GetPosition()) / plane_normal.dot(line_direction);
}
```
and not
```
TimeType TimeOfIntersection(Line const& l, Plane const& p) {
auto const d = p.GetCenter() - l.GetR0();
auto const v = l.GetV0();
auto const n = p.GetNormal();
auto const c = n.dot(v);
return n.dot(d) / c;
}
```
This actually is suffient to document the code, no further comments should be added in such cases. Only if further clarification is needed.
- We use namespaces to avoid clashes and to structure code
- *Everything* is part of one of those namespaces:
- ```corsika::framework```, ```corsika::physics```, or ```corsika::process```
- All classes and objects are encapsulated into suited sub-namespaces,
thus corsika, corsikaes, corsika::units, etc.
- Namespace names do not use capital letters.
- Every header file is copied during build and install into
"include/corsika/[namespace]" which also means, each header file
can only provide definitions for a _single_ namespace. It is one
main purpose of namespaces to structure the location of header
files.
- Each header file uses an include protection that includes at
least the namespace name, and header file name, thus, `#ifndef
__include_geometry_Point_h__` or `#ifndef __geometry_Point_h__`,
or similar are acceptable.
- Header files should always be included with `<..>`, thus,
`#include <corsika/framework/geometry/Point.hpp>` since the build system
will always provide the correct include directives (and files
anyway cannot be found in file-system paths, which generally do
not follow the namespace naming conventions outlined
here).
- Header files are named after the main class (or object) they
define. This also means each header file name starts with a
capital letter.
## Coding rules
- Warnings should be fixed, when they appear on the system(s) currently used by the CI, by altering the code unless the warning originates from third-party code and cannot be fixed. In that case, the warning should be locally silenced with appropriate pragmas or by locally turning off warnings for that translation unit.
- All unit tests must succeed on the specified systems/configurations on gitlab-ci. If tests fail, code is not merged.
- The unit test code coverage should not decrease due to a new merge request.
- We use C++17 features wherever useful and helpful.
- On any major error or malfunction we throw an exception. This is needed and required for complex physics and shower debugging.
- We never catch exceptions for error handling, there might be very few special exceptions from this. We need to discuss such cases.
- Everything that should not change should be ```const```
- Everything that does not need to be visible to the outside of a class/struct should be `private` or `protected`
- We prefer the use of references, wherever useful
- There cannot be any raw pointer in the interface of any class or object
exposed to outside users, there might be (technical) raw pointers for very special cases
inside of classes.
- (member)functions that do something (are not just getters/setters), model actions or transformations, and should therefore be verbs. Classes are nouns.
- When you contribute new code, or extend existing code, at the same time provide unit-tests for all functionality.
- When you contribute new physics algorithms, in addition you also need to provide a validation module (this is still TBD what exactly this means)
- Code must be documented with `doxygen` commands extensively -> MAKE THIS INVESTMENT OF YOUR TIME EARLY, IT REALLY HELPS
- There should not be any useless comments in code, in particular absolutely avoid to commit commented-out debug remnants
- Add sufficient and meaningful comments to the code (only in English)
## CMAKE formatting
- command are lower cases, e.g. ```set (...)```
- variables upper case, e.g. ```set (VAR1 Text)```
Since cmake itself lacks structure almost entirely:
- put a space between command and start of parenthesis, e.g. ```command (...)```
- add two spaces for logical indent
```
if (condition)
do something
endif (condition)
```
- break long lines to start with new keyword in new line (indented)
```
install (
FILES ${CORSIKAstackinterface_HEADERS}
DESTINATION include/${CORSIKAstackinterface_NAMESPACE}
)
```
- add plenty of comments to all cmake code
- use expressive variables and functions
## Coding rules, conventions and guidelines
Please read the [Coding wiki page](https://gitlab.iap.kit.edu/AirShowerPhysics/corsika/-/wikis/Coding-Conventions-and-Guidelines).
## Release versioning scheme
Releases of CORSIKA are thought to be the baseline for larger scale
testing, and full production. The releases are numbered as x.y.z,
starting with x=8 form the gitlab c++ version. X will only be
incremented for major design or physics changes. The y index is
updated for new official releases that normally contain improved or
enhanced physics performance, and may also contain normal interface
changes to accomodate improvements. The z index can be updated more
Releases of CORSIKA 8 are thought to be the baseline for larger scale
validation, and full production. The releases are numbered as CORSIKA 8 vx.y.z,
starting with x=1. The x index is updated for new releases that normally contain improved or
enhanced physics performance, and also interface
changes to accomodate improvements. The y and z indices can be updated more
frequently for bug fixes or new features. Changes in z will not
contain (major) interface changes, thus, production code will remain
fully compatible within changes of z. Special releases of CORSIKA can
also have a tag name from git, e.g. as in the "milestone1" release.
contain interface changes, thus, production code will remain
fully compatible within changes of z. Special releases of CORSIKA might
also have a release name.
# How to become scientific author of the CORSIKA Project
The CORSIKA Project decides on who becomes scientific author. The
following conditions are clearly sufficient, but not all of them are
following conditions are sufficient, but not all of them are
required all the time:
- responsibility for a particular functionality or software/management part
- have read and follow these [GUIDELINES](CONTRIBUTING.md)
- have read and follow our [contributing guidelines](CONTRIBUTING.md)
- active in the CORSIKA Project, that means responsive to
discussions and problems in corsika-devel@list.kit.edu or on https//gitlab.ikp.kit.edu,
of relevant *Issues*,
or in (phone) meetings
- agreement to the [COLLABORATION_AGREEMENT](COLLABORATION_AGREEMENT.md) is strictly required
- the members of the CORSIKA Project panel agree
discussions and problems in corsika-devel@list.kit.edu or on https//gitlab.iap.kit.edu,
of relevant *Issues*, in (phone) meetings or our Mattermost workspace
- agreement to the [using and collaborating agreement](USING_COLLABORATING.md)
- the members of the CORSIKA Project must agree
Subproject commit 4d1785e74a7bf6769ee016509b357e63d7117438
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#include <corsika/cascade/Cascade.h>
#include <corsika/environment/Environment.h>
#include <corsika/environment/LayeredSphericalAtmosphereBuilder.h>
#include <corsika/environment/NuclearComposition.h>
#include <corsika/environment/ShowerAxis.h>
#include <corsika/geometry/Plane.h>
#include <corsika/geometry/Sphere.h>
#include <corsika/process/ProcessSequence.h>
#include <corsika/process/StackProcess.h>
#include <corsika/process/longitudinal_profile/LongitudinalProfile.h>
#include <corsika/process/observation_plane/ObservationPlane.h>
#include <corsika/process/particle_cut/ParticleCut.h>
#include <corsika/process/proposal/ContinuousProcess.h>
#include <corsika/process/proposal/Interaction.h>
#include <corsika/process/track_writer/TrackWriter.h>
#include <corsika/random/RNGManager.h>
#include <corsika/setup/SetupStack.h>
#include <corsika/setup/SetupTrajectory.h>
#include <corsika/units/PhysicalUnits.h>
#include <corsika/utl/CorsikaFenv.h>
#include <corsika/process/interaction_counter/InteractionCounter.hpp>
#include <corsika/logging/Logging.h>
#include <iomanip>
#include <iostream>
#include <limits>
#include <string>
#include <typeinfo>
using namespace corsika;
using namespace corsika::process;
using namespace corsika::units;
using namespace corsika::particles;
using namespace corsika::random;
using namespace corsika::geometry;
using namespace corsika::environment;
using namespace std;
using namespace corsika::units::si;
void registerRandomStreams() {
random::RNGManager::GetInstance().RegisterRandomStream("cascade");
random::RNGManager::GetInstance().RegisterRandomStream("proposal");
random::RNGManager::GetInstance().SeedAll();
}
template <typename T>
using MyExtraEnv = environment::MediumPropertyModel<environment::UniformMagneticField<T>>;
int main(int argc, char** argv) {
logging::SetLevel(logging::level::info);
if (argc != 2) {
std::cerr << "usage: em_shower <energy/GeV>" << std::endl;
return 1;
}
feenableexcept(FE_INVALID);
// initialize random number sequence(s)
registerRandomStreams();
// setup environment, geometry
using EnvType = setup::Environment;
EnvType env;
const CoordinateSystem& rootCS = env.GetCoordinateSystem();
Point const center{rootCS, 0_m, 0_m, 0_m};
auto builder = environment::make_layered_spherical_atmosphere_builder<
setup::EnvironmentInterface,
MyExtraEnv>::create(center, units::constants::EarthRadius::Mean,
environment::Medium::AirDry1Atm,
geometry::Vector{rootCS, 0_T, 50_uT, 0_T});
builder.setNuclearComposition(
{{particles::Code::Nitrogen, particles::Code::Oxygen},
{0.7847f, 1.f - 0.7847f}}); // values taken from AIRES manual, Ar removed for now
builder.addExponentialLayer(1222.6562_g / (1_cm * 1_cm), 994186.38_cm, 4_km);
builder.addExponentialLayer(1144.9069_g / (1_cm * 1_cm), 878153.55_cm, 10_km);
builder.addExponentialLayer(1305.5948_g / (1_cm * 1_cm), 636143.04_cm, 40_km);
builder.addExponentialLayer(540.1778_g / (1_cm * 1_cm), 772170.16_cm, 100_km);
builder.addLinearLayer(1e9_cm, 112.8_km);
builder.assemble(env);
// setup particle stack, and add primary particle
setup::Stack stack;
stack.Clear();
const Code beamCode = Code::Electron;
auto const mass = particles::GetMass(beamCode);
const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[1]));
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 = corsika::stack::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.norm()
<< endl;
auto const observationHeight = 1.4_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 +
Vector<dimensionless_d>{rootCS, {-sin(thetaRad), 0, cos(thetaRad)}} * t;
std::cout << "point of injection: " << injectionPos.GetCoordinates() << std::endl;
stack.AddParticle(
std::tuple<particles::Code, units::si::HEPEnergyType,
corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
beamCode, E0, plab, injectionPos, 0_ns});
std::cout << "shower axis length: " << (showerCore - injectionPos).norm() * 1.02
<< std::endl;
environment::ShowerAxis const showerAxis{injectionPos,
(showerCore - injectionPos) * 1.02, env};
// setup processes, decays and interactions
// PROPOSAL processs proposal{...};
process::particle_cut::ParticleCut cut(10_GeV, false, true);
process::proposal::Interaction proposal(env, cut.GetECut());
process::proposal::ContinuousProcess em_continuous(env, cut.GetECut());
process::interaction_counter::InteractionCounter proposalCounted(proposal);
process::track_writer::TrackWriter trackWriter("tracks.dat");
// long. profile; columns for gamma, e+, e- still need to be added
process::longitudinal_profile::LongitudinalProfile longprof{showerAxis};
Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.}));
process::observation_plane::ObservationPlane observationLevel(
obsPlane, Vector<dimensionless_d>(rootCS, {1., 0., 0.}), "particles.dat");
auto sequence = process::sequence(proposalCounted, em_continuous, longprof, cut,
observationLevel, trackWriter);
// define air shower object, run simulation
setup::Tracking tracking;
cascade::Cascade EAS(env, tracking, sequence, stack);
// to fix the point of first interaction, uncomment the following two lines:
// EAS.SetNodes();
// EAS.forceInteraction();
EAS.Run();
cut.ShowResults();
em_continuous.showResults();
observationLevel.ShowResults();
const HEPEnergyType Efinal = cut.GetCutEnergy() + cut.GetInvEnergy() +
cut.GetEmEnergy() + em_continuous.energyLost() +
observationLevel.GetEnergyGround();
cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl
<< "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl;
observationLevel.Reset();
cut.Reset();
em_continuous.reset();
auto const hists = proposalCounted.GetHistogram();
hists.saveLab("inthist_lab_emShower.npz");
hists.saveCMS("inthist_cms_emShower.npz");
longprof.save("longprof_emShower.txt");
}
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* 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/process/interaction_counter/InteractionCounter.hpp>
/* clang-format on */
#include <corsika/cascade/Cascade.h>
#include <corsika/environment/Environment.h>
#include <corsika/environment/FlatExponential.h>
#include <corsika/environment/LayeredSphericalAtmosphereBuilder.h>
#include <corsika/environment/NuclearComposition.h>
#include <corsika/environment/ShowerAxis.h>
#include <corsika/geometry/Plane.h>
#include <corsika/geometry/Sphere.h>
#include <corsika/logging/Logging.h>
#include <corsika/process/ProcessSequence.h>
#include <corsika/process/SwitchProcessSequence.h>
#include <corsika/process/StackProcess.h>
#include <corsika/process/conex_source_cut/CONEXSourceCut.h>
#include <corsika/process/energy_loss/EnergyLoss.h>
#include <corsika/process/longitudinal_profile/LongitudinalProfile.h>
#include <corsika/process/observation_plane/ObservationPlane.h>
#include <corsika/process/on_shell_check/OnShellCheck.h>
#include <corsika/process/particle_cut/ParticleCut.h>
#include <corsika/process/pythia/Decay.h>
#include <corsika/process/sibyll/Decay.h>
#include <corsika/process/sibyll/Interaction.h>
#include <corsika/process/sibyll/NuclearInteraction.h>
#include <corsika/process/urqmd/UrQMD.h>
#include <corsika/random/RNGManager.h>
#include <corsika/setup/SetupStack.h>
#include <corsika/setup/SetupTrajectory.h>
#include <corsika/units/PhysicalUnits.h>
#include <corsika/utl/CorsikaFenv.h>
#include <iomanip>
#include <iostream>
#include <limits>
#include <string>
using namespace corsika;
using namespace corsika::process;
using namespace corsika::units;
using namespace corsika::particles;
using namespace corsika::random;
using namespace corsika::geometry;
using namespace corsika::environment;
using namespace std;
using namespace corsika::units::si;
void registerRandomStreams(const int seed) {
random::RNGManager::GetInstance().RegisterRandomStream("cascade");
random::RNGManager::GetInstance().RegisterRandomStream("qgsjet");
random::RNGManager::GetInstance().RegisterRandomStream("sibyll");
random::RNGManager::GetInstance().RegisterRandomStream("pythia");
random::RNGManager::GetInstance().RegisterRandomStream("urqmd");
random::RNGManager::GetInstance().RegisterRandomStream("proposal");
if (seed == 0)
random::RNGManager::GetInstance().SeedAll();
else
random::RNGManager::GetInstance().SeedAll(seed);
}
template <typename T>
using MyExtraEnv = environment::MediumPropertyModel<environment::UniformMagneticField<T>>;
int main(int argc, char** argv) {
logging::SetLevel(logging::level::info);
C8LOG_INFO("hybrid_MC");
if (argc < 4) {
std::cerr << "usage: hybrid_MC <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);
// setup environment, geometry
using EnvType = setup::Environment;
EnvType env;
const CoordinateSystem& rootCS = env.GetCoordinateSystem();
Point const center{rootCS, 0_m, 0_m, 0_m};
auto builder = environment::make_layered_spherical_atmosphere_builder<
setup::EnvironmentInterface,
MyExtraEnv>::create(center, units::constants::EarthRadius::Mean,
environment::Medium::AirDry1Atm,
geometry::Vector{rootCS, 0_T, 50_uT, 0_T});
builder.setNuclearComposition(
{{particles::Code::Nitrogen, particles::Code::Oxygen},
{0.7847f, 1.f - 0.7847f}}); // values taken from AIRES manual, Ar removed for now
builder.addExponentialLayer(1222.6562_g / (1_cm * 1_cm), 994186.38_cm, 4_km);
builder.addExponentialLayer(1144.9069_g / (1_cm * 1_cm), 878153.55_cm, 10_km);
builder.addExponentialLayer(1305.5948_g / (1_cm * 1_cm), 636143.04_cm, 40_km);
builder.addExponentialLayer(540.1778_g / (1_cm * 1_cm), 772170.16_cm, 100_km);
builder.addLinearLayer(1e9_cm, 112.8_km);
builder.assemble(env);
// 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 = particles::GetNucleusMass(A, Z);
const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3]));
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 = corsika::stack::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.norm()
<< endl;
auto const observationHeight = 0_km + builder.getEarthRadius();
auto const injectionHeight = 112.75_km + builder.getEarthRadius();
auto const t = -observationHeight * cos(thetaRad) +
sqrt(-units::static_pow<2>(sin(thetaRad) * observationHeight) +
units::static_pow<2>(injectionHeight));
Point const showerCore{rootCS, 0_m, 0_m, observationHeight};
Point const injectionPos =
showerCore +
Vector<dimensionless_d>{rootCS, {-sin(thetaRad), 0, cos(thetaRad)}} * t;
std::cout << "point of injection: " << injectionPos.GetCoordinates() << std::endl;
if (A != 1) {
stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
corsika::stack::MomentumVector, geometry::Point,
units::si::TimeType, unsigned short, unsigned short>{
beamCode, E0, plab, injectionPos, 0_ns, A, Z});
} else {
stack.AddParticle(
std::tuple<particles::Code, units::si::HEPEnergyType,
corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
particles::Code::Proton, E0, plab, injectionPos, 0_ns});
}
std::cout << "shower axis length: " << (showerCore - injectionPos).norm() * 1.02
<< std::endl;
environment::ShowerAxis const showerAxis{injectionPos,
(showerCore - injectionPos) * 1.02, env};
// setup processes, decays and interactions
process::sibyll::Interaction sibyll;
process::interaction_counter::InteractionCounter sibyllCounted(sibyll);
process::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
process::interaction_counter::InteractionCounter sibyllNucCounted(sibyllNuc);
process::pythia::Decay decayPythia;
// use sibyll decay routine for decays of particles unknown to pythia
process::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();
process::particle_cut::ParticleCut cut{60_GeV, false, true};
process::energy_loss::EnergyLoss eLoss{showerAxis, cut.GetECut()};
corsika::process::conex_source_cut::CONEXSourceCut conex(
center, showerAxis, t, injectionHeight, E0,
particles::GetPDG(particles::Code::Proton));
process::on_shell_check::OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false);
process::longitudinal_profile::LongitudinalProfile longprof{showerAxis};
Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.}));
process::observation_plane::ObservationPlane observationLevel(
obsPlane, Vector<dimensionless_d>(rootCS, {1., 0., 0.}), "particles.dat");
process::UrQMD::UrQMD urqmd;
process::interaction_counter::InteractionCounter urqmdCounted{urqmd};
// assemble all processes into an ordered process list
struct EnergySwitch {
HEPEnergyType cutE_;
EnergySwitch(HEPEnergyType cutE)
: cutE_(cutE) {}
process::SwitchResult operator()(const setup::Stack::ParticleType& p) {
if (p.GetEnergy() < cutE_)
return process::SwitchResult::First;
else
return process::SwitchResult::Second;
}
};
auto hadronSequence =
process::select(urqmdCounted, process::sequence(sibyllNucCounted, sibyllCounted),
EnergySwitch(55_GeV));
auto decaySequence = process::sequence(decayPythia, decaySibyll);
auto sequence = process::sequence(hadronSequence, reset_particle_mass, decaySequence,
eLoss, cut, conex, longprof, observationLevel);
// define air shower object, run simulation
setup::Tracking tracking;
cascade::Cascade EAS(env, tracking, sequence, stack);
// to fix the point of first interaction, uncomment the following two lines:
// EAS.SetNodes();
// EAS.forceInteraction();
EAS.Run();
cut.ShowResults();
eLoss.showResults();
observationLevel.ShowResults();
const HEPEnergyType Efinal = cut.GetCutEnergy() + cut.GetInvEnergy() +
cut.GetEmEnergy() + eLoss.energyLost() +
observationLevel.GetEnergyGround();
cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl
<< "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl;
observationLevel.Reset();
cut.Reset();
eLoss.reset();
conex.SolveCE();
auto const hists = sibyllCounted.GetHistogram() + sibyllNucCounted.GetHistogram() +
urqmdCounted.GetHistogram();
hists.saveLab("inthist_lab.txt");
hists.saveCMS("inthist_cms.txt");
hists.saveLab("inthist_lab.txt");
hists.saveCMS("inthist_cms.txt");
longprof.save("longprof.txt");
std::ofstream finish("finished");
finish << "run completed without error" << std::endl;
}
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#include <corsika/particles/ParticleProperties.h>
#include <corsika/process/ProcessSequence.h>
#include <corsika/process/qgsjetII/ParticleConversion.h>
#include <corsika/process/sibyll/ParticleConversion.h>
#include <corsika/setup/SetupEnvironment.h>
#include <corsika/units/PhysicalUnits.h>
#include <iomanip>
#include <iostream>
#include <string>
using namespace corsika::units;
using namespace corsika::units::si;
using namespace corsika::particles;
using namespace std;
//
// The example main program for a particle list
//
int main() {
std::cout << "particle_list_example" << std::endl;
cout << "------------------------------------------"
<< "particles in CORSIKA"
<< "------------------------------------------" << endl;
cout << std::setw(20) << "Name"
<< " | " << std::setw(10) << "PDG-id"
<< " | " << std::setw(10) << "SIBYLL-id"
<< " | " << std::setw(10) << "QGSJETII-id"
<< " | " << std::setw(18) << "PDG-mass (GeV)"
<< " | " << std::setw(18) << "SIBYLL-mass (GeV)"
<< " | " << endl;
cout << std::setw(104) << std::setfill('-') << "-" << endl;
for (auto p : getAllParticles()) {
if (!IsNucleus(p)) {
corsika::process::sibyll::SibyllCode sib_id =
corsika::process::sibyll::ConvertToSibyll(p);
auto const sib_mass =
(sib_id != corsika::process::sibyll::SibyllCode::Unknown
? to_string(corsika::process::sibyll::GetSibyllMass(p) / 1_GeV)
: "--");
auto const qgs_id = corsika::process::qgsjetII::ConvertToQgsjetII(p);
cout << std::setw(20) << std::setfill(' ') << p << " | " << std::setw(10)
<< static_cast<int>(GetPDG(p)) << " | " << std::setw(10)
<< (sib_id != corsika::process::sibyll::SibyllCode::Unknown
? to_string(static_cast<int>(sib_id))
: "--")
<< " | " << std::setw(10)
<< (qgs_id != corsika::process::qgsjetII::QgsjetIICode::Unknown
? to_string(static_cast<int>(qgs_id))
: "--")
<< " | " << std::setw(18) << std::setprecision(5) << GetMass(p) / 1_GeV
<< " | " << std::setw(18) << std::setprecision(5) << sib_mass << " | " << endl;
}
}
cout << std::setw(104) << std::setfill('-') << "-" << endl;
}
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
namespace corsika::environment {
/**
* Medium types are useful most importantly for effective models
* like energy losses. a particular medium (mixture of components)
* may have specif properties not reflected by its mixture of
* components.
**/
enum class MediumType {
Unknown,
Element,
RadioactiveElement,
InorganicCompound,
OrganicCompound,
Polymer,
Mixture,
BiologicalDosimetry
};
enum class State { Unknown, Solid, Liquid, Gas, DiatomicGas };
enum class Medium : int16_t;
using MediumIntType = std::underlying_type<Medium>::type;
/**
* \struct MediumData
*
* Simple object to group together a number of properties
*
**/
struct MediumData {
std::string name_;
std::string pretty_name_;
double weight_;
int weight_significant_figure_;
int weight_error_last_digit_;
double Z_over_A_;
double sternheimer_density_;
double corrected_density_;
State state_;
MediumType type_;
std::string symbol_;
double Ieff_;
double Cbar_;
double x0_;
double x1_;
double aa_;
double sk_;
double dlt0_;
std::string name() const { return name_; }
std::string pretty_name() const { return pretty_name_; }
double weight() const { return weight_; }
int weight_significant_figure() const { return weight_significant_figure_; }
int weight_error_last_digit() const { return weight_error_last_digit_; }
double Z_over_A() const { return Z_over_A_; }
double sternheimer_density() const { return sternheimer_density_; }
double corrected_density() const { return corrected_density_; }
State state() const { return state_; }
MediumType type() const { return type_; }
std::string symbol() const { return symbol_; }
double Ieff() const { return Ieff_; }
double Cbar() const { return Cbar_; }
double x0() const { return x0_; }
double x1() const { return x1_; }
double aa() const { return aa_; }
double sk() const { return sk_; }
double dlt0() const { return dlt0_; }
};
} // namespace corsika::environment
#include <corsika/environment/GeneratedMediaProperties.inc>
namespace corsika::environment {
constexpr MediumData const& mediumData(Medium const m) {
return detail::medium_data[static_cast<MediumIntType>(m)];
}
} // namespace corsika::environment
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
namespace corsika::environment {
/**
* Medium types are useful most importantly for effective models
* like energy losses. a particular medium (mixture of components)
* may have specif properties not reflected by its mixture of
* components.
*/
enum class EMediumType { eUnknown, eAir, eWater, eIce, eRock };
} // namespace corsika::environment
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
#include <corsika/environment/IMagneticFieldModel.h>
#include <corsika/geometry/RootCoordinateSystem.h>
namespace corsika::environment {
/**
* A uniform (constant) magnetic field.
*
* This class returns the same magnetic field vector
* for all evaluated locations.
*
*/
template <typename T>
class NoMagneticField : public T {
// a type-alias for a magnetic field vector
using MagneticFieldVector =
corsika::geometry::Vector<corsika::units::si::magnetic_flux_density_d>;
public:
/**
* Construct a NoMagneticField.
*
* This is initialized with a fixed magnetic field
* and returns this magnetic field at all locations.
*
* @param field The fixed magnetic field to return.
*/
template <typename... Args>
NoMagneticField(Args&&... args)
: T(std::forward<Args>(args)...) {}
/**
* Evaluate the magnetic field at a given location.
*
* @param point The location to evaluate the field at.
* @returns The magnetic field vector.
*/
MagneticFieldVector GetMagneticField(
corsika::geometry::Point const&) const final override {
CoordinateSystem const& gCS =
RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
return MagneticFieldVector(gCS, {0_T, 0_T, 0_T});
}
}; // END: class MagneticField
} // namespace corsika::environment
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#include <corsika/environment/ShowerAxis.h>
#include <corsika/logging/Logging.h>
#include <string>
using namespace corsika::environment;
using namespace corsika::units::si;
using namespace corsika;
GrammageType ShowerAxis::X(LengthType l) const {
double const fractionalBin = l / steplength_;
int const lower = fractionalBin; // indices of nearest X support points
double const frac = fractionalBin - lower;
unsigned int const upper = lower + 1;
if (fractionalBin < 0) {
C8LOG_ERROR("cannot extrapolate to points behind point of injection l={} m", l / 1_m);
if (throw_) {
throw std::runtime_error("cannot extrapolate to points behind point of injection");
}
return minimumX();
}
if (upper >= X_.size()) {
const std::string err =
fmt::format("shower axis too short, cannot extrapolate (l / max_length_ = {} )",
l / max_length_);
C8LOG_ERROR(err);
if (throw_) { throw std::runtime_error(err.c_str()); }
return maximumX();
}
C8LOG_TRACE("showerAxis::X frac={}, fractionalBin={}, lower={}, upper={}", frac,
fractionalBin, lower, upper);
assert(0 <= frac && frac <= 1.);
C8LOG_TRACE("ShowerAxis::X l={} m, lower={}, frac={}, upper={}", l / 1_m, lower, frac,
upper);
// linear interpolation between X[lower] and X[upper]
return X_[upper] * frac + X_[lower] * (1 - frac);
}
LengthType ShowerAxis::steplength() const { return steplength_; }
GrammageType ShowerAxis::maximumX() const { return *X_.rbegin(); }
GrammageType ShowerAxis::minimumX() const { return GrammageType::zero(); }
GrammageType ShowerAxis::projectedX(geometry::Point const& p) const {
auto const projectedLength = (p - pointStart_).dot(axis_normalized_);
return X(projectedLength);
}
geometry::Vector<units::si::dimensionless_d> const& ShowerAxis::GetDirection() const {
return axis_normalized_;
}
geometry::Point const& ShowerAxis::GetStart() const { return pointStart_; }
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
#include <corsika/environment/Environment.h>
#include <corsika/geometry/Point.h>
#include <corsika/geometry/Vector.h>
#include <corsika/units/PhysicalUnits.h>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <vector>
#include <iostream>
#include <boost/math/quadrature/gauss_kronrod.hpp>
namespace corsika::environment {
/**
* \class ShowerAxis
*
* The environment::ShowerAxis is created from a geometry::Point and
* a geometry::Vector and inside an Environment. It internally uses
* a table with steps=10000 (default) rows for interpolation.
*
* The shower axis can convert location in the shower into a
* projected grammage along the shower axis.
*
**/
class ShowerAxis {
public:
template <typename TEnvModel>
ShowerAxis(geometry::Point const& pStart,
geometry::Vector<units::si::length_d> length,
environment::Environment<TEnvModel> const& env, bool doThrow = false,
int steps = 10'000)
: pointStart_(pStart)
, length_(length)
, throw_(doThrow)
, max_length_(length_.norm())
, steplength_(max_length_ / steps)
, axis_normalized_(length / max_length_)
, X_(steps + 1) {
auto const* const universe = env.GetUniverse().get();
auto rho = [pStart, length, universe](double x) {
auto const p = pStart + length * x;
auto const* node = universe->GetContainingNode(p);
return node->GetModelProperties().GetMassDensity(p).magnitude();
};
double error;
int k = 0;
X_[0] = units::si::GrammageType::zero();
auto sum = units::si::GrammageType::zero();
for (int i = 1; i <= steps; ++i) {
auto const x_prev = (i - 1.) / steps;
auto const d_prev = max_length_ * x_prev;
auto const x = double(i) / steps;
auto const r = boost::math::quadrature::gauss_kronrod<double, 15>::integrate(
rho, x_prev, x, 15, 1e-9, &error);
auto const result =
units::si::MassDensityType(phys::units::detail::magnitude_tag, r) *
max_length_;
sum += result;
X_[i] = sum;
for (; sum > k * X_binning_; ++k) {
d_.emplace_back(d_prev + k * X_binning_ * steplength_ / result);
}
}
assert(std::is_sorted(X_.cbegin(), X_.cend()));
assert(std::is_sorted(d_.cbegin(), d_.cend()));
}
units::si::LengthType steplength() const;
units::si::GrammageType maximumX() const;
units::si::GrammageType minimumX() const;
units::si::GrammageType projectedX(geometry::Point const& p) const;
units::si::GrammageType X(units::si::LengthType) const;
geometry::Vector<units::si::dimensionless_d> const& GetDirection() const;
geometry::Point const& GetStart() const;
private:
geometry::Point const pointStart_;
geometry::Vector<units::si::length_d> const length_;
bool throw_ = false;
units::si::LengthType const max_length_, steplength_;
geometry::Vector<units::si::dimensionless_d> const axis_normalized_;
std::vector<units::si::GrammageType> X_;
// for storing the lengths corresponding to equidistant X values
units::si::GrammageType const X_binning_ = std::invoke([]() {
using namespace units::si;
return 1_g / 1_cm / 1_cm;
});
std::vector<units::si::LengthType> d_;
};
} // namespace corsika::environment
/*
* (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#include <corsika/environment/DensityFunction.h>
#include <corsika/environment/HomogeneousMedium.h>
#include <corsika/environment/IMediumModel.h>
#include <corsika/environment/NuclearComposition.h>
#include <corsika/environment/ShowerAxis.h>
#include <corsika/environment/VolumeTreeNode.h>
#include <corsika/geometry/Line.h>
#include <corsika/geometry/RootCoordinateSystem.h>
#include <corsika/geometry/Vector.h>
#include <corsika/particles/ParticleProperties.h>
#include <corsika/units/PhysicalUnits.h>
#include <catch2/catch.hpp>
using namespace corsika::geometry;
using namespace corsika::environment;
using namespace corsika::particles;
using namespace corsika::units;
using namespace corsika::units::si;
using namespace corsika;
const auto density = 1_kg / (1_m * 1_m * 1_m);
auto setupEnvironment(particles::Code vTargetCode) {
// setup environment, geometry
auto env = std::make_unique<environment::Environment<environment::IMediumModel>>();
auto& universe = *(env->GetUniverse());
const geometry::CoordinateSystem& cs = env->GetCoordinateSystem();
auto theMedium =
environment::Environment<environment::IMediumModel>::CreateNode<geometry::Sphere>(
geometry::Point{cs, 0_m, 0_m, 0_m},
1_km * std::numeric_limits<double>::infinity());
using MyHomogeneousModel = environment::HomogeneousMedium<environment::IMediumModel>;
theMedium->SetModelProperties<MyHomogeneousModel>(
density, environment::NuclearComposition(std::vector<particles::Code>{vTargetCode},
std::vector<float>{1.}));
auto const* nodePtr = theMedium.get();
universe.AddChild(std::move(theMedium));
return std::make_tuple(std::move(env), &cs, nodePtr);
}
TEST_CASE("Homogeneous Density") {
auto [env, csPtr, nodePtr] = setupEnvironment(particles::Code::Nitrogen);
auto const& cs = *csPtr;
[[maybe_unused]] auto const& env_dummy = env;
[[maybe_unused]] auto const& node_dummy = nodePtr;
auto const observationHeight = 0_km;
auto const injectionHeight = 10_km;
auto const t = -observationHeight + injectionHeight;
Point const showerCore{cs, 0_m, 0_m, observationHeight};
Point const injectionPos = showerCore + Vector<dimensionless_d>{cs, {0, 0, 1}} * t;
environment::ShowerAxis const showerAxis{injectionPos, (showerCore - injectionPos),
*env,
false, // -> do not throw exceptions
20}; // -> number of bins
CHECK(showerAxis.steplength() == 500_m);
CHECK(showerAxis.maximumX() / (10_km * density) == Approx(1).epsilon(1e-8));
CHECK(showerAxis.minimumX() == 0_g / square(1_cm));
const Point p{cs, 10_km, 20_km, 8.3_km};
CHECK(showerAxis.projectedX(p) / (1.7_km * density) == Approx(1).epsilon(1e-8));
const units::si::LengthType d = 6.789_km;
CHECK(showerAxis.X(d) / (d * density) == Approx(1).epsilon(1e-8));
const Vector<dimensionless_d> dir{cs, {0, 0, -1}};
CHECK(showerAxis.GetDirection().GetComponents(cs) == dir.GetComponents(cs));
CHECK(showerAxis.GetStart().GetCoordinates() == injectionPos.GetCoordinates());
}
This diff is collapsed.