56 std::string processorName =
"tpc-cluster-decoder";
58 std::unique_ptr<HardwareClusterDecoder> decoder;
59 std::set<o2::header::DataHeader::SubSpecificationType> activeInputs;
66 auto processAttributes = std::make_shared<ProcessAttributes>();
67 processAttributes->decoder = std::make_unique<HardwareClusterDecoder>();
68 processAttributes->sendMC = sendMC;
71 auto& decoder = processAttributes->decoder;
72 auto&
verbosity = processAttributes->verbosity;
73 auto& activeInputs = processAttributes->activeInputs;
76 auto const* dataHeader = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
86 sectorHeaderMC = DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(mclabelref);
89 std::swap(mcHeaderStack, actual);
90 if (sectorHeaderMC->
sector() < 0) {
95 auto const* sectorHeader = DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(
ref);
98 std::swap(rawHeaderStack, actual);
99 if (sectorHeader->sector() < 0) {
104 assert(sectorHeaderMC ==
nullptr || sectorHeader->
sector() == sectorHeaderMC->
sector());
110 size_t nPages =
size / 8192;
111 std::vector<std::pair<const ClusterHardwareContainer*, std::size_t>> inputList;
113 LOG(info) <<
"Decoder input: " <<
size <<
", " << nPages <<
" pages for sector " << sectorHeader->sector();
118 std::vector<ConstMCLabelContainer> mcinCopiesFlat;
119 std::vector<ConstMCLabelContainerView> mcinCopiesFlatView;
122 mcin = pc.
inputs().
get<gsl::span<char>>(mclabelref);
123 mcinCopiesFlat.resize(nPages);
124 mcinCopiesFlatView.reserve(nPages);
126 LOG(info) <<
"Decoder input: " <<
size <<
", " << nPages <<
" pages, " << mcin.
getIndexedSize() <<
" MC label sets for sector " << sectorHeader->sector();
136 size_t totalNumberOfClusters = 0;
137 for (
size_t page = 0; page < nPages; page++) {
142 LOG(info) <<
"Decoder input in page " << std::setw(2) << page <<
": "
143 <<
"CRU " << std::setw(3) << container.
CRU <<
" "
148 for (
size_t mccopyPos = 0;
150 mccopyPos++, mcinPos++) {
157 mcinCopiesFlatView.emplace_back(mcinCopiesFlat[page]);
161 if (mcin.
getBuffer().size() && mcinPos != totalNumberOfClusters) {
162 LOG(error) <<
"inconsistent number of MC label objects processed"
163 <<
", expecting MC label objects for " << totalNumberOfClusters <<
" cluster(s)"
168 char* outputBuffer =
nullptr;
169 auto outputAllocator = [&pc, &fanSpec, &outputBuffer, &rawHeaderStack](
size_t size) ->
char* {
174 decoder->decodeClusters(inputList, outputAllocator, (mcin.
getBuffer().size() ? &mcinCopiesFlatView :
nullptr), &mcout);
186 <<
" label object(s)" << std::endl;
195 auto processingFct = [processAttributes, processSectorFunction](
ProcessingContext& pc) {
196 struct SectorInputDesc {
202 std::map<int, SectorInputDesc> inputs;
203 std::vector<InputSpec>
filter = {
208 auto const* sectorHeader = DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(inputRef);
209 if (sectorHeader ==
nullptr) {
210 LOG(error) <<
"sector header missing on header stack for input on " << inputRef.spec->binding;
213 const int sector = sectorHeader->sector();
215 inputs[sector].dataref = inputRef;
218 inputs[sector].mclabelref = inputRef;
221 for (
auto const& input : inputs) {
223 throw std::runtime_error(
"missing the required MC label data for sector " +
std::to_string(input.first));
225 processSectorFunction(pc, input.second.dataref, input.second.mclabelref);
231 return processingFct;
234 auto createInputSpecs = [](
bool makeMcInput) {
235 std::vector<InputSpec> inputSpecs{
243 return std::move(inputSpecs);
246 auto createOutputSpecs = [](
bool makeMcOutput) {
247 std::vector<OutputSpec> outputSpecs{
256 return std::move(outputSpecs);
260 {createInputSpecs(sendMC)},
261 {createOutputSpecs(sendMC)},
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.