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>
34
35// NOTE: The DataFormatsTPC package does not have all required dependencies for these includes.
36// The users of these headers should add them by themselves, in order to avoid making
37// DataFormatsTPC depend on the Framework.
38
39namespace o2
40{
41namespace tpc
42{
43namespace internal
44{
50 std::map<int, InputRef> inputrefs;
51 std::vector<o2::dataformats::ConstMCLabelContainerView> mcInputs;
52 std::vector<gsl::span<const char>> inputs;
53 std::vector<o2::dataformats::ConstMCLabelContainerView> inputDigitsMC;
54 std::unique_ptr<ClusterNative[]> clusterBuffer;
56};
59 std::array<gsl::span<const o2::tpc::Digit>, constants::MAXSECTOR> inputDigits;
60 std::array<const o2::dataformats::ConstMCLabelContainerView*, constants::MAXSECTOR> inputDigitsMCPtrs;
62};
63} // namespace internal
64
65static 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)
66{
67 auto retVal = std::make_unique<internal::getWorkflowTPCInput_ret>();
68
69 if (do_clusters && do_digits) {
70 throw std::invalid_argument("Currently cannot process both clusters and digits");
71 }
72 std::array<int, constants::MAXSECTOR> inputDigitsMCIndex;
73
74 if (do_mcLabels) {
75 std::vector<o2::framework::InputSpec> filter = {
76 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "DIGITSMCTR"}, o2::framework::Lifetime::Timeframe},
77 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "CLNATIVEMCLBL"}, o2::framework::Lifetime::Timeframe},
78 };
79 unsigned long recvMask = 0;
80 if (do_digits) {
81 std::fill(inputDigitsMCIndex.begin(), inputDigitsMCIndex.end(), -1);
82 }
83 for (auto const& ref : o2::framework::InputRecordWalker(pc.inputs(), filter)) {
84 auto const* sectorHeader = o2::framework::DataRefUtils::getHeader<TPCSectorHeader*>(ref);
85 if (sectorHeader == nullptr) {
86 // FIXME: think about error policy
87 LOG(error) << "sector header missing on header stack";
88 return retVal;
89 }
90 const int sector = sectorHeader->sector();
91 if (sector < 0) {
92 continue;
93 }
94 if (recvMask & sectorHeader->sectorBits) {
95 throw std::runtime_error("can only have one MC data set per sector");
96 }
97 recvMask |= (sectorHeader->sectorBits & tpcSectorMask);
98 retVal->internal.inputrefs[sector].labels = ref;
99 if (do_digits) {
100 inputDigitsMCIndex[sector] = retVal->internal.inputDigitsMC.size();
101 retVal->internal.inputDigitsMC.emplace_back(o2::dataformats::ConstMCLabelContainerView(pc.inputs().get<gsl::span<char>>(ref)));
102 }
103 }
104 if (recvMask != tpcSectorMask) {
105 throw std::runtime_error("Incomplete set of MC labels received");
106 }
107 if (do_digits) {
108 for (unsigned int i = 0; i < constants::MAXSECTOR; i++) {
109 if (tpcSectorMask & (1ul << i)) {
110 if (verbosity >= 1) {
111 LOG(info) << "GOT MC LABELS FOR SECTOR " << i << " -> " << retVal->internal.inputDigitsMC[inputDigitsMCIndex[i]].getNElements();
112 }
113 if (inputDigitsMCIndex[i] == -1) {
114 throw std::runtime_error("digit mc labels missing");
115 }
116 retVal->inputDigitsMCPtrs[i] = &retVal->internal.inputDigitsMC[inputDigitsMCIndex[i]];
117 } else {
118 retVal->inputDigitsMCPtrs[i] = nullptr;
119 }
120 }
121 }
122 }
123
124 if (do_clusters || do_digits) {
125 std::vector<o2::framework::InputSpec> filter = {
126 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "DIGITS"}, o2::framework::Lifetime::Timeframe},
127 {"check", o2::framework::ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "CLUSTERNATIVE"}, o2::framework::Lifetime::Timeframe},
128 };
129 unsigned long recvMask = 0;
130 for (auto const& ref : o2::framework::InputRecordWalker(pc.inputs(), filter)) {
131 auto const* sectorHeader = o2::framework::DataRefUtils::getHeader<TPCSectorHeader*>(ref);
132 if (sectorHeader == nullptr) {
133 throw std::runtime_error("sector header missing on header stack");
134 }
135 const int sector = sectorHeader->sector();
136 if (sector < 0) {
137 continue;
138 }
139 if (recvMask & sectorHeader->sectorBits) {
140 throw std::runtime_error("can only have one cluster data set per sector");
141 }
142 recvMask |= (sectorHeader->sectorBits & tpcSectorMask);
143 retVal->internal.inputrefs[sector].data = ref;
144 if (do_digits) {
145 if (tpcSectorMask & (1ul << sector)) {
146 retVal->inputDigits[sector] = pc.inputs().get<gsl::span<o2::tpc::Digit>>(ref);
147 if (verbosity >= 1) {
148 LOG(info) << "GOT DIGITS SPAN FOR SECTOR " << sector << " -> " << retVal->inputDigits[sector].size();
149 }
150 }
151 }
152 }
153 if (recvMask != tpcSectorMask) {
154 throw std::runtime_error("Incomplete set of clusters/digits received");
155 }
156
157 for (auto const& refentry : retVal->internal.inputrefs) {
158 auto& sector = refentry.first;
159 auto& ref = refentry.second.data;
160 if (do_clusters) {
161 if (ref.payload == nullptr) {
162 // skip zero-length message
163 continue;
164 }
165 if (!(tpcSectorMask & (1ul << sector))) {
166 continue;
167 }
168 if (refentry.second.labels.header != nullptr && refentry.second.labels.payload != nullptr) {
169 retVal->internal.mcInputs.emplace_back(o2::dataformats::ConstMCLabelContainerView(pc.inputs().get<gsl::span<char>>(refentry.second.labels)));
170 }
171 retVal->internal.inputs.emplace_back(gsl::span(ref.payload, o2::framework::DataRefUtils::getPayloadSize(ref)));
172 }
173 if (verbosity > 1) {
174 LOG(info) << "received " << *(ref.spec) << ", size " << o2::framework::DataRefUtils::getPayloadSize(ref) << " for sector " << sector;
175 }
176 }
177 }
178
179 if (do_clusters) {
180 memset(&retVal->clusterIndex, 0, sizeof(retVal->clusterIndex));
181 ClusterNativeHelper::Reader::fillIndex(retVal->clusterIndex, retVal->internal.clusterBuffer, retVal->internal.clustersMCBuffer, retVal->internal.inputs, retVal->internal.mcInputs, tpcSectorMask);
182 }
183
184 return retVal;
185}
186
187} // namespace tpc
188} // namespace o2
189#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.
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"