Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QC-1020] Fall back to default values if beamtype or runtype cannot b… #2033

Merged
Merged
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
26 changes: 22 additions & 4 deletions Framework/include/QualityControl/CustomParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,33 @@ class CustomParameters

/**
* Return the value for the given key, runType and beamType.
* If no key is found for the runType and the Beamtype, the fallback is to substitute with "default", first for beamType then for runType.
* An exception is raised only if the key could not be found in any combination of the provided run and beam types with "default".
* @param key
* @param runType
* @param beamType
* @return the value for the given key, runType and beamType.
* @throw std::out_of_range if no key-value pair corresponds to this key and to these beamType and runType
* @throw std::out_of_range if no key-value pair corresponds to this key and to these beamType and runType and that substitutions
* with "default" failed.
*/
std::string at(const std::string& key, const std::string& runType = "default", const std::string& beamType = "default") const;

/**
* Return the optional value for the given key, runType and beamType (the two latter optional).
* Return the value for the given key, runType and beamType.
* If no key is found for the runType and the Beamtype, the fallback is to substitute with "default", first for beamType then for runType.
* An exception is raised only if the key could not be found in any combination of the provided run and beam types with "default".
* @param key
* @param activity
* @return the value for the given key and for the given activity.
* @throw std::out_of_range if no key-value pair corresponds to this key and to this activity and that substitutions
* with "default" failed.
*/
std::string at(const std::string& key, const Activity& activity) const;

/**
* Return the optional value for the given key, runType and beamType.
* If no key is found for the runType and the Beamtype, the fallback is to substitute with "default", first for beamType then for runType.
* Empty is only returned if the key could not be found in any combination of the provided run and beam types with "default".
* @param key
* @param runType
* @param beamType
Expand All @@ -87,8 +104,9 @@ class CustomParameters
std::optional<std::string> atOptional(const std::string& key, const std::string& runType = "default", const std::string& beamType = "default") const;

/**
* Return the optional value for the given key in the specified activity.
* @param key
* Return the optional value for the given key, runType and beamType.
* If no key is found for the runType and the Beamtype, the fallback is to substitute with "default", first for beamType then for runType.
* Empty is only returned if the key could not be found in any combination of the provided run and beam types with "default". * @param key
* @param activity
* @return an optional with the value for the given key and for the given activity.
*/
Expand Down
35 changes: 30 additions & 5 deletions Framework/src/CustomParameters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "QualityControl/CustomParameters.h"
#include <DataFormatsParameters/ECSDataAdapters.h>
#include <iostream>
#include <string_view>
#include <vector>

namespace o2::quality_control::core
{
Expand Down Expand Up @@ -54,16 +56,39 @@ const std::unordered_map<std::string, std::string>& CustomParameters::getAllDefa

std::string CustomParameters::at(const std::string& key, const std::string& runType, const std::string& beamType) const
{
return mCustomParameters.at(runType).at(beamType).at(key);
auto optionalResult = atOptional(key, runType, beamType); // just reuse the logic we developed in atOptional
if (!optionalResult.has_value()) {
return mCustomParameters.at(runType).at(beamType).at(key); // we know we will get a out_of_range exception
}
return optionalResult.value();
}

std::string CustomParameters::at(const std::string& key, const Activity& activity) const
{
// Get the proper parameter for the given activity
const int runType = activity.mType; // get the type for this run
// convert it to a string (via a string_view as this is what we get from O2)
const std::string_view runTypeStringView = o2::parameters::GRPECS::RunTypeNames[runType];
const std::string runTypeString{ runTypeStringView };
// get the param
return at(key, runTypeString, activity.mBeamType);
}

std::optional<std::string> CustomParameters::atOptional(const std::string& key, const std::string& runType, const std::string& beamType) const
{
try {
return mCustomParameters.at(runType).at(beamType).at(key);
} catch (const std::out_of_range& exc) {
return {};
std::optional<std::string> result = std::nullopt;
const std::vector<std::string> runTypes = { runType, std::string("default") };
const std::vector<std::string> beamTypes = { beamType, std::string("default") };
for (const auto& rt : runTypes) {
for (const auto& bt : beamTypes) {
try {
result = mCustomParameters.at(rt).at(bt).at(key);
return result;
} catch (const std::out_of_range& exc) { // ignored on purpose
}
}
}
return result;
}

std::optional<std::string> CustomParameters::atOptional(const std::string& key, const Activity& activity) const
Expand Down
56 changes: 56 additions & 0 deletions Framework/test/testCustomParameters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,59 @@ BOOST_AUTO_TEST_CASE(test_cp_new_access_pattern)
BOOST_CHECK_EQUAL(std::stoi(param2->second), 1);
}
}

BOOST_AUTO_TEST_CASE(test_default_if_not_found_at_optional)
{
CustomParameters cp;

// no default values are in the CP, we get an empty result
BOOST_CHECK_EQUAL(cp.atOptional("key", "PHYSICS", "proton-proton").has_value(), false);
BOOST_CHECK_EQUAL(cp.atOptional("key", "TECHNICAL", "proton-proton").has_value(), false);

// prepare the CP
cp.set("key", "valueDefaultDefault", "default", "default");
cp.set("key", "valuePhysicsDefault", "PHYSICS", "default");
cp.set("key", "valuePhysicsPbPb", "PHYSICS", "Pb-Pb");
cp.set("key", "valueCosmicsDefault", "COSMICS", "default");
cp.set("key", "valueCosmicsDefault", "default", "PROTON-PROTON");

// check the data
BOOST_CHECK_EQUAL(cp.atOptional("key").value(), "valueDefaultDefault");
BOOST_CHECK_EQUAL(cp.atOptional("key", "PHYSICS").value(), "valuePhysicsDefault");
BOOST_CHECK_EQUAL(cp.atOptional("key", "PHYSICS", "Pb-Pb").value(), "valuePhysicsPbPb");
BOOST_CHECK_EQUAL(cp.atOptional("key", "COSMICS", "default").value(), "valueCosmicsDefault");
BOOST_CHECK_EQUAL(cp.atOptional("key", "default", "PROTON-PROTON").value(), "valueCosmicsDefault");

// check when something is missing
BOOST_CHECK_EQUAL(cp.atOptional("key", "PHYSICS", "PROTON-PROTON").value(), "valuePhysicsDefault"); // key is not defined for pp
BOOST_CHECK_EQUAL(cp.atOptional("key", "TECHNICAL", "STRANGE").value(), "valueDefaultDefault"); // key is not defined for run nor beam
BOOST_CHECK_EQUAL(cp.atOptional("key", "TECHNICAL", "PROTON-PROTON").value(), "valueCosmicsDefault"); // key is not defined for technical
}

BOOST_AUTO_TEST_CASE(test_default_if_not_found_at)
{
CustomParameters cp;

// no default values are in the CP, we get an empty result
BOOST_CHECK_THROW(cp.at("key", "PHYSICS", "proton-proton"), std::out_of_range);
BOOST_CHECK_THROW(cp.at("key", "TECHNICAL", "proton-proton"), std::out_of_range);

// prepare the CP
cp.set("key", "valueDefaultDefault", "default", "default");
cp.set("key", "valuePhysicsDefault", "PHYSICS", "default");
cp.set("key", "valuePhysicsPbPb", "PHYSICS", "Pb-Pb");
cp.set("key", "valueCosmicsDefault", "COSMICS", "default");
cp.set("key", "valueCosmicsDefault", "default", "PROTON-PROTON");

// check the data
BOOST_CHECK_EQUAL(cp.at("key"), "valueDefaultDefault");
BOOST_CHECK_EQUAL(cp.at("key", "PHYSICS"), "valuePhysicsDefault");
BOOST_CHECK_EQUAL(cp.at("key", "PHYSICS", "Pb-Pb"), "valuePhysicsPbPb");
BOOST_CHECK_EQUAL(cp.at("key", "COSMICS", "default"), "valueCosmicsDefault");
BOOST_CHECK_EQUAL(cp.at("key", "default", "PROTON-PROTON"), "valueCosmicsDefault");

// check when something is missing
BOOST_CHECK_EQUAL(cp.at("key", "PHYSICS", "PROTON-PROTON"), "valuePhysicsDefault"); // key is not defined for pp
BOOST_CHECK_EQUAL(cp.at("key", "TECHNICAL", "STRANGE"), "valueDefaultDefault"); // key is not defined for run nor beam
BOOST_CHECK_EQUAL(cp.at("key", "TECHNICAL", "PROTON-PROTON"), "valueCosmicsDefault"); // key is not defined for technical
}
13 changes: 10 additions & 3 deletions doc/Advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ The simple, deprecated, syntax is
"tasks": {
"QcTask": {
"taskParameters": {
"myOwnKey": "myOwnValue"
"myOwnKey1": "myOwnValue1"
},
```
It is accessed with : `mCustomParameters["myOwnKey"]`.
Expand All @@ -1055,7 +1055,7 @@ The new syntax is
"extendedTaskParameters": {
"default": {
"default": {
"myOwnKey": "myOwnValue",
"myOwnKey1": "myOwnValue1",
"myOwnKey2": "myOwnValue2",
"myOwnKey3": "myOwnValue3"
}
Expand Down Expand Up @@ -1086,8 +1086,12 @@ The values can be accessed in various ways.

### Access optional values with or without activity

The value for the key, runType and beamType is returned if found, or an empty value otherwise.
However, before returning an empty value we try to substitute the runType and the beamType with "default".

```c++
// returns an Optional<string> if it finds the key `myOwnKey` for the runType and beamType of the provided activity.
// returns an Optional<string> if it finds the key `myOwnKey` for the runType and beamType of the provided activity,
Barthelemy marked this conversation as resolved.
Show resolved Hide resolved
// or if it can find the key with the runType or beamType substituted with "default".
auto param = mCustomParameters.atOptional("myOwnKey", activity); // activity is "PHYSICS", "Pb-Pb" , returns "myOwnValue1d"
// same but passing directly the run and beam types
auto param = mCustomParameters.atOptional("myOwnKey", "PHYSICS", "Pb-Pb"); // returns "myOwnValue1d"
Expand All @@ -1097,6 +1101,9 @@ auto param = mCustomParameters.atOptional("myOwnKey", "PHYSICS"); // returns "my

### Access values directly specifying the run and beam type

The value for the key, runType and beamType is returned if found, or an exception is thrown otherwise..
However, before throwing we try to substitute the runType and the beamType with "default".

```c++
mCustomParameters["myOwnKey"]; // considering that run and beam type are `default` --> returns `myOwnValue`
mCustomParameters.at("myOwnKey"); // returns `myOwnValue`
Expand Down
Loading