Skip to content

Commit

Permalink
[QC-1020] Fall back to default values if beamtype or runtype cannot b… (
Browse files Browse the repository at this point in the history
#2033)

* [QC-1020] Fall back to default values if beamtype or runtype cannot be found.

* [QC-1020] Remove cout

* format

* explicit use of nullopt

* Address Andrea's comments
  • Loading branch information
Barthelemy authored Nov 21, 2023
1 parent 40082d3 commit 46aa0b9
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 12 deletions.
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 @@ -1044,7 +1044,7 @@ The simple, deprecated, syntax is
"tasks": {
"QcTask": {
"taskParameters": {
"myOwnKey": "myOwnValue"
"myOwnKey1": "myOwnValue1"
},
```
It is accessed with : `mCustomParameters["myOwnKey"]`.
Expand All @@ -1056,7 +1056,7 @@ The new syntax is
"extendedTaskParameters": {
"default": {
"default": {
"myOwnKey": "myOwnValue",
"myOwnKey1": "myOwnValue1",
"myOwnKey2": "myOwnValue2",
"myOwnKey3": "myOwnValue3"
}
Expand Down Expand Up @@ -1087,8 +1087,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,
// 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 @@ -1098,6 +1102,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

0 comments on commit 46aa0b9

Please sign in to comment.