Commit 1906a0ae authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'v1.0.2_cherrypicking' into 'v1.0-stable'

V1.0.2 cherrypicking

See merge request !247
parents f3001623 179ed2db
Pipeline #1531428 failed with stages
in 5 minutes and 6 seconds
......@@ -57,3 +57,10 @@ export DYLD_LIBRARY_PATH="$ROOTSYS/lib:$DYLD_LIBRARY_PATH"
export Ninja_HOME=${CLICREPO}/software/Ninja/1.9.0/${BUILD_FLAVOUR}
export PATH="$Ninja_HOME:$PATH"
#--------------------------------------------------------------------------------
# Eigen
#--------------------------------------------------------------------------------
export Eigen_HOME=${CLICREPO}/software/Eigen/3.3.7/${BUILD_FLAVOUR}
export Eigen3_DIR=${Eigen_HOME}/share/eigen3/cmake/
......@@ -95,6 +95,14 @@ export CMAKE_PREFIX_PATH="$ROOTSYS:$CMAKE_PREFIX_PATH"
export Ninja_HOME=${CLICREPO}/software/Ninja/1.7.2/${BUILD_FLAVOUR}
export PATH="$Ninja_HOME:$PATH"
#--------------------------------------------------------------------------------
# Eigen
#--------------------------------------------------------------------------------
export Eigen_HOME=${CLICREPO}/software/Eigen/3.3.3/${BUILD_FLAVOUR}/
export Eigen3_DIR=${Eigen_HOME}/share/eigen3/cmake/
export CMAKE_PREFIX_PATH="$Eigen3_DIR:$CMAKE_PREFIX_PATH"
#--------------------------------------------------------------------------------
# Doxygen
#--------------------------------------------------------------------------------
......@@ -108,4 +116,3 @@ export PATH="$Doxygen_HOME:$PATH"
export Git_HOME=${CLICREPO}/software/git/2.13.2/${BUILD_FLAVOUR}
export PATH=${Git_HOME}/bin:${PATH}
......@@ -25,7 +25,7 @@ cmp:slc6-gcc:
- source .gitlab-ci.d/load_deps.sh
- mkdir build
- cd build
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS ..
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DEigen3_DIR=$Eigen3_DIR ..
- ninja
- ninja install
artifacts:
......@@ -45,7 +45,7 @@ cmp:slc6-llvm:
- source .gitlab-ci.d/init_x86_64.sh
- mkdir build
- cd build
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS ..
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DEigen3_DIR=$Eigen3_DIR ..
- ninja
- ninja install
artifacts:
......@@ -66,7 +66,7 @@ cmp:cc7-gcc:
- source .gitlab-ci.d/load_deps.sh
- mkdir build
- cd build
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS ..
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DEigen3_DIR=$Eigen3_DIR ..
- ninja
- ninja install
artifacts:
......@@ -88,7 +88,7 @@ cmp:cc7-docker:
script:
- mkdir build
- cd build
- cmake3 -DBUILD_EventLoaderEUDAQ2=ON -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS ..
- cmake3 -DBUILD_EventLoaderEUDAQ2=ON -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DEigen3_DIR=$Eigen3_DIR ..
- make
- make install
artifacts:
......@@ -108,7 +108,7 @@ cmp:cc7-llvm:
- source .gitlab-ci.d/init_x86_64.sh
- mkdir build
- cd build
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS ..
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DEigen3_DIR=$Eigen3_DIR ..
- ninja
- ninja install
artifacts:
......@@ -127,7 +127,7 @@ cmp:mac1014-clang:
- source .gitlab-ci.d/load_deps.sh
- mkdir build
- cd build
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DCMAKE_USE_RELATIVE_PATHS=TRUE ..
- cmake -GNinja -DCMAKE_BUILD_TYPE=RELEASE -DROOT_DIR=$ROOTSYS -DCMAKE_USE_RELATIVE_PATHS=TRUE -DEigen3_DIR=$Eigen3_DIR ..
- ninja
- ninja install
artifacts:
......
......@@ -76,6 +76,9 @@ IF("${IsSystemDir}" STREQUAL "-1")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
ENDIF("${IsSystemDir}" STREQUAL "-1")
# Include corry cmake functions
INCLUDE("cmake/corryvreckan.cmake")
#########################################
# Define build flags for Corryvreckan #
#########################################
......@@ -83,13 +86,18 @@ ENDIF("${IsSystemDir}" STREQUAL "-1")
# Set standard build flags
SET(COMPILER_FLAGS -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wconversion -Wuseless-cast -Wctor-dtor-privacy -Wzero-as-null-pointer-constant -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wswitch-default -Wundef -Werror -Wshadow -Wformat-security -Wdeprecated -fdiagnostics-color=auto -Wheader-hygiene)
# Require a C++14 compiler but do allow extensions
SET(CMAKE_CXX_STANDARD 14)
INCLUDE("cmake/compiler-flag-checks.cmake")
# Check for C++17 and require C++17 if available else fallback to C++14 (should currently be sufficient)
CHECK_CXX_COMPILER_FLAG(-std=c++17 SUPPORT_STD_CXX17)
IF(SUPPORT_STD_CXX17)
SET(CMAKE_CXX_STANDARD 17)
ELSE()
SET(CMAKE_CXX_STANDARD 14)
ENDIF()
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
INCLUDE("cmake/compiler-flag-checks.cmake")
# Set some debug flags
# FIXME: not using the flag checker now because it wrongly rejects a sanitizer flag..
IF(CMAKE_BUILD_TYPE MATCHES Debug AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
......@@ -103,26 +111,44 @@ ENDIF()
# Prerequisistes for Corryvreckan #
###################################
INCLUDE("cmake/corryvreckan.cmake")
# Define the libraries
SET(CORRYVRECKAN_LIBRARIES "")
# ROOT is required for vector and persistency etc
FIND_PACKAGE(ROOT REQUIRED COMPONENTS Minuit Minuit2 Gui GenVector)
FIND_PACKAGE(ROOT REQUIRED COMPONENTS Minuit Minuit2 Gui GenVector Geom Core Hist RIO NO_MODULE)
IF(NOT ROOT_FOUND)
MESSAGE(FATAL_ERROR "Could not find ROOT, make sure to source the ROOT environment\n"
"$ source YOUR_ROOT_DIR/bin/thisroot.sh")
ENDIF()
# Downgrade to C++14 if ROOT is not build with C++17 support
IF(ROOT_CXX_FLAGS MATCHES ".*std=c\\+\\+17.*")
IF(NOT SUPPORT_STD_CXX17)
MESSAGE(FATAL_ERROR "ROOT was built with C++17 support but current compiler doesn't support it")
ENDIF()
ELSEIF(ROOT_CXX_FLAGS MATCHES ".*std=c\\+\\+1[14].*")
SET(CMAKE_CXX_STANDARD 14)
ELSEIF(ROOT_CXX_FLAGS MATCHES ".*std=c\\+\\+.*")
MESSAGE(FATAL_ERROR "ROOT was built with an unsupported C++ version: ${ROOT_CXX_FLAGS}")
ELSE()
MESSAGE(FATAL_ERROR "Could not deduce ROOT's C++ version from build flags: ${ROOT_CXX_FLAGS}")
ENDIF()
# Check ROOT version
IF (NOT ${ROOT_VERSION} VERSION_GREATER "6.0")
MESSAGE(FATAL_ERROR "ROOT versions below 6.0 are not supported")
ENDIF()
# Eigen3
FIND_PACKAGE(Eigen3 REQUIRED NO_MODULE)
# Prepare ROOT and EIGEN3 Targets if necessary:
CORRYVRECKAN_SETUP_ROOT_TARGETS()
CORRYVRECKAN_SETUP_EIGEN_TARGETS()
# Set the dependencies
SET(CORRYVRECKAN_DEPS_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS})
SET(CORRYVRECKAN_DEPS_LIBRARIES ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES})
SET(CORRYVRECKAN_DEPS_LIBRARIES Eigen3::Eigen ROOT::Core ROOT::GenVector ROOT::Geom ROOT::RIO ROOT::Hist ROOT::Minuit ROOT::Minuit2)
# Add "thisroot.sh" as runtime dependency for setup.sh file:
ADD_RUNTIME_DEP(thisroot.sh)
......
......@@ -55,6 +55,7 @@ The following authors, in alphabetical order, have contributed to Corryvreckan:
* Katharina Dort, University of Giessen/CERN, @kdort
* Adrian Fiergolski, CERN, @afiergol
* Lennart Huth, DESY, @lhuth
* Magnus Mager, CERN, @mmager
* Andreas Matthias Nürnberg, KIT, @nurnberg
* Florian Pitters, HEPHY Vienna, @fpipper
* Paul Schütze, DESY, @pschutze
......
# Additional targets to perform clang-format/clang-tidy/cppcheck
# Check if the git pre-commit hook for formatting is installed:
IF(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
SET(HOOK_SRC "${CMAKE_SOURCE_DIR}/etc/git-hooks/pre-commit-clang-format-hook")
SET(HOOK_DST "${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit-clang-format")
IF(NOT EXISTS ${HOOK_DST})
MESSAGE(WARNING "Git hooks are not installed - consider installing them via ${CMAKE_SOURCE_DIR}/etc/git-hooks/install-hooks.sh")
ELSE()
EXECUTE_PROCESS(COMMAND "cmake" "-E" "compare_files" ${HOOK_SRC} ${HOOK_DST} RESULT_VARIABLE HOOKS_DIFFER)
IF(${HOOKS_DIFFER})
MESSAGE(WARNING "Git hooks are outdated - consider updating them via ${CMAKE_SOURCE_DIR}/etc/git-hooks/install-hooks.sh")
ENDIF()
ENDIF()
ENDIF()
# Get all project files - FIXME: this should also use the list of generated targets
IF(NOT CHECK_CXX_SOURCE_FILES)
MESSAGE(FATAL_ERROR "Variable CHECK_CXX_SOURCE_FILES not defined - set it to the list of files to auto-format")
......
......@@ -7,7 +7,7 @@ FOREACH( FLAG ${COMPILER_FLAGS} )
CHECK_CXX_COMPILER_FLAG( "${FLAG}" CXX_FLAG_WORKS_${FLAG_WORD} )
IF( ${CXX_FLAG_WORKS_${FLAG_WORD}} )
SET ( CMAKE_CXX_FLAGS "${FLAG} ${CMAKE_CXX_FLAGS}")
LIST(APPEND CORRYVRECKAN_CXX_FLAGS ${FLAG})
ELSE()
MESSAGE ( STATUS "NOT adding ${FLAG} to CXX_FLAGS - unsupported flag" )
ENDIF()
......@@ -15,7 +15,7 @@ ENDFOREACH()
# Find threading provider and enable it (NOTE: not used yet)
IF( THREADS_HAVE_PTHREAD_ARG )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
LIST(APPEND CORRYVRECKAN_CXX_FLAGS "-pthread")
SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pthread")
ELSEIF( CMAKE_THREAD_LIBS_INIT )
SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
......@@ -32,6 +32,6 @@ ENDIF()
# Reduce Wstrict-overflow level for some GCC versions due to false positives:
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wstrict-overflow=2")
LIST(APPEND CORRYVRECKAN_CXX_FLAGS "-Wstrict-overflow=2")
ENDIF()
ENDIF()
......@@ -55,6 +55,7 @@ Create the header or provide the alternative class name as first argument")
# Set the special header flags and add the special dynamic implementation file
TARGET_COMPILE_DEFINITIONS(${${name}} PRIVATE CORRYVRECKAN_MODULE_NAME=${_corryvreckan_module_class})
TARGET_COMPILE_DEFINITIONS(${${name}} PRIVATE CORRYVRECKAN_MODULE_HEADER="${_corryvreckan_module_class}.h")
TARGET_COMPILE_OPTIONS(${${name}} PRIVATE ${CORRYVRECKAN_CXX_FLAGS})
TARGET_SOURCES(${${name}} PRIVATE "${PROJECT_SOURCE_DIR}/src/core/module/dynamic_module_impl.cpp")
SET_PROPERTY(SOURCE "${PROJECT_SOURCE_DIR}/src/core/module/dynamic_module_impl.cpp" APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${_corryvreckan_module_class}.h")
......@@ -120,3 +121,51 @@ MACRO(corryvreckan_module_install name)
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
ENDMACRO()
# Macro to set up Eigen3:: targets
MACRO(CORRYVRECKAN_SETUP_EIGEN_TARGETS)
IF(NOT TARGET Eigen3::Eigen)
ADD_LIBRARY(Eigen3::Eigen INTERFACE IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(Eigen3::Eigen
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${EIGEN3_INCLUDE_DIR}
)
ENDIF()
ENDMACRO()
# Macro to set up ROOT:: targets so that we can use the same code for root 6.8 and for root 6.10 and beyond
# Inpsired by CMake build system of DD4Hep
MACRO(CORRYVRECKAN_SETUP_ROOT_TARGETS)
#ROOT CXX Flags are a string with quotes, not a list, so we need to convert to a list...
STRING(REPLACE " " ";" CORRYVRECKAN_ROOT_CXX_FLAGS "${ROOT_CXX_FLAGS}")
IF(NOT TARGET ROOT::Core)
#in ROOT before 6.10 there is no ROOT namespace, so we create ROOT::Core ourselves
ADD_LIBRARY(ROOT::Core INTERFACE IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(ROOT::Core
PROPERTIES
INTERFACE_COMPILE_OPTIONS "${CORRYVRECKAN_ROOT_CXX_FLAGS}"
INTERFACE_INCLUDE_DIRECTORIES ${ROOT_INCLUDE_DIRS}
)
# there is also no dependency between the targets
TARGET_LINK_LIBRARIES(ROOT::Core INTERFACE Core)
# we list here the targets we use, as later versions of root have the namespace, we do not have to to this for ever
FOREACH(LIB Minuit Minuit2 Gui GenVector Geom Graf3d RIO MathCore Tree Hist GuiBld)
IF(TARGET ${LIB})
ADD_LIBRARY(ROOT::${LIB} INTERFACE IMPORTED GLOBAL)
TARGET_LINK_LIBRARIES(ROOT::${LIB} INTERFACE ${LIB} ROOT::Core)
ENDIF()
ENDFOREACH()
ELSEIF(${ROOT_VERSION} VERSION_GREATER_EQUAL 6.12 AND ${ROOT_VERSION} VERSION_LESS 6.14)
# Root 6.12 exports ROOT::Core, but does not assign include directories to the target
SET_TARGET_PROPERTIES(ROOT::Core
PROPERTIES
INTERFACE_COMPILE_OPTIONS "${CORRYVRECKAN_ROOT_CXX_FLAGS}"
INTERFACE_INCLUDE_DIRECTORIES ${ROOT_INCLUDE_DIRS}
)
ENDIF()
ENDMACRO()
......@@ -301,3 +301,9 @@ keywords = "Simulation, Silicon detectors, Geant4, TCAD, Drift–diffusion"
url = "https://cds.cern.ch/record/2649493",
note = {accessed 11~1019}
}
@online{root-tefficiency-class-ref,
title = {ROOT TEfficiency Class Reference},
author = {},
url = {https://root.cern.ch/doc/master/classTEfficiency.html#ae80c3189bac22b7ad15f57a1476ef75b},
note = {accessed 01~2020},
}
......@@ -61,7 +61,7 @@ if [ ! -x "$CLANG_FORMAT" ] ; then
fi
# create one patch containing all changes to the files
git diff-index --cached --diff-filter=ACMR --name-only $against -- | while read file;
git diff-index --cached --diff-filter=ACMR --name-only $against -- src/ | while read file;
do
# ignore file if we do check for file extensions and the file
# does not match any of the extensions specified in $FILE_EXTS
......
......@@ -25,6 +25,8 @@ TARGET_LINK_LIBRARIES(CorryvreckanCore ${CORRYVRECKAN_LIBRARIES})
# Define compile-time library extension
TARGET_COMPILE_DEFINITIONS(CorryvreckanCore PRIVATE SHARED_LIBRARY_SUFFIX="${CMAKE_SHARED_LIBRARY_SUFFIX}")
TARGET_COMPILE_OPTIONS(CorryvreckanCore PRIVATE ${CORRYVRECKAN_CXX_FLAGS})
# Link the DL libraries
TARGET_LINK_LIBRARIES(CorryvreckanCore ${CMAKE_DL_LIBS})
......
......@@ -2,11 +2,9 @@
* @file
* @brief Implementation of logger
*
* @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
* This software is distributed under the terms of the MIT License, copied
* verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an
* @copyright Copyright (c) 2017-2019 CERN and the Allpix Squared authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
......@@ -34,17 +32,14 @@ std::string DefaultLogger::last_message_;
std::mutex DefaultLogger::write_mutex_;
/**
* The logger will save the number of uncaught exceptions during construction to
* compare that with the number of exceptions
* The logger will save the number of uncaught exceptions during construction to compare that with the number of exceptions
* during destruction later.
*/
DefaultLogger::DefaultLogger() : exception_count_(get_uncaught_exceptions(true)) {}
/**
* The output is written to the streams as soon as the logger gets out-of-scope
* and desctructed. The destructor checks
* specifically if an exception is thrown while output is written to the stream.
* In that case the log stream will not be
* The output is written to the streams as soon as the logger gets out-of-scope and desctructed. The destructor checks
* specifically if an exception is thrown while output is written to the stream. In that case the log stream will not be
* forwarded to the output streams and the message will be discarded.
*/
DefaultLogger::~DefaultLogger() {
......@@ -163,8 +158,7 @@ void DefaultLogger::finish() {
}
/**
* This method is typically automatically called by the \ref LOG macro to return
* a stream after constructing the logger. The
* This method is typically automatically called by the \ref LOG macro to return a stream after constructing the logger. The
* header of the stream is added before returning the output stream.
*/
std::ostringstream&
......@@ -235,8 +229,7 @@ DefaultLogger::getStream(LogLevel level, const std::string& file, const std::str
}
/**
* This method is typically automatically called by the \ref LOG_PROGRESS macro.
* An empty identifier is the same as
* This method is typically automatically called by the \ref LOG_PROGRESS macro. An empty identifier is the same as
* underscore.
*/
std::ostringstream& DefaultLogger::getProcessStream(
......@@ -244,8 +237,7 @@ std::ostringstream& DefaultLogger::getProcessStream(
// Get the standard process stream
std::ostringstream& stream = getStream(level, file, function, line);
// Replace empty identifier with underscore because empty is already used for
// check
// Replace empty identifier with underscore because empty is already used for check
if(identifier.empty()) {
identifier = "_";
}
......@@ -272,8 +264,7 @@ std::string DefaultLogger::getStringFromLevel(LogLevel level) {
return type.at(static_cast<decltype(type)::size_type>(level));
}
/**
* @throws std::invalid_argument If the string does not correspond with an
* existing log level
* @throws std::invalid_argument If the string does not correspond with an existing log level
*/
LogLevel DefaultLogger::getLevelFromString(const std::string& level) {
if(level == "TRACE") {
......@@ -319,8 +310,7 @@ std::string DefaultLogger::getStringFromFormat(LogFormat format) {
return type.at(static_cast<decltype(type)::size_type>(format));
}
/**
* @throws std::invalid_argument If the string does not correspond with an
* existing log format
* @throws std::invalid_argument If the string does not correspond with an existing log format
*/
LogFormat DefaultLogger::getFormatFromString(const std::string& format) {
if(format == "SHORT") {
......@@ -350,13 +340,10 @@ void DefaultLogger::clearStreams() {
get_streams().clear();
}
/**
* The caller has to make sure that the added ostream exists for as long log
* messages may be written. The std::cout stream is
* added automatically to the list of streams and does not need to be added
* itself.
* The caller has to make sure that the added ostream exists for as long log messages may be written. The std::cout stream is
* added automatically to the list of streams and does not need to be added itself.
*
* @note Streams cannot be individually removed at the moment and only all at
* once using \ref clearStreams().
* @note Streams cannot be individually removed at the moment and only all at once using \ref clearStreams().
*/
void DefaultLogger::addStream(std::ostream& stream) {
// Disable cursor if stream supports it
......@@ -399,8 +386,7 @@ std::string DefaultLogger::get_current_date() {
}
/*
* It is impossible to know for sure a terminal has support for all extra
* terminal features, but every modern terminal has
* It is impossible to know for sure a terminal has support for all extra terminal features, but every modern terminal has
* this so we just assume it.
*/
bool DefaultLogger::is_terminal(std::ostream& stream) {
......@@ -415,20 +401,20 @@ bool DefaultLogger::is_terminal(std::ostream& stream) {
}
/**
* The number of uncaught exceptions can only be properly determined in C++17.
* In earlier versions it is only possible to
* check if there is at least a single exception thrown and that function is
* used instead. This means a return value of zero
* The number of uncaught exceptions can only be properly determined in C++17. In earlier versions it is only possible to
* check if there is at least a single exception thrown and that function is used instead. This means a return value of zero
* corresponds to no exception and one to at least one exception.
*/
int DefaultLogger::get_uncaught_exceptions(bool cons = false) {
#if __cplusplus > 201402L
int DefaultLogger::get_uncaught_exceptions(bool) {
// we can only do this fully correctly in C++17
return std::uncaught_exceptions();
}
#else
int DefaultLogger::get_uncaught_exceptions(bool cons = false) {
if(cons) {
return 0;
}
return static_cast<int>(std::uncaught_exception());
#endif
}
#endif
/**
* @file
* @brief Provides a logger and macros for convenient access
* @copyright Copyright (c) 2017 CERN and the Allpix Squared authors.
* This software is distributed under the terms of the MIT License, copied
* verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an
* @copyright Copyright (c) 2017-2019 CERN and the Allpix Squared authors.
* This software is distributed under the terms of the MIT License, copied verbatim in the file "LICENSE.md".
* In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an
* Intergovernmental Organization or submit itself to any jurisdiction.
*/
......@@ -32,30 +30,24 @@ namespace corryvreckan {
STATUS, ///< Only critical progress information
ERROR, ///< Critical problems that usually lead to fatal errors
WARNING, ///< Possible issue that could lead to unexpected results
INFO, ///< General information about processes (should not be called in run
/// function)
INFO, ///< General information about processes (should not be called in run function)
DEBUG, ///< Detailed information about physics process
NONE, ///< Indicates the log level has not been set (cannot be selected by the
/// user)
TRACE, ///< Software debugging information about what part is currently
/// running
NONE, ///< Indicates the log level has not been set (cannot be selected by the user)
TRACE, ///< Software debugging information about what part is currently running
};
/**
* @brief Format of the logger
*/
enum class LogFormat {
SHORT = 0, ///< Only include a single character for the log level, the section
/// header and the message
SHORT = 0, ///< Only include a single character for the log level, the section header and the message
DEFAULT, ///< Also include the time and a full logging level description
LONG ///< All of the above and also information about the file and line where
/// the message was defined
LONG ///< All of the above and also information about the file and line where the message was defined
};
/**
* @brief Logger of the framework to inform the user of process
*
* Should almost never be instantiated directly. The \ref LOG macro should be
* used instead to pass all the information.
* Should almost never be instantiated directly. The \ref LOG macro should be used instead to pass all the information.
* This leads to a cleaner interface for sending log messages.
*/
// TODO [DOC] This just be renamed to Log?
......@@ -100,10 +92,8 @@ namespace corryvreckan {
uint32_t line = 0);
/**
* @brief Gives a process stream which updates the same line as long as it is
* the same
* @param identifier Name to indicate the line, used to distinguish when to
* update or write new line
* @brief Gives a process stream which updates the same line as long as it is the same
* @param identifier Name to indicate the line, used to distinguish when to update or write new line
* @param level Logging level
* @param file The file name of the file containing the log message
* @param function The function containing the log message
......@@ -198,8 +188,7 @@ namespace corryvreckan {
private:
/**
* @brief The number of exceptions that are uncaught
* @param cons If true: always return zero if amount of exceptions cannot be
* properly determined
* @param cons If true: always return zero if amount of exceptions cannot be properly determined
* @return Number of uncaught exceptions
*/
int get_uncaught_exceptions(bool cons);
......@@ -210,8 +199,7 @@ namespace corryvreckan {
std::string get_current_date();
/**
* @brief Return if a stream is likely a terminal screen (supporting colors
* etc.)
* @brief Return if a stream is likely a terminal screen (supporting colors etc.)
* @return True if the stream is terminal, false otherwise
*/
static bool is_terminal(std::ostream& stream);
......@@ -243,7 +231,9 @@ namespace corryvreckan {
/**
* @brief Base name of the file without the directory
*/
#ifndef __FILE_NAME__
#define __FILE_NAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
/**
* @brief Execute a block only if the reporting level is high enough
......@@ -262,8 +252,7 @@ namespace corryvreckan {
corryvreckan::LogLevel::level, __FILE_NAME__, std::string(static_cast<const char*>(__func__)), __LINE__)
/**
* @brief Create a logging stream that overwrites the line if the previous
* message has the same identifier
* @brief Create a logging stream that overwrites the line if the previous message has the same identifier
* @param level The log level of the stream
* @param identifier Identifier for this stream to determine overwrites
*/
......@@ -275,6 +264,35 @@ namespace corryvreckan {
std::string(static_cast<const char*>(__func__)), \
__LINE__)
/**
* @brief Create a logging stream if the reporting level is high enough and this message has not yet been logged
* @param level The log level of the stream
*/
#define LOG_ONCE(level) LOG_N(level, 1)
/**
* @brief Generator for a local variable to hold the logging count of a message
* @param Count Number of allowed counts
* @return Local counter variable
*/
#define GENERATE_LOG_VAR(Count) thread_local size_t local___FUNCTION__##Count##__LINE__ = Count
#define GET_LOG_VARIABLE(Count) local___FUNCTION__##Count##__LINE__
/**
* @brief Create a logging stream if the reporting level is high enough and this message has not yet been logged more than
* max_log_count times.
* @param level The log level of the stream
* @param max_log_count Maximum number of times this message is allowed to be logged
*/
#define LOG_N(level, max_log_count) \
GENERATE_LOG_VAR(max_log_count); \
if(GET_LOG_VARIABLE(max_log_count) != 0 && GET_LOG_VARIABLE(max_log_count)-- != 0) \
if(corryvreckan::LogLevel::level <= corryvreckan::Log::getReportingLevel() && \
!corryvreckan::Log::getStreams().empty()) \
corryvreckan::Log().getStream( \
corryvreckan::LogLevel::level, __FILE_NAME__, std::string(static_cast<const char*>(__func__)), __LINE__) \
<< (GET_LOG_VARIABLE(max_log_count) == 0 ? "[further messages will be suppressed] " : "")
/**
* @brief Suppress an stream from writing any output
* @param stream The stream to suppress
......
......@@ -9,6 +9,7 @@ TARGET_LINK_LIBRARIES(corry ${CORRYVRECKAN_LIBRARIES})
# NOTE: fixes both the RPATH problem as well as the TLS problems
# FIXME: should be removed when we have a better solution
TARGET_LINK_LIBRARIES(corry ${CORRYVRECKAN_MODULE_LIBRARIES})
TARGET_COMPILE_OPTIONS(corry PRIVATE ${CORRYVRECKAN_CXX_FLAGS})
# set install location
INSTALL(TARGETS corry EXPORT corry_install
......
......@@ -42,7 +42,7 @@ void AlignmentMillepede::initialise() {
// Renumber the planes in Millepede, ignoring masked planes.
unsigned int index = 0;
for(const auto& det : get_detectors()) {
if(det->isDUT()) {
if(det->isDUT() && m_excludeDUT) {
continue;
}
m_millePlanes[det->name()] = index;
......@@ -166,7 +166,7 @@ void AlignmentMillepede::setConstraints(const size_t nPlanes) {
// Calculate the mean z-position.
double avgz = 0.;
for(const auto& det : get_detectors()) {
if(det->isDUT()) {
if(det->isDUT() && m_excludeDUT) {
continue;
}
avgz += det->displacement().Z();
......@@ -175,7 +175,7 @@ void AlignmentMillepede::setConstraints(const size_t nPlanes) {
// Calculate the variance.
double varz = 0.0;
for(const auto& det : get_detectors()) {
if(det->isDUT()) {
if(det->isDUT() && m_excludeDUT) {
continue;
}
const double dz = det->displacement().Z() - avgz;
......@@ -197,7 +197,7 @@ void AlignmentMillepede::setConstraints(const size_t nPlanes) {
m_constraints.clear();
for(const auto& det : get_detectors()) {
if(det->isDUT()) {
if(det->isDUT() && m_excludeDUT) {