diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index d878d6dc..7a32d959 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -10,6 +10,7 @@ jobs: matrix: #os: [ubuntu-20.04, windows-2019, macos-11] os: [ubuntu-20.04, macos-11] + arch: [x86_64, auto32, auto64, aarch64, ppc64le, s390x, arm64] steps: - name: Checkout LeptonInjector diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c147ab3..dbff4e3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,26 +58,8 @@ else() endif() # load python and pybind11 +include(Python) include(pybind11) -if(CMAKE_VERSION VERSION_LESS 3.12.0) - if(Python_ROOT_DIR) - MESSAGE(WARNING "Python_ROOT_DIR is set but will be ignored by this version of CMake; set PYTHON_EXECUTABLE instead") - endif() - find_package(PythonInterp) - find_package(PythonLibs) - set(PYTHON_FOUND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) -else() - if(PYTHON_EXECUTABLE) - MESSAGE(WARNING "PYTHON_EXECUTABLE is set but will be ignored by this version of CMake; set Python_ROOT_DIR instead") - endif() - find_package(Python COMPONENTS Interpreter Development) - set(PYTHON_FOUND Python_Interpreter_FOUND AND Python_Development_FOUND) - set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}") - set(PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}") - set(PYTHON_LIBRARIES "${Python_LIBRARIES}") - set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}") - set(PYTHON_VERSION_MINOR "${Python_VERSION_MINOR}") -endif() # load project dependencies include(rk) @@ -105,33 +87,35 @@ add_library(LeptonInjector SHARED) set_property(TARGET LeptonInjector PROPERTY POSITION_INDEPENDENT_CODE ON) if(${MACOSX}) target_link_libraries(LeptonInjector - LI_utilities - LI_serialization - LI_math - LI_dataclasses - LI_geometry - LI_detector - LI_crosssections - LI_distributions - LI_injection - rk - delabella + PRIVATE + PUBLIC + delabella_shared + photospline + LI_utilities + LI_serialization + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections + LI_distributions + LI_injection ) else() target_link_libraries(LeptonInjector - LI_utilities - LI_serialization - LI_math - LI_dataclasses - LI_geometry - LI_detector - LI_crosssections - LI_distributions - LI_injection - -Wl,--whole-archive - rk - delabella - -Wl,--no-whole-archive + PRIVATE + PUBLIC + photospline + delabella_shared + LI_utilities + LI_serialization + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections + LI_distributions + LI_injection ) endif() @@ -144,15 +128,48 @@ if(DEFINED SKBUILD) message(STATUS "Setting LeptonInjector install lib dir to: ${CI_INSTALL_PREFIX}/lib") message(STATUS "Setting LeptonInjector install include dir to: ${CI_INSTALL_PREFIX}/include") install(TARGETS LeptonInjector + delabella_shared + LI_utilities + LI_serialization + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections + LI_distributions + LI_injection + EXPORT ${PROJECT_NAME}Config LIBRARY DESTINATION "${CI_INSTALL_PREFIX}/lib" PUBLIC_HEADER DESTINATION "${CI_INSTALL_PREFIX}/include") else() install(TARGETS LeptonInjector + delabella_shared + LI_utilities + LI_serialization + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections + LI_distributions + LI_injection + EXPORT ${PROJECT_NAME}Config LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/leptoninjector.libs PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() else() install(TARGETS LeptonInjector + delabella_shared + LI_utilities + LI_serialization + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections + LI_distributions + LI_injection + EXPORT ${PROJECT_NAME}Config LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() @@ -201,9 +218,30 @@ if(DEFINED SKBUILD) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/leptoninjector) install(TARGETS injection LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/leptoninjector) - install(FILES ${PROJECT_SOURCE_DIR}/python/__init__.py DESTINATION ${CMAKE_INSTALL_LIBDIR}/leptoninjector) + install(FILES ${PROJECT_SOURCE_DIR}/python/__init__.py + DESTINATION ${CMAKE_INSTALL_LIBDIR}/leptoninjector) endif() +# Export targets for use in downstream CMake projects +# ----------------------------------------------------------------------------- +include(CMakePackageConfigHelpers) +# Make importable from build directory +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) +export(EXPORT ${PROJECT_NAME}Config FILE ${PROJECT_NAME}Config.cmake) + +# Make importable from install location +set(_config_dir share/${PROJECT_NAME}/cmake) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${_config_dir} +) +install(EXPORT ${PROJECT_NAME}Config + DESTINATION ${_config_dir} +) + MESSAGE("") MESSAGE("Done!") MESSAGE("Run `make` then `make install`") diff --git a/cmake/Packages/Python.cmake b/cmake/Packages/Python.cmake index 9b1e6b16..c79b2874 100644 --- a/cmake/Packages/Python.cmake +++ b/cmake/Packages/Python.cmake @@ -2,14 +2,23 @@ IF(CMAKE_VERSION VERSION_LESS 3.12.0) IF(Python_ROOT_DIR) MESSAGE(WARNING "Python_ROOT_DIR is set but will be ignored by this version of CMake; set PYTHON_EXECUTABLE instead") ENDIF(Python_ROOT_DIR) - find_package(PythonInterp) - find_package(PythonLibs) + IF(PYTHON_VERSION) + find_package(PythonInterp ${PYTHON_VERSION}) + find_package(PythonLibs ${PYTHON_VERSION}) + ELSE(PYTHON_VERSION) + find_package(PythonInterp) + find_package(PythonLibs) + ENDIF(PYTHON_VERSION) set(PYTHON_FOUND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) ELSE() IF(PYTHON_EXECUTABLE) MESSAGE(WARNING "PYTHON_EXECUTABLE is set but will be ignored by this version of CMake; set Python_ROOT_DIR instead") ENDIF(PYTHON_EXECUTABLE) - FIND_PACKAGE(Python COMPONENTS Interpreter Development) + IF(PYTHON_VERSION) + FIND_PACKAGE(Python ${PYTHON_VERSION} COMPONENTS Interpreter Development) + ELSE(PYTHON_VERSION) + FIND_PACKAGE(Python COMPONENTS Interpreter Development) + ENDIF(PYTHON_VERSION) SET(PYTHON_FOUND "${Python_FOUND}") SET(PYTHON_EXECUTABLE "${Python_EXECUTABLE}") SET(PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}") diff --git a/cmake/Packages/cereal.cmake b/cmake/Packages/cereal.cmake index df8ac12c..86b3fbbd 100644 --- a/cmake/Packages/cereal.cmake +++ b/cmake/Packages/cereal.cmake @@ -22,5 +22,5 @@ endif() set(JUST_INSTALL_CEREAL ON CACHE INTERNAL "Cereal just install library.") set(SKIP_PORTABILITY_TEST ON CACHE INTERNAL "Skip cereal portability tests.") set(SKIP_PERFORMANCE_COMPARISON ON CACHE INTERNAL "Skip cereal performance comparison.") -add_subdirectory("${PROJECT_SOURCE_DIR}/vendor/cereal" "extern/cereal" EXCLUDE_FROM_ALL) +add_subdirectory("${PROJECT_SOURCE_DIR}/vendor/cereal" "extern/cereal") include_directories("${PROJECT_SOURCE_DIR}/vendor/cereal/include") diff --git a/cmake/Packages/delabella.cmake b/cmake/Packages/delabella.cmake index 53c4314c..bfe5c53e 100644 --- a/cmake/Packages/delabella.cmake +++ b/cmake/Packages/delabella.cmake @@ -19,4 +19,14 @@ if(NOT EXISTS "${PROJECT_SOURCE_DIR}/vendor/delabella/CMakeLists.txt") message(FATAL_ERROR "The delabella submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") endif() -add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/delabella EXCLUDE_FROM_ALL) +add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/delabella) +#add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/delabella) +#install(TARGETS delabella_shared +# ARCHIVE DESTINATION lib) +#set(_config_dir share/delabella/cmake) +#install(FILES "${CMAKE_CURRENT_BINARY_DIR}/delabellaConfigVersion.cmake" +# DESTINATION ${_config_dir} +#) +#install(EXPORT delabellaConfig +# DESTINATION ${_config_dir} +#) diff --git a/cmake/Packages/photospline.cmake b/cmake/Packages/photospline.cmake index d0ab9e32..7394fb6c 100644 --- a/cmake/Packages/photospline.cmake +++ b/cmake/Packages/photospline.cmake @@ -19,7 +19,8 @@ if(NOT EXISTS "${PROJECT_SOURCE_DIR}/vendor/photospline/CMakeLists.txt") message(FATAL_ERROR "The photospline submodule was not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") endif() -add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/photospline EXCLUDE_FROM_ALL) +#add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/photospline EXCLUDE_FROM_ALL) +add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/photospline) if(DEFINED SKBUILD) if(${CIBUILDWHEEL}) message(STATUS "Setting photospline install lib dir to: ${CI_INSTALL_PREFIX}/lib") @@ -42,6 +43,6 @@ if(DEFINED SKBUILD) # LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/leptoninjector.libs # PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) else() - install(TARGETS photospline DESTINATION ${CMAKE_INSTALL_LIBDIR}) + #install(TARGETS photospline DESTINATION ${CMAKE_INSTALL_LIBDIR}) #install(TARGETS spglam DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() diff --git a/cmake/testing.cmake b/cmake/testing.cmake index ecd096c4..143dc604 100644 --- a/cmake/testing.cmake +++ b/cmake/testing.cmake @@ -13,7 +13,7 @@ set_target_properties(gmock_main PROPERTIES FOLDER extern) macro(package_add_test TESTNAME) add_executable(${TESTNAME} ${ARGN}) target_link_libraries(${TESTNAME} gtest gmock gtest_main LeptonInjector) - add_dependencies(${TESTNAME} rk) + add_dependencies(${TESTNAME} rk_static) add_test(NAME ${TESTNAME} COMMAND ${TESTNAME} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) set_target_properties(${TESTNAME} PROPERTIES FOLDER tests) endmacro() diff --git a/projects/crosssections/CMakeLists.txt b/projects/crosssections/CMakeLists.txt index 20ade2d9..79221590 100644 --- a/projects/crosssections/CMakeLists.txt +++ b/projects/crosssections/CMakeLists.txt @@ -7,28 +7,28 @@ LIST (APPEND crosssections_SOURCES ${PROJECT_SOURCE_DIR}/projects/crosssections/private/DipoleFromTable.cxx ${PROJECT_SOURCE_DIR}/projects/crosssections/private/NeutrissimoDecay.cxx ${PROJECT_SOURCE_DIR}/projects/crosssections/private/DISFromSpline.cxx + ${PROJECT_SOURCE_DIR}/projects/crosssections/private/HNLFromSpline.cxx ${PROJECT_SOURCE_DIR}/projects/crosssections/private/ElasticScattering.cxx + ${PROJECT_SOURCE_DIR}/projects/crosssections/private/DummyCrossSection.cxx ) add_library(LI_crosssections OBJECT ${crosssections_SOURCES}) set_property(TARGET LI_crosssections PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_crosssections PUBLIC - ${PROJECT_SOURCE_DIR}/projects/crosssections/public/ + $ + $ ) -add_dependencies(LI_crosssections rk) -add_dependencies(LI_crosssections LI_serialization LI_utilities LI_math LI_dataclasses LI_detector) -target_link_libraries(LI_crosssections photospline) -target_link_libraries(LI_crosssections rk) - -target_include_directories(LI_crosssections PUBLIC ${PROJECT_SOURCE_DIR}/vendor/rk/include) -target_include_directories(LI_crosssections PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) -target_include_directories(LI_crosssections PUBLIC ${PROJECT_SOURCE_DIR}/projects/utilities/public/) -target_include_directories(LI_crosssections PUBLIC ${PROJECT_SOURCE_DIR}/projects/math/public/) -target_include_directories(LI_crosssections PUBLIC ${PROJECT_SOURCE_DIR}/projects/detector/public/) -target_include_directories(LI_crosssections PUBLIC ${PROJECT_SOURCE_DIR}/projects/dataclasses/public/) - -install(TARGETS LI_crosssections - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +target_link_libraries(LI_crosssections + PRIVATE + $ + PUBLIC + photospline + LI_serialization + LI_utilities + LI_math + LI_dataclasses + LI_detector +) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/crosssections/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} @@ -42,7 +42,7 @@ package_add_test(UnitTest_DipoleFromTable ${PROJECT_SOURCE_DIR}/projects/crossse #package_add_test(UnitTest_ElasticScattering ${PROJECT_SOURCE_DIR}/projects/crosssections/private/test/ElasticScattering_TEST.cxx) pybind11_add_module(crosssections ${PROJECT_SOURCE_DIR}/projects/crosssections/private/pybindings/crosssections.cxx) -target_link_libraries(crosssections PRIVATE LeptonInjector photospline rk) +target_link_libraries(crosssections PRIVATE LeptonInjector photospline rk_static) if(DEFINED SKBUILD) set_target_properties(crosssections PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE diff --git a/projects/crosssections/private/CrossSectionCollection.cxx b/projects/crosssections/private/CrossSectionCollection.cxx index 0c094eb1..9168e138 100644 --- a/projects/crosssections/private/CrossSectionCollection.cxx +++ b/projects/crosssections/private/CrossSectionCollection.cxx @@ -1,14 +1,18 @@ -#include -#include -#include -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include // for map +#include // for operator== +#include // for tie +#include // for numeric... +#include // for vector +#include // for pair + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSe... +#include "LeptonInjector/crosssections/Decay.h" // for Decay +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle + namespace LI { namespace crosssections { diff --git a/projects/crosssections/private/DISFromSpline.cxx b/projects/crosssections/private/DISFromSpline.cxx index 313a7999..ef4c4a0b 100644 --- a/projects/crosssections/private/DISFromSpline.cxx +++ b/projects/crosssections/private/DISFromSpline.cxx @@ -1,22 +1,27 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/utilities/Random.h" - -#include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/DISFromSpline.h" +#include // for map, opera... +#include // for set, opera... +#include // for array +#include // for pow, log10 +#include // for tie, opera... +#include // for allocator +#include // for basic_string +#include // for vector +#include // for assert +#include // for size_t + +#include // for P4, Boost +#include // for Vector3 + +#include // for splinetable +//#include + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSection +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/utilities/Random.h" // for LI_random + namespace LI { namespace crosssections { diff --git a/projects/crosssections/private/Decay.cxx b/projects/crosssections/private/Decay.cxx index 8225fb8e..47e9d32b 100644 --- a/projects/crosssections/private/Decay.cxx +++ b/projects/crosssections/private/Decay.cxx @@ -1,7 +1,12 @@ #include "LeptonInjector/crosssections/Decay.h" -#include "LeptonInjector/utilities/Constants.h" -#include +#include // for array + +#include // for P4 +#include // for Vector3 + +#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/utilities/Constants.h" namespace LI { namespace crosssections { diff --git a/projects/crosssections/private/DipoleFromTable.cxx b/projects/crosssections/private/DipoleFromTable.cxx index 0afa23b1..d47c7588 100644 --- a/projects/crosssections/private/DipoleFromTable.cxx +++ b/projects/crosssections/private/DipoleFromTable.cxx @@ -1,24 +1,37 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/utilities/Errors.h" -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/utilities/Interpolator.h" - -#include "LeptonInjector/detector/MaterialModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/DipoleFromTable.h" +#include // for set +#include // for array +#include // for pow, sqrt +#include // for tie +#include // for snprintf +#include // for allocator +#include // for basic_s... +#include // for vector +#include +#include // for operator<< +#include // for pair +#include // for assert +#include // for basic_i... +#include // for int32_t +#include // for abs +#include // for back_in... +#include // for find, max, min, set_int... +#include // for function + +#include // for Vector3 +#include // for P4, Boost + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSe... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/detector/MaterialModel.h" // for Materia... +#include "LeptonInjector/utilities/Constants.h" // for invGeVs... +#include "LeptonInjector/utilities/Errors.h" // for Injecti... +#include "LeptonInjector/utilities/Interpolator.h" // for Interpo... +#include "LeptonInjector/utilities/Random.h" // for LI_random + namespace LI { namespace crosssections { diff --git a/projects/crosssections/private/DummyCrossSection.cxx b/projects/crosssections/private/DummyCrossSection.cxx new file mode 100644 index 00000000..dbc3585f --- /dev/null +++ b/projects/crosssections/private/DummyCrossSection.cxx @@ -0,0 +1,245 @@ +#include "LeptonInjector/crosssections/DummyCrossSection.h" + +#include // for array +#include // for sqrt, M_PI +#include // for basic_s... +#include // for vector +#include // for size_t + +#include // for Vector3 +#include // for P4, Boost + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSe... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/utilities/Random.h" // for LI_random + +namespace LI { +namespace crosssections { + +DummyCrossSection::DummyCrossSection() {} + + +bool DummyCrossSection::equal(CrossSection const & other) const { + const DummyCrossSection* x = dynamic_cast(&other); + + if(!x) + return false; + else + return true; +} + +double DummyCrossSection::TotalCrossSection(dataclasses::InteractionRecord const & interaction) const { + LI::dataclasses::Particle::ParticleType primary_type = interaction.signature.primary_type; + LI::dataclasses::Particle::ParticleType target_type = interaction.signature.target_type; + rk::P4 p1(geom3::Vector3(interaction.primary_momentum[1], interaction.primary_momentum[2], interaction.primary_momentum[3]), interaction.primary_mass); + rk::P4 p2(geom3::Vector3(interaction.target_momentum[1], interaction.target_momentum[2], interaction.target_momentum[3]), interaction.target_mass); + double primary_energy; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + primary_energy = interaction.primary_momentum[0]; + } else { + rk::Boost boost_start_to_lab = p2.restBoost(); + rk::P4 p1_lab = boost_start_to_lab * p1; + primary_energy = p1_lab.e(); + } + return TotalCrossSection(primary_type, primary_energy, target_type); +} + +double DummyCrossSection::TotalCrossSection(LI::dataclasses::Particle::ParticleType primary_type, double primary_energy, LI::dataclasses::Particle::ParticleType target_type) const { + double interaction_length_m = 1e6; + double interaction_length_cm = interaction_length_m * 100; + double density = 1.0; // g/cm^3 + double mol = 6.0221415e23; // particles/g + double per_cm2 = density * interaction_length_cm * mol; // particles / cm^2 + double cm2 = 1.0 / per_cm2; // cm2/particle + return cm2 * primary_energy / 1e5; // Interaction length was computed for 100TeV +} + + +double DummyCrossSection::DifferentialCrossSection(dataclasses::InteractionRecord const & interaction) const { + LI::dataclasses::Particle::ParticleType primary_type = interaction.signature.primary_type; + LI::dataclasses::Particle::ParticleType target_type = interaction.signature.target_type; + rk::P4 p1(geom3::Vector3(interaction.primary_momentum[1], interaction.primary_momentum[2], interaction.primary_momentum[3]), interaction.primary_mass); + rk::P4 p2(geom3::Vector3(interaction.target_momentum[1], interaction.target_momentum[2], interaction.target_momentum[3]), interaction.target_mass); + double primary_energy; + rk::P4 p1_lab; + rk::P4 p2_lab; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + primary_energy = interaction.primary_momentum[0]; + p1_lab = p1; + p2_lab = p2; + } else { + rk::Boost boost_start_to_lab = p2.restBoost(); + p1_lab = boost_start_to_lab * p1; + p2_lab = boost_start_to_lab * p2; + primary_energy = p1_lab.e(); + } + + return TotalCrossSection(primary_type, primary_energy, target_type); +} + +double DummyCrossSection::InteractionThreshold(dataclasses::InteractionRecord const & interaction) const { + return 0; +} + +void DummyCrossSection::SampleFinalState(dataclasses::InteractionRecord& interaction, std::shared_ptr random) const { + rk::P4 p1(geom3::Vector3(interaction.primary_momentum[1], interaction.primary_momentum[2], interaction.primary_momentum[3]), interaction.primary_mass); + rk::P4 p2(geom3::Vector3(interaction.target_momentum[1], interaction.target_momentum[2], interaction.target_momentum[3]), interaction.target_mass); + + // we assume that: + // the target is stationary so its energy is just its mass + // the incoming neutrino is massless, so its kinetic energy is its total energy + // double s = target_mass_ * tinteraction.secondary_momentarget_mass_ + 2 * target_mass_ * primary_energy; + // double s = std::pow(rk::invMass(p1, p2), 2); + + double primary_energy; + rk::P4 p1_lab; + rk::P4 p2_lab; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + p1_lab = p1; + p2_lab = p2; + primary_energy = p1_lab.e(); + } else { + // Rest frame of p2 will be our "lab" frame + rk::Boost boost_start_to_lab = p2.restBoost(); + p1_lab = boost_start_to_lab * p1; + p2_lab = boost_start_to_lab * p2; + primary_energy = p1_lab.e(); + } + + double final_x = random->Uniform(0, 1); + double final_y = random->Uniform(0, 1); + + interaction.interaction_parameters.resize(3); + interaction.interaction_parameters[0] = primary_energy; + interaction.interaction_parameters[1] = final_x; + interaction.interaction_parameters[2] = final_y; + + double m1 = interaction.primary_mass; + double m3 = 0; + double E1_lab = p1_lab.e(); + double E2_lab = p2_lab.e(); + double Q2 = 2 * E1_lab * E2_lab * final_x * final_y; + double p1x_lab = std::sqrt(p1_lab.px() * p1_lab.px() + p1_lab.py() * p1_lab.py() + p1_lab.pz() * p1_lab.pz()); + double pqx_lab = (m1*m1 + m3*m3 + 2 * p1x_lab * p1x_lab + Q2 + 2 * E1_lab * E1_lab * (final_y - 1)) / (2.0 * p1x_lab); + double momq_lab = std::sqrt(m1*m1 + p1x_lab*p1x_lab + Q2 + E1_lab * E1_lab * (final_y * final_y - 1)); + double pqy_lab = std::sqrt(momq_lab*momq_lab - pqx_lab *pqx_lab); + double Eq_lab = E1_lab * final_y; + + geom3::UnitVector3 x_dir = geom3::UnitVector3::xAxis(); + geom3::Vector3 p1_mom = p1_lab.momentum(); + geom3::UnitVector3 p1_lab_dir = p1_mom.direction(); + geom3::Rotation3 x_to_p1_lab_rot = geom3::rotationBetween(x_dir, p1_lab_dir); + + double phi = random->Uniform(0, 2.0 * M_PI); + geom3::Rotation3 rand_rot(p1_lab_dir, phi); + + rk::P4 pq_lab(Eq_lab, geom3::Vector3(pqx_lab, pqy_lab, 0)); + pq_lab.rotate(x_to_p1_lab_rot); + pq_lab.rotate(rand_rot); + + rk::P4 p3_lab((p1_lab - pq_lab).momentum(), m3); + rk::P4 p4_lab = p2_lab + pq_lab; + + rk::P4 p3; + rk::P4 p4; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + p3 = p3_lab; + p4 = p4_lab; + } else { + rk::Boost boost_lab_to_start = p2.labBoost(); + p3 = boost_lab_to_start * p3_lab; + p4 = boost_lab_to_start * p4_lab; + } + + interaction.secondary_momenta.resize(2); + interaction.secondary_masses.resize(2); + interaction.secondary_helicity.resize(2); + + size_t lepton_index = 0; + size_t other_index = 0; + + interaction.secondary_momenta[lepton_index][0] = p3.e(); // p3_energy + interaction.secondary_momenta[lepton_index][1] = p3.px(); // p3_x + interaction.secondary_momenta[lepton_index][2] = p3.py(); // p3_y + interaction.secondary_momenta[lepton_index][3] = p3.pz(); // p3_z + interaction.secondary_masses[lepton_index] = p3.m(); + + interaction.secondary_helicity[lepton_index] = interaction.primary_helicity; + + interaction.secondary_momenta[other_index][0] = p4.e(); // p4_energy + interaction.secondary_momenta[other_index][1] = p4.px(); // p4_x + interaction.secondary_momenta[other_index][2] = p4.py(); // p4_y + interaction.secondary_momenta[other_index][3] = p4.pz(); // p4_z + interaction.secondary_masses[other_index] = p4.m(); + + interaction.secondary_helicity[other_index] = interaction.target_helicity; +} + +double DummyCrossSection::FinalStateProbability(dataclasses::InteractionRecord const & interaction) const { + double dxs = DifferentialCrossSection(interaction); + double txs = TotalCrossSection(interaction); + if(dxs == 0) { + return 0.0; + } else { + return dxs / txs; + } +} + +std::vector DummyCrossSection::GetPossibleTargets() const { + return { + LI::dataclasses::Particle::ParticleType::Nucleon + }; +} + +std::vector DummyCrossSection::GetPossibleTargetsFromPrimary(LI::dataclasses::Particle::ParticleType primary_type) const { + return { + LI::dataclasses::Particle::ParticleType::Nucleon + }; +} + +std::vector DummyCrossSection::GetPossiblePrimaries() const { + return { + LI::dataclasses::Particle::ParticleType::NuE, + LI::dataclasses::Particle::ParticleType::NuEBar, + LI::dataclasses::Particle::ParticleType::NuMu, + LI::dataclasses::Particle::ParticleType::NuMuBar, + LI::dataclasses::Particle::ParticleType::NuTau, + LI::dataclasses::Particle::ParticleType::NuTauBar + }; +} + +std::vector DummyCrossSection::GetPossibleSignatures() const { + std::vector sigs; + LI::dataclasses::InteractionSignature signature; + std::vector targets = GetPossibleTargets(); + std::vector primaries = GetPossiblePrimaries(); + for(auto target : targets) { + signature.target_type = target; + for(auto primary : primaries) { + signature.primary_type = primary; + signature.secondary_types = {primary, target}; + sigs.push_back(signature); + } + } + return sigs; +} + +std::vector DummyCrossSection::GetPossibleSignaturesFromParents(LI::dataclasses::Particle::ParticleType primary_type, LI::dataclasses::Particle::ParticleType target_type) const { + std::vector sigs = DummyCrossSection::GetPossibleSignatures(); + std::vector these_sigs; + for(auto sig : sigs) { + if(sig.primary_type == primary_type) + these_sigs.push_back(sig); + } + return these_sigs; +} + +std::vector DummyCrossSection::DensityVariables() const { + return std::vector{"Bjorken x", "Bjorken y"}; +} + +} // namespace crosssections +} // namespace LI + diff --git a/projects/crosssections/private/ElasticScattering.cxx b/projects/crosssections/private/ElasticScattering.cxx index 85bf66b4..66647074 100644 --- a/projects/crosssections/private/ElasticScattering.cxx +++ b/projects/crosssections/private/ElasticScattering.cxx @@ -1,20 +1,27 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/utilities/Integration.h" - -#include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/ElasticScattering.h" +#include // for set +#include // for array +#include // for pow, sqrt +#include // for basic_s... +#include // for vector +#include // for assert +#include // for size_t +#include // for basic_o... +#include +#include + +#include // for Vector3 +#include // for P4, Boost + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSe... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/utilities/Constants.h" // for electro... +#include "LeptonInjector/utilities/Integration.h" // for romberg... +#include "LeptonInjector/utilities/Random.h" // for LI_random + namespace LI { namespace crosssections { diff --git a/projects/crosssections/private/HNLDecay.cxx b/projects/crosssections/private/HNLDecay.cxx new file mode 100644 index 00000000..a3b8bf79 --- /dev/null +++ b/projects/crosssections/private/HNLDecay.cxx @@ -0,0 +1,289 @@ +#include "LeptonInjector/crosssections/HNLDecay.h" + +#include +#include + +#include "LeptonInjector/dataclasses/Particle.h" + +#include "LeptonInjector/math/Vector3D.h" + +#include "LeptonInjector/utilities/Errors.h" +#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/utilities/Constants.h" + +#include "LeptonInjector/detector/MaterialModel.h" + +#include "LeptonInjector/crosssections/Decay.h" + +namespace LI { +namespace crosssections { + +bool HNLDecay::equal(Decay const & other) const { + const HNLDecay* x = dynamic_cast(&other); + + if(!x) + return false; + else + return + std::tie( + primary_types, + hnl_mass, + nature, + dipole_coupling) + == + std::tie( + x->primary_types, + x->hnl_mass, + x->nature, + x->dipole_coupling); +} + +double HNLDecay::TotalDecayWidth(dataclasses::InteractionRecord const & record) const { + return TotalDecayWidth(record.signature.primary_type); +} + +double HNLDecay::TotalDecayWidth(LI::dataclasses::Particle::ParticleType primary) const { + double total_coupling_sq = 0; + for(auto dc : dipole_coupling) total_coupling_sq += dc*dc; + return total_coupling_sq * std::pow(hnl_mass,3) / (4*LI::utilities::Constants::pi) * LI::utilities::Constants::GeV; +} + +double HNLDecay::TotalDecayWidthForFinalState(dataclasses::InteractionRecord const & record) const { + unsigned int gamma_index = (record.signature.secondary_types[0] == LI::dataclasses::Particle::ParticleType::Gamma) ? 0 : 1; + unsigned int nu_index = 1 - gamma_index; + double dipole_coupling_sq = 0; + if(record.signature.secondary_types[nu_index]==LI::dataclasses::Particle::ParticleType::NuE || + record.signature.secondary_types[nu_index]==LI::dataclasses::Particle::ParticleType::NuEBar) + dipole_coupling_sq = dipole_coupling[0]*dipole_coupling[0]; + else if(record.signature.secondary_types[nu_index]==LI::dataclasses::Particle::ParticleType::NuMu || + record.signature.secondary_types[nu_index]==LI::dataclasses::Particle::ParticleType::NuMuBar) + dipole_coupling_sq = dipole_coupling[1]*dipole_coupling[1]; + else if(record.signature.secondary_types[nu_index]==LI::dataclasses::Particle::ParticleType::NuTau || + record.signature.secondary_types[nu_index]==LI::dataclasses::Particle::ParticleType::NuTauBar) + dipole_coupling_sq = dipole_coupling[2]*dipole_coupling[2]; + return dipole_coupling_sq * std::pow(hnl_mass,3) / (4*LI::utilities::Constants::pi) * LI::utilities::Constants::GeV; +} + +std::vector HNLDecay::DensityVariables() const { + return std::vector{"CosTheta"}; +} + + +std::vector HNLDecay::GetPossibleSignatures() const { + std::vector signatures; + for(auto primary : primary_types) { + std::vector new_signatures = GetPossibleSignaturesFromParent(primary); + signatures.insert(signatures.end(),new_signatures.begin(),new_signatures.end()); + } + return signatures; +} + +std::vector HNLDecay::GetPossibleSignaturesFromParent(LI::dataclasses::Particle::ParticleType primary) const { + + std::vector signatures; + dataclasses::InteractionSignature signature; + signature.primary_type = primary; + signature.target_type = LI::dataclasses::Particle::ParticleType::Decay; + + // Two body decays (from 2007.03701) + signature.secondary_types.resize(2); + if(primary==LI::dataclasses::Particle::ParticleType::NuF4) { + // N -> nu P (P = pi0, eta, eta prime, rho0, omega, hadrons, phi) + for(auto particle : std::vector{LI::dataclasses::Particle::ParticleType::NuE, LI::dataclasses::Particle::ParticleType::NuMu, LI::dataclasses::Particle::ParticleType::NuTau}) { + signature.secondary_types[0] = particle; + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Pi0; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Eta; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Rho0; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Omega; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::EtaPrime; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Hadrons; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Phi; + signatures.push_back(signature); + } + // N -> l- P+ (P+ = pi, K , rho, K*, hadrons, D, Ds) + for(auto particle : std::vector{LI::dataclasses::Particle::ParticleType::EMinus, LI::dataclasses::Particle::ParticleType::MuMinus, LI::dataclasses::Particle::ParticleType::TauMinus}) { + signature.secondary_types[0] = particle; + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::PiPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::KPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::RhoPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::KStarPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Hadrons; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::DPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::DsPlus; + signatures.push_back(signature); + } + } + else if(primary==LI::dataclasses::Particle::ParticleType::NuF4Bar) { + // N -> nu P (P = pi0, eta, eta prime, rho0, omega, hadrons, phi) + for(auto particle : std::vector{LI::dataclasses::Particle::ParticleType::NuEBar, LI::dataclasses::Particle::ParticleType::NuMuBar, LI::dataclasses::Particle::ParticleType::NuTauBar}) { + signature.secondary_types[0] = particle; + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Pi0; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Eta; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Rho0; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Omega; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::EtaPrime; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Hadrons; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Phi; + signatures.push_back(signature); + } + // N -> l- P+ (P+ = pi, K , rho, K*, hadrons, D, Ds) + for(auto particle : std::vector{LI::dataclasses::Particle::ParticleType::EPlus, LI::dataclasses::Particle::ParticleType::MuPlus, LI::dataclasses::Particle::ParticleType::TauPlus}) { + signature.secondary_types[0] = particle; + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::PiMinus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::KMinus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::RhoMinus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::KStarMinus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::Hadrons; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::DMinus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::DsMinus; + signatures.push_back(signature); + } + } + + // Three body decays (from 2007.03701) + signature.secondary_types.resize(3); + if(primary==LI::dataclasses::Particle::ParticleType::NuF4) { + for(auto particle : std::vector{LI::dataclasses::Particle::ParticleType::NuE, LI::dataclasses::Particle::ParticleType::NuMu, LI::dataclasses::Particle::ParticleType::NuTau}) { + signature.secondary_types[0] = particle; + // N -> nu nu nu + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::NuE; + signature.secondary_types[2] = LI::dataclasses::Particle::ParticleType::NuEBar; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::NuMu; + signature.secondary_types[2] = LI::dataclasses::Particle::ParticleType::NuMuBar; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::NuTau; + signature.secondary_types[2] = LI::dataclasses::Particle::ParticleType::NuTauBar; + signatures.push_back(signature); + // N -> nu l- l+ (l same flavor) + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::EMinus; + signature.secondary_types[2] = LI::dataclasses::Particle::ParticleType::EPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::MuMinus; + signature.secondary_types[2] = LI::dataclasses::Particle::ParticleType::MuPlus; + signatures.push_back(signature); + signature.secondary_types[1] = LI::dataclasses::Particle::ParticleType::TauMinus; + signature.secondary_types[2] = LI::dataclasses::Particle::ParticleType::TauPlus; + signatures.push_back(signature); + + return signatures; +} + +double HNLDecay::DifferentialDecayWidth(dataclasses::InteractionRecord const & record) const { + double DecayWidth = TotalDecayWidthForFinalState(record); + if(nature==ChiralNature::Majorana) { + //TODO: make sure factor of 2 is correct here + return DecayWidth/2.; + } + LI::math::Vector3D hnl_dir = LI::math::Vector3D(record.primary_momentum[0], + record.primary_momentum[1], + record.primary_momentum[2]); + hnl_dir.normalize(); + unsigned int gamma_index = (record.signature.secondary_types[0] == LI::dataclasses::Particle::ParticleType::Gamma) ? 0 : 1; + rk::P4 pHNL(geom3::Vector3(record.primary_momentum[1], record.primary_momentum[2], record.primary_momentum[3]), record.primary_mass); + rk::P4 pGamma(geom3::Vector3(record.secondary_momenta[gamma_index][1], record.secondary_momenta[gamma_index][2], record.secondary_momenta[gamma_index][3]), record.secondary_masses[gamma_index]); + rk::Boost boost_to_HNL_rest = pHNL.restBoost(); + rk::P4 pGamma_HNLrest = pGamma.boost(boost_to_HNL_rest); + + LI::math::Vector3D gamma_dir = LI::math::Vector3D(pGamma_HNLrest.px(), + pGamma_HNLrest.py(), + pGamma_HNLrest.pz()); + gamma_dir.normalize(); + double CosThetaGamma = gamma_dir*hnl_dir; // scalar product + double alpha = std::copysign(1.0,record.primary_helicity); // 1 for RH, -1 for LH + alpha = (record.signature.primary_type == LI::dataclasses::Particle::ParticleType::NuF4) ? -1*alpha : alpha; + return DecayWidth/2. * (1 + alpha*CosThetaGamma); +} + +void HNLDecay::SampleFinalState(dataclasses::InteractionRecord & record, std::shared_ptr random) const { + + unsigned int gamma_index = (record.signature.secondary_types[0] == LI::dataclasses::Particle::ParticleType::Gamma) ? 0 : 1; + unsigned int nu_index = 1 - gamma_index; + + double CosTheta; + double alpha = std::copysign(1.0,record.primary_helicity); // 1 for RH, -1 for LH + alpha = (record.signature.primary_type == LI::dataclasses::Particle::ParticleType::NuF4) ? -1*alpha : alpha; + if(nature==ChiralNature::Majorana) { + CosTheta = random->Uniform(-1,1); + } + else { + double X = random->Uniform(0,1); + CosTheta = (std::sqrt(1 - 2*alpha*(1 - alpha/2. - 2*X)) - 1)/alpha; + } + double SinTheta = std::sin(std::acos(CosTheta)); + + rk::P4 pHNL(geom3::Vector3(record.primary_momentum[1], record.primary_momentum[2], record.primary_momentum[3]), record.primary_mass); + rk::Boost boost_to_lab = pHNL.labBoost(); + + geom3::UnitVector3 x_dir = geom3::UnitVector3::xAxis(); + geom3::Vector3 pHNL_mom = pHNL.momentum(); + geom3::UnitVector3 pHNL_dir = pHNL_mom.direction(); + geom3::Rotation3 x_to_pHNL_rot = geom3::rotationBetween(x_dir, pHNL_dir); + + double phi = random->Uniform(0, 2.0 * M_PI); + geom3::Rotation3 rand_rot(pHNL_dir, phi); + + rk::P4 pGamma_HNLrest(hnl_mass/2.*geom3::Vector3(CosTheta,SinTheta,0),0); + pGamma_HNLrest.rotate(x_to_pHNL_rot); + pGamma_HNLrest.rotate(rand_rot); + + rk::P4 pGamma = pGamma_HNLrest.boost(boost_to_lab); + rk::P4 pNu(pHNL.momentum() - pGamma.momentum(),0); // ensures the neutrino has zero mass, avoids rounding errors + + record.secondary_momenta.resize(2); + record.secondary_masses.resize(2); + record.secondary_helicity.resize(2); + + record.secondary_momenta[gamma_index][0] = pGamma.e(); // pGamma_energy + record.secondary_momenta[gamma_index][1] = pGamma.px(); // pGamma_x + record.secondary_momenta[gamma_index][2] = pGamma.py(); // pGamma_y + record.secondary_momenta[gamma_index][3] = pGamma.pz(); // pGamma_z + record.secondary_masses[gamma_index] = pGamma.m(); + record.secondary_helicity[gamma_index] = 0; + + record.secondary_momenta[nu_index][0] = pNu.e(); // pNu_energy + record.secondary_momenta[nu_index][1] = pNu.px(); // pNu_x + record.secondary_momenta[nu_index][2] = pNu.py(); // pNu_y + record.secondary_momenta[nu_index][3] = pNu.pz(); // pNu_z + record.secondary_masses[nu_index] = pNu.m(); + record.secondary_helicity[nu_index] = -1*record.primary_helicity; + +} + +double HNLDecay::FinalStateProbability(dataclasses::InteractionRecord const & record) const { + double dd = DifferentialDecayWidth(record); + double td = TotalDecayWidthForFinalState(record); + if (dd == 0) return 0.; + else if (td == 0) return 0.; + else return dd/td; +} + + + +} // namespace crosssections +} // namespace LI + diff --git a/projects/crosssections/private/HNLFromSpline.cxx b/projects/crosssections/private/HNLFromSpline.cxx new file mode 100644 index 00000000..d6d0dd5f --- /dev/null +++ b/projects/crosssections/private/HNLFromSpline.cxx @@ -0,0 +1,607 @@ +#include "LeptonInjector/crosssections/HNLFromSpline.h" + +#include // for map, opera... +#include // for set, opera... +#include // for array +#include // for pow, log10 +#include // for tie, opera... +#include // for basic_string +#include // for allocator +#include // for vector +#include // for assert +#include // for size_t + +#include // for Vector3 +#include // for P4, Boost + +#include +#include + +#include +#include + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSection +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/utilities/Random.h" // for LI_random + +namespace LI { +namespace crosssections { + +namespace { +///Check whether a given point in phase space is physically realizable. +///Based on equations 6-8 of http://dx.doi.org/10.1103/PhysRevD.66.113007 +///S. Kretzer and M. H. Reno +///"Tau neutrino deep inelastic charged current interactions" +///Phys. Rev. D 66, 113007 +///\param x Bjorken x of the interaction +///\param y Bjorken y of the interaction +///\param E Incoming neutrino in energy in the lab frame ($E_\nu$) +///\param M Mass of the target nucleon ($M_N$) +///\param m Mass of the secondary lepton ($m_\tau$) +bool kinematicallyAllowed(double x, double y, double E, double M, double m) { + if(x > 1) //Eq. 6 right inequality + return false; + if(x < ((m * m) / (2 * M * (E - m)))) //Eq. 6 left inequality + return false; + //denominator of a and b + double d = 2 * (1 + (M * x) / (2 * E)); + //the numerator of a (or a*d) + double ad = 1 - m * m * ((1 / (2 * M * E * x)) + (1 / (2 * E * E))); + double term = 1 - ((m * m) / (2 * M * E * x)); + //the numerator of b (or b*d) + double bd = sqrt(term * term - ((m * m) / (E * E))); + return (ad - bd) <= d * y and d * y <= (ad + bd); //Eq. 7 +} +} + +HNLFromSpline::HNLFromSpline() {} + +HNLFromSpline::HNLFromSpline(std::vector differential_data, std::vector total_data, int interaction, double target_mass, double minimum_Q2, std::set primary_types, std::set target_types) : primary_types_(primary_types), target_types_(target_types), interaction_type_(interaction), target_mass_(target_mass), minimum_Q2_(minimum_Q2) { + LoadFromMemory(differential_data, total_data); + InitializeSignatures(); +} + +HNLFromSpline::HNLFromSpline(std::vector differential_data, std::vector total_data, int interaction, double target_mass, double minimum_Q2, std::vector primary_types, std::vector target_types) : primary_types_(primary_types.begin(), primary_types.end()), target_types_(target_types.begin(), target_types.end()), interaction_type_(interaction), target_mass_(target_mass), minimum_Q2_(minimum_Q2) { + LoadFromMemory(differential_data, total_data); + InitializeSignatures(); +} + +HNLFromSpline::HNLFromSpline(std::string differential_filename, std::string total_filename, int interaction, double target_mass, double minimum_Q2, std::set primary_types, std::set target_types) : primary_types_(primary_types), target_types_(target_types), interaction_type_(interaction), target_mass_(target_mass), minimum_Q2_(minimum_Q2) { + LoadFromFile(differential_filename, total_filename); + InitializeSignatures(); +} + +HNLFromSpline::HNLFromSpline(std::string differential_filename, std::string total_filename, std::set primary_types, std::set target_types) : primary_types_(primary_types), target_types_(target_types) { + LoadFromFile(differential_filename, total_filename); + ReadParamsFromSplineTable(); + InitializeSignatures(); +} + +HNLFromSpline::HNLFromSpline(std::string differential_filename, std::string total_filename, int interaction, double target_mass, double minimum_Q2, std::vector primary_types, std::vector target_types) : primary_types_(primary_types.begin(), primary_types.end()), target_types_(target_types.begin(), target_types.end()), interaction_type_(interaction), target_mass_(target_mass), minimum_Q2_(minimum_Q2) { + LoadFromFile(differential_filename, total_filename); + InitializeSignatures(); +} + +HNLFromSpline::HNLFromSpline(std::string differential_filename, std::string total_filename, std::vector primary_types, std::vector target_types) : primary_types_(primary_types.begin(), primary_types.end()), target_types_(target_types.begin(), target_types.end()) { + LoadFromFile(differential_filename, total_filename); + ReadParamsFromSplineTable(); + InitializeSignatures(); +} + +bool HNLFromSpline::equal(CrossSection const & other) const { + const HNLFromSpline* x = dynamic_cast(&other); + + if(!x) + return false; + else + return + std::tie( + interaction_type_, + target_mass_, + minimum_Q2_, + signatures_, + primary_types_, + target_types_, + differential_cross_section_, + total_cross_section_) + == + std::tie( + x->interaction_type_, + x->target_mass_, + x->minimum_Q2_, + x->signatures_, + x->primary_types_, + x->target_types_, + x->differential_cross_section_, + x->total_cross_section_); +} + +void HNLFromSpline::LoadFromFile(std::string dd_crossSectionFile, std::string total_crossSectionFile) { + + differential_cross_section_ = photospline::splinetable<>(dd_crossSectionFile.c_str()); + + if(differential_cross_section_.get_ndim()!=3 && differential_cross_section_.get_ndim()!=2) + throw std::runtime_error("cross section spline has " + std::to_string(differential_cross_section_.get_ndim()) + + " dimensions, should have either 3 (log10(E), log10(x), log10(y)) or 2 (log10(E), log10(y))"); + + total_cross_section_ = photospline::splinetable<>(total_crossSectionFile.c_str()); + + if(total_cross_section_.get_ndim() != 1) + throw std::runtime_error("Total cross section spline has " + std::to_string(total_cross_section_.get_ndim()) + + " dimensions, should have 1, log10(E)"); +} + +void HNLFromSpline::LoadFromMemory(std::vector & differential_data, std::vector & total_data) { + differential_cross_section_.read_fits_mem(differential_data.data(), differential_data.size()); + total_cross_section_.read_fits_mem(total_data.data(), total_data.size()); +} + +void HNLFromSpline::ReadParamsFromSplineTable() { + // returns true if successfully read target mass + bool mass_good = differential_cross_section_.read_key("TARGETMASS", target_mass_); + // returns true if successfully read interaction type + bool int_good = differential_cross_section_.read_key("INTERACTION", interaction_type_); + // returns true if successfully read minimum Q2 + bool q2_good = differential_cross_section_.read_key("Q2MIN", minimum_Q2_); + + if(!int_good) { + // assume HNL to preserve compatability with previous versions + interaction_type_ = 2; + } + + if(!q2_good) { + // assume 1 GeV^2 + minimum_Q2_ = 1; + } + + if(!mass_good) { + if(int_good) { + if(interaction_type_ == 1 or interaction_type_ == 2) { + target_mass_ = (LI::dataclasses::isLepton(LI::dataclasses::Particle::ParticleType::PPlus)+ + LI::dataclasses::isLepton(LI::dataclasses::Particle::ParticleType::Neutron))/2; + } else if(interaction_type_ == 3) { + target_mass_ = LI::dataclasses::isLepton(LI::dataclasses::Particle::ParticleType::EMinus); + } else { + throw std::runtime_error("Logic error. Interaction type is not 1, 2, or 3!"); + } + + } else { + if(differential_cross_section_.get_ndim() == 3) { + target_mass_ = (LI::dataclasses::isLepton(LI::dataclasses::Particle::ParticleType::PPlus)+ + LI::dataclasses::isLepton(LI::dataclasses::Particle::ParticleType::Neutron))/2; + } else if(differential_cross_section_.get_ndim() == 2) { + target_mass_ = LI::dataclasses::isLepton(LI::dataclasses::Particle::ParticleType::EMinus); + } else { + throw std::runtime_error("Logic error. Spline dimensionality is not 2, or 3!"); + } + } + } +} + +void HNLFromSpline::InitializeSignatures() { + signatures_.clear(); + for(auto primary_type : primary_types_) { + dataclasses::InteractionSignature signature; + signature.primary_type = primary_type; + + if(not isNeutrino(primary_type)) { + throw std::runtime_error("This HNL implementation only supports neutrinos as primaries!"); + } + + LI::dataclasses::Particle::ParticleType charged_lepton_product = LI::dataclasses::Particle::ParticleType::unknown; + LI::dataclasses::Particle::ParticleType neutral_lepton_product = LI::dataclasses::Particle::ParticleType::unknown; + + if(primary_type == LI::dataclasses::Particle::ParticleType::NuE) { + charged_lepton_product = LI::dataclasses::Particle::ParticleType::EMinus; + neutral_lepton_product = LI::dataclasses::Particle::ParticleType::NuF4; + } else if(primary_type == LI::dataclasses::Particle::ParticleType::NuEBar) { + charged_lepton_product = LI::dataclasses::Particle::ParticleType::EPlus; + neutral_lepton_product = LI::dataclasses::Particle::ParticleType::NuF4Bar; + } else if(primary_type == LI::dataclasses::Particle::ParticleType::NuMu) { + charged_lepton_product = LI::dataclasses::Particle::ParticleType::MuMinus; + neutral_lepton_product = LI::dataclasses::Particle::ParticleType::NuF4; + } else if(primary_type == LI::dataclasses::Particle::ParticleType::NuMuBar) { + charged_lepton_product = LI::dataclasses::Particle::ParticleType::MuPlus; + neutral_lepton_product = LI::dataclasses::Particle::ParticleType::NuF4Bar; + } else if(primary_type == LI::dataclasses::Particle::ParticleType::NuTau) { + charged_lepton_product = LI::dataclasses::Particle::ParticleType::TauMinus; + neutral_lepton_product = LI::dataclasses::Particle::ParticleType::NuF4; + } else if(primary_type == LI::dataclasses::Particle::ParticleType::NuTauBar) { + charged_lepton_product = LI::dataclasses::Particle::ParticleType::TauPlus; + neutral_lepton_product = LI::dataclasses::Particle::ParticleType::NuF4Bar; + } else { + throw std::runtime_error("InitializeSignatures: Unkown parent neutrino type!"); + } + + if(interaction_type_ == 1) { + signature.secondary_types.push_back(charged_lepton_product); + } else if(interaction_type_ == 2) { + signature.secondary_types.push_back(neutral_lepton_product); + } else if(interaction_type_ == 3) { + signature.secondary_types.push_back(LI::dataclasses::Particle::ParticleType::Hadrons); + } else { + throw std::runtime_error("InitializeSignatures: Unkown interaction type!"); + } + + signature.secondary_types.push_back(LI::dataclasses::Particle::ParticleType::Hadrons); + for(auto target_type : target_types_) { + signature.target_type = target_type; + + signatures_.push_back(signature); + + std::pair key(primary_type, target_type); + signatures_by_parent_types_[key].push_back(signature); + } + } +} + +double HNLFromSpline::TotalCrossSection(dataclasses::InteractionRecord const & interaction) const { + LI::dataclasses::Particle::ParticleType primary_type = interaction.signature.primary_type; + rk::P4 p1(geom3::Vector3(interaction.primary_momentum[1], interaction.primary_momentum[2], interaction.primary_momentum[3]), interaction.primary_mass); + rk::P4 p2(geom3::Vector3(interaction.target_momentum[1], interaction.target_momentum[2], interaction.target_momentum[3]), interaction.target_mass); + double primary_energy; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + primary_energy = interaction.primary_momentum[0]; + } else { + rk::Boost boost_start_to_lab = p2.restBoost(); + rk::P4 p1_lab = boost_start_to_lab * p1; + primary_energy = p1_lab.e(); + } + // if we are below threshold, return 0 + if(primary_energy < InteractionThreshold(interaction)) + return 0; + return TotalCrossSection(primary_type, primary_energy); +} + +double HNLFromSpline::TotalCrossSection(LI::dataclasses::Particle::ParticleType primary_type, double primary_energy) const { + if(not primary_types_.count(primary_type)) { + throw std::runtime_error("Supplied primary not supported by cross section!"); + } + double log_energy = log10(primary_energy); + + if(log_energy < total_cross_section_.lower_extent(0) + or log_energy > total_cross_section_.upper_extent(0)) { + throw std::runtime_error("Interaction energy ("+ std::to_string(primary_energy) + + ") out of cross section table range: [" + + std::to_string(pow(10.,total_cross_section_.lower_extent(0))) + " GeV," + + std::to_string(pow(10.,total_cross_section_.upper_extent(0))) + " GeV]"); + } + + int center; + total_cross_section_.searchcenters(&log_energy, ¢er); + double log_xs = total_cross_section_.ndsplineeval(&log_energy, ¢er, 0); + + return std::pow(10.0, log_xs); +} + +// No implementation for HNL yet, just use non-target function +double HNLFromSpline::TotalCrossSection(LI::dataclasses::Particle::ParticleType primary_type, double primary_energy, LI::dataclasses::Particle::ParticleType target_type) const { + return HNLFromSpline::TotalCrossSection(primary_type,primary_energy); +} + + +double HNLFromSpline::DifferentialCrossSection(dataclasses::InteractionRecord const & interaction) const { + rk::P4 p1(geom3::Vector3(interaction.primary_momentum[1], interaction.primary_momentum[2], interaction.primary_momentum[3]), interaction.primary_mass); + rk::P4 p2(geom3::Vector3(interaction.target_momentum[1], interaction.target_momentum[2], interaction.target_momentum[3]), interaction.target_mass); + double primary_energy; + rk::P4 p1_lab; + rk::P4 p2_lab; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + primary_energy = interaction.primary_momentum[0]; + p1_lab = p1; + p2_lab = p2; + } else { + rk::Boost boost_start_to_lab = p2.restBoost(); + p1_lab = boost_start_to_lab * p1; + p2_lab = boost_start_to_lab * p2; + primary_energy = p1_lab.e(); + } + assert(interaction.signature.secondary_types.size() == 2); + unsigned int lepton_index = (isLepton(interaction.signature.secondary_types[0])) ? 0 : 1; + unsigned int other_index = 1 - lepton_index; + + std::array const & mom3 = interaction.secondary_momenta[lepton_index]; + std::array const & mom4 = interaction.secondary_momenta[other_index]; + rk::P4 p3(geom3::Vector3(mom3[1], mom3[2], mom3[3]), interaction.secondary_masses[lepton_index]); + rk::P4 p4(geom3::Vector3(mom4[1], mom4[2], mom4[3]), interaction.secondary_masses[other_index]); + + rk::P4 q = p1 - p3; + + double Q2 = -q.dot(q); + double y = 1.0 - p2.dot(p3) / p2.dot(p1); + double x = Q2 / (2.0 * p2.dot(q)); + double lepton_mass = particleMass(interaction.signature.secondary_types[lepton_index]); + + return DifferentialCrossSection(primary_energy, x, y, lepton_mass); +} + +double HNLFromSpline::DifferentialCrossSection(double energy, double x, double y, double secondary_lepton_mass) const { + double log_energy = log10(energy); + // check preconditions + if(log_energy < differential_cross_section_.lower_extent(0) + || log_energy>differential_cross_section_.upper_extent(0)) + return 0.0; + if(x <= 0 || x >= 1) + return 0.0; + if(y <= 0 || y >= 1) + return 0.0; + + // we assume that: + // the target is stationary so its energy is just its mass + // the incoming neutrino is massless, so its kinetic energy is its total energy + double Q2 = 2.0 * energy * target_mass_ * x * y; + if(Q2 < minimum_Q2_) // cross section not calculated, assumed to be zero + return 0; + + // cross section should be zero, but this check is missing from the original + // CSMS calculation, so we must add it here + if(!kinematicallyAllowed(x, y, energy, target_mass_, secondary_lepton_mass)) + return 0; + + std::array coordinates{{log_energy, log10(x), log10(y)}}; + std::array centers; + if(!differential_cross_section_.searchcenters(coordinates.data(), centers.data())) + return 0; + double result = pow(10., differential_cross_section_.ndsplineeval(coordinates.data(), centers.data(), 0)); + assert(result >= 0); + return result; +} + +double HNLFromSpline::InteractionThreshold(dataclasses::InteractionRecord const & interaction) const { + // Consider implementing HNL thershold at some point + return 0; +} + +void HNLFromSpline::SampleFinalState(dataclasses::InteractionRecord& interaction, std::shared_ptr random) const { + // Uses Metropolis-Hastings Algorithm! + // useful for cases where we don't know the supremum of our distribution, and the distribution is multi-dimensional + if (differential_cross_section_.get_ndim() != 3) { + throw std::runtime_error("I expected 3 dimensions in the cross section spline, but got " + std::to_string(differential_cross_section_.get_ndim()) +". Maybe your fits file doesn't have the right 'INTERACTION' key?"); + } + + rk::P4 p1(geom3::Vector3(interaction.primary_momentum[1], interaction.primary_momentum[2], interaction.primary_momentum[3]), interaction.primary_mass); + rk::P4 p2(geom3::Vector3(interaction.target_momentum[1], interaction.target_momentum[2], interaction.target_momentum[3]), interaction.target_mass); + + // we assume that: + // the target is stationary so its energy is just its mass + // the incoming neutrino is massless, so its kinetic energy is its total energy + // double s = target_mass_ * tinteraction.secondary_momentarget_mass_ + 2 * target_mass_ * primary_energy; + // double s = std::pow(rk::invMass(p1, p2), 2); + + double primary_energy; + rk::P4 p1_lab; + rk::P4 p2_lab; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + p1_lab = p1; + p2_lab = p2; + primary_energy = p1_lab.e(); + } else { + // Rest frame of p2 will be our "lab" frame + rk::Boost boost_start_to_lab = p2.restBoost(); + p1_lab = boost_start_to_lab * p1; + p2_lab = boost_start_to_lab * p2; + primary_energy = p1_lab.e(); + } + + unsigned int lepton_index = (isLepton(interaction.signature.secondary_types[0])) ? 0 : 1; + unsigned int other_index = 1 - lepton_index; + double m = particleMass(interaction.signature.secondary_types[lepton_index]); + + double m1 = interaction.primary_mass; + double m3 = m; + double E1_lab = p1_lab.e(); + double E2_lab = p2_lab.e(); + + // The out-going particle always gets at least enough energy for its rest mass + double yMax = 1 - m / primary_energy; + double logYMax = log10(yMax); + + // The minimum allowed value of y occurs when x = 1 and Q is minimized + double yMin = minimum_Q2_ / (2 * E1_lab * E2_lab); + double logYMin = log10(yMin); + // The minimum allowed value of x occurs when y = yMax and Q is minimized + // double xMin = minimum_Q2_ / ((s - target_mass_ * target_mass_) * yMax); + double xMin = minimum_Q2_ / (2 * E1_lab * E2_lab * yMax); + double logXMin = log10(xMin); + + bool accept; + + // kin_vars and its twin are 3-vectors containing [nu-energy, Bjorken X, Bjorken Y] + std::array kin_vars, test_kin_vars; + + // centers of the cross section spline tales. + std::array spline_table_center, test_spline_table_center; + + // values of cross_section from the splines. By * Bx * Spline(E,x,y) + double cross_section, test_cross_section; + + // No matter what, we're evaluating at this specific energy. + kin_vars[0] = test_kin_vars[0] = log10(primary_energy); + + // check preconditions + if(kin_vars[0] < differential_cross_section_.lower_extent(0) + || kin_vars[0] > differential_cross_section_.upper_extent(0)) + throw std::runtime_error("Interaction energy out of cross section table range: [" + + std::to_string(pow(10.,differential_cross_section_.lower_extent(0))) + " GeV," + + std::to_string(pow(10.,differential_cross_section_.upper_extent(0))) + " GeV]"); + + // sample an intial point + do { + // rejection sample a point which is kinematically allowed by calculation limits + double trialQ; + do { + kin_vars[1] = random->Uniform(logXMin,0); + kin_vars[2] = random->Uniform(logYMin,logYMax); + trialQ = (2 * E1_lab * E2_lab) * pow(10., kin_vars[1] + kin_vars[2]); + } while(trialQ differential_cross_section_.upper_extent(1)) { + accept = false; + } + if(kin_vars[2] < differential_cross_section_.lower_extent(2) + || kin_vars[2] > differential_cross_section_.upper_extent(2)) { + accept = false; + } + + if(accept) { + // finds the centers in the cross section spline table, returns true if it's successful + // also sets the centers + accept = differential_cross_section_.searchcenters(kin_vars.data(),spline_table_center.data()); + } + } while(!accept); + + //TODO: better proposal distribution? + double measure = pow(10., kin_vars[1] + kin_vars[2]); // Bx * By + + // Bx * By * xs(E, x, y) + // evalutates the differential spline at that point + cross_section = measure*pow(10., differential_cross_section_.ndsplineeval(kin_vars.data(), spline_table_center.data(), 0)); + + // this is the magic part. Metropolis Hastings Algorithm. + // MCMC method! + const size_t burnin = 40; // converges to the correct distribution over multiple samplings. + // big number means more accurate, but slower + for(size_t j = 0; j <= burnin; j++) { + // repeat the sampling from above to get a new valid point + double trialQ; + do { + test_kin_vars[1] = random->Uniform(logXMin, 0); + test_kin_vars[2] = random->Uniform(logYMin, logYMax); + trialQ = (2 * E1_lab * E2_lab) * pow(10., test_kin_vars[1] + test_kin_vars[2]); + } while(trialQ < minimum_Q2_ || !kinematicallyAllowed(pow(10., test_kin_vars[1]), pow(10., test_kin_vars[2]), primary_energy, target_mass_, m)); + + accept = true; + if(test_kin_vars[1] < differential_cross_section_.lower_extent(1) + || test_kin_vars[1] > differential_cross_section_.upper_extent(1)) + accept = false; + if(test_kin_vars[2] < differential_cross_section_.lower_extent(2) + || test_kin_vars[2] > differential_cross_section_.upper_extent(2)) + accept = false; + if(!accept) + continue; + + accept = differential_cross_section_.searchcenters(test_kin_vars.data(), test_spline_table_center.data()); + if(!accept) + continue; + + double measure = pow(10., test_kin_vars[1] + test_kin_vars[2]); + double eval = differential_cross_section_.ndsplineeval(test_kin_vars.data(), test_spline_table_center.data(), 0); + if(std::isnan(eval)) + continue; + test_cross_section = measure * pow(10., eval); + + double odds = (test_cross_section / cross_section); + accept = (cross_section == 0 || (odds > 1.) || random->Uniform(0, 1) < odds); + + if(accept) { + kin_vars = test_kin_vars; + cross_section = test_cross_section; + } + } + double final_x = pow(10., kin_vars[1]); + double final_y = pow(10., kin_vars[2]); + + interaction.interaction_parameters.resize(3); + interaction.interaction_parameters[0] = E1_lab; + interaction.interaction_parameters[1] = final_x; + interaction.interaction_parameters[2] = final_y; + + double Q2 = 2 * E1_lab * E2_lab * pow(10.0, kin_vars[1] + kin_vars[2]); + double p1x_lab = std::sqrt(p1_lab.px() * p1_lab.px() + p1_lab.py() * p1_lab.py() + p1_lab.pz() * p1_lab.pz()); + double pqx_lab = (m1*m1 + m3*m3 + 2 * p1x_lab * p1x_lab + Q2 + 2 * E1_lab * E1_lab * (final_y - 1)) / (2.0 * p1x_lab); + double momq_lab = std::sqrt(m1*m1 + p1x_lab*p1x_lab + Q2 + E1_lab * E1_lab * (final_y * final_y - 1)); + double pqy_lab = std::sqrt(momq_lab*momq_lab - pqx_lab *pqx_lab); + double Eq_lab = E1_lab * final_y; + + geom3::UnitVector3 x_dir = geom3::UnitVector3::xAxis(); + geom3::Vector3 p1_mom = p1_lab.momentum(); + geom3::UnitVector3 p1_lab_dir = p1_mom.direction(); + geom3::Rotation3 x_to_p1_lab_rot = geom3::rotationBetween(x_dir, p1_lab_dir); + + double phi = random->Uniform(0, 2.0 * M_PI); + geom3::Rotation3 rand_rot(p1_lab_dir, phi); + + rk::P4 pq_lab(Eq_lab, geom3::Vector3(pqx_lab, pqy_lab, 0)); + pq_lab.rotate(x_to_p1_lab_rot); + pq_lab.rotate(rand_rot); + + rk::P4 p3_lab((p1_lab - pq_lab).momentum(), m3); + rk::P4 p4_lab = p2_lab + pq_lab; + + rk::P4 p3; + rk::P4 p4; + if(interaction.target_momentum[1] == 0 and interaction.target_momentum[2] == 0 and interaction.target_momentum[3] == 0) { + p3 = p3_lab; + p4 = p4_lab; + } else { + rk::Boost boost_lab_to_start = p2.labBoost(); + p3 = boost_lab_to_start * p3_lab; + p4 = boost_lab_to_start * p4_lab; + } + + interaction.secondary_momenta.resize(2); + interaction.secondary_masses.resize(2); + interaction.secondary_helicity.resize(2); + + interaction.secondary_momenta[lepton_index][0] = p3.e(); // p3_energy + interaction.secondary_momenta[lepton_index][1] = p3.px(); // p3_x + interaction.secondary_momenta[lepton_index][2] = p3.py(); // p3_y + interaction.secondary_momenta[lepton_index][3] = p3.pz(); // p3_z + interaction.secondary_masses[lepton_index] = p3.m(); + + interaction.secondary_helicity[lepton_index] = interaction.primary_helicity; + + interaction.secondary_momenta[other_index][0] = p4.e(); // p4_energy + interaction.secondary_momenta[other_index][1] = p4.px(); // p4_x + interaction.secondary_momenta[other_index][2] = p4.py(); // p4_y + interaction.secondary_momenta[other_index][3] = p4.pz(); // p4_z + interaction.secondary_masses[other_index] = p4.m(); + + interaction.secondary_helicity[other_index] = interaction.target_helicity; +} + +double HNLFromSpline::FinalStateProbability(dataclasses::InteractionRecord const & interaction) const { + double dxs = DifferentialCrossSection(interaction); + double txs = TotalCrossSection(interaction); + if(dxs == 0) { + return 0.0; + } else { + return dxs / txs; + } +} + +std::vector HNLFromSpline::GetPossiblePrimaries() const { + return std::vector(primary_types_.begin(), primary_types_.end()); +} + +std::vector HNLFromSpline::GetPossibleTargetsFromPrimary(LI::dataclasses::Particle::ParticleType primary_type) const { + return std::vector(target_types_.begin(), target_types_.end()); +} + +std::vector HNLFromSpline::GetPossibleSignatures() const { + return std::vector(signatures_.begin(), signatures_.end()); +} + +std::vector HNLFromSpline::GetPossibleTargets() const { + return std::vector(target_types_.begin(), target_types_.end()); +} + +std::vector HNLFromSpline::GetPossibleSignaturesFromParents(LI::dataclasses::Particle::ParticleType primary_type, LI::dataclasses::Particle::ParticleType target_type) const { + std::pair key(primary_type, target_type); + if(signatures_by_parent_types_.find(key) != signatures_by_parent_types_.end()) { + return signatures_by_parent_types_.at(key); + } else { + return std::vector(); + } +} + +std::vector HNLFromSpline::DensityVariables() const { + return std::vector{"Bjorken x", "Bjorken y"}; +} + +} // namespace crosssections +} // namespace LI diff --git a/projects/crosssections/private/NeutrissimoDecay.cxx b/projects/crosssections/private/NeutrissimoDecay.cxx index 3f3944de..95bbc249 100644 --- a/projects/crosssections/private/NeutrissimoDecay.cxx +++ b/projects/crosssections/private/NeutrissimoDecay.cxx @@ -1,20 +1,21 @@ - -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/utilities/Errors.h" -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/utilities/Constants.h" - -#include "LeptonInjector/detector/MaterialModel.h" - -#include "LeptonInjector/crosssections/Decay.h" #include "LeptonInjector/crosssections/NeutrissimoDecay.h" +#include // for array +#include // for copysign +#include // for tie +#include // for basic_s... + +#include // for Vector3 +#include // for P4, Boost + +#include "LeptonInjector/crosssections/Decay.h" // for Decay +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/math/Vector3D.h" // for Vector3D +#include "LeptonInjector/utilities/Constants.h" // for GeV, pi +#include "LeptonInjector/utilities/Random.h" // for LI_random + namespace LI { namespace crosssections { diff --git a/projects/crosssections/private/pybindings/CrossSection.h b/projects/crosssections/private/pybindings/CrossSection.h new file mode 100644 index 00000000..bca5360b --- /dev/null +++ b/projects/crosssections/private/pybindings/CrossSection.h @@ -0,0 +1,163 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +using namespace pybind11; +using namespace LI::crosssections; +class PyCrossSection : public LI::crosssections::CrossSection { +public: + using CrossSection::CrossSection; + + bool equal(const CrossSection& other) const override { + PYBIND11_OVERRIDE_PURE_NAME( + bool, + CrossSection, + "_equal", + equal, + other + ); + } + + double TotalCrossSection(LI::dataclasses::InteractionRecord const & record) const override { + PYBIND11_OVERRIDE_PURE( + double, + CrossSection, + TotalCrossSection, + record + ); + } + + double TotalCrossSection(LI::dataclasses::Particle::ParticleType primary, double energy, LI::dataclasses::Particle::ParticleType target) const override { + PYBIND11_OVERRIDE_PURE( + double, + CrossSection, + TotalCrossSection, + primary, + energy, + target + ); + } + + double DifferentialCrossSection(LI::dataclasses::InteractionRecord const & record) const override { + PYBIND11_OVERRIDE_PURE( + double, + CrossSection, + DifferentialCrossSection, + record + ); + } + + double InteractionThreshold(LI::dataclasses::InteractionRecord const & record) const override { + PYBIND11_OVERRIDE_PURE( + double, + CrossSection, + InteractionRecord, + record + ); + } + + void SampleFinalState(LI::dataclasses::InteractionRecord & record, std::shared_ptr rand) const override { + PYBIND11_OVERRIDE_PURE( + void, + CrossSection, + SampleFinalState, + record, + rand + ); + } + + std::vector GetPossibleTargets() const override { + PYBIND11_OVERRIDE_PURE( + std::vector, + CrossSection, + GetPossibleTargets + ); + } + + std::vector GetPossibleTargetsFromPrimary(LI::dataclasses::Particle::ParticleType primary_type) const override { + PYBIND11_OVERRIDE_PURE( + std::vector, + CrossSection, + GetPossibleTargetsFromPrimary, + primary_type + ); + } + + std::vector GetPossiblePrimaries() const override { + PYBIND11_OVERRIDE_PURE( + std::vector, + CrossSection, + GetPossiblePrimaries + ); + } + + std::vector GetPossibleSignatures() const override { + PYBIND11_OVERRIDE_PURE( + std::vector, + CrossSection, + GetPossibleSignatures + ); + } + + std::vector GetPossibleSignaturesFromParents(LI::dataclasses::Particle::ParticleType primary_type, LI::dataclasses::Particle::ParticleType target_type) const override { + PYBIND11_OVERRIDE_PURE( + std::vector, + CrossSection, + GetPossibleSignaturesFromParents, + primary_type, + target_type + ); + } + + double FinalStateProbability(LI::dataclasses::InteractionRecord const & record) const override { + PYBIND11_OVERRIDE_PURE( + double, + CrossSection, + FinalStateProbability, + record + ); + } + + std::vector DensityVariables() const override { + PYBIND11_OVERRIDE_PURE( + std::vector, + CrossSection, + DensityVariables + ); + } +}; + +void register_CrossSection(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_, PyCrossSection>(m, "CrossSection") + .def(init<>()) + .def("__eq__", [](const CrossSection &self, const CrossSection &other){ return self == other; }) + .def("equal", &CrossSection::equal) + .def("TotalCrossSection", (double (CrossSection::*)(LI::dataclasses::InteractionRecord const &) const)(&CrossSection::TotalCrossSection)) + .def("TotalCrossSection", (double (CrossSection::*)(LI::dataclasses::Particle::ParticleType, double, LI::dataclasses::Particle::ParticleType) const)(&CrossSection::TotalCrossSection)) + .def("DifferentialCrossSection", &CrossSection::DifferentialCrossSection) + .def("InteractionThreshold", &CrossSection::InteractionThreshold) + .def("SampleFinalState", &CrossSection::SampleFinalState) + .def("GetPossibleTargets", &CrossSection::GetPossibleTargets) + .def("GetPossibleTargetsFromPrimary", &CrossSection::GetPossibleTargetsFromPrimary) + .def("GetPossiblePrimaries", &CrossSection::GetPossiblePrimaries) + .def("GetPossibleSignatures", &CrossSection::GetPossibleSignatures) + .def("GetPossibleSignaturesFromParents", &CrossSection::GetPossibleSignaturesFromParents) + .def("FinalStateProbability", &CrossSection::FinalStateProbability) + .def("DensityVariables", &CrossSection::DensityVariables) + ; +} + diff --git a/projects/crosssections/private/pybindings/CrossSectionCollection.h b/projects/crosssections/private/pybindings/CrossSectionCollection.h new file mode 100644 index 00000000..0daedefd --- /dev/null +++ b/projects/crosssections/private/pybindings/CrossSectionCollection.h @@ -0,0 +1,36 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/CrossSectionCollection.h" +#include "../../public/LeptonInjector/crosssections/Decay.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_CrossSectionCollection(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_>(m, "CrossSectionCollection") + .def(init<>()) + .def(init>>()) + .def(init>>()) + .def(init>, std::vector>>()) + .def(self == self) + .def("GetDecays",&CrossSectionCollection::GetDecays) + .def("HasCrossSections",&CrossSectionCollection::HasCrossSections) + .def("HasDecays",&CrossSectionCollection::HasDecays) + .def("GetCrossSectionsForTarget",&CrossSectionCollection::GetCrossSectionsForTarget) + .def("GetCrossSectionsByTarget",&CrossSectionCollection::GetCrossSectionsByTarget) + .def("TargetTypes",&CrossSectionCollection::TargetTypes) + .def("TotalDecayWidth",&CrossSectionCollection::TotalDecayWidth) + .def("TotalDecayLength",&CrossSectionCollection::TotalDecayLength) + .def("MatchesPrimary",&CrossSectionCollection::MatchesPrimary) + ; +} diff --git a/projects/crosssections/private/pybindings/DISFromSpline.h b/projects/crosssections/private/pybindings/DISFromSpline.h new file mode 100644 index 00000000..a447b8a5 --- /dev/null +++ b/projects/crosssections/private/pybindings/DISFromSpline.h @@ -0,0 +1,45 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/DISFromSpline.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_DISFromSpline(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_, CrossSection> disfromspline(m, "DISFromSpline"); + + disfromspline + .def(init<>()) + .def(init, std::vector, int, double, double, std::set, std::set>()) + .def(init, std::vector, int, double, double, std::vector, std::vector>()) + .def(init, std::set>()) + .def(init, std::set>()) + .def(init, std::vector>()) + .def(init, std::vector>()) + .def(self == self) + .def("TotalCrossSection",overload_cast(&DISFromSpline::TotalCrossSection, const_)) + .def("TotalCrossSection",overload_cast(&DISFromSpline::TotalCrossSection, const_)) + .def("TotalCrossSection",overload_cast(&DISFromSpline::TotalCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&DISFromSpline::DifferentialCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&DISFromSpline::DifferentialCrossSection, const_)) + .def("InteractionThreshold",&DISFromSpline::InteractionThreshold) + .def("GetPossibleTargets",&DISFromSpline::GetPossibleTargets) + .def("GetPossibleTargetsFromPrimary",&DISFromSpline::GetPossibleTargetsFromPrimary) + .def("GetPossiblePrimaries",&DISFromSpline::GetPossiblePrimaries) + .def("GetPossibleSignatures",&DISFromSpline::GetPossibleSignatures) + .def("GetPossibleSignaturesFromParents",&DISFromSpline::GetPossibleSignaturesFromParents) + .def("FinalStateProbability",&DISFromSpline::FinalStateProbability); +} + diff --git a/projects/crosssections/private/pybindings/Decay.h b/projects/crosssections/private/pybindings/Decay.h new file mode 100644 index 00000000..9444a4d3 --- /dev/null +++ b/projects/crosssections/private/pybindings/Decay.h @@ -0,0 +1,23 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/Decay.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_Decay(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_>(m, "Decay") + .def("TotalDecayLength",&Decay::TotalDecayLength) + .def("TotalDecayLengthForFinalState",&Decay::TotalDecayLengthForFinalState); + +} diff --git a/projects/crosssections/private/pybindings/DipoleFromTable.h b/projects/crosssections/private/pybindings/DipoleFromTable.h new file mode 100644 index 00000000..46baacfb --- /dev/null +++ b/projects/crosssections/private/pybindings/DipoleFromTable.h @@ -0,0 +1,56 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/DipoleFromTable.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_DipoleFromTable(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_, CrossSection> dipolefromtable(m, "DipoleFromTable"); + + dipolefromtable + .def(init()) + .def(init()) + .def(init()) + .def(init>()) + .def(self == self) + .def(init>()) + .def(init>()) + .def("TotalCrossSection",overload_cast(&DipoleFromTable::TotalCrossSection, const_)) + .def("TotalCrossSection",overload_cast(&DipoleFromTable::TotalCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&DipoleFromTable::DifferentialCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&DipoleFromTable::DifferentialCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&DipoleFromTable::DifferentialCrossSection, const_)) + .def("InteractionThreshold",&DipoleFromTable::InteractionThreshold) + .def("GetPossibleTargets",&DipoleFromTable::GetPossibleTargets) + .def("GetPossibleTargetsFromPrimary",&DipoleFromTable::GetPossibleTargetsFromPrimary) + .def("GetPossiblePrimaries",&DipoleFromTable::GetPossiblePrimaries) + .def("GetPossibleSignatures",&DipoleFromTable::GetPossibleSignatures) + .def("GetPossibleSignaturesFromParents",&DipoleFromTable::GetPossibleSignaturesFromParents) + .def("AddDifferentialCrossSectionFile",&DipoleFromTable::AddDifferentialCrossSectionFile) + .def("AddTotalCrossSectionFile",&DipoleFromTable::AddTotalCrossSectionFile) + .def("AddDifferentialCrossSection",&DipoleFromTable::AddDifferentialCrossSection) + .def("AddTotalCrossSection",&DipoleFromTable::AddTotalCrossSection) + .def("DensityVariables",&DipoleFromTable::DensityVariables) + .def("FinalStateProbability",&DipoleFromTable::FinalStateProbability) + ; + + enum_(dipolefromtable, "HelicityChannel") + .value("Conserving",DipoleFromTable::HelicityChannel::Conserving) + .value("Flipping",DipoleFromTable::HelicityChannel::Flipping) + .export_values() + ; +} + diff --git a/projects/crosssections/private/pybindings/DummyCrossSection.h b/projects/crosssections/private/pybindings/DummyCrossSection.h new file mode 100644 index 00000000..ecbfcf61 --- /dev/null +++ b/projects/crosssections/private/pybindings/DummyCrossSection.h @@ -0,0 +1,38 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/DummyCrossSection.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_DummyCrossSection(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_, CrossSection> dummycrosssection(m, "DummyCrossSection"); + + dummycrosssection + .def(init<>()) + .def("_equal", &DummyCrossSection::equal) + .def("TotalCrossSection",overload_cast(&DummyCrossSection::TotalCrossSection, const_)) + .def("TotalCrossSection",overload_cast(&DummyCrossSection::TotalCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&DummyCrossSection::DifferentialCrossSection, const_)) + .def("InteractionThreshold",&DummyCrossSection::InteractionThreshold) + .def("GetPossibleTargets",&DummyCrossSection::GetPossibleTargets) + .def("GetPossibleTargetsFromPrimary",&DummyCrossSection::GetPossibleTargetsFromPrimary) + .def("GetPossiblePrimaries",&DummyCrossSection::GetPossiblePrimaries) + .def("GetPossibleSignatures",&DummyCrossSection::GetPossibleSignatures) + .def("GetPossibleSignaturesFromParents",&DummyCrossSection::GetPossibleSignaturesFromParents) + .def("FinalStateProbability",&DummyCrossSection::FinalStateProbability) + ; +} + diff --git a/projects/crosssections/private/pybindings/HNLFromSpline.h b/projects/crosssections/private/pybindings/HNLFromSpline.h new file mode 100644 index 00000000..bd7b7967 --- /dev/null +++ b/projects/crosssections/private/pybindings/HNLFromSpline.h @@ -0,0 +1,45 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/HNLFromSpline.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_HNLFromSpline(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_, CrossSection> disfromspline(m, "HNLFromSpline"); + + disfromspline + .def(init<>()) + .def(init, std::vector, int, double, double, std::set, std::set>()) + .def(init, std::vector, int, double, double, std::vector, std::vector>()) + .def(init, std::set>()) + .def(init, std::set>()) + .def(init, std::vector>()) + .def(init, std::vector>()) + .def(self == self) + .def("TotalCrossSection",overload_cast(&HNLFromSpline::TotalCrossSection, const_)) + .def("TotalCrossSection",overload_cast(&HNLFromSpline::TotalCrossSection, const_)) + .def("TotalCrossSection",overload_cast(&HNLFromSpline::TotalCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&HNLFromSpline::DifferentialCrossSection, const_)) + .def("DifferentialCrossSection",overload_cast(&HNLFromSpline::DifferentialCrossSection, const_)) + .def("InteractionThreshold",&HNLFromSpline::InteractionThreshold) + .def("GetPossibleTargets",&HNLFromSpline::GetPossibleTargets) + .def("GetPossibleTargetsFromPrimary",&HNLFromSpline::GetPossibleTargetsFromPrimary) + .def("GetPossiblePrimaries",&HNLFromSpline::GetPossiblePrimaries) + .def("GetPossibleSignatures",&HNLFromSpline::GetPossibleSignatures) + .def("GetPossibleSignaturesFromParents",&HNLFromSpline::GetPossibleSignaturesFromParents) + .def("FinalStateProbability",&HNLFromSpline::FinalStateProbability); +} + diff --git a/projects/crosssections/private/pybindings/NeutrissimoDecay.h b/projects/crosssections/private/pybindings/NeutrissimoDecay.h new file mode 100644 index 00000000..a8867969 --- /dev/null +++ b/projects/crosssections/private/pybindings/NeutrissimoDecay.h @@ -0,0 +1,44 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/crosssections/CrossSection.h" +#include "../../public/LeptonInjector/crosssections/NeutrissimoDecay.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/Particle.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h" +#include "../../../dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" +#include "../../../utilities/public/LeptonInjector/utilities/Random.h" + +void register_NeutrissimoDecay(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::crosssections; + + class_, Decay> neutrissimodecay(m, "NeutrissimoDecay"); + + neutrissimodecay + .def(init, NeutrissimoDecay::ChiralNature>()) + .def(init, NeutrissimoDecay::ChiralNature, std::set const &>()) + .def(init()) + .def(init const &>()) + .def(self == self) + .def("GetHNLMass",&NeutrissimoDecay::GetHNLMass) + .def("TotalDecayWidth",overload_cast(&NeutrissimoDecay::TotalDecayWidth, const_)) + .def("TotalDecayWidth",overload_cast(&NeutrissimoDecay::TotalDecayWidth, const_)) + .def("TotalDecayWidthForFinalState",&NeutrissimoDecay::TotalDecayWidthForFinalState) + .def("DifferentialDecayWidth",&NeutrissimoDecay::DifferentialDecayWidth) + .def("GetPossibleSignatures",&NeutrissimoDecay::GetPossibleSignatures) + .def("GetPossibleSignaturesFromParent",&NeutrissimoDecay::GetPossibleSignaturesFromParent) + .def("FinalStateProbability",&NeutrissimoDecay::FinalStateProbability) + ; + + enum_(neutrissimodecay, "ChiralNature") + .value("Dirac",NeutrissimoDecay::ChiralNature::Dirac) + .value("Majorana",NeutrissimoDecay::ChiralNature::Majorana) + .export_values() + ; +} diff --git a/projects/crosssections/private/pybindings/crosssections.cxx b/projects/crosssections/private/pybindings/crosssections.cxx index e1ea2cf8..0a4e31a4 100644 --- a/projects/crosssections/private/pybindings/crosssections.cxx +++ b/projects/crosssections/private/pybindings/crosssections.cxx @@ -2,10 +2,20 @@ #include #include "../../public/LeptonInjector/crosssections/CrossSection.h" -#include "../../public/LeptonInjector/crosssections/Decay.h" -#include "../../public/LeptonInjector/crosssections/DipoleFromTable.h" #include "../../public/LeptonInjector/crosssections/NeutrissimoDecay.h" #include "../../public/LeptonInjector/crosssections/CrossSectionCollection.h" +#include "../../public/LeptonInjector/crosssections/DISFromSpline.h" +#include "../../public/LeptonInjector/crosssections/HNLFromSpline.h" +#include "../../public/LeptonInjector/crosssections/CrossSectionCollection.h" + +#include "./CrossSection.h" +#include "./DipoleFromTable.h" +#include "./DISFromSpline.h" +#include "./HNLFromSpline.h" +#include "./Decay.h" +#include "./NeutrissimoDecay.h" +#include "./CrossSectionCollection.h" +#include "./DummyCrossSection.h" #include #include @@ -16,83 +26,14 @@ PYBIND11_DECLARE_HOLDER_TYPE(T__,std::shared_ptr) using namespace pybind11; PYBIND11_MODULE(crosssections,m) { - using namespace LI::crosssections; - - class_>(m, "CrossSection"); - - class_>(m, "Decay") - .def("TotalDecayLength",&Decay::TotalDecayLength) - .def("TotalDecayLengthForFinalState",&Decay::TotalDecayLengthForFinalState); - - class_, CrossSection> dipolefromtable(m, "DipoleFromTable"); - - dipolefromtable - .def(init()) - .def(init()) - .def(init()) - .def(init>()) - .def(self == self) - .def(init>()) - .def(init>()) - .def("TotalCrossSection",overload_cast(&DipoleFromTable::TotalCrossSection, const_)) - .def("TotalCrossSection",overload_cast(&DipoleFromTable::TotalCrossSection, const_)) - .def("DifferentialCrossSection",overload_cast(&DipoleFromTable::DifferentialCrossSection, const_)) - .def("DifferentialCrossSection",overload_cast(&DipoleFromTable::DifferentialCrossSection, const_)) - .def("DifferentialCrossSection",overload_cast(&DipoleFromTable::DifferentialCrossSection, const_)) - .def("InteractionThreshold",&DipoleFromTable::InteractionThreshold) - .def("GetPossibleTargets",&DipoleFromTable::GetPossibleTargets) - .def("GetPossibleTargetsFromPrimary",&DipoleFromTable::GetPossibleTargetsFromPrimary) - .def("GetPossiblePrimaries",&DipoleFromTable::GetPossiblePrimaries) - .def("GetPossibleSignatures",&DipoleFromTable::GetPossibleSignatures) - .def("GetPossibleSignaturesFromParents",&DipoleFromTable::GetPossibleSignaturesFromParents) - .def("AddDifferentialCrossSectionFile",&DipoleFromTable::AddDifferentialCrossSectionFile) - .def("AddTotalCrossSectionFile",&DipoleFromTable::AddTotalCrossSectionFile) - .def("AddDifferentialCrossSection",&DipoleFromTable::AddDifferentialCrossSection) - .def("AddTotalCrossSection",&DipoleFromTable::AddTotalCrossSection) - .def("DensityVariables",&DipoleFromTable::DensityVariables) - .def("FinalStateProbability",&DipoleFromTable::FinalStateProbability); - - enum_(dipolefromtable, "HelicityChannel") - .value("Conserving",DipoleFromTable::HelicityChannel::Conserving) - .value("Flipping",DipoleFromTable::HelicityChannel::Flipping) - .export_values(); - - class_, Decay> neutrissimodecay(m, "NeutrissimoDecay"); - - neutrissimodecay - .def(init, NeutrissimoDecay::ChiralNature>()) - .def(init, NeutrissimoDecay::ChiralNature, std::set const &>()) - .def(init()) - .def(init const &>()) - .def(self == self) - .def("GetHNLMass",&NeutrissimoDecay::GetHNLMass) - .def("TotalDecayWidth",overload_cast(&NeutrissimoDecay::TotalDecayWidth, const_)) - .def("TotalDecayWidth",overload_cast(&NeutrissimoDecay::TotalDecayWidth, const_)) - .def("TotalDecayWidthForFinalState",&NeutrissimoDecay::TotalDecayWidthForFinalState) - .def("DifferentialDecayWidth",&NeutrissimoDecay::DifferentialDecayWidth) - .def("GetPossibleSignatures",&NeutrissimoDecay::GetPossibleSignatures) - .def("GetPossibleSignaturesFromParent",&NeutrissimoDecay::GetPossibleSignaturesFromParent) - .def("FinalStateProbability",&NeutrissimoDecay::FinalStateProbability); - - enum_(neutrissimodecay, "ChiralNature") - .value("Dirac",NeutrissimoDecay::ChiralNature::Dirac) - .value("Majorana",NeutrissimoDecay::ChiralNature::Majorana) - .export_values(); - - class_>(m, "CrossSectionCollection") - .def(init<>()) - .def(init>>()) - .def(init>>()) - .def(init>, std::vector>>()) - .def(self == self) - .def("GetDecays",&CrossSectionCollection::GetDecays) - .def("HasCrossSections",&CrossSectionCollection::HasCrossSections) - .def("HasDecays",&CrossSectionCollection::HasDecays) - .def("GetCrossSectionsForTarget",&CrossSectionCollection::GetCrossSectionsForTarget) - .def("GetCrossSectionsByTarget",&CrossSectionCollection::GetCrossSectionsByTarget) - .def("TargetTypes",&CrossSectionCollection::TargetTypes) - .def("TotalDecayWidth",&CrossSectionCollection::TotalDecayWidth) - .def("TotalDecayLength",&CrossSectionCollection::TotalDecayLength) - .def("MatchesPrimary",&CrossSectionCollection::MatchesPrimary); - + using namespace LI::crosssections; + + register_CrossSection(m); + register_DipoleFromTable(m); + register_DISFromSpline(m); + register_HNLFromSpline(m); + register_Decay(m); + register_NeutrissimoDecay(m); + register_CrossSectionCollection(m); + register_DummyCrossSection(m); } diff --git a/projects/crosssections/public/LeptonInjector/crosssections/CrossSection.h b/projects/crosssections/public/LeptonInjector/crosssections/CrossSection.h index e396f414..ebe28006 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/CrossSection.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/CrossSection.h @@ -2,9 +2,10 @@ #ifndef LI_CrossSection_H #define LI_CrossSection_H -#include -#include -#include +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t #include #include @@ -13,15 +14,11 @@ #include #include -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -namespace LI { -namespace utilities { -class LI_random; -} -} +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace dataclasses { struct InteractionSignature; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace crosssections { diff --git a/projects/crosssections/public/LeptonInjector/crosssections/CrossSectionCollection.h b/projects/crosssections/public/LeptonInjector/crosssections/CrossSectionCollection.h index 6b47ac1d..a2282a4d 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/CrossSectionCollection.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/CrossSectionCollection.h @@ -2,6 +2,13 @@ #ifndef LI_CrossSectionCollection_H #define LI_CrossSectionCollection_H +#include // for map +#include // for set +#include // for shared_ptr +#include // for vector +#include // for uint32_t +#include // for runtime_error + #include #include #include @@ -16,12 +23,11 @@ #include #include -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/crosssections/Decay.h" +namespace LI { namespace crosssections { class CrossSection; } } +namespace LI { namespace crosssections { class Decay; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } namespace LI { namespace crosssections { diff --git a/projects/crosssections/public/LeptonInjector/crosssections/DISFromSpline.h b/projects/crosssections/public/LeptonInjector/crosssections/DISFromSpline.h index bf5d3872..8089ac60 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/DISFromSpline.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/DISFromSpline.h @@ -2,13 +2,14 @@ #ifndef LI_DISFromSpline_H #define LI_DISFromSpline_H -#include -#include +#include // for set +#include // for map #include -#include -#include +#include // for vector +#include // for uint32_t +#include // for pair #include -#include +#include // for runtime... #include #include @@ -23,11 +24,12 @@ #include #include -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSe... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -#include "LeptonInjector/crosssections/CrossSection.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace crosssections { diff --git a/projects/crosssections/public/LeptonInjector/crosssections/Decay.h b/projects/crosssections/public/LeptonInjector/crosssections/Decay.h index fdd73c42..66198801 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/Decay.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/Decay.h @@ -2,9 +2,10 @@ #ifndef LI_Decay_H #define LI_Decay_H -#include -#include -#include +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t #include #include @@ -13,23 +14,19 @@ #include #include -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -namespace LI { -namespace utilities { -class LI_random; -} -} +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace dataclasses { struct InteractionSignature; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace crosssections { class Decay{ - friend cereal::access; - private: - public: +friend cereal::access; +private: +public: Decay(); virtual ~Decay() {}; bool operator==(Decay const & other) const; diff --git a/projects/crosssections/public/LeptonInjector/crosssections/DipoleFromTable.h b/projects/crosssections/public/LeptonInjector/crosssections/DipoleFromTable.h index 60a848d3..427b8009 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/DipoleFromTable.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/DipoleFromTable.h @@ -2,12 +2,13 @@ #ifndef LI_DipoleFromTable_H #define LI_DipoleFromTable_H -#include -#include -#include -#include -#include -#include +#include // for map +#include // for set +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include @@ -18,13 +19,13 @@ #include #include -#include "LeptonInjector/utilities/Interpolator.h" +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSection +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/utilities/Interpolator.h" // for Interpolator1D -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/crosssections/CrossSection.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace dataclasses { struct InteractionSignature; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace crosssections { diff --git a/projects/crosssections/public/LeptonInjector/crosssections/DummyCrossSection.h b/projects/crosssections/public/LeptonInjector/crosssections/DummyCrossSection.h new file mode 100644 index 00000000..fe8f4319 --- /dev/null +++ b/projects/crosssections/public/LeptonInjector/crosssections/DummyCrossSection.h @@ -0,0 +1,80 @@ +#pragma once +#ifndef LI_DummyCrossSection_H +#define LI_DummyCrossSection_H + +#include +#include +#include // for vector +#include // for uint32_t +#include // for runtime_error + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSection +#include "LeptonInjector/dataclasses/Particle.h" // for Particle + +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace dataclasses { struct InteractionSignature; } } +namespace LI { namespace utilities { class LI_random; } } + +namespace LI { +namespace crosssections { + +class DummyCrossSection : public CrossSection { +friend cereal::access; +private: +public: + DummyCrossSection(); + + virtual bool equal(CrossSection const & other) const override; + + double TotalCrossSection(dataclasses::InteractionRecord const &) const override; + double TotalCrossSection(LI::dataclasses::Particle::ParticleType primary, double energy, LI::dataclasses::Particle::ParticleType target) const override; + double DifferentialCrossSection(dataclasses::InteractionRecord const &) const override; + double InteractionThreshold(dataclasses::InteractionRecord const &) const override; + void SampleFinalState(dataclasses::InteractionRecord &, std::shared_ptr random) const override; + + std::vector GetPossibleTargets() const override; + std::vector GetPossibleTargetsFromPrimary(LI::dataclasses::Particle::ParticleType primary_type) const override; + std::vector GetPossiblePrimaries() const override; + std::vector GetPossibleSignatures() const override; + std::vector GetPossibleSignaturesFromParents(LI::dataclasses::Particle::ParticleType primary_type, LI::dataclasses::Particle::ParticleType target_type) const override; + + virtual double FinalStateProbability(dataclasses::InteractionRecord const & record) const override; + +public: + virtual std::vector DensityVariables() const override; + template + void save(Archive & archive, std::uint32_t const version) const { + if(version == 0) { + archive(cereal::virtual_base_class(this)); + } else { + throw std::runtime_error("DummyCrossSection only supports version <= 0!"); + } + } + template + void load(Archive & archive, std::uint32_t version) { + if(version == 0) { + archive(cereal::virtual_base_class(this)); + } else { + throw std::runtime_error("DummyCrossSection only supports version <= 0!"); + } + } +}; + +} // namespace crosssections +} // namespace LI + +CEREAL_CLASS_VERSION(LI::crosssections::DummyCrossSection, 0); +CEREAL_REGISTER_TYPE(LI::crosssections::DummyCrossSection); +CEREAL_REGISTER_POLYMORPHIC_RELATION(LI::crosssections::CrossSection, LI::crosssections::DummyCrossSection); + +#endif // LI_DummyCrossSection_H diff --git a/projects/crosssections/public/LeptonInjector/crosssections/ElasticScattering.h b/projects/crosssections/public/LeptonInjector/crosssections/ElasticScattering.h index 2db4c917..06893b3a 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/ElasticScattering.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/ElasticScattering.h @@ -2,11 +2,12 @@ #ifndef LI_ElasticScattering_H #define LI_ElasticScattering_H -#include +#include // for set #include #include -#include -#include +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include @@ -16,11 +17,12 @@ #include #include -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSection +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -#include "LeptonInjector/crosssections/CrossSection.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace dataclasses { struct InteractionSignature; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace crosssections { diff --git a/projects/crosssections/public/LeptonInjector/crosssections/HNLDecay.h b/projects/crosssections/public/LeptonInjector/crosssections/HNLDecay.h new file mode 100644 index 00000000..68cee7b1 --- /dev/null +++ b/projects/crosssections/public/LeptonInjector/crosssections/HNLDecay.h @@ -0,0 +1,100 @@ +#pragma once +#ifndef LI_HNLDecay_H +#define LI_HNLDecay_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/dataclasses/InteractionSignature.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" + +#include "LeptonInjector/crosssections/Decay.h" + +namespace LI { +namespace crosssections { + +class HNLDecay : public Decay { +friend cereal::access; +protected: +HNLDecay() {}; +public: + enum ChiralNature {Dirac, Majorana}; +private: + double hnl_mass; + std::vector mixing; // Ue4, Um4, Ut4 + ChiralNature nature; + const std::set primary_types = {LI::dataclasses::Particle::ParticleType::NuF4, LI::dataclasses::Particle::ParticleType::NuF4Bar}; +public: + HNLDecay(double hnl_mass, std::vector mixing, ChiralNature nature) : hnl_mass(hnl_mass), mixing(mixing), nature(nature) {}; + HNLDecay(double hnl_mass, std::vector mixing, ChiralNature nature, std::set const & primary_types) : hnl_mass(hnl_mass), mixing(mixing), nature(nature), primary_types(primary_types) {}; + virtual bool equal(Decay const & other) const override; + double GetHNLMass() const {return hnl_mass;}; + // if only one dipole coupling provided, assume it is U4t + HNLDecay(double hnl_mass, double mixing, ChiralNature nature) : hnl_mass(hnl_mass), mixing(std::vector{0,0,mixing}), nature(nature) {}; + HNLDecay(double hnl_mass, double mixing, ChiralNature nature, std::set const & primary_types) : hnl_mass(hnl_mass), mixing(std::vector{0,0,mixing}), nature(nature), primary_types(primary_types) {}; + virtual double TotalDecayWidth(dataclasses::InteractionRecord const &) const override; + virtual double TotalDecayWidth(LI::dataclasses::Particle::ParticleType primary) const override; + virtual double TotalDecayWidthForFinalState(dataclasses::InteractionRecord const &) const override; + virtual double DifferentialDecayWidth(dataclasses::InteractionRecord const &) const override; + virtual void SampleFinalState(dataclasses::InteractionRecord &, std::shared_ptr) const override; + virtual std::vector GetPossibleSignatures() const override; + virtual std::vector GetPossibleSignaturesFromParent(LI::dataclasses::Particle::ParticleType primary) const override; + virtual double FinalStateProbability(dataclasses::InteractionRecord const & record) const override; +public: + virtual std::vector DensityVariables() const override; + template + void save(Archive & archive, std::uint32_t const version) const { + if(version == 0) { + archive(::cereal::make_nvp("PrimaryTypes", primary_types)); + archive(::cereal::make_nvp("HNLMass", hnl_mass)); + archive(::cereal::make_nvp("DipoleCoupling", mixing)); + archive(::cereal::make_nvp("ChiralNature", static_cast(nature))); + archive(::cereal::make_nvp("Decay", cereal::virtual_base_class(this))); + } else { + throw std::runtime_error("HNLDecay only supports version <= 0!"); + } + } + template + void load_and_construct(Archive & archive, cereal::construct & construct, std::uint32_t version) { + if(version == 0) { + std::set _primary_types; + double _hnl_mass; + double _mixing; + ChiralNature _nature; + + archive(::cereal::make_nvp("PrimaryTypes", _primary_types)); + archive(::cereal::make_nvp("HNLMass", _hnl_mass)); + archive(::cereal::make_nvp("DipoleCoupling", _mixing)); + archive(::cereal::make_nvp("ChiralNature", _nature)); + construct(_hnl_mass, _mixing, _nature, _primary_types); + archive(::cereal::make_nvp("Decay", cereal::virtual_base_class(construct.ptr()))); + } else { + throw std::runtime_error("HNLDecay only supports version <= 0!"); + } + } + +}; + +} // namespace crosssections +} // namespace LI + +CEREAL_CLASS_VERSION(LI::crosssections::HNLDecay, 0); +CEREAL_REGISTER_TYPE(LI::crosssections::HNLDecay); +CEREAL_REGISTER_POLYMORPHIC_RELATION(LI::crosssections::Decay, LI::crosssections::HNLDecay); + +#endif // LI_HNLDecay_H diff --git a/projects/crosssections/public/LeptonInjector/crosssections/HNLFromSpline.h b/projects/crosssections/public/LeptonInjector/crosssections/HNLFromSpline.h new file mode 100644 index 00000000..16b654e8 --- /dev/null +++ b/projects/crosssections/public/LeptonInjector/crosssections/HNLFromSpline.h @@ -0,0 +1,158 @@ +#pragma once +#ifndef LI_HNLFromSpline_H +#define LI_HNLFromSpline_H + +#include // for map +#include // for set +#include +#include +#include // for vector +#include // for uint32_t +#include +#include // for runtime... + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "LeptonInjector/crosssections/CrossSection.h" // for CrossSe... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "photospline/detail/fitsio.h" // for splinet... + +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace utilities { class LI_random; } } +namespace cereal { class access; } + + +namespace LI { +namespace crosssections { + +class HNLFromSpline : public CrossSection { +friend cereal::access; +private: + photospline::splinetable<> differential_cross_section_; + photospline::splinetable<> total_cross_section_; + + std::vector signatures_; + std::set primary_types_; + std::set target_types_; + std::map> targets_by_primary_types_; + std::map, std::vector> signatures_by_parent_types_; + + int interaction_type_; + double target_mass_; + double minimum_Q2_; + +public: + HNLFromSpline(); + HNLFromSpline(std::vector differential_data, std::vector total_data, int interaction, double target_mass, double minumum_Q2, std::set primary_types, std::set target_types); + HNLFromSpline(std::vector differential_data, std::vector total_data, int interaction, double target_mass, double minumum_Q2, std::vector primary_types, std::vector target_types); + HNLFromSpline(std::string differential_filename, std::string total_filename, int interaction, double target_mass, double minumum_Q2, std::set primary_types, std::set target_types); + HNLFromSpline(std::string differential_filename, std::string total_filename, std::set primary_types, std::set target_types); + HNLFromSpline(std::string differential_filename, std::string total_filename, int interaction, double target_mass, double minumum_Q2, std::vector primary_types, std::vector target_types); + HNLFromSpline(std::string differential_filename, std::string total_filename, std::vector primary_types, std::vector target_types); + + virtual bool equal(CrossSection const & other) const override; + + double TotalCrossSection(dataclasses::InteractionRecord const &) const override; + double TotalCrossSection(LI::dataclasses::Particle::ParticleType primary, double energy) const; + double TotalCrossSection(LI::dataclasses::Particle::ParticleType primary, double energy, LI::dataclasses::Particle::ParticleType target) const override; + double DifferentialCrossSection(dataclasses::InteractionRecord const &) const override; + double DifferentialCrossSection(double energy, double x, double y, double secondary_lepton_mass) const; + double InteractionThreshold(dataclasses::InteractionRecord const &) const override; + void SampleFinalState(dataclasses::InteractionRecord &, std::shared_ptr random) const override; + + std::vector GetPossibleTargets() const override; + std::vector GetPossibleTargetsFromPrimary(LI::dataclasses::Particle::ParticleType primary_type) const override; + std::vector GetPossiblePrimaries() const override; + std::vector GetPossibleSignatures() const override; + std::vector GetPossibleSignaturesFromParents(LI::dataclasses::Particle::ParticleType primary_type, LI::dataclasses::Particle::ParticleType target_type) const override; + + virtual double FinalStateProbability(dataclasses::InteractionRecord const & record) const override; + + void LoadFromFile(std::string differential_filename, std::string total_filename); + void LoadFromMemory(std::vector & differential_data, std::vector & total_data); + + double GetMinimumQ2() const {return minimum_Q2_;}; + double GetTargetMass() const {return target_mass_;}; + int GetInteractionType() const {return interaction_type_;}; + +public: + virtual std::vector DensityVariables() const override; + template + void save(Archive & archive, std::uint32_t const version) const { + if(version == 0) { + splinetable_buffer buf; + buf.size = 0; + auto result_obj = differential_cross_section_.write_fits_mem(); + buf.data = result_obj.first; + buf.size = result_obj.second; + + std::vector diff_blob; + diff_blob.resize(buf.size); + std::copy((char*)buf.data, (char*)buf.data + buf.size, &diff_blob[0]); + + archive(::cereal::make_nvp("DifferentialCrossSectionSpline", diff_blob)); + + buf.size = 0; + result_obj = total_cross_section_.write_fits_mem(); + buf.data = result_obj.first; + buf.size = result_obj.second; + + std::vector total_blob; + total_blob.resize(buf.size); + std::copy((char*)buf.data, (char*)buf.data + buf.size, &total_blob[0]); + + archive(::cereal::make_nvp("TotalCrossSectionSpline", total_blob)); + archive(::cereal::make_nvp("PrimaryTypes", primary_types_)); + archive(::cereal::make_nvp("TargetTypes", target_types_)); + archive(::cereal::make_nvp("InteractionType", interaction_type_)); + archive(::cereal::make_nvp("TargetMass", target_mass_)); + archive(::cereal::make_nvp("MinimumQ2", minimum_Q2_)); + archive(cereal::virtual_base_class(this)); + } else { + throw std::runtime_error("HNLFromSpline only supports version <= 0!"); + } + } + template + void load(Archive & archive, std::uint32_t version) { + if(version == 0) { + std::vector differential_data; + std::vector total_data; + archive(::cereal::make_nvp("DifferentialCrossSectionSpline", differential_data)); + archive(::cereal::make_nvp("TotalCrossSectionSpline", total_data)); + archive(::cereal::make_nvp("PrimaryTypes", primary_types_)); + archive(::cereal::make_nvp("TargetTypes", target_types_)); + archive(::cereal::make_nvp("InteractionType", interaction_type_)); + archive(::cereal::make_nvp("TargetMass", target_mass_)); + archive(::cereal::make_nvp("MinimumQ2", minimum_Q2_)); + archive(cereal::virtual_base_class(this)); + LoadFromMemory(differential_data, total_data); + InitializeSignatures(); + } else { + throw std::runtime_error("HNLFromSpline only supports version <= 0!"); + } + } +private: + void ReadParamsFromSplineTable(); + void InitializeSignatures(); +}; + +} // namespace crosssections +} // namespace LI + +CEREAL_CLASS_VERSION(LI::crosssections::HNLFromSpline, 0); +CEREAL_REGISTER_TYPE(LI::crosssections::HNLFromSpline); +CEREAL_REGISTER_POLYMORPHIC_RELATION(LI::crosssections::CrossSection, LI::crosssections::HNLFromSpline); + +#endif // LI_HNLFromSpline_H diff --git a/projects/crosssections/public/LeptonInjector/crosssections/NeutrissimoDecay.h b/projects/crosssections/public/LeptonInjector/crosssections/NeutrissimoDecay.h index 49898f8c..d8650fb3 100644 --- a/projects/crosssections/public/LeptonInjector/crosssections/NeutrissimoDecay.h +++ b/projects/crosssections/public/LeptonInjector/crosssections/NeutrissimoDecay.h @@ -2,12 +2,12 @@ #ifndef LI_NeutrissimoDecay_H #define LI_NeutrissimoDecay_H -#include -#include -#include -#include -#include -#include +#include // for set +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include @@ -18,12 +18,12 @@ #include #include +#include "LeptonInjector/crosssections/Decay.h" // for Decay +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/crosssections/Decay.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace dataclasses { struct InteractionSignature; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace crosssections { diff --git a/projects/dataclasses/CMakeLists.txt b/projects/dataclasses/CMakeLists.txt index 69ae720f..ef630ec9 100644 --- a/projects/dataclasses/CMakeLists.txt +++ b/projects/dataclasses/CMakeLists.txt @@ -11,18 +11,16 @@ LIST (APPEND dataclasses_SOURCES add_library(LI_dataclasses OBJECT ${dataclasses_SOURCES}) set_property(TARGET LI_dataclasses PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_dataclasses PUBLIC - ${PROJECT_SOURCE_DIR}/projects/dataclasses/public/ + $ + $ ) -add_dependencies(LI_dataclasses LI_serialization LI_utilities LI_math) -target_link_libraries(LI_dataclasses photospline) - -target_include_directories(LI_dataclasses PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) -target_include_directories(LI_dataclasses PUBLIC ${PROJECT_SOURCE_DIR}/projects/utilities/public/) -target_include_directories(LI_dataclasses PUBLIC ${PROJECT_SOURCE_DIR}/projects/math/public/) - -install(TARGETS LI_dataclasses - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +target_link_libraries(LI_dataclasses PUBLIC + photospline + LI_serialization + LI_utilities + LI_math +) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/dataclasses/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} diff --git a/projects/dataclasses/private/DecayRecord.cxx b/projects/dataclasses/private/DecayRecord.cxx index ec8bb539..2014c4c8 100644 --- a/projects/dataclasses/private/DecayRecord.cxx +++ b/projects/dataclasses/private/DecayRecord.cxx @@ -1,8 +1,6 @@ -#include - -#include "LeptonInjector/dataclasses/Particle.h" #include "LeptonInjector/dataclasses/DecayRecord.h" -#include "LeptonInjector/dataclasses/DecaySignature.h" + +#include namespace LI { namespace dataclasses { diff --git a/projects/dataclasses/private/DecaySignature.cxx b/projects/dataclasses/private/DecaySignature.cxx index fea72f35..0d74f8c4 100644 --- a/projects/dataclasses/private/DecaySignature.cxx +++ b/projects/dataclasses/private/DecaySignature.cxx @@ -1,8 +1,7 @@ -#include - -#include "LeptonInjector/dataclasses/Particle.h" #include "LeptonInjector/dataclasses/DecaySignature.h" +#include + namespace LI { namespace dataclasses { diff --git a/projects/dataclasses/private/InteractionRecord.cxx b/projects/dataclasses/private/InteractionRecord.cxx index fe35a039..b516c010 100644 --- a/projects/dataclasses/private/InteractionRecord.cxx +++ b/projects/dataclasses/private/InteractionRecord.cxx @@ -1,5 +1,8 @@ #include "LeptonInjector/dataclasses/InteractionRecord.h" +#include // for tie, operator==, tuple +#include // for operator<<, basic_ostream, char_traits, endl, ost... + namespace LI { namespace dataclasses { diff --git a/projects/dataclasses/private/InteractionSignature.cxx b/projects/dataclasses/private/InteractionSignature.cxx index 2413975d..d2a1e2be 100644 --- a/projects/dataclasses/private/InteractionSignature.cxx +++ b/projects/dataclasses/private/InteractionSignature.cxx @@ -1,7 +1,8 @@ -#include - #include "LeptonInjector/dataclasses/InteractionSignature.h" +#include // for tie, operator<, operator==, tuple +#include // for operator<<, char_traits, basic_ostream, endl, ost... + namespace LI { namespace dataclasses { diff --git a/projects/dataclasses/private/InteractionTree.cxx b/projects/dataclasses/private/InteractionTree.cxx index e366da6b..f54709a7 100644 --- a/projects/dataclasses/private/InteractionTree.cxx +++ b/projects/dataclasses/private/InteractionTree.cxx @@ -1,8 +1,10 @@ #include "LeptonInjector/dataclasses/InteractionTree.h" +#include + namespace LI { namespace dataclasses { - + int InteractionTreeDatum::depth() const { int depth = 0; if(parent==NULL) return depth; diff --git a/projects/dataclasses/private/Particle.cxx b/projects/dataclasses/private/Particle.cxx index 412f6cca..2a237ec8 100644 --- a/projects/dataclasses/private/Particle.cxx +++ b/projects/dataclasses/private/Particle.cxx @@ -1,8 +1,17 @@ -#include -#include // adds sqrt, power functions -#include #include "LeptonInjector/dataclasses/Particle.h" +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "LeptonInjector/utilities/Constants.h" + namespace LI { namespace dataclasses { Particle::Particle(void){ diff --git a/projects/dataclasses/public/LeptonInjector/dataclasses/DecayRecord.h b/projects/dataclasses/public/LeptonInjector/dataclasses/DecayRecord.h index ad2283d6..8672300f 100644 --- a/projects/dataclasses/public/LeptonInjector/dataclasses/DecayRecord.h +++ b/projects/dataclasses/public/LeptonInjector/dataclasses/DecayRecord.h @@ -1,6 +1,12 @@ #ifndef LI_DecayRecord_H #define LI_DecayRecord_H +#include // for array +#include // for vector +#include // for uint32_t +#include // for ostream +#include // for runtime_error + #include #include #include @@ -9,13 +15,6 @@ #include #include -#include -#include -#include -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" #include "LeptonInjector/dataclasses/DecaySignature.h" namespace LI { diff --git a/projects/dataclasses/public/LeptonInjector/dataclasses/DecaySignature.h b/projects/dataclasses/public/LeptonInjector/dataclasses/DecaySignature.h index beac5a60..7024a31d 100644 --- a/projects/dataclasses/public/LeptonInjector/dataclasses/DecaySignature.h +++ b/projects/dataclasses/public/LeptonInjector/dataclasses/DecaySignature.h @@ -1,6 +1,11 @@ #ifndef LI_DecaySignature_H #define LI_DecaySignature_H +#include // for uint32_t +#include // for vector +#include // for ostream +#include // for runtime_error + #include #include #include @@ -9,11 +14,6 @@ #include #include -#include -#include -#include -#include - #include "LeptonInjector/dataclasses/Particle.h" namespace LI { diff --git a/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h b/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h index d44f99c6..7010dccb 100644 --- a/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h +++ b/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionRecord.h @@ -2,8 +2,11 @@ #ifndef LI_InteractionRecord_H #define LI_InteractionRecord_H -#include -#include +#include // for array +#include // for ostream +#include // for vector +#include // for uint32_t +#include // for runtime... #include #include diff --git a/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h b/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h index 1eb87f22..730705b4 100644 --- a/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h +++ b/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionSignature.h @@ -2,9 +2,13 @@ #ifndef LI_InteractionSignature_H #define LI_InteractionSignature_H -#include +#include // for ostream +#include // for vector +#include // for uint32_t +#include // for runtime_error +#include // for make_nvp, CEREAL_CL... -#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle namespace LI { namespace dataclasses { diff --git a/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionTree.h b/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionTree.h index 04f58a39..42f6a2d8 100644 --- a/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionTree.h +++ b/projects/dataclasses/public/LeptonInjector/dataclasses/InteractionTree.h @@ -2,10 +2,15 @@ #ifndef LI_InteractionTree_H #define LI_InteractionTree_H -#endif // LI_InteractionTree_H - #include "LeptonInjector/dataclasses/InteractionRecord.h" +#include // for set +#include // for shared_ptr +#include // for vector +#include // for uint32_t +#include // for NULL +#include // for runtime_error + #include #include #include @@ -15,7 +20,6 @@ #include #include - namespace LI { namespace dataclasses { @@ -55,3 +59,6 @@ struct InteractionTree { } // namespace dataclasses } // namespace LI + +#endif // LI_InteractionTree_H + diff --git a/projects/dataclasses/public/LeptonInjector/dataclasses/Particle.h b/projects/dataclasses/public/LeptonInjector/dataclasses/Particle.h index 66f538b4..b1b7e749 100644 --- a/projects/dataclasses/public/LeptonInjector/dataclasses/Particle.h +++ b/projects/dataclasses/public/LeptonInjector/dataclasses/Particle.h @@ -5,12 +5,10 @@ // Used to define the Particle class // Partiles have a type, energy, position, and direction -// !!! Important !!! -// At the moment, only leptons (charged + uncharged) and hadrons are fully supported - +#include #include -#include // std::pair -#include +#include +#include #include #include @@ -19,10 +17,7 @@ #include #include - -#include "LeptonInjector/utilities/Constants.h" - -// positions are in Cartesian, centered in the middle of IceCube +#include namespace LI { namespace dataclasses { @@ -42,14 +37,22 @@ class Particle { Pi0 = 111, PiPlus = 211, PiMinus = -211, + Rho0 = 113, + RhoPlus = 213, + RhoMinus = -213, K0_Long = 130, KPlus = 321, KMinus = -321, + KStarPlus = 9000311, + KStarMinus = -9000311, Neutron = 2112, PPlus = 2212, PMinus = -2212, K0_Short = 310, Eta = 221, + EtaPrime= 331, + Omega = 223, + Phi = 333, Lambda = 3122, SigmaPlus = 3222, Sigma0 = 3212, diff --git a/projects/detector/CMakeLists.txt b/projects/detector/CMakeLists.txt index fd24bf88..86af2dd8 100644 --- a/projects/detector/CMakeLists.txt +++ b/projects/detector/CMakeLists.txt @@ -20,22 +20,21 @@ LIST (APPEND detector_SOURCES add_library(LI_detector OBJECT ${detector_SOURCES}) set_property(TARGET LI_detector PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_detector PUBLIC - ${PROJECT_SOURCE_DIR}/projects/detector/public/ + $ + $ ) -add_dependencies(LI_detector LI_serialization LI_utilities LI_math LI_dataclasses LI_geometry) -target_link_libraries(LI_detector photospline) -target_link_libraries(LI_detector rk) - -target_include_directories(LI_detector PUBLIC ${PROJECT_SOURCE_DIR}/vendor/rk/include) -target_include_directories(LI_detector PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) -target_include_directories(LI_detector PUBLIC ${PROJECT_SOURCE_DIR}/projects/utilities/public/) -target_include_directories(LI_detector PUBLIC ${PROJECT_SOURCE_DIR}/projects/math/public/) -target_include_directories(LI_detector PUBLIC ${PROJECT_SOURCE_DIR}/projects/dataclasses/public/) -target_include_directories(LI_detector PUBLIC ${PROJECT_SOURCE_DIR}/projects/geometry/public/) - -install(TARGETS LI_detector - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +target_link_libraries(LI_detector + PRIVATE + $ + PUBLIC + photospline + LI_serialization + LI_utilities + LI_math + LI_dataclasses + LI_geometry +) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/detector/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} diff --git a/projects/detector/private/AtomicMasses.cxx b/projects/detector/private/AtomicMasses.cxx index 22bef808..0ad5bb2c 100644 --- a/projects/detector/private/AtomicMasses.cxx +++ b/projects/detector/private/AtomicMasses.cxx @@ -1,12 +1,7 @@ -#include -#include -#include -#include -#include -#include -#include +#include // for map +#include // for tuple -#include "LeptonInjector/detector/MaterialModel.h" +#include "LeptonInjector/detector/MaterialModel.h" // for MaterialModel using namespace LI::detector; diff --git a/projects/detector/private/Axis1D.cxx b/projects/detector/private/Axis1D.cxx index 725d6508..850c3f88 100644 --- a/projects/detector/private/Axis1D.cxx +++ b/projects/detector/private/Axis1D.cxx @@ -1,6 +1,7 @@ -#include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/detector/Axis1D.h" +#include "LeptonInjector/math/Vector3D.h" + namespace LI { namespace detector { diff --git a/projects/detector/private/CartesianAxis1D.cxx b/projects/detector/private/CartesianAxis1D.cxx index ff634aea..6763a1b7 100644 --- a/projects/detector/private/CartesianAxis1D.cxx +++ b/projects/detector/private/CartesianAxis1D.cxx @@ -1,6 +1,7 @@ -#include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/detector/CartesianAxis1D.h" +#include "LeptonInjector/math/Vector3D.h" + namespace LI { namespace detector { diff --git a/projects/detector/private/DensityDistribution.cxx b/projects/detector/private/DensityDistribution.cxx index 6ae023d3..f25cb26c 100644 --- a/projects/detector/private/DensityDistribution.cxx +++ b/projects/detector/private/DensityDistribution.cxx @@ -1,5 +1,3 @@ -#include -#include #include "LeptonInjector/detector/DensityDistribution.h" namespace LI { diff --git a/projects/detector/private/Distribution1D.cxx b/projects/detector/private/Distribution1D.cxx index 11472ae4..35e07422 100644 --- a/projects/detector/private/Distribution1D.cxx +++ b/projects/detector/private/Distribution1D.cxx @@ -1,4 +1,3 @@ -#include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/detector/Distribution1D.h" namespace LI { diff --git a/projects/detector/private/EarthModel.cxx b/projects/detector/private/EarthModel.cxx index d26f064c..3e1b6899 100644 --- a/projects/detector/private/EarthModel.cxx +++ b/projects/detector/private/EarthModel.cxx @@ -1,24 +1,38 @@ +#include "LeptonInjector/detector/EarthModel.h" + #include -#include +#include +#include +#include #include -#include +#include +#include #include -#include +#include +#include #include #include +#include +#include #include +#include + +#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/math/EulerQuaternionConversions.h" + +#include "LeptonInjector/detector/MaterialModel.h" +#include "LeptonInjector/detector/RadialAxis1D.h" +#include "LeptonInjector/detector/DensityDistribution.h" #include "LeptonInjector/detector/ConstantDensityDistribution.h" #include "LeptonInjector/detector/RadialAxisPolynomialDensityDistribution.h" -#include "LeptonInjector/detector/EarthModel.h" #include "LeptonInjector/geometry/Box.h" #include "LeptonInjector/geometry/Sphere.h" #include "LeptonInjector/geometry/Cylinder.h" #include "LeptonInjector/geometry/ExtrPoly.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/math/EulerQuaternionConversions.h" +#include "LeptonInjector/geometry/Placement.h" #include "LeptonInjector/utilities/Constants.h" @@ -94,6 +108,24 @@ bool EarthSector::operator==(EarthSector const & o) const { return name == o.name and material_id == o.material_id and level == o.level and geo == o.geo and density == o.density; } +std::ostream & EarthSector::Print(std::ostream& oss) const { + oss << "[EarthSector:\n" + << " Name : " << name << '\n' + << " MaterialID : " << material_id << '\n' + << " Level : " << level << '\n' + << " Geo : " << geo << '\n' + << " Density : " << density << "\n]"; + return oss; +} + +std::ostream& operator<<(std::ostream& oss, EarthSector const & bcm) { + return(bcm.Print(oss)); +} + +std::ostream& operator<<(std::ostream& oss, EarthSector & bcm) { + return(bcm.Print(oss)); +} + EarthModel::EarthModel() { LoadDefaultMaterials(); LoadDefaultSectors(); @@ -252,7 +284,7 @@ void EarthModel::LoadEarthModel(std::string const & earth_model) { // density data std::stringstream ss(buf); - ss >> type; + ss >> type; if(type.find("object") != std::string::npos) { EarthSector sector; @@ -293,18 +325,18 @@ void EarthModel::LoadEarthModel(std::string const & earth_model) { std::vector zsecs; ss >> nverts; for (int i = 0; i < nverts; ++i){ - ss >> v1 >> v2; - polyVert.push_back(v1); - polyVert.push_back(v2); - poly.push_back(polyVert); - polyVert.clear(); + ss >> v1 >> v2; + polyVert.push_back(v1); + polyVert.push_back(v2); + poly.push_back(polyVert); + polyVert.clear(); } ss >> nzsec; for (int i = 0; i < nzsec; ++i){ - ss >> zpos >> off1 >> off2 >> scale; - offset[0] = off1; - offset[1] = off2; - zsecs.push_back(ExtrPoly::ZSection(zpos,offset,scale)); + ss >> zpos >> off1 >> off2 >> scale; + offset[0] = off1; + offset[1] = off2; + zsecs.push_back(ExtrPoly::ZSection(zpos,offset,scale)); } sector.geo = ExtrPoly(placement, poly, zsecs).create(); } @@ -823,10 +855,10 @@ double EarthModel::GetInteractionDepthInCGS(Geometry::IntersectionList const & i } else { dot = 1; } - + // If we have only decays, avoid the sector loop if(targets.empty()) { - return distance/total_decay_length; // m / m --> dimensionless + return distance/total_decay_length; // m / m --> dimensionless } std::vector interaction_depths(targets.size(), 0.0); @@ -858,7 +890,7 @@ double EarthModel::GetInteractionDepthInCGS(Geometry::IntersectionList const & i } double interaction_depth = accumulate(interaction_depths.begin(), interaction_depths.end()); - + interaction_depth += distance/total_decay_length; return interaction_depth; @@ -996,8 +1028,8 @@ void EarthModel::SortIntersections(Geometry::IntersectionList & intersections) { void EarthModel::SortIntersections(std::vector & intersections) { // Intersections should be sorted according to distance and then hierarchy std::function comp = [](Geometry::Intersection const & a, Geometry::Intersection const & b){ - bool a_enter = a.entering; - bool b_enter = b.entering; + bool a_enter = a.entering; + bool b_enter = b.entering; if(a.distance < b.distance) return true; else if(a.distance == b.distance) { @@ -1027,15 +1059,15 @@ Geometry::IntersectionList EarthModel::GetOuterBounds(Geometry::IntersectionList result.position = intersections.position; result.direction = intersections.direction; int min_hierarchy = std::numeric_limits::min(); - unsigned int min_index = 0; - for(unsigned int i=0; i min_hierarchy) { result.intersections.push_back(intersections.intersections[i]); min_index = i; break; } } - for(unsigned int i=intersections.intersections.size()-1; (i >= 0 and i > min_index); --i) { + for(ptrdiff_t i=ptrdiff_t(intersections.intersections.size())-1; (i >= 0 and i > min_index); --i) { if(intersections.intersections[i].hierarchy > min_hierarchy) { result.intersections.push_back(intersections.intersections[i]); break; @@ -1209,7 +1241,7 @@ double EarthModel::DistanceForInteractionDepthFromPoint(Geometry::IntersectionLi } done = distance >= 0; double integral = sector.density->Integral(p0+start_point*direction, direction, segment_length); // g cm^-3 * m - integral *= (target_composition*LI::utilities::Constants::m/LI::utilities::Constants::cm); // --> m cm^-1 --> dimensionless + integral *= (target_composition*LI::utilities::Constants::m/LI::utilities::Constants::cm); // --> m cm^-1 --> dimensionless total_interaction_depth += integral; if(done) { total_distance = start_point + distance; diff --git a/projects/detector/private/ExponentialDistribution1D.cxx b/projects/detector/private/ExponentialDistribution1D.cxx index 4b029a70..e656beb9 100644 --- a/projects/detector/private/ExponentialDistribution1D.cxx +++ b/projects/detector/private/ExponentialDistribution1D.cxx @@ -1,8 +1,7 @@ -#include -#include - #include "LeptonInjector/detector/ExponentialDistribution1D.h" +#include // for exp + namespace LI { namespace detector { diff --git a/projects/detector/private/MaterialModel.cxx b/projects/detector/private/MaterialModel.cxx index 84d54d8f..2f3a7d4c 100644 --- a/projects/detector/private/MaterialModel.cxx +++ b/projects/detector/private/MaterialModel.cxx @@ -1,15 +1,16 @@ -#include -#include -#include -#include -#include -#include -#include +#include "LeptonInjector/detector/MaterialModel.h" -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/utilities/Constants.h" +#include // for map, operator!= +#include // for pow, exp, log, sqrt +#include // for basic_string, opera... +#include // for vector, operator== +#include // for basic_istream, getline +#include +#include // for sprintf, sscanf +#include // for abs -#include "LeptonInjector/detector/MaterialModel.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/utilities/Constants.h" // for avogadro, GeV_per_amu using namespace LI::detector ; diff --git a/projects/detector/private/Path.cxx b/projects/detector/private/Path.cxx index 2b11f3a6..b6e3af72 100644 --- a/projects/detector/private/Path.cxx +++ b/projects/detector/private/Path.cxx @@ -1,14 +1,15 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "LeptonInjector/dataclasses/Particle.h" #include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/geometry/Geometry.h" + +#include // for copysign, abs +#include // for vector +#include // for swap +#include // for assert +#include // for abs +#include // for max + +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/detector/EarthModel.h" // for EarthModel +#include "LeptonInjector/geometry/Geometry.h" // for Geometry namespace LI { namespace detector { diff --git a/projects/detector/private/PolynomialDistribution1D.cxx b/projects/detector/private/PolynomialDistribution1D.cxx index e721e8d8..00f729c6 100644 --- a/projects/detector/private/PolynomialDistribution1D.cxx +++ b/projects/detector/private/PolynomialDistribution1D.cxx @@ -1,7 +1,8 @@ +#include "LeptonInjector/detector/PolynomialDistribution1D.h" + #include #include "LeptonInjector/math/Polynomial.h" -#include "LeptonInjector/detector/PolynomialDistribution1D.h" namespace LI { namespace detector { diff --git a/projects/detector/private/RadialAxis1D.cxx b/projects/detector/private/RadialAxis1D.cxx index 8667c69a..4515fbc4 100644 --- a/projects/detector/private/RadialAxis1D.cxx +++ b/projects/detector/private/RadialAxis1D.cxx @@ -1,6 +1,7 @@ -#include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/detector/RadialAxis1D.h" +#include "LeptonInjector/math/Vector3D.h" + namespace LI { namespace detector { diff --git a/projects/detector/private/pybindings/Axis1D.h b/projects/detector/private/pybindings/Axis1D.h new file mode 100644 index 00000000..16053d48 --- /dev/null +++ b/projects/detector/private/pybindings/Axis1D.h @@ -0,0 +1,81 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Axis1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +using namespace pybind11; +using namespace LI::detector; +class PyAxis1D : public LI::detector::Axis1D { +public: + using Axis1D::Axis1D; + + bool compare(const Axis1D& density_distr) const override { + PYBIND11_OVERRIDE_PURE_NAME( + bool, + Axis1D, + "_compare", + compare, + density_distr + ); + } + + Axis1D * clone() const override { + PYBIND11_OVERRIDE_PURE_NAME( + Axis1D *, + Axis1D, + "_clone", + clone + ); + } + std::shared_ptr create() const override { + PYBIND11_OVERRIDE_PURE_NAME( + std::shared_ptr, + Axis1D, + "_create", + create + ); + } + + double GetX(const LI::math::Vector3D& xi) const override { + PYBIND11_OVERRIDE_PURE( + double, + Axis1D, + GetX, + xi + ); + } + + double GetdX(const LI::math::Vector3D& xi, const LI::math::Vector3D& direction) const override { + PYBIND11_OVERRIDE_PURE( + double, + Axis1D, + GetdX, + xi, + direction + ); + } +}; + +void register_Axis1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_, PyAxis1D>(m, "Axis1D") + .def(init<>()) + .def("__eq__", [](const Axis1D &self, const Axis1D &other){ return self == other; }) + .def("__ne__", [](const Axis1D &self, const Axis1D &other){ return self != other; }) + .def("_clone", &Axis1D::clone) + .def("_create", &Axis1D::create) + .def("GetX", &Axis1D::GetX) + .def("GetdX", &Axis1D::GetdX) + .def("GetAxis", &Axis1D::GetAxis) + .def("GetFp0", &Axis1D::GetFp0) + ; +} diff --git a/projects/detector/private/pybindings/CartesianAxis1D.h b/projects/detector/private/pybindings/CartesianAxis1D.h new file mode 100644 index 00000000..faa7b1aa --- /dev/null +++ b/projects/detector/private/pybindings/CartesianAxis1D.h @@ -0,0 +1,29 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/CartesianAxis1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +using namespace pybind11; +using namespace LI::detector; + +void register_CartesianAxis1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "CartesianAxis1D") + .def(init<>()) + .def(init()) + .def("_compare", &CartesianAxis1D::compare) + .def("_clone", &CartesianAxis1D::clone) + .def("_create", &CartesianAxis1D::create) + .def("GetX", &CartesianAxis1D::GetX) + .def("GetdX", &CartesianAxis1D::GetdX) + ; +} diff --git a/projects/detector/private/pybindings/CartesianAxisExponentialDensityDistribution.h b/projects/detector/private/pybindings/CartesianAxisExponentialDensityDistribution.h new file mode 100644 index 00000000..32de67a1 --- /dev/null +++ b/projects/detector/private/pybindings/CartesianAxisExponentialDensityDistribution.h @@ -0,0 +1,61 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/CartesianAxisExponentialDensityDistribution.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_CartesianAxisExponentialDensityDistribution(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + typedef CartesianAxis1D AxisT; + typedef ExponentialDistribution1D DistributionT; + typedef DensityDistribution1D DDist1DT; + + + std::string name = "CartesianAxisExponentialDensityDistribution"; + + class_, DensityDistribution>(m, name.c_str()) + .def(init<>()) + .def(init()) + .def(init()) + .def("_compare", &DDist1DT::compare) + .def("_clone", &DDist1DT::clone) + .def("_create", &DDist1DT::create) + .def("Derivative", &DDist1DT::Derivative) + .def("AntiDerivative", &DDist1DT::AntiDerivative) + .def("Integral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const)(&DDist1DT::Integral) + ) + .def("Integral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &) const)(&DDist1DT::Integral) + ) + .def("InverseIntegral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double) const)(&DDist1DT::InverseIntegral) + ) + .def("InverseIntegral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double, + double) const)(&DDist1DT::InverseIntegral) + ) + .def("Evaluate", &DDist1DT::Evaluate) + ; +} diff --git a/projects/detector/private/pybindings/CartesianAxisPolynomialDensityDistribution.h b/projects/detector/private/pybindings/CartesianAxisPolynomialDensityDistribution.h new file mode 100644 index 00000000..4cf0cd93 --- /dev/null +++ b/projects/detector/private/pybindings/CartesianAxisPolynomialDensityDistribution.h @@ -0,0 +1,62 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/CartesianAxisPolynomialDensityDistribution.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_CartesianAxisPolynomialDensityDistribution(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + typedef CartesianAxis1D AxisT; + typedef PolynomialDistribution1D DistributionT; + typedef DensityDistribution1D DDist1DT; + + + std::string name = "CartesianAxisPolynomialDensityDistribution"; + + class_, DensityDistribution>(m, name.c_str()) + .def(init<>()) + .def(init()) + .def(init()) + .def("_compare", &DDist1DT::compare) + .def("_clone", &DDist1DT::clone) + .def("_create", &DDist1DT::create) + .def("Derivative", &DDist1DT::Derivative) + .def("AntiDerivative", &DDist1DT::AntiDerivative) + .def("Integral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const)(&DDist1DT::Integral) + ) + .def("Integral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &) const)(&DDist1DT::Integral) + ) + .def("InverseIntegral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double) const)(&DDist1DT::InverseIntegral) + ) + .def("InverseIntegral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double, + double) const)(&DDist1DT::InverseIntegral) + ) + .def("Evaluate", &DDist1DT::Evaluate) + ; +} + diff --git a/projects/detector/private/pybindings/ConstantDensityDistribution.h b/projects/detector/private/pybindings/ConstantDensityDistribution.h new file mode 100644 index 00000000..479f3190 --- /dev/null +++ b/projects/detector/private/pybindings/ConstantDensityDistribution.h @@ -0,0 +1,64 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/ConstantDensityDistribution.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_ConstantDensityDistribution(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + typedef CartesianAxis1D AxisT; + typedef ConstantDistribution1D DistributionT; + typedef DensityDistribution1D DDist1DT; + + std::string name = "ConstantDensityDistribution"; + + class_, DensityDistribution>(m, name.c_str()) + .def(init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def("_compare", &DDist1DT::compare) + .def("_clone", &DDist1DT::clone) + .def("_create", &DDist1DT::create) + .def("Derivative", &DDist1DT::Derivative) + .def("AntiDerivative", &DDist1DT::AntiDerivative) + .def("Integral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const)(&DDist1DT::Integral) + ) + .def("Integral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &) const)(&DDist1DT::Integral) + ) + .def("InverseIntegral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double) const)(&DDist1DT::InverseIntegral) + ) + .def("InverseIntegral", ( + double (DDist1DT::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double, + double) const)(&DDist1DT::InverseIntegral) + ) + .def("Evaluate", &DDist1DT::Evaluate) + ; +} + + diff --git a/projects/detector/private/pybindings/ConstantDistribution1D.h b/projects/detector/private/pybindings/ConstantDistribution1D.h new file mode 100644 index 00000000..ab7a0e63 --- /dev/null +++ b/projects/detector/private/pybindings/ConstantDistribution1D.h @@ -0,0 +1,30 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Distribution1D.h" +#include "../../public/LeptonInjector/detector/ConstantDistribution1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_ConstantDistribution1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "ConstantDistribution1D") + .def(init<>()) + .def(self == self) + .def(self != self) + .def("_compare", &ConstantDistribution1D::compare) + .def("_clone", &ConstantDistribution1D::clone) + .def("_create", &ConstantDistribution1D::create) + .def("Derivative", &ConstantDistribution1D::Derivative) + .def("AntiDerivative", &ConstantDistribution1D::AntiDerivative) + .def("Evaluate", &ConstantDistribution1D::Evaluate) + ; +} + diff --git a/projects/detector/private/pybindings/DensityDistribution.h b/projects/detector/private/pybindings/DensityDistribution.h new file mode 100644 index 00000000..35b31b58 --- /dev/null +++ b/projects/detector/private/pybindings/DensityDistribution.h @@ -0,0 +1,169 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/DensityDistribution.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +using namespace pybind11; +using namespace LI::detector; +class PyDensityDistribution : public LI::detector::DensityDistribution { +public: + using DensityDistribution::DensityDistribution; + + bool compare(const DensityDistribution& density_distr) const override { + PYBIND11_OVERRIDE_PURE_NAME( + bool, + DensityDistribution, + "_compare", + compare, + density_distr + ); + } + + DensityDistribution * clone() const override { + PYBIND11_OVERRIDE_PURE_NAME( + DensityDistribution *, + DensityDistribution, + "_clone", + clone + ); + } + std::shared_ptr create() const override { + PYBIND11_OVERRIDE_PURE_NAME( + std::shared_ptr, + DensityDistribution, + "_create", + create + ); + } + + double Derivative(LI::math::Vector3D const & xi, + LI::math::Vector3D const & direction) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + Derivative, + xi, + direction + ); + } + double AntiDerivative(LI::math::Vector3D const & xi, + LI::math::Vector3D const & direction) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + AntiDerivative, + xi, + direction + ); + } + double Integral(LI::math::Vector3D const & xi, + LI::math::Vector3D const & direction, + double distance) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + Integral, + xi, + direction, + distance + ); + } + double Integral(LI::math::Vector3D const & xi, + LI::math::Vector3D const & xj) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + Integral, + xi, + xj + ); + } + double InverseIntegral(LI::math::Vector3D const & xi, + LI::math::Vector3D const & direction, + double integral, + double max_distance) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + InverseIntegral, + xi, + direction, + integral, + max_distance + ); + } + double InverseIntegral(LI::math::Vector3D const & xi, + LI::math::Vector3D const & direction, + double constant, + double integral, + double max_distance) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + InverseIntegral, + xi, + direction, + constant, + integral, + max_distance + ); + } + double Evaluate(const LI::math::Vector3D& xi) const override { + PYBIND11_OVERRIDE_PURE( + double, + DensityDistribution, + Evaluate, + xi + ); + } +}; + +void register_DensityDistribution(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_, PyDensityDistribution>(m, "DensityDistribution") + .def(init<>()) + .def("__eq__", [](const DensityDistribution &self, const DensityDistribution &other){ return self == other; }) + .def("__ne__", [](const DensityDistribution &self, const DensityDistribution &other){ return self != other; }) + .def("_compare", &DensityDistribution::compare) + .def("_clone", &DensityDistribution::clone) + .def("_create", &DensityDistribution::create) + .def("Derivative", &DensityDistribution::Derivative) + .def("AntiDerivative", &DensityDistribution::AntiDerivative) + .def("Integral", ( + double (DensityDistribution::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const)(&DensityDistribution::Integral) + ) + .def("Integral", ( + double (DensityDistribution::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &) const)(&DensityDistribution::Integral) + ) + .def("InverseIntegral", ( + double (DensityDistribution::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double) const)(&DensityDistribution::InverseIntegral) + ) + .def("InverseIntegral", ( + double (DensityDistribution::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + double, + double) const)(&DensityDistribution::InverseIntegral) + ) + .def("Evaluate", &DensityDistribution::Evaluate) + ; +} diff --git a/projects/detector/private/pybindings/Distribution1D.h b/projects/detector/private/pybindings/Distribution1D.h new file mode 100644 index 00000000..dfff9703 --- /dev/null +++ b/projects/detector/private/pybindings/Distribution1D.h @@ -0,0 +1,87 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Distribution1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +using namespace pybind11; +using namespace LI::detector; +class PyDistribution1D : public LI::detector::Distribution1D { +public: + using Distribution1D::Distribution1D; + + bool compare(const Distribution1D& density_distr) const override { + PYBIND11_OVERRIDE_PURE_NAME( + bool, + Distribution1D, + "_compare", + compare, + density_distr + ); + } + + Distribution1D * clone() const override { + PYBIND11_OVERRIDE_PURE_NAME( + Distribution1D *, + Distribution1D, + "_clone", + clone + ); + } + std::shared_ptr create() const override { + PYBIND11_OVERRIDE_PURE_NAME( + std::shared_ptr, + Distribution1D, + "_create", + create + ); + } + + double Derivative(double x) const override { + PYBIND11_OVERRIDE_PURE( + double, + Distribution1D, + Derivative, + x + ); + } + double AntiDerivative(double x) const override { + PYBIND11_OVERRIDE_PURE( + double, + Distribution1D, + AntiDerivative, + x + ); + } + double Evaluate(double x) const override { + PYBIND11_OVERRIDE_PURE( + double, + Distribution1D, + Evaluate, + x + ); + } +}; + +void register_Distribution1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_, PyDistribution1D>(m, "Distribution1D") + .def(init<>()) + .def("__eq__", [](const Distribution1D &self, const Distribution1D &other){ return self == other; }) + .def("__ne__", [](const Distribution1D &self, const Distribution1D &other){ return self != other; }) + .def("_compare", &Distribution1D::compare) + .def("_clone", &Distribution1D::clone) + .def("_create", &Distribution1D::create) + .def("Derivative", &Distribution1D::Derivative) + .def("AntiDerivative", &Distribution1D::AntiDerivative) + .def("Evaluate", &Distribution1D::Evaluate) + ; +} diff --git a/projects/detector/private/pybindings/EarthModel.h b/projects/detector/private/pybindings/EarthModel.h new file mode 100644 index 00000000..c133b069 --- /dev/null +++ b/projects/detector/private/pybindings/EarthModel.h @@ -0,0 +1,232 @@ +#include +#include +#include + +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_EarthModel(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "EarthModel") + .def(init<>()) + .def(init()) + .def(init()) + .def("LoadEarthModel",&EarthModel::LoadEarthModel) + .def("LoadMaterialModel",&EarthModel::LoadMaterialModel) + .def("GetMassDensity", ( + double (EarthModel::*)(LI::geometry::Geometry::IntersectionList const &, LI::math::Vector3D const &) const + )(&EarthModel::GetMassDensity)) + .def("GetMassDensity", ( + double (EarthModel::*)(LI::math::Vector3D const &) const + )(&EarthModel::GetMassDensity)) + .def("GetParticleDensity", ( + double (EarthModel::*)(LI::geometry::Geometry::IntersectionList const &, LI::math::Vector3D const &, LI::dataclasses::Particle::ParticleType) const + )(&EarthModel::GetParticleDensity)) + .def("GetParticleDensity", ( + double (EarthModel::*)(LI::math::Vector3D const &, LI::dataclasses::Particle::ParticleType) const + )(&EarthModel::GetParticleDensity)) + .def("GetInteractionDensity", ( + double (EarthModel::*)(LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::GetInteractionDensity)) + .def("GetInteractionDensity", ( + double (EarthModel::*)(LI::math::Vector3D const &, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::GetInteractionDensity)) + .def("GetColumnDepthInCGS", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &) const + )(&EarthModel::GetColumnDepthInCGS)) + .def("GetColumnDepthInCGS", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &) const + )(&EarthModel::GetColumnDepthInCGS)) + .def("DistanceForColumnDepthFromPoint", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const + )(&EarthModel::DistanceForColumnDepthFromPoint)) + .def("DistanceForColumnDepthFromPoint", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const + )(&EarthModel::DistanceForColumnDepthFromPoint)) + .def("DistanceForColumnDepthToPoint", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const + )(&EarthModel::DistanceForColumnDepthToPoint)) + .def("DistanceForColumnDepthToPoint", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double) const + )(&EarthModel::DistanceForColumnDepthToPoint)) + .def("GetMassDensity", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + std::set) const + )(&EarthModel::GetMassDensity)) + .def("GetMassDensity", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + std::set) const + )(&EarthModel::GetMassDensity)) + .def("GetParticleDensity", ( + std::vector (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + std::set) const + )(&EarthModel::GetParticleDensity)) + .def("GetParticleDensity", ( + std::vector (EarthModel::*)( + LI::math::Vector3D const &, + std::set) const + )(&EarthModel::GetParticleDensity)) + .def("GetInteractionDepthInCGS", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::GetInteractionDepthInCGS)) + .def("GetInteractionDepthInCGS", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::GetInteractionDepthInCGS)) + .def("DistanceForInteractionDepthFromPoint", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::DistanceForInteractionDepthFromPoint)) + .def("DistanceForInteractionDepthFromPoint", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::DistanceForInteractionDepthFromPoint)) + .def("DistanceForInteractionDepthToPoint", ( + double (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::DistanceForInteractionDepthToPoint)) + .def("DistanceForInteractionDepthToPoint", ( + double (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &, + double, + std::vector const &, + std::vector const &, + double const &) const + )(&EarthModel::DistanceForInteractionDepthToPoint)) + .def("GetParticleColumnDepth", ( + std::vector (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const &, + LI::math::Vector3D const &, + std::vector const &) const + )(&EarthModel::GetParticleColumnDepth)) + .def("GetContainingSector", ( + EarthSector (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + LI::math::Vector3D const & p0) const + )(&EarthModel::GetContainingSector)) + .def("GetContainingSector", ( + EarthSector (EarthModel::*)( + LI::math::Vector3D const & p0) const + )(&EarthModel::GetContainingSector)) + .def("GetEarthCoordPosFromDetCoordPos", ( + LI::math::Vector3D (EarthModel::*)( + LI::math::Vector3D const &) const + )(&EarthModel::GetEarthCoordPosFromDetCoordPos)) + .def("GetEarthCoordDirFromDetCoordDir", ( + LI::math::Vector3D (EarthModel::*)( + LI::math::Vector3D const &) const + )(&EarthModel::GetEarthCoordDirFromDetCoordDir)) + .def("GetDetCoordPosFromEarthCoordPos", ( + LI::math::Vector3D (EarthModel::*)( + LI::math::Vector3D const &) const + )(&EarthModel::GetDetCoordPosFromEarthCoordPos)) + .def("GetDetCoordDirFromEarthCoordDir", ( + LI::math::Vector3D (EarthModel::*)( + LI::math::Vector3D const &) const + )(&EarthModel::GetDetCoordDirFromEarthCoordDir)) + .def_property("Path", &EarthModel::GetPath, &EarthModel::SetPath) + .def_property("Materials", &EarthModel::GetMaterials, &EarthModel::SetMaterials) + .def_property("Sectors", &EarthModel::GetSectors, &EarthModel::SetSectors) + .def_property("DetectorOrigin", &EarthModel::GetDetectorOrigin, &EarthModel::SetDetectorOrigin) + .def("AddSector", &EarthModel::AddSector) + .def("GetSector", &EarthModel::GetSector) + .def("ClearSectors", &EarthModel::ClearSectors) + .def("GetIntersections", &EarthModel::GetIntersections) + .def_static("SortIntersections", ( + void (*)(LI::geometry::Geometry::IntersectionList &) + )(&EarthModel::SortIntersections)) + .def_static("SortIntersections", ( + void (*)(std::vector &) + )(&EarthModel::SortIntersections)) + .def_static("SectorLoop", &EarthModel::SectorLoop) + .def_static("GetOuterBoundsFromIntersections", ( + LI::geometry::Geometry::IntersectionList (*)( + LI::geometry::Geometry::IntersectionList const &) + )(&EarthModel::GetOuterBounds)) + .def("GetOuterBounds", [](LI::detector::EarthModel const & earth, LI::geometry::Geometry::IntersectionList const & intersections){ + return earth.GetOuterBounds(intersections); + }) + .def("GetOuterBounds", ( + LI::geometry::Geometry::IntersectionList (EarthModel::*)( + LI::math::Vector3D const &, + LI::math::Vector3D const &) const + )(&EarthModel::GetOuterBounds)) + .def("GetAvailableTargets", ( + std::set (EarthModel::*)( + LI::geometry::Geometry::IntersectionList const &, + std::array const &) const + )(&EarthModel::GetAvailableTargets)) + .def("GetAvailableTargets", ( + std::set (EarthModel::*)( + std::array const &) const + )(&EarthModel::GetAvailableTargets)) + .def("GetTargetMass", &EarthModel::GetTargetMass) + .def("GetMaterials",&EarthModel::GetMaterials) + .def("GetDetectorOrigin",&EarthModel::GetDetectorOrigin); + +} diff --git a/projects/detector/private/pybindings/EarthSector.h b/projects/detector/private/pybindings/EarthSector.h new file mode 100644 index 00000000..955aee19 --- /dev/null +++ b/projects/detector/private/pybindings/EarthSector.h @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" + +std::string to_str(LI::detector::EarthSector const & sector) { + std::stringstream ss; + sector.Print(ss); + return ss.str(); +} + +void register_EarthSector(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "EarthSector") + .def(init<>()) + .def("__str__", &to_str) + .def_readwrite("name",&EarthSector::name) + .def_readwrite("material_id",&EarthSector::material_id) + .def_readwrite("level", &EarthSector::level) + .def_readwrite("geo",&EarthSector::geo) + .def_readwrite("density",&EarthSector::density); +} diff --git a/projects/detector/private/pybindings/ExponentialDistribution1D.h b/projects/detector/private/pybindings/ExponentialDistribution1D.h new file mode 100644 index 00000000..1188c910 --- /dev/null +++ b/projects/detector/private/pybindings/ExponentialDistribution1D.h @@ -0,0 +1,30 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Distribution1D.h" +#include "../../public/LeptonInjector/detector/ExponentialDistribution1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_ExponentialDistribution1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "ExponentialDistribution1D") + .def(init<>()) + .def(init()) + .def(init()) + .def("_compare", &ExponentialDistribution1D::compare) + .def("_clone", &ExponentialDistribution1D::clone) + .def("_create", &ExponentialDistribution1D::create) + .def("Derivative", &ExponentialDistribution1D::Derivative) + .def("AntiDerivative", &ExponentialDistribution1D::AntiDerivative) + .def("Evaluate", &ExponentialDistribution1D::Evaluate) + ; +} + diff --git a/projects/detector/private/pybindings/MaterialModel.h b/projects/detector/private/pybindings/MaterialModel.h new file mode 100644 index 00000000..23ec7e67 --- /dev/null +++ b/projects/detector/private/pybindings/MaterialModel.h @@ -0,0 +1,65 @@ +#include +#include +#include + +#include +#include + +#include "../../public/LeptonInjector/detector/MaterialModel.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_MaterialModel(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_> material_model(m, "MaterialModel"); + material_model + .def(init<>()) + .def(init()) + .def(init()) + .def(init>()) + .def(init>()) + .def(self == self) + .def("SetPath", &MaterialModel::SetPath) + .def("AddMaterial", &MaterialModel::AddMaterial) + .def("AddModelFiles", &MaterialModel::AddModelFiles) + .def("AddModelFile", &MaterialModel::AddModelFile) + .def("GetMaterialTargets", &MaterialModel::GetMaterialTargets) + .def("GetMaterialRadiationLength", &MaterialModel::GetMaterialRadiationLength) + .def("GetMaterialName", &MaterialModel::GetMaterialName) + .def("GetMaterialId", &MaterialModel::GetMaterialId) + .def("HasMaterial", (bool (MaterialModel::*)(std::string const &) const)(&MaterialModel::HasMaterial)) + .def("HasMaterial", (bool (MaterialModel::*)(int) const)(&MaterialModel::HasMaterial)) + .def("GetTargetMassFraction", (double (MaterialModel::*)(int, LI::dataclasses::Particle::ParticleType) const)(&MaterialModel::GetTargetMassFraction)) + .def("GetTargetMassFraction", (std::vector (MaterialModel::*)(int, std::vector const &) const)(&MaterialModel::GetTargetMassFraction)) + .def("GetTargetParticleFraction", (double (MaterialModel::*)(int, LI::dataclasses::Particle::ParticleType) const)(&MaterialModel::GetTargetParticleFraction)) + .def("GetTargetParticleFraction", (std::vector (MaterialModel::*)(int, std::vector const &) const)(&MaterialModel::GetTargetParticleFraction)) + .def("GetTargetRadiationFraction", (std::vector (MaterialModel::*)(int, std::vector const &) const)(&MaterialModel::GetTargetRadiationFraction)) + .def("GetMaterialConstituents", &MaterialModel::GetMaterialConstituents) + .def_static("GetNucleonContent", &MaterialModel::GetNucleonContent) + .def_static("GetMolarMass", &MaterialModel::GetMolarMass) + .def_static("GetStrangeCount", &MaterialModel::GetStrangeCount) + .def_static("GetNucleonCount", &MaterialModel::GetNucleonCount) + .def_static("GetNeutronCount", &MaterialModel::GetNeutronCount) + .def_static("GetProtonCount", &MaterialModel::GetProtonCount) + .def_static("GetEmpericalNuclearBindingEnergy", &MaterialModel::GetEmpericalNuclearBindingEnergy) + ; + + class_(material_model, "Component") + .def(init<>()) + .def(init()) + .def(self == self) + .def_readwrite("type", &MaterialModel::Component::type) + .def_readwrite("strange_count", &MaterialModel::Component::strange_count) + .def_readwrite("neutron_count", &MaterialModel::Component::neutron_count) + .def_readwrite("nucleon_count", &MaterialModel::Component::nucleon_count) + .def_readwrite("proton_count", &MaterialModel::Component::proton_count) + .def_readwrite("molar_mass", &MaterialModel::Component::molar_mass) + .def_readwrite("is_atom", &MaterialModel::Component::is_atom); + + class_(material_model, "MaterialComponent") + .def(init<>()) + .def_readwrite("component", &MaterialModel::MaterialComponent::component) + .def_readwrite("mass_density_over_total_mass_density", &MaterialModel::MaterialComponent::mass_density_over_total_mass_density) + .def_readwrite("particle_density_over_total_mass_density", &MaterialModel::MaterialComponent::particle_density_over_total_mass_density); +} diff --git a/projects/detector/private/pybindings/Path.h b/projects/detector/private/pybindings/Path.h new file mode 100644 index 00000000..4066f73b --- /dev/null +++ b/projects/detector/private/pybindings/Path.h @@ -0,0 +1,64 @@ +#include +#include + +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Path.h" + +void register_Path(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "Path") + .def(init>()) + .def(init, LI::math::Vector3D const &, LI::math::Vector3D const &>()) + .def(init, LI::math::Vector3D const &, LI::math::Vector3D const &, double>()) + + .def("HasEarthModel",&Path::HasEarthModel) + .def("HasPoints",&Path::HasPoints) + .def("HasIntersections",&Path::HasIntersections) + .def("HasColumnDepth",&Path::HasColumnDepth) + .def("GetEarthModel",&Path::GetEarthModel) + .def("HasEarthModel",&Path::HasEarthModel) + .def("GetFirstPoint",&Path::GetFirstPoint) + .def("GetLastPoint",&Path::GetLastPoint) + .def("GetDirection",&Path::GetDirection) + .def("GetDistance",&Path::GetDistance) + + .def("ClipToOuterBounds",&Path::ClipToOuterBounds) + + .def("ExtendFromEndByDistance",&Path::ExtendFromEndByDistance) + .def("ExtendFromStartByDistance",&Path::ExtendFromStartByDistance) + .def("ShrinkFromEndByDistance",&Path::ShrinkFromEndByDistance) + .def("ShrinkFromStartByDistance",&Path::ShrinkFromStartByDistance) + .def("ExtendFromEndByColumnDepth",&Path::ExtendFromEndByColumnDepth) + .def("ExtendFromStartByColumnDepth",&Path::ExtendFromStartByColumnDepth) + .def("ShrinkFromEndByColumnDepth",&Path::ShrinkFromEndByColumnDepth) + .def("ShrinkFromStartByColumnDepth",&Path::ShrinkFromStartByColumnDepth) + .def("ExtendFromEndByInteractionDepth",&Path::ExtendFromEndByInteractionDepth) + .def("ExtendFromStartByInteractionDepth",&Path::ExtendFromStartByInteractionDepth) + .def("ShrinkFromEndByInteractionDepth",&Path::ShrinkFromEndByInteractionDepth) + .def("ShrinkFromStartByInteractionDepth",&Path::ShrinkFromStartByInteractionDepth) + .def("ExtendFromEndToDistance",&Path::ExtendFromEndToDistance) + .def("ExtendFromStartToDistance",&Path::ExtendFromStartToDistance) + .def("ShrinkFromEndToDistance",&Path::ShrinkFromEndToDistance) + .def("ShrinkFromStartToDistance",&Path::ShrinkFromStartToDistance) + .def("ExtendFromEndToColumnDepth",&Path::ExtendFromEndToColumnDepth) + .def("ExtendFromStartToColumnDepth",&Path::ExtendFromStartToColumnDepth) + .def("ShrinkFromEndToColumnDepth",&Path::ShrinkFromEndToColumnDepth) + .def("ShrinkFromStartToColumnDepth",&Path::ShrinkFromStartToColumnDepth) + .def("ExtendFromEndToInteractionDepth",&Path::ExtendFromEndToInteractionDepth) + .def("ExtendFromStartToInteractionDepth",&Path::ExtendFromStartToInteractionDepth) + .def("ShrinkFromEndToInteractionDepth",&Path::ShrinkFromEndToInteractionDepth) + .def("ShrinkFromStartToInteractionDepth",&Path::ShrinkFromStartToInteractionDepth) + .def("GetColumnDepthInBounds",&Path::GetColumnDepthInBounds) + .def("GetInteractionDepthInBounds",&Path::GetInteractionDepthInBounds) + + .def("GetDistanceFromStartAlongPath",overload_cast const &, std::vector< double > const &, double const &>(&Path::GetDistanceFromStartAlongPath)) + .def("GetDistanceFromStartAlongPath",overload_cast(&Path::GetDistanceFromStartAlongPath)) + + .def("GetDistanceFromStartInReverse",overload_cast const &, std::vector< double > const &, double const &>(&Path::GetDistanceFromStartInReverse)) + .def("GetDistanceFromStartInReverse",overload_cast(&Path::GetDistanceFromStartInReverse)); +} diff --git a/projects/detector/private/pybindings/PolynomialDistribution1D.h b/projects/detector/private/pybindings/PolynomialDistribution1D.h new file mode 100644 index 00000000..8b64383c --- /dev/null +++ b/projects/detector/private/pybindings/PolynomialDistribution1D.h @@ -0,0 +1,31 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Distribution1D.h" +#include "../../public/LeptonInjector/detector/PolynomialDistribution1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_PolynomialDistribution1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "PolynomialDistribution1D") + .def(init<>()) + .def(init()) + .def(init()) + .def(init>()) + .def("_compare", &PolynomialDistribution1D::compare) + .def("_clone", &PolynomialDistribution1D::clone) + .def("_create", &PolynomialDistribution1D::create) + .def("Derivative", &PolynomialDistribution1D::Derivative) + .def("AntiDerivative", &PolynomialDistribution1D::AntiDerivative) + .def("Evaluate", &PolynomialDistribution1D::Evaluate) + ; +} + diff --git a/projects/detector/private/pybindings/RadialAxis1D.h b/projects/detector/private/pybindings/RadialAxis1D.h new file mode 100644 index 00000000..2e43e5ba --- /dev/null +++ b/projects/detector/private/pybindings/RadialAxis1D.h @@ -0,0 +1,31 @@ +#include +#include +#include + +#include +#include +#include + +#include "../../public/LeptonInjector/detector/EarthModel.h" +#include "../../public/LeptonInjector/detector/Axis1D.h" +#include "../../public/LeptonInjector/detector/RadialAxis1D.h" +#include "../../../geometry/public/LeptonInjector/geometry/Geometry.h" + +void register_RadialAxis1D(pybind11::module_ & m) { + using namespace pybind11; + using namespace LI::detector; + + class_>(m, "RadialAxis1D") + .def(init<>()) + .def(init()) + .def(init()) + .def(self == self) + .def(self != self) + .def("_compare", &RadialAxis1D::compare) + .def("_clone", &RadialAxis1D::clone) + .def("_create", &RadialAxis1D::create) + .def("GetX", &RadialAxis1D::GetX) + .def("GetdX", &RadialAxis1D::GetdX) + ; +} + diff --git a/projects/detector/private/pybindings/detector.cxx b/projects/detector/private/pybindings/detector.cxx index 7c10c801..6d0704fc 100644 --- a/projects/detector/private/pybindings/detector.cxx +++ b/projects/detector/private/pybindings/detector.cxx @@ -1,29 +1,40 @@ - -#include - -#include "../../public/LeptonInjector/detector/EarthModel.h" - #include #include - +#include "./EarthModel.h" +#include "./EarthSector.h" +#include "./Path.h" +#include "./DensityDistribution.h" +#include "./Distribution1D.h" +#include "./ConstantDistribution1D.h" +#include "./ExponentialDistribution1D.h" +#include "./PolynomialDistribution1D.h" +#include "./Axis1D.h" +#include "./RadialAxis1D.h" +#include "./CartesianAxis1D.h" +#include "./CartesianAxisExponentialDensityDistribution.h" +#include "./CartesianAxisPolynomialDensityDistribution.h" +#include "./ConstantDensityDistribution.h" +#include "./MaterialModel.h" using namespace pybind11; PYBIND11_MODULE(detector,m) { - using namespace LI::detector; - - class_>(m, "EarthModel") - .def(init<>()) - .def(init()) - .def(init()) - .def("LoadEarthModel",&EarthModel::LoadEarthModel) - .def("LoadMaterialModel",&EarthModel::LoadMaterialModel) - .def("GetSectors",&EarthModel::GetSectors); - - class_>(m, "EarthSector") - .def_readwrite("name",&EarthSector::name) - .def_readwrite("material_id",&EarthSector::material_id) - .def_readwrite("geo",&EarthSector::geo); - + register_EarthModel(m); + register_EarthSector(m); + register_Path(m); + register_DensityDistribution(m); + register_Distribution1D(m); + register_ConstantDistribution1D(m); + register_ExponentialDistribution1D(m); + register_PolynomialDistribution1D(m); + register_Axis1D(m); + register_CartesianAxis1D(m); + register_RadialAxis1D(m); + + register_CartesianAxisExponentialDensityDistribution(m); + register_CartesianAxisPolynomialDensityDistribution(m); + register_ConstantDensityDistribution(m); + + register_MaterialModel(m); } diff --git a/projects/detector/public/LeptonInjector/detector/Axis1D.h b/projects/detector/public/LeptonInjector/detector/Axis1D.h index fdd298ed..9646eee4 100644 --- a/projects/detector/public/LeptonInjector/detector/Axis1D.h +++ b/projects/detector/public/LeptonInjector/detector/Axis1D.h @@ -1,10 +1,10 @@ #pragma once #ifndef LI_Axis1D_H #define LI_Axis1D_H -#include -#include -#include -#include + +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error #include #include diff --git a/projects/detector/public/LeptonInjector/detector/CartesianAxis1D.h b/projects/detector/public/LeptonInjector/detector/CartesianAxis1D.h index d18d9e4b..f9f9562e 100644 --- a/projects/detector/public/LeptonInjector/detector/CartesianAxis1D.h +++ b/projects/detector/public/LeptonInjector/detector/CartesianAxis1D.h @@ -1,10 +1,10 @@ #pragma once #ifndef LI_CartesianAxis1D_H #define LI_CartesianAxis1D_H -#include -#include -#include -#include + +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error #include #include @@ -12,9 +12,10 @@ #include #include -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/math/Vector3D.h" // for Vector3D + +#include "LeptonInjector/detector/Axis1D.h" // for Axis1D -#include "LeptonInjector/detector/Axis1D.h" namespace LI { namespace detector { diff --git a/projects/detector/public/LeptonInjector/detector/CartesianAxisDensityDistribution.h b/projects/detector/public/LeptonInjector/detector/CartesianAxisDensityDistribution.h index 24adb2fc..b4aee962 100644 --- a/projects/detector/public/LeptonInjector/detector/CartesianAxisDensityDistribution.h +++ b/projects/detector/public/LeptonInjector/detector/CartesianAxisDensityDistribution.h @@ -108,9 +108,8 @@ class DensityDistribution1D -#include -#include -#include + +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error #include #include diff --git a/projects/detector/public/LeptonInjector/detector/DensityDistribution.h b/projects/detector/public/LeptonInjector/detector/DensityDistribution.h index 57475f60..cb07fadb 100644 --- a/projects/detector/public/LeptonInjector/detector/DensityDistribution.h +++ b/projects/detector/public/LeptonInjector/detector/DensityDistribution.h @@ -28,10 +28,11 @@ #pragma once #ifndef LI_DensityDistribution_H #define LI_DensityDistribution_H -#include -#include -#include -#include + +#include // for basic_string +#include // for shared_ptr +#include // for uint32_t +#include // for exception #include #include diff --git a/projects/detector/public/LeptonInjector/detector/Distribution1D.h b/projects/detector/public/LeptonInjector/detector/Distribution1D.h index 0497c90b..a3830603 100644 --- a/projects/detector/public/LeptonInjector/detector/Distribution1D.h +++ b/projects/detector/public/LeptonInjector/detector/Distribution1D.h @@ -1,10 +1,8 @@ #pragma once #ifndef LI_Distribution1D_H #define LI_Distribution1D_H -#include -#include -#include -#include +#include // for shared_ptr +#include // for uint32_t #include #include diff --git a/projects/detector/public/LeptonInjector/detector/EarthModel.h b/projects/detector/public/LeptonInjector/detector/EarthModel.h index b4c2aa77..7ba68c11 100644 --- a/projects/detector/public/LeptonInjector/detector/EarthModel.h +++ b/projects/detector/public/LeptonInjector/detector/EarthModel.h @@ -2,9 +2,14 @@ #ifndef LI_EarthModel_H #define LI_EarthModel_H -#include -#include -#include +#include // for map +#include // for set +#include // for array +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error +#include // for function +#include // for enable_if, is_same #include #include @@ -19,15 +24,15 @@ #include "LeptonInjector/serialization/array.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/geometry/Geometry.h" -#include "LeptonInjector/geometry/Placement.h" -#include "LeptonInjector/detector/DensityDistribution.h" -#include "LeptonInjector/detector/MaterialModel.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/detector/MaterialModel.h" // for MaterialModel +#include "LeptonInjector/geometry/Geometry.h" // for Geometry +#include "LeptonInjector/math/Vector3D.h" // for Vector3D -#include "LeptonInjector/utilities/Constants.h" #include "LeptonInjector/dataclasses/Particle.h" +namespace LI { namespace detector { class DensityDistribution; } } + namespace LI { namespace detector { @@ -50,6 +55,7 @@ struct EarthSector { throw std::runtime_error("EarthSector only supports version <= 0!"); } } + std::ostream & Print(std::ostream& oss) const; }; class EarthModel { @@ -189,6 +195,10 @@ class EarthModel { } // namespace detector } // namespace LI + +std::ostream& operator<<(std::ostream& oss, LI::detector::EarthSector const & bcm); +std::ostream& operator<<(std::ostream& oss, LI::detector::EarthSector & bcm); + #include "LeptonInjector/detector/EarthModel.tcc" CEREAL_CLASS_VERSION(LI::detector::EarthModel, 0); diff --git a/projects/detector/public/LeptonInjector/detector/EarthModel.tcc b/projects/detector/public/LeptonInjector/detector/EarthModel.tcc index 97c4ae5f..887bae5e 100644 --- a/projects/detector/public/LeptonInjector/detector/EarthModel.tcc +++ b/projects/detector/public/LeptonInjector/detector/EarthModel.tcc @@ -3,8 +3,10 @@ #define LI_EarthModel_TCC #include +#include #include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/detector/DensityDistribution.h" namespace LI { namespace detector { diff --git a/projects/detector/public/LeptonInjector/detector/ExponentialDistribution1D.h b/projects/detector/public/LeptonInjector/detector/ExponentialDistribution1D.h index c26d5d6b..fb86448b 100644 --- a/projects/detector/public/LeptonInjector/detector/ExponentialDistribution1D.h +++ b/projects/detector/public/LeptonInjector/detector/ExponentialDistribution1D.h @@ -1,10 +1,10 @@ #pragma once #ifndef LI_ExponentialDistribution1D_H #define LI_ExponentialDistribution1D_H -#include -#include -#include -#include + +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error #include #include diff --git a/projects/detector/public/LeptonInjector/detector/MaterialModel.h b/projects/detector/public/LeptonInjector/detector/MaterialModel.h index e95f6368..9e968c3f 100644 --- a/projects/detector/public/LeptonInjector/detector/MaterialModel.h +++ b/projects/detector/public/LeptonInjector/detector/MaterialModel.h @@ -2,9 +2,14 @@ #ifndef LI_MaterialModel_H #define LI_MaterialModel_H -#include -#include -#include +#include // for map +#include // for tuple +#include // for basic_string, opera... +#include // for vector +#include // for pair +#include // for uint32_t +#include // for runtime_error +#include // for enable_if, is_same #include #include @@ -19,7 +24,6 @@ #include "LeptonInjector/serialization/array.h" #include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/utilities/Constants.h" namespace LI { namespace detector { diff --git a/projects/detector/public/LeptonInjector/detector/MaterialModel.tcc b/projects/detector/public/LeptonInjector/detector/MaterialModel.tcc index b8ef0b40..05709e44 100644 --- a/projects/detector/public/LeptonInjector/detector/MaterialModel.tcc +++ b/projects/detector/public/LeptonInjector/detector/MaterialModel.tcc @@ -4,6 +4,8 @@ #include "LeptonInjector/detector/MaterialModel.h" +#include + namespace LI { namespace detector { diff --git a/projects/detector/public/LeptonInjector/detector/Path.h b/projects/detector/public/LeptonInjector/detector/Path.h index d16b415a..88b86b23 100644 --- a/projects/detector/public/LeptonInjector/detector/Path.h +++ b/projects/detector/public/LeptonInjector/detector/Path.h @@ -2,7 +2,10 @@ #ifndef LI_Path_H #define LI_Path_H -#include +#include // for vector +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error #include #include @@ -16,7 +19,11 @@ #include #include "LeptonInjector/serialization/array.h" -#include "LeptonInjector/detector/EarthModel.h" + +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/geometry/Geometry.h" // for Geometry +#include "LeptonInjector/detector/EarthModel.h" // for EarthModel +#include "LeptonInjector/math/Vector3D.h" // for Vector3D namespace LI { namespace detector { diff --git a/projects/detector/public/LeptonInjector/detector/PolynomialDistribution1D.h b/projects/detector/public/LeptonInjector/detector/PolynomialDistribution1D.h index cc4bf60b..b3f866aa 100644 --- a/projects/detector/public/LeptonInjector/detector/PolynomialDistribution1D.h +++ b/projects/detector/public/LeptonInjector/detector/PolynomialDistribution1D.h @@ -1,10 +1,11 @@ #pragma once #ifndef LI_PolynomialDistribution1D_H #define LI_PolynomialDistribution1D_H -#include -#include -#include -#include + +#include // for shared_ptr +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include @@ -12,9 +13,9 @@ #include #include -#include "LeptonInjector/math/Polynomial.h" +#include "LeptonInjector/math/Polynomial.h" // for Polynom -#include "LeptonInjector/detector/Distribution1D.h" +#include "LeptonInjector/detector/Distribution1D.h" // for Distribution1D namespace LI { namespace detector { diff --git a/projects/detector/public/LeptonInjector/detector/RadialAxis1D.h b/projects/detector/public/LeptonInjector/detector/RadialAxis1D.h index f64a9d73..c883fca9 100644 --- a/projects/detector/public/LeptonInjector/detector/RadialAxis1D.h +++ b/projects/detector/public/LeptonInjector/detector/RadialAxis1D.h @@ -1,20 +1,20 @@ #pragma once #ifndef LI_RadialAxis1D_H #define LI_RadialAxis1D_H -#include -#include -#include -#include -#include +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error + +#include // for CEREAL_CLASS_VERSION #include #include -#include -#include +#include // for virtual_base_class +#include // for CEREAL_REGISTER_POLYMORP... -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/math/Vector3D.h" // for Vector3D -#include "LeptonInjector/detector/Axis1D.h" +#include "LeptonInjector/detector/Axis1D.h" // for Axis1D namespace LI { namespace detector { diff --git a/projects/distributions/CMakeLists.txt b/projects/distributions/CMakeLists.txt index b29c0006..2341f6fa 100644 --- a/projects/distributions/CMakeLists.txt +++ b/projects/distributions/CMakeLists.txt @@ -37,25 +37,23 @@ LIST (APPEND distributions_SOURCES add_library(LI_distributions OBJECT ${distributions_SOURCES}) set_property(TARGET LI_distributions PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_distributions PUBLIC - ${PROJECT_SOURCE_DIR}/projects/distributions/public/ + $ + $ ) -add_dependencies(LI_distributions rk) -add_dependencies(LI_distributions LI_serialization LI_utilities LI_math LI_dataclasses LI_geometry LI_detector LI_crosssections) -target_link_libraries(LI_distributions photospline) -target_link_libraries(LI_distributions rk) - -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/extern/rk/include) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/utilities/public/) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/math/public/) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/dataclasses/public/) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/geometry/public/) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/detector/public/) -target_include_directories(LI_distributions PUBLIC ${PROJECT_SOURCE_DIR}/projects/crosssections/public/) - -install(TARGETS LI_distributions - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +target_link_libraries(LI_distributions + PRIVATE + $ + PUBLIC + photospline + LI_serialization + LI_utilities + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections +) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/distributions/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} diff --git a/projects/distributions/private/Distributions.cxx b/projects/distributions/private/Distributions.cxx index 03ff7652..acc1dac7 100644 --- a/projects/distributions/private/Distributions.cxx +++ b/projects/distributions/private/Distributions.cxx @@ -1,5 +1,10 @@ #include "LeptonInjector/distributions/Distributions.h" +#include // for basic_string +#include // for vector +#include // for type_info +#include // for type_index + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/direction/Cone.cxx b/projects/distributions/private/primary/direction/Cone.cxx index 97b17c1a..a7e436df 100644 --- a/projects/distributions/private/primary/direction/Cone.cxx +++ b/projects/distributions/private/primary/direction/Cone.cxx @@ -1,13 +1,18 @@ -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/math/Quaternion.h" +#include "LeptonInjector/distributions/primary/direction/Cone.h" -#include "LeptonInjector/utilities/Random.h" +#include // for array +#include // for acos, cos +#include // for basic_string +#include // for abs -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... +#include "LeptonInjector/math/Quaternion.h" // for Quaternion +#include "LeptonInjector/math/Vector3D.h" // for Vector3D +#include "LeptonInjector/utilities/Random.h" // for LI_random -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/direction/Cone.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/direction/FixedDirection.cxx b/projects/distributions/private/primary/direction/FixedDirection.cxx index 283134eb..80b8e2b7 100644 --- a/projects/distributions/private/primary/direction/FixedDirection.cxx +++ b/projects/distributions/private/primary/direction/FixedDirection.cxx @@ -1,10 +1,17 @@ -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/distributions/primary/direction/FixedDirection.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include // for array +#include // for tie, opera... +#include // for basic_string +#include // for abs -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/direction/FixedDirection.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... +#include "LeptonInjector/math/Vector3D.h" // for Vector3D + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/direction/IsotropicDirection.cxx b/projects/distributions/private/primary/direction/IsotropicDirection.cxx index 8c18e5e3..1a29f612 100644 --- a/projects/distributions/private/primary/direction/IsotropicDirection.cxx +++ b/projects/distributions/private/primary/direction/IsotropicDirection.cxx @@ -1,12 +1,15 @@ -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/distributions/primary/direction/IsotropicDirection.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include // for M_PI, cos, sin +#include // for basic_string -#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/distributions/Distributions.h" // for InjectionDis... +#include "LeptonInjector/math/Vector3D.h" // for Vector3D +#include "LeptonInjector/utilities/Random.h" // for LI_random -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/direction/IsotropicDirection.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/direction/PrimaryDirectionDistribution.cxx b/projects/distributions/private/primary/direction/PrimaryDirectionDistribution.cxx index b6e6f88a..9bce69c1 100644 --- a/projects/distributions/private/primary/direction/PrimaryDirectionDistribution.cxx +++ b/projects/distributions/private/primary/direction/PrimaryDirectionDistribution.cxx @@ -1,9 +1,11 @@ -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include // for array +#include // for sqrt +#include // for basic_string -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/math/Vector3D.h" // for Vector3D namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.cxx b/projects/distributions/private/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.cxx index 6f3b0d2e..8e018c9e 100644 --- a/projects/distributions/private/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.cxx +++ b/projects/distributions/private/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.cxx @@ -1,11 +1,19 @@ -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/distributions/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.h" -#include "LeptonInjector/utilities/Integration.h" +#include // for array +#include // for exp, sqrt +#include // for tie, opera... +#include // for basic_string +#include // for abs, size_t +#include // for function -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" -#include "LeptonInjector/distributions/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... +#include "LeptonInjector/utilities/Integration.h" // for rombergInt... +#include "LeptonInjector/utilities/Random.h" // for LI_random + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/energy/Monoenergetic.cxx b/projects/distributions/private/primary/energy/Monoenergetic.cxx index 03f656d0..e60b1aa5 100644 --- a/projects/distributions/private/primary/energy/Monoenergetic.cxx +++ b/projects/distributions/private/primary/energy/Monoenergetic.cxx @@ -1,10 +1,18 @@ -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/utilities/Random.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" #include "LeptonInjector/distributions/primary/energy/Monoenergetic.h" +#include // for array +#include // for abs +#include // for tie, opera... +#include // for basic_string +#include // for abs + +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/energy/PowerLaw.cxx b/projects/distributions/private/primary/energy/PowerLaw.cxx index f8c96bb2..cd6ba7c0 100644 --- a/projects/distributions/private/primary/energy/PowerLaw.cxx +++ b/projects/distributions/private/primary/energy/PowerLaw.cxx @@ -1,10 +1,17 @@ -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/utilities/Random.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" #include "LeptonInjector/distributions/primary/energy/PowerLaw.h" +#include // for array +#include // for tie, opera... +#include // for pow, log10 +#include // for basic_string + +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... +#include "LeptonInjector/utilities/Random.h" // for LI_random + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace detector { class EarthModel; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/energy/PrimaryEnergyDistribution.cxx b/projects/distributions/private/primary/energy/PrimaryEnergyDistribution.cxx index dc6f550d..fdb0beeb 100644 --- a/projects/distributions/private/primary/energy/PrimaryEnergyDistribution.cxx +++ b/projects/distributions/private/primary/energy/PrimaryEnergyDistribution.cxx @@ -1,8 +1,10 @@ -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" +#include // for array +#include // for basic_string + +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/energy/TabulatedFluxDistribution.cxx b/projects/distributions/private/primary/energy/TabulatedFluxDistribution.cxx index 9249eb81..7def72e7 100644 --- a/projects/distributions/private/primary/energy/TabulatedFluxDistribution.cxx +++ b/projects/distributions/private/primary/energy/TabulatedFluxDistribution.cxx @@ -1,13 +1,18 @@ -#include - -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/utilities/Interpolator.h" -#include "LeptonInjector/utilities/Integration.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" #include "LeptonInjector/distributions/primary/energy/TabulatedFluxDistribution.h" +#include // for array +#include // for tie, opera... +#include // for vector +#include // for basic_istream +#include // for function + +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... +#include "LeptonInjector/utilities/Integration.h" // for rombergInt... +#include "LeptonInjector/utilities/Interpolator.h" // for TableData1D +#include "LeptonInjector/utilities/Random.h" // for LI_random + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/helicity/PrimaryNeutrinoHelicityDistribution.cxx b/projects/distributions/private/primary/helicity/PrimaryNeutrinoHelicityDistribution.cxx index 87c98093..3100b47f 100644 --- a/projects/distributions/private/primary/helicity/PrimaryNeutrinoHelicityDistribution.cxx +++ b/projects/distributions/private/primary/helicity/PrimaryNeutrinoHelicityDistribution.cxx @@ -1,13 +1,14 @@ -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" +#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/dataclasses/Particle.h" +#include // for array +#include // for basic_s... +#include // for abs -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/distributions/Distributions.h" // for Injecti... +#include "LeptonInjector/math/Vector3D.h" // for Vector3D namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/type/PrimaryInjector.cxx b/projects/distributions/private/primary/type/PrimaryInjector.cxx index 36fda689..821dd2da 100644 --- a/projects/distributions/private/primary/type/PrimaryInjector.cxx +++ b/projects/distributions/private/primary/type/PrimaryInjector.cxx @@ -1,11 +1,15 @@ -#include "LeptonInjector/detector/EarthModel.h" -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/type/PrimaryInjector.h" +#include // for tie +#include // for basic_s... +#include // for operator<< +#include // for abs + +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interac... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Interac... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/distributions/Distributions.h" // for Injecti... + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/ColumnDepthPositionDistribution.cxx b/projects/distributions/private/primary/vertex/ColumnDepthPositionDistribution.cxx index b5541145..9d8b97e2 100644 --- a/projects/distributions/private/primary/vertex/ColumnDepthPositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/ColumnDepthPositionDistribution.cxx @@ -1,18 +1,24 @@ -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h" + +#include +#include +#include +#include +#include #include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/CrossSectionCollection.h" - -#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include "LeptonInjector/dataclasses/InteractionSignature.h" #include "LeptonInjector/dataclasses/Particle.h" - +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/detector/Path.h" #include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" -#include "LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h" - +#include "LeptonInjector/math/Quaternion.h" +#include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/utilities/Errors.h" +#include "LeptonInjector/utilities/Random.h" namespace LI { namespace distributions { @@ -51,7 +57,7 @@ LI::math::Vector3D ColumnDepthPositionDistribution::SamplePosition(std::shared_p dir.normalize(); LI::math::Vector3D pca = SampleFromDisk(rand, dir); - double lepton_depth = (*depth_function)(record.signature, record.primary_momentum[0]); + double lepton_depth = (*depth_function)(record.signature, record.primary_momentum[0]);//note: return is in cgs units!!! LI::math::Vector3D endcap_0 = pca - endcap_length * dir; LI::math::Vector3D endcap_1 = pca + endcap_length * dir; @@ -96,6 +102,14 @@ LI::math::Vector3D ColumnDepthPositionDistribution::SamplePosition(std::shared_p return vertex; } +// public getter function for the private SamplePosition function (for debugging) +LI::math::Vector3D ColumnDepthPositionDistribution::GetSamplePosition(std::shared_ptr rand, std::shared_ptr earth_model, std::shared_ptr cross_sections, LI::dataclasses::InteractionRecord & record) { + + LI::math::Vector3D samplepos = ColumnDepthPositionDistribution::SamplePosition(rand, earth_model, cross_sections, record); + + return samplepos; +} + double ColumnDepthPositionDistribution::GenerationProbability(std::shared_ptr earth_model, std::shared_ptr cross_sections, LI::dataclasses::InteractionRecord const & record) const { LI::math::Vector3D dir(record.primary_momentum[1], record.primary_momentum[2], record.primary_momentum[3]); dir.normalize(); @@ -114,7 +128,9 @@ double ColumnDepthPositionDistribution::GenerationProbability(std::shared_ptr
  • GetEarthCoordPosFromDetCoordPos(vertex); + + if(not path.IsWithinBounds(earth_vertex)) return 0.0; std::set const & possible_targets = cross_sections->TargetTypes(); @@ -134,11 +150,11 @@ double ColumnDepthPositionDistribution::GenerationProbability(std::shared_ptr
  • GetEarthCoordPosFromDetCoordPos(vertex))); + path.SetPointsWithRay(path.GetFirstPoint(), path.GetDirection(), path.GetDistanceFromStartInBounds(earth_vertex)); double traversed_interaction_depth = path.GetInteractionDepthInBounds(targets, total_cross_sections, total_decay_length); - double interaction_density = earth_model->GetInteractionDensity(path.GetIntersections(), earth_model->GetEarthCoordPosFromDetCoordPos(vertex), targets, total_cross_sections, total_decay_length); + double interaction_density = earth_model->GetInteractionDensity(path.GetIntersections(), earth_vertex, targets, total_cross_sections, total_decay_length); double prob_density; if(total_interaction_depth < 1e-6) { diff --git a/projects/distributions/private/primary/vertex/CylinderVolumePositionDistribution.cxx b/projects/distributions/private/primary/vertex/CylinderVolumePositionDistribution.cxx index 57f0a157..a645fd18 100644 --- a/projects/distributions/private/primary/vertex/CylinderVolumePositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/CylinderVolumePositionDistribution.cxx @@ -1,15 +1,19 @@ -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" +#include "LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h" -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/dataclasses/Particle.h" +#include // for array +#include // for sqrt, cos +#include // for basic_string +#include // for vector +#include // for abs -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/detector/EarthModel.h" // for EarthModel +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... +#include "LeptonInjector/geometry/Geometry.h" // for Geometry +#include "LeptonInjector/math/Vector3D.h" // for Vector3D +#include "LeptonInjector/utilities/Random.h" // for LI_random -#include "LeptonInjector/utilities/Errors.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/DecayRangeFunction.cxx b/projects/distributions/private/primary/vertex/DecayRangeFunction.cxx index 5e41ad15..127900ac 100644 --- a/projects/distributions/private/primary/vertex/DecayRangeFunction.cxx +++ b/projects/distributions/private/primary/vertex/DecayRangeFunction.cxx @@ -1,6 +1,11 @@ -#include "LeptonInjector/dataclasses/InteractionSignature.h" #include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" +#include // for tie, operator<, operator==, tuple +#include // for sqrt +#include // for min + +namespace LI { namespace dataclasses { struct InteractionSignature; } } + namespace LI { namespace distributions { @@ -9,7 +14,7 @@ namespace distributions { //--------------- double DecayRangeFunction::DecayLength(double particle_mass, double decay_width, double energy) { - double beta = sqrt(energy*energy - particle_mass*particle_mass) / energy; + double beta = std::sqrt(energy*energy - particle_mass*particle_mass) / energy; double gamma = energy / particle_mass; double time_in_rest_frame = 1.0 / decay_width; // inverse GeV double time_in_lab_frame = time_in_rest_frame * gamma; // inverse GeV diff --git a/projects/distributions/private/primary/vertex/DecayRangePositionDistribution.cxx b/projects/distributions/private/primary/vertex/DecayRangePositionDistribution.cxx index 164d85b6..85d0468c 100644 --- a/projects/distributions/private/primary/vertex/DecayRangePositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/DecayRangePositionDistribution.cxx @@ -1,17 +1,20 @@ -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h" -#include "LeptonInjector/crosssections/CrossSection.h" +#include +#include +#include +#include -#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" #include "LeptonInjector/dataclasses/Particle.h" - +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/detector/Path.h" #include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" -#include "LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h" - -#include "LeptonInjector/utilities/Errors.h" +#include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" +#include "LeptonInjector/math/Quaternion.h" +#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/utilities/Random.h" namespace LI { namespace distributions { @@ -68,11 +71,13 @@ double DecayRangePositionDistribution::GenerationProbability(std::shared_ptrMultiplier()); path.ClipToOuterBounds(); - if(not path.IsWithinBounds(vertex)) + LI::math::Vector3D earth_vertex = earth_model->GetEarthCoordPosFromDetCoordPos(vertex); + + if(not path.IsWithinBounds(earth_vertex)) return 0.0; double total_distance = path.GetDistance(); - double dist = LI::math::scalar_product(path.GetDirection(), vertex - path.GetFirstPoint()); + double dist = LI::math::scalar_product(path.GetDirection(), earth_vertex - path.GetFirstPoint()); double prob_density = exp(-dist / decay_length) / (decay_length * (1.0 - exp(-total_distance / decay_length))); // m^-1 prob_density /= (M_PI * radius * radius); // (m^-1 * m^-2) -> m^-3 @@ -109,7 +114,9 @@ std::pair DecayRangePositionDistribution path.ExtendFromStartByDistance(decay_length * range_function->Multiplier()); path.ClipToOuterBounds(); - if(not path.IsWithinBounds(vertex)) + LI::math::Vector3D earth_vertex = earth_model->GetEarthCoordPosFromDetCoordPos(vertex); + + if(not path.IsWithinBounds(earth_vertex)) return std::pair(LI::math::Vector3D(0, 0, 0), LI::math::Vector3D(0, 0, 0)); return std::pair(path.GetFirstPoint(), path.GetLastPoint()); diff --git a/projects/distributions/private/primary/vertex/DepthFunction.cxx b/projects/distributions/private/primary/vertex/DepthFunction.cxx index 115db8eb..3f4a4fe7 100644 --- a/projects/distributions/private/primary/vertex/DepthFunction.cxx +++ b/projects/distributions/private/primary/vertex/DepthFunction.cxx @@ -1,7 +1,10 @@ -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" +#include // for type_info +#include // for type_index + +namespace LI { namespace dataclasses { struct InteractionSignature; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/LeptonDepthFunction.cxx b/projects/distributions/private/primary/vertex/LeptonDepthFunction.cxx index 1c9a3e94..13950123 100644 --- a/projects/distributions/private/primary/vertex/LeptonDepthFunction.cxx +++ b/projects/distributions/private/primary/vertex/LeptonDepthFunction.cxx @@ -1,6 +1,11 @@ +#include "LeptonInjector/distributions/primary/vertex/LeptonDepthFunction.h" + #include +#include +#include + +#include "LeptonInjector/dataclasses/InteractionSignature.h" #include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" -#include "LeptonInjector/distributions/primary/vertex/LeptonDepthFunction.h" namespace LI { namespace distributions { @@ -54,9 +59,9 @@ double LeptonDepthFunction::GetMaxDepth() const { } double LeptonDepthFunction::operator()(LI::dataclasses::InteractionSignature const & signature, double energy) const { - double range = log(1.0 + energy * mu_beta / mu_alpha) / mu_beta; + double range = std::log(1.0 + energy * mu_beta / mu_alpha) / mu_beta; if(tau_primaries.count(signature.primary_type) > 0) - range += log(1.0 + energy * tau_beta / tau_alpha) / tau_beta; + range += std::log(1.0 + energy * tau_beta / tau_alpha) / tau_beta; return std::min(range, max_depth); } diff --git a/projects/distributions/private/primary/vertex/OrientedCylinderPositionDistribution.cxx b/projects/distributions/private/primary/vertex/OrientedCylinderPositionDistribution.cxx index 762f489a..be05928b 100644 --- a/projects/distributions/private/primary/vertex/OrientedCylinderPositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/OrientedCylinderPositionDistribution.cxx @@ -1,15 +1,14 @@ -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/primary/vertex/OrientedCylinderPositionDistribution.h" -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" +#include // for array +#include // for sqrt, cos -#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/math/Quaternion.h" // for rotation_b... +#include "LeptonInjector/math/Vector3D.h" // for Vector3D +#include "LeptonInjector/utilities/Random.h" // for LI_random -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/OrientedCylinderPositionDistribution.h" +namespace LI { namespace distributions { class WeightableDistribution; } } namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/PointSourcePositionDistribution.cxx b/projects/distributions/private/primary/vertex/PointSourcePositionDistribution.cxx index 910bbdf4..4d92f25d 100644 --- a/projects/distributions/private/primary/vertex/PointSourcePositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/PointSourcePositionDistribution.cxx @@ -1,18 +1,22 @@ -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/crosssections/CrossSectionCollection.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/PointSourcePositionDistribution.h" -#include "LeptonInjector/utilities/Errors.h" +#include // for array +#include // for exp +#include // for tie +#include // for bas... +#include // for vector + +#include "LeptonInjector/crosssections/CrossSection.h" // for Cro... +#include "LeptonInjector/crosssections/CrossSectionCollection.h" // for Cro... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Int... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Int... +#include "LeptonInjector/dataclasses/Particle.h" // for Par... +#include "LeptonInjector/detector/EarthModel.h" // for Ear... +#include "LeptonInjector/detector/Path.h" // for Path +#include "LeptonInjector/distributions/Distributions.h" // for Inj... +#include "LeptonInjector/math/Vector3D.h" // for Vec... +#include "LeptonInjector/utilities/Errors.h" // for Inj... +#include "LeptonInjector/utilities/Random.h" // for LI_... namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/RangeFunction.cxx b/projects/distributions/private/primary/vertex/RangeFunction.cxx index eacec509..a42d2e34 100644 --- a/projects/distributions/private/primary/vertex/RangeFunction.cxx +++ b/projects/distributions/private/primary/vertex/RangeFunction.cxx @@ -1,6 +1,8 @@ -#include "LeptonInjector/dataclasses/InteractionSignature.h" #include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" +#include // for type_index +#include // for type_info + namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/RangePositionDistribution.cxx b/projects/distributions/private/primary/vertex/RangePositionDistribution.cxx index 76d13763..3af16be9 100644 --- a/projects/distributions/private/primary/vertex/RangePositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/RangePositionDistribution.cxx @@ -1,18 +1,24 @@ -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h" + +#include +#include +#include +#include +#include #include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/CrossSectionCollection.h" #include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/utilities/Random.h" +#include "LeptonInjector/dataclasses/InteractionSignature.h" #include "LeptonInjector/dataclasses/Particle.h" - +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/detector/Path.h" #include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h" - +#include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" +#include "LeptonInjector/math/Quaternion.h" +#include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/utilities/Errors.h" +#include "LeptonInjector/utilities/Random.h" namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/SecondaryPositionDistribution.cxx b/projects/distributions/private/primary/vertex/SecondaryPositionDistribution.cxx index 98ecf89b..d766b7a4 100644 --- a/projects/distributions/private/primary/vertex/SecondaryPositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/SecondaryPositionDistribution.cxx @@ -1,18 +1,24 @@ -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/crosssections/CrossSectionCollection.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/SecondaryPositionDistribution.h" -#include "LeptonInjector/utilities/Errors.h" +#include // for set +#include // for array +#include // for exp +#include // for tie +#include // for bas... +#include // for vector + +#include "LeptonInjector/crosssections/CrossSection.h" // for Cro... +#include "LeptonInjector/crosssections/CrossSectionCollection.h" // for Cro... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Int... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Int... +#include "LeptonInjector/dataclasses/Particle.h" // for Par... +#include "LeptonInjector/detector/EarthModel.h" // for Ear... +#include "LeptonInjector/detector/Path.h" // for Path +#include "LeptonInjector/distributions/Distributions.h" // for Inj... +#include "LeptonInjector/geometry/Geometry.h" // for Geo... +#include "LeptonInjector/math/Vector3D.h" // for Vec... +#include "LeptonInjector/utilities/Errors.h" // for Sec... +#include "LeptonInjector/utilities/Random.h" // for LI_... namespace LI { namespace distributions { diff --git a/projects/distributions/private/primary/vertex/VertexPositionDistribution.cxx b/projects/distributions/private/primary/vertex/VertexPositionDistribution.cxx index 5869dc91..5aa0c597 100644 --- a/projects/distributions/private/primary/vertex/VertexPositionDistribution.cxx +++ b/projects/distributions/private/primary/vertex/VertexPositionDistribution.cxx @@ -1,13 +1,12 @@ -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" -#include "LeptonInjector/utilities/Random.h" +#include // for array +#include // for bas... -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/crosssections/CrossSectionCollection.h" // for Cro... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Int... +#include "LeptonInjector/detector/EarthModel.h" // for Ear... +#include "LeptonInjector/math/Vector3D.h" // for Vec... namespace LI { namespace distributions { diff --git a/projects/distributions/private/pybindings/distributions.cxx b/projects/distributions/private/pybindings/distributions.cxx index 4cde8b1c..b21f5fa6 100644 --- a/projects/distributions/private/pybindings/distributions.cxx +++ b/projects/distributions/private/pybindings/distributions.cxx @@ -157,6 +157,7 @@ PYBIND11_MODULE(distributions,m) { class_, DepthFunction>(m, "LeptonDepthFunction") .def(init<>()) + .def("__call__", &LeptonDepthFunction::operator()) .def("SetMuParams",&LeptonDepthFunction::SetMuParams) .def("SetTauParams",&LeptonDepthFunction::SetTauParams) .def("SetScale",&LeptonDepthFunction::SetScale) @@ -166,7 +167,8 @@ PYBIND11_MODULE(distributions,m) { .def("GetTauAlpha",&LeptonDepthFunction::GetTauAlpha) .def("GetTauBeta",&LeptonDepthFunction::GetTauBeta) .def("GetScale",&LeptonDepthFunction::GetScale) - .def("GetMaxDepth",&LeptonDepthFunction::GetMaxDepth); + .def("GetMaxDepth",&LeptonDepthFunction::GetMaxDepth) + ; //.def((LI::dataclasses::InteractionSignature const &, double)); // VertexPositionDistribution subclasses @@ -181,7 +183,8 @@ PYBIND11_MODULE(distributions,m) { .def(init, std::set>()) .def("GenerationProbability",&ColumnDepthPositionDistribution::GenerationProbability) .def("InjectionBounds",&ColumnDepthPositionDistribution::InjectionBounds) - .def("Name",&ColumnDepthPositionDistribution::Name); + .def("Name",&ColumnDepthPositionDistribution::Name) + .def("GetSamplePosition",&ColumnDepthPositionDistribution::GetSamplePosition); class_, VertexPositionDistribution>(m, "DecayRangePositionDistribution") .def(init<>()) diff --git a/projects/distributions/private/target/momentum/TargetMomentumDistribution.cxx b/projects/distributions/private/target/momentum/TargetMomentumDistribution.cxx index 13e113bf..785ff513 100644 --- a/projects/distributions/private/target/momentum/TargetMomentumDistribution.cxx +++ b/projects/distributions/private/target/momentum/TargetMomentumDistribution.cxx @@ -1,11 +1,10 @@ -#include "LeptonInjector/detector/EarthModel.h" -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/utilities/Random.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h" +#include // for basic_string + +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/distributions/Distributions.h" // for InjectionD... + namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/Distributions.h b/projects/distributions/public/LeptonInjector/distributions/Distributions.h index 494be955..7f00ec3b 100644 --- a/projects/distributions/public/LeptonInjector/distributions/Distributions.h +++ b/projects/distributions/public/LeptonInjector/distributions/Distributions.h @@ -2,18 +2,23 @@ #ifndef LI_Distributions_H #define LI_Distributions_H -#include -#include -#include -#include -#include +#include // for string +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error +#include // for vector #include #include #include #include -#include "LeptonInjector/dataclasses/InteractionTree.h" +#include "LeptonInjector/dataclasses/InteractionTree.h" // for InteractionT... + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace utilities { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/direction/Cone.h b/projects/distributions/public/LeptonInjector/distributions/primary/direction/Cone.h index 136bf796..4cc4f662 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/direction/Cone.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/direction/Cone.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -11,11 +11,16 @@ #include #include -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" #include "LeptonInjector/math/Quaternion.h" +#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/direction/FixedDirection.h b/projects/distributions/public/LeptonInjector/distributions/primary/direction/FixedDirection.h index 529c9713..6a4d08a7 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/direction/FixedDirection.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/direction/FixedDirection.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -12,10 +12,15 @@ #include #include +#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/direction/IsotropicDirection.h b/projects/distributions/public/LeptonInjector/distributions/primary/direction/IsotropicDirection.h index e8ec1403..0ba8552c 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/direction/IsotropicDirection.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/direction/IsotropicDirection.h @@ -4,8 +4,7 @@ #include #include -#include -#include +#include #include #include @@ -13,8 +12,15 @@ #include #include -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" +#include "LeptonInjector/math/Vector3D.h" + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace math { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h index 74ef3c00..c3f9e45d 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h @@ -2,14 +2,19 @@ #ifndef LI_PrimaryDirectionDistribution_H #define LI_PrimaryDirectionDistribution_H -#include +#include // for string +#include // for shared_ptr +#include // for vector +#include // for uint32_t +#include // for runtime_error -#include -#include -#include -#include +#include "LeptonInjector/distributions/Distributions.h" // for WeightableDi... -#include "LeptonInjector/distributions/Distributions.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace math { class Vector3D; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace utilities { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.h index c2b36c5a..379a370b 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/energy/ModifiedMoyalPlusExponentialEnergyDistribution.h @@ -2,16 +2,26 @@ #ifndef LI_ModifiedMoyalPlusExponentialEnergyDistribution_H #define LI_ModifiedMoyalPlusExponentialEnergyDistribution_H +#include #include +#include +#include +#include #include #include #include #include -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/energy/Monoenergetic.h b/projects/distributions/public/LeptonInjector/distributions/primary/energy/Monoenergetic.h index 655aaf67..8169c79d 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/energy/Monoenergetic.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/energy/Monoenergetic.h @@ -2,16 +2,25 @@ #ifndef LI_Monoenergetic_H #define LI_Monoenergetic_H +#include #include +#include +#include #include #include #include #include -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/energy/PowerLaw.h b/projects/distributions/public/LeptonInjector/distributions/primary/energy/PowerLaw.h index 6f61bdd6..d261ed8a 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/energy/PowerLaw.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/energy/PowerLaw.h @@ -2,16 +2,25 @@ #ifndef LI_PowerLaw_H #define LI_PowerLaw_H +#include #include +#include +#include #include #include #include #include -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h index 23ccbe94..41624efd 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h @@ -2,32 +2,24 @@ #ifndef LI_PrimaryEnergyDistribution_H #define LI_PrimaryEnergyDistribution_H -#include +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include #include #include -#include "LeptonInjector/distributions/Distributions.h" +#include "LeptonInjector/distributions/Distributions.h" // for WeightableDi... -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LI +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } +namespace cereal { class access; } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/energy/TabulatedFluxDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/energy/TabulatedFluxDistribution.h index 335a1de5..472a5417 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/energy/TabulatedFluxDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/energy/TabulatedFluxDistribution.h @@ -2,17 +2,26 @@ #ifndef LI_TabulatedFluxDistribution_H #define LI_TabulatedFluxDistribution_H +#include #include +#include +#include +#include #include #include #include #include +#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" #include "LeptonInjector/utilities/Interpolator.h" -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h index c9a6890e..5fb6d7c8 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h @@ -2,33 +2,23 @@ #ifndef LI_PrimaryNeutrinoHelicityDistribution_H #define LI_PrimaryNeutrinoHelicityDistribution_H -#include -#include +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include #include #include -#include "LeptonInjector/distributions/Distributions.h" +#include "LeptonInjector/distributions/Distributions.h" // for InjectionDis... -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/type/PrimaryInjector.h b/projects/distributions/public/LeptonInjector/distributions/primary/type/PrimaryInjector.h index ac72d5cf..d788cbd9 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/type/PrimaryInjector.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/type/PrimaryInjector.h @@ -2,35 +2,24 @@ #ifndef LI_PrimaryInjector_H #define LI_PrimaryInjector_H -#include -#include +#include // for string +#include // for shared_ptr +#include // for uint32_t +#include // for runtime_error +#include // for vector #include #include #include #include -#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/distributions/Distributions.h" // for InjectionDis... -#include "LeptonInjector/distributions/Distributions.h" - -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h index fb788731..238a36ae 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h @@ -2,9 +2,10 @@ #ifndef LI_ColumnDepthPositionDistribution_H #define LI_ColumnDepthPositionDistribution_H +#include #include #include -#include +#include #include #include @@ -15,29 +16,16 @@ #include #include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" +#include "LeptonInjector/math/Vector3D.h" -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { @@ -56,6 +44,7 @@ friend cereal::access; LI::math::Vector3D SamplePosition(std::shared_ptr rand, std::shared_ptr earth_model, std::shared_ptr cross_sections, LI::dataclasses::InteractionRecord & record) const override; public: + LI::math::Vector3D GetSamplePosition(std::shared_ptr rand, std::shared_ptr earth_model, std::shared_ptr cross_sections, LI::dataclasses::InteractionRecord & record); virtual double GenerationProbability(std::shared_ptr earth_model, std::shared_ptr cross_sections, LI::dataclasses::InteractionRecord const & record) const override; ColumnDepthPositionDistribution(double radius, double endcap_length, std::shared_ptr depth_function, std::set target_types); std::string Name() const override; diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h index 4f6f3873..08fedb9c 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -13,19 +13,18 @@ #include #include +#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/geometry/Cylinder.h" #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/geometry/Cylinder.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { - -namespace detector { -class EarthModel; -} // namespace detector - namespace distributions { class CylinderVolumePositionDistribution : virtual public VertexPositionDistribution { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h index cc656235..b4659706 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h @@ -2,13 +2,20 @@ #ifndef LI_DecayRangeFunction_H #define LI_DecayRangeFunction_H +#include +#include + #include +#include +#include #include #include #include #include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" +namespace LI { namespace dataclasses { struct InteractionSignature; } } + namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h index 92696eed..d09ddd78 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h @@ -2,9 +2,12 @@ #ifndef LI_DecayRangePositionDistribution_H #define LI_DecayRangePositionDistribution_H +#include #include #include #include +#include +#include #include #include @@ -13,30 +16,16 @@ #include #include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" +#include "LeptonInjector/math/Vector3D.h" -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DepthFunction.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DepthFunction.h index fc64ceda..f4062031 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DepthFunction.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/DepthFunction.h @@ -2,21 +2,19 @@ #ifndef LI_DepthFunction_H #define LI_DepthFunction_H -#include -#include -#include +#include // for uint32_t +#include // for runtime_error #include +#include +#include #include #include #include -#include "LeptonInjector/dataclasses/InteractionSignature.h" +namespace LI { namespace dataclasses { struct InteractionSignature; } } namespace LI { -namespace dataclassses { -class InteractionSignature; -} namespace distributions { class DepthFunction { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/LeptonDepthFunction.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/LeptonDepthFunction.h index 9ee29dd9..02937dde 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/LeptonDepthFunction.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/LeptonDepthFunction.h @@ -2,21 +2,25 @@ #ifndef LI_LeptonDepthFunction_H #define LI_LeptonDepthFunction_H -#include +#include +#include +#include #include #include +#include +#include #include #include #include #include +#include "LeptonInjector/dataclasses/Particle.h" #include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" +namespace LI { namespace dataclasses { struct InteractionSignature; } } + namespace LI { -namespace dataclassses { -class InteractionSignature; -} namespace distributions { class LeptonDepthFunction : virtual public DepthFunction { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/OrientedCylinderPositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/OrientedCylinderPositionDistribution.h index 6bf3c58d..e3566eae 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/OrientedCylinderPositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/OrientedCylinderPositionDistribution.h @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -12,28 +13,15 @@ #include #include -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/math/Vector3D.h" -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/PointSourcePositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/PointSourcePositionDistribution.h index 529c9d8b..bb8853af 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/PointSourcePositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/PointSourcePositionDistribution.h @@ -2,8 +2,12 @@ #ifndef LI_PointSourcePositionDistribution_H #define LI_PointSourcePositionDistribution_H +#include #include #include +#include +#include +#include #include #include @@ -12,29 +16,15 @@ #include #include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/math/Vector3D.h" -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangeFunction.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangeFunction.h index 4bfb8711..07c31da3 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangeFunction.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangeFunction.h @@ -2,15 +2,19 @@ #ifndef LI_RangeFunction_H #define LI_RangeFunction_H +#include // for uint32_t +#include // for runtime_error + #include +#include +#include #include #include #include +namespace LI { namespace dataclasses { struct InteractionSignature; } } + namespace LI { -namespace dataclasses { -struct InteractionSignature; -} namespace distributions { class RangeFunction { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h index b5e94e95..797e7180 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h @@ -2,8 +2,12 @@ #ifndef LI_RangePositionDistribution_H #define LI_RangePositionDistribution_H +#include #include #include +#include +#include +#include #include #include @@ -12,30 +16,16 @@ #include #include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" +#include "LeptonInjector/math/Vector3D.h" -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/SecondaryPositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/SecondaryPositionDistribution.h index fc913661..c8fe7424 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/SecondaryPositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/SecondaryPositionDistribution.h @@ -2,8 +2,13 @@ #ifndef LI_SecondaryPositionDistribution_H #define LI_SecondaryPositionDistribution_H +#include #include #include +#include +#include +#include +#include #include #include @@ -11,32 +16,17 @@ #include #include -#include "LeptonInjector/dataclasses/Particle.h" - -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/geometry/Geometry.h" - -#include "LeptonInjector/distributions/Distributions.h" +#include "LeptonInjector/dataclasses/InteractionTree.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/math/Vector3D.h" -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace geometry { class Geometry; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h index 98a730db..f9f9570b 100644 --- a/projects/distributions/public/LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h @@ -2,36 +2,26 @@ #ifndef LI_VertexPositionDistribution_H #define LI_VertexPositionDistribution_H -#include -#include -#include +#include // for shared_ptr +#include // for string +#include // for vector +#include // for uint32_t +#include // for pair +#include // for runtime_error #include #include #include #include -#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/dataclasses/InteractionTree.h" // for InteractionT... +#include "LeptonInjector/distributions/Distributions.h" // for WeightableDi... +#include "LeptonInjector/math/Vector3D.h" // for Vector3D -#include "LeptonInjector/distributions/Distributions.h" - -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/distributions/public/LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h b/projects/distributions/public/LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h index dc17b48d..a456ed18 100644 --- a/projects/distributions/public/LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h +++ b/projects/distributions/public/LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h @@ -2,11 +2,12 @@ #ifndef LI_TargetMomentumDistribution_H #define LI_TargetMomentumDistribution_H +#include // for array #include #include -#include -#include -#include +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include @@ -14,29 +15,12 @@ #include #include -#include "LeptonInjector/serialization/array.h" +#include "LeptonInjector/distributions/Distributions.h" // for InjectionDis... -#include "LeptonInjector/math/Vector3D.h" - -#include "LeptonInjector/distributions/Distributions.h" - -namespace LI { -namespace utilities { -class LI_random; -} // namespace utilities - -namespace detector { -class EarthModel; -} // namespace detector - -namespace dataclasses { -struct InteractionRecord; -struct InteractionSignature; -} -namespace crosssections { -class CrossSectionCollection; -} // namespace crosssections -} // namespace LeptonInjector +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { namespace distributions { diff --git a/projects/geometry/CMakeLists.txt b/projects/geometry/CMakeLists.txt index 8207318f..eec43c51 100644 --- a/projects/geometry/CMakeLists.txt +++ b/projects/geometry/CMakeLists.txt @@ -13,22 +13,18 @@ LIST (APPEND geometry_SOURCES add_library(LI_geometry OBJECT ${geometry_SOURCES}) set_property(TARGET LI_geometry PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_geometry PUBLIC - ${PROJECT_SOURCE_DIR}/projects/geometry/public/ + $ + $ ) -add_dependencies(LI_geometry rk) -add_dependencies(LI_geometry LI_serialization LI_math LI_geometry) - -target_link_libraries(LI_geometry photospline) -target_link_libraries(LI_geometry rk) - -target_include_directories(LI_geometry PUBLIC ${PROJECT_SOURCE_DIR}/vendor/rk/include) -target_include_directories(LI_geometry PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) -target_include_directories(LI_geometry PUBLIC ${PROJECT_SOURCE_DIR}/projects/math/public/) -target_include_directories(LI_geometry PUBLIC ${PROJECT_SOURCE_DIR}/projects/geometry/public/) - -install(TARGETS LI_geometry - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +target_link_libraries(LI_geometry + PRIVATE + $ + PUBLIC + photospline + LI_serialization + LI_math +) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/geometry/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} diff --git a/projects/geometry/private/Box.cxx b/projects/geometry/private/Box.cxx index e73987cb..f0bb9f65 100644 --- a/projects/geometry/private/Box.cxx +++ b/projects/geometry/private/Box.cxx @@ -1,15 +1,18 @@ -#include +#include "LeptonInjector/geometry/Box.h" + #include #include +#include #include #include +#include +#include #include #include #include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/geometry/Geometry.h" #include "LeptonInjector/geometry/Placement.h" -#include "LeptonInjector/geometry/Box.h" namespace LI { namespace geometry { diff --git a/projects/geometry/private/Cylinder.cxx b/projects/geometry/private/Cylinder.cxx index 64615147..43f04396 100644 --- a/projects/geometry/private/Cylinder.cxx +++ b/projects/geometry/private/Cylinder.cxx @@ -1,15 +1,18 @@ -#include +#include "LeptonInjector/geometry/Cylinder.h" + #include #include #include #include +#include +#include #include +#include #include #include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/geometry/Geometry.h" #include "LeptonInjector/geometry/Placement.h" -#include "LeptonInjector/geometry/Cylinder.h" namespace LI { namespace geometry { diff --git a/projects/geometry/private/ExtrPoly.cxx b/projects/geometry/private/ExtrPoly.cxx index c080b04b..1fed318c 100644 --- a/projects/geometry/private/ExtrPoly.cxx +++ b/projects/geometry/private/ExtrPoly.cxx @@ -1,15 +1,19 @@ -#include -#include +#include "LeptonInjector/geometry/ExtrPoly.h" + #include +#include #include #include +#include +#include +#include #include +#include #include #include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/geometry/Geometry.h" #include "LeptonInjector/geometry/Placement.h" -#include "LeptonInjector/geometry/ExtrPoly.h" namespace LI { namespace geometry { diff --git a/projects/geometry/private/Geometry.cxx b/projects/geometry/private/Geometry.cxx index fad9feaa..085f01de 100644 --- a/projects/geometry/private/Geometry.cxx +++ b/projects/geometry/private/Geometry.cxx @@ -1,19 +1,13 @@ -/* - * Geometry.cxx - * - * Created on: 05.06.2013 - * Author: koehne - */ -#include -#include -#include +#include "LeptonInjector/geometry/Geometry.h" + #include #include -#include -#include +#include +#include +#include +#include #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/geometry/Geometry.h" #include "LeptonInjector/geometry/Placement.h" /****************************************************************************** diff --git a/projects/geometry/private/GeometryMesh.cxx b/projects/geometry/private/GeometryMesh.cxx index 213b2340..ae13ae8b 100644 --- a/projects/geometry/private/GeometryMesh.cxx +++ b/projects/geometry/private/GeometryMesh.cxx @@ -1,12 +1,13 @@ -#include +#include "LeptonInjector/geometry/GeometryMesh.h" + +#include #include -#include -#include +#include + #include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/geometry/Geometry.h" #include "LeptonInjector/geometry/Placement.h" #include "LeptonInjector/geometry/MeshBuilder.h" -#include "LeptonInjector/geometry/GeometryMesh.h" using namespace LI::geometry; diff --git a/projects/geometry/private/MeshBuilder.cxx b/projects/geometry/private/MeshBuilder.cxx index a96d6fa8..f9f13a84 100644 --- a/projects/geometry/private/MeshBuilder.cxx +++ b/projects/geometry/private/MeshBuilder.cxx @@ -1,13 +1,19 @@ -#include -#include +#include "LeptonInjector/geometry/MeshBuilder.h" + +#include +#include #include -#include +#include #include +#include +#include +#include #include +#include +#include +#include #include -#include "LeptonInjector/geometry/MeshBuilder.h" - /****************************************************************************** * OStream * ******************************************************************************/ diff --git a/projects/geometry/private/Placement.cxx b/projects/geometry/private/Placement.cxx index 6e91f21f..44dcea04 100644 --- a/projects/geometry/private/Placement.cxx +++ b/projects/geometry/private/Placement.cxx @@ -1,8 +1,12 @@ -#include +#include "LeptonInjector/geometry/Placement.h" + #include -#include +#include +#include +#include -#include "LeptonInjector/geometry/Placement.h" +#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/math/Quaternion.h" #include "LeptonInjector/math/EulerQuaternionConversions.h" using namespace LI::geometry; diff --git a/projects/geometry/private/Sphere.cxx b/projects/geometry/private/Sphere.cxx index 40efdbe1..b8f537c7 100644 --- a/projects/geometry/private/Sphere.cxx +++ b/projects/geometry/private/Sphere.cxx @@ -1,15 +1,19 @@ -#include +#include "LeptonInjector/geometry/Sphere.h" + #include #include +#include #include #include +#include +#include #include +#include #include #include "LeptonInjector/math/Vector3D.h" #include "LeptonInjector/geometry/Geometry.h" #include "LeptonInjector/geometry/Placement.h" -#include "LeptonInjector/geometry/Sphere.h" namespace LI { namespace geometry { diff --git a/projects/geometry/private/pybindings/geometry.cxx b/projects/geometry/private/pybindings/geometry.cxx index 5154c480..43c80a4d 100644 --- a/projects/geometry/private/pybindings/geometry.cxx +++ b/projects/geometry/private/pybindings/geometry.cxx @@ -16,83 +16,106 @@ using namespace pybind11; PYBIND11_MODULE(geometry,m) { - using namespace LI::geometry; - - class_>(m, "Geometry") - .def("IsInside",&Geometry::IsInside) - .def("IsInfront",&Geometry::IsInfront) - .def("IsBehind",&Geometry::IsBehind) - .def("DistanceToBorder",&Geometry::DistanceToBorder) - .def("Intersections",&Geometry::Intersections) - .def("DistanceToClosestApproach",&Geometry::DistanceToClosestApproach) - .def("GetLocation",&Geometry::GetLocation) - .def_property_readonly("name",&Geometry::GetName) - .def_property("placement",&Geometry::GetPlacement, &Geometry::SetPlacement) - .def("ComputeIntersections",&Geometry::ComputeIntersections) - .def("create",&Geometry::create); - - // ExtrPoly - - class_(m, "ZSection") - .def(init<>()) - .def(init()) - .def_readwrite("zpos", &ExtrPoly::ZSection::zpos) - .def_readwrite("scale", &ExtrPoly::ZSection::scale) - .def_readwrite("offset", &ExtrPoly::ZSection::offset); - - class_(m, "plane") - .def_readwrite("a", &ExtrPoly::plane::a) - .def_readwrite("b", &ExtrPoly::plane::b) - .def_readwrite("c", &ExtrPoly::plane::c) - .def_readwrite("d", &ExtrPoly::plane::d); - - class_, Geometry>(m, "ExtrPoly") - .def(init<>()) - .def(init>&, - const std::vector&>()) - .def(init>&, - const std::vector&>()) - .def(init()) - .def(init()) - .def_property("polygon",&ExtrPoly::GetPolygon, &ExtrPoly::SetPolygon) - .def_property("zsections",&ExtrPoly::GetZSections, &ExtrPoly::SetZSections) - .def("ComputeLateralPlanes",&ExtrPoly::ComputeLateralPlanes); - - // Box - - class_, Geometry>(m, "Box") - .def(init<>()) - .def(init()) - .def(init()) - .def(init()) - .def(init()) - .def_property("X",&Box::GetX, &Box::SetX) - .def_property("Y",&Box::GetY, &Box::SetY) - .def_property("Z",&Box::GetZ, &Box::SetZ); - - // Cylinder - - class_, Geometry>(m, "Cylinder") - .def(init<>()) - .def(init()) - .def(init()) - .def(init()) - .def(init()) - .def_property("InnerRadius",&Cylinder::GetInnerRadius, &Cylinder::SetInnerRadius) - .def_property("Radius",&Cylinder::GetRadius, &Cylinder::SetRadius) - .def_property("Z",&Cylinder::GetZ, &Cylinder::SetZ); - - // Sphere - - class_, Geometry>(m, "Sphere") - .def(init<>()) - .def(init()) - .def(init()) - .def(init()) - .def(init()) - .def_property("InnerRadius",&Sphere::GetInnerRadius, &Sphere::SetInnerRadius) - .def_property("Radius",&Sphere::GetRadius, &Sphere::SetRadius); - - + using namespace LI::geometry; + + // geometry + + class_>(m, "Geometry") + .def("IsInside",&Geometry::IsInside) + .def("IsInfront",&Geometry::IsInfront) + .def("IsBehind",&Geometry::IsBehind) + .def("DistanceToBorder",&Geometry::DistanceToBorder) + .def("Intersections",&Geometry::Intersections) + .def("DistanceToClosestApproach",&Geometry::DistanceToClosestApproach) + .def("GetLocation",&Geometry::GetLocation) + .def_property_readonly("name",&Geometry::GetName) + .def_property("placement",&Geometry::GetPlacement, &Geometry::SetPlacement) + .def("ComputeIntersections",&Geometry::ComputeIntersections) + .def("create",&Geometry::create); + + // data structs in Geometry class + + class_(m, "Intersection") + .def_readwrite("distance", &Geometry::Intersection::distance) + .def_readwrite("hierarchy", &Geometry::Intersection::hierarchy) + .def_readwrite("entering", &Geometry::Intersection::entering) + .def_readwrite("matID", &Geometry::Intersection::matID) + .def_readwrite("position", &Geometry::Intersection::position); + + class_(m, "IntersectionList") + .def_readwrite("position", &Geometry::IntersectionList::position) + .def_readwrite("direction", &Geometry::IntersectionList::direction) + .def_readwrite("intersections", &Geometry::IntersectionList::intersections); + + // ExtrPoly + + class_(m, "ZSection") + .def(init<>()) + .def(init()) + .def_readwrite("zpos", &ExtrPoly::ZSection::zpos) + .def_readwrite("scale", &ExtrPoly::ZSection::scale) + .def_readwrite("offset", &ExtrPoly::ZSection::offset); + + class_(m, "plane") + .def_readwrite("a", &ExtrPoly::plane::a) + .def_readwrite("b", &ExtrPoly::plane::b) + .def_readwrite("c", &ExtrPoly::plane::c) + .def_readwrite("d", &ExtrPoly::plane::d); + + class_, Geometry>(m, "ExtrPoly") + .def(init<>()) + .def(init>&, + const std::vector&>()) + .def(init>&, + const std::vector&>()) + .def(init()) + .def(init()) + .def_property("polygon",&ExtrPoly::GetPolygon, &ExtrPoly::SetPolygon) + .def_property("zsections",&ExtrPoly::GetZSections, &ExtrPoly::SetZSections) + .def("ComputeLateralPlanes",&ExtrPoly::ComputeLateralPlanes); + + // Box + + class_, Geometry>(m, "Box") + .def(init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def_property("X",&Box::GetX, &Box::SetX) + .def_property("Y",&Box::GetY, &Box::SetY) + .def_property("Z",&Box::GetZ, &Box::SetZ); + + // Cylinder + + class_, Geometry>(m, "Cylinder") + .def(init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def_property("InnerRadius",&Cylinder::GetInnerRadius, &Cylinder::SetInnerRadius) + .def_property("Radius",&Cylinder::GetRadius, &Cylinder::SetRadius) + .def_property("Z",&Cylinder::GetZ, &Cylinder::SetZ); + + // Sphere + + class_, Geometry>(m, "Sphere") + .def(init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def_property("InnerRadius",&Sphere::GetInnerRadius, &Sphere::SetInnerRadius) + .def_property("Radius",&Sphere::GetRadius, &Sphere::SetRadius); + + class_>(m, "Placement") + .def(init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def_property("Position", &Placement::GetPosition, &Placement::SetPosition) + .def_property("Quaternion", &Placement::GetQuaternion, &Placement::SetQuaternion); } diff --git a/projects/geometry/public/LeptonInjector/geometry/Box.h b/projects/geometry/public/LeptonInjector/geometry/Box.h index 8393f094..fb2e23b6 100644 --- a/projects/geometry/public/LeptonInjector/geometry/Box.h +++ b/projects/geometry/public/LeptonInjector/geometry/Box.h @@ -2,12 +2,12 @@ #ifndef LI_Box_H #define LI_Box_H -#include -#include #include #include -#include +#include +#include #include +#include #include #include diff --git a/projects/geometry/public/LeptonInjector/geometry/Cylinder.h b/projects/geometry/public/LeptonInjector/geometry/Cylinder.h index 03358075..29c1d9d3 100644 --- a/projects/geometry/public/LeptonInjector/geometry/Cylinder.h +++ b/projects/geometry/public/LeptonInjector/geometry/Cylinder.h @@ -2,12 +2,12 @@ #ifndef LI_Cylinder_H #define LI_Cylinder_H -#include -#include #include #include -#include +#include +#include #include +#include #include #include diff --git a/projects/geometry/public/LeptonInjector/geometry/ExtrPoly.h b/projects/geometry/public/LeptonInjector/geometry/ExtrPoly.h index 860b6f1d..946fedc7 100644 --- a/projects/geometry/public/LeptonInjector/geometry/ExtrPoly.h +++ b/projects/geometry/public/LeptonInjector/geometry/ExtrPoly.h @@ -2,12 +2,14 @@ #ifndef LI_ExtrPoly_H #define LI_ExtrPoly_H -#include +#include +#include #include #include -#include -#include +#include +#include #include +#include #include #include diff --git a/projects/geometry/public/LeptonInjector/geometry/Geometry.h b/projects/geometry/public/LeptonInjector/geometry/Geometry.h index 92b1dcf7..c11d638d 100644 --- a/projects/geometry/public/LeptonInjector/geometry/Geometry.h +++ b/projects/geometry/public/LeptonInjector/geometry/Geometry.h @@ -30,11 +30,14 @@ #ifndef LI_Geometry_H #define LI_Geometry_H -#include -#include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/projects/geometry/public/LeptonInjector/geometry/GeometryMesh.h b/projects/geometry/public/LeptonInjector/geometry/GeometryMesh.h index 64b2a12f..89ef94a0 100644 --- a/projects/geometry/public/LeptonInjector/geometry/GeometryMesh.h +++ b/projects/geometry/public/LeptonInjector/geometry/GeometryMesh.h @@ -2,11 +2,12 @@ #ifndef LI_GeometryMesh_H #define LI_GeometryMesh_H -#include -#include #include -#include -#include +#include +#include +#include +#include +#include #include #include diff --git a/projects/geometry/public/LeptonInjector/geometry/MeshBuilder.h b/projects/geometry/public/LeptonInjector/geometry/MeshBuilder.h index 9f8ff5a3..5e26ea4e 100644 --- a/projects/geometry/public/LeptonInjector/geometry/MeshBuilder.h +++ b/projects/geometry/public/LeptonInjector/geometry/MeshBuilder.h @@ -2,11 +2,12 @@ #ifndef LI_MeshBuilder_H #define LI_MeshBuilder_H -#include +#include #include +#include +#include #include -#include -#include +#include #include #include @@ -18,6 +19,7 @@ #include #include #include + #include "LeptonInjector/serialization/array.h" namespace LI { diff --git a/projects/geometry/public/LeptonInjector/geometry/Placement.h b/projects/geometry/public/LeptonInjector/geometry/Placement.h index bc3a5cf1..c6a320ac 100644 --- a/projects/geometry/public/LeptonInjector/geometry/Placement.h +++ b/projects/geometry/public/LeptonInjector/geometry/Placement.h @@ -3,7 +3,9 @@ #define LI_Placement_H #include +#include #include +#include #include #include diff --git a/projects/geometry/public/LeptonInjector/geometry/Sphere.h b/projects/geometry/public/LeptonInjector/geometry/Sphere.h index 9dcd4757..cf8859ac 100644 --- a/projects/geometry/public/LeptonInjector/geometry/Sphere.h +++ b/projects/geometry/public/LeptonInjector/geometry/Sphere.h @@ -2,12 +2,12 @@ #ifndef LI_Sphere_H #define LI_Sphere_H -#include #include #include -#include -#include +#include +#include #include +#include #include #include diff --git a/projects/injection/CMakeLists.txt b/projects/injection/CMakeLists.txt index 34b346c4..c42d3311 100644 --- a/projects/injection/CMakeLists.txt +++ b/projects/injection/CMakeLists.txt @@ -14,26 +14,24 @@ LIST (APPEND injection_SOURCES add_library(LI_injection OBJECT ${injection_SOURCES}) set_property(TARGET LI_injection PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_injection PUBLIC - ${PROJECT_SOURCE_DIR}/projects/injection/public/ + $ + $ ) -add_dependencies(LI_injection rk) -add_dependencies(LI_injection LI_serialization LI_utilities LI_math LI_dataclasses LI_geometry LI_detector LI_crosssections LI_distributions) -target_link_libraries(LI_injection photospline) -target_link_libraries(LI_injection rk) - -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/extern/rk/include) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/utilities/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/math/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/dataclasses/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/geometry/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/detector/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/crosssections/public/) -target_include_directories(LI_injection PUBLIC ${PROJECT_SOURCE_DIR}/projects/distributions/public/) - -install(TARGETS LI_injection - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +target_link_libraries(LI_injection + PRIVATE + $ + PUBLIC + photospline + LI_serialization + LI_utilities + LI_math + LI_dataclasses + LI_geometry + LI_detector + LI_crosssections + LI_distributions +) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/injection/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} diff --git a/projects/injection/private/ColumnDepthLeptonInjector.cxx b/projects/injection/private/ColumnDepthLeptonInjector.cxx index bc9e74c3..236b4e3b 100644 --- a/projects/injection/private/ColumnDepthLeptonInjector.cxx +++ b/projects/injection/private/ColumnDepthLeptonInjector.cxx @@ -1,13 +1,20 @@ -#include +#include "LeptonInjector/injection/ColumnDepthLeptonInjector.h" + #include #include -#include #include +#include +#include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h" +#include "LeptonInjector/injection/InjectorBase.h" +#include "LeptonInjector/injection/Process.h" #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/injection/InjectorBase.h" -#include "LeptonInjector/injection/ColumnDepthLeptonInjector.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class DepthFunction; } } namespace LI { namespace injection { diff --git a/projects/injection/private/CylinderVolumeLeptonInjector.cxx b/projects/injection/private/CylinderVolumeLeptonInjector.cxx index 9978be63..cc133b9b 100644 --- a/projects/injection/private/CylinderVolumeLeptonInjector.cxx +++ b/projects/injection/private/CylinderVolumeLeptonInjector.cxx @@ -1,13 +1,15 @@ -#include -#include +#include "LeptonInjector/injection/CylinderVolumeLeptonInjector.h" + #include -#include #include +#include "LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h" +#include "LeptonInjector/injection/InjectorBase.h" +#include "LeptonInjector/injection/Process.h" #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/injection/InjectorBase.h" -#include "LeptonInjector/injection/CylinderVolumeLeptonInjector.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace injection { diff --git a/projects/injection/private/DecayRangeLeptonInjector.cxx b/projects/injection/private/DecayRangeLeptonInjector.cxx index b440b9e1..0da74f47 100644 --- a/projects/injection/private/DecayRangeLeptonInjector.cxx +++ b/projects/injection/private/DecayRangeLeptonInjector.cxx @@ -1,13 +1,19 @@ -#include +#include "LeptonInjector/injection/DecayRangeLeptonInjector.h" + #include #include -#include #include +#include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" +#include "LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h" +#include "LeptonInjector/injection/InjectorBase.h" +#include "LeptonInjector/injection/Process.h" #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/injection/InjectorBase.h" -#include "LeptonInjector/injection/DecayRangeLeptonInjector.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace injection { diff --git a/projects/injection/private/InjectorBase.cxx b/projects/injection/private/InjectorBase.cxx index 0dc3665a..91255b23 100644 --- a/projects/injection/private/InjectorBase.cxx +++ b/projects/injection/private/InjectorBase.cxx @@ -1,31 +1,32 @@ -#include -#include +#include "LeptonInjector/injection/InjectorBase.h" + +#include +#include +#include #include #include -#include "LeptonInjector/detector/Path.h" -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - #include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include "LeptonInjector/crosssections/Decay.h" +#include "LeptonInjector/dataclasses/DecayRecord.h" +#include "LeptonInjector/dataclasses/DecaySignature.h" #include "LeptonInjector/dataclasses/InteractionSignature.h" - -#include "LeptonInjector/utilities/Random.h" -#include "LeptonInjector/injection/Weighter.h" +#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/detector/MaterialModel.h" +#include "LeptonInjector/detector/Path.h" #include "LeptonInjector/distributions/Distributions.h" #include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" - -// For CrossSectionProbability +#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/geometry/Geometry.h" +#include "LeptonInjector/injection/Process.h" #include "LeptonInjector/injection/WeightingUtils.h" - -#include "LeptonInjector/injection/InjectorBase.h" - +#include "LeptonInjector/math/Vector3D.h" +#include "LeptonInjector/utilities/Constants.h" #include "LeptonInjector/utilities/Errors.h" - -#include "LeptonInjector/injection/Process.h" -#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/utilities/Random.h" namespace LI { namespace injection { diff --git a/projects/injection/private/Process.cxx b/projects/injection/private/Process.cxx index 79d65cb5..757f6ba4 100644 --- a/projects/injection/private/Process.cxx +++ b/projects/injection/private/Process.cxx @@ -1,5 +1,7 @@ #include "LeptonInjector/injection/Process.h" +#include + namespace LI { namespace injection { diff --git a/projects/injection/private/RangedLeptonInjector.cxx b/projects/injection/private/RangedLeptonInjector.cxx index 453e2652..22b7a0fe 100644 --- a/projects/injection/private/RangedLeptonInjector.cxx +++ b/projects/injection/private/RangedLeptonInjector.cxx @@ -1,13 +1,19 @@ -#include +#include "LeptonInjector/injection/RangedLeptonInjector.h" + #include #include -#include #include +#include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" +#include "LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h" +#include "LeptonInjector/injection/InjectorBase.h" +#include "LeptonInjector/injection/Process.h" #include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/injection/InjectorBase.h" -#include "LeptonInjector/injection/RangedLeptonInjector.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace injection { diff --git a/projects/injection/private/TreeWeighter.cxx b/projects/injection/private/TreeWeighter.cxx index a2d35897..09f786d4 100644 --- a/projects/injection/private/TreeWeighter.cxx +++ b/projects/injection/private/TreeWeighter.cxx @@ -1,10 +1,30 @@ +#include "LeptonInjector/injection/TreeWeighter.h" + +#include // for ite... +#include // for array +#include // for assert +#include // for exp +#include // for ini... +#include // for ope... +#include // for set +#include // for out... +#include "LeptonInjector/crosssections/CrossSection.h" // for Cro... +#include "LeptonInjector/crosssections/CrossSectionCollection.h" // for Cro... +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Int... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Int... +#include "LeptonInjector/detector/EarthModel.h" // for Ear... +#include "LeptonInjector/distributions/Distributions.h" // for Inj... +#include "LeptonInjector/geometry/Geometry.h" // for Geo... +#include "LeptonInjector/injection/InjectorBase.h" // for Inj... +#include "LeptonInjector/injection/Process.h" // for Phy... +#include "LeptonInjector/injection/WeightingUtils.h" // for Cro... +#include "LeptonInjector/math/Vector3D.h" // for Vec... + #include #include #include #include -#include "LeptonInjector/injection/TreeWeighter.h" - #include "LeptonInjector/injection/InjectorBase.h" #include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" @@ -152,6 +172,15 @@ LeptonTreeWeighter::LeptonTreeWeighter(std::vector Initialize(); } +LeptonTreeWeighter::LeptonTreeWeighter(std::vector> injectors, std::shared_ptr earth_model, std::shared_ptr primary_physical_process) + : injectors(injectors) + , earth_model(earth_model) + , primary_physical_process(primary_physical_process) + , secondary_physical_processes(std::vector>()) +{ + Initialize(); +} + //--------------- // class LeptonProcessWeighter //--------------- diff --git a/projects/injection/private/Weighter.cxx b/projects/injection/private/Weighter.cxx index 405180dc..9df94d6f 100644 --- a/projects/injection/private/Weighter.cxx +++ b/projects/injection/private/Weighter.cxx @@ -1,20 +1,28 @@ +#include "LeptonInjector/injection/Weighter.h" + +#include +#include +#include #include #include -#include +#include +#include #include - -#include "LeptonInjector/injection/Weighter.h" - -#include "LeptonInjector/injection/InjectorBase.h" - -#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include +#include #include "LeptonInjector/crosssections/CrossSection.h" #include "LeptonInjector/crosssections/CrossSectionCollection.h" - +#include "LeptonInjector/dataclasses/InteractionRecord.h" #include "LeptonInjector/dataclasses/InteractionSignature.h" - -#include +#include "LeptonInjector/dataclasses/Particle.h" +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/Distributions.h" +#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" +#include "LeptonInjector/geometry/Geometry.h" +#include "LeptonInjector/injection/InjectorBase.h" +#include "LeptonInjector/injection/WeightingUtils.h" +#include "LeptonInjector/math/Vector3D.h" namespace LI { namespace injection { diff --git a/projects/injection/private/WeightingUtils.cxx b/projects/injection/private/WeightingUtils.cxx index 8acf2e94..fee9e5fa 100644 --- a/projects/injection/private/WeightingUtils.cxx +++ b/projects/injection/private/WeightingUtils.cxx @@ -1,16 +1,19 @@ -#include -#include -#include -#include +#include "LeptonInjector/injection/WeightingUtils.h" -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/crosssections/CrossSectionCollection.h" -#include "LeptonInjector/detector/EarthModel.h" -#include "LeptonInjector/geometry/Geometry.h" -#include "LeptonInjector/utilities/Constants.h" +#include // for set +#include // for array +#include // for vector + +#include "LeptonInjector/crosssections/CrossSection.h" // for Cro... +#include "LeptonInjector/crosssections/CrossSectionCollection.h" // for Cro... +#include "LeptonInjector/crosssections/Decay.h" // for Decay +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Int... +#include "LeptonInjector/dataclasses/InteractionSignature.h" // for Int... +#include "LeptonInjector/dataclasses/Particle.h" // for Par... +#include "LeptonInjector/detector/EarthModel.h" // for Ear... +#include "LeptonInjector/geometry/Geometry.h" // for Geo... +#include "LeptonInjector/math/Vector3D.h" // for Vec... +#include "LeptonInjector/utilities/Constants.h" // for cm namespace LI { namespace injection { diff --git a/projects/injection/private/pybindings/injection.cxx b/projects/injection/private/pybindings/injection.cxx index 196a9712..0af2edbf 100644 --- a/projects/injection/private/pybindings/injection.cxx +++ b/projects/injection/private/pybindings/injection.cxx @@ -10,6 +10,7 @@ #include "../../public/LeptonInjector/injection/TreeWeighter.h" #include "../../public/LeptonInjector/injection/Weighter.h" +#include "../../../distributions/public/LeptonInjector/distributions/primary/vertex/DepthFunction.h" #include "../../../utilities/public/LeptonInjector/utilities/Random.h" #include "../../../detector/public/LeptonInjector/detector/EarthModel.h" #include "../../../crosssections/public/LeptonInjector/crosssections/CrossSectionCollection.h" @@ -75,7 +76,8 @@ PYBIND11_MODULE(injection,m) { class_, InjectorBase>(m, "ColumnDepthLeptonInjector") .def(init, std::shared_ptr, std::vector>, std::shared_ptr, std::shared_ptr, double, double>()) - .def("Name",&ColumnDepthLeptonInjector::Name); + .def("Name",&ColumnDepthLeptonInjector::Name) + .def("InjectionBounds",&ColumnDepthLeptonInjector::InjectionBounds); class_, InjectorBase>(m, "CylinderVolumeLeptonInjector") .def(init, std::shared_ptr, std::vector>, std::shared_ptr, LI::geometry::Cylinder>()) @@ -85,7 +87,7 @@ PYBIND11_MODULE(injection,m) { class_>(m, "LeptonProcessWeighter") .def(init, std::shared_ptr, std::shared_ptr>()) - //.def("InteractionProbability",&LeptonProcessWeighter::InteractionProbability) + .def("InteractionProbability",&LeptonProcessWeighter::InteractionProbability) .def("NormalizedPositionProbability",&LeptonProcessWeighter::NormalizedPositionProbability) .def("PhysicalProbability",&LeptonProcessWeighter::PhysicalProbability) .def("GenerationProbability",&LeptonProcessWeighter::GenerationProbability) @@ -93,6 +95,7 @@ PYBIND11_MODULE(injection,m) { class_>(m, "LeptonTreeWeighter") .def(init>, std::shared_ptr, std::shared_ptr, std::vector>>()) + .def(init>, std::shared_ptr, std::shared_ptr>()) .def("EventWeight",&LeptonTreeWeighter::EventWeight); class_>(m, "LeptonWeighter") diff --git a/projects/injection/private/test/CCM_HNL_TEST.cxx b/projects/injection/private/test/CCM_HNL_TEST.cxx index fa2aadee..c3856541 100644 --- a/projects/injection/private/test/CCM_HNL_TEST.cxx +++ b/projects/injection/private/test/CCM_HNL_TEST.cxx @@ -16,6 +16,7 @@ #include "LeptonInjector/utilities/Constants.h" #include "LeptonInjector/dataclasses/Particle.h" #include "LeptonInjector/injection/InjectorBase.h" +#include "LeptonInjector/injection/Process.h" #include "LeptonInjector/injection/RangedLeptonInjector.h" #include "LeptonInjector/injection/TreeWeighter.h" #include "LeptonInjector/geometry/Geometry.h" @@ -29,6 +30,8 @@ #include "LeptonInjector/distributions/primary/direction/IsotropicDirection.h" #include "LeptonInjector/distributions/primary/vertex/PointSourcePositionDistribution.h" #include "LeptonInjector/distributions/primary/vertex/SecondaryPositionDistribution.h" +#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" +#include "LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h" #include "LeptonInjector/crosssections/CrossSectionCollection.h" #include "LeptonInjector/crosssections/CrossSection.h" diff --git a/projects/injection/public/LeptonInjector/injection/ColumnDepthLeptonInjector.h b/projects/injection/public/LeptonInjector/injection/ColumnDepthLeptonInjector.h index 5e15ac2b..3acc1f26 100644 --- a/projects/injection/public/LeptonInjector/injection/ColumnDepthLeptonInjector.h +++ b/projects/injection/public/LeptonInjector/injection/ColumnDepthLeptonInjector.h @@ -4,9 +4,10 @@ #include #include -#include +#include // for vector #include -#include +#include // for uint32_t +#include // for runtime_error #include #include @@ -19,31 +20,20 @@ #include #include -#include "LeptonInjector/detector/EarthModel.h" - #include "LeptonInjector/crosssections/CrossSection.h" - -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/type/PrimaryInjector.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" +#include "LeptonInjector/crosssections/Decay.h" +#include "LeptonInjector/detector/EarthModel.h" #include "LeptonInjector/distributions/primary/vertex/ColumnDepthPositionDistribution.h" -#include "LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h" +#include "LeptonInjector/distributions/primary/vertex/DepthFunction.h" +#include "LeptonInjector/injection/InjectorBase.h" // for InjectorBase -#include "LeptonInjector/injection/InjectorBase.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace injection { struct InjectionProcess; } } +namespace LI { namespace math { class Vector3D; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { -namespace math { -class Vector3D; -} - -namespace utilities { -class LI_random; -} - namespace injection { class ColumnDepthLeptonInjector : public InjectorBase { diff --git a/projects/injection/public/LeptonInjector/injection/CylinderVolumeLeptonInjector.h b/projects/injection/public/LeptonInjector/injection/CylinderVolumeLeptonInjector.h index d09d8a41..5c3c9b23 100644 --- a/projects/injection/public/LeptonInjector/injection/CylinderVolumeLeptonInjector.h +++ b/projects/injection/public/LeptonInjector/injection/CylinderVolumeLeptonInjector.h @@ -5,8 +5,9 @@ #include #include #include +#include // for uint32_t #include -#include +#include // for runtime_error #include #include @@ -19,21 +20,18 @@ #include #include -#include "LeptonInjector/detector/EarthModel.h" - +#include "LeptonInjector/crosssections/CrossSectionCollection.h" #include "LeptonInjector/crosssections/CrossSection.h" - -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/type/PrimaryInjector.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" +#include "LeptonInjector/crosssections/Decay.h" +#include "LeptonInjector/detector/EarthModel.h" #include "LeptonInjector/distributions/primary/vertex/CylinderVolumePositionDistribution.h" -#include "LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h" +#include "LeptonInjector/geometry/Cylinder.h" // for Cylinder +#include "LeptonInjector/injection/InjectorBase.h" // for InjectorBase -#include "LeptonInjector/injection/InjectorBase.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace injection { struct InjectionProcess; } } +namespace LI { namespace math { class Vector3D; } } // lines 40-40 +namespace LI { namespace utilities { class LI_random; } } // lines 44-44 namespace LI { namespace math { diff --git a/projects/injection/public/LeptonInjector/injection/DecayRangeLeptonInjector.h b/projects/injection/public/LeptonInjector/injection/DecayRangeLeptonInjector.h index c768894e..3d5cee7e 100644 --- a/projects/injection/public/LeptonInjector/injection/DecayRangeLeptonInjector.h +++ b/projects/injection/public/LeptonInjector/injection/DecayRangeLeptonInjector.h @@ -5,8 +5,9 @@ #include #include #include +#include // for uint32_t #include -#include +#include // for runtime_error #include #include @@ -19,31 +20,20 @@ #include #include -#include "LeptonInjector/detector/EarthModel.h" - +#include "LeptonInjector/crosssections/CrossSectionCollection.h" #include "LeptonInjector/crosssections/CrossSection.h" - -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/type/PrimaryInjector.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" +#include "LeptonInjector/crosssections/Decay.h" +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/primary/vertex/DecayRangeFunction.h" #include "LeptonInjector/distributions/primary/vertex/DecayRangePositionDistribution.h" -#include "LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h" +#include "LeptonInjector/injection/InjectorBase.h" // for InjectorBase -#include "LeptonInjector/injection/InjectorBase.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace injection { struct InjectionProcess; } } +namespace LI { namespace math { class Vector3D; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { -namespace math { -class Vector3D; -} - -namespace utilities { -class LI_random; -} - namespace injection { class DecayRangeLeptonInjector : public InjectorBase { diff --git a/projects/injection/public/LeptonInjector/injection/InjectorBase.h b/projects/injection/public/LeptonInjector/injection/InjectorBase.h index 0dde250e..559013c2 100644 --- a/projects/injection/public/LeptonInjector/injection/InjectorBase.h +++ b/projects/injection/public/LeptonInjector/injection/InjectorBase.h @@ -2,11 +2,17 @@ #ifndef LI_LeptonInjector_H #define LI_LeptonInjector_H -#include +#include // for map +#include // for set #include -#include +#include +#include // for vector +#include // for uint32_t #include -#include +#include // for NULL +#include // for runtime_error +#include +#include // for make_nvp #include #include @@ -20,32 +26,21 @@ #include #include -#include "LeptonInjector/serialization/array.h" - -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/crosssections/CrossSection.h" -#include "LeptonInjector/crosssections/CrossSectionCollection.h" +#include "LeptonInjector/dataclasses/InteractionRecord.h" // for Interactio... +#include "LeptonInjector/dataclasses/InteractionTree.h" // for Interactio... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -#include "LeptonInjector/dataclasses/InteractionRecord.h" -#include "LeptonInjector/dataclasses/DecayRecord.h" -#include "LeptonInjector/dataclasses/Particle.h" -#include "LeptonInjector/injection/Process.h" -#include "LeptonInjector/dataclasses/InteractionTree.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/vertex/VertexPositionDistribution.h" -#include "LeptonInjector/distributions/primary/type/PrimaryInjector.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct DecayRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class VertexPositionDistribution; } } +namespace LI { namespace geometry { class Geometry; } } +namespace LI { namespace injection { struct InjectionProcess; } } +namespace LI { namespace math { class Vector3D; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { -namespace math { -class Vector3D; -} - -namespace utilities { -class LI_random; -} - namespace injection { class InjectorBase { diff --git a/projects/injection/public/LeptonInjector/injection/Process.h b/projects/injection/public/LeptonInjector/injection/Process.h index 4e941acc..bcaedbc1 100644 --- a/projects/injection/public/LeptonInjector/injection/Process.h +++ b/projects/injection/public/LeptonInjector/injection/Process.h @@ -2,8 +2,10 @@ #ifndef LI_Process_H #define LI_Process_H -#include -#include +#include // for shared_ptr +#include // for vector +#include // for uint32_t +#include // for runtime_error #include #include @@ -14,12 +16,10 @@ #include #include -#include "LeptonInjector/serialization/array.h" +#include "LeptonInjector/dataclasses/Particle.h" // for Particle +#include "LeptonInjector/distributions/Distributions.h" // for InjectionDis... -#include "LeptonInjector/dataclasses/InteractionSignature.h" -#include "LeptonInjector/dataclasses/InteractionTree.h" -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/crosssections/CrossSection.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } namespace LI { namespace injection { diff --git a/projects/injection/public/LeptonInjector/injection/RangedLeptonInjector.h b/projects/injection/public/LeptonInjector/injection/RangedLeptonInjector.h index faf70549..956b4ea5 100644 --- a/projects/injection/public/LeptonInjector/injection/RangedLeptonInjector.h +++ b/projects/injection/public/LeptonInjector/injection/RangedLeptonInjector.h @@ -2,12 +2,12 @@ #ifndef LI_RangedLeptonInjector_H #define LI_RangedLeptonInjector_H -#include #include #include #include +#include // for uint32_t #include -#include +#include // for runtime_error #include #include @@ -18,31 +18,20 @@ #include #include -#include "LeptonInjector/detector/EarthModel.h" - +#include "LeptonInjector/crosssections/CrossSectionCollection.h" #include "LeptonInjector/crosssections/CrossSection.h" - -#include "LeptonInjector/dataclasses/InteractionRecord.h" - -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/distributions/primary/type/PrimaryInjector.h" -#include "LeptonInjector/distributions/primary/energy/PrimaryEnergyDistribution.h" -#include "LeptonInjector/distributions/primary/direction/PrimaryDirectionDistribution.h" -#include "LeptonInjector/distributions/primary/helicity/PrimaryNeutrinoHelicityDistribution.h" +#include "LeptonInjector/crosssections/Decay.h" +#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/distributions/primary/vertex/RangeFunction.h" #include "LeptonInjector/distributions/primary/vertex/RangePositionDistribution.h" -#include "LeptonInjector/distributions/target/momentum/TargetMomentumDistribution.h" +#include "LeptonInjector/injection/InjectorBase.h" // for InjectorBase -#include "LeptonInjector/injection/InjectorBase.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace injection { struct InjectionProcess; } } +namespace LI { namespace math { class Vector3D; } } +namespace LI { namespace utilities { class LI_random; } } namespace LI { -namespace math { -class Vector3D; -} - -namespace utilities { -class LI_random; -} - namespace injection { class RangedLeptonInjector : public InjectorBase { diff --git a/projects/injection/public/LeptonInjector/injection/TreeWeighter.h b/projects/injection/public/LeptonInjector/injection/TreeWeighter.h index 45d956f4..359817bc 100644 --- a/projects/injection/public/LeptonInjector/injection/TreeWeighter.h +++ b/projects/injection/public/LeptonInjector/injection/TreeWeighter.h @@ -2,13 +2,10 @@ #ifndef LI_TreeWeighter_H #define LI_TreeWeighter_H -#include -#include // adds shared pointer -#include - -#include -#include -#include +#include // for map +#include // for shared_ptr +#include // for vector +#include // for pair #include #include @@ -18,17 +15,17 @@ #include #include -#include "LeptonInjector/math/Coordinates.h" -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/injection/InjectorBase.h" -#include "LeptonInjector/injection/WeightingUtils.h" - -#include "LeptonInjector/crosssections/CrossSectionCollection.h" - -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" +#include "LeptonInjector/dataclasses/InteractionTree.h" // for InteractionT... +#include "LeptonInjector/dataclasses/Particle.h" // for Particle -#include "LeptonInjector/injection/Process.h" +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class InjectionDistribution; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace injection { class InjectorBase; } } +namespace LI { namespace injection { struct InjectionProcess; } } +namespace LI { namespace injection { struct PhysicalProcess; } } +namespace LI { namespace math { class Vector3D; } } namespace LI { namespace injection { @@ -76,6 +73,7 @@ class LeptonTreeWeighter { public: double EventWeight(LI::dataclasses::InteractionTree const & tree) const; LeptonTreeWeighter(std::vector> injectors, std::shared_ptr earth_model, std::shared_ptr primary_physical_process, std::vector> secondary_physical_processes); + LeptonTreeWeighter(std::vector> injectors, std::shared_ptr earth_model, std::shared_ptr primary_physical_process); }; // LeptonTreeWeighter diff --git a/projects/injection/public/LeptonInjector/injection/Weighter.h b/projects/injection/public/LeptonInjector/injection/Weighter.h index a7ad97aa..a5c459ee 100644 --- a/projects/injection/public/LeptonInjector/injection/Weighter.h +++ b/projects/injection/public/LeptonInjector/injection/Weighter.h @@ -2,13 +2,10 @@ #ifndef LI_Weighter_H #define LI_Weighter_H -#include -#include // adds shared pointer -#include - -#include -#include -#include +#include // for tuple +#include // for shared_ptr +#include // for vector +#include // for pair #include #include @@ -18,22 +15,16 @@ #include #include -#include "LeptonInjector/math/Coordinates.h" -#include "LeptonInjector/distributions/Distributions.h" -#include "LeptonInjector/injection/InjectorBase.h" -#include "LeptonInjector/injection/WeightingUtils.h" - -#include "LeptonInjector/crosssections/CrossSectionCollection.h" - -#include "LeptonInjector/math/Vector3D.h" -#include "LeptonInjector/detector/EarthModel.h" - -#include "LeptonInjector/injection/Process.h" +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } +namespace LI { namespace distributions { class WeightableDistribution; } } +namespace LI { namespace injection { class InjectorBase; } } +namespace LI { namespace math { class Vector3D; } } namespace LI { namespace injection { - class LeptonWeighter { private: std::vector> injectors; diff --git a/projects/injection/public/LeptonInjector/injection/WeightingUtils.h b/projects/injection/public/LeptonInjector/injection/WeightingUtils.h index 829e428b..3af6e665 100644 --- a/projects/injection/public/LeptonInjector/injection/WeightingUtils.h +++ b/projects/injection/public/LeptonInjector/injection/WeightingUtils.h @@ -2,6 +2,11 @@ #ifndef LI_WeightingUtils_H #define LI_WeightingUtils_H +#include // for shared_ptr + +namespace LI { namespace crosssections { class CrossSectionCollection; } } +namespace LI { namespace dataclasses { struct InteractionRecord; } } +namespace LI { namespace detector { class EarthModel; } } namespace LI { namespace injection { diff --git a/projects/math/CMakeLists.txt b/projects/math/CMakeLists.txt index 86866999..9796e2c7 100644 --- a/projects/math/CMakeLists.txt +++ b/projects/math/CMakeLists.txt @@ -11,33 +11,32 @@ LIST (APPEND math_SOURCES add_library(LI_math OBJECT ${math_SOURCES}) set_property(TARGET LI_math PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_math PUBLIC - ${PROJECT_SOURCE_DIR}/projects/math/public/ + $ + $ ) -add_dependencies(LI_math rk) -add_dependencies(LI_math LI_serialization) if(${MACOSX}) -target_link_libraries(LI_math PUBLIC - photospline - rk - delabella +target_link_libraries(LI_math + PUBLIC + photospline + delabella_shared + PRIVATE + $ + LI_serialization ) else() -target_link_libraries(LI_math PUBLIC - photospline - rk - -Wl,--whole-archive - delabella - -Wl,--no-whole-archive +target_link_libraries(LI_math + PUBLIC + photospline + delabella_shared + PRIVATE + -Wl,--whole-archive + $ + -Wl,--no-whole-archive + LI_serialization ) endif() -target_include_directories(LI_math PUBLIC ${PROJECT_SOURCE_DIR}/vendor/rk) -target_include_directories(LI_math PUBLIC ${PROJECT_SOURCE_DIR}/projects/serialization/public/) - -install(TARGETS LI_math - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/math/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING diff --git a/projects/math/private/Coordinates.cxx b/projects/math/private/Coordinates.cxx index 0f4a9388..516189f7 100644 --- a/projects/math/private/Coordinates.cxx +++ b/projects/math/private/Coordinates.cxx @@ -1,7 +1,9 @@ +#include "LeptonInjector/math/Coordinates.h" + #include #include -#include //assertions -#include "LeptonInjector/math/Coordinates.h" +#include + #include "LeptonInjector/math/Vector3D.h" namespace LeptonInjector { diff --git a/projects/math/private/EulerAngles.cxx b/projects/math/private/EulerAngles.cxx index 606f3d45..feaa0cac 100644 --- a/projects/math/private/EulerAngles.cxx +++ b/projects/math/private/EulerAngles.cxx @@ -1,10 +1,10 @@ +#include "LeptonInjector/math/EulerAngles.h" -#include -#include - -#include "LeptonInjector/math/Matrix3D.h" +#include +#include +#include -#include "LeptonInjector/math/EulerAngles.h" +#include "LeptonInjector/math/Vector3D.h" using namespace LI::math; diff --git a/projects/math/private/Interpolation.cxx b/projects/math/private/Interpolation.cxx index 0414f2b9..eb981ca5 100644 --- a/projects/math/private/Interpolation.cxx +++ b/projects/math/private/Interpolation.cxx @@ -1,6 +1,8 @@ - #include "LeptonInjector/math/Interpolation.h" +#include +#include + namespace LI { namespace math { diff --git a/projects/math/private/Matrix3D.cxx b/projects/math/private/Matrix3D.cxx index 6fafd653..29757b84 100644 --- a/projects/math/private/Matrix3D.cxx +++ b/projects/math/private/Matrix3D.cxx @@ -1,8 +1,10 @@ +#include "LeptonInjector/math/Matrix3D.h" -#include +#include #include +#include +#include -#include "LeptonInjector/math/Matrix3D.h" #include "LeptonInjector/math/Vector3D.h" using namespace LI::math; diff --git a/projects/math/private/Polynomial.cxx b/projects/math/private/Polynomial.cxx index a1ae488e..e771cc6e 100644 --- a/projects/math/private/Polynomial.cxx +++ b/projects/math/private/Polynomial.cxx @@ -1,9 +1,9 @@ -#include +#include "LeptonInjector/math/Polynomial.h" + #include +#include +#include #include -#include - -#include "LeptonInjector/math/Polynomial.h" // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%% Polynom %%%%%%%%%%%%%%%%%%%% diff --git a/projects/math/private/Quaternion.cxx b/projects/math/private/Quaternion.cxx index 5af2d105..b8173132 100644 --- a/projects/math/private/Quaternion.cxx +++ b/projects/math/private/Quaternion.cxx @@ -1,8 +1,12 @@ +#include "LeptonInjector/math/Quaternion.h" + #include #include -#include +#include #include #include +#include +#include #include "LeptonInjector/math/Matrix3D.h" #include "LeptonInjector/math/Vector3D.h" @@ -10,8 +14,6 @@ #include "LeptonInjector/math/EulerAngles.h" #include "LeptonInjector/math/EulerQuaternionConversions.h" -#include "LeptonInjector/math/Quaternion.h" - using namespace LI::math; //----------------------------------------------------------------------// @@ -65,14 +67,6 @@ Quaternion::Quaternion(Quaternion&& other) : { } -Quaternion::Quaternion(geom3::Rotation3::Quaternion const & q) : - x_(q.v_.x()), - y_(q.v_.y()), - z_(q.v_.z()), - w_(q.s_) -{ -} - // destructor Quaternion::~Quaternion() {} @@ -105,10 +99,6 @@ Quaternion& Quaternion::operator=(Quaternion const && other) { return *this; } -Quaternion::operator geom3::Rotation3::Quaternion() const { - return geom3::Rotation3::Quaternion(x_, y_, z_, w_); -} - bool Quaternion::operator==(const Quaternion& quaternion) const { return (this == &quaternion) or ( @@ -512,10 +502,30 @@ void Quaternion::SetEulerAnglesXYZs(double alpha, double beta, double gamma) Quaternion LI::math::rotation_between(Vector3D const & v0, Vector3D const & v1) { Vector3D dir0 = v0.normalized(); Vector3D dir1 = v1.normalized(); - Vector3D cross = cross_product(dir0, dir1); - Quaternion rot(cross); - rot.SetW(1.0 + scalar_product(dir0, dir1)); - rot.normalize(); - return rot; + double dot = scalar_product(dir0, dir1); + if(dot == -1.0) { + // Special case for 180deg rotation + // Find most perpendicular axis vector + Vector3D vecs[3] = { + Vector3D(1,0,0), + Vector3D(0,1,0), + Vector3D(0,0,1) + }; + double dots[3] = { + std::abs(scalar_product(vecs[0], dir0)), + std::abs(scalar_product(vecs[1], dir0)), + std::abs(scalar_product(vecs[2], dir0)) + }; + // Find axis vector most perpendicular to original direction + size_t idx = std::distance(&(dots), std::min_element(&(dots), &(dots)+3)); + // Initialize quaternion with unit vector perpendicular to original direction and selected axis + return Quaternion(cross_product(vecs[idx], dir0).normalized()); + } else { + Vector3D cross = cross_product(dir0, dir1); + Quaternion rot(cross); + rot.SetW(1.0 + dot); + rot.normalize(); + return rot; + } } diff --git a/projects/math/private/Vector3D.cxx b/projects/math/private/Vector3D.cxx index 06250d14..2f2dc677 100644 --- a/projects/math/private/Vector3D.cxx +++ b/projects/math/private/Vector3D.cxx @@ -1,8 +1,11 @@ -#include -#include - #include "LeptonInjector/math/Vector3D.h" +#include +#include +#include +#include +#include + using namespace LI::math; //----------------------------------------------------------------------// @@ -41,24 +44,6 @@ Vector3D::Vector3D(std::array const & vec) { } -Vector3D::Vector3D(geom3::UnitVector3 const & vec) - : cartesian_(vec.x(), vec.y(), vec.z()) - , spherical_(0,0,0) -{ -} - -Vector3D::Vector3D(geom3::Vector3 const & vec) - : cartesian_(vec.x(), vec.y(), vec.z()) - , spherical_(0,0,0) -{ -} - -Vector3D::Vector3D(geom3::Point3 const & vec) - : cartesian_(vec.x(), vec.y(), vec.z()) - , spherical_(0,0,0) -{ -} - // destructor Vector3D::~Vector3D() {} @@ -91,18 +76,6 @@ Vector3D::operator std::array() const { return std::array{cartesian_.x_, cartesian_.y_, cartesian_.z_}; } -Vector3D::operator geom3::UnitVector3() const { - return geom3::UnitVector3(cartesian_.x_, cartesian_.y_, cartesian_.z_, true); -} - -Vector3D::operator geom3::Vector3() const { - return geom3::Vector3(cartesian_.x_, cartesian_.y_, cartesian_.z_); -} - -Vector3D::operator geom3::Point3() const { - return geom3::Point3(cartesian_.x_, cartesian_.y_, cartesian_.z_); -} - bool Vector3D::operator==(const Vector3D& vector_3d) const { if (cartesian_.x_ != vector_3d.cartesian_.x_) diff --git a/projects/math/private/pybindings/math.cxx b/projects/math/private/pybindings/math.cxx index bcb01cbe..0dac932d 100644 --- a/projects/math/private/pybindings/math.cxx +++ b/projects/math/private/pybindings/math.cxx @@ -1,6 +1,8 @@ #include #include "../../public/LeptonInjector/math/Vector3D.h" +#include "../../public/LeptonInjector/math/Quaternion.h" +#include "../../public/LeptonInjector/math/Matrix3D.h" #include #include @@ -9,34 +11,88 @@ using namespace pybind11; PYBIND11_MODULE(math,m) { - using namespace LI::math; + using namespace LI::math; - class_>(m, "Vector3D") - .def(init<>()) - .def(init()) - .def(init()) - .def(init const &>()) - .def(self + self) - .def(self += self) - .def(self - self) - .def(self -= self) - .def(self * double()) - .def(self *= double()) - .def(double() * self) - .def(self / double()) - .def(self /= double()) - .def("magnitude",&Vector3D::magnitude) - .def("normalize",&Vector3D::normalize) - .def("normalized",&Vector3D::normalized) - .def("deflect",&Vector3D::deflect) - .def("invert",&Vector3D::invert) - .def("inverted",&Vector3D::inverted) - .def("CalculateCartesianFromSpherical",&Vector3D::CalculateCartesianFromSpherical) - .def("CalculateSphericalCoordinates",&Vector3D::CalculateSphericalCoordinates) - .def("GetX",&Vector3D::GetX) - .def("GetY",&Vector3D::GetY) - .def("GetZ",&Vector3D::GetZ) - .def("GetRadius",&Vector3D::GetRadius) - .def("GetPhi",&Vector3D::GetPhi) - .def("GetTheta",&Vector3D::GetTheta); + class_>(m, "Vector3D") + .def(init<>()) + .def(init()) + .def(init()) + .def(init const &>()) + .def(self == self) + .def(self != self) + .def(self < self) + .def(self + self) + .def(self += self) + .def(self - self) + .def(self -= self) + .def(self * double()) + .def(self *= double()) + .def(double() * self) + .def(self / double()) + .def(self /= double()) + .def("magnitude",&Vector3D::magnitude) + .def("normalize",&Vector3D::normalize) + .def("normalized",&Vector3D::normalized) + .def("deflect",&Vector3D::deflect) + .def("invert",&Vector3D::invert) + .def("inverted",&Vector3D::inverted) + .def("CalculateCartesianFromSpherical",&Vector3D::CalculateCartesianFromSpherical) + .def("CalculateSphericalCoordinates",&Vector3D::CalculateSphericalCoordinates) + .def("GetX",&Vector3D::GetX) + .def("GetY",&Vector3D::GetY) + .def("GetZ",&Vector3D::GetZ) + .def("GetRadius",&Vector3D::GetRadius) + .def("GetPhi",&Vector3D::GetPhi) + .def("GetTheta",&Vector3D::GetTheta); + + class_>(m, "Quaternion") + .def(init<>()) + .def(init()) + .def(init()) + .def(init()) + //.def(init()) + .def(self == self) + .def(self != self) + .def(self < self) + .def(self * self) + .def(self *= self) + .def(self * double()) + .def(self *= double()) + .def(self + self) + .def(self += self) + .def(self + double()) + .def(self += double()) + .def("__invert__", [](Quaternion const & q)->Quaternion{return ~q;}) + .def("__not__", [](Quaternion const & q)->Quaternion{return !q;}) + .def("SetPosition", &Quaternion::SetPosition) + .def("GetMatrix", (void (Quaternion::*)(Matrix3D &) const)(&Quaternion::GetMatrix)) + .def("GetMatrix", (Matrix3D (Quaternion::*)( ) const)(&Quaternion::GetMatrix)) + .def("SetMatrix", &Quaternion::SetMatrix) + .def("invert", &Quaternion::invert) + .def("inverted", &Quaternion::inverted) + .def("conjugate", &Quaternion::conjugate) + .def("conjugated", &Quaternion::conjugated) + .def("normalize", &Quaternion::normalize) + .def("normalized", &Quaternion::normalized) + .def("magnitude", &Quaternion::magnitude) + .def("magnitudesq", &Quaternion::magnitudesq) + .def("DotProduct", &Quaternion::DotProduct) + .def("lerp", &Quaternion::lerp) + .def("slerp", &Quaternion::slerp) + .def("SetAxisAngle", &Quaternion::SetAxisAngle) + .def("GetAxisAngle", (void (Quaternion::*)(Vector3D &, double &) const)(&Quaternion::GetAxisAngle)) + .def("GetAxisAngle", (std::tuple (Quaternion::*)()const)(&Quaternion::GetAxisAngle)) + .def("GetEulerAngles", &Quaternion::GetEulerAngles) + .def("GetEulerAnglesZXZr", &Quaternion::GetEulerAnglesZXZr) + .def("GetEulerAnglesXYZs", &Quaternion::GetEulerAnglesXYZs) + .def("SetEulerAngles", &Quaternion::SetEulerAngles) + .def("SetEulerAnglesZXZr", &Quaternion::SetEulerAnglesZXZr) + .def("SetEulerAnglesXYZs", &Quaternion::SetEulerAnglesXYZs) + .def("rotate", (Quaternion (Quaternion::*)(Quaternion const &, bool) const)(&Quaternion::rotate)) + .def("rotate", (Vector3D (Quaternion::*)(Vector3D const &, bool) const)(&Quaternion::rotate)) + .def_property("X", &Quaternion::GetX, &Quaternion::SetX) + .def_property("Y", &Quaternion::GetY, &Quaternion::SetY) + .def_property("Z", &Quaternion::GetZ, &Quaternion::SetZ) + .def_property("W", &Quaternion::GetW, &Quaternion::SetW) + .def_static("rotation_between", [](object, Vector3D const & a, Vector3D const & b)->Quaternion{return rotation_between(a, b);}); } diff --git a/projects/math/public/LeptonInjector/math/EulerAngles.h b/projects/math/public/LeptonInjector/math/EulerAngles.h index 7857922e..0b0b2fd1 100644 --- a/projects/math/public/LeptonInjector/math/EulerAngles.h +++ b/projects/math/public/LeptonInjector/math/EulerAngles.h @@ -2,7 +2,9 @@ #ifndef LI_EulerAngles_H #define LI_EulerAngles_H +#include #include +#include #include #include diff --git a/projects/math/public/LeptonInjector/math/EulerQuaternionConversions.h b/projects/math/public/LeptonInjector/math/EulerQuaternionConversions.h index 2916d0a2..c742eb9c 100644 --- a/projects/math/public/LeptonInjector/math/EulerQuaternionConversions.h +++ b/projects/math/public/LeptonInjector/math/EulerQuaternionConversions.h @@ -2,6 +2,7 @@ #ifndef LI_EulerQuaternionConversions_H #define LI_EulerQuaternionConversions_H +#include #include #include "LeptonInjector/math/Quaternion.h" diff --git a/projects/math/public/LeptonInjector/math/Interpolation.h b/projects/math/public/LeptonInjector/math/Interpolation.h index f114cb4c..de8380cc 100644 --- a/projects/math/public/LeptonInjector/math/Interpolation.h +++ b/projects/math/public/LeptonInjector/math/Interpolation.h @@ -5,10 +5,19 @@ #include #include #include +#include +#include #include #include +#include +#include +#include +#include #include +#include #include +#include +#include #include #include diff --git a/projects/math/public/LeptonInjector/math/Polynomial.h b/projects/math/public/LeptonInjector/math/Polynomial.h index d603bb85..8b1afdc2 100644 --- a/projects/math/public/LeptonInjector/math/Polynomial.h +++ b/projects/math/public/LeptonInjector/math/Polynomial.h @@ -28,9 +28,12 @@ * * ******************************************************************************/ -#include +#include #include +#include #include +#include +#include #include #include diff --git a/projects/math/public/LeptonInjector/math/Quaternion.h b/projects/math/public/LeptonInjector/math/Quaternion.h index 2a6c0510..23272a01 100644 --- a/projects/math/public/LeptonInjector/math/Quaternion.h +++ b/projects/math/public/LeptonInjector/math/Quaternion.h @@ -3,12 +3,10 @@ #define LI_Quaternion_H #include +#include #include #include -#include -#include - #include #include #include @@ -29,7 +27,6 @@ class Quaternion Quaternion(const Quaternion & quaternion); Quaternion(const Vector3D & vec); Quaternion(Quaternion&& other); - Quaternion(geom3::Rotation3::Quaternion const &); ~Quaternion(); void SetPosition(Vector3D const & vec); @@ -69,8 +66,6 @@ class Quaternion Quaternion& operator=(Quaternion const && quaternion); Quaternion& operator=(Quaternion && quaternion); - operator geom3::Rotation3::Quaternion() const; - bool operator==(const Quaternion& quaternion) const; bool operator!=(const Quaternion& quaternion) const; bool operator<(const Quaternion& quaternion) const; diff --git a/projects/math/public/LeptonInjector/math/Vector3D.h b/projects/math/public/LeptonInjector/math/Vector3D.h index 70c528c9..f13ba43b 100644 --- a/projects/math/public/LeptonInjector/math/Vector3D.h +++ b/projects/math/public/LeptonInjector/math/Vector3D.h @@ -26,14 +26,15 @@ #ifndef LI_Vector3D_H #define LI_Vector3D_H +#include +#include #include +#include #include #include #include -#include - namespace LI { namespace math { @@ -48,9 +49,6 @@ class Vector3D Vector3D(const Vector3D& vector_3d); Vector3D(Vector3D&& other); Vector3D(std::array const & vec); - Vector3D(geom3::UnitVector3 const & vec); - Vector3D(geom3::Vector3 const & vec); - Vector3D(geom3::Point3 const & vec); //Vector3D(const nlohmann::json&); ~Vector3D(); @@ -61,9 +59,6 @@ class Vector3D Vector3D& operator=(Vector3D && vector_3d); operator std::array() const; - operator geom3::UnitVector3() const; - operator geom3::Vector3() const; - operator geom3::Point3() const; bool operator==(const Vector3D& vector_3d) const; bool operator!=(const Vector3D& vector_3d) const; diff --git a/projects/serialization/CMakeLists.txt b/projects/serialization/CMakeLists.txt index 56873ac3..ed85bb8c 100644 --- a/projects/serialization/CMakeLists.txt +++ b/projects/serialization/CMakeLists.txt @@ -1,9 +1,11 @@ add_library(LI_serialization INTERFACE) target_include_directories(LI_serialization INTERFACE - ${PROJECT_SOURCE_DIR}/projects/serialization/public/ + $ + $ ) install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/serialization/public/" + EXPORT ${PROJECT_NAME}Config DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" diff --git a/projects/utilities/CMakeLists.txt b/projects/utilities/CMakeLists.txt index 62536f21..9a18a682 100644 --- a/projects/utilities/CMakeLists.txt +++ b/projects/utilities/CMakeLists.txt @@ -7,12 +7,10 @@ LIST (APPEND utilities_SOURCES add_library(LI_utilities OBJECT ${utilities_SOURCES}) set_property(TARGET LI_utilities PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(LI_utilities PUBLIC - ${PROJECT_SOURCE_DIR}/projects/utilities/public/ + $ + $ ) -install(TARGETS LI_utilities - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - install(DIRECTORY "${PROJECT_SOURCE_DIR}/projects/utilities/public/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING diff --git a/projects/utilities/private/Interpolator.cxx b/projects/utilities/private/Interpolator.cxx index 5aecfab2..744981f8 100644 --- a/projects/utilities/private/Interpolator.cxx +++ b/projects/utilities/private/Interpolator.cxx @@ -1,7 +1,8 @@ -#include - #include "LeptonInjector/utilities/Interpolator.h" +#include +#include + using namespace LI::utilities; template<> diff --git a/projects/utilities/private/Random.cxx b/projects/utilities/private/Random.cxx index 54b9865d..44861974 100644 --- a/projects/utilities/private/Random.cxx +++ b/projects/utilities/private/Random.cxx @@ -1,5 +1,8 @@ #include "LeptonInjector/utilities/Random.h" +#include +#include + namespace LI { namespace utilities { diff --git a/projects/utilities/public/LeptonInjector/utilities/Interpolator.h b/projects/utilities/public/LeptonInjector/utilities/Interpolator.h index 85d4208e..7cd11d7e 100644 --- a/projects/utilities/public/LeptonInjector/utilities/Interpolator.h +++ b/projects/utilities/public/LeptonInjector/utilities/Interpolator.h @@ -6,8 +6,11 @@ #include #include #include +#include #include #include +#include +#include #include #include diff --git a/resources/ATLAS_SNe_Injection/Makefile b/resources/ATLAS_SNe_Injection/Makefile new file mode 100644 index 00000000..3cc2a54e --- /dev/null +++ b/resources/ATLAS_SNe_Injection/Makefile @@ -0,0 +1,6 @@ +all: inject_HNLs_CCM + +args=-I/usr/include/hdf5/serial/ -I/n/home01/awen/LeptonInjector/sources/LeptonInjector/vendor/cereal/include/ -I${PREFIX}/include/ -I${PWD}/extern/rk/include/ -I/n/home01/awen/homebrew/opt/cfitsio/include -L/n/home01/awen/homebrew/lib -L${PREFIX}/lib/ -L${PREFIX}/lib/pkgconfig/ -lcfitsio -g -std=c++14 + +inject_HNLs_CCM: + g++ inject_HNLs_CCM.cpp -o inject_HNLs_CCM ${args} diff --git a/resources/ATLAS_SNe_Injection/inject_nu_ATLAS.py b/resources/ATLAS_SNe_Injection/inject_nu_ATLAS.py new file mode 100644 index 00000000..de3514d8 --- /dev/null +++ b/resources/ATLAS_SNe_Injection/inject_nu_ATLAS.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +# Import python libraries +import numpy as np +import matplotlib.pyplot as plt +from scipy.stats import poisson +from scipy.special import erf +import pandas as pd + +# Import the CCM modules +import leptoninjector as LI + +# Make an instance of random for use +random = LI.utilities.LI_random() + + +# ### Define geometry + +# In[2]: + + +# Make the earth model, add ATLAS detector layout and materials file + +materials_file = '../earthparams/materials/ATLAS.dat' +earth_model_file = '../earthparams/densities/PREM_ATLAS.dat' + +earth_model = LI.detector.EarthModel() +earth_model.LoadMaterialModel(materials_file) +earth_model.LoadEarthModel(earth_model_file) + + +# ### Define injection processes + +# In[3]: + + +primary_type = LI.dataclasses.Particle.ParticleType.NuMu + +primary_injection_process = LI.injection.InjectionProcess() +primary_injection_process.primary_type = primary_type + +primary_physical_process = LI.injection.PhysicalProcess() +primary_physical_process.primary_type = primary_type + + +# ### Construct Cross Section Classes + +# In[4]: + + +# DISFromSpline(std::string differential_filename, +# std::string total_filename, +# std::vector primary_types, +# std::vector target_types); + +xsfiledir = '/n/home01/awen/prometheus/resources/cross_section_splines' +target_type = LI.dataclasses.Particle.ParticleType.Nucleon + +DIS_xs = LI.crosssections.DISFromSpline(xsfiledir+'/dsdxdy_nu_CC_iso.fits', + xsfiledir+'/sigma_nu_CC_iso.fits', + [primary_type], + [target_type]) + +primary_xs = LI.crosssections.CrossSectionCollection(primary_type, [DIS_xs]) +primary_injection_process.SetCrossSections(primary_xs) +primary_physical_process.SetCrossSections(primary_xs) + + +# ### Construct Energy Distributions + +# In[5]: + + +#nu_energy = 100 #GeV +#edist = LI.distributions.Monoenergetic(nu_energy) +edist = LI.distributions.TabulatedFluxDistribution(110, int(8e6), '/n/home01/awen/LeptonInjector/Sandbox/flux_2P_D0_1_s20.txt', True) + +primary_injection_process.AddInjectionDistribution(edist) +primary_physical_process.AddPhysicalDistribution(edist) + +#flux_units = LI.distributions.NormalizationConstant(3.76e-2) +# flux_units = LI.distributions.NormalizationConstant(1) +# primary_physical_process.AddPhysicalDistribution(flux_units) + + +# ### Construct Direction Distributions (position of injection, momentum of particle) + +# In[6]: + + +ATLAS_origin = LI.math.Vector3D(0, 0, 6371234) #6371234 #90m below earth surface, ~depth of altas cavern +earth_origin = LI.math.Vector3D(0, 0, 0) + +injection_dir = ATLAS_origin - earth_origin +injection_dir.normalize() +injection_dir = LI.math.Vector3D(0, 1, 0) + +inj_ddist = LI.distributions.FixedDirection(injection_dir) +phys_ddist = LI.distributions.FixedDirection(injection_dir) + +primary_injection_process.AddInjectionDistribution(inj_ddist) +primary_physical_process.AddPhysicalDistribution(phys_ddist) + + +# ### Some other trivial specifications: target at rest, neutrinos, positions + +# In[7]: + + +target_momentum_distribution = LI.distributions.TargetAtRest() +primary_injection_process.AddInjectionDistribution(target_momentum_distribution) +primary_physical_process.AddPhysicalDistribution(target_momentum_distribution) + +helicity_distribution = LI.distributions.PrimaryNeutrinoHelicityDistribution() +primary_injection_process.AddInjectionDistribution(helicity_distribution) +primary_physical_process.AddPhysicalDistribution(helicity_distribution) + + +# ### Position + +# In[8]: + + +primary_pos_dist = None +for sector in earth_model.GetSectors(): + if sector.name=='tilecal': + fid_vol = sector.geo + primary_pos_dist = LI.distributions.CylinderVolumePositionDistribution(fid_vol) + +primary_injection_process.AddInjectionDistribution(primary_pos_dist) +#primary_physical_process.AddPhysicalDistribution(primary_pos_dist) + + +# ### Building the Injector + +# In[9]: + + +# Put it all together! One injector for each W target +events_to_inject = 10000 + +ATLAS_injector = LI.injection.InjectorBase(events_to_inject, earth_model, primary_injection_process, [], random) + +# stopping condition for interaction tree generation +# +# this function should return true if the input datum should terminate +# the simulation for the current branch of the interaction +# +# for this test, stop after any secondary interaction tree datum is created +def StoppingCondition(datum): + return True + +ATLAS_injector.SetStoppingCondition(StoppingCondition) + + +# In[10]: + + +tree = ATLAS_injector.GenerateEvent() + +for datum in tree.tree: # loop over interactions in the tree + print(LI.math.Vector3D(datum.record.interaction_vertex).GetX()) + print(LI.math.Vector3D(datum.record.interaction_vertex).GetY()) + print(LI.math.Vector3D(datum.record.interaction_vertex).GetZ()) + #if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuMu): + + +# ### Building the weighter + +# In[12]: + + +ATLAS_weighter = LI.injection.LeptonTreeWeighter([ATLAS_injector], + earth_model, + primary_physical_process, + []) #empty last argument since no secondary physical process + + +# In[ ]: + + +tree = ATLAS_injector.GenerateEvent() +datum = None + +for datum in tree.tree: # loop over interactions in the tree + #if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuMu): + print(LI.math.Vector3D(datum.record.interaction_vertex).GetX()) + print(LI.math.Vector3D(datum.record.interaction_vertex).GetY()) + print(LI.math.Vector3D(datum.record.interaction_vertex).GetZ()) + + +weight = ATLAS_weighter.EventWeight(tree) +print(weight) + + +# ### Loops to process events + +# In[19]: + + +# c = 2.998e-1 #m/ns + +# gamma_energy_list = [] +# gamma_weight_list = [] +# gamma_time_list = [] + +# # generate evenents in lower target +# while lower_injector.InjectedEvents() < events_to_inject: +# print(lower_injector.InjectedEvents(),end='\r') +# tree = lower_injector.GenerateEvent() # generate the interaction tree +# weight = lower_weighter.EventWeight(tree) # calculate the event weight for this tree +# time = 0 +# for datum in tree.tree: # loop over interactions in the tree +# if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuMu): +# # calculate travel time of speed of light neutrino +# dist = LI.math.Vector3D(datum.record.interaction_vertex) - lower_target_origin +# time += dist.magnitude()/c +# if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuF4): +# # calculate travel time of non-ultra-relativistic HNL +# dist = LI.math.Vector3D(datum.record.interaction_vertex) - LI.math.Vector3D(datum.parent.record.interaction_vertex) +# gamma = datum.record.primary_momentum[0]/datum.record.primary_mass +# beta = np.sqrt(1 - (1/gamma)**2) +# time += dist.magnitude()/(beta*c) + +# # figure out if we're in the fiducial volume +# HNL_vtx = LI.math.Vector3D(datum.record.interaction_vertex) +# HNL_dir = LI.math.Vector3D(datum.record.primary_momentum[1:]) +# HNL_dir.normalize() +# if(fid_vol.IsInside(HNL_vtx,HNL_dir)): + +# # Save the energy of the gamma +# for sID,sP in zip(datum.record.signature.secondary_types, +# datum.record.secondary_momenta): +# if(sID==LI.dataclasses.Particle.ParticleType.Gamma): +# gamma_energy_list.append(sP[0]*1e3) +# gamma_weight_list.append(weight) + +# # if this is a fiducial event, save the travel time +# if(fid_vol.IsInside(HNL_vtx,HNL_dir)): +# gamma_time_list.append(time - 23./c) + + +# ### Post-processing and plotting + +# In[ ]: + + +# # Class for energy smearing: assumes 15% uncertainty on energy reconstruction +# class EnergySmearingGaus: + +# def __init__(self,gamma_energies, +# gamma_weights, +# res=0.15): +# self.gamma_energies = gamma_energies +# self.gamma_weights = gamma_weights +# self.res = res + +# def Gaus(self,x,mu,std_dev): +# return 1./np.sqrt(2*np.pi*std_dev**2)*np.exp(-(x-mu)**2/(2*std_dev**2)) + +# def smeared_rate(self,E): +# ret = 0 +# for e,w in zip(self.gamma_energies,self.gamma_weights): +# ret += w*self.Gaus(E,e,self.res*e) +# return(ret) + +# def smeared_rate_in_bin(self,Elow,Ehigh): +# ret = 0 +# for e,w in zip(self.gamma_energies,self.gamma_weights): +# ret += w/2. * (erf((Ehigh - e)/ (np.sqrt(2)*self.res*e)) - erf((Elow - e) / (np.sqrt(2)*self.res*e))) +# return(ret) + +# smear_gaus = EnergySmearingGaus(gamma_energy_list,gamma_weight_list) + + +# data = pd.read_csv(WorkshopToolsDir+'CCM120_Data/finalHists_all_beamShift.txt') +# print(data.keys()) + + +# # Calculate binning in PE, convert to MeV +# blow = data['binLowEdge'] +# bhigh = list(blow[1:]) + [5e3] +# data['BinLow(PE)'] = blow +# data['BinHigh(PE)'] = bhigh +# data['Bin(PE)'] = (blow+bhigh)/2. +# data['BinWidth(PE)'] = bhigh - blow +# data['BinLow(MeV)'] = data['BinLow(PE)']*pe_to_MeV +# data['BinHigh(MeV)'] = data['BinHigh(PE)']*pe_to_MeV +# data['Bin(MeV)'] = data['Bin(PE)']*pe_to_MeV +# data['bc'] = data['Bin(MeV)'] +# data['BinWidth(MeV)'] = data['BinWidth(PE)']*pe_to_MeV + +# # find the HNL decay to gamma rate in each bin +# gamma_rate = np.array([smear_gaus.smeared_rate_in_bin(elow,ehigh) for (elow,ehigh) in zip(data['BinLow(MeV)'],data['BinHigh(MeV)'])]) + + +# plt.errorbar(data['Bin(MeV)'],data['DataValue']/data['BinWidth(MeV)'], +# xerr=data['BinWidth(MeV)']/2,yerr=data['DataError']/data['BinWidth(MeV)'], +# fmt='.',color='black',capsize=2,label='Data') +# plt.fill_between(data['BinLow(MeV)'],data['BackgroundPrediction']/data['BinWidth(MeV)'], +# color='red',alpha=0.5,step='post',label='Background') +# plt.fill_between(data['BinLow(MeV)'], +# y1=data['BackgroundPrediction']/data['BinWidth(MeV)'], +# y2=data['BackgroundPrediction']/data['BinWidth(MeV)'] + gamma_rate/data['BinWidth(MeV)']*CCM120_POT, +# color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +# plt.xlabel('Energy [MeV]') +# plt.ylabel('Events / MeV') +# plt.xlim(1,1e2) +# plt.legend(title='CCM120 %2.2e POT'%CCM120_POT) +# plt.loglog() +# plt.show() + +# plt.errorbar(data['Bin(MeV)'],data['Subtraction'], +# xerr=data['BinWidth(MeV)']/2,yerr=data['SubtractionError'], +# fmt='.',color='black',capsize=2,label='Data') +# plt.fill_between(data['BinLow(MeV)'], +# gamma_rate*CCM120_POT, +# color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +# plt.xlabel('Energy [MeV]') +# plt.ylabel('Background-Subtrcacted Events') +# plt.xlim(1,1e2) +# plt.legend(title='CCM120 %2.2e POT'%CCM120_POT) +# plt.semilogx() +# plt.show() + +# # adjustment to CCM200 +# adj = CCM200_POT/CCM120_POT*bkg_reduction_factor + +# plt.fill_between(data['BinLow(MeV)'],data['BackgroundPrediction']/data['BinWidth(MeV)']*adj, +# color='red',alpha=0.5,step='post',label='Background') +# plt.fill_between(data['BinLow(MeV)'], +# y1=data['BackgroundPrediction']/data['BinWidth(MeV)']*adj, +# y2=data['BackgroundPrediction']/data['BinWidth(MeV)']*adj + gamma_rate/data['BinWidth(MeV)']*CCM200_POT, +# color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +# plt.xlabel('Energy [MeV]') +# plt.ylabel('Events / MeV') +# plt.xlim(1,1e2) +# plt.legend(title='CCM200 %2.2e POT'%CCM200_POT) +# plt.loglog() +# plt.show() + +# plt.fill_between(data['BinLow(MeV)'], +# y1=-(data['BackgroundPrediction']*adj)**(0.5), +# y2=(data['BackgroundPrediction']*adj)**(0.5), +# color='red',alpha=0.5,step='post',label='Background Stat. Unc.') +# plt.fill_between(data['BinLow(MeV)'], +# gamma_rate*CCM200_POT, +# color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +# plt.xlabel('Energy [MeV]') +# plt.ylabel('Background-Subtrcacted Events') +# plt.xlim(1,1e2) +# plt.legend(title='CCM120 %2.2e POT'%CCM200_POT,loc='lower right') +# plt.semilogx() +# plt.show() + + + +# weights = CCM200_POT*np.array(gamma_weight_list) +# plt.hist(gamma_time_list,bins=30,weights=weights,label='%2.2f total events'%(sum(weights))) +# plt.xlabel('Gamma Time Delay [ns]') +# plt.ylabel('Number of Events in CCM') +# plt.title('HNL Mass: %s GeV; Coupling: %2.2e GeV^-1'%(hnl_mass_str,d_dipole)) +# plt.legend() +# plt.tight_layout() +# plt.show() + + +# In[ ]: + + + + diff --git a/resources/ATLAS_SNe_Injection/rangedInjection_nu_ATLAS.py b/resources/ATLAS_SNe_Injection/rangedInjection_nu_ATLAS.py new file mode 100644 index 00000000..08334d01 --- /dev/null +++ b/resources/ATLAS_SNe_Injection/rangedInjection_nu_ATLAS.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +# Import python libraries +import numpy as np +import matplotlib.pyplot as plt +from scipy.stats import poisson +from scipy.special import erf +import pandas as pd +import math +#%matplotlib notebook + +# Import the CCM modules +import leptoninjector as LI + +# Make an instance of random for use +random = LI.utilities.LI_random() + + +# ### Initial parameters + +# In[2]: + + +events_to_inject = 10000 + + +# ### Define geometry + +# In[3]: + + +# Make the earth model, add ATLAS detector layout and materials file +materials_file = '../earthparams/materials/ATLAS.dat' +earth_model_file = '../earthparams/densities/PREM_ATLAS.dat' + +earth_model = LI.detector.EarthModel() +earth_model.LoadMaterialModel(materials_file) +earth_model.LoadEarthModel(earth_model_file) + + +# ### Define injection processes + +# In[4]: + + +primary_type = LI.dataclasses.Particle.ParticleType.NuMu + +primary_injection_process = LI.injection.InjectionProcess() +primary_injection_process.primary_type = primary_type + +primary_physical_process = LI.injection.PhysicalProcess() +primary_physical_process.primary_type = primary_type + + +# ### Construct Cross Section Classes + +# In[5]: + + +xsfiledir = '/n/home01/awen/prometheus/resources/cross_section_splines' +target_type = LI.dataclasses.Particle.ParticleType.Nucleon + +DIS_xs = LI.crosssections.DISFromSpline(xsfiledir+'/dsdxdy_nu_CC_iso.fits', + xsfiledir+'/sigma_nu_CC_iso.fits', + [primary_type], + [target_type]) + +primary_xs = LI.crosssections.CrossSectionCollection(primary_type, [DIS_xs]) +primary_injection_process.SetCrossSections(primary_xs) +primary_physical_process.SetCrossSections(primary_xs) + + +# ### Construct Energy Distributions + +# In[6]: + + +# input: file with energy (GeV) vs physical (time-integrated) total number of neutrinos at each energy +flux_file = '/n/home01/awen/LeptonInjector/Sandbox/flux_2P_D0_1_s20.txt' +edist = LI.distributions.TabulatedFluxDistribution(100, int(1e6), flux_file, False) #bool is whether flux is physical + +primary_injection_process.AddInjectionDistribution(edist) +primary_physical_process.AddPhysicalDistribution(edist) + +flux_units = LI.distributions.NormalizationConstant(3.76e-9) # normalize to a total number of events +primary_physical_process.AddPhysicalDistribution(flux_units) + + +# In[7]: + + +# plot dN spectrum just to show +flux_verify = np.loadtxt(flux_file) +plt.plot(flux_verify[:,0], flux_verify[:,1]) +plt.xscale('log'); plt.xlim(1e-2, 1e6) +plt.yscale('log'); plt.ylim(1e30, 1e53) + + +# ### Construct Direction Distributions (position of injection, momentum of particle) + +# In[8]: + + +#ATLAS_origin = LI.math.Vector3D(0, 0, 6371234) #6371234 #90m below earth surface, ~depth of altas cavern +#earth_origin = LI.math.Vector3D(0, 0, 0) +#injection_dir = ATLAS_origin - earth_origin + +# let's just inject upwards for throughgoing events at cos(theta) = -1 +injection_dir = LI.math.Vector3D(0, 0, -1) +injection_dir.normalize() + +inj_ddist = LI.distributions.FixedDirection(injection_dir) +phys_ddist = LI.distributions.FixedDirection(injection_dir) + +primary_injection_process.AddInjectionDistribution(inj_ddist) +primary_physical_process.AddPhysicalDistribution(phys_ddist) + + +# ### Some other specifications: target at rest, neutrino helicity + +# In[9]: + + +target_momentum_distribution = LI.distributions.TargetAtRest() +primary_injection_process.AddInjectionDistribution(target_momentum_distribution) +primary_physical_process.AddPhysicalDistribution(target_momentum_distribution) + +helicity_distribution = LI.distributions.PrimaryNeutrinoHelicityDistribution() +primary_injection_process.AddInjectionDistribution(helicity_distribution) +primary_physical_process.AddPhysicalDistribution(helicity_distribution) + + +# ### Position +# (Not necessary if using ColumnDepthLeptonInjector). However, define the volume anyways to calculate intersections with the produced muon + +# In[10]: + + +primary_pos_dist = None +fid_vol = None +for sector in earth_model.GetSectors(): + if sector.name=='muon_system': + fid_vol = sector.geo + primary_pos_dist = LI.distributions.CylinderVolumePositionDistribution(fid_vol) + +#primary_injection_process.AddInjectionDistribution(primary_pos_dist) +#primary_physical_process.AddPhysicalDistribution(primary_pos_dist) + + +# ### Building the Injector + +# In[11]: + + +lepton_depth_function = LI.distributions.LeptonDepthFunction() + +ATLAS_ColumnDepthInjector = LI.injection.ColumnDepthLeptonInjector(events_to_inject, + earth_model, + primary_injection_process, + [], + random, + lepton_depth_function, + 23, 23) #radius, endcap length + +# stopping condition for interaction tree generation +# +# this function should return true if the input datum should terminate +# the simulation for the current branch of the interaction +# +# for this test, stop after any secondary interaction tree datum is created +def StoppingCondition(datum): + return True + +ATLAS_ColumnDepthInjector.SetStoppingCondition(StoppingCondition) + + +# ### Building the weighter + +# In[12]: + + +ATLAS_weighter = LI.injection.LeptonTreeWeighter([ATLAS_ColumnDepthInjector], + earth_model, + primary_physical_process, + []) #empty last argument since no secondary physical process + + +# ### Event Loop + +# In[13]: + + +vertex_xarray = np.asarray([]) +vertex_yarray = np.asarray([]) +vertex_zarray = np.asarray([]) +lepton_energies = np.asarray([]) +HadRecoil_energies = np.asarray([]) +primary_energies = np.asarray([]) +inter_array = [] + +weightarray = np.asarray([]) +totalweightarray = np.asarray([]) + +for i in range(events_to_inject): + tree = ATLAS_ColumnDepthInjector.GenerateEvent() + weight = ATLAS_weighter.EventWeight(tree) + + totalweightarray = np.append(totalweightarray, weight) + + if not math.isinf(weight): + print(i,end='\r') + weightarray = np.append(weightarray, weight) + + for datum in tree.tree: + vertex_xarray = np.append(vertex_xarray, LI.math.Vector3D(datum.record.interaction_vertex).GetX()) + vertex_yarray = np.append(vertex_yarray, LI.math.Vector3D(datum.record.interaction_vertex).GetY()) + vertex_zarray = np.append(vertex_zarray, LI.math.Vector3D(datum.record.interaction_vertex).GetZ()) + + lepton_energies = np.append(lepton_energies, datum.record.secondary_momenta[0][0]) + HadRecoil_energies = np.append(HadRecoil_energies, datum.record.secondary_momenta[1][0]) + primary_energies = np.append(primary_energies, datum.record.primary_momentum[0]) + + vtx = LI.math.Vector3D(datum.record.interaction_vertex) + #vtx = LI.math.Vector3D([vtx.GetX(), vtx.GetY(), vtx.GetZ()/100]) + lepton_direction = LI.math.Vector3D(datum.record.secondary_momenta[0][1:]) + + inter = fid_vol.ComputeIntersections(vtx, lepton_direction) + + if len(inter) != 0: + #print('found intersection!') + inter_array.append(inter) + + +# ### Plot of positions of vertices + +# In[14]: + + +fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(10, 3), dpi=200) +counts, bins = np.histogram(vertex_xarray, weights=weightarray, bins=60) +ax1.stairs(counts, bins, label='lepton') +ax1.set_xlabel('x (m)') + +counts, bins = np.histogram(vertex_yarray, weights=weightarray, bins=60) +ax2.stairs(counts, bins, label='lepton') +ax2.set_xlabel('y (m)') + +counts, bins = np.histogram(vertex_zarray, weights=weightarray, bins=60) +ax3.stairs(counts, bins, label='lepton') +ax3.set_xlabel('z (m)') + +fig = plt.figure(figsize=(12, 12)) +ax = fig.add_subplot(projection='3d') + +ax.scatter(vertex_xarray, vertex_yarray, vertex_zarray) + + +# In[15]: + + +vertex_xarray.size + + +# ### Plotting where the lepton intersects the detector volume + +# In[16]: + + +X_inter_array = [] +Y_inter_array = [] +Z_inter_array = [] + +for i in inter_array: + for j in i: + X_inter_array.append(j.position.GetX()) + Y_inter_array.append(j.position.GetY()) + Z_inter_array.append(j.position.GetZ()) + +plt.figure() +plt.scatter(X_inter_array[::2], Y_inter_array[::2]) +plt.scatter(X_inter_array[1:][::2], Y_inter_array[1:][::2], marker='.') +plt.xlim(-12,12) +plt.ylim(-12,12) + + +# ### Plotting the Energy Spectrum at the primary vertex + +# In[17]: + + +fig = plt.figure(figsize=(5, 4), dpi=200) + +counts, bins = np.histogram(lepton_energies, weights=weightarray, bins=np.logspace(np.log10(1e1),np.log10(1e6), 60)) +counts2, bins2 = np.histogram(HadRecoil_energies, weights=weightarray, bins=np.logspace(np.log10(1e1),np.log10(1e6), 60)) +counts3, bins3 = np.histogram(primary_energies, weights=weightarray, bins=np.logspace(np.log10(1e1),np.log10(1e6), 60)) +#counts, bins = np.histogram(zarray, bins=100) +plt.stairs(counts, bins, label='lepton') +plt.stairs(counts2, bins2, label='recoil') +plt.stairs(counts3, bins3, label='primary nu') +plt.yscale('log') +plt.xscale('log') +plt.xlim(1e1, 2e6) +plt.legend() +plt.xlabel('Energy (GeV)') + + +# ### Distribution of weights + +# In[18]: + + +counts, bins = np.histogram(weightarray, bins=60) +plt.stairs(counts, bins) +#plt.yscale('log') + + +# ### Some playing around for Finding intersections + +# In[ ]: + + +tree = ATLAS_ColumnDepthInjector.GenerateEvent() +datum = None + +for datum in tree.tree: # loop over interactions in the tree + if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuTau): + print(LI.math.Vector3D(datum.record.interaction_vertex).GetX()) + print(LI.math.Vector3D(datum.record.interaction_vertex).GetY()) + print(LI.math.Vector3D(datum.record.interaction_vertex).GetZ()) + +weight = ATLAS_weighter.EventWeight(tree) +#print(weight) + +vtx = LI.math.Vector3D(datum.record.interaction_vertex) +lepton_direction = LI.math.Vector3D(datum.record.secondary_momenta[0][1:]) + +inter = fid_vol.ComputeIntersections(vtx, lepton_direction) + +inter[0].position.GetZ() + diff --git a/resources/DipoleInjection/inject_HNLs_CCM.ipynb b/resources/DipoleInjection/inject_HNLs_CCM.ipynb deleted file mode 100644 index b4edaa64..00000000 --- a/resources/DipoleInjection/inject_HNLs_CCM.ipynb +++ /dev/null @@ -1,668 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "9aa1cfdb-c500-4f8f-aeb9-b0cffd79607d", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/nwkamp/anaconda3/lib/python3.8/site-packages/scipy/__init__.py:138: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.23.1)\n", - " warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion} is required for this version of \"\n" - ] - } - ], - "source": [ - "# Import python libraries\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from scipy.stats import poisson\n", - "from scipy.special import erf\n", - "import pandas as pd\n", - "\n", - "# Import the CCM modules\n", - "import leptoninjector as LI\n", - "\n", - "# Make an instance of random for use \n", - "random = LI.utilities.LI_random()\n", - "\n", - "# HNL parameters\n", - "hnl_mass_str = \"0.02035\" # make sure this matches one of the cross section tables\n", - "hnl_mass = float(hnl_mass_str) # GeV\n", - "d_dipole = 5e-7 # GeV^-1\n", - "\n", - "# Injection parameters\n", - "events_to_inject = int(1e5)\n", - "primary_type = LI.dataclasses.Particle.ParticleType.NuMu\n", - "\n", - "# For upscattering cross section\n", - "z_samp = False\n", - "inv_GeV = True\n", - "inelastic = True\n", - "target_types = [LI.dataclasses.Particle.ParticleType.HNucleus,\n", - " LI.dataclasses.Particle.ParticleType.Be9Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.C12Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.N14Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.O16Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Na23Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Al27Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Si28Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Ar40Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Ca40Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Mn55Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Fe56Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Cu63Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Cu65Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.W183Nucleus,\n", - " LI.dataclasses.Particle.ParticleType.Pb208Nucleus]\n", - "ZA_combos = [[1,1],\n", - " [4,9],\n", - " [6,12],\n", - " [7,14],\n", - " [8,16],\n", - " [11,23],\n", - " [13,27],\n", - " [14,28],\n", - " [18,40],\n", - " [20,40],\n", - " [25,55],\n", - " [26,56],\n", - " [29,63],\n", - " [29,65],\n", - " [74,183],\n", - " [82,208]]\n", - "# file locations\n", - "tot_xsec_path = '../../../../Sandbox/Dipole_xsec_tables/tot_xsec_E0_Ne20'\n", - "diff_xsec_path = '../../../../Sandbox/Dipole_xsec_tables/diff_xsec_y_Enu_0.055_Ne20'\n", - "tot_hf_files = ['%s/xsec_Z_%i_A_%i_mHNL_%s_hf.dat'%(tot_xsec_path,\n", - " Z,A,\n", - " hnl_mass_str) for Z,A in ZA_combos]\n", - "tot_hc_files = ['%s/xsec_Z_%i_A_%i_mHNL_%s_hc.dat'%(tot_xsec_path,\n", - " Z,A,\n", - " hnl_mass_str) for Z,A in ZA_combos]\n", - "diff_hf_files = ['%s/dxsec_Z_%i_A_%i_mHNL_%s_hf.dat'%(diff_xsec_path,\n", - " Z,A,\n", - " hnl_mass_str) for Z,A in ZA_combos]\n", - "diff_hc_files = ['%s/dxsec_Z_%i_A_%i_mHNL_%s_hc.dat'%(diff_xsec_path,\n", - " Z,A,\n", - " hnl_mass_str) for Z,A in ZA_combos]\n", - "\n", - "# For comparing data to HNL prediction later on\n", - "CCM200_POT = 2.25e22\n", - "CCM120_POT = 1.79e21\n", - "bkg_reduction_factor = 1e-2 # optimistic, with Chrenkov reconstruction working\n", - "pe_to_MeV = 0.1\n", - "WorkshopToolsDir = '../../../../Sandbox/' # Change this if need be" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "3e34c890-bd89-4da6-bdae-6443a0966982", - "metadata": {}, - "outputs": [], - "source": [ - "# Make the earth model, add CCM detector layout and materials file\n", - "\n", - "materials_file = '../earthparams/materials/CCM.dat'\n", - "earth_model_file = '../earthparams/densities/PREM_ccm.dat'\n", - "\n", - "earth_model = LI.detector.EarthModel()\n", - "earth_model.LoadMaterialModel(materials_file)\n", - "earth_model.LoadEarthModel(earth_model_file)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "30b5d426-b07c-4432-8d85-9b50ad0acf43", - "metadata": {}, - "outputs": [], - "source": [ - "# Define injection processes for each target\n", - "primary_injection_process_upper_target = LI.injection.InjectionProcess()\n", - "primary_injection_process_lower_target = LI.injection.InjectionProcess()\n", - "secondary_injection_processes = []\n", - "primary_injection_process_upper_target.primary_type = primary_type\n", - "primary_injection_process_lower_target.primary_type = primary_type\n", - "\n", - "# Define physical processes for each target\n", - "primary_physical_process_upper_target = LI.injection.PhysicalProcess()\n", - "primary_physical_process_lower_target = LI.injection.PhysicalProcess()\n", - "secondary_physical_processes = []\n", - "primary_physical_process_upper_target.primary_type = primary_type\n", - "primary_physical_process_lower_target.primary_type = primary_type\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "9ede34ab-17bd-4580-8a6e-5efecbfe9d75", - "metadata": {}, - "outputs": [], - "source": [ - "# Define upscattering cross section classes\n", - "\n", - "cross_sections = []\n", - "hf_xs = LI.crosssections.DipoleFromTable(hnl_mass,\n", - " d_dipole,\n", - " LI.crosssections.DipoleFromTable.HelicityChannel.Flipping,\n", - " z_samp,inv_GeV,inelastic)\n", - "hc_xs = LI.crosssections.DipoleFromTable(hnl_mass,\n", - " d_dipole,\n", - " LI.crosssections.DipoleFromTable.HelicityChannel.Conserving,\n", - " z_samp,inv_GeV,inelastic)\n", - "for i in range(len(target_types)):\n", - " hf_xs.AddTotalCrossSectionFile(tot_hf_files[i],target_types[i])\n", - " hf_xs.AddDifferentialCrossSectionFile(diff_hf_files[i],target_types[i])\n", - " hc_xs.AddTotalCrossSectionFile(tot_hc_files[i],target_types[i])\n", - " hc_xs.AddDifferentialCrossSectionFile(diff_hc_files[i],target_types[i])\n", - "\n", - "cross_sections.append(hf_xs)\n", - "cross_sections.append(hc_xs)\n", - "primary_cross_sections = LI.crosssections.CrossSectionCollection(primary_type, cross_sections)\n", - "primary_injection_process_upper_target.SetCrossSections(primary_cross_sections)\n", - "primary_injection_process_lower_target.SetCrossSections(primary_cross_sections)\n", - "primary_physical_process_upper_target.SetCrossSections(primary_cross_sections)\n", - "primary_physical_process_lower_target.SetCrossSections(primary_cross_sections)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "a4edf055-3dbc-4eeb-88a7-37a17d7fb853", - "metadata": {}, - "outputs": [], - "source": [ - "# Energy distribution: monoenergetic neutrino from pion decay at rest\n", - "\n", - "nu_energy = 0.02965 # from pi+ DAR\n", - "edist = LI.distributions.Monoenergetic(nu_energy)\n", - "primary_injection_process_upper_target.AddInjectionDistribution(edist)\n", - "primary_injection_process_lower_target.AddInjectionDistribution(edist)\n", - "primary_physical_process_upper_target.AddPhysicalDistribution(edist)\n", - "primary_physical_process_lower_target.AddPhysicalDistribution(edist)\n", - "\n", - "# Flux normalization: \n", - "# using the number quoted in 2105.14020, 4.74e9 nu/m^2/s / (6.2e14 POT/s) * 4*pi*20m^2 to get nu/POT\n", - "flux_units = LI.distributions.NormalizationConstant(3.76e-2)\n", - "primary_physical_process_upper_target.AddPhysicalDistribution(flux_units)\n", - "primary_physical_process_lower_target.AddPhysicalDistribution(flux_units)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "c643f0c5-03fa-438f-b31d-fdf9af6aa7a3", - "metadata": {}, - "outputs": [], - "source": [ - "# Primary direction: A cone around CCM\n", - "\n", - "opening_angle = np.arctan(12/23.); # slightly larger than CCM\n", - "upper_target_origin = LI.math.Vector3D(0, 0, 0.1375)\n", - "lower_target_origin = LI.math.Vector3D(0, 0, -0.241)\n", - "detector_origin = LI.math.Vector3D(23, 0, -0.65)\n", - "upper_dir = detector_origin - upper_target_origin\n", - "upper_dir.normalize()\n", - "lower_dir = detector_origin - lower_target_origin\n", - "lower_dir.normalize()\n", - "upper_inj_ddist = LI.distributions.Cone(upper_dir,opening_angle)\n", - "lower_inj_ddist = LI.distributions.Cone(lower_dir,opening_angle)\n", - "phys_ddist = LI.distributions.IsotropicDirection() # truly we are isotropic\n", - "primary_injection_process_upper_target.AddInjectionDistribution(upper_inj_ddist)\n", - "primary_injection_process_lower_target.AddInjectionDistribution(lower_inj_ddist)\n", - "primary_physical_process_upper_target.AddPhysicalDistribution(phys_ddist)\n", - "primary_physical_process_lower_target.AddPhysicalDistribution(phys_ddist);\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "04d80482-79b3-46fc-842e-6a4d3b26527d", - "metadata": {}, - "outputs": [], - "source": [ - "# Target momentum distribution: target is at rest\n", - "\n", - "target_momentum_distribution = LI.distributions.TargetAtRest()\n", - "primary_injection_process_upper_target.AddInjectionDistribution(target_momentum_distribution)\n", - "primary_injection_process_lower_target.AddInjectionDistribution(target_momentum_distribution)\n", - "primary_physical_process_upper_target.AddPhysicalDistribution(target_momentum_distribution)\n", - "primary_physical_process_lower_target.AddPhysicalDistribution(target_momentum_distribution)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "712e2d18-995e-4fc6-97a6-1e8150d9e5db", - "metadata": {}, - "outputs": [], - "source": [ - "# Helicity distribution: primary neutrino helicity\n", - "\n", - "helicity_distribution = LI.distributions.PrimaryNeutrinoHelicityDistribution()\n", - "primary_injection_process_upper_target.AddInjectionDistribution(helicity_distribution)\n", - "primary_injection_process_lower_target.AddInjectionDistribution(helicity_distribution)\n", - "primary_physical_process_upper_target.AddPhysicalDistribution(helicity_distribution)\n", - "primary_physical_process_lower_target.AddPhysicalDistribution(helicity_distribution)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "819e86b4-f504-4890-b840-ea67f07580c6", - "metadata": {}, - "outputs": [], - "source": [ - "# Position distribution: consider neutrinos from a point source\n", - "\n", - "max_dist = 25\n", - "upper_pos_dist = LI.distributions.PointSourcePositionDistribution(upper_target_origin, max_dist, primary_cross_sections.TargetTypes())\n", - "lower_pos_dist = LI.distributions.PointSourcePositionDistribution(lower_target_origin, max_dist, primary_cross_sections.TargetTypes())\n", - "primary_injection_process_upper_target.AddInjectionDistribution(upper_pos_dist)\n", - "primary_injection_process_lower_target.AddInjectionDistribution(lower_pos_dist)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "ac618d59-9e5e-462a-bf77-7b639761cff1", - "metadata": {}, - "outputs": [], - "source": [ - "# Secondary process definition\n", - "\n", - "secondary_decay_injection_process = LI.injection.InjectionProcess()\n", - "secondary_decay_physical_process = LI.injection.PhysicalProcess()\n", - "secondary_decay_injection_process.primary_type = LI.dataclasses.Particle.ParticleType.NuF4\n", - "secondary_decay_physical_process.primary_type = LI.dataclasses.Particle.ParticleType.NuF4\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "e2b071e9-b559-40c3-9589-ad8a88b1fcc1", - "metadata": {}, - "outputs": [], - "source": [ - "# Secondary cross section class: HNL decay\n", - "\n", - "sec_decay = LI.crosssections.NeutrissimoDecay(hnl_mass, d_dipole, LI.crosssections.NeutrissimoDecay.ChiralNature.Majorana)\n", - "secondary_cross_sections = LI.crosssections.CrossSectionCollection(LI.dataclasses.Particle.ParticleType.NuF4, [sec_decay])\n", - "secondary_decay_injection_process.SetCrossSections(secondary_cross_sections)\n", - "secondary_decay_physical_process.SetCrossSections(secondary_cross_sections)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "45bbc030-5458-48e6-8061-b7e100839a69", - "metadata": {}, - "outputs": [], - "source": [ - "# Secondary position distribution\n", - "\n", - "secondary_pos_dist = LI.distributions.SecondaryPositionDistribution()\n", - "for sector in earth_model.GetSectors():\n", - " if sector.name=='ccm_inner_argon':\n", - " fid_vol = sector.geo\n", - " secondary_pos_dist = LI.distributions.SecondaryPositionDistribution(sector.geo)\n", - "\n", - "secondary_decay_injection_process.AddInjectionDistribution(secondary_pos_dist)\n", - "\n", - "secondary_injection_processes.append(secondary_decay_injection_process)\n", - "secondary_physical_processes.append(secondary_decay_physical_process)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "1af57c0f-e87a-4585-84c4-7829ec6d7e22", - "metadata": {}, - "outputs": [], - "source": [ - "# Put it all together! One injector for each W target\n", - "upper_injector = LI.injection.InjectorBase(events_to_inject, earth_model, \n", - " primary_injection_process_upper_target, \n", - " secondary_injection_processes,\n", - " random)\n", - "\n", - "lower_injector = LI.injection.InjectorBase(events_to_inject, earth_model, \n", - " primary_injection_process_lower_target, \n", - " secondary_injection_processes,\n", - " random)\n", - "\n", - "# stopping condition for interaction tree generation\n", - "#\n", - "# this function should return true if the input datum should terminate\n", - "# the simulation for the current branch of the interaction\n", - "#\n", - "# for this test, stop after any secondary interaction tree datum is created\n", - "def StoppingCondition(datum):\n", - " return True\n", - "\n", - "upper_injector.SetStoppingCondition(StoppingCondition)\n", - "lower_injector.SetStoppingCondition(StoppingCondition)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "ac3b51c4-5fe0-4448-8055-22bef64e8222", - "metadata": {}, - "outputs": [], - "source": [ - "# Weighter instances, one for each target\n", - "\n", - "upper_weighter = LI.injection.LeptonTreeWeighter([upper_injector],\n", - " earth_model, \n", - " primary_physical_process_upper_target, \n", - " secondary_physical_processes)\n", - "lower_weighter = LI.injection.LeptonTreeWeighter([lower_injector],\n", - " earth_model, \n", - " primary_physical_process_upper_target, \n", - " secondary_physical_processes)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "e5fb8d03-a786-4260-aaea-db20938a0ece", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "99999\r" - ] - } - ], - "source": [ - "c = 2.998e-1 #m/ns\n", - "\n", - "gamma_energy_list = []\n", - "gamma_weight_list = []\n", - "gamma_time_list = []\n", - "\n", - "# generate evenents in lower target\n", - "while lower_injector.InjectedEvents() < events_to_inject:\n", - " print(lower_injector.InjectedEvents(),end='\\r')\n", - " tree = lower_injector.GenerateEvent() # generate the interaction tree\n", - " weight = lower_weighter.EventWeight(tree) # calculate the event weight for this tree\n", - " time = 0\n", - " for datum in tree.tree: # loop over interactions in the tree\n", - " if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuMu):\n", - " # calculate travel time of speed of light neutrino\n", - " dist = LI.math.Vector3D(datum.record.interaction_vertex) - lower_target_origin\n", - " time += dist.magnitude()/c\n", - " if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuF4):\n", - " # calculate travel time of non-ultra-relativistic HNL\n", - " dist = LI.math.Vector3D(datum.record.interaction_vertex) - LI.math.Vector3D(datum.parent.record.interaction_vertex)\n", - " gamma = datum.record.primary_momentum[0]/datum.record.primary_mass\n", - " beta = np.sqrt(1 - (1/gamma)**2)\n", - " time += dist.magnitude()/(beta*c)\n", - "\n", - " # figure out if we're in the fiducial volume\n", - " HNL_vtx = LI.math.Vector3D(datum.record.interaction_vertex)\n", - " HNL_dir = LI.math.Vector3D(datum.record.primary_momentum[1:])\n", - " HNL_dir.normalize()\n", - " if(fid_vol.IsInside(HNL_vtx,HNL_dir)):\n", - "\n", - " # Save the energy of the gamma\n", - " for sID,sP in zip(datum.record.signature.secondary_types,\n", - " datum.record.secondary_momenta):\n", - " if(sID==LI.dataclasses.Particle.ParticleType.Gamma):\n", - " gamma_energy_list.append(sP[0]*1e3)\n", - " gamma_weight_list.append(weight)\n", - "\n", - " # if this is a fiducial event, save the travel time\n", - " if(fid_vol.IsInside(HNL_vtx,HNL_dir)):\n", - " gamma_time_list.append(time - 23./c)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "9c467782-953f-4262-afbf-0a5dc87624c2", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index(['binLowEdge', 'binWidth', 'DataValue', 'DataError',\n", - " 'BackgroundPrediction', 'BackgroundError', 'Subtraction',\n", - " 'SubtractionError'],\n", - " dtype='object')\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
    " - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZYAAAELCAYAAAD6AKALAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA5hUlEQVR4nO3deXhU5dn48e8NIiBCtBYoGJAgFCEQwi4UTBQXRCuiokDfFpTW2lq17Wur1P7MpErV2tddaalVsUYQrQhaFQFNXIhFlsgqSiFiAIFSDRTZc//+mDPjZJjlZHImM0nuz3XNlZnnbM+cmZx7nvNsoqoYY4wxXmmS6gwYY4xpWCywGGOM8ZQFFmOMMZ6ywGKMMcZTFliMMcZ4ygKLMcYYT6U8sIhIUxFZKSKvOK+/ISILReQT5+/JIetOFZGNIrJBRC5IXa6NMcZEI6nuxyIivwQGAm1U9WIR+QPwH1W9W0RuBU5W1VtEpBcwCxgMdAQWAd9W1aOx9v/Nb35Tu3Tpktw3YYwxDczy5cv/raptE9n2OK8zUxMikglcBEwDfukkjwHyneczgWLgFid9tqoeBDaLyEb8QaY01jG6dOnCsmXLPM+7McY0ZCLyaaLbpvpW2APAr4GqkLT2qrodwPnbzkk/FfgsZL0KJ80YY0waSVlgEZGLgZ2qutztJhHSIt7HE5FrRWSZiCzbtWtXwnk0xhhTc6kssXwHuEREyoHZwDki8gywQ0Q6ADh/dzrrVwCdQrbPBLZF2rGqzlDVgao6sG3bhG4RGmOMSVDK6lhUdSowFUBE8oGbVfV/ROReYBJwt/N3nrPJfOBZEbkPf+V9d2BpHWfbeODw4cNUVFRw4MCBVGfFmEavRYsWZGZm0qxZM8/2mdLK+yjuBuaIyBRgCzAOQFXXisgcYB1wBLg+Xoswk54qKipo3bo1Xbp0QSTSHU5jTF1QVXbv3k1FRQVZWVme7TctAouqFuNv/YWq7gZGRllvGv4WZKYeO3DggAUVY9KAiHDKKafgdV10qluFmUbKgoox6SEZ/4uNPrD4fD5EJPjw+XypzpKp5z7//HPGjx/P6aefTq9evRg9ejQff/wxAB9//DGjR4+mW7du9OzZkyuvvJIdO3ZQXFyMiPDXv/41uJ+VK1ciIvzxj38E4Pnnnyc7O5smTZpU65u1cOFCBgwYQJ8+fRgwYABvvvlmcNny5cvp06cP3bp148YbbyRSh+iPPvqIoUOH0rx58+CxIhkxYgS5ubnk5ubSsWNHLr30UgC++OILxo4dS05ODoMHD2bNmjW1On8A9913H7169SInJ4eRI0fy6adfd6kYNWoUJ510EhdffHHU7SdPnkxWVha5ubn079+f0lJ/dzdV5c4776R79+58+9vf5uyzz2bt2rUADBkyhNzcXDp37kzbtm2D77W8vLzW76fRUdUG/RgwYIDGk5eXp3l5eXHXM95Yt25dqrOQNFVVVXrmmWfq9OnTg2krV67Ut99+W/fv36/dunXT+fPnB5e9+eabunr1an3rrbe0T58+et555wWX/frXv9a+ffvqvffeq6r+8/bRRx9pXl6efvDBB8H1VqxYoVu3blVV1dWrV2vHjh2DywYNGqRLlizRqqoqHTVqlL766qvH5HnHjh26dOlS/c1vfhM8VjyXXXaZzpw5U1VVb775ZvX5fKqqun79ej3nnHNc7UNVdfPmzRH/9958803dt2+fqqo+9thjeuWVVwaXLVq0SOfPn68XXXRR1P1OmjRJn3/+eVVVXbBggfbp00dVVR9++GG98MILg/tesGCBdu3aVffv3x/c9sknn9Trr7/e9XtoCCL9TwLLNMHrbqMosVipxNSVt956i2bNmnHdddcF03JzcxkxYgTPPvssQ4cO5bvf/W5w2dlnn03v3r0B6Ny5MwcOHGDHjh2oKq+//joXXnhhcN2ePXvSo0ePY47Zr18/OnbsCEB2djYHDhzg4MGDbN++nT179jB06FBEhB/84Ae89NJLx2zfrl07Bg0a5LpV0N69e3nzzTeDJZZ169YxcqS/WvSMM86gvLycHTt2APDMM88wePBgcnNz+fGPf8zRo+7a25x99tmccMIJAJx55plUVFQEl40cOZLWrVu72g/AWWedxcaNGwG45557ePjhh4P7Pv/88xk2bBhFRUWu92fiazSBJS8vj7y8PFTVAotJmjVr1jBgwIAaLwu44ooreP7551myZAn9+/enefPmNTr+3//+d/r160fz5s3ZunUrmZmZwWWZmZls3bq1RvuLZO7cuYwcOZI2bdoA0LdvX1588UUAli5dyqeffkpFRQXr16/nueee47333qOsrIymTZsmdAH/61//Wi3A1tTLL79Mnz592LNnD/v27eP000+vtnzgwIHB22HGG2nR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\n", - "text/plain": [ - "
    " - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEKCAYAAADXdbjqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAtE0lEQVR4nO3deXyU5bn/8c9lAEFArQSqGBEQyh4jq1IXFLGAAqKIgEehcFzqVuqr+tNjj6KFo1ZOf2oFFQVXSkCOICCFqoAK6k9AUEBcOIAStLLJWkJYrt8fk0xDyEwmmUyeyeT7fr3ygnmW+7nmYZgr9/Lct7k7IiIi8Tgu6ABERKTyUzIREZG4KZmIiEjclExERCRuSiYiIhI3JRMREYlbtaADSIT09HRv3Lhx0GGIiFQay5cv3+bu9ct6fkolEzPrA/Rp1qwZy5YtCzocEZFKw8y+jef8lGrmcvfZ7n7TSSedFHQoIiJVSkolEzPrY2YTdu3aFXQoIiJVSkolE9VMRESCkbJ9JpJcDh48SE5ODrm5uUGHIlKl1axZk4yMDKpXr16u5VoqTvTYsWNHVwd8ctmwYQN169alXr16mFnQ4YhUSe7O9u3b2bNnD02aNDlqn5ktd/eOZS07pZq5JHnl5uYqkYgEzMyoV69eQloIUiqZqAM+uSmRiAQvUf8PUyqZFHTA7/vBGJU1s/if898JOkxJQf/4xz8YNGgQZ511Fq1bt6Z37958/fXXAHz99df07t2bZs2a0apVKwYOHMiPP/7IokWLMDMmTpwYLmfFihWYGWPHjgXg7rvvpmXLlmRmZtK/f3927twZPvaRRx6hWbNmtGjRgvnz54e3L1++nHbt2tGsWTPuvPNOimvKnjx5MpmZmWRmZtK1a1c+++yzYt/XddddR4sWLWjbti3Dhw/n4MGDACxatIiTTjqJrKwssrKyePjhh+O+h3/+859p3bo1mZmZdO/enW+/DT32sHLlSs477zzatGlDZmYmU6dOLfb8YcOG0aRJE7Kysmjfvj0fffQREGraGT16NM2bN+cXv/gFF198MWvWrAGgS5cuZGVl0ahRI+rXrx9+Pxs3boz7/VQ57p5yPx3q1XN/8MFifx5sNdUfPHvGsT+/fNslcb744ougQ0iYI0eO+LnnnuvPPPNMeNuKFSv8/fff9/3793uzZs181qxZ4X0LFizwVatW+cKFC71du3beo0eP8L577rnHzz77bH/88cfd3X3+/Pl+8ODB8L577rnH3d3XrFnjmZmZnpub6+vXr/emTZv6oUOH3N29U6dO/uGHH/qRI0e8Z8+ePnfu3GNiXrJkie/YscPd3efOneudO3cu9r299dZbfuTIET9y5IgPGjTIx48f7+7uCxcu9Msvv7xM92vDhg1+0UUXHbN9wYIFvm/fPnd3Hz9+vA8cONDd3b/66iv/+uuv3d198+bNfuqpp/pPP/10zPlDhw71119/3d1D961du3bu7v6Xv/zFe/XqFS57/vz53rRpU9+/f3/43BdffNFvu+22Mr2fyqi4/4/AMo/jezelRnPFYtTAL4rfPq01o7JmHrujTh1GLb40sUFJpbZw4UKqV6/OLbfcEt6WlZUFwKRJkzjvvPPo06dPeN/FF18MhH67b9SoEbt37+bHH3+kQYMGzJs3j969e4ePveyyy8J/P/fcc5k+fToAb775JoMGDeL444+nSZMmNGvWjE8++YTGjRuze/duzjvvPABuuOEGZs6cSa9evY6KuWvXrkeVm5OTU+x7KxxL586dIx5X2GuvvcZTTz1FXl4eXbp0Yfz48aSlpZV4XsF9KYjptddeA+AXv/hFeHvDhg1p0KABW7du5eSTT45Y1oUXXsi6desAeOyxx1i0aBEnnHACELqnXbt2ZfLkyYwYMaLEuCQ2KZVMwkOD69Yt9bmlSjJKMFLI6tWr6dChQ6n3FRgwYACvv/4655xzDu3bt+f4448v9rhJkyZx7bXXArB582bOPffc8L6MjAw2b95M9erVycjIOGZ7NBMnTjwm2RR18OBBXn31VZ588snwto8++oizzz6bhg0bMnbsWNq0acPatWuZOnUqS5YsoXr16tx6661MnjyZG264IWr5scb0ySefkJeXx1lnnRX1/NmzZ9OuXTt2797Nvn37jjm+Y8eO4aYuKR8plUzcfTYwu2N6+o3lVWZxSWbUzKzyKl6EgQMHcu211/Lll18yePBgPvzww2OOGTNmDNWqVeO6664DKLYfxMwibo9k4cKFTJw4kcWLF0eN8dZbb+XCCy/kggsuAKB9+/Z8++231KlTh7lz53LllVfyzTff8O6777J8+XI6deoEwP79+2nQoAEA/fv3Z8OGDeTl5fHdd9+Fa2+//e1v+fWvfx2+1muvvcayZct47733jorhhx9+4Prrr+fll1/muOOK7+69++67GT16NPXr1z+qL6ood9eAkHKWUsmkwuTlqbYiYW3atAk3PxW3r+iXYlGnnnoq1atX5+233+bJJ588Jpm8/PLLzJkzh3fffTf8BZiRkcGmTZvCx+Tk5NCwYUMyMjKOaooq2F6czz//nH//93/nb3/7G/Xq1YsY30MPPcTWrVt57rnnwttOPPHE8N979+7NrbfeyrZt23B3hg4dyiOPPHJMOTNmzABg48aNDBs2jEWLFh1zzDvvvMOYMWN47733jqqh7d69m8svv5zRo0cfVSMr6vHHH2fAgAFHbatduzbr16+nadOm4W2ffvopF110UcRypPRSajRXRRk18AtGXbnyqB/27g06LAnIJZdcwoEDB3j++efD25YuXcp7773HkCFD+PDDD3nrrbfC++bNm8eqVauOKuPhhx/mscceO6ZvYd68eTz22GPMmjUr3OYP0LdvX7Kzszlw4AAbNmzgm2++oXPnzpx22mnUrVuXjz/+GHfnlVdeoV+/fsfE/N1333HVVVfx6quvHtUnUdQLL7zA/PnzmTJlylG1gX/84x/hWtAnn3zCkSNHqFevHt27d2f69Ols2bIFgB07doRHZZVkxYoV3HzzzcyaNStcmwHIy8ujf//+3HDDDVxzzTUxlVXY3XffzZ133sn+/fuBUMJavHgxQ4YMKXVZEplqJuWluNpKUaq9pCQzY8aMGYwcOZJHH32UmjVr0rhxY5544glq1arFnDlzGDlyJCNHjqR69epkZmby5JNPsn379nAZhTvEC7v99ts5cOAAPXr0AEId088++yxt2rRh4MCBtG7dmmrVqjFu3LhwInrmmWcYNmwY+/fvp1evXsX2PTz88MNs376dW2+9FYBq1aqFl23o3bs3L7zwAg0bNuSWW27hzDPPDHfoX3XVVTzwwANMnz6dZ555hmrVqlGrVi2ys7MxM1q3bs3o0aO57LLLOHLkCNWrV2fcuHGceeaZJd7Hu+++m71794YTRqNGjZg1axbTpk3j/fffZ/v27bz00ksAvPTSS+FmspLccccd/PTTT7Rr1460tDROPfVU3nzzTWrVqhXT+RKb1JxOJT3dl91+e9BhHGPUzCxGrbwy6DACsXbtWlq1ahV0GCJC8f8fNZ1KIeEn4PPygg5FRKRKSalk4gVT0NeoEXQoIiJVivpM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\n", - "text/plain": [ - "
    " - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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OTn079+f0aNHs2LFCpYtW8bo0aMjbdCtW7fO94GYlZVFmzZtIsutWrXi1VdfpVu3bvnKTEtL44033mDx4sU8++yzXHLJJZFto0ePZuLEiXz11Vd89dVXTJ8+/ZCYGzVqxLvvvsuiRYu4+eabueKKK6K+tosvvpjly5ezePFidu3axRNPPBHZ1rVrV7Kzs8nOzuaWW24JfL1WrVpF9+7dD1nftm1b5s+fz6JFixg6dCh/+tOfADj88MN57rnnWLp0KdOnT2fMmDFs3bo16rnvuecesrOzmTBhAldeeSUADz/8MB9++CGfffYZX375JePGjWPAgAHk5OTwn//8h+zsbG6//XYuvPDCyOtp2LBh4NcjIQUmEHefBjQBxoR/mgJvu/tOd7+/CGX/L/An8t+gHwhkuftud/8GWIHmX5cy6J133iE1NZWrrroqsi4zM5OuXbvy0ksv0blzZ84995e52Hr06EGrVq0AaNCgATk5Oaxfvx53Z/r06fTt2zeyb/PmzWnatOkhZbZt25b69esD0LJlS3Jycti9ezdr165l+/btdO7cGTPj0ksv5bXXXjvk+DPOOIOjjz4agNNPP53Vq1dHfW39+vXDzDAzOnXqFHO/vF544QU6depEZmYmV155Jfv37y/wGAhdl8MPP/yQmE499VSaNGkCQP369alXr16BN4G7devGihUrALj77rv5v//7v8i5e/fuzRlnnMGLL74YKC4JJsh8IE+FP9A/c/dsIAWYVpRCzWwAsMbdD65DnwB8n2d5dXhdtHNcYWbzzWz+RvU1CG7pUli1KvaPBj8MZMmSJbRv377Q23INHTqUf/zjH3z44Ye0a9eOatWqFar8f/7zn7Rt25Zq1aqxZs0a0tN/maInPT2dNWvWxD3+ySefzJe0otm7dy/PP/88ffr0iaz76KOPaNOmDX379o00CS1btoyXX36ZuXPnkp2dTUpKSkIf1LFimjdvHnv27OHkk0+Oe/wbb7xB69at2b59Ozt37jxk/w4dOkRiluIR5Cb6GjN71N1Hm9nRwL8I8PSVmb0NRPs0ugn4M9A72mFR1kWdf93dJwITATqkpWmO9qA0KGKZcMEFF3DhhReyfPlyhg8fzocffhj42KVLl3LjjTfy1ltvAUS93xHvqZt33nmHJ598kg8++CBuOVdffTXdunWja9euALRr145vv/2WWrVqMW3aNM477zy++uorZs2axYIFC+jYsSMAu3btol69egAMGjSIb775hj179vDdd9+RmZkJwPXXX89vf/vLZKcvvPAC8+fP5913380Xw9q1a7nkkkt49tlnqVIl+vfdG264gTvvvJO6devmu7d0MHfXk4HFLEhHwpvN7G4z+zvQHpjg7v8McNxZ0dabWWugEfBZ+I+ZDnxqZp0I1ThOzLN7OqFe8CJlSsuWLZk8eXLMbQd/EB7suOOOIzU1lZkzZ/LAAw8ETiCrV69m0KBBPPfcc5Fv2Onp6fmamVavXh1p6jrYokWL+K//+i/+/e9/U6dOnZjl3HbbbWzcuJHHHnsssu6II46I/N6vXz+uvvpqNm3ahLszYsQI7rrrrkPOM2XKFCB0D2TkyJHMmTPnkH3efvttxo8fz7vvvpuvJrZ9+3b69+/PnXfeyemnnx4z1nvuuYehQ4fmW1ezZk1WrlxJ48aNI+s+/fRTfvWrX8U8jxRezCYsMxuc+wPMA04HFgIeXpcQd1/s7vXcvaG7NySUNNq5+zpCMx8OM7NqZtaI0L2XeYmWJZIsv/71r9m9ezePP/5LZfyTTz7h3Xff5aKLLuLDDz/kX//6V2Tb9OnTWbx4cb5z3H777dx9992kpAR7TmTr1q3079+fu+66izPPPDOy/vjjj6d27dp8/PHHuDvPPfccAwcOPOT47777jsGDB/P8889z6qmnxizniSeeYMaMGUyaNCnft/5169ZFajvz5s3jwIED1KlTh549ezJ58mQ2bNgAwJYtWyJPUxVk4cKFXHnllUydOjVSawHYs2cPgwYN4tJLL+X8888PdK68brjhBq677jp27doFhJLUBx98wEUXXVToc0ls8Wog5x60vBBIDa934NXiDsbdl5rZK8DnwD7gmvCIwHKwWEOO7NwJLVuWfDyVjJkxZcoUxowZw4QJE6hevToNGzbk/vvvp0aNGrz55puMGTOGMWPGkJqaSkZGBg888ACbN/8yF9sZZ5wR9dxTpkzh2muvZePGjfTv35/MzExmzJjBQw89xIoVK7jjjju44447AHjrrbeoV68ejz76KCNHjmTXrl307ds36r2E22+/nc2bN3P11VcDULVq1chjwv369eOJJ56gfv36XHXVVZx00kl07twZgMGDB3PLLbcwefJkHn30UapWrUqNGjXIysrCzGjRogV33nkn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oUykwsr9BlilSqii/dlnnzF69GgAVq9eTf369SMfCDNmzKBbt27UqFGDJUuWMGTIkEOmWu3atWvUiZbuvfdezjrr0Ft+e/fuZciQIVx88cUMHjwYCH2L/f777yP75MYRz1FHHUX37t2ZPn06rVq1iuxfr149Bg0axLx582ImEAh9mP/xj39kzpw5kUmc3J0RI0bE/PA777zz+MMf/sCnn37Krl274n6TzhWkia2w1zDIa411TWOtj/XaH374YR5//HEApk2bVuDf6t///jft2rXj2GOPjfpaW7ZsyT//+c9859+0aVPkYYB4f4NErn9p0FAmUmEtXryYNm3aRJYXLVpERkYGEEomub9D6EZt7qyCW7ZsoV27djQ86KbN+++/T3Z29iE/0T743J3LLruM5s2b84c//CGyvmPHjnz11Vd888037Nmzh6ysrKjf1jdu3MjWrVuB0DfTt99+m2bNmrFz587IB/DOnTt56623aNWqVdzrMGrUKG655RZat24dWdezZ08mT57Mhg0bIq85d0ZCCE2J2717d0aNGpWviaZnz55Rm9y6devGlClT2LVrFzt27OCNN96IGkthrmHQ1xrrmsZaH+u1X3PNNZF46tevX+DfKveeUiy//vWvycnJ4dFHH42s+/nnn/Ndy1h/g1jXv6xRApEKa/HixZEZCXNycti1axdHH300kD+ZALRt2zbyoXfwzdREzJ07l+eff57Zs2dH2vmnTZtG1apVeeihhzj77LNp3rw5F1xwAS3zzGrZr18/fvjhB9auXUuPHj3IyMigY8eO9OrVi3POOYf169fTpUsX2rRpQ6dOnejfvz99+sSfYTo9PZ3rr78+37oWLVpw55130rt3bzIyMujVqxdr167Nt8/w4cP57LPPGDZsGAAHDhxgxYoVh9TMANq1a8eFF15IZmYmQ4YMoWvXroleuoh4rzX3OgExr2ms9UFee7zzQigRzJw5M1KzjMbMeO2113j33Xdp1KgRnTp1YsSIEdx9991AwX+Dg69/WRRzRsLypEOHDj5//vySLzjIjIQVdMbBghw8+1lZfYw3JyeHlStXsmfPHj799FN27NjB+eefX2CzUmW0ZMkSnnrqKe67777SDkUSkIwZCXUPREpEWe2z8cc//pEjjzyS8ePHk5mZyV//+lcljxhatWql5CH5KIFIpfbQQw/lW77ttttK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\n", - "text/plain": [ - "
    " - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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fDIAY8eO5Z133mHIkCEcdthhAOy3335st912bLHFFowfP77JOO+991523HFHtt12Ww488ECWLFnC3XffzUEHHbSszuTJk9l7773L1ofsCO20005j2223ZauttmLmzJnMnj2bcePGcdFFFzFkyBAefvhhbrzxRrbccksGDx68bP+0hhOUmXVrEyZMYMSIEcvm//GPf7DNNtuwyy678PDDD5dcZ8stt+S2224D4MYbb+SVV16pur3jjz+eddZZhwceeIAHHniAuXPncvLJJ/OnP/2JGTNmMGXKFG655RbOPfdcPvWpTzFjxgyuvfbaZbFOmzaNqVOncskll7Bw4cKy7SxYsICzzjqL++67j+nTp9PY2MiFF17I8OHDeeSRR3jrrbcAuP766zn44IPL1i/o378/06dP55vf/CYXXHABDQ0NHHvssXz3u99lxowZfOlLX+KMM87gnnvu4bHHHlu2f1rDCcrMuq2zzz6bnj17LjtCWXvttXn55Zd59NFHufDCCzn00ENZtGjRJ9abMGECl19+Odtttx2LFy+md+/eLY5hypQpDBs2jAEDBiyL5aGHHipZ95JLLmHw4MEMHTqUV155heeff77sdh955BGefvppdtppJ4YMGcLEiRN56aWX6NmzJ3vuuSe33347S5cu5c4772TfffctW79g//33B2C77bZj9uzZJdvcaaedGD16NFdccQUffvhhi/dJgc9BmVm3NHHiRO644w7uv//+ZcOfV1xxRVZccUUg+yDeeOONee6552hsbFxu3U033ZR7770XgOeee44772z5AJBqbxo7efJk7rvvPv7617+y0korMWzYsIq/KYoIhg8fzqRJkz6x7OCDD+byyy9njTXW4POf/zx9+/atWB9Ytl969OjB0qVLS9YZN24cf/vb37jzzjsZMmQIM2bMoF+/flU9v1J8BGVm3c4f/vAHzjvvPG677bblBirMnz9/2Tf/F198keeff56NNtroE+vPmzcPgI8++oizzjqLY489tlnt9+3bl8WLFwOwww478OCDD7JgwQI+/PBDJk2axC677AJAr169+OCDDwB48803WX311VlppZWYOXMmjzzySMU2hg4dyl/+8hdmzZoFwNtvv81zzz0HwLBhw5g+fTpXXHEFBx98cJP1q3keAC+88AI77LADZ5xxBv37929W12cpPoIys3bREaMA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\n", - "text/plain": [ - "
    " - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "# Class for energy smearing: assumes 15% uncertainty on energy reconstruction\n", - "class EnergySmearingGaus:\n", - " \n", - " def __init__(self,gamma_energies,\n", - " gamma_weights,\n", - " res=0.15):\n", - " self.gamma_energies = gamma_energies\n", - " self.gamma_weights = gamma_weights\n", - " self.res = res\n", - "\n", - " def Gaus(self,x,mu,std_dev):\n", - " return 1./np.sqrt(2*np.pi*std_dev**2)*np.exp(-(x-mu)**2/(2*std_dev**2))\n", - "\n", - " def smeared_rate(self,E):\n", - " ret = 0\n", - " for e,w in zip(self.gamma_energies,self.gamma_weights):\n", - " ret += w*self.Gaus(E,e,self.res*e)\n", - " return(ret)\n", - "\n", - " def smeared_rate_in_bin(self,Elow,Ehigh):\n", - " ret = 0\n", - " for e,w in zip(self.gamma_energies,self.gamma_weights):\n", - " ret += w/2. * (erf((Ehigh - e)/ (np.sqrt(2)*self.res*e)) - erf((Elow - e) / (np.sqrt(2)*self.res*e)))\n", - " return(ret)\n", - "\n", - "smear_gaus = EnergySmearingGaus(gamma_energy_list,gamma_weight_list)\n", - "\n", - "\n", - "data = pd.read_csv(WorkshopToolsDir+'CCM120_Data/finalHists_all_beamShift.txt')\n", - "print(data.keys())\n", - "\n", - "\n", - "# Calculate binning in PE, convert to MeV\n", - "blow = data['binLowEdge']\n", - "bhigh = list(blow[1:]) + [5e3]\n", - "data['BinLow(PE)'] = blow\n", - "data['BinHigh(PE)'] = bhigh\n", - "data['Bin(PE)'] = (blow+bhigh)/2.\n", - "data['BinWidth(PE)'] = bhigh - blow\n", - "data['BinLow(MeV)'] = data['BinLow(PE)']*pe_to_MeV\n", - "data['BinHigh(MeV)'] = data['BinHigh(PE)']*pe_to_MeV\n", - "data['Bin(MeV)'] = data['Bin(PE)']*pe_to_MeV\n", - "data['bc'] = data['Bin(MeV)']\n", - "data['BinWidth(MeV)'] = data['BinWidth(PE)']*pe_to_MeV\n", - "\n", - "# find the HNL decay to gamma rate in each bin\n", - "gamma_rate = np.array([smear_gaus.smeared_rate_in_bin(elow,ehigh) for (elow,ehigh) in zip(data['BinLow(MeV)'],data['BinHigh(MeV)'])])\n", - "\n", - "\n", - "plt.errorbar(data['Bin(MeV)'],data['DataValue']/data['BinWidth(MeV)'],\n", - " xerr=data['BinWidth(MeV)']/2,yerr=data['DataError']/data['BinWidth(MeV)'],\n", - " fmt='.',color='black',capsize=2,label='Data')\n", - "plt.fill_between(data['BinLow(MeV)'],data['BackgroundPrediction']/data['BinWidth(MeV)'],\n", - " color='red',alpha=0.5,step='post',label='Background')\n", - "plt.fill_between(data['BinLow(MeV)'],\n", - " y1=data['BackgroundPrediction']/data['BinWidth(MeV)'],\n", - " y2=data['BackgroundPrediction']/data['BinWidth(MeV)'] + gamma_rate/data['BinWidth(MeV)']*CCM120_POT,\n", - " color='blue',alpha=0.5,step='post',label=r'$m_{\\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole))\n", - "plt.xlabel('Energy [MeV]')\n", - "plt.ylabel('Events / MeV')\n", - "plt.xlim(1,1e2)\n", - "plt.legend(title='CCM120 %2.2e POT'%CCM120_POT)\n", - "plt.loglog()\n", - "plt.show()\n", - "\n", - "plt.errorbar(data['Bin(MeV)'],data['Subtraction'],\n", - " xerr=data['BinWidth(MeV)']/2,yerr=data['SubtractionError'],\n", - " fmt='.',color='black',capsize=2,label='Data')\n", - "plt.fill_between(data['BinLow(MeV)'],\n", - " gamma_rate*CCM120_POT,\n", - " color='blue',alpha=0.5,step='post',label=r'$m_{\\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole))\n", - "plt.xlabel('Energy [MeV]')\n", - "plt.ylabel('Background-Subtrcacted Events')\n", - "plt.xlim(1,1e2)\n", - "plt.legend(title='CCM120 %2.2e POT'%CCM120_POT)\n", - "plt.semilogx()\n", - "plt.show()\n", - "\n", - "# adjustment to CCM200\n", - "adj = CCM200_POT/CCM120_POT*bkg_reduction_factor\n", - "\n", - "plt.fill_between(data['BinLow(MeV)'],data['BackgroundPrediction']/data['BinWidth(MeV)']*adj,\n", - " color='red',alpha=0.5,step='post',label='Background')\n", - "plt.fill_between(data['BinLow(MeV)'],\n", - " y1=data['BackgroundPrediction']/data['BinWidth(MeV)']*adj,\n", - " y2=data['BackgroundPrediction']/data['BinWidth(MeV)']*adj + gamma_rate/data['BinWidth(MeV)']*CCM200_POT,\n", - " color='blue',alpha=0.5,step='post',label=r'$m_{\\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole))\n", - "plt.xlabel('Energy [MeV]')\n", - "plt.ylabel('Events / MeV')\n", - "plt.xlim(1,1e2)\n", - "plt.legend(title='CCM200 %2.2e POT'%CCM200_POT)\n", - "plt.loglog()\n", - "plt.show()\n", - "\n", - "plt.fill_between(data['BinLow(MeV)'],\n", - " y1=-(data['BackgroundPrediction']*adj)**(0.5),\n", - " y2=(data['BackgroundPrediction']*adj)**(0.5),\n", - " color='red',alpha=0.5,step='post',label='Background Stat. Unc.')\n", - "plt.fill_between(data['BinLow(MeV)'],\n", - " gamma_rate*CCM200_POT,\n", - " color='blue',alpha=0.5,step='post',label=r'$m_{\\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole))\n", - "plt.xlabel('Energy [MeV]')\n", - "plt.ylabel('Background-Subtrcacted Events')\n", - "plt.xlim(1,1e2)\n", - "plt.legend(title='CCM120 %2.2e POT'%CCM200_POT,loc='lower right')\n", - "plt.semilogx()\n", - "plt.show()\n", - "\n", - "\n", - "\n", - "weights = CCM200_POT*np.array(gamma_weight_list)\n", - "plt.hist(gamma_time_list,bins=30,weights=weights,label='%2.2f total events'%(sum(weights)))\n", - "plt.xlabel('Gamma Time Delay [ns]')\n", - "plt.ylabel('Number of Events in CCM')\n", - "plt.title('HNL Mass: %s GeV; Coupling: %2.2e GeV^-1'%(hnl_mass_str,d_dipole))\n", - "plt.legend()\n", - "plt.tight_layout()\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dda3b42f-94b3-4b15-bf3f-b502b55eb801", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "@webio": { - "lastCommId": null, - "lastKernelId": null - }, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/resources/DipoleInjection/inject_HNLs_CCM.py b/resources/DipoleInjection/inject_HNLs_CCM.py index 8edb26a8..2dc8fb77 100644 --- a/resources/DipoleInjection/inject_HNLs_CCM.py +++ b/resources/DipoleInjection/inject_HNLs_CCM.py @@ -146,6 +146,7 @@ primary_physical_process_lower_target.SetCrossSections(primary_cross_sections) + # In[5]: @@ -262,6 +263,7 @@ secondary_physical_processes.append(secondary_decay_physical_process) + # In[13]: @@ -297,14 +299,14 @@ def StoppingCondition(datum): upper_weighter = LI.injection.LeptonTreeWeighter([upper_injector], earth_model, primary_physical_process_upper_target, - secondary_physical_processes) + [secondary_physical_processes]) lower_weighter = LI.injection.LeptonTreeWeighter([lower_injector], earth_model, primary_physical_process_upper_target, - secondary_physical_processes) + [secondary_physical_processes]) -# In[15]: +# In[ ]: c = 2.998e-1 #m/ns @@ -349,7 +351,7 @@ def StoppingCondition(datum): gamma_time_list.append(time - 23./c) -# In[16]: +# In[ ]: # Class for energy smearing: assumes 15% uncertainty on energy reconstruction diff --git a/resources/DipoleInjection/inject_HNLs_CCM_v1.py b/resources/DipoleInjection/inject_HNLs_CCM_v1.py new file mode 100644 index 00000000..8edb26a8 --- /dev/null +++ b/resources/DipoleInjection/inject_HNLs_CCM_v1.py @@ -0,0 +1,479 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +# Import python libraries +import numpy as np +import matplotlib.pyplot as plt +from scipy.stats import poisson +from scipy.special import erf +import pandas as pd + +# Import the CCM modules +import leptoninjector as LI + +# Make an instance of random for use +random = LI.utilities.LI_random() + +# HNL parameters +hnl_mass_str = "0.02035" # make sure this matches one of the cross section tables +hnl_mass = float(hnl_mass_str) # GeV +d_dipole = 5e-7 # GeV^-1 + +# Injection parameters +events_to_inject = int(1e5) +primary_type = LI.dataclasses.Particle.ParticleType.NuMu + +# For upscattering cross section +z_samp = False +inv_GeV = True +inelastic = True +target_types = [LI.dataclasses.Particle.ParticleType.HNucleus, + LI.dataclasses.Particle.ParticleType.Be9Nucleus, + LI.dataclasses.Particle.ParticleType.C12Nucleus, + LI.dataclasses.Particle.ParticleType.N14Nucleus, + LI.dataclasses.Particle.ParticleType.O16Nucleus, + LI.dataclasses.Particle.ParticleType.Na23Nucleus, + LI.dataclasses.Particle.ParticleType.Al27Nucleus, + LI.dataclasses.Particle.ParticleType.Si28Nucleus, + LI.dataclasses.Particle.ParticleType.Ar40Nucleus, + LI.dataclasses.Particle.ParticleType.Ca40Nucleus, + LI.dataclasses.Particle.ParticleType.Mn55Nucleus, + LI.dataclasses.Particle.ParticleType.Fe56Nucleus, + LI.dataclasses.Particle.ParticleType.Cu63Nucleus, + LI.dataclasses.Particle.ParticleType.Cu65Nucleus, + LI.dataclasses.Particle.ParticleType.W183Nucleus, + LI.dataclasses.Particle.ParticleType.Pb208Nucleus] +ZA_combos = [[1,1], + [4,9], + [6,12], + [7,14], + [8,16], + [11,23], + [13,27], + [14,28], + [18,40], + [20,40], + [25,55], + [26,56], + [29,63], + [29,65], + [74,183], + [82,208]] +# file locations +tot_xsec_path = '../../../../Sandbox/Dipole_xsec_tables/tot_xsec_E0_Ne20' +diff_xsec_path = '../../../../Sandbox/Dipole_xsec_tables/diff_xsec_y_Enu_0.055_Ne20' +tot_hf_files = ['%s/xsec_Z_%i_A_%i_mHNL_%s_hf.dat'%(tot_xsec_path, + Z,A, + hnl_mass_str) for Z,A in ZA_combos] +tot_hc_files = ['%s/xsec_Z_%i_A_%i_mHNL_%s_hc.dat'%(tot_xsec_path, + Z,A, + hnl_mass_str) for Z,A in ZA_combos] +diff_hf_files = ['%s/dxsec_Z_%i_A_%i_mHNL_%s_hf.dat'%(diff_xsec_path, + Z,A, + hnl_mass_str) for Z,A in ZA_combos] +diff_hc_files = ['%s/dxsec_Z_%i_A_%i_mHNL_%s_hc.dat'%(diff_xsec_path, + Z,A, + hnl_mass_str) for Z,A in ZA_combos] + +# For comparing data to HNL prediction later on +CCM200_POT = 2.25e22 +CCM120_POT = 1.79e21 +bkg_reduction_factor = 1e-2 # optimistic, with Chrenkov reconstruction working +pe_to_MeV = 0.1 +WorkshopToolsDir = '../../../../Sandbox/' # Change this if need be + + +# In[2]: + + +# Make the earth model, add CCM detector layout and materials file + +materials_file = '../earthparams/materials/CCM.dat' +earth_model_file = '../earthparams/densities/PREM_ccm.dat' + +earth_model = LI.detector.EarthModel() +earth_model.LoadMaterialModel(materials_file) +earth_model.LoadEarthModel(earth_model_file) + + +# In[3]: + + +# Define injection processes for each target +primary_injection_process_upper_target = LI.injection.InjectionProcess() +primary_injection_process_lower_target = LI.injection.InjectionProcess() +secondary_injection_processes = [] +primary_injection_process_upper_target.primary_type = primary_type +primary_injection_process_lower_target.primary_type = primary_type + +# Define physical processes for each target +primary_physical_process_upper_target = LI.injection.PhysicalProcess() +primary_physical_process_lower_target = LI.injection.PhysicalProcess() +secondary_physical_processes = [] +primary_physical_process_upper_target.primary_type = primary_type +primary_physical_process_lower_target.primary_type = primary_type + + +# In[4]: + + +# Define upscattering cross section classes + +cross_sections = [] +hf_xs = LI.crosssections.DipoleFromTable(hnl_mass, + d_dipole, + LI.crosssections.DipoleFromTable.HelicityChannel.Flipping, + z_samp,inv_GeV,inelastic) +hc_xs = LI.crosssections.DipoleFromTable(hnl_mass, + d_dipole, + LI.crosssections.DipoleFromTable.HelicityChannel.Conserving, + z_samp,inv_GeV,inelastic) +for i in range(len(target_types)): + hf_xs.AddTotalCrossSectionFile(tot_hf_files[i],target_types[i]) + hf_xs.AddDifferentialCrossSectionFile(diff_hf_files[i],target_types[i]) + hc_xs.AddTotalCrossSectionFile(tot_hc_files[i],target_types[i]) + hc_xs.AddDifferentialCrossSectionFile(diff_hc_files[i],target_types[i]) + +cross_sections.append(hf_xs) +cross_sections.append(hc_xs) +primary_cross_sections = LI.crosssections.CrossSectionCollection(primary_type, cross_sections) +primary_injection_process_upper_target.SetCrossSections(primary_cross_sections) +primary_injection_process_lower_target.SetCrossSections(primary_cross_sections) +primary_physical_process_upper_target.SetCrossSections(primary_cross_sections) +primary_physical_process_lower_target.SetCrossSections(primary_cross_sections) + + +# In[5]: + + +# Energy distribution: monoenergetic neutrino from pion decay at rest + +nu_energy = 0.02965 # from pi+ DAR +edist = LI.distributions.Monoenergetic(nu_energy) +primary_injection_process_upper_target.AddInjectionDistribution(edist) +primary_injection_process_lower_target.AddInjectionDistribution(edist) +primary_physical_process_upper_target.AddPhysicalDistribution(edist) +primary_physical_process_lower_target.AddPhysicalDistribution(edist) + +# Flux normalization: +# using the number quoted in 2105.14020, 4.74e9 nu/m^2/s / (6.2e14 POT/s) * 4*pi*20m^2 to get nu/POT +flux_units = LI.distributions.NormalizationConstant(3.76e-2) +primary_physical_process_upper_target.AddPhysicalDistribution(flux_units) +primary_physical_process_lower_target.AddPhysicalDistribution(flux_units) + + +# In[6]: + + +# Primary direction: A cone around CCM + +opening_angle = np.arctan(12/23.); # slightly larger than CCM +upper_target_origin = LI.math.Vector3D(0, 0, 0.1375) +lower_target_origin = LI.math.Vector3D(0, 0, -0.241) +detector_origin = LI.math.Vector3D(23, 0, -0.65) +upper_dir = detector_origin - upper_target_origin +upper_dir.normalize() +lower_dir = detector_origin - lower_target_origin +lower_dir.normalize() +upper_inj_ddist = LI.distributions.Cone(upper_dir,opening_angle) +lower_inj_ddist = LI.distributions.Cone(lower_dir,opening_angle) +phys_ddist = LI.distributions.IsotropicDirection() # truly we are isotropic +primary_injection_process_upper_target.AddInjectionDistribution(upper_inj_ddist) +primary_injection_process_lower_target.AddInjectionDistribution(lower_inj_ddist) +primary_physical_process_upper_target.AddPhysicalDistribution(phys_ddist) +primary_physical_process_lower_target.AddPhysicalDistribution(phys_ddist); + + +# In[7]: + + +# Target momentum distribution: target is at rest + +target_momentum_distribution = LI.distributions.TargetAtRest() +primary_injection_process_upper_target.AddInjectionDistribution(target_momentum_distribution) +primary_injection_process_lower_target.AddInjectionDistribution(target_momentum_distribution) +primary_physical_process_upper_target.AddPhysicalDistribution(target_momentum_distribution) +primary_physical_process_lower_target.AddPhysicalDistribution(target_momentum_distribution) + + +# In[8]: + + +# Helicity distribution: primary neutrino helicity + +helicity_distribution = LI.distributions.PrimaryNeutrinoHelicityDistribution() +primary_injection_process_upper_target.AddInjectionDistribution(helicity_distribution) +primary_injection_process_lower_target.AddInjectionDistribution(helicity_distribution) +primary_physical_process_upper_target.AddPhysicalDistribution(helicity_distribution) +primary_physical_process_lower_target.AddPhysicalDistribution(helicity_distribution) + + +# In[9]: + + +# Position distribution: consider neutrinos from a point source + +max_dist = 25 +upper_pos_dist = LI.distributions.PointSourcePositionDistribution(upper_target_origin, max_dist, primary_cross_sections.TargetTypes()) +lower_pos_dist = LI.distributions.PointSourcePositionDistribution(lower_target_origin, max_dist, primary_cross_sections.TargetTypes()) +primary_injection_process_upper_target.AddInjectionDistribution(upper_pos_dist) +primary_injection_process_lower_target.AddInjectionDistribution(lower_pos_dist) + + +# In[10]: + + +# Secondary process definition + +secondary_decay_injection_process = LI.injection.InjectionProcess() +secondary_decay_physical_process = LI.injection.PhysicalProcess() +secondary_decay_injection_process.primary_type = LI.dataclasses.Particle.ParticleType.NuF4 +secondary_decay_physical_process.primary_type = LI.dataclasses.Particle.ParticleType.NuF4 + + +# In[11]: + + +# Secondary cross section class: HNL decay + +sec_decay = LI.crosssections.NeutrissimoDecay(hnl_mass, d_dipole, LI.crosssections.NeutrissimoDecay.ChiralNature.Majorana) +secondary_cross_sections = LI.crosssections.CrossSectionCollection(LI.dataclasses.Particle.ParticleType.NuF4, [sec_decay]) +secondary_decay_injection_process.SetCrossSections(secondary_cross_sections) +secondary_decay_physical_process.SetCrossSections(secondary_cross_sections) + + +# In[12]: + + +# Secondary position distribution + +secondary_pos_dist = LI.distributions.SecondaryPositionDistribution() +for sector in earth_model.GetSectors(): + if sector.name=='ccm_inner_argon': + fid_vol = sector.geo + secondary_pos_dist = LI.distributions.SecondaryPositionDistribution(sector.geo) + +secondary_decay_injection_process.AddInjectionDistribution(secondary_pos_dist) + +secondary_injection_processes.append(secondary_decay_injection_process) +secondary_physical_processes.append(secondary_decay_physical_process) + + +# In[13]: + + +# Put it all together! One injector for each W target +upper_injector = LI.injection.InjectorBase(events_to_inject, earth_model, + primary_injection_process_upper_target, + secondary_injection_processes, + random) + +lower_injector = LI.injection.InjectorBase(events_to_inject, earth_model, + primary_injection_process_lower_target, + secondary_injection_processes, + random) + +# stopping condition for interaction tree generation +# +# this function should return true if the input datum should terminate +# the simulation for the current branch of the interaction +# +# for this test, stop after any secondary interaction tree datum is created +def StoppingCondition(datum): + return True + +upper_injector.SetStoppingCondition(StoppingCondition) +lower_injector.SetStoppingCondition(StoppingCondition) + + +# In[14]: + + +# Weighter instances, one for each target + +upper_weighter = LI.injection.LeptonTreeWeighter([upper_injector], + earth_model, + primary_physical_process_upper_target, + secondary_physical_processes) +lower_weighter = LI.injection.LeptonTreeWeighter([lower_injector], + earth_model, + primary_physical_process_upper_target, + secondary_physical_processes) + + +# In[15]: + + +c = 2.998e-1 #m/ns + +gamma_energy_list = [] +gamma_weight_list = [] +gamma_time_list = [] + +# generate evenents in lower target +while lower_injector.InjectedEvents() < events_to_inject: + print(lower_injector.InjectedEvents(),end='\r') + tree = lower_injector.GenerateEvent() # generate the interaction tree + weight = lower_weighter.EventWeight(tree) # calculate the event weight for this tree + time = 0 + for datum in tree.tree: # loop over interactions in the tree + if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuMu): + # calculate travel time of speed of light neutrino + dist = LI.math.Vector3D(datum.record.interaction_vertex) - lower_target_origin + time += dist.magnitude()/c + if(datum.record.signature.primary_type == LI.dataclasses.Particle.ParticleType.NuF4): + # calculate travel time of non-ultra-relativistic HNL + dist = LI.math.Vector3D(datum.record.interaction_vertex) - LI.math.Vector3D(datum.parent.record.interaction_vertex) + gamma = datum.record.primary_momentum[0]/datum.record.primary_mass + beta = np.sqrt(1 - (1/gamma)**2) + time += dist.magnitude()/(beta*c) + + # figure out if we're in the fiducial volume + HNL_vtx = LI.math.Vector3D(datum.record.interaction_vertex) + HNL_dir = LI.math.Vector3D(datum.record.primary_momentum[1:]) + HNL_dir.normalize() + if(fid_vol.IsInside(HNL_vtx,HNL_dir)): + + # Save the energy of the gamma + for sID,sP in zip(datum.record.signature.secondary_types, + datum.record.secondary_momenta): + if(sID==LI.dataclasses.Particle.ParticleType.Gamma): + gamma_energy_list.append(sP[0]*1e3) + gamma_weight_list.append(weight) + + # if this is a fiducial event, save the travel time + if(fid_vol.IsInside(HNL_vtx,HNL_dir)): + gamma_time_list.append(time - 23./c) + + +# In[16]: + + +# Class for energy smearing: assumes 15% uncertainty on energy reconstruction +class EnergySmearingGaus: + + def __init__(self,gamma_energies, + gamma_weights, + res=0.15): + self.gamma_energies = gamma_energies + self.gamma_weights = gamma_weights + self.res = res + + def Gaus(self,x,mu,std_dev): + return 1./np.sqrt(2*np.pi*std_dev**2)*np.exp(-(x-mu)**2/(2*std_dev**2)) + + def smeared_rate(self,E): + ret = 0 + for e,w in zip(self.gamma_energies,self.gamma_weights): + ret += w*self.Gaus(E,e,self.res*e) + return(ret) + + def smeared_rate_in_bin(self,Elow,Ehigh): + ret = 0 + for e,w in zip(self.gamma_energies,self.gamma_weights): + ret += w/2. * (erf((Ehigh - e)/ (np.sqrt(2)*self.res*e)) - erf((Elow - e) / (np.sqrt(2)*self.res*e))) + return(ret) + +smear_gaus = EnergySmearingGaus(gamma_energy_list,gamma_weight_list) + + +data = pd.read_csv(WorkshopToolsDir+'CCM120_Data/finalHists_all_beamShift.txt') +print(data.keys()) + + +# Calculate binning in PE, convert to MeV +blow = data['binLowEdge'] +bhigh = list(blow[1:]) + [5e3] +data['BinLow(PE)'] = blow +data['BinHigh(PE)'] = bhigh +data['Bin(PE)'] = (blow+bhigh)/2. +data['BinWidth(PE)'] = bhigh - blow +data['BinLow(MeV)'] = data['BinLow(PE)']*pe_to_MeV +data['BinHigh(MeV)'] = data['BinHigh(PE)']*pe_to_MeV +data['Bin(MeV)'] = data['Bin(PE)']*pe_to_MeV +data['bc'] = data['Bin(MeV)'] +data['BinWidth(MeV)'] = data['BinWidth(PE)']*pe_to_MeV + +# find the HNL decay to gamma rate in each bin +gamma_rate = np.array([smear_gaus.smeared_rate_in_bin(elow,ehigh) for (elow,ehigh) in zip(data['BinLow(MeV)'],data['BinHigh(MeV)'])]) + + +plt.errorbar(data['Bin(MeV)'],data['DataValue']/data['BinWidth(MeV)'], + xerr=data['BinWidth(MeV)']/2,yerr=data['DataError']/data['BinWidth(MeV)'], + fmt='.',color='black',capsize=2,label='Data') +plt.fill_between(data['BinLow(MeV)'],data['BackgroundPrediction']/data['BinWidth(MeV)'], + color='red',alpha=0.5,step='post',label='Background') +plt.fill_between(data['BinLow(MeV)'], + y1=data['BackgroundPrediction']/data['BinWidth(MeV)'], + y2=data['BackgroundPrediction']/data['BinWidth(MeV)'] + gamma_rate/data['BinWidth(MeV)']*CCM120_POT, + color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +plt.xlabel('Energy [MeV]') +plt.ylabel('Events / MeV') +plt.xlim(1,1e2) +plt.legend(title='CCM120 %2.2e POT'%CCM120_POT) +plt.loglog() +plt.show() + +plt.errorbar(data['Bin(MeV)'],data['Subtraction'], + xerr=data['BinWidth(MeV)']/2,yerr=data['SubtractionError'], + fmt='.',color='black',capsize=2,label='Data') +plt.fill_between(data['BinLow(MeV)'], + gamma_rate*CCM120_POT, + color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +plt.xlabel('Energy [MeV]') +plt.ylabel('Background-Subtrcacted Events') +plt.xlim(1,1e2) +plt.legend(title='CCM120 %2.2e POT'%CCM120_POT) +plt.semilogx() +plt.show() + +# adjustment to CCM200 +adj = CCM200_POT/CCM120_POT*bkg_reduction_factor + +plt.fill_between(data['BinLow(MeV)'],data['BackgroundPrediction']/data['BinWidth(MeV)']*adj, + color='red',alpha=0.5,step='post',label='Background') +plt.fill_between(data['BinLow(MeV)'], + y1=data['BackgroundPrediction']/data['BinWidth(MeV)']*adj, + y2=data['BackgroundPrediction']/data['BinWidth(MeV)']*adj + gamma_rate/data['BinWidth(MeV)']*CCM200_POT, + color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +plt.xlabel('Energy [MeV]') +plt.ylabel('Events / MeV') +plt.xlim(1,1e2) +plt.legend(title='CCM200 %2.2e POT'%CCM200_POT) +plt.loglog() +plt.show() + +plt.fill_between(data['BinLow(MeV)'], + y1=-(data['BackgroundPrediction']*adj)**(0.5), + y2=(data['BackgroundPrediction']*adj)**(0.5), + color='red',alpha=0.5,step='post',label='Background Stat. Unc.') +plt.fill_between(data['BinLow(MeV)'], + gamma_rate*CCM200_POT, + color='blue',alpha=0.5,step='post',label=r'$m_{\mathcal{N}}$ = %2.2f MeV; d = %2.2e GeV$^{-1}$'%(hnl_mass*1e3,d_dipole)) +plt.xlabel('Energy [MeV]') +plt.ylabel('Background-Subtrcacted Events') +plt.xlim(1,1e2) +plt.legend(title='CCM120 %2.2e POT'%CCM200_POT,loc='lower right') +plt.semilogx() +plt.show() + + + +weights = CCM200_POT*np.array(gamma_weight_list) +plt.hist(gamma_time_list,bins=30,weights=weights,label='%2.2f total events'%(sum(weights))) +plt.xlabel('Gamma Time Delay [ns]') +plt.ylabel('Number of Events in CCM') +plt.title('HNL Mass: %s GeV; Coupling: %2.2e GeV^-1'%(hnl_mass_str,d_dipole)) +plt.legend() +plt.tight_layout() +plt.show() + + +# In[ ]: + + + + diff --git a/resources/DipoleInjection/makeerror.log b/resources/DipoleInjection/makeerror.log new file mode 100644 index 00000000..8346757b --- /dev/null +++ b/resources/DipoleInjection/makeerror.log @@ -0,0 +1 @@ +g++ inject_HNLs_CCM.cpp -o inject_HNLs_CCM -I/usr/include/hdf5/serial/ -I/n/home01/awen/LeptonInjector/local/include/ -I/n/home01/awen/LeptonInjector/sources/LeptonInjector/resources/DipoleInjection/extern/rk/include/ -I/n/home01/awen/homebrew/opt/cfitsio/include -L/n/home01/awen/homebrew/lib -L/n/home01/awen/LeptonInjector/local/lib/ -L/n/home01/awen/LeptonInjector/local/lib/pkgconfig/ -lcfitsio -g -std=c++14 diff --git a/resources/earthparams/densities/PREM_ATLAS-earthcenter.dat b/resources/earthparams/densities/PREM_ATLAS-earthcenter.dat new file mode 100644 index 00000000..0cae14e2 --- /dev/null +++ b/resources/earthparams/densities/PREM_ATLAS-earthcenter.dat @@ -0,0 +1,66 @@ +# +# crust model file +# PREM + mmc crust setup +# crust data is consistent with MMC mediadef. +# +# format as a context free grammar: +# [line] -> [entry] [comment] +# [comment] -> +# [comment] -> #(string comment) +# [entry] -> +# [entry] -> [object] +# [entry] -> [detector] +# [detector] -> detector (double x) (double y) (double z) +# [object] -> object [shape] [label] [material name] [density distribution] +# [shape] -> [sphere] +# [shape] -> [box] +# [shape] -> [cylinder] +# [sphere] -> sphere [shape coords] [rotation angles] (double radius) +# [box] -> box [shape coords] [rotation angles] (double dx) (double dy) (double dz) +# [cylinder] -> cylinder [shape coords] [rotation angles] (double or) (double ir) (double z) #or is radius, ir inner radius, z is height +# [shape coords] -> (double x) (double y) (double z) +# [rotation angles] -> (double alpha) (double beta) (double gamma) # ZXZr convention Euler angles +# [label] -> (string label) +# [material name] -> (string material) +# [density distribution] -> [constant] +# [density distribution] -> [radial polynomial] +# [constant] -> constant (double density) +# [radial polynomial] -> radial_polynomial [axis coords] [polynomial] +# [axis coords] -> (double x) (double y) (double z) +# [polynomial] -> (int n_params) [polynomial {n_params}] +# [polynomial {n_params}] -> (double param_n) [polynomial {n_params-1}] +# [polynomial {1}] -> (double param_1) +# +# format notes: +# - no space before first column +# - delimiter must be whitespaces +# - for overlapping objects the object defined later in the file is given precidence +# - MediumType must be consistent with EarthModelService::MediumType +# - number_of_parameters is the number of params for polynominal density function +# - parameters : ex. +# for 3 parameters p0, p1, p2 and distance from Earth's center x : +# density = p0 + p1*x + p2*x*x +# +# CAUTION : the unit of density must be [g/cm3] (CGS unit) +# +# - lines start from '#' or whitespace are treated +# as comments +# +# + + +object sphere 0 0 0 0 0 0 6371324 rockair_boundary ROCK constant 2.650 # surface of bed rock, 1.0 x 2.65 + +# just a placeholder, need a volume to detect passing muons +# treat muon system as a big cylinder sensitive volume +object cylinder 0 0 0 0 1.57 0 11 0 22 muon_system AIR constant 0.000811 +#object sphere 0 0 0 0 1.57 0 20 muon_system AIR constant 0.000811 +# hcal in the middle (or=3.82, ir=2.30, length=12.3) +#object cylinder 0 0 0 0 1.57 0 3.82 2.30 12.3 tilecal TILECAL constant 7.83 + +# just a test to see how things vary with different geometry +#object sphere 0 0 0 0 0 0 22 muon_system AIR constant 0.000811 + +# declare center of the detector for columndepth lepton injector +detector 0 0 0 + diff --git a/resources/earthparams/densities/PREM_ATLAS.dat b/resources/earthparams/densities/PREM_ATLAS.dat new file mode 100644 index 00000000..77130def --- /dev/null +++ b/resources/earthparams/densities/PREM_ATLAS.dat @@ -0,0 +1,75 @@ +# +# crust model file +# PREM + mmc crust setup +# crust data is consistent with MMC mediadef. +# +# format as a context free grammar: +# [line] -> [entry] [comment] +# [comment] -> +# [comment] -> #(string comment) +# [entry] -> +# [entry] -> [object] +# [entry] -> [detector] +# [detector] -> detector (double x) (double y) (double z) +# [object] -> object [shape] [label] [material name] [density distribution] +# [shape] -> [sphere] +# [shape] -> [box] +# [shape] -> [cylinder] +# [sphere] -> sphere [shape coords] [rotation angles] (double radius) +# [box] -> box [shape coords] [rotation angles] (double dx) (double dy) (double dz) +# [cylinder] -> cylinder [shape coords] [rotation angles] (double or) (double ir) (double z) #or is radius, ir inner radius, z is height +# [shape coords] -> (double x) (double y) (double z) +# [rotation angles] -> (double alpha) (double beta) (double gamma) # ZXZr convention Euler angles +# [label] -> (string label) +# [material name] -> (string material) +# [density distribution] -> [constant] +# [density distribution] -> [radial polynomial] +# [constant] -> constant (double density) +# [radial polynomial] -> radial_polynomial [axis coords] [polynomial] +# [axis coords] -> (double x) (double y) (double z) +# [polynomial] -> (int n_params) [polynomial {n_params}] +# [polynomial {n_params}] -> (double param_n) [polynomial {n_params-1}] +# [polynomial {1}] -> (double param_1) +# +# format notes: +# - no space before first column +# - delimiter must be whitespaces +# - for overlapping objects the object defined later in the file is given precidence +# - MediumType must be consistent with EarthModelService::MediumType +# - number_of_parameters is the number of params for polynominal density function +# - parameters : ex. +# for 3 parameters p0, p1, p2 and distance from Earth's center x : +# density = p0 + p1*x + p2*x*x +# +# CAUTION : the unit of density must be [g/cm3] (CGS unit) +# +# - lines start from '#' or whitespace are treated +# as comments +# +# + + +object sphere 0 0 0 0 0 0 6478000 atmo_radius AIR radial_polynomial 0 0 0 1 0.000811 # 0.673atm x 1.205e-3(g/cm3 for 1atm) +object sphere 0 0 0 0 0 0 6371324 rockair_boundary ROCK radial_polynomial 0 0 0 1 2.650 # surface of bed rock, 1.0 x 2.65 +object sphere 0 0 0 0 0 0 6356000 inner_crust ROCK radial_polynomial 0 0 0 1 2.900 +object sphere 0 0 0 0 0 0 6346600 moho_boundary MANTLE radial_polynomial 0 0 0 2 2.691 1.08679956050855438e-07 # surface of mantle +object sphere 0 0 0 0 0 0 6151000 upper_transition MANTLE radial_polynomial 0 0 0 2 7.1089 -5.97159001726573544e-07 +object sphere 0 0 0 0 0 0 5971000 middle_transition MANTLE radial_polynomial 0 0 0 2 11.2494 -1.26036728927954783e-06 +object sphere 0 0 0 0 0 0 5771000 lower_transition MANTLE radial_polynomial 0 0 0 2 5.3197 -2.32867681682624407e-07 +object sphere 0 0 0 0 0 0 5701000 lowermantle_boundary MANTLE radial_polynomial 0 0 0 4 7.9565 -1.01649662533354259e-06 1.36199775701391389e-13 -1.19131495406828110e-20 +object sphere 0 0 0 0 0 0 3480000 coremantle_boundary OUTERCORE radial_polynomial 0 0 0 4 12.5815 -1.98367603202009108e-07 -8.97421093229181259e-14 -2.13773109929070169e-20 +object sphere 0 0 0 0 0 0 1221500 innercore_boundary INNERCORE radial_polynomial 0 0 0 3 13.0885 0 -2.17742748697875934e-13 + + +# just a placeholder, need a volume to detect passing muons +# treat muon system as a big cylinder sensitive volume +object cylinder 0 0 6371234 0 1.57 0 11 0 22 muon_system AIR constant 0.000811 +# hcal in the middle (or=3.82, ir=2.30, length=12.3) +object cylinder 0 0 6371234 0 1.57 0 3.82 2.30 12.3 tilecal TILECAL constant 7.83 + +# just a test to see how things vary with different geometry +#object sphere 0 0 6371234 0 0 0 22 muon_system AIR constant 0.000811 + +# declare center of the detector for columndepth lepton injector +detector 0 0 6371234 + diff --git a/resources/earthparams/densities/PREM_ATLAS_backup.dat b/resources/earthparams/densities/PREM_ATLAS_backup.dat new file mode 100644 index 00000000..bbc81d55 --- /dev/null +++ b/resources/earthparams/densities/PREM_ATLAS_backup.dat @@ -0,0 +1,70 @@ +# +# crust model file +# PREM + mmc crust setup +# crust data is consistent with MMC mediadef. +# +# format as a context free grammar: +# [line] -> [entry] [comment] +# [comment] -> +# [comment] -> #(string comment) +# [entry] -> +# [entry] -> [object] +# [entry] -> [detector] +# [detector] -> detector (double x) (double y) (double z) +# [object] -> object [shape] [label] [material name] [density distribution] +# [shape] -> [sphere] +# [shape] -> [box] +# [shape] -> [cylinder] +# [sphere] -> sphere [shape coords] [rotation angles] (double radius) +# [box] -> box [shape coords] [rotation angles] (double dx) (double dy) (double dz) +# [cylinder] -> cylinder [shape coords] [rotation angles] (double or) (double ir) (double z) #or is radius, ir inner radius, z is height +# [shape coords] -> (double x) (double y) (double z) +# [rotation angles] -> (double alpha) (double beta) (double gamma) # ZXZr convention Euler angles +# [label] -> (string label) +# [material name] -> (string material) +# [density distribution] -> [constant] +# [density distribution] -> [radial polynomial] +# [constant] -> constant (double density) +# [radial polynomial] -> radial_polynomial [axis coords] [polynomial] +# [axis coords] -> (double x) (double y) (double z) +# [polynomial] -> (int n_params) [polynomial {n_params}] +# [polynomial {n_params}] -> (double param_n) [polynomial {n_params-1}] +# [polynomial {1}] -> (double param_1) +# +# format notes: +# - no space before first column +# - delimiter must be whitespaces +# - for overlapping objects the object defined later in the file is given precidence +# - MediumType must be consistent with EarthModelService::MediumType +# - number_of_parameters is the number of params for polynominal density function +# - parameters : ex. +# for 3 parameters p0, p1, p2 and distance from Earth's center x : +# density = p0 + p1*x + p2*x*x +# +# CAUTION : the unit of density must be [g/cm3] (CGS unit) +# +# - lines start from '#' or whitespace are treated +# as comments +# +# + + +object sphere 0 0 0 0 0 0 1221500 innercore_boundary INNERCORE radial_polynomial 0 0 0 3 13.0885 0 -2.17742748697875934e-13 +object sphere 0 0 0 0 0 0 3480000 coremantle_boundary OUTERCORE radial_polynomial 0 0 0 4 12.5815 -1.98367603202009108e-07 -8.97421093229181259e-14 -2.13773109929070169e-20 +object sphere 0 0 0 0 0 0 5701000 lowermantle_boundary MANTLE radial_polynomial 0 0 0 4 7.9565 -1.01649662533354259e-06 1.36199775701391389e-13 -1.19131495406828110e-20 +object sphere 0 0 0 0 0 0 5771000 lower_transition MANTLE radial_polynomial 0 0 0 2 5.3197 -2.32867681682624407e-07 +object sphere 0 0 0 0 0 0 5971000 middle_transition MANTLE radial_polynomial 0 0 0 2 11.2494 -1.26036728927954783e-06 +object sphere 0 0 0 0 0 0 6151000 upper_transition MANTLE radial_polynomial 0 0 0 2 7.1089 -5.97159001726573544e-07 +object sphere 0 0 0 0 0 0 6346600 moho_boundary MANTLE radial_polynomial 0 0 0 2 2.691 1.08679956050855438e-07 # surface of mantle +object sphere 0 0 0 0 0 0 6356000 inner_crust ROCK radial_polynomial 0 0 0 1 2.900 +object sphere 0 0 0 0 0 0 6371324 rockair_boundary ROCK radial_polynomial 0 0 0 1 2.650 # surface of bed rock, 1.0 x 2.65 +object sphere 0 0 0 0 0 0 6478000 atmo_radius AIR radial_polynomial 0 0 0 1 0.000811 # 0.673atm x 1.205e-3(g/cm3 for 1atm) + +# just a placeholder, need a volume to detect passing muons +# treat muon system as a big cylinder sensitive volume +object cylinder 0 0 6371234 0 1.57 0 11 0 22 muon_system AIR constant 0.000811 +# hcal in the middle (or=3.82, ir=2.30, length=12.3) +object cylinder 0 0 6371234 0 1.57 0 3.82 2.30 12.3 tilecal TILECAL constant 7.83 +# declare center of the detector for columndepth lepton injector +detector 0 0 6371234 + diff --git a/resources/earthparams/materials/ATLAS.dat b/resources/earthparams/materials/ATLAS.dat new file mode 100644 index 00000000..11a541b5 --- /dev/null +++ b/resources/earthparams/materials/ATLAS.dat @@ -0,0 +1,53 @@ +# +# crust model file +# PREM + mmc crust setup +# crust data is consistent with MMC mediadef. +# +# format : +# MediumType[string] number_of_materials[int] +# material_pdg[int] weight[double] +# ..... +# +# - no space before first column +# - delimiter must be whitespaces +# - data must include at least 6 materials +# "INNERCORE", "OUTERCORE", "MANTLE", +# "ROCK", "ICE", "AIR", and "VACUUM" +# - MediumType must be consistent with EarthModelService::MediumType +# - number_of_materials is the number of atm type in the medium +# - weight must be normalized to 1 within a MediumType +# - lines start from '#' or whitespace are treated +# as comments +# + +ICE 2 # H20 +1000080160 0.8881016 # 0, 88.8% in weight +1000010010 0.1118984 # 2H, 11% in weight + +ROCK 2 # SiO2 +1000140280 0.4674349 # Si, 33% +1000080160 0.5325651 # 20, 66% + +INNERCORE 1 # Fe +1000260560 1.0000000 # Fe56 100% + +OUTERCORE 1 # Fe +1000260560 1.0000000 # Fe56 100% + +MANTLE 2 # SiO2 +1000140280 0.4674349 # Si, 33% +1000080160 0.5325651 # 20, 66% + +AIR 2 # N2 + O2 +1000070140 0.7562326 # N2 78% in volume +1000080160 0.2437674 # O2 22% in volume + +VACUUM 1 # dummy, H +1000010010 1.0000000 # N2 78% in volume + +TILECAL 1 # TileCal iron +1000260560 1.0000000 # Fe56 100% to good approximation. maybe add scintillator later + +LEAD 2 # Mostly Pb +1000822080 0.9995000 # Pb208 99.95% +1000290630 0.0005000 # Cu63 0.05% diff --git a/vendor/delabella b/vendor/delabella index 373187ee..6c8f61fe 160000 --- a/vendor/delabella +++ b/vendor/delabella @@ -1 +1 @@ -Subproject commit 373187ee591b3268b7f76aab3f51bbb0091491a6 +Subproject commit 6c8f61fe3ec3653868ff3ebe41d180632e530d8e diff --git a/vendor/rk/CMakeLists.txt b/vendor/rk/CMakeLists.txt index 173b7d41..cc15f75c 100644 --- a/vendor/rk/CMakeLists.txt +++ b/vendor/rk/CMakeLists.txt @@ -29,19 +29,54 @@ LIST(APPEND rk_HEADERS ${PROJECT_SOURCE_DIR}/rk/rkIO.hh ) -add_library(rk STATIC ${rk_SOURCES}) +add_library(rk_static STATIC ${rk_SOURCES}) add_library(rk_shared SHARED ${rk_SOURCES}) +set_target_properties(rk_static PROPERTIES EXPORT_NAME rk) +set_target_properties(rk_shared PROPERTIES EXPORT_NAME rk) -target_include_directories(rk PUBLIC ${PROJECT_SOURCE_DIR}) -target_include_directories(rk_shared PUBLIC ${PROJECT_SOURCE_DIR}) +target_include_directories(rk_static PUBLIC + $ + $ +) +target_include_directories(rk_shared PUBLIC + $ + $ +) + +install(TARGETS rk_static + EXPORT ${PROJECT_NAME}Config + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(TARGETS rk_shared + EXPORT ${PROJECT_NAME}Config PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY "${PROJECT_SOURCE_DIR}/rk/" + #EXPORT ${PROJECT_NAME}Config DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hh" PATTERN "*.icc" ) + +# Export targets for use in downstream CMake projects +# ----------------------------------------------------------------------------- +include(CMakePackageConfigHelpers) +# Make importable from build directory +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) +export(EXPORT ${PROJECT_NAME}Config FILE ${PROJECT_NAME}Config.cmake) + +# Make importable from install location +set(_config_dir share/${PROJECT_NAME}/cmake) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${_config_dir} +) +install(EXPORT ${PROJECT_NAME}Config + DESTINATION ${_config_dir} +) + message("Added rk!")