Skip to content
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
2 changes: 2 additions & 0 deletions Modules/Example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

add_library(O2QcExample
src/BenchmarkTask.cxx
src/EveryObject.cxx
src/ExampleTask.cxx
src/AnalysisTask.cxx
src/FakeCheck.cxx
Expand All @@ -19,6 +20,7 @@ target_link_libraries(O2QcExample PUBLIC O2QualityControl)

add_root_dictionary(O2QcExample
HEADERS include/Example/BenchmarkTask.h
include/Example/EveryObject.h
include/Example/AnalysisTask.h
include/Example/ExampleTask.h
include/Example/FakeCheck.h
Expand Down
52 changes: 52 additions & 0 deletions Modules/Example/etc/every-object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"qc": {
"config": {
"database": {
"implementation": "CCDB",
"host": "ccdb-test.cern.ch:8080",
"username": "not_applicable",
"password": "not_applicable",
"name": "not_applicable"
},
"Activity": {
"number": "42",
"type": "2",
"periodName": "", "": "Period name - e.g. LHC22c, LHC22c1b_test",
"passName": "", "": "Pass type - e.g. spass, cpass1",
"provenance": "qc", "": "Provenance - qc or qc_mc depending whether it is normal data or monte carlo data"
},
"monitoring": {
"url": "infologger:///debug?qc"
},
"consul": {
"url": ""
},
"conditionDB": {
"url": "ccdb-test.cern.ch:8080"
},
"infologger": { "": "Configuration of the Infologger (optional).",
"filterDiscardDebug": "false", "": "Set to true to discard debug and trace messages (default: false)",
"filterDiscardLevel": "21", "": "Message at this level or above are discarded (default: 21 - Trace)"
}
},
"tasks": {
"EveryObject": {
"active": "true",
"className": "o2::quality_control_modules::example::EveryObject",
"moduleName": "QcExample",
"detectorName": "TST",
"cycleDurationSeconds": "10", "": "10 seconds minimum",
"maxNumberCycles": "-1",
"": "The other type of dataSource is \"direct\", see basic-no-sampling.json.",
"dataSource": {
"type": "direct",
"query": "random:TST/RAWDATA/0"
}
}
},
"checks": {
}
},
"dataSamplingPolicies": [
]
}
64 changes: 64 additions & 0 deletions Modules/Example/include/Example/EveryObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 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 EveryObject.h
/// \author Piotr Konopka
///

#ifndef QC_MODULE_EXAMPLE_EXAMPLEEVERYOBJECT_H
#define QC_MODULE_EXAMPLE_EXAMPLEEVERYOBJECT_H

#include "QualityControl/TaskInterface.h"
#include <array>

class TH1F;
class TH2F;
class TH3F;
class THnSparse;
class TCanvas;

using namespace o2::quality_control::core;

namespace o2::quality_control_modules::example
{

/// \brief Task which publishes (not exactly) every class object used as MO. Can be used to test memory leaks.
/// \author Piotr Konopka
class EveryObject final : public TaskInterface
{
public:
/// \brief Constructor
EveryObject() = default;
/// Destructor
~EveryObject() override;

// Definition of the methods for the template method pattern
void initialize(o2::framework::InitContext& ctx) override;
void startOfActivity(Activity& activity) override;
void startOfCycle() override;
void monitorData(o2::framework::ProcessingContext& ctx) override;
void endOfCycle() override;
void endOfActivity(Activity& activity) override;
void reset() override;

private:
TH1F* mTH1F = nullptr;
TH2F* mTH2F = nullptr;
TH3F* mTH3F = nullptr;
THnSparse* mTHnSparseF = nullptr;
TCanvas* mTCanvas = nullptr;
std::array<TH2F*, 4> mTCanvasMembers = { nullptr };
};

} // namespace o2::quality_control_modules::example

#endif // QC_MODULE_EXAMPLE_EXAMPLEEVERYOBJECT_H
2 changes: 1 addition & 1 deletion Modules/Example/include/Example/LinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
#pragma link C++ class o2::quality_control_modules::example::BenchmarkTask + ;
#pragma link C++ class o2::quality_control_modules::example::ExampleCondition + ;
#pragma link C++ class o2::quality_control_modules::example::CustomTH2F + ;

#pragma link C++ class o2::quality_control_modules::example::AnalysisTask + ;
#pragma link C++ class o2::quality_control_modules::example::EveryObject+;
#endif
162 changes: 162 additions & 0 deletions Modules/Example/src/EveryObject.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// 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 EveryObject.cxx
/// \author Piotr Konopka
///

#include <TCanvas.h>
#include <TH1.h>

#include "QualityControl/QcInfoLogger.h"
#include "Example/EveryObject.h"
#include <Framework/InputRecord.h>
#include <Framework/InputRecordWalker.h>

#include <TH1F.h>
#include <TH2F.h>
#include <TH3F.h>
#include <THnSparse.h>
#include <TCanvas.h>

constexpr Double_t rangeLimiter = 16 * 64000;

namespace o2::quality_control_modules::example
{

EveryObject::~EveryObject()
{
delete mTH1F;
delete mTH2F;
delete mTH3F;
delete mTHnSparseF;
delete mTCanvas; // TCanvas should delete the contained plots, given that we set kCanDelete
}

void EveryObject::initialize(o2::framework::InitContext& /*ctx*/)
{
ILOG(Info, Support) << "initialize EveryObject" << ENDM; // QcInfoLogger is used. FairMQ logs will go to there as well.

// todo: enable/disable with config flags (this is why objects are always accessed after checking if not null)
// todo: ttree, tefficiency, tprofile

mTH1F = new TH1F("th1f", "th1f", 64000, 0, rangeLimiter);
getObjectsManager()->startPublishing(mTH1F);

mTH2F = new TH2F("th2f", "th2f", 250, 0, rangeLimiter, 250, 0, rangeLimiter);
getObjectsManager()->startPublishing(mTH2F);

mTH3F = new TH3F("th3f", "th3f", 40, 0, rangeLimiter, 40, 0, rangeLimiter, 40, 0, rangeLimiter);
getObjectsManager()->startPublishing(mTH3F);
{
const size_t bins = 1000;
const size_t dim = 5;
const Double_t min = 0.0;
const Double_t max = rangeLimiter;

const std::vector<Int_t> binsDims(dim, bins);
const std::vector<Double_t> mins(dim, min);
const std::vector<Double_t> maxs(dim, max);
mTHnSparseF = new THnSparseF("thnsparsef", "thnsparsef", dim, binsDims.data(), mins.data(), maxs.data());
getObjectsManager()->startPublishing(mTHnSparseF);
}
{
mTCanvas = new TCanvas("tcanvas", "tcanvas", 1000, 1000);
mTCanvas->Clear();
mTCanvas->Divide(2, 2);
for (size_t i = 0; i < 4; i++) {
auto name = std::string("tcanvas_th2f_") + std::to_string(i);
mTCanvasMembers[i] = new TH2F(name.c_str(), name.c_str(), 250, 0, rangeLimiter, 250, 0, rangeLimiter);

mTCanvas->cd(i + 1);
mTCanvasMembers[i]->Draw();
mTCanvasMembers[i]->SetBit(TObject::kCanDelete);
}
getObjectsManager()->startPublishing(mTCanvas);
}
}

void EveryObject::startOfActivity(Activity& activity)
{
ILOG(Info, Support) << "startOfActivity " << activity.mId << ENDM;
}

void EveryObject::startOfCycle()
{
ILOG(Info, Support) << "startOfCycle" << ENDM;
}

void EveryObject::monitorData(o2::framework::ProcessingContext& ctx)
{
for (auto&& input : framework::InputRecordWalker(ctx.inputs())) {
const auto* header = header::get<header::DataHeader*>(input.header);
auto value1 = (Float_t)(header->payloadSize % (size_t)rangeLimiter);
auto value2 = (Float_t)((header->tfCounter + header->payloadSize) % (size_t)rangeLimiter);
auto value3 = (Float_t)((header->tfCounter * header->payloadSize) % (size_t)rangeLimiter);

if (mTH1F) {
mTH1F->Fill(value1);
}
if (mTH2F) {
mTH2F->Fill(value1, value3);
}
if (mTH3F) {
mTH3F->Fill(value1, value2, value3);
}
if (mTHnSparseF) {
std::array<Double_t, 5> values{ value1, value2, value3, value2 / (value1 + 1), value2 / (value3 + 1) };
mTHnSparseF->Fill(values.data());
}
if (mTCanvas) {
mTCanvasMembers[0]->Fill(value1, value3);
mTCanvasMembers[1]->Fill(value3, value1);
mTCanvasMembers[2]->Fill(value2, value3);
mTCanvasMembers[3]->Fill(value3, value2);
}
}
}

void EveryObject::endOfCycle()
{
ILOG(Info, Support) << "endOfCycle" << ENDM;
}

void EveryObject::endOfActivity(Activity& /*activity*/)
{
ILOG(Info, Support) << "endOfActivity" << ENDM;
}

void EveryObject::reset()
{
ILOG(Info, Support) << "Resetting the objects" << ENDM;
if (mTH1F) {
mTH1F->Reset();
}
if (mTH2F) {
mTH2F->Reset();
}
if (mTH3F) {
mTH3F->Reset();
}
if (mTHnSparseF) {
mTHnSparseF->Reset();
}
if (mTCanvas) {
for (const auto member : mTCanvasMembers) {
if (member) {
member->Reset();
}
}
}
}

} // namespace o2::quality_control_modules::example