Skip to content

Commit 59a9a2e

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

19 files changed

+222
-49
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}

Framework/include/QualityControl/MonitorObjectCollection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class MonitorObjectCollection : public TObjArray, public mergers::MergeInterface
4040
void setTaskName(const std::string&);
4141
const std::string& getTaskName() const;
4242

43-
void addOrUpdateMetadata(std::string key, std::string value);
43+
void addOrUpdateMetadata(const std::string& key, const std::string& value);
4444

4545
MergeInterface* cloneMovingWindow() const override;
4646

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/include/QualityControl/Triggers.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ struct Trigger {
4949

5050
/// \brief Constructor. Timestamp is generated from the time of construction.
5151
Trigger(TriggerType triggerType, bool last = false, core::Activity activity = {})
52-
: triggerType(triggerType), last(last), activity(std::move(activity)), timestamp(msSinceEpoch()) {};
52+
: triggerType(triggerType), last(last), activity(std::move(activity)), timestamp(msSinceEpoch()){};
5353
/// \brief Constructor.
5454
Trigger(TriggerType triggerType, bool last, core::Activity activity, uint64_t timestamp, std::string config = {})
55-
: triggerType(triggerType), last(last), activity(std::move(activity)), timestamp(timestamp), config(std::move(config)) {};
55+
: triggerType(triggerType), last(last), activity(std::move(activity)), timestamp(timestamp), config(std::move(config)){};
5656
/// \brief Constructor.
57-
Trigger(TriggerType triggerType, bool last, uint64_t timestamp) : triggerType(triggerType), last(last), activity(), timestamp(timestamp) {};
57+
Trigger(TriggerType triggerType, bool last, uint64_t timestamp) : triggerType(triggerType), last(last), activity(), timestamp(timestamp){};
5858

5959
operator bool() const { return triggerType != TriggerType::No && triggerType != TriggerType::INVALID; }
6060
friend std::ostream& operator<<(std::ostream& out, const Trigger& t);

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: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
#include <memory>
1515
#include <algorithm>
16-
#include <stdexcept>
1716
#include <string>
1817
#include <utility>
1918
#include <ranges>
@@ -31,7 +30,7 @@
3130
#include "QualityControl/QcInfoLogger.h"
3231
#include "QualityControl/Quality.h"
3332
#include "QualityControl/HashDataDescription.h"
34-
#include "QualityControl/runnerUtils.h"
33+
#include "QualityControl/ObjectMetadataKeysHelpers.h"
3534

3635
#include <QualityControl/AggregatorRunner.h>
3736

@@ -166,17 +165,13 @@ QualityObjectsType Check::check(std::map<std::string, std::shared_ptr<MonitorObj
166165
}));
167166
ILOG(Debug, Devel) << "Check '" << mCheckConfig.name << "', quality '" << quality << "'" << ENDM;
168167
std::vector<std::string> monitorObjectsNames;
169-
unsigned long maxCycle{};
168+
std::optional<unsigned long> maxCycle{};
170169
for (const auto& [moName, mo] : moMapToCheck) {
171170
monitorObjectsNames.emplace_back(moName);
172171
if (const auto cycle = mo->getMetadata(repository::metadata_keys::cycle)) {
173172
const auto& cycleStr = cycle.value();
174-
unsigned long cycleVal{};
175-
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);
177-
} else {
178-
ILOG(Warning, Support) << "metadata " << repository::metadata_keys::cycle << " with value " << cycleStr << " couldn't be parsed for a reason: "
179-
<< std::make_error_code(fromCharsRed.ec).message() << ENDM;
173+
if (const auto cycleVal = repository::metadata_keys::parseCycle(cycleStr); cycleVal.has_value()) {
174+
maxCycle = std::max(cycleVal.value(), maxCycle.value_or(0));
180175
}
181176
}
182177
}
@@ -190,8 +185,8 @@ QualityObjectsType Check::check(std::map<std::string, std::shared_ptr<MonitorObj
190185
monitorObjectsNames));
191186

192187
qualityObjects.back()->setActivity(commonActivity);
193-
if (maxCycle > 0) {
194-
qualityObjects.back()->addMetadata(repository::metadata_keys::cycle, std::to_string(maxCycle));
188+
if (maxCycle.has_value()) {
189+
qualityObjects.back()->addMetadata(repository::metadata_keys::cycle, std::to_string(maxCycle.value()));
195190
}
196191
beautify(moMapToCheck, quality);
197192
}

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: 4 additions & 15 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())));
@@ -179,7 +168,7 @@ const std::string& MonitorObjectCollection::getTaskName() const
179168
return mTaskName;
180169
}
181170

182-
void MonitorObjectCollection::addOrUpdateMetadata(std::string key, std::string value)
171+
void MonitorObjectCollection::addOrUpdateMetadata(const std::string& key, const std::string& value)
183172
{
184173
for (auto obj : *this) {
185174
if (auto mo = dynamic_cast<MonitorObject*>(obj)) {

0 commit comments

Comments
 (0)