Skip to content

Commit 6a1c74b

Browse files
author
Michal Tichák
committed
QC-1086 added cycle handling to Aggregators
1 parent 196fa28 commit 6a1c74b

16 files changed

+215
-36
lines changed

Framework/CMakeLists.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ configure_file("include/QualityControl/Version.h.in"
55
"${CMAKE_CURRENT_BINARY_DIR}/include/QualityControl/Version.h"
66
@ONLY)
77

8-
# ---- Library for IL ----
8+
# ---- Library for IL ----
99
add_library(O2QualityControlInfoLogger STATIC
1010
src/QcInfoLogger.cxx
1111
)
@@ -135,7 +135,8 @@ add_library(O2QualityControl
135135
src/RootFileStorage.cxx
136136
src/ReductorHelpers.cxx
137137
src/KafkaPoller.cxx
138-
src/FlagHelpers.cxx)
138+
src/FlagHelpers.cxx
139+
src/ObjectMetadataKeysHelpers.cxx)
139140

140141
target_include_directories(
141142
O2QualityControl
@@ -263,7 +264,7 @@ endforeach()
263264

264265
# ---- Tests ----
265266

266-
add_executable(o2-qc-test-core
267+
add_executable(o2-qc-test-core
267268
test/testActivity.cxx
268269
test/testActivityHelpers.cxx
269270
test/testAggregatorInterface.cxx
@@ -353,7 +354,7 @@ foreach(i RANGE ${count})
353354
get_filename_component(test_name ${test} NAME)
354355
string(REGEX REPLACE ".cxx" "" test_name ${test_name})
355356
string(REPLACE " " ";" arg "${arg}") # make list of string (arguments) out of
356-
# one string
357+
# one string
357358

358359
add_executable(${test_name} ${test})
359360
set_property(TARGET ${test_name}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file ObjectMetadataKeysHelpers.h
14+
/// \author Michal Tichak
15+
///
16+
17+
#include <optional>
18+
#include <string>
19+
20+
namespace o2::quality_control::repository::metadata_keys
21+
{
22+
/**
23+
* \brief Parses metadata value stored under metadata_keys::cycle
24+
* @param cycleStr string expecting unsigned number
25+
* @return if parsing fails (eg. too big of a number, string wasn't a number) it returns nullopt
26+
*
27+
*/
28+
std::optional<unsigned long> parseCycle(const std::string& cycleStr);
29+
} // namespace o2::quality_control::repository::metadata_keys

Framework/include/QualityControl/Quality.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define QC_CORE_QUALITY_H
1919

2020
#include <Rtypes.h>
21+
#include <optional>
2122
#include <string>
2223
#include <map>
2324
#include <vector>
@@ -105,6 +106,9 @@ class Quality
105106
/// \brief Get metadata
106107
/// \return the value corresponding to the key if it was found, default value otherwise
107108
std::string getMetadata(const std::string& key, const std::string& defaultValue) const;
109+
/// \brief Get metadata
110+
/// \return the value corresponding to the key if it was found, nulopt otherwise
111+
std::optional<std::string> getMetadataOpt(const std::string&) const;
108112

109113
/// \brief Associate the Quality with a new flag and an optional comment
110114
/// \return reference to *this
@@ -121,7 +125,7 @@ class Quality
121125
std::map<std::string, std::string> mUserMetadata;
122126
std::vector<std::pair<FlagType, std::string>> mFlags;
123127

124-
ClassDef(Quality, 2);
128+
ClassDef(Quality, 3);
125129
};
126130

127131
} // namespace o2::quality_control::core

Framework/include/QualityControl/QualityObject.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
// std
1616
#include <map>
17+
#include <optional>
1718
#include <string>
1819
#include <vector>
1920
// ROOT
@@ -107,6 +108,9 @@ class QualityObject : public TObject
107108
/// \brief Get a metadata
108109
/// \return the value corresponding to the key if it was found, default value otherwise
109110
std::string getMetadata(std::string key, std::string defaultValue) const;
111+
/// \brief Get a metadata
112+
/// \return the value corresponding to the key if it was found, nullopt otherwise
113+
std::optional<std::string> getMetadataOpt(const std::string& key) const;
110114

111115
/// \brief Build the path to this object.
112116
/// Build the path to this object as it will appear in the GUI.
@@ -145,7 +149,7 @@ class QualityObject : public TObject
145149
std::vector<std::string> mMonitorObjectsNames;
146150
Activity mActivity;
147151

148-
ClassDefOverride(QualityObject, 6);
152+
ClassDefOverride(QualityObject, 7);
149153
};
150154

151155
using QualityObjectsType = std::vector<std::shared_ptr<QualityObject>>;

Framework/src/Aggregator.cxx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
#include "QualityControl/Aggregator.h"
1818
#include "QualityControl/AggregatorSpec.h"
19+
#include "QualityControl/ObjectMetadataKeys.h"
20+
#include "QualityControl/QualityObject.h"
1921
#include "QualityControl/RootClassFactory.h"
2022
#include "QualityControl/AggregatorInterface.h"
23+
#include "QualityControl/ObjectMetadataKeysHelpers.h"
2124
#include "QualityControl/UpdatePolicyType.h"
2225
#include "QualityControl/ActivityHelpers.h"
2326
#include "QualityControl/Activity.h"
@@ -106,6 +109,21 @@ QualityObjectsMapType Aggregator::filter(QualityObjectsMapType& qoMap)
106109
return result;
107110
}
108111

112+
std::optional<unsigned long> getMaxCycle(const QualityObjectsMapType& qoMap)
113+
{
114+
std::optional<unsigned long> max{};
115+
for (const auto& [_, qo] : qoMap) {
116+
auto cycle = qo->getMetadataOpt(repository::metadata_keys::cycle);
117+
if (cycle.has_value()) {
118+
auto parsedCycle = repository::metadata_keys::parseCycle(cycle.value());
119+
if (parsedCycle) {
120+
max = std::max(parsedCycle.value(), max.value_or(0));
121+
}
122+
}
123+
}
124+
return max;
125+
}
126+
109127
QualityObjectsType Aggregator::aggregate(QualityObjectsMapType& qoMap, const Activity& defaultActivity)
110128
{
111129
auto filtered = filter(qoMap);
@@ -133,7 +151,8 @@ QualityObjectsType Aggregator::aggregate(QualityObjectsMapType& qoMap, const Act
133151
}
134152
}
135153

136-
auto results = mAggregatorInterface->aggregate(filtered);
154+
const auto maxCycle = getMaxCycle(filtered);
155+
const auto results = mAggregatorInterface->aggregate(filtered);
137156
QualityObjectsType qualityObjects;
138157
for (auto const& [qualityName, quality] : results) {
139158
qualityObjects.emplace_back(std::make_shared<QualityObject>(
@@ -142,6 +161,9 @@ QualityObjectsType Aggregator::aggregate(QualityObjectsMapType& qoMap, const Act
142161
mAggregatorConfig.detectorName,
143162
UpdatePolicyTypeUtils::ToString(mAggregatorConfig.policyType)));
144163
qualityObjects.back()->setActivity(resultActivity);
164+
if (maxCycle.has_value()) {
165+
qualityObjects.back()->addMetadata(repository::metadata_keys::cycle, std::to_string(maxCycle.value()));
166+
}
145167
}
146168
return qualityObjects;
147169
}

Framework/src/Check.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,14 @@ QualityObjectsType Check::check(std::map<std::string, std::shared_ptr<MonitorObj
166166
}));
167167
ILOG(Debug, Devel) << "Check '" << mCheckConfig.name << "', quality '" << quality << "'" << ENDM;
168168
std::vector<std::string> monitorObjectsNames;
169-
unsigned long maxCycle{};
169+
std::optional<unsigned long> maxCycle{};
170170
for (const auto& [moName, mo] : moMapToCheck) {
171171
monitorObjectsNames.emplace_back(moName);
172172
if (const auto cycle = mo->getMetadata(repository::metadata_keys::cycle)) {
173173
const auto& cycleStr = cycle.value();
174174
unsigned long cycleVal{};
175175
if (const auto fromCharsRed = std::from_chars(cycleStr.c_str(), cycleStr.c_str() + cycleStr.size(), cycleVal); fromCharsRed.ec == std::errc()) {
176-
maxCycle = std::max(cycleVal, maxCycle);
176+
maxCycle = std::max(cycleVal, maxCycle.value_or(0));
177177
} else {
178178
ILOG(Warning, Support) << "metadata " << repository::metadata_keys::cycle << " with value " << cycleStr << " couldn't be parsed for a reason: "
179179
<< std::make_error_code(fromCharsRed.ec).message() << ENDM;
@@ -190,8 +190,8 @@ QualityObjectsType Check::check(std::map<std::string, std::shared_ptr<MonitorObj
190190
monitorObjectsNames));
191191

192192
qualityObjects.back()->setActivity(commonActivity);
193-
if (maxCycle > 0) {
194-
qualityObjects.back()->addMetadata(repository::metadata_keys::cycle, std::to_string(maxCycle));
193+
if (maxCycle.has_value()) {
194+
qualityObjects.back()->addMetadata(repository::metadata_keys::cycle, std::to_string(maxCycle.value()));
195195
}
196196
beautify(moMapToCheck, quality);
197197
}

Framework/src/MonitorObject.cxx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "QualityControl/RepoPathUtils.h"
2020
#include "QualityControl/QcInfoLogger.h"
2121

22-
#include <iostream>
2322
#include <iterator>
2423
#include <optional>
2524

Framework/src/MonitorObjectCollection.cxx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,25 @@
1818
#include "QualityControl/MonitorObject.h"
1919
#include "QualityControl/ObjectMetadataKeys.h"
2020
#include "QualityControl/QcInfoLogger.h"
21+
#include "QualityControl/ObjectMetadataKeysHelpers.h"
2122

2223
#include <Mergers/MergerAlgorithm.h>
2324
#include <TNamed.h>
2425
#include <optional>
2526
#include <string>
26-
#include <charconv>
2727

2828
using namespace o2::mergers;
2929

3030
namespace o2::quality_control::core
3131
{
3232

33-
std::optional<unsigned long> parseCycle(const std::string& cycleStr)
34-
{
35-
unsigned long cycleVal{};
36-
if (auto parse_res = std::from_chars(cycleStr.c_str(), cycleStr.c_str() + cycleStr.size(), cycleVal); parse_res.ec != std::errc{}) {
37-
ILOG(Warning, Support) << "failed to decypher " << repository::metadata_keys::cycle << " metadata with value " << cycleStr
38-
<< ", with std::errc " << std::make_error_code(parse_res.ec).message() << ENDM;
39-
return std::nullopt;
40-
}
41-
return cycleVal;
42-
}
43-
4433
void mergeCycles(MonitorObject* targetMO, MonitorObject* otherMO)
4534
{
4635
const auto otherCycle = otherMO->getMetadata(repository::metadata_keys::cycle);
4736
const auto targetCycle = targetMO->getMetadata(repository::metadata_keys::cycle);
4837
if (otherCycle.has_value() && targetCycle.has_value()) {
49-
const auto targetCycleParsed = parseCycle(targetCycle.value());
50-
const auto otherCycleParsed = parseCycle(otherCycle.value());
38+
const auto targetCycleParsed = repository::metadata_keys::parseCycle(targetCycle.value());
39+
const auto otherCycleParsed = repository::metadata_keys::parseCycle(otherCycle.value());
5140

5241
if (targetCycleParsed && otherCycleParsed) {
5342
targetMO->addOrUpdateMetadata(repository::metadata_keys::cycle, std::to_string(std::max(targetCycleParsed.value(), otherCycleParsed.value())));
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2025 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
///
13+
/// \file ObjectMetadataKeysHelpers.cxx
14+
/// \author Michal Tichak
15+
///
16+
17+
#include <charconv>
18+
#include "QualityControl/ObjectMetadataKeysHelpers.h"
19+
#include "QualityControl/ObjectMetadataKeys.h"
20+
#include "QualityControl/QcInfoLogger.h"
21+
22+
namespace o2::quality_control::repository::metadata_keys
23+
{
24+
std::optional<unsigned long> parseCycle(const std::string& cycleStr)
25+
{
26+
unsigned long cycleVal{};
27+
if (auto parse_res = std::from_chars(cycleStr.c_str(), cycleStr.c_str() + cycleStr.size(), cycleVal);
28+
parse_res.ec != std::errc{}) {
29+
ILOG(Warning, Support) << "failed to decypher " << repository::metadata_keys::cycle << " metadata with value " << cycleStr
30+
<< ", with std::errc " << std::make_error_code(parse_res.ec).message() << ENDM;
31+
return std::nullopt;
32+
}
33+
return cycleVal;
34+
}
35+
} // namespace o2::quality_control::repository::metadata_keys

Framework/src/Quality.cxx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
///
1616

1717
#include "QualityControl/Quality.h"
18+
#include <optional>
1819
#include <ostream>
19-
#include <iostream>
2020
#include <utility>
2121
#include <Common/Exceptions.h>
2222
#include <boost/algorithm/string.hpp>
@@ -93,6 +93,14 @@ std::string Quality::getMetadata(const std::string& key, const std::string& defa
9393
return mUserMetadata.count(key) > 0 ? mUserMetadata.at(key) : defaultValue;
9494
}
9595

96+
std::optional<std::string> Quality::getMetadataOpt(const std::string& key) const
97+
{
98+
if (auto found = mUserMetadata.find(key); found != mUserMetadata.end()) {
99+
return found->second;
100+
}
101+
return std::nullopt;
102+
}
103+
96104
Quality& Quality::addFlag(const FlagType& flag, std::string comment)
97105
{
98106
if (isWorseThan(Quality::Medium) && !flag.getBad()) {

0 commit comments

Comments
 (0)