diff --git a/.clang-format b/.clang-format
index add8fbd624..f201cdd689 100644
--- a/.clang-format
+++ b/.clang-format
@@ -49,6 +49,7 @@ SpacesInParentheses: false
Standard: Cpp11
TabWidth: 2
UseTab: Never
+DeriveLineEnding: true
---
Language: ObjC
DisableFormat: true
diff --git a/.cmake-format.py b/.cmake-format.py
new file mode 100644
index 0000000000..29245190b0
--- /dev/null
+++ b/.cmake-format.py
@@ -0,0 +1,109 @@
+# How wide to allow formatted cmake files
+line_width = 120
+
+# How many spaces to tab for indent
+tab_size = 2
+
+# If arglists are longer than this, break them always
+max_subargs_per_line = 5
+
+# If true, separate flow control names from their parentheses with a space
+separate_ctrl_name_with_space = False
+
+# If true, separate function names from parentheses with a space
+separate_fn_name_with_space = False
+
+# If a statement is wrapped to more than one line, than dangle the closing
+# parenthesis on it's own line
+dangle_parens = False
+
+# What character to use for bulleted lists
+bullet_char = '*'
+
+# What character to use as punctuation after numerals in an enumerated list
+enum_char = '.'
+
+# What style line endings to use in the output.
+line_ending = 'unix'
+
+# Format command names consistently as 'lower' or 'upper' case
+command_case = 'canonical'
+
+# Format keywords consistently as 'lower' or 'upper' case
+keyword_case = 'upper'
+
+# Specify structure for custom cmake functions
+# * = ZERO_OR_MORE
+# + = ONE_OR_MORE
+additional_commands = {
+ "add_root_dictionary": {
+ "kwargs": {
+ "LINKDEF": '+',
+ "HEADERS": '*',
+ "BASENAME": '*',
+ }
+ },
+ "find_package_handle_standard_args": {
+ "flags": ["CONFIG_MODE"],
+ "kwargs": {
+ "DEFAULT_MSG": '*',
+ "REQUIRED_VARS": '*',
+ "VERSION_VAR": '*',
+ "HANDLE_COMPONENTS": '*',
+ "FAIL_MESSAGE": '*'
+ }
+ }
+}
+
+# A list of command names which should always be wrapped
+always_wrap = []
+
+# Specify the order of wrapping algorithms during successive reflow attempts
+algorithm_order = [0, 1, 2, 3, 4]
+
+# If true, the argument lists which are known to be sortable will be sorted
+# lexicographicall
+autosort = False
+
+# enable comment markup parsing and reflow
+enable_markup = True
+
+# If comment markup is enabled, don't reflow the first comment block in
+# eachlistfile. Use this to preserve formatting of your
+# copyright/licensestatements.
+first_comment_is_literal = False
+
+# If comment markup is enabled, don't reflow any comment block which matchesthis
+# (regex) pattern. Default is `None` (disabled).
+literal_comment_pattern = None
+
+# Regular expression to match preformat fences in comments
+# default=r'^\s*([`~]{3}[`~]*)(.*)$'
+fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$'
+
+# Regular expression to match rulers in comments
+# default=r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'
+ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$'
+
+# If true, emit the unicode byte-order mark (BOM) at the start of the file
+emit_byteorder_mark = False
+
+# If a comment line starts with at least this many consecutive hash characters,
+# then don't lstrip() them off. This allows for lazy hash rulers where the first
+# hash char is not separated by space
+hashruler_min_length = 10
+
+# If true, then insert a space between the first hash char and remaining hash
+# chars in a hash ruler, and normalize it's length to fill the column
+canonicalize_hashrulers = True
+
+# Specify the encoding of the input file. Defaults to utf-8.
+input_encoding = 'utf-8'
+
+# Specify the encoding of the output file. Defaults to utf-8. Note that cmake
+# only claims to support utf-8 so be careful when using anything else
+output_encoding = 'utf-8'
+
+# A dictionary containing any per-command configuration overrides. Currently
+# only `command_case` is supported.
+per_command = {}
diff --git a/.cmake-format.yaml b/.cmake-format.yaml
deleted file mode 100644
index cdb5bbea52..0000000000
--- a/.cmake-format.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-additional_commands:
- foo:
- flags:
- - BAR
- - BAZ
- kwargs:
- DEPENDS: '*'
- HEADERS: '*'
- SOURCES: '*'
-algorithm_order:
- - 0
- - 1
- - 2
- - 3
-always_wrap: []
-bullet_char: '*'
-command_case: lower
-dangle_parens: true
-enable_markup: true
-enum_char: .
-fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
-first_comment_is_literal: false
-keyword_case: unchanged
-line_ending: unix
-line_width: 120
-literal_comment_pattern: null
-max_subargs_per_line: 3
-ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
-separate_ctrl_name_with_space: false
-separate_fn_name_with_space: false
-tab_size: 2
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000000..f9b76cbeea
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,12 @@
+# Global access
+* @Barthelemy @knopers8 @justonedev1
+
+# Detectors
+/Modules/TOF/ @ercolessi
+/Modules/EMCAL/ @jokonig @Barthelemy @knopers8
+/Modules/TPC/ @wiechula @makor
+/Modules/MFT/ @AlexianL
+/Modules/ITS/ @iravasen @IsakovAD
+/Modules/TRD/ @martenole @bazinski
+/Modules/FOCAL/ @mfasDa @fjonasALICE
+/Modules/FIT/ @andreasmolander @afurs @jotwinow @sahilupadhyaya92
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000000..3a9665150b
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,19 @@
+## ALICE data Quality Control framework and Modules
+
+This repository contains the ALICE O2 data Quality Control (QC) framework and modules.
+It is divided into `Framework`, maintained by the framework developers and `Modules`, which are mostly developed by detector experts.
+
+### Copilot agent instructions
+
+- All the code should apply the [ALICE O2 Coding Guidelines](https://github.com/AliceO2Group/CodingGuidelines).
+See [Formatting tool](https://github.com/AliceO2Group/CodingGuidelines?tab=readme-ov-file#formatting-tool) for details how to set up code formatter.
+Do not attempt to install `clang` with `aliBuild`, use the one you have available on your system.
+- Unless you are running on a developer's machine and you were provided specific instructions, do not attempt to build the code or run tests. Quality Control uses a large number of external dependencies, which are not available in the default Copilot environment on GitHub.
+- When working on the C++ code-base, use the C++20 standard.
+- When modifying class definitions for which a ROOT dictionary is generated, remember to update their version in macros such as `ClassDefOverride` (e.g. `ClassDefOverride(MonitorObject, 15)` -> `ClassDefOverride(MonitorObject, 16)`).
+- Avoid changes which are not relevant to the current task.
+- When adding a new feature, write a unit test if feasible. Unit tests should use catch2.
+- When adding a new feature, extend the documentation accordingly and make sure that Tables of Contents are updated.
+- When providing a fix, explain what was causing the issue and how it was fixed.
+- When adding new code, make sure that necessary headers are included. Likewise, when removing code, remove the corresponding headers if they are not needed anymore.
+- When dealing with the code in `Modules`, prefer minimal changes which do not break the existing functionality.
\ No newline at end of file
diff --git a/.github/workflows/clean-test.yml b/.github/workflows/clean-test.yml
new file mode 100644
index 0000000000..b1490d3868
--- /dev/null
+++ b/.github/workflows/clean-test.yml
@@ -0,0 +1,57 @@
+---
+name: Clean PR checks
+
+'on':
+ workflow_dispatch:
+ inputs:
+ pr:
+ description: PR number in this repo to be cleaned
+ type: string # can't use number here
+ required: true
+ message:
+ description: Human-readable message displayed on the new pending status
+ type: string
+ required: false
+ default: ''
+
+ # Warning: GitHub limits the total number of inputs to 10, so a maximum of
+ # 8 checks is allowed here!
+ # Warning: the check_* keys are magic and must consist of the string
+ # "check_" followed by the applicable check name exactly. The
+ # "description" field is only the human-readable label for the input.
+ 'check_build/QualityControl/o2':
+ description: build/QualityControl/o2
+ type: boolean
+ default: true
+ 'check_build/QualityControl/o2-dataflow-cs8':
+ description: build/QualityControl/o2-dataflow-cs8
+ type: boolean
+ default: true
+ 'check_build/QualityControl/o2-cs8':
+ description: build/QualityControl/o2-cs8
+ type: boolean
+ default: true
+ 'check_build/QualityControl/o2-dataflow/macOS-arm':
+ description: build/QualityControl/o2-dataflow/macOS-arm
+ type: boolean
+ default: true
+ 'check_build/QualityControl/O2fst/o2':
+ description: Could you add build/QualityControl/O2fst/o2
+ type: boolean
+ default: true
+
+permissions: {}
+
+jobs:
+ clean:
+ name: Clean PR checks
+ uses: alisw/ali-bot/.github/workflows/clean-pr-checks.yml@master
+ with:
+ owner: ${{ github.event.repository.owner.login }}
+ repo: ${{ github.event.repository.name }}
+ pr: ${{ github.event.inputs.pr }}
+ message: ${{ github.event.inputs.message }}
+ checks: ${{ toJSON(github.event.inputs) }}
+ permissions:
+ pull-requests: read # to get last commit for pr (octokit/graphql-action)
+ statuses: write # for set-github-status
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
new file mode 100644
index 0000000000..2d13710723
--- /dev/null
+++ b/.github/workflows/format.yml
@@ -0,0 +1,42 @@
+name: Clang format
+
+on: [pull_request]
+
+jobs:
+ clang-format:
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+ # To get the merge base, we need the full history.
+ fetch-depth: 0
+ - name: Install prerequisites
+ env:
+ DEBIAN_FRONTEND: noninteractive
+ run: |
+ sudo apt update
+ sudo apt install -y clang-format-18
+ sudo update-alternatives --install /usr/bin/clang-format \
+ clang-format /usr/bin/clang-format-18 100
+ sudo update-alternatives --install /usr/bin/git-clang-format \
+ git-clang-format /usr/bin/git-clang-format-18 100
+ - name: Run clang-format on changed files
+ run: |
+ set -x
+ git fetch origin ${{ github.event.pull_request.base.ref }}
+ git fetch origin pull/${{ github.event.pull_request.number }}/head:${{ github.event.pull_request.head.ref }}
+ BASE_COMMIT=$(git merge-base HEAD ${{ github.event.pull_request.base.sha }})
+ COMMIT_FILES=$(git diff --diff-filter=d --name-only "$BASE_COMMIT" -- '*.cxx' '*.h' ':!*LinkDef*')
+ if [ "$COMMIT_FILES" == "" ]; then
+ exit 0 ;# nothing to check
+ fi
+
+ RESULT_OUTPUT=$(git-clang-format --commit ${BASE_COMMIT} --diff ${COMMIT_FILES})
+ if [ "$RESULT_OUTPUT" == "no modified files to format" ] || [ "$RESULT_OUTPUT" == "clang-format did not modify any files" ]; then
+ exit 0 ;# all good
+ else
+ git-clang-format --commit $BASE_COMMIT --diff
+ echo "$RESULT_OUTPUT"
+ exit 1
+ fi
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..c50e98ebf7
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,28 @@
+name: Release
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ bump_alidist:
+ runs-on: ubuntu-22.04
+ steps:
+ - run: curl -L https://github.com/github/hub/releases/download/v2.12.7/hub-linux-amd64-2.12.7.tgz | tar xz
+ - run: |
+ git config --global user.email ${{ secrets.GH_EMAIL }}
+ git config --global user.name ${{ secrets.GH_USERNAME }}
+ - run: git clone https://github.com/alisw/alidist.git
+ - run: |
+ cd alidist
+ CURRENT_VERSION=`cat ${{ secrets.MODULE }}.sh | grep "tag:" | awk '{print $2}'`
+ sed -i "s/${CURRENT_VERSION}/${GITHUB_REF##*/}/g" ${{ secrets.MODULE }}.sh
+ - run: |
+ cd alidist
+ git add .
+ git commit -m "Bump ${{ secrets.MODULE }} to ${GITHUB_REF##*/}"
+ git push "https://${{ secrets.GH_TOKEN }}@github.com/${{ secrets.ORG }}/alidist" HEAD:refs/heads/${{ secrets.MODULE }}-${GITHUB_REF##*/} -f > /dev/null 2>&1
+ - run: |
+ cd alidist
+ GITHUB_TOKEN=${{ secrets.GH_TOKEN }} ../hub-linux-amd64-2.12.7/bin/hub pull-request -h ${{ secrets.MODULE }}-${GITHUB_REF##*/} -b master -m "Bump ${{ secrets.MODULE }} to ${GITHUB_REF##*/}"
+
diff --git a/.gitignore b/.gitignore
index ed225499fe..2e0f8addcf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
/build/
.cproject
.project
+.vscode
+.cache
*~
.idea
*.jpg
@@ -10,3 +12,10 @@ README.md.*
cmake-build-*
Framework/test/testCcdbApi2.cxx
local_history.patch
+compile_commands.json
+.*.swp
+*.orig
+gh-md-toc
+.clangd
+/Framework/script/RepoCleaner/build/
+/Framework/script/RepoCleaner/qcrepocleaner.egg-info/
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index cbd8d3505a..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-language: cpp
-matrix:
- include:
- - os: linux
- dist: xenial
- env: TOOL=clang-format
- addons:
- apt:
- sources:
- - llvm-toolchain-xenial-7
- packages:
- - clang-format-7
- compiler: clang
-script:
- - if [[ $TOOL == "clang-format" ]] && [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
- cd $TRAVIS_BUILD_DIR;
- BASE_COMMIT=$(git rev-parse $TRAVIS_BRANCH);
- COMMIT_FILES=$(git diff --name-only $BASE_COMMIT | grep -i -v LinkDef);
- RESULT_OUTPUT="$(git-clang-format-7 --commit $BASE_COMMIT --diff --binary `which clang-format-7` $COMMIT_FILES)";
- if [ "$RESULT_OUTPUT" == "no modified files to format" ] || [ "$RESULT_OUTPUT" == "clang-format did not modify any files" ] ; then
- exit 0;
- else
- echo "$RESULT_OUTPUT";
- exit 1;
- fi
- fi
-notifications:
- email: false
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 0000000000..5063a55c4e
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,30 @@
+# This CITATION.cff file was generated with cffinit.
+# Visit https://bit.ly/cffinit to generate yours today!
+
+cff-version: 1.2.0
+title: The ALICE Data Quality Control framework
+message: >-
+ If you use this software, please cite it using the
+ metadata from this file.
+type: software
+authors:
+ - given-names: Barthélémy
+ family-names: von Haller
+ email: barthelemy.von.haller@cern.ch
+ affiliation: CERN
+ orcid: 'https://orcid.org/0000-0002-3422-4585'
+ - given-names: Piotr
+ family-names: Konopka
+ email: piotr.jan.konopka@cern.ch
+ affiliation: CERN
+ orcid: 'https://orcid.org/0000-0001-8738-7268'
+repository-code: 'https://github.com/AliceO2Group/QualityControl'
+keywords:
+ - data quality monitoring
+ - data quality
+ - quality control
+ - quality assurance
+ - cern
+ - alice
+ - message passing
+license: GPL-3.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 70f475b27a..850645813e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,51 +1,67 @@
# ---- CMake options ----
-cmake_minimum_required(VERSION 3.5.2 FATAL_ERROR)
-
-# Set cmake policy by version: https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html
-if(${CMAKE_VERSION} VERSION_LESS 3.12)
- cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
-else()
- cmake_policy(VERSION 3.12)
-endif()
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
enable_testing()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+cmake_policy(SET CMP0144 NEW) # find_package() uses upper-case _ROOT variables.
include(CMakeParseArguments)
-include(QCModulesUtils)
include(GNUInstallDirs)
# ---- Project ----
-project(
- QualityControl
- VERSION
- 0.12.0 # TODO update this automatically when there are new releases
- DESCRIPTION
- "O2 Quality Control"
- LANGUAGES CXX
-)
+project(QualityControl
+ VERSION 1.189.0
+ DESCRIPTION "O2 Data Quality Control Framework"
+ LANGUAGES C CXX)
+
+if(ONLYDOC)
+ add_subdirectory(doc)
+ return()
+endif()
+
+# Set CMAKE_INSTALL_LIBDIR explicitly to lib (to avoid lib64 on CC7)
+set(CMAKE_INSTALL_LIBDIR lib)
+
+include(GNUInstallDirs)
+
+if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
+endif()
+if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
+endif()
+if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
+endif()
-set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
-set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
-set(INCLUDE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/include")
+# ---- End Project ----
+# The line above is necessary for the generation of doxygen by travis
# ---- Compilation flags and build options ----
# Set the default build type to "RelWithDebInfo"
if(NOT CMAKE_BUILD_TYPE)
set(
- CMAKE_BUILD_TYPE "RelWithDebInfo"
- CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel Coverage."
- FORCE
- )
+ CMAKE_BUILD_TYPE
+ "RelWithDebInfo"
+ CACHE
+ STRING
+ "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel Coverage."
+ FORCE)
endif(NOT CMAKE_BUILD_TYPE)
+option(BUILD_SHARED_LIBS "Build shared libs" ON)
+
# Build targets with install rpath on Mac to dramatically speed up installation
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
-list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
+list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib"
+ isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_INSTALL_RPATH "@loader_path/../lib")
@@ -58,55 +74,41 @@ unset(isSystemDir)
# C++ standard
if(NOT DEFINED CMAKE_CXX_STANDARD)
- set(CMAKE_CXX_STANDARD 17)
+ set(CMAKE_CXX_STANDARD 20)
+ set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
endif()
-# Add compiler flags for warnings and (more importantly) fPIC and debug symbols
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wextra")
-
# Set fPIC for all targets
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# ---- Dependencies ----
-find_package(
- Boost 1.58
- COMPONENTS
- container
- unit_test_framework
- program_options
- system
- log
- signals
- system
-)
+find_package(Boost 1.58
+ COMPONENTS container
+ unit_test_framework
+ program_options
+ system
+ log
+ system)
find_package(Git QUIET)
find_package(Configuration REQUIRED)
find_package(Monitoring REQUIRED)
-find_package(MySQL)
find_package(Common REQUIRED)
find_package(InfoLogger REQUIRED)
-find_package(AliceO2 REQUIRED)
+find_package(BookkeepingApi REQUIRED) # it must be before O2 for some reasons.
+find_package(O2 CONFIG REQUIRED)
find_package(CURL REQUIRED)
-find_package(ZeroMQ REQUIRED)
-find_package(Arrow REQUIRED)
-find_package(GLFW)
-find_package(FairRoot REQUIRED)
-find_package(FairMQ REQUIRED)
+find_package(GLFW NAMES glfw3 CONFIG)
+find_package(FairMQ 1.4.41 REQUIRED)
find_package(FairLogger REQUIRED)
-find_package(
- ROOT 6.06.02
- COMPONENTS
- RHTTP
- Gui
- REQUIRED
-)
-
-set(ENABLE_MYSQL ON)
-if(NOT (MYSQL_FOUND AND TARGET ROOT::RMySQL))
- set(ENABLE_MYSQL OFF)
- message(WARNING "MySQL or ROOT::RMySQL not found, the corresponding classes won't be built.")
-endif()
+find_package(Occ REQUIRED)
+find_package(ROOT 6.06.02 COMPONENTS RHTTP Gui REQUIRED)
+
+# rdkafka is built by configure and does not provide FindPackage.cmake file
+find_library(RDKAFKA_LIB rdkafka REQUIRED PATHS ${RDKAFKA_ROOT}/lib)
+set(RDKAFKA_INCLUDE "${RDKAFKA_ROOT}/include")
+
+configure_file(getTestDataDirectory.cxx.in getTestDataDirectory.cxx)
# ---- Subdirectories ----
diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt
index 6ee7ada382..e2dd27055b 100644
--- a/Framework/CMakeLists.txt
+++ b/Framework/CMakeLists.txt
@@ -1,224 +1,432 @@
-# ---- Files ----
+# Produce the final Version.h using template Version.h.in and substituting
+# variables. We don't want to pollute our source tree with it, thus putting it in
+# binary tree.
+configure_file("include/QualityControl/Version.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/include/QualityControl/Version.h"
+ @ONLY)
+
+# ---- Library for IL ----
+add_library(O2QualityControlInfoLogger STATIC
+ src/QcInfoLogger.cxx
+)
+
+target_include_directories(O2QualityControlInfoLogger
+ PUBLIC
+ $
+)
-set(
- SRCS
+target_link_libraries(O2QualityControlInfoLogger
+ PUBLIC
+ AliceO2::InfoLogger
+)
+
+# ---- Library for the types ----
+add_library(O2QualityControlTypes
src/MonitorObject.cxx
+ src/QualityObject.cxx
src/Quality.cxx
- src/ObjectsManager.cxx
- src/Checker.cxx
- src/CheckerFactory.cxx
- src/CheckInterface.cxx
- src/DatabaseFactory.cxx
- src/CcdbDatabase.cxx
- src/InformationService.cxx
- src/InformationServiceDump.cxx
- src/TaskRunner.cxx
- src/TaskRunnerFactory.cxx
- src/TaskInterface.cxx
- src/RepositoryBenchmark.cxx
- src/HistoMerger.cxx
- src/InfrastructureGenerator.cxx
- src/runnerUtils.h
)
-set(
- HEADERS # needed for the dictionary generation
- include/QualityControl/MonitorObject.h
- include/QualityControl/Quality.h
- include/QualityControl/CheckInterface.h
- include/QualityControl/Checker.h
- include/QualityControl/CheckerFactory.h
- include/QualityControl/DatabaseInterface.h
- include/QualityControl/CcdbDatabase.h
- include/QualityControl/TaskRunner.h
- include/QualityControl/TaskRunnerFactory.h
- include/QualityControl/HistoMerger.h
- include/QualityControl/InfrastructureGenerator.h
+target_include_directories(
+ O2QualityControlTypes
+ PUBLIC $
+ $
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
)
-if(ENABLE_MYSQL)
- list(APPEND SRCS src/MySqlDatabase.cxx)
-endif()
+target_link_libraries(O2QualityControlTypes
+ PRIVATE
+ O2QualityControlInfoLogger
+ PUBLIC
+ AliceO2::BookkeepingApi
+ AliceO2::Common
+ O2::DataFormatsQualityControl
+ ROOT::Hist
+)
+
+add_root_dictionary(O2QualityControlTypes
+ HEADERS include/QualityControl/MonitorObject.h
+ include/QualityControl/QualityObject.h
+ include/QualityControl/Quality.h
+ include/QualityControl/Activity.h
+ LINKDEF include/QualityControl/TypesLinkDef.h)
+
+# ---- Kafka ----
+
+add_library(O2QualityControlKafkaProtos OBJECT
+ proto/events.proto)
-# Produce the final Version.h using template Version.h.in and substituting variables. We don't want to polute our source
-# tree with it, thus putting it in binary tree.
-configure_file(
- "include/QualityControl/Version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/${MODULE_NAME}/Version.h" @ONLY
+target_link_libraries(O2QualityControlKafkaProtos PUBLIC
+ protobuf::libprotobuf
)
-# ---- ROOT dictionary ----
-
-# ROOT dictionary the following root macros expect include dirs to be set as directory property TODO how to generate
-# this automatically ? ? ?
-get_directory_property(include_dirs INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/include")
-get_target_property(config_inc_dir AliceO2::Configuration INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${config_inc_dir}")
-get_target_property(arrow_inc_dir Arrow::Arrow INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${arrow_inc_dir}")
-get_target_property(monitoring_inc_dir AliceO2::Monitoring INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${monitoring_inc_dir}")
-get_target_property(infologger_inc_dir AliceO2::InfoLogger INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${infologger_inc_dir}")
-get_target_property(o2_inc_dir AliceO2::AliceO2 INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${o2_inc_dir}")
-get_target_property(common_inc_dir AliceO2::Common INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${common_inc_dir}")
-get_target_property(boost_inc_dir Boost::container INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${boost_inc_dir}")
-get_target_property(fairlogger_inc_dir FairLogger::FairLogger INTERFACE_INCLUDE_DIRECTORIES)
-list(APPEND include_dirs "${fairlogger_inc_dir}")
-list(APPEND include_dirs "${FAIRROOT_INCLUDE_DIR}")
-list(APPEND include_dirs "${FairMQ_INCDIR}")
-list(APPEND include_dirs "${FairMQ_INCDIR}/fairmq")
-list(REMOVE_DUPLICATES include_dirs)
-include_directories(${include_dirs})
-
-set(dict "QualityControlDict")
-set(dict_src ${CMAKE_CURRENT_BINARY_DIR}/${dict}.cxx)
-set_source_files_properties(${dict_src} PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast")
-set_source_files_properties(${dict_src} PROPERTIES GENERATED TRUE)
-
-root_generate_dictionary("${dict}" ${HEADERS} LINKDEF include/QualityControl/LinkDef.h)
-
-# TODO review how and what to install for dictionary
-install(
- FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${dict}_rdict.pcm ${CMAKE_CURRENT_BINARY_DIR}/lib${dict}.rootmap
- DESTINATION ${CMAKE_INSTALL_LIBDIR}
+target_include_directories(O2QualityControlKafkaProtos PUBLIC
+ "$"
)
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/proto")
+
+protobuf_generate(
+ TARGET O2QualityControlKafkaProtos
+ IMPORT_DIRS "${CMAKE_CURRENT_LIST_DIR}/proto"
+ PROTOC_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/proto")
+
# ---- Library ----
-add_library(QualityControl SHARED ${SRCS} QualityControlDict.cxx)
+add_library(O2QualityControl
+ src/Activity.cxx
+ src/ActivityHelpers.cxx
+ src/ObjectsManager.cxx
+ src/CheckRunner.cxx
+ src/BookkeepingQualitySink.cxx
+ src/AggregatorRunner.cxx
+ src/CheckRunnerFactory.cxx
+ src/AggregatorRunnerFactory.cxx
+ src/CheckInterface.cxx
+ src/AggregatorInterface.cxx
+ src/DatabaseFactory.cxx
+ src/CcdbDatabase.cxx
+ src/TaskFactory.cxx
+ src/TaskRunner.cxx
+ src/TaskRunnerFactory.cxx
+ src/TaskInterface.cxx
+ src/UserCodeInterface.cxx
+ src/RepositoryBenchmark.cxx
+ src/RepoPathUtils.cxx
+ src/stringUtils.cxx
+ src/InfrastructureGenerator.cxx
+ src/InfrastructureSpecReader.cxx
+ src/Check.cxx
+ src/Aggregator.cxx
+ src/DataHeaderHelpers.cxx
+ src/Triggers.cxx
+ src/TriggerHelpers.cxx
+ src/PostProcessingRunner.cxx
+ src/PostProcessingFactory.cxx
+ src/PostProcessingConfig.cxx
+ src/PostProcessingInterface.cxx
+ src/PostProcessingDevice.cxx
+ src/TrendingTask.cxx
+ src/TrendingTaskConfig.cxx
+ src/DummyDatabase.cxx
+ src/DataProducer.cxx
+ src/HistoProducer.cxx
+ src/DataProducerExample.cxx
+ src/MonitorObjectCollection.cxx
+ src/UpdatePolicyManager.cxx
+ src/AdvancedWorkflow.cxx
+ src/QualitiesToFlagCollectionConverter.cxx
+ src/DataSourceSpec.cxx
+ src/RootFileSink.cxx
+ src/RootFileSource.cxx
+ src/UpdatePolicyType.cxx
+ src/RootClassFactory.cxx
+ src/ConfigParamGlo.cxx
+ src/SliceTrendingTask.cxx
+ src/SliceTrendingTaskConfig.cxx
+ src/Bookkeeping.cxx
+ src/CustomParameters.cxx
+ src/runnerUtils.cxx
+ src/Timekeeper.cxx
+ src/TimekeeperSynchronous.cxx
+ src/TimekeeperAsynchronous.cxx
+ src/WorkflowType.cxx
+ src/TimekeeperFactory.cxx
+ src/RootFileStorage.cxx
+ src/ReductorHelpers.cxx
+ src/KafkaPoller.cxx
+ src/FlagHelpers.cxx
+ src/ObjectMetadataHelpers.cxx
+ src/QCInputsAdapters.cxx
+ src/QCInputsFactory.cxx
+ src/UserInputOutput.cxx
+)
target_include_directories(
- QualityControl
- PUBLIC $ $
+ O2QualityControl
+ PUBLIC $
+ $
+ ${MODERNCPPKAFKA_ROOT}
+ $
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
-)
-
-target_link_libraries(
- QualityControl
- PUBLIC
- Boost::boost
- FairLogger::FairLogger
- FairMQ::FairMQ
- ROOT::Hist
- AliceO2::Common
- AliceO2::InfoLogger
- AliceO2::Monitoring
- AliceO2::Configuration
- ROOT::Net
- AliceO2::AliceO2
- Boost::container
- PRIVATE
- Boost::system
- $<$:MySQL::MySQL>
- $<$:ROOT::RMySQL>
- ROOT::Gui
-)
+ $
+ )
-target_compile_definitions(QualityControl
- PRIVATE
- $<$:_WITH_MYSQL>
-)
+target_link_libraries(O2QualityControl
+ PUBLIC Boost::boost
+ FairLogger::FairLogger
+ FairMQ::FairMQ
+ ROOT::Hist
+ ROOT::TreePlayer
+ AliceO2::Common
+ AliceO2::Monitoring
+ AliceO2::Configuration
+ AliceO2::Occ
+ ROOT::Net
+ Boost::container
+ O2::Framework
+ O2::CCDB
+ O2QualityControlTypes
+ O2::Mergers
+ O2::DataSampling
+ O2::DataFormatsQualityControl
+ O2::DetectorsBase
+ O2::GlobalTracking
+ O2QualityControlKafkaProtos
+ ${RDKAFKA_LIB}
+ PRIVATE CURL::libcurl
+ O2QualityControlInfoLogger
+ )
+
+add_root_dictionary(O2QualityControl
+ HEADERS
+ include/QualityControl/CheckInterface.h
+ include/QualityControl/TaskInterface.h
+ include/QualityControl/UserCodeInterface.h
+ include/QualityControl/AggregatorInterface.h
+ include/QualityControl/PostProcessingInterface.h
+ include/QualityControl/TrendingTask.h
+ include/QualityControl/SliceInfoTrending.h
+ include/QualityControl/SliceTrendingTask.h
+ include/QualityControl/MonitorObjectCollection.h
+ LINKDEF include/QualityControl/LinkDef.h)
# ---- Executables ----
-set(
- EXE_SRCS
- src/runInformationService.cxx
- src/runInformationServiceDump.cxx
+set(EXE_SRCS
+ src/runDataProducer.cxx
+ src/runDataProducerExample.cxx
+ src/runHistoProducer.cxx
+ src/runQC.cxx
src/runBasic.cxx
src/runAdvanced.cxx
src/runReadout.cxx
- src/runMergerTest.cxx
- src/runReadoutForDataDump.cxx
src/runRepositoryBenchmark.cxx
-)
-
-set(
- EXE_NAMES
- qcInfoService
- qcInfoServiceDump
+ src/runPostProcessing.cxx
+ src/runPostProcessingOCC.cxx
+ src/runUploadRootObjects.cxx
+ src/runFileMerger.cxx
+ src/runMetadataUpdater.cxx
+ src/runBookkeepingBenchmark.cxx)
+
+set(EXE_NAMES
+ o2-qc-run-producer
+ o2-qc-run-producer-basic
+ o2-qc-run-histo-producer
+ o2-qc
+ o2-qc-run-basic
+ o2-qc-run-advanced
+ o2-qc-run-readout
+ o2-qc-repository-benchmark
+ o2-qc-run-postprocessing
+ o2-qc-run-postprocessing-occ
+ o2-qc-upload-root-objects
+ o2-qc-file-merger
+ o2-qc-metadata-updater
+ o2-qc-bk-benchmark)
+
+# These were the original names before the convention changed. We will get rid
+# of them but for the time being we want to create symlinks to avoid confusion.
+set(EXE_OLD_NAMES
+ qcRunProducer
+ o2-qc-run-producer-basic
+ o2-qc-run-histo-producer
+ o2-qc-run-qc
qcRunBasic
qcRunAdvanced
qcRunReadout
- runMergerTest
- qcRunReadoutForDataDump
repositoryBenchmark
-)
+ qcRunPostProcessing
+ qcRunPostProcessingOCC
+ o2-qc-upload-root-objects
+ o2-qc-file-merger
+ o2-qc-metadata-updater
+ o2-qc-bk-benchmark)
+
+
+# As per https://stackoverflow.com/questions/35765106/symbolic-links-cmake
+macro(install_symlink filepath sympath)
+ install(DIRECTORY DESTINATION bin) # just in case it is not there yet
+ install(
+ CODE
+ "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${filepath} ${sympath})"
+ )
+ install(CODE "message(\"-- Created symlink: ${sympath} -> ${filepath}\")")
+endmacro(install_symlink)
list(LENGTH EXE_SRCS count)
math(EXPR count "${count}-1")
foreach(i RANGE ${count})
list(GET EXE_SRCS ${i} src)
list(GET EXE_NAMES ${i} name)
+ list(GET EXE_OLD_NAMES ${i} oldname)
add_executable(${name} ${src})
- target_link_libraries(${name} PRIVATE QualityControl)
+ target_link_libraries(${name} PRIVATE O2QualityControl CURL::libcurl ROOT::Tree)
+ install_symlink(${name} ${CMAKE_INSTALL_FULL_BINDIR}/${oldname})
endforeach()
-# ---- Gui ----
-
-set(DATADUMP "")
-if(GLFW_FOUND)
- set(
- GUI_SRCS
- src/imgui/imgui.cpp
- src/imgui/imgui_draw.cpp
- src/imgui/imgui_impl_glfw_gl3.cpp
- src/imgui/gl3w.c
- src/imgui/imgui_widgets.cpp
- src/imgui/imgui_demo.cpp
- src/imgui/BaseGui.cxx
- src/DataDumpGui.cxx
- src/runDataDump.cxx
- )
-
- add_executable(dataDump ${GUI_SRCS})
-
- target_link_libraries(dataDump PRIVATE QualityControl GLFW::GLFW)
-
- set(DATADUMP "dataDump")
-else()
- message(STATUS "GLFW not found, DataDump will not be built")
-endif()
-
# ---- Tests ----
-set(
- TEST_SRCS
- test/testDbFactory.cxx
- test/testMonitorObject.cxx
- test/testPublisher.cxx
- test/testQcInfoLogger.cxx
- test/testInfrastructureGenerator.cxx
- test/testQCTask.cxx
- test/testQuality.cxx
+add_executable(o2-qc-test-core
+ test/testActivity.cxx
+ test/testActivityHelpers.cxx
+ test/testAggregatorInterface.cxx
+ test/testAggregatorRunner.cxx
+ test/testCheck.cxx
+ test/testCheckInterface.cxx
+ test/testCheckRunner.cxx
+ test/testCustomParameters.cxx
+ test/testDataHeaderHelpers.cxx
+ test/testInfrastructureGenerator.cxx
+ test/testMonitorObject.cxx
+ test/testPolicyManager.cxx
+ test/testPostProcessingRunner.cxx
+ test/testQuality.cxx
+ test/testQualityObject.cxx
+ test/testRootFileStorage.cxx
+ test/testTaskInterface.cxx
+ test/testTimekeeper.cxx
+ test/testTriggerHelpers.cxx
+ test/testVersion.cxx
+ test/testMonitorObjectCollection.cxx
+ test/testTrendingTask.cxx
+ test/testKafkaTests.cxx
+ test/testFlagHelpers.cxx
+ test/testQualitiesToFlagCollectionConverter.cxx
+ test/testQCInputs.cxx
+ test/testUserInputOutput.cxx
)
+set_property(TARGET o2-qc-test-core
+ PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)
+target_link_libraries(o2-qc-test-core PRIVATE O2QualityControl O2::Catch2)
+target_link_libraries(o2-qc-test-core PRIVATE O2::EMCALBase O2::EMCALCalib)
+target_include_directories(o2-qc-test-core PRIVATE ${CMAKE_SOURCE_DIR})
+
+add_test(NAME o2-qc-test-core COMMAND o2-qc-test-core)
+set_tests_properties(o2-qc-test-core PROPERTIES TIMEOUT 30)
+target_sources(o2-qc-test-core PRIVATE
+ ${CMAKE_BINARY_DIR}/getTestDataDirectory.cxx)
+target_include_directories(o2-qc-test-core PRIVATE ${CMAKE_SOURCE_DIR})
+target_include_directories(o2-qc-test-core PRIVATE $)
+
+set(TEST_SRCS
+ test/testDbFactory.cxx
+ test/testPublisher.cxx
+ test/testQcInfoLogger.cxx
+ test/testTaskRunner.cxx
+ test/testObjectsManager.cxx
+ test/testCcdbDatabase.cxx
+ test/testCcdbDatabaseExtra.cxx
+ test/testTriggers.cxx
+ test/testPostProcessingInterface.cxx
+ test/testPostProcessingConfig.cxx
+ test/testReductor.cxx
+ test/testCheckWorkflow.cxx
+ test/testWorkflow.cxx
+ test/testRepoPathUtils.cxx
+ test/testUserCodeInterface.cxx
+ test/testStringUtils.cxx
+ test/testRunnerUtils.cxx
+ test/testBookkeepingQualitySink.cxx
+ )
-foreach(test ${TEST_SRCS})
+set(TEST_ARGS
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "-b --run"
+ "-b --run"
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ )
+
+list(LENGTH TEST_SRCS count)
+math(EXPR count "${count}-1")
+foreach(i RANGE ${count})
+ list(GET TEST_SRCS ${i} test)
+ list(GET TEST_ARGS ${i} arg)
get_filename_component(test_name ${test} NAME)
string(REGEX REPLACE ".cxx" "" test_name ${test_name})
+ string(REPLACE " " ";" arg "${arg}") # make list of string (arguments) out of
+ # one string
add_executable(${test_name} ${test})
- target_link_libraries(${test_name} PRIVATE QualityControl Boost::unit_test_framework )
- add_test(NAME ${test_name} COMMAND ${test_name})
- set_tests_properties(${test_name} PROPERTIES TIMEOUT 60)
+ set_property(TARGET ${test_name}
+ PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)
+ target_link_libraries(${test_name}
+ PRIVATE O2QualityControl Boost::unit_test_framework)
+ add_test(NAME ${test_name} COMMAND ${test_name} ${arg})
+ set_tests_properties(${test_name} PROPERTIES TIMEOUT 30)
endforeach()
-install(
- FILES
- test/testQCFactory.json
- DESTINATION test
-)
+foreach(t testWorkflow testTaskRunner testCheckWorkflow
+ testPostProcessingConfig testPostProcessingInterface)
+ target_sources(${t} PRIVATE
+ ${CMAKE_BINARY_DIR}/getTestDataDirectory.cxx)
+ target_include_directories(${t} PRIVATE ${CMAKE_SOURCE_DIR})
+endforeach()
+
+target_include_directories(testCcdbDatabase PRIVATE $)
+
+set_property(TEST testWorkflow PROPERTY TIMEOUT 40)
+set_property(TEST testWorkflow PROPERTY LABELS slow)
+set_property(TEST testCheckWorkflow PROPERTY TIMEOUT 50)
+set_property(TEST testCheckWorkflow PROPERTY LABELS slow)
+set_property(TEST testObjectsManager PROPERTY TIMEOUT 30)
+set_property(TEST testObjectsManager PROPERTY LABELS slow)
+set_property(TEST testCcdbDatabase PROPERTY TIMEOUT 60)
+set_property(TEST testCcdbDatabase PROPERTY LABELS slow CCDB)
+set_property(TEST testCcdbDatabaseExtra PROPERTY LABELS manual CCDB)
+set_property(TEST testDbFactory PROPERTY LABELS CCDB)
+set_property(TEST testUserCodeInterface PROPERTY LABELS CCDB)
+
+# Add a functional test (QC-336)
+string(RANDOM UNIQUE_ID)
+configure_file(basic-functional.json.in ${CMAKE_BINARY_DIR}/tests/basic-functional.json) # substitute the unique id in the task name
+add_test(NAME functional_test COMMAND o2-qc-functional-test.sh)
+set_tests_properties(functional_test PROPERTIES ENVIRONMENT "JSON_DIR=${CMAKE_BINARY_DIR}/tests;UNIQUE_ID=${UNIQUE_ID}")
+set_property(TEST functional_test PROPERTY LABELS slow)
+set_property(TEST functional_test PROPERTY TIMEOUT 45)
+
+include(GenerateUniquePort)
+o2_generate_unique_port(UNIQUE_PORT_1)
+# UNIQUE_PORT_2 is UNIQUE_PORT_1 + 1
+# since we are guaranteed UNIQUE_PORT_1 is even.
+math(EXPR UNIQUE_PORT_2 "${UNIQUE_PORT_1} + 1")
+configure_file(multinode-test.json.in ${CMAKE_BINARY_DIR}/tests/multinode-test.json)
+add_test(NAME multinode_test COMMAND o2-qc-multinode-test.sh)
+set_tests_properties(multinode_test
+ PROPERTIES ENVIRONMENT "JSON_DIR=${CMAKE_BINARY_DIR}/tests;UNIQUE_PORT_1=${UNIQUE_PORT_1};UNIQUE_PORT_2=${UNIQUE_PORT_2}")
+set_property(TEST multinode_test PROPERTY LABELS slow)
+set_property(TEST multinode_test PROPERTY TIMEOUT 75)
+
+# Batch processing test
+string(RANDOM UNIQUE_ID)
+configure_file(batch-test.json.in ${CMAKE_BINARY_DIR}/tests/batch-test.json) # substitute the unique id in the task name
+add_test(NAME batch_test COMMAND o2-qc-batch-test.sh)
+set_tests_properties(batch_test PROPERTIES ENVIRONMENT "JSON_DIR=${CMAKE_BINARY_DIR}/tests;UNIQUE_ID=${UNIQUE_ID}")
+set_property(TEST batch_test PROPERTY LABELS slow)
+set_property(TEST batch_test PROPERTY TIMEOUT 60)
# ---- Install ----
# Build targets with install rpath on Mac to dramatically speed up installation
# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
-list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
+list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
+ "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
if("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR}")
@@ -228,32 +436,28 @@ endif()
unset(isSystemDir)
# Install library and binaries
-install(
- TARGETS QualityControl ${EXE_NAMES} ${DATADUMP}
- EXPORT QualityControlTargets
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-)
+install(TARGETS O2QualityControl O2QualityControlTypes O2QualityControlKafkaProtos ${EXE_NAMES}
+ EXPORT QualityControlTargets
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
# Install headers
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/QualityControl DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/QualityControl
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
# Create version file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
- "${CMAKE_CURRENT_BINARY_DIR}/cmake/QualityControlConfigVersion.cmake"
- VERSION ${PACKAGE_VERSION}
- COMPATIBILITY AnyNewerVersion
-)
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake/QualityControlConfigVersion.cmake"
+ VERSION ${PACKAGE_VERSION}
+ COMPATIBILITY AnyNewerVersion)
# Export targets
-install(
- EXPORT QualityControlTargets
- FILE QualityControlTargets.cmake
- NAMESPACE QualityControl::
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QualityControl
-)
+install(EXPORT QualityControlTargets
+ FILE QualityControlTargets.cmake
+ NAMESPACE QualityControl::
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QualityControl)
# Configure and install Config files
configure_package_config_file(
@@ -262,33 +466,49 @@ configure_package_config_file(
INSTALL_DESTINATION
"${CMAKE_INSTALL_LIBDIR}/cmake/QualityControl"
PATH_VARS
- CMAKE_INSTALL_PREFIX
-)
-
-install(
- FILES
- "${CMAKE_CURRENT_BINARY_DIR}/cmake/QualityControlConfig.cmake"
- "${CMAKE_CURRENT_BINARY_DIR}/cmake/QualityControlConfigVersion.cmake"
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QualityControl
-)
-
-# ---- Extra scripts ----
+ CMAKE_INSTALL_PREFIX)
-install(PROGRAMS script/qcDatabaseSetup.sh DESTINATION bin)
install(
- FILES
- example-default.json
- alfa.json
- dataDump.json
- DESTINATION etc
-)
-install(
- FILES
- basic.json
- basic-no-sampling.json
- advanced.json
- readout.json
- readout-no-sampling.json
- readoutForDataDump.json
- DESTINATION etc
-)
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/QualityControlConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake/QualityControlConfigVersion.cmake"
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QualityControl)
+
+# ---- Install config files and scripts ----
+
+install(FILES example-default.json
+ basic.json
+ basic-aggregator.json
+ basic-external-histo.json
+ basic-no-sampling.json
+ advanced.json
+ advanced-aggregator.json
+ advanced-external-histo.json
+ multiNode.json
+ readout.json
+ readout-no-sampling.json
+ postprocessing.json
+ DESTINATION etc)
+
+install(PROGRAMS script/o2-qc-functional-test.sh
+ script/o2-qc-multinode-test.sh
+ script/o2-qc-batch-test.sh
+ DESTINATION bin)
+
+# ---- Copy test files ----
+#
+# Using file(COPY is wrong because cmake will not detect when the files are modified.
+# Using install is also wrong because we don't want to install nor package the test files.
+# The solution is to use configure_file with COPYONLY.
+
+set(TEST_FILES
+ "testSharedConfig.json"
+ "testEmptyConfig.json"
+ "testCheckWorkflow.json"
+ "testWorkflow.json"
+ "testThrowNameClash.json")
+set(TEST_FILES_PREFIXED ${TEST_FILES})
+list(TRANSFORM TEST_FILES_PREFIXED PREPEND ${CMAKE_BINARY_DIR}/tests/)
+
+foreach(test_file ${TEST_FILES})
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/${test_file} ${CMAKE_BINARY_DIR}/tests/${test_file} COPYONLY)
+endforeach()
diff --git a/Framework/__init__.py b/Framework/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Framework/advanced-aggregator.json b/Framework/advanced-aggregator.json
new file mode 100644
index 0000000000..c0d6fe83e0
--- /dev/null
+++ b/Framework/advanced-aggregator.json
@@ -0,0 +1,159 @@
+{
+ "qc": {
+ "config": {
+ "database": {
+ "implementation": "CCDB",
+ "host": "ccdb-test.cern.ch:8080",
+ "username": "not_applicable",
+ "password": "not_applicable",
+ "name": "not_applicable"
+ },
+ "Activity": {
+ "number": "42",
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ },
+ "infologger": { "": "Configuration of the Infologger (optional).",
+ "filterDiscardDebug": "true", "": "Set to true to discard debug and trace messages (default: false)",
+ "filterDiscardLevel": "21", "": "Message at this level or above are discarded (default: 21 - Trace)"
+ }
+ },
+ "tasks": {
+ "dataSizeTask": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonTask",
+ "moduleName": "QcSkeleton",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "10",
+ "dataSource": {
+ "type": "dataSamplingPolicy",
+ "name": "tst2"
+ },
+ "location": "remote"
+ },
+ "someNumbersTask": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonTask",
+ "moduleName": "QcSkeleton",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "10",
+ "dataSource": {
+ "type": "dataSamplingPolicy",
+ "name": "tst1"
+ },
+ "location": "remote"
+ }
+ },
+ "checks": {
+ "dataSizeCheck": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "dataSizeTask",
+ "MOs": ["example"]
+ }]
+ },
+ "someNumbersCheck": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnEachSeparately",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "someNumbersTask",
+ "MOs": ["example"]
+ }]
+ }
+ },
+ "aggregators": {
+ "MyAggregator1": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check",
+ "name": "dataSizeCheck"
+ }, {
+ "type": "Check",
+ "name": "someNumbersCheck"
+ }]
+ },
+ "MyAggregator2": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check",
+ "name": "dataSizeCheck"
+ }, {
+ "type": "Check", "": "this one is using onEachSeparately and thus it sends under a full path",
+ "name": "someNumbersCheck",
+ "QOs": ["someNumbersTask/example"], "": "also possible to ignore it altogether, meaning we take all objects"
+ }]
+ },
+ "MyAggregator3": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Aggregator",
+ "name": "MyAggregator1", "": "no QOs parameter -> all QOs of this aggregator",
+ "QOs": ["newQuality"], "": "list all objects we are interested in"
+ }, {
+ "type": "Aggregator",
+ "name": "MyAggregator2",
+ "QOs": ["newQuality", "another"], "": "if we omitted the QOs for a data source we would default to OnAny"
+ }]
+ }
+ }
+ },
+ "dataSamplingPolicies": [
+ {
+ "id": "tst1",
+ "active": "true",
+ "machines": [],
+ "query" : "data:TST/SUM/2;param:TST/PARAM/2",
+ "samplingConditions": [
+ {
+ "condition": "random",
+ "fraction": "0.1",
+ "seed": "32112332123"
+ }
+ ],
+ "blocking": "false"
+ },
+ {
+ "id": "tst2",
+ "active": "true",
+ "machines": [],
+ "query" : "data:TST/DATA",
+ "samplingConditions": [
+ {
+ "condition": "payloadSize",
+ "lowerLimit": "8000",
+ "upperLimit": "10000"
+ }
+ ],
+ "blocking": "false"
+ }
+ ]
+}
diff --git a/Framework/advanced-external-histo.json b/Framework/advanced-external-histo.json
new file mode 100644
index 0000000000..ec93326a4f
--- /dev/null
+++ b/Framework/advanced-external-histo.json
@@ -0,0 +1,96 @@
+{
+ "qc": {
+ "config": {
+ "database": {
+ "implementation": "CCDB",
+ "host": "ccdb-test.cern.ch:8080",
+ "username": "not_applicable",
+ "password": "not_applicable",
+ "name": "not_applicable"
+ },
+ "Activity": {
+ "number": "42",
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ }
+ },
+ "tasks": {
+ "QcTask": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonTask",
+ "moduleName": "QcSkeleton",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "10",
+ "dataSource_comment": "The other type of dataSource is \"direct\", see basic-no-sampling.json.",
+ "dataSource": {
+ "type": "dataSamplingPolicy",
+ "name": "tst-raw"
+ },
+ "taskParameters": {
+ "myOwnKey": "myOwnValue"
+ },
+ "location": "remote"
+ }
+ },
+ "externalTasks": {
+ "External-1": {
+ "active": "true",
+ "query": "External-1:TST/HISTO/0", "": "Use the task name as binding (encouraged)"
+ },
+ "External-2": {
+ "active": "true",
+ "query": "External-2:TST/HISTO/1", "": "Use the task name as binding (encouraged)"
+ }
+ },
+ "checks": {
+ "QcCheck-external-1": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "ExternalTask",
+ "name": "External-1",
+ "MOs": ["hello_0", "hello_1"]
+ }]
+ },
+ "QcCheck2": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "QcTask",
+ "MOs": ["example"]
+ }]
+ }
+ }
+ },
+ "dataSamplingPolicies": [
+ {
+ "id": "tst-raw",
+ "active": "true",
+ "machines": [],
+ "query": "data:TST/RAWDATA/0",
+ "samplingConditions": [
+ {
+ "condition": "random",
+ "fraction": "0.1",
+ "seed": "1234"
+ }
+ ],
+ "blocking": "false"
+ }
+ ]
+}
diff --git a/Framework/advanced.json b/Framework/advanced.json
index 283656d5de..5a37ec8702 100644
--- a/Framework/advanced.json
+++ b/Framework/advanced.json
@@ -10,88 +10,290 @@
},
"Activity": {
"number": "42",
- "type": "2"
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ },
+ "infologger": { "": "Configuration of the Infologger (optional).",
+ "filterDiscardDebug": "true", "": "Set to true to discard debug and trace messages (default: false)",
+ "filterDiscardLevel": "21", "": "Message at this level or above are discarded (default: 21 - Trace)"
}
},
"tasks": {
- "dataSizeTask": {
+ "AdvTaskA": {
"active": "true",
"className": "o2::quality_control_modules::skeleton::SkeletonTask",
"moduleName": "QcSkeleton",
+ "detectorName": "TST",
"cycleDurationSeconds": "10",
- "maxNumberCycles": "-1",
"dataSource": {
"type": "dataSamplingPolicy",
- "name": "tst2"
- },
- "location": "local",
- "machines": [
- "o2flptst1",
- "o2flptst2",
- "o2flptst3"
- ]
+ "name": "tst"
+ }
},
- "someNumbersTask": {
+ "AdvTaskB": {
"active": "true",
"className": "o2::quality_control_modules::skeleton::SkeletonTask",
"moduleName": "QcSkeleton",
- "cycleDurationSeconds": "10",
- "maxNumberCycles": "-1",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "25",
"dataSource": {
- "type": "dataSamplingPolicy",
- "name": "tst1"
+ "type": "direct",
+ "query": "data:TST/SUM"
+ }
+ }
+ },
+ "checks": {
+ "AdvCheckA1": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "AdvTaskA",
+ "MOs": ["example"]
+ }]
+ },
+ "AdvCheckA2": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "AdvTaskA",
+ "MOs": ["example", "example2"]
+ }]
+ },
+ "AdvCheckB": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::TrendCheck",
+ "moduleName": "QualityControl",
+ "detectorName": "TST",
+ "policy": "OnAll",
+ "extendedCheckParameters": {
+ "default": {
+ "default": {
+ "trendCheckMode": "DeviationFromMean",
+ "nPointsForAverage": "3",
+ "thresholdsBad": "-0.02,0.02",
+ "thresholdsMedium": "-0.005,0.005"
+ }
+ }
},
- "location": "remote"
+ "dataSource": [
+ {
+ "type": "PostProcessing",
+ "name": "AdvTrendB",
+ "MOs" : [
+ "mean_of_histogram"
+ ]
+ }
+ ]
+ }
+ },
+ "aggregators": {
+ "AdvAggregatorA": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::WorstOfAllAggregator",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check",
+ "name": "AdvCheckA1"
+ }, {
+ "type": "Check",
+ "name": "AdvCheckA2"
+ }]
+ },
+ "AdvAggregatorB": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::WorstOfAllAggregator",
+ "moduleName": "QcCommon",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check",
+ "name": "AdvCheckB"
+ }]
+ },
+ "AdvAggregatorC": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::WorstOfAllAggregator",
+ "moduleName": "QcCommon",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Aggregator",
+ "name": "AdvAggregatorA",
+ "QOs": []
+ }, {
+ "type": "Aggregator",
+ "name": "AdvAggregatorB",
+ "QOs": []
+ }]
+ }
+
+ },
+ "postprocessing": {
+ "AdvTrendB": {
+ "active": "true",
+ "className": "o2::quality_control::postprocessing::TrendingTask",
+ "moduleName": "QualityControl",
+ "detectorName": "TST",
+ "dataSources": [
+ {
+ "type": "repository",
+ "path": "TST/MO/AdvTaskB",
+ "names": [ "example" ],
+ "reductorName": "o2::quality_control_modules::common::TH1Reductor",
+ "moduleName": "QcCommon"
+ }
+ ],
+ "plots": [
+ {
+ "name": "mean_of_histogram",
+ "title": "Mean trend of the example histogram",
+ "graphAxisLabel": "Mean X:time",
+ "graphYRange": "0:10000",
+ "graphs" : [
+ {
+ "name": "mean_trend",
+ "title": "mean trend",
+ "varexp": "example.mean:time",
+ "selection": "",
+ "option": "*L PLC PMC"
+ }
+ ]
+ }
+ ],
+ "initTrigger": [
+ "userorcontrol"
+ ],
+ "updateTrigger": [
+ "newobject:qcdb:TST/MO/AdvTaskB/example"
+ ],
+ "stopTrigger": [
+ "userorcontrol"
+ ]
+ },
+ "AdvTrendA": {
+ "active": "true",
+ "className": "o2::quality_control::postprocessing::TrendingTask",
+ "moduleName": "QualityControl",
+ "detectorName": "TST",
+ "dataSources": [
+ {
+ "type": "repository-quality",
+ "path": "TST/QO",
+ "names": [ "AdvCheckA1" ],
+ "reductorName": "o2::quality_control_modules::common::QualityReductor",
+ "moduleName": "QcCommon"
+ }
+ ],
+ "plots": [
+ {
+ "name": "example_quality",
+ "title": "Trend of the example histogram's quality",
+ "graphs" : [{
+ "varexp": "AdvCheckA1.name:time",
+ "selection": "",
+ "option": "*"
+ }]
+ }
+ ],
+ "initTrigger": [
+ "userorcontrol"
+ ],
+ "updateTrigger": [
+ "newobject:qcdb:TST/QO/AdvCheckA1"
+ ],
+ "stopTrigger": [
+ "userorcontrol"
+ ]
+ },
+ "AdvQualityTask": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::QualityTask",
+ "moduleName": "QualityControl",
+ "detectorName": "TST",
+ "qualityGroups": [
+ {
+ "name" : "global",
+ "title" : "Advanced example: Aggregators",
+ "path": "TST/QO",
+ "ignoreQualitiesDetails" : [],
+ "inputObjects": [
+ {
+ "name" : "AdvAggregatorC/AdvAggregatorC",
+ "title" : "Adv. Aggregator C (total)"
+ },
+ {
+ "name" : "AdvAggregatorA/AdvAggregatorA",
+ "title" : "Adv. Aggregator A"
+ },
+ {
+ "name" : "AdvAggregatorB/AdvAggregatorB",
+ "title" : "Adv. Aggregator B"
+ }
+ ]
+ },
+ {
+ "name" : "details",
+ "title" : "Advanced example: Checks",
+ "path": "TST/QO",
+ "ignoreQualitiesDetails" : [],
+ "inputObjects": [
+ {
+ "name" : "AdvCheckA1",
+ "title" : ""
+ },
+ {
+ "name" : "AdvCheckA2",
+ "title" : ""
+ },
+ {
+ "name" : "AdvCheckB",
+ "title" : ""
+ }
+ ]
+ }
+ ],
+ "initTrigger": [
+ "userorcontrol"
+ ],
+ "updateTrigger": [
+ "newobject:qcdb:TST/QO/AdvAggregatorC/AdvAggregatorC"
+ ],
+ "stopTrigger": [
+ "userorcontrol"
+ ]
}
}
},
"dataSamplingPolicies": [
{
- "id": "tst1",
+ "id": "tst",
"active": "true",
- "machines": [],
- "dataHeaders": [
- {
- "binding": "sum",
- "dataOrigin": "TST",
- "dataDescription": "SUM"
- },
- {
- "binding": "param",
- "dataOrigin": "TST",
- "dataDescription": "PARAM"
- }
- ],
- "subSpec": "2",
+ "query" : "data:TST/DATA/1",
"samplingConditions": [
{
"condition": "random",
"fraction": "0.1",
- "seed": "32112332123"
- }
- ],
- "blocking": "false"
- },
- {
- "id": "tst2",
- "active": "true",
- "machines": [],
- "dataHeaders": [
- {
- "binding": "data",
- "dataOrigin": "TST",
- "dataDescription": "DATA"
- }
- ],
- "subSpec": "*",
- "samplingConditions": [
- {
- "condition": "payloadSize",
- "lowerLimit": "8000",
- "upperLimit": "10000"
+ "seed": "0"
}
- ],
- "blocking": "false"
+ ]
}
]
-}
\ No newline at end of file
+}
diff --git a/Framework/alfa.json b/Framework/alfa.json
deleted file mode 100644
index b3f9148586..0000000000
--- a/Framework/alfa.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "fairMQOptions": {
- "devices": [
- {
- "id": "myTask_1",
- "channels": [
- {
- "name": "data-out",
- "sockets": [
- {
- "type": "pub",
- "method": "bind",
- "address": "tcp://*:5556",
- "sndBufSize": 100,
- "rcvBufSize": 100,
- "rateLogging": 0
- }
- ]
- },
- {
- "name": "information-service-out",
- "sockets": [
- {
- "type": "pub",
- "method": "connect",
- "address": "tcp://localhost:5560",
- "sndBufSize": 100,
- "rcvBufSize": 100,
- "rateLogging": 0
- }
- ]
- }
- ]
- },
- {
- "id": "daqTask",
- "channels": [
- {
- "name": "data-out",
- "sockets": [
- {
- "type": "pub",
- "method": "bind",
- "address": "tcp://*:5557",
- "sndBufSize": 100,
- "rcvBufSize": 100,
- "rateLogging": 0
- }
- ]
- },
- {
- "name": "information-service-out",
- "sockets": [
- {
- "type": "pub",
- "method": "connect",
- "address": "tcp://localhost:5560",
- "sndBufSize": 100,
- "rcvBufSize": 100,
- "rateLogging": 0
- }
- ]
- }
- ]
- }
- ]
- }
-}
-
diff --git a/Framework/alfaTestReceiver.json b/Framework/alfaTestReceiver.json
deleted file mode 100644
index d1e098cb0d..0000000000
--- a/Framework/alfaTestReceiver.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "fairMQOptions": {
- "devices": [
- {
- "id": "receiver",
- "channels": [
- {
- "name": "data",
- "sockets": [
- {
- "type": "sub",
- "method": "connect",
- "address": "tcp://localhost:5556",
- "sndBufSize": 100,
- "rcvBufSize": 100,
- "rateLogging": 0
- }
- ]
- }
- ]
- }
- ]
- }
-}
\ No newline at end of file
diff --git a/Framework/basic-aggregator.json b/Framework/basic-aggregator.json
new file mode 100644
index 0000000000..a5c553741f
--- /dev/null
+++ b/Framework/basic-aggregator.json
@@ -0,0 +1,111 @@
+{
+ "qc": {
+ "config": {
+ "database": {
+ "implementation": "CCDB",
+ "host": "ccdb-test.cern.ch:8080",
+ "username": "not_applicable",
+ "password": "not_applicable",
+ "name": "not_applicable"
+ },
+ "Activity": {
+ "number": "42",
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ },
+ "infologger": { "": "Configuration of the Infologger (optional).",
+ "filterDiscardDebug": "false", "": "Set to 1 to discard debug and trace messages (default: false)",
+ "filterDiscardLevel": "21", "": "Message at this level or above are discarded (default: 21 - Trace)"
+ }
+ },
+ "tasks": {
+ "QcTask": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonTask",
+ "moduleName": "QcSkeleton",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "10",
+ "dataSource_comment": "The other type of dataSource is \"direct\", see basic-no-sampling.json.",
+ "dataSource": {
+ "type": "dataSamplingPolicy",
+ "name": "tst-raw"
+ },
+ "taskParameters": {
+ "myOwnKey": "myOwnValue"
+ },
+ "location": "remote"
+ }
+ },
+ "checks": {
+ "QcCheck": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "QcTask",
+ "MOs": ["example"]
+ }]
+ },
+ "QcCheck2": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnEachSeparately",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "QcTask",
+ "MOs": ["example"]
+ }]
+ }
+ },
+ "aggregators": {
+ "MyAggregator1": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check", "": "for a check which produces a single result do it like that",
+ "name": "QcCheck", "": "no need to specify each object because there is only 1"
+ },
+ {
+ "type": "Check", "": "for a check which produces a single result do it like that",
+ "name": "QcCheck2", "": "no need to specify each object because there is only 1",
+ "QOs": ["QcTask/example"], "": "also possible to ignore it altogether, meaning we take all objects"
+ }],
+ "aggregatorParameters": {
+ "myOwnKey": "myOwnValue"
+ }
+ }
+ }
+ },
+ "dataSamplingPolicies": [
+ {
+ "id": "tst-raw",
+ "active": "true",
+ "machines": [],
+ "query": "data:TST/RAWDATA/0",
+ "samplingConditions": [
+ {
+ "condition": "random",
+ "fraction": "0.1",
+ "seed": "1234"
+ }
+ ],
+ "blocking": "false"
+ }
+ ]
+}
diff --git a/Framework/basic-external-histo.json b/Framework/basic-external-histo.json
new file mode 100644
index 0000000000..bbf7e78d99
--- /dev/null
+++ b/Framework/basic-external-histo.json
@@ -0,0 +1,50 @@
+{
+ "qc": {
+ "config": {
+ "database": {
+ "implementation": "CCDB",
+ "host": "ccdb-test.cern.ch:8080",
+ "username": "not_applicable",
+ "password": "not_applicable",
+ "name": "not_applicable"
+ },
+ "Activity": {
+ "number": "42",
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ }
+ },
+ "tasks": {
+ },
+ "externalTasks": {
+ "External-1": {
+ "active": "true",
+ "query": "External-1:TST/HISTO/0", "": "Use the task name as binding (encouraged)"
+ }
+ },
+ "checks": {
+ "QcCheck": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "ExternalTask",
+ "name": "External-1",
+ "MOs": ["hello_0"]
+ }]
+ }
+ }
+ },
+ "dataSamplingPolicies": [
+ ]
+}
diff --git a/Framework/basic-functional.json.in b/Framework/basic-functional.json.in
new file mode 100644
index 0000000000..2d47226ca6
--- /dev/null
+++ b/Framework/basic-functional.json.in
@@ -0,0 +1,91 @@
+{
+ "qc": {
+ "config": {
+ "database": {
+ "implementation": "CCDB",
+ "host": "ccdb-test.cern.ch:8080",
+ "username": "not_applicable",
+ "password": "not_applicable",
+ "name": "not_applicable"
+ },
+ "Activity": {
+ "number": "42",
+ "type": "NONE",
+ "start": "8000000",
+ "end": "9000000",
+ "periodName": "LHC9000x",
+ "passName": "apass500"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ }
+ },
+ "tasks": {
+ "FunctionalTest@UNIQUE_ID@": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonTask",
+ "moduleName": "QcSkeleton",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "10",
+ "dataSource_comment": "The other type of dataSource is \"direct\", see basic-no-sampling.json.",
+ "dataSource": {
+ "type": "dataSamplingPolicy",
+ "name": "tst-raw"
+ },
+ "taskParameters": {
+ "myOwnKey": "myOwnValue"
+ },
+ "location": "remote"
+ }
+ },
+ "checks": {
+ "FunctionalTest@UNIQUE_ID@": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "FunctionalTest@UNIQUE_ID@",
+ "MOs": ["example"]
+ }]
+ }
+ },
+ "aggregators": {
+ "FunctionalTestAggregator@UNIQUE_ID@": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check" , "": "for a check which produces a single result do it like that",
+ "name": "FunctionalTest@UNIQUE_ID@" , "": "no need to specify each object because there is only 1"
+ }]
+ }
+ }
+ },
+ "dataSamplingPolicies": [
+ {
+ "id": "tst-raw",
+ "active": "true",
+ "machines": [],
+ "query": "data:TST/RAWDATA/0",
+ "samplingConditions": [
+ {
+ "condition": "random",
+ "fraction": "0.1",
+ "seed": "1234"
+ }
+ ],
+ "blocking": "false"
+ }
+ ]
+}
diff --git a/Framework/basic-no-sampling.json b/Framework/basic-no-sampling.json
index 1147fb581d..221ce7205c 100644
--- a/Framework/basic-no-sampling.json
+++ b/Framework/basic-no-sampling.json
@@ -10,7 +10,16 @@
},
"Activity": {
"number": "42",
- "type": "2"
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
}
},
"tasks": {
@@ -18,23 +27,34 @@
"active": "true",
"className": "o2::quality_control_modules::skeleton::SkeletonTask",
"moduleName": "QcSkeleton",
+ "detectorName": "TST",
"cycleDurationSeconds": "10",
- "maxNumberCycles": "-1",
"dataSource": {
"type": "direct",
- "binding": "its-rawdata",
- "dataOrigin": "ITS",
- "dataDescription": "RAWDATA",
- "subSpec": "0"
+ "query" : "data:TST/RAWDATA/0"
},
"taskParameters": {
"nothing": "rien"
},
"location": "remote"
}
+ },
+ "checks": {
+ "QcCheck": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "QcTask",
+ "MOs": ["example"]
+ }]
+ }
}
},
"dataSamplingPolicies": [
]
-}
\ No newline at end of file
+}
diff --git a/Framework/basic.json b/Framework/basic.json
index 38689eb5df..1d8ff36da3 100644
--- a/Framework/basic.json
+++ b/Framework/basic.json
@@ -6,53 +6,105 @@
"host": "ccdb-test.cern.ch:8080",
"username": "not_applicable",
"password": "not_applicable",
- "name": "not_applicable"
+ "name": "not_applicable",
+ "maxObjectSize": "2097152", "": "[Bytes, default=2MB] Maximum size allowed, larger objects are rejected."
},
"Activity": {
"number": "42",
- "type": "2"
+ "type": "NONE",
+ "periodName": "", "": "Period name - e.g. LHC22c, LHC22c1b_test",
+ "passName": "", "": "Pass type - e.g. spass, cpass1",
+ "provenance": "qc", "": "Provenance - qc or qc_mc depending whether it is normal data or monte carlo data"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ },
+ "infologger": { "": "Configuration of the Infologger (optional).",
+ "filterDiscardDebug": "false", "": "Set to true to discard debug and trace messages (default: false)",
+ "filterDiscardLevel": "12", "": "Message at this level or above are discarded (default: 21 - Trace)",
+ "filterDiscardFile": "/tmp/_ID_.txt", "": ["If set, the messages discarded because of filterDiscardLevel",
+ "will go to this file (default: ); The keyword _ID_ is replaced by the device id. Discarded Debug ",
+ "messages won't go there."]
+ },
+ "bookkeeping": {
+ "url": ""
}
},
"tasks": {
"QcTask": {
"active": "true",
+ "critical": "false", "": "if false the task is allowed to die without stopping the workflow, default: true",
"className": "o2::quality_control_modules::skeleton::SkeletonTask",
"moduleName": "QcSkeleton",
- "cycleDurationSeconds": "10",
- "maxNumberCycles": "-1",
- "dataSource_comment": "The other type of dataSource is \"direct\", see basic-no-sampling.json.",
+ "detectorName": "TST",
+ "": "The last item in cycleDurations will be used for the rest of the duration whatever the period",
+ "cycleDurations": [
+ {"cycleDurationSeconds": 10, "validitySeconds": 35},
+ {"cycleDurationSeconds": 12, "validitySeconds": 1}
+ ],
+ "": "The other type of dataSource is \"direct\", see basic-no-sampling.json.",
"dataSource": {
"type": "dataSamplingPolicy",
- "name": "its-raw"
+ "name": "tst-raw"
},
- "taskParameters": {
- "nothing": "rien"
+ "extendedTaskParameters": {
+ "default": {
+ "default": {
+ "myOwnKey": "myOwnValue",
+ "myOwnKey2": "myOwnValue2"
+ }
+ },
+ "PHYSICS": {
+ "default": {
+ "myOwnKey1": "myOwnValue1b",
+ "myOwnKey2": "myOwnValue2b"
+ }
+ }
},
- "location": "remote"
+ "saveObjectsToFile": "", "": "For debugging, path to the file where to save. If empty or missing it won't save."
+ }
+ },
+ "checks": {
+ "QcCheck": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "QcTask",
+ "MOs": ["example"]
+ }],
+ "extendedCheckParameters": {
+ "physics": {
+ "pp": {
+ "myOwnKey1": "myOwnValue1c"
+ }
+ }
+ }
}
}
},
"dataSamplingPolicies": [
{
- "id": "its-raw",
+ "id": "tst-raw",
"active": "true",
"machines": [],
- "dataHeaders": [
- {
- "binding": "random",
- "dataOrigin": "ITS",
- "dataDescription": "RAWDATA"
- }
- ],
- "subSpec": "0",
+ "query": "data:TST/RAWDATA/0",
"samplingConditions": [
{
"condition": "random",
"fraction": "0.1",
"seed": "1234"
}
- ],
- "blocking": "false"
+ ]
}
]
-}
\ No newline at end of file
+}
diff --git a/Framework/batch-test.json.in b/Framework/batch-test.json.in
new file mode 100644
index 0000000000..b0541e6e15
--- /dev/null
+++ b/Framework/batch-test.json.in
@@ -0,0 +1,74 @@
+{
+ "qc": {
+ "config": {
+ "database": {
+ "implementation": "CCDB",
+ "host": "ccdb-test.cern.ch:8080",
+ "username": "not_applicable",
+ "password": "not_applicable",
+ "name": "not_applicable"
+ },
+ "Activity": {
+ "number": "42",
+ "type": "NONE",
+ "start": "8000000",
+ "end": "9000000",
+ "periodName": "LHC9000x",
+ "passName": "apass500"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
+ }
+ },
+ "tasks": {
+ "BatchTestTask@UNIQUE_ID@": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonTask",
+ "moduleName": "QcSkeleton",
+ "detectorName": "TST",
+ "cycleDurationSeconds": "100",
+ "dataSource": {
+ "type": "dataSamplingPolicy",
+ "name": "tst-raw"
+ },
+ "movingWindows" : [ "example" ]
+ }
+ },
+ "checks": {
+ "BatchTestCheck@UNIQUE_ID@": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonCheck",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Task",
+ "name": "BatchTestTask@UNIQUE_ID@",
+ "MOs": ["example"]
+ },
+ {
+ "type": "TaskMovingWindow",
+ "name": "BatchTestTask@UNIQUE_ID@",
+ "MOs": ["example"]
+ }
+ ]
+ }
+ }
+ },
+ "dataSamplingPolicies": [
+ {
+ "id": "tst-raw",
+ "active": "true",
+ "machines": [],
+ "query": "data:TST/RAWDATA/0",
+ "samplingConditions": [],
+ "blocking": "false"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Framework/example-default.json b/Framework/example-default.json
index 22ea380c87..07bd335def 100644
--- a/Framework/example-default.json
+++ b/Framework/example-default.json
@@ -10,7 +10,16 @@
},
"Activity": {
"number": "42",
- "type": "2"
+ "type": "NONE"
+ },
+ "monitoring": {
+ "url": "infologger:///debug?qc"
+ },
+ "consul": {
+ "url": ""
+ },
+ "conditionDB": {
+ "url": "ccdb-test.cern.ch:8080"
}
},
"tasks": {
@@ -18,7 +27,6 @@
"className": "o2::quality_control_modules::example::ExampleTask",
"moduleName": "QcExample",
"cycleDurationSeconds": "10",
- "maxNumberCycles": "-1",
"dataSource": {
"type": "dataSamplingPolicy",
"name": "ex1"
@@ -28,7 +36,6 @@
"daqTask": {
"className": "o2::quality_control_modules::daq::DaqTask",
"moduleName": "QcDaq",
- "maxNumberCycles": "-1",
"cycleDurationSeconds": "10",
"dataSource": {
"type": "dataSamplingPolicy",
@@ -45,41 +52,157 @@
"name": "ex1"
},
"location": "local",
- "machines": [
+ "localMachines": [
"o2flp1",
"o2flp2"
- ]
+ ],
+ "remoteMachine": "o2qc1",
+ "remotePort": "30432"
+ }
+ },
+ "checks": {
+ "example/checkMeanIsAbove": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::MeanIsAbove",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "myTask_1", "": "MOs parameter is not specfied, meaning we take all objects"
+ }]
+ },
+ "example/checkNonEmpty": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::MeanIsAbove",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "myTask_1", "": "MOs parameter is not specfied, meaning we take all objects"
+ }]
+ },
+ "example/checkFromExample": {
+ "active": "true",
+ "className": "o2::quality_control_modules::example::FakeCheck",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "myTask_1", "": "MOs parameter is not specfied, meaning we take all objects"
+ }]
+ },
+ "daq/checkNonEmpty/payloadSize": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::NonEmpty",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "DaqTask",
+ "MOs": ["payloadSize"]
+ }]
+ },
+ "daq/checkNonEmpty/IDs": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::NonEmpty",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "DaqTask",
+ "MOs": ["IDs"]
+ }]
+ },
+ "daq/checkIncreasingIDs": {
+ "active": "true",
+ "className": "o2::quality_control_modules::daq::EverIncreasingGraph",
+ "moduleName": "QcDaq",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "DaqTask",
+ "MOs": ["IDs"]
+ }]
+ },
+ "benchmark/fakeCheck_1": {
+ "active": "true",
+ "className": "o2::quality_control_modules::common::NonEmpty",
+ "moduleName": "QcCommon",
+ "policy": "OnAny",
+ "dataSource": [{
+ "type": "Task",
+ "name": "myTask_1",
+ "MOs": ["histogram_myTask_1_0"]
+ }]
+ }
+
+ },
+ "aggregators": {
+ "MyAggregator1": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAny",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check",
+ "name": "dataSizeCheck"
+ }, {
+ "type": "Check",
+ "name": "someNumbersCheck"
+ }]
+ },
+ "MyAggregator2": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Check",
+ "name": "dataSizeCheck"
+ }, {
+ "type": "Check", "": "this one is using onEachSeparately and thus it sends under a full path",
+ "name": "someNumbersCheck",
+ "QOs": ["someNumbersTask/example"], "": "also possible to ignore it altogether, meaning we take all objects"
+ }]
+ },
+ "MyAggregator3": {
+ "active": "true",
+ "className": "o2::quality_control_modules::skeleton::SkeletonAggregator",
+ "moduleName": "QcSkeleton",
+ "policy": "OnAll",
+ "detectorName": "TST",
+ "dataSource": [{
+ "type": "Aggregator",
+ "name": "MyAggregator1", "": "no QOs parameter -> all QOs of this aggregator"
+ }, {
+ "type": "Aggregator",
+ "name": "MyAggregator2",
+ "QOs": ["newQuality", "another"], "": "list all objects we are interested in"
+ }]
}
}
},
- "dataSamplingPoliciesFile_comment": "In case that policies are stored in different file, specify its path below. When both dataSamplingPolicies and dataSamplingPoliciesFile are specified, the latter has higher priority",
- "dataSamplingPoliciesFile": "json:///home/genghiskhan/alice/QualityControl/dataSamplingConfig.json",
- "dataSamplingPolicies_comment": "this is ignored when dataSamplingPoliciesFile is specified",
"dataSamplingPolicies": [
{
"id": "ex1",
"active": "true",
- "dataHeaders": [
+ "query_comment" : "query is in the format of binding1:origin1/description1/subSpec1;binding2:origin2/description2/subSpec2;...",
+ "query" : "data:TST/DATA/0",
+ "samplingConditions": [
{
- "binding": "data",
- "dataOrigin": "TST",
- "dataDescription": "DATA"
+ "condition": "custom",
+ "moduleName": "QcExample",
+ "className": "o2::quality_control_modules::example::ExampleCondition",
+ "threshold": "120"
}
- ],
- "subSpec": "0",
- "samplingConditions": []
+ ]
},
{
"id": "mftclusters",
"active": "true",
- "dataHeaders": [
- {
- "binding": "mft-clusters",
- "dataOrigin": "MFT",
- "dataDescription": "CLUSTERS"
- }
- ],
- "subSpec": "0",
+ "query" : "mft-clusters:MFT/CLUSTERS/0",
"samplingConditions": [
{
"condition": "payloadSize",
diff --git a/Framework/include/QualityControl/Activity.h b/Framework/include/QualityControl/Activity.h
index 846bd57c67..63fcc18370 100644
--- a/Framework/include/QualityControl/Activity.h
+++ b/Framework/include/QualityControl/Activity.h
@@ -1,3 +1,14 @@
+// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
+// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
+// All rights not expressly granted are reserved.
+//
+// This software is distributed under the terms of the GNU General Public
+// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
+//
+// 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.
+
///
/// \file Activity.h
/// \author Barthelemy von Haller
@@ -6,17 +17,41 @@
#ifndef QC_CORE_ACTIVITY_H
#define QC_CORE_ACTIVITY_H
+#include
+#include "QualityControl/ValidityInterval.h"
+
+#include "Rtypes.h"
+
namespace o2::quality_control::core
{
-/// \brief Dummy class that should be removed when there is the official one.
-/// This corresponds to a Run1/2 "run".
+/// \brief Class that represents a Run 3 activity such as a run.
/// \author Barthelemy von Haller
class Activity
{
public:
Activity() = default;
- Activity(int id, int type) : mId(id), mType(type) {}
+ Activity(int id,
+ const std::string& type,
+ const std::string& periodName = "",
+ const std::string& passName = "",
+ const std::string& provenance = "qc",
+ ValidityInterval validity = gFullValidityInterval,
+ const std::string& beamType = "",
+ const std::string& partitionName = "",
+ int fillNumber = 0,
+ int originalId = 0)
+ : mId(id),
+ mType(type),
+ mPeriodName(periodName),
+ mPassName(passName),
+ mProvenance(provenance),
+ mValidity(validity),
+ mBeamType(beamType),
+ mPartitionName(partitionName),
+ mFillNumber(fillNumber),
+ mOriginalId(originalId) {}
+
/// Copy constructor
Activity(const Activity& other) = default;
/// Move constructor
@@ -25,11 +60,31 @@ class Activity
Activity& operator=(const Activity& other) = default;
/// Move assignment operator
Activity& operator=(Activity&& other) noexcept = default;
+ /// Comparator. All fields should be exactly the same
+ bool operator==(const Activity& other) const;
+
+ /// prints Activity
+ friend std::ostream& operator<<(std::ostream& out, const Activity& activity);
+
+ /// Checks if the other activity matches this, taking into account that default values match any.
+ bool matches(const Activity& other) const;
+ /// Checks if the other object describes the same Activity (but e.g. in different time)
+ bool same(const Activity& other) const;
virtual ~Activity() = default;
int mId{ 0 };
- int mType{ 0 };
+ std::string mType{ "NONE" };
+ std::string mPeriodName{};
+ std::string mPassName{};
+ std::string mProvenance{ "qc" };
+ ValidityInterval mValidity{ gFullValidityInterval };
+ std::string mBeamType{};
+ std::string mPartitionName{};
+ int mFillNumber{ 0 };
+ int mOriginalId{ 0 }; // original run number of REPLAY runs
+
+ ClassDef(Activity, 6);
};
} // namespace o2::quality_control::core
diff --git a/Framework/include/QualityControl/ActivityHelpers.h b/Framework/include/QualityControl/ActivityHelpers.h
new file mode 100644
index 0000000000..61268d729a
--- /dev/null
+++ b/Framework/include/QualityControl/ActivityHelpers.h
@@ -0,0 +1,125 @@
+// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
+// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
+// All rights not expressly granted are reserved.
+//
+// This software is distributed under the terms of the GNU General Public
+// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
+//
+// 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.
+
+///
+/// \file ActivityHelpers.h
+/// \author Piotr Konopka
+///
+
+#ifndef QUALITYCONTROL_ACTIVITYHELPERS_H
+#define QUALITYCONTROL_ACTIVITYHELPERS_H
+
+#include "QualityControl/Activity.h"
+
+#include
+#include