Skip to content

Commit

Permalink
QC-686 Allow apply Reductors to CCDB data in TrendingTasks and alike (#…
Browse files Browse the repository at this point in the history
…2110)

* [QC-686] Allow apply Reductors to CCDB data in TrendingTasks and alike

This commit brings the possibility to apply Reductors to CCDB objects.
To achieve that, the former Reductor (which assumes the expected type as TObject*) has become ReductorTObject, while ReductorConditionAny lets us retrieve any type which has a dictionary with retrieveConditionAny method.
For better separation and easier testability, I extracted that method into a separate ConditionAccess class.

* LHCClockPhaseReductor as an example of ReductorConditionAny

assuming the presence of the expected object in the database for given timestamps, the LHC phase can be trended with the following config:
```
      "LHCClockPhaseTrend": {
        "active": "true",
        "className": "o2::quality_control::postprocessing::TrendingTask",
        "moduleName": "QualityControl",
        "detectorName": "TST",
        "dataSources": [
          {
            "type": "condition",
            "path": "TOF/Calib",
            "names": [ "LHCphase" ],
            "reductorName": "o2::quality_control_modules::common::LHCClockPhaseReductor",
            "moduleName": "QcCommon"
          }
        ],
        "plots": [
          {
            "name": "lhc_phase",
            "title": "LHC Phase trend",
            "varexp": "LHCphase.phase:time",
            "selection": "",
            "option": "*L",
            "graphAxisLabel": "Mean X:time"
          }
        ],
        "initTrigger": [
          "userorcontrol"
        ],
        "updateTrigger": [
          "10 seconds"
        ],
        "stopTrigger": [
          "userorcontrol"
        ]
      }
```
  • Loading branch information
knopers8 authored Jan 31, 2024
1 parent 91adb14 commit 57314e0
Show file tree
Hide file tree
Showing 56 changed files with 626 additions and 148 deletions.
3 changes: 2 additions & 1 deletion Framework/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ add_library(O2QualityControl
src/TimekeeperAsynchronous.cxx
src/WorkflowType.cxx
src/TimekeeperFactory.cxx
src/RootFileStorage.cxx)
src/RootFileStorage.cxx
src/ReductorHelpers.cxx)

target_include_directories(
O2QualityControl
Expand Down
53 changes: 53 additions & 0 deletions Framework/include/QualityControl/ConditionAccess.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#ifndef QUALITYCONTROL_CONDITIONACCESS_H
#define QUALITYCONTROL_CONDITIONACCESS_H

#include <string>
#include <map>
#include <CCDB/BasicCCDBManager.h>

namespace o2::quality_control::core
{

class ConditionAccess
{
public:
/// Default constructor
ConditionAccess() = default;
/// Destructor
virtual ~ConditionAccess() = default;

void setCcdbUrl(const std::string& url)
{
o2::ccdb::BasicCCDBManager::instance().setURL(url);
}

/**
* Get an object from the CCDB. The object is owned by the CCDBManager, don't delete it !
*/
template <typename T>
T* retrieveConditionAny(std::string const& path, std::map<std::string, std::string> const& metadata = {}, long timestamp = -1);
};

template <typename T>
T* ConditionAccess::retrieveConditionAny(std::string const& path, std::map<std::string, std::string> const& metadata, long timestamp)
{
auto& mgr = o2::ccdb::BasicCCDBManager::instance();
mgr.setFatalWhenNull(false);
mgr.setTimestamp(timestamp);
return mgr.getSpecific<T>(path, mgr.getTimestamp(), metadata);
}

} // namespace o2::quality_control::core

#endif // QUALITYCONTROL_CONDITIONACCESS_H
7 changes: 1 addition & 6 deletions Framework/include/QualityControl/Reductor.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
#ifndef QUALITYCONTROL_REDUCTOR_H
#define QUALITYCONTROL_REDUCTOR_H

#include <TObject.h>

namespace o2::quality_control::postprocessing
{

/// \brief An interface for storing data derived from QC objects into a TTree
/// \brief An interface for storing columnar data into a TTree
class Reductor
{
public:
Expand All @@ -36,9 +34,6 @@ class Reductor
/// \brief Branch leaf list getter
/// \return A C string with a description of a branch format, formatted accordingly to the TTree interface
virtual const char* getBranchLeafList() = 0;
/// \brief Fill the data structure with new data
/// \param An object to be reduced
virtual void update(TObject* obj) = 0;
};

} // namespace o2::quality_control::postprocessing
Expand Down
73 changes: 73 additions & 0 deletions Framework/include/QualityControl/ReductorConditionAny.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file ReductorConditionAny.h
/// \author Piotr Konopka
///
#ifndef QUALITYCONTROL_REDUCTORCONDITIONANY_H
#define QUALITYCONTROL_REDUCTORCONDITIONANY_H

#include "QualityControl/Reductor.h"
#include <QualityControl/ConditionAccess.h>

namespace o2::quality_control::postprocessing
{

/// \brief An interface for storing data derived from any object into a TTree
class ReductorConditionAny : public Reductor
{
public:
class ConditionRetriever;

/// \brief Constructor
ReductorConditionAny() = default;
/// \brief Destructor
virtual ~ReductorConditionAny() = default;

/// \brief A helper for the caller to have the ConditionRetriever created
virtual bool update(core::ConditionAccess& conditionAccess, uint64_t timestamp, const std::string& path) final
{
ConditionRetriever retriever{ conditionAccess, timestamp, path };
return update(retriever);
}

/// \brief Fill the data structure with new data
/// \param An object getter, object presence is not guaranteed
/// \return false if failed, true if success
virtual bool update(ConditionRetriever& retriever) = 0;

/// \brief A wrapper class to allow implementations of ReductorConditionAny to state the expected type of the reduced object.
///
/// A wrapper class to allow implementations of ReductorConditionAny to state the expected type of the reduced object.
/// It is declared within ReductorConditionAny, as it is intended to be used only in this context.
struct ConditionRetriever {
public:
ConditionRetriever(core::ConditionAccess& conditionAccess, uint64_t timestamp, const std::string& path)
: conditionAccess(conditionAccess), timestamp(timestamp), path(path){};
~ConditionRetriever() = default;

/// \brief Gets the object with a specified type. The result can be nullptr, the pointer should not be deleted!
template <typename T>
T* retrieve()
{
return conditionAccess.retrieveConditionAny<T>(path, {}, timestamp);
}

private:
core::ConditionAccess& conditionAccess;
uint64_t timestamp;
const std::string& path;
};
};

} // namespace o2::quality_control::postprocessing
#endif // QUALITYCONTROL_REDUCTORCONDITIONANY_H
71 changes: 71 additions & 0 deletions Framework/include/QualityControl/ReductorHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file ReductorHelpers.h
/// \author Piotr Konopka
///

#ifndef QUALITYCONTROL_REDUCTORHELPERS_H
#define QUALITYCONTROL_REDUCTORHELPERS_H

#include <string>

namespace o2::quality_control
{
namespace postprocessing
{
class Reductor;
struct Trigger;
} // namespace postprocessing
namespace core
{
class ConditionAccess;
}
namespace repository
{
class DatabaseInterface;
}
} // namespace o2::quality_control

namespace o2::quality_control::postprocessing::reductor_helpers
{

namespace implementation
{

/// \brief implementation details of updateReductor, hiding some header inclusions
bool updateReductorImpl(Reductor* r, const Trigger& t, const std::string& path, const std::string& name, const std::string& type,
repository::DatabaseInterface& qcdb, core::ConditionAccess& ccdbAccess);

} // namespace implementation

/// \brief Updates the provided Reductor with implementation-specific procedures
///
/// \tparam DataSourceT data source structure type to be accessed. path, name and type string members are required.
/// \param r reductor which is going to be type-checked
/// \param t trigger
/// \param ds data source
/// \param qcdb QCDB interface
/// \param ccdbAccess a class which has access to conditions
/// \return bool value indicating the success or failure in reducing an object
template <typename DataSourceT>
bool updateReductor(Reductor* r, const Trigger& t, const DataSourceT& ds, repository::DatabaseInterface& qcdb, core::ConditionAccess& ccdbAccess)
{
const std::string& path = ds.path;
const std::string& name = ds.name;
const std::string& type = ds.type;

return implementation::updateReductorImpl(r, t, path, name, type, qcdb, ccdbAccess);
}

} // namespace o2::quality_control::postprocessing::reductor_helpers
#endif // QUALITYCONTROL_REDUCTORHELPERS_H
42 changes: 42 additions & 0 deletions Framework/include/QualityControl/ReductorTObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file ReductorTObject.h
/// \author Piotr Konopka
///
#ifndef QUALITYCONTROL_REDUCTORTOBJECT_H
#define QUALITYCONTROL_REDUCTORTOBJECT_H

#include "QualityControl/Reductor.h"
#include <RtypesCore.h>

class TObject;

namespace o2::quality_control::postprocessing
{

/// \brief An interface for storing data derived from TObjects into a TTree
class ReductorTObject : public Reductor
{
public:
/// \brief Constructor
ReductorTObject() = default;
/// \brief Destructor
virtual ~ReductorTObject() = default;

/// \brief Fill the data structure with new data
/// \param An object to be reduced into a limited set of observables
virtual void update(TObject* obj) = 0;
};

} // namespace o2::quality_control::postprocessing
#endif // QUALITYCONTROL_REDUCTORTOBJECT_H
20 changes: 2 additions & 18 deletions Framework/include/QualityControl/UserCodeInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#include <string>
#include <map>
#include <Rtypes.h>
#include <CCDB/BasicCCDBManager.h>

#include "QualityControl/ConditionAccess.h"
#include "QualityControl/CustomParameters.h"

namespace o2::quality_control::core
Expand All @@ -30,7 +30,7 @@ namespace o2::quality_control::core
/// \brief Common interface for Check and Task Interfaces.
///
/// \author Barthelemy von Haller
class UserCodeInterface
class UserCodeInterface : public ConditionAccess
{
public:
/// Default constructor
Expand All @@ -46,32 +46,16 @@ class UserCodeInterface
/// It is called each time mCustomParameters is updated, including the first time it is read.
virtual void configure() = 0;

void setCcdbUrl(const std::string& url);
const std::string& getName() const;
void setName(const std::string& name);

/**
* Get an object from the CCDB. The object is owned by the CCDBManager, don't delete it !
*/
template <typename T>
T* retrieveConditionAny(std::string const& path, std::map<std::string, std::string> const& metadata = {}, long timestamp = -1);

protected:
CustomParameters mCustomParameters;
std::string mName;

ClassDef(UserCodeInterface, 3)
};

template <typename T>
T* UserCodeInterface::retrieveConditionAny(std::string const& path, std::map<std::string, std::string> const& metadata, long timestamp)
{
auto& mgr = o2::ccdb::BasicCCDBManager::instance();
mgr.setFatalWhenNull(false);
mgr.setTimestamp(timestamp);
return mgr.getSpecific<T>(path, mgr.getTimestamp(), metadata);
}

} // namespace o2::quality_control::core

#endif // QUALITYCONTROL_USERCODEINTERFACE_H
62 changes: 62 additions & 0 deletions Framework/src/ReductorHelpers.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file ReductorHelpers.cxx
/// \author Piotr Konopka
///

#include "QualityControl/ReductorHelpers.h"

#include "QualityControl/Reductor.h"
#include "QualityControl/ReductorTObject.h"
#include "QualityControl/ReductorConditionAny.h"
#include "QualityControl/Triggers.h"
#include "QualityControl/DatabaseInterface.h"
#include "QualityControl/ConditionAccess.h"

namespace o2::quality_control::postprocessing::reductor_helpers::implementation
{

bool updateReductorImpl(Reductor* r, const Trigger& t, const std::string& path, const std::string& name, const std::string& type,
repository::DatabaseInterface& qcdb, core::ConditionAccess& ccdbAccess)
{
if (r == nullptr) {
return false;
}

if (type == "repository") {
auto mo = qcdb.retrieveMO(path, name, t.timestamp, t.activity);
TObject* obj = mo ? mo->getObject() : nullptr;
auto reductorTObject = dynamic_cast<ReductorTObject*>(r);
if (obj && reductorTObject) {
reductorTObject->update(obj);
return true;
}
} else if (type == "repository-quality") {
auto qo = qcdb.retrieveQO(path + "/" + name, t.timestamp, t.activity);
auto reductorTObject = dynamic_cast<ReductorTObject*>(r);
if (qo && reductorTObject) {
reductorTObject->update(qo.get());
return true;
}
} else if (type == "condition") {
auto reductorConditionAny = dynamic_cast<ReductorConditionAny*>(r);
if (reductorConditionAny) {
auto conditionPath = name.empty() || path.empty() ? path + name : path + "/" + name;
reductorConditionAny->update(ccdbAccess, t.timestamp, conditionPath);
return true;
}
}
return false;
}

} // namespace o2::quality_control::postprocessing::reductor_helpers::implementation
Loading

0 comments on commit 57314e0

Please sign in to comment.