Skip to content

Commit d4e415a

Browse files
committed
DPL Test Workflow: dummy example using Ruben AOD spec
This is just a dummy example which uses part of Ruben's AOD schema from WP1 meeting on the 1st of November. Just a placeholder to get people started on it.
1 parent d9ab755 commit d4e415a

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

Framework/TestWorkflows/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ O2_GENERATE_EXECUTABLE(
6363
BUCKET_NAME ${MODULE_BUCKET_NAME}
6464
)
6565

66+
O2_GENERATE_EXECUTABLE(
67+
EXE_NAME "o2AODDummy"
68+
SOURCES "src/o2AODDummy.cxx"
69+
MODULE_LIBRARY_NAME ${LIBRARY_NAME}
70+
BUCKET_NAME ${MODULE_BUCKET_NAME}
71+
)
6672

6773
O2_GENERATE_EXECUTABLE(
6874
EXE_NAME "test_MakeDPLObjects"
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
#include "Framework/runDataProcessing.h"
11+
12+
#include <ROOT/RDataFrame.hxx>
13+
#include <ROOT/RArrowDS.hxx>
14+
15+
using namespace o2::framework;
16+
17+
// A dummy workflow which creates a few of the tables proposed by Ruben,
18+
// using ARROW
19+
WorkflowSpec defineDataProcessing(ConfigContext const& specs)
20+
{
21+
WorkflowSpec workflow{
22+
DataProcessorSpec{
23+
"dummy-aod-producer",
24+
{},
25+
{
26+
OutputSpec{ { "TrackPar" }, "AOD", "TRACKPAR" },
27+
OutputSpec{ { "TrackParCov" }, "AOD", "TRACKPARCOV" },
28+
OutputSpec{ { "TrackExtra" }, "AOD", "TRACKEXTRA" },
29+
OutputSpec{ { "Muon" }, "AOD", "MUONINFO" },
30+
OutputSpec{ { "Calo" }, "AOD", "CALOINFO" },
31+
},
32+
AlgorithmSpec{
33+
[](InitContext& setup) {
34+
return [](ProcessingContext& ctx) {
35+
/// We get the table builder for track param.
36+
auto& trackParBuilder = ctx.outputs().make<TableBuilder>(Output{ "AOD", "TRACKPAR" });
37+
auto& trackParCovBuilder = ctx.outputs().make<TableBuilder>(Output{ "AOD", "TRACKPARCOV" });
38+
// We use RDataFrame to create a few columns with 100 rows.
39+
// The final action is the one which allows the user to create the
40+
// output message.
41+
//
42+
// FIXME: bloat in the code I'd like to get rid of:
43+
//
44+
// * I need to specify the types for the columns
45+
// * I need to specify the names of the columns twice
46+
// * I should use the RDataFrame to read / convert from the ESD...
47+
// Using dummy values for now.
48+
ROOT::RDataFrame rdf(100);
49+
auto trackParRDF = rdf.Define("mX", "1.f")
50+
.Define("mAlpha", "2.f")
51+
.Define("y", "3.f")
52+
.Define("z", "4.f")
53+
.Define("snp", "5.f")
54+
.Define("tgl", "6.f")
55+
.Define("qpt", "7.f");
56+
57+
/// FIXME: think of the best way to include the non-diag elements.
58+
auto trackParCorRDF = rdf.Define("sigY", "1.f")
59+
.Define("sigZ", "2.f")
60+
.Define("sigSnp", "3.f")
61+
.Define("sigTgl", "4.f")
62+
.Define("sigQpt", "5.f");
63+
64+
/// FIXME: we need to do some cling magic to hide all of this.
65+
trackParRDF.ForeachSlot(trackParBuilder.persist<float, float, float, float, float, float, float>(
66+
{ "mX", "mAlpha", "y", "z", "snp", "tgl", "qpt" }),
67+
{ "mX", "mAlpha", "y", "z", "snp", "tgl", "qpt" });
68+
69+
trackParCorRDF.ForeachSlot(trackParCovBuilder.persist<float, float, float, float, float>(
70+
{ "sigY", "sigZ", "sigSnp", "sigTgl", "sigQpt" }),
71+
{ "sigY", "sigZ", "sigSnp", "sigTgl", "sigQpt" });
72+
73+
};
74+
} },
75+
{ ConfigParamSpec{ "infile", VariantType::Int, 28, { "Input ESD file" } } } },
76+
/// Minimal analysis example
77+
DataProcessorSpec{
78+
"dummy-analysis",
79+
{ InputSpec{ "TrackPar", "AOD", "TRACKPAR" },
80+
InputSpec{ "TrackParCov", "AOD", "TRACKPARCOV" } },
81+
{},
82+
AlgorithmSpec{
83+
[](InitContext& setup) {
84+
return [](ProcessingContext& ctx) {
85+
auto s = ctx.inputs().get<TableConsumer>("TrackPar");
86+
/// From the handle, we construct the actual arrow table
87+
/// which is then used as a source for the RDataFrame.
88+
/// This is probably easy to change to a:
89+
///
90+
/// auto rdf = ctx.inputs().get<RDataSource>("xz");
91+
auto table = s->asArrowTable();
92+
if (table->num_rows() != 100) {
93+
LOG(ERROR) << "Wrong number of entries for the arrow table" << table->num_rows();
94+
}
95+
if (table->num_columns() != 7) {
96+
LOG(ERROR) << "Wrong number of columns for the arrow table" << table->num_columns();
97+
}
98+
auto source = std::make_unique<ROOT::RDF::RArrowDS>(s->asArrowTable(), std::vector<std::string>{});
99+
100+
auto s2 = ctx.inputs().get<TableConsumer>("TrackParCov");
101+
auto table2 = s->asArrowTable();
102+
auto source2 = std::make_unique<ROOT::RDF::RArrowDS>(s->asArrowTable(), std::vector<std::string>{});
103+
ROOT::RDataFrame rdf2(std::move(source2));
104+
LOG(ERROR) << *(rdf2.Count());
105+
};
106+
} } }
107+
};
108+
return workflow;
109+
}

0 commit comments

Comments
 (0)