Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Framework/include/QualityControl/CheckConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define QC_CORE_CHECKCONFIG_H

#include <string>
#include <unordered_map>
#include <vector>

#include <Framework/DataProcessorSpec.h>
Expand All @@ -35,6 +36,7 @@ struct CheckConfig : public o2::quality_control::core::UserCodeConfig {
bool allowBeautify = false;
framework::Inputs inputSpecs{};
framework::OutputSpec qoSpec{ "XXX", "INVALID" };
std::unordered_map<std::string, std::string> externalTaskDetectorNames;
};

} // namespace o2::quality_control::checker
Expand Down
5 changes: 4 additions & 1 deletion Framework/include/QualityControl/CheckRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <string>
#include <map>
#include <vector>
#include <unordered_map>
#include <unordered_set>
// O2
#include <Common/Timer.h>
Expand Down Expand Up @@ -100,8 +101,9 @@ class CheckRunner : public framework::Task
*
* @param checkRunnerConfig configuration of CheckRunner
* @param input Monitor Object input spec.
* @param detectorName detector override for raw objects, or empty to use the input origin.
*/
CheckRunner(CheckRunnerConfig, o2::framework::InputSpec input);
CheckRunner(CheckRunnerConfig, o2::framework::InputSpec input, std::string detectorName = {});

/// Destructor
~CheckRunner() override;
Expand Down Expand Up @@ -215,6 +217,7 @@ class CheckRunner : public framework::Task
std::string mDeviceName;
std::map<std::string, Check> mChecks;
std::string mDetectorName;
std::unordered_map<std::string, std::string> mExternalTaskDetectorNames;
std::shared_ptr<Activity> mActivity; // shareable with the Checks
CheckRunnerConfig mConfig;
std::shared_ptr<o2::quality_control::repository::DatabaseInterface> mDatabase;
Expand Down
2 changes: 1 addition & 1 deletion Framework/include/QualityControl/CheckRunnerFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class CheckRunnerFactory
* @param input InputSpec with the content to store
* @param configurationSource
*/
static framework::DataProcessorSpec createSinkDevice(const CheckRunnerConfig& checkRunnerConfig, const o2::framework::InputSpec& input);
static framework::DataProcessorSpec createSinkDevice(const CheckRunnerConfig& checkRunnerConfig, const o2::framework::InputSpec& input, std::string detectorName = {});

static CheckRunnerConfig extractConfig(const core::CommonSpec&);

Expand Down
1 change: 1 addition & 0 deletions Framework/include/QualityControl/DataSourceSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct DataSourceSpec {
DataSourceType type;
std::string id;
std::string name;
std::string detectorName;
std::vector<framework::InputSpec> inputs;
std::vector<std::string> subInputs; // can be MO or QO names
};
Expand Down
2 changes: 2 additions & 0 deletions Framework/include/QualityControl/ExternalTaskSpec.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <string>
#include <utility>

// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
Expand Down Expand Up @@ -31,6 +32,7 @@ struct ExternalTaskSpec {

std::string taskName;
std::string query;
std::string detectorName;
bool active = true;
};

Expand Down
8 changes: 8 additions & 0 deletions Framework/src/Check.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <memory>
#include <algorithm>
#include <Framework/DataSpecUtils.h>
#include <string>
#include <utility>
#include <ranges>
Expand Down Expand Up @@ -213,6 +214,7 @@ CheckConfig Check::extractConfig(const CommonSpec& commonSpec, const CheckSpec&
{
framework::Inputs inputs;
std::vector<std::string> objectNames;
std::unordered_map<std::string, std::string> externalTaskDetectorNames;
UpdatePolicyType updatePolicy = checkSpec.updatePolicy;
bool checkAllObjects = false;
for (const auto& dataSource : checkSpec.dataSources) {
Expand All @@ -221,6 +223,11 @@ CheckConfig Check::extractConfig(const CommonSpec& commonSpec, const CheckSpec&
"Unsupported dataSource '" + dataSource.name + "' for a Check '" + checkSpec.checkName + "'");
}
inputs.insert(inputs.end(), dataSource.inputs.begin(), dataSource.inputs.end());
if (dataSource.type == DataSourceType::ExternalTask && !dataSource.detectorName.empty()) {
for (const auto& input : dataSource.inputs) {
externalTaskDetectorNames[framework::DataSpecUtils::label(input)] = dataSource.detectorName;
}
}

// Subscribe on predefined MOs.
// If "MOs" are not set, the check function will be triggered whenever a new MO appears.
Expand Down Expand Up @@ -264,6 +271,7 @@ CheckConfig Check::extractConfig(const CommonSpec& commonSpec, const CheckSpec&
allowBeautify,
std::move(inputs),
createUserOutputSpec(DataSourceType::Check, checkSpec.detectorName, checkSpec.checkName),
std::move(externalTaskDetectorNames),
};
}

Expand Down
12 changes: 10 additions & 2 deletions Framework/src/CheckRunner.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,12 @@ CheckRunner::CheckRunner(CheckRunnerConfig checkRunnerConfig, const std::vector<
mTotalQOSent(0)
{
for (auto& checkConfig : checkConfigs) {
mExternalTaskDetectorNames.insert(checkConfig.externalTaskDetectorNames.begin(), checkConfig.externalTaskDetectorNames.end());
mChecks.emplace(checkConfig.name, checkConfig);
}
}

CheckRunner::CheckRunner(CheckRunnerConfig checkRunnerConfig, InputSpec input)
CheckRunner::CheckRunner(CheckRunnerConfig checkRunnerConfig, InputSpec input, std::string detectorName)
: mDeviceName(createSinkCheckRunnerName(input)),
mConfig(std::move(checkRunnerConfig)),
mInputs{ input },
Expand All @@ -158,6 +159,9 @@ CheckRunner::CheckRunner(CheckRunnerConfig checkRunnerConfig, InputSpec input)
mTotalNumberMOStored(0),
mTotalQOSent(0)
{
if (!detectorName.empty()) {
mExternalTaskDetectorNames.emplace(DataSpecUtils::label(input), std::move(detectorName));
}
}

CheckRunner::~CheckRunner()
Expand Down Expand Up @@ -262,7 +266,11 @@ void CheckRunner::prepareCacheData(framework::InputRecord& inputRecord)
ILOG(Debug, Devel) << "The MO is null, probably a TObject could not be casted into an MO." << ENDM;
ILOG(Debug, Devel) << " Creating an ad hoc MO." << ENDM;
header::DataOrigin origin = DataSpecUtils::asConcreteOrigin(input);
mo = std::make_shared<MonitorObject>(tObject, input.binding, "CheckRunner", origin.str);
std::string detectorName = origin.str;
if (auto detector = mExternalTaskDetectorNames.find(DataSpecUtils::label(input)); detector != mExternalTaskDetectorNames.end()) {
detectorName = detector->second;
}
mo = std::make_shared<MonitorObject>(tObject, input.binding, "CheckRunner", detectorName);
mo->setActivity(*mActivity);
}

Expand Down
5 changes: 3 additions & 2 deletions Framework/src/CheckRunnerFactory.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
///
#include <vector>
#include <unordered_set>
#include <utility>

#include <Framework/DataProcessorSpec.h>
#include <Framework/DeviceSpec.h>
Expand Down Expand Up @@ -49,9 +50,9 @@ DataProcessorSpec CheckRunnerFactory::create(CheckRunnerConfig checkRunnerConfig
return newCheckRunner;
}

DataProcessorSpec CheckRunnerFactory::createSinkDevice(const CheckRunnerConfig& checkRunnerConfig, const o2::framework::InputSpec& input)
DataProcessorSpec CheckRunnerFactory::createSinkDevice(const CheckRunnerConfig& checkRunnerConfig, const o2::framework::InputSpec& input, std::string detectorName)
{
CheckRunner qcCheckRunner{ checkRunnerConfig, input };
CheckRunner qcCheckRunner{ checkRunnerConfig, input, std::move(detectorName) };
qcCheckRunner.setTaskStoreSet({ DataSpecUtils::label(input) });

DataProcessorSpec newCheckRunner{ qcCheckRunner.getDeviceName(),
Expand Down
9 changes: 8 additions & 1 deletion Framework/src/InfrastructureGenerator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ void InfrastructureGenerator::generateCheckRunners(framework::WorkflowSpec& work
typedef std::vector<std::string> InputNames;
typedef std::vector<CheckConfig> CheckConfigs;
std::map<std::string, o2::framework::InputSpec> tasksOutputMap; // all active tasks' output, as inputs, keyed by their label
std::map<std::string, std::string> externalTaskDetectorNames;
std::map<InputNames, CheckConfigs> checksMap; // all the Checks defined in the config mapped keyed by their sorted inputNames
std::map<InputNames, InputNames> storeVectorMap;

Expand Down Expand Up @@ -658,6 +659,9 @@ void InfrastructureGenerator::generateCheckRunners(framework::WorkflowSpec& work
Inputs inputs = DataDescriptorQueryBuilder::parse(query.c_str());
for (const auto& taskOutput : inputs) {
tasksOutputMap.insert({ DataSpecUtils::label(taskOutput), taskOutput });
if (!externalTaskSpec.detectorName.empty()) {
externalTaskDetectorNames[DataSpecUtils::label(taskOutput)] = externalTaskSpec.detectorName;
}
}
}

Expand Down Expand Up @@ -711,8 +715,11 @@ void InfrastructureGenerator::generateCheckRunners(framework::WorkflowSpec& work
ILOG(Debug, Devel) << input << " ";
ILOG(Debug, Devel) << ENDM;

auto detectorName = externalTaskDetectorNames.find(inputNames[0]);
DataProcessorSpec spec = checkConfigs.empty()
? CheckRunnerFactory::createSinkDevice(checkRunnerConfig, tasksOutputMap.find(inputNames[0])->second)
? CheckRunnerFactory::createSinkDevice(checkRunnerConfig,
tasksOutputMap.find(inputNames[0])->second,
detectorName == externalTaskDetectorNames.end() ? std::string{} : detectorName->second)
: CheckRunnerFactory::create(checkRunnerConfig, checkConfigs, storeVectorMap[inputNames]);
workflow.emplace_back(spec);
checkRunnerOutputs.insert(checkRunnerOutputs.end(), spec.outputs.begin(), spec.outputs.end());
Expand Down
10 changes: 10 additions & 0 deletions Framework/src/InfrastructureSpecReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ DataSourceSpec InfrastructureSpecReader::readSpecEntry<DataSourceSpec>(const std
dss.id = dataSourceTree.get<std::string>("name");
dss.name = dss.id;
auto query = wholeTree.get<std::string>("qc.externalTasks." + dss.name + ".query");
dss.detectorName = wholeTree.get<std::string>("qc.externalTasks." + dss.name + ".detectorName", "");
if (!dss.detectorName.empty()) {
dss.detectorName = InfrastructureSpecReader::validateDetectorName(dss.detectorName);
}
dss.inputs = o2::framework::DataDescriptorQueryBuilder::parse(query.c_str());
break;
}
Expand Down Expand Up @@ -478,6 +482,12 @@ ExternalTaskSpec

ets.taskName = externalTaskName;
ets.query = externalTaskTree.get<std::string>("query");
ets.detectorName = externalTaskTree.get<std::string>("detectorName", "");
if (ets.detectorName.empty()) {
ILOG(Warning, Ops) << "External task " << externalTaskName << " has no detectorName configured. The detector will be inferred from the query origin when wrapping raw objects." << ENDM;
} else {
ets.detectorName = InfrastructureSpecReader::validateDetectorName(ets.detectorName);
}
ets.active = externalTaskTree.get<bool>("active", ets.active);

return ets;
Expand Down
1 change: 1 addition & 0 deletions doc/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ Below the external task configuration structure is described. Note that more tha
"External-1": { "": "ID of the task",
"active": "true", "": "Activation flag. If not \"true\", the Task will not be created.",
"taskName": "External-1", "": "Name of the task, used e.g. in the QCDB. If empty, the ID is used.",
"detectorName": "TST", "": "Detector name used when wrapping raw objects as MonitorObjects. If omitted, the query origin is used.",
"query": "External-1:TST/HISTO/0", "": "Query specifying where the objects to be checked and stored are coming from. Use the task name as binding."
}
}
Expand Down
Loading