Project
Loading...
Searching...
No Matches
testMFTCARecoWorkflow.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#define BOOST_TEST_MODULE MFTCARecoWorkflow
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
15#include <boost/test/unit_test.hpp>
16
17#include <algorithm>
18#include <string_view>
19#include <stdexcept>
20
27
28namespace
29{
30bool hasDevice(const o2::framework::WorkflowSpec& workflow, std::string_view name)
31{
32 return std::any_of(workflow.begin(), workflow.end(), [name](const auto& spec) { return spec.name == name; });
33}
34} // namespace
35
36BOOST_AUTO_TEST_CASE(DefaultWorkflowIsMonolithic)
37{
39 input.useMC = false;
41
42 BOOST_CHECK(hasDevice(workflow, "mft-digit-reader"));
43 BOOST_CHECK(hasDevice(workflow, "mft-clusterer"));
44 BOOST_CHECK(hasDevice(workflow, "mft-cluster-writer"));
45 BOOST_CHECK(hasDevice(workflow, "mft-ca-tracker"));
46 BOOST_CHECK(hasDevice(workflow, "mft-track-writer"));
47 BOOST_CHECK(!hasDevice(workflow, "mft-tracker"));
48}
49
50BOOST_AUTO_TEST_CASE(UpstreamClustersCanRunTrackerOnly)
51{
53 input.useMC = false;
54 input.upstreamClusters = true;
55 input.disableRootOutput = true;
57
58 BOOST_REQUIRE_EQUAL(workflow.size(), 1);
59 BOOST_CHECK_EQUAL(workflow.front().name, "mft-ca-tracker");
60}
61
62BOOST_AUTO_TEST_CASE(ParameterAliasesHaveIdenticalPrecedenceForBothEntryPoints)
63{
64 using namespace o2::mft::ca;
67 input.nThreads = 4;
68 const TrackerOptionAliases aliases{1, 1, true};
69 const auto reco = resolveWorkflowOptions(input, aliases);
70 input.kind = WorkflowKind::TrackerOnly;
71 const auto standalone = resolveWorkflowOptions(input, aliases);
72 BOOST_CHECK(reco.tracker.mode == o2::itsmft::TrackingMode::Async);
73 BOOST_CHECK(reco.tracker.mode == standalone.tracker.mode);
74 BOOST_CHECK_EQUAL(reco.tracker.nThreads, 1);
75 BOOST_CHECK_EQUAL(reco.tracker.nThreads, standalone.tracker.nThreads);
76 BOOST_CHECK(reco.tracker.filterIRFrames == standalone.tracker.filterIRFrames);
77 BOOST_REQUIRE_EQUAL(reco.diagnostics.size(), 2u);
78 BOOST_CHECK(reco.diagnostics[0].find("MFTCATrackerParam.trackingMode") != std::string::npos);
79 BOOST_CHECK(reco.diagnostics[0].find("--tracking-mode") != std::string::npos);
80 BOOST_CHECK(reco.diagnostics[1].find("MFTCATrackerParam.nThreads") != std::string::npos);
81 BOOST_CHECK(reco.diagnostics[1].find("--nThreads") != std::string::npos);
82}
83
84BOOST_AUTO_TEST_CASE(InputAndIRRoutingMatrixMatchesGraphSubscriptions)
85{
86 using namespace o2::mft::ca;
87 for (int stage = 0; stage < 3; ++stage) {
88 for (const bool subscribe : {false, true}) {
89 for (const bool filter : {false, true}) {
91 input.useMC = false;
92 input.upstreamDigits = stage == 1;
93 input.upstreamClusters = stage == 2;
94 input.useIRFrames = subscribe;
95 const auto resolved = resolveWorkflowOptions(input, {-1, 1, filter});
96 const auto workflow = o2::mft::ca_reco_workflow::getWorkflow(resolved);
97 BOOST_CHECK_EQUAL(hasDevice(workflow, "mft-digit-reader"), stage == 0);
98 BOOST_CHECK_EQUAL(hasDevice(workflow, "mft-clusterer"), stage != 2);
99 BOOST_CHECK_EQUAL(hasDevice(workflow, "its-irframe-reader"), stage == 0 && (subscribe || filter));
100 const auto tracker = std::find_if(workflow.begin(), workflow.end(), [](const auto& spec) { return spec.name == "mft-ca-tracker"; });
101 BOOST_REQUIRE(tracker != workflow.end());
102 const bool consumesIR = std::any_of(tracker->inputs.begin(), tracker->inputs.end(), [](const auto& spec) { return spec.binding == "IRFramesITS"; });
103 BOOST_CHECK_EQUAL(consumesIR, subscribe || filter);
104 BOOST_CHECK_EQUAL(resolved.tracker.filterIRFrames, filter);
105 }
106 }
107 }
108}
109
110BOOST_AUTO_TEST_CASE(OutputFlagsRetainTheirWriterPolicy)
111{
112 using namespace o2::mft::ca;
113 for (const bool disable : {false, true}) {
114 for (const bool rofs : {false, true}) {
116 input.useMC = false;
117 input.disableRootOutput = disable;
118 input.clusterROFsOnly = rofs;
119 const auto workflow = o2::mft::ca_reco_workflow::getWorkflow(resolveWorkflowOptions(input, {}));
120 BOOST_CHECK_EQUAL(hasDevice(workflow, "mft-cluster-writer"), !disable || rofs);
121 BOOST_CHECK_EQUAL(hasDevice(workflow, "mft-track-writer"), !disable);
122 }
123 }
124}
125
126BOOST_AUTO_TEST_CASE(DisabledAndInactiveTrackingHaveDistinctGraphs)
127{
128 using namespace o2::mft::ca;
130 input.useMC = false;
132 auto workflow = o2::mft::ca_reco_workflow::getWorkflow(resolveWorkflowOptions(input, {}));
133 BOOST_CHECK(hasDevice(workflow, "mft-ca-tracker"));
134 BOOST_CHECK(hasDevice(workflow, "mft-track-writer"));
135 input.runTracking = false;
136 input.useIRFrames = true;
137 workflow = o2::mft::ca_reco_workflow::getWorkflow(resolveWorkflowOptions(input, {}));
138 BOOST_CHECK(!hasDevice(workflow, "mft-ca-tracker"));
139 BOOST_CHECK(!hasDevice(workflow, "mft-track-writer"));
140 BOOST_CHECK(!hasDevice(workflow, "its-irframe-reader"));
141 input.assessment = true;
142 BOOST_CHECK_THROW(resolveWorkflowOptions(input, {}), std::invalid_argument);
143 input.assessment = false;
144 input.tracksToRecords = true;
145 BOOST_CHECK_THROW(resolveWorkflowOptions(input, {}), std::invalid_argument);
146}
147
148BOOST_AUTO_TEST_CASE(InvalidAliasesAndConflictingInputStagesFailBeforeGraphConstruction)
149{
150 using namespace o2::mft::ca;
152 BOOST_CHECK_THROW(resolveWorkflowOptions(input, {99, 1, false}), std::invalid_argument);
153 BOOST_CHECK_THROW(resolveWorkflowOptions(input, {-1, 0, false}), std::invalid_argument);
154 input.nThreads = 0;
155 BOOST_CHECK_THROW(resolveWorkflowOptions(input, {}), std::invalid_argument);
156 input.nThreads = 1;
157 input.upstreamDigits = input.upstreamClusters = true;
158 BOOST_CHECK_THROW(resolveWorkflowOptions(input, {}), std::invalid_argument);
159}
160
161BOOST_AUTO_TEST_CASE(DriverBoundaryAppliesThreadAndModeAliasesBeforeDeviceConstruction)
162{
163 using namespace o2::framework;
164 using namespace o2::mft::ca;
165 std::vector<ConfigParamSpec> specs{
166 {"nThreads", VariantType::Int, 4, {"threads"}},
167 {"tracking-mode", VariantType::String, "sync", {"mode"}},
168 {"configKeyValues", VariantType::String, "MFTCATrackerParam.nThreads=1;MFTCATrackerParam.trackingMode=1", {"parameters"}}};
169 for (const auto* key : {"disable-mc", "disable-root-output", "use-geom", "use-full-geometry", "use-irframes",
170 "digits-from-upstream", "clusters-from-upstream", "cluster-rof-branch-only", "disable-tracking",
171 "run-assessment", "disable-process-gen", "run-tracks2records", "enable-mft-staggering"}) {
172 specs.push_back({key, VariantType::Bool, false, {key}});
173 }
174 auto store = std::make_unique<ConfigParamStore>(specs, std::vector<std::unique_ptr<ParamRetriever>>{});
175 store->preload();
176 store->activate();
177 ConfigParamRegistry registry{std::move(store)};
178 ServiceRegistry services;
179 ConfigContext context{registry, ServiceRegistryRef{services}, 0, nullptr};
180 const auto reco = readWorkflowOptions(context, WorkflowKind::Reconstruction);
181 const auto standalone = readWorkflowOptions(context, WorkflowKind::TrackerOnly);
182 BOOST_CHECK_EQUAL(reco.tracker.nThreads, 1);
183 BOOST_CHECK_EQUAL(reco.tracker.nThreads, standalone.tracker.nThreads);
184 BOOST_CHECK(reco.tracker.mode == o2::itsmft::TrackingMode::Async);
185 BOOST_CHECK(reco.tracker.mode == standalone.tracker.mode);
186 registry.override("configKeyValues", std::string{"MFTCATrackerParam.trackingMode=-1"});
187 BOOST_CHECK_EQUAL(readWorkflowOptions(context, WorkflowKind::TrackerOnly).tracker.nThreads, 4);
188 o2::conf::ConfigurableParam::setValue<int>("MFTCATrackerParam", "nThreads", 1);
189}
StringRef key
GLuint const GLchar * name
Definition glcorearb.h:781
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< DataProcessorSpec > WorkflowSpec
framework::WorkflowSpec getWorkflow(const ca::WorkflowOptions &options)
WorkflowOptions resolveWorkflowOptions(const WorkflowOptionInput &, const TrackerOptionAliases &)
o2::itsmft::TrackingMode::Type mode
BOOST_AUTO_TEST_CASE(DefaultWorkflowIsMonolithic)
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())