Project
Loading...
Searching...
No Matches
WorkflowHelper.h
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
15
16#ifndef WORKFLOWHELPER_H
17#define WORKFLOWHELPER_H
18
19#include <memory>
35
36// NOTE: The DataFormatsTPC package does not have all required dependencies for these includes.
37// The users of these headers should add them by themselves, in order to avoid making
38// DataFormatsTPC depend on the Framework.
39
40namespace o2
41{
42namespace tpc
43{
44namespace internal
45{
51 std::map<int, InputRef> inputrefs;
52 std::vector<o2::dataformats::ConstMCLabelContainerView> mcInputs;
53 std::vector<gsl::span<const char>> inputs;
54 std::vector<o2::dataformats::ConstMCLabelContainerView> inputDigitsMC;
55 std::unique_ptr<ClusterNative[]> clusterBuffer;
57};
60 std::array<gsl::span<const o2::tpc::Digit>, constants::MAXSECTOR> inputDigits;
61 std::array<const o2::dataformats::ConstMCLabelContainerView*, constants::MAXSECTOR> inputDigitsMCPtrs;
63};
64} // namespace internal
65
66static auto getWorkflowTPCInput(o2::framework::ProcessingContext& pc, int verbosity = 0, bool do_mcLabels = false, bool do_clusters = true, unsigned long tpcSectorMask = 0xFFFFFFFFF, bool do_digits = false)
67{
68 auto retVal = std::make_unique<internal::getWorkflowTPCInput_ret>();
69
70 if (do_clusters && do_digits) {
71 throw std::invalid_argument("Currently cannot process both clusters and digits");
72 }
73 std::array<int, constants::MAXSECTOR> inputDigitsMCIndex;
74
75 if (do_mcLabels) {
76 std::vector<o2::framework::InputSpec> filter = {
77 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "DIGITSMCTR"}, o2::framework::Lifetime::Timeframe},
78 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "CLNATIVEMCLBL"}, o2::framework::Lifetime::Timeframe},
79 };
80 unsigned long recvMask = 0;
81 if (do_digits) {
82 std::fill(inputDigitsMCIndex.begin(), inputDigitsMCIndex.end(), -1);
83 }
84 for (auto const& ref : o2::framework::InputRecordWalker<o2::utilities::DataSamplingHeader>(pc.inputs(), filter)) {
85 auto const* sectorHeader = o2::framework::DataRefUtils::getHeader<TPCSectorHeader*>(ref);
86 if (sectorHeader == nullptr) {
87 // FIXME: think about error policy
88 LOG(error) << "sector header missing on header stack";
89 return retVal;
90 }
91 const int sector = sectorHeader->sector();
92 if (sector < 0) {
93 continue;
94 }
95 if (recvMask & sectorHeader->sectorBits) {
96 throw std::runtime_error("can only have one MC data set per sector");
97 }
98 recvMask |= (sectorHeader->sectorBits & tpcSectorMask);
99 retVal->internal.inputrefs[sector].labels = ref;
100 if (do_digits) {
101 inputDigitsMCIndex[sector] = retVal->internal.inputDigitsMC.size();
102 retVal->internal.inputDigitsMC.emplace_back(o2::dataformats::ConstMCLabelContainerView(pc.inputs().get<gsl::span<char>>(ref)));
103 }
104 }
105 if (recvMask != tpcSectorMask) {
106 throw std::runtime_error("Incomplete set of MC labels received");
107 }
108 if (do_digits) {
109 for (unsigned int i = 0; i < constants::MAXSECTOR; i++) {
110 if (tpcSectorMask & (1ul << i)) {
111 if (verbosity >= 1) {
112 LOG(info) << "GOT MC LABELS FOR SECTOR " << i << " -> " << retVal->internal.inputDigitsMC[inputDigitsMCIndex[i]].getNElements();
113 }
114 if (inputDigitsMCIndex[i] == -1) {
115 throw std::runtime_error("digit mc labels missing");
116 }
117 retVal->inputDigitsMCPtrs[i] = &retVal->internal.inputDigitsMC[inputDigitsMCIndex[i]];
118 } else {
119 retVal->inputDigitsMCPtrs[i] = nullptr;
120 }
121 }
122 }
123 }
124
125 if (do_clusters || do_digits) {
126 std::vector<o2::framework::InputSpec> filter = {
127 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "DIGITS"}, o2::framework::Lifetime::Timeframe},
128 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "CLUSTERNATIVE"}, o2::framework::Lifetime::Timeframe},
129 };
130 unsigned long recvMask = 0;
131 for (auto const& ref : o2::framework::InputRecordWalker<o2::utilities::DataSamplingHeader>(pc.inputs(), filter)) {
132 auto const* sectorHeader = o2::framework::DataRefUtils::getHeader<TPCSectorHeader*>(ref);
133 if (sectorHeader == nullptr) {
134 throw std::runtime_error("sector header missing on header stack");
135 }
136 const int sector = sectorHeader->sector();
137 if (sector < 0) {
138 continue;
139 }
140 if (recvMask & sectorHeader->sectorBits) {
141 throw std::runtime_error("can only have one cluster data set per sector");
142 }
143 recvMask |= (sectorHeader->sectorBits & tpcSectorMask);
144 retVal->internal.inputrefs[sector].data = ref;
145 if (do_digits) {
146 if (tpcSectorMask & (1ul << sector)) {
147 retVal->inputDigits[sector] = pc.inputs().get<gsl::span<o2::tpc::Digit>>(ref);
148 if (verbosity >= 1) {
149 LOG(info) << "GOT DIGITS SPAN FOR SECTOR " << sector << " -> " << retVal->inputDigits[sector].size();
150 }
151 }
152 }
153 }
154 if (recvMask != tpcSectorMask) {
155 throw std::runtime_error("Incomplete set of clusters/digits received");
156 }
157
158 for (auto const& refentry : retVal->internal.inputrefs) {
159 auto& sector = refentry.first;
160 auto& ref = refentry.second.data;
161 if (do_clusters) {
162 if (ref.payload == nullptr) {
163 // skip zero-length message
164 continue;
165 }
166 if (!(tpcSectorMask & (1ul << sector))) {
167 continue;
168 }
169 if (refentry.second.labels.header != nullptr && refentry.second.labels.payload != nullptr) {
170 retVal->internal.mcInputs.emplace_back(o2::dataformats::ConstMCLabelContainerView(pc.inputs().get<gsl::span<char>>(refentry.second.labels)));
171 }
172 retVal->internal.inputs.emplace_back(gsl::span(ref.payload, o2::framework::DataRefUtils::getPayloadSize(ref)));
173 }
174 if (verbosity > 1) {
175 LOG(info) << "received " << *(ref.spec) << ", size " << o2::framework::DataRefUtils::getPayloadSize(ref) << " for sector " << sector;
176 }
177 }
178 }
179
180 if (do_clusters) {
181 memset(&retVal->clusterIndex, 0, sizeof(retVal->clusterIndex));
182 ClusterNativeHelper::Reader::fillIndex(retVal->clusterIndex, retVal->internal.clusterBuffer, retVal->internal.clustersMCBuffer, retVal->internal.inputs, retVal->internal.mcInputs, tpcSectorMask);
183 }
184
185 return retVal;
186}
187
188} // namespace tpc
189} // namespace o2
190#endif // WORKFLOWHELPER_H
#define verbosity
Meta data for a group describing it by sector number and global padrow.
Helper class to read the binary format of TPC ClusterNative.
Class of a TPC cluster in TPC-native coordinates (row, time)
A const (ready only) version of MCTruthContainer.
Definition of the TPC Digit.
A declaration of O2 Data Sampling Header.
int32_t i
int32_t retVal
A helper class to iteratate over all parts of all input routes.
Definition of a container to keep Monte Carlo truth external to simulation objects.
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
ClusterNativeAccess::ConstMCLabelContainerViewWithBuffer ConstMCLabelContainerViewWithBuffer
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLint ref
Definition glcorearb.h:291
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
constexpr int MAXSECTOR
Definition Constants.h:28
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
o2::framework::DataRef data
o2::framework::DataRef labels
std::vector< o2::dataformats::ConstMCLabelContainerView > inputDigitsMC
ClusterNativeHelper::ConstMCLabelContainerViewWithBuffer clustersMCBuffer
std::vector< gsl::span< const char > > inputs
std::unique_ptr< ClusterNative[]> clusterBuffer
std::vector< o2::dataformats::ConstMCLabelContainerView > mcInputs
std::array< gsl::span< const o2::tpc::Digit >, constants::MAXSECTOR > inputDigits
std::array< const o2::dataformats::ConstMCLabelContainerView *, constants::MAXSECTOR > inputDigitsMCPtrs
getWorkflowTPCInput_ret_internal internal
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"