57 std::string processorName =
"tpc-cluster-decoder";
59 std::unique_ptr<HardwareClusterDecoder> decoder;
60 std::set<o2::header::DataHeader::SubSpecificationType> activeInputs;
67 auto processAttributes = std::make_shared<ProcessAttributes>();
68 processAttributes->decoder = std::make_unique<HardwareClusterDecoder>();
69 processAttributes->sendMC = sendMC;
72 auto& decoder = processAttributes->decoder;
73 auto&
verbosity = processAttributes->verbosity;
74 auto& activeInputs = processAttributes->activeInputs;
77 auto const* dataHeader = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
85 sectorHeaderMC = DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(mclabelref);
88 if (sectorHeaderMC && sectorHeaderMC->
sector() < 0) {
91 auto const* sectorHeader = DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(
ref);
92 if (sectorHeader && sectorHeader->sector() < 0) {
96 assert(sectorHeaderMC ==
nullptr || sectorHeader->
sector() == sectorHeaderMC->
sector());
102 size_t nPages =
size / 8192;
103 std::vector<std::pair<const ClusterHardwareContainer*, std::size_t>> inputList;
105 LOG(info) <<
"Decoder input: " <<
size <<
", " << nPages <<
" pages for sector " << sectorHeader->sector();
110 std::vector<ConstMCLabelContainer> mcinCopiesFlat;
111 std::vector<ConstMCLabelContainerView> mcinCopiesFlatView;
114 mcin = pc.
inputs().
get<gsl::span<char>>(mclabelref);
115 mcinCopiesFlat.resize(nPages);
116 mcinCopiesFlatView.reserve(nPages);
118 LOG(info) <<
"Decoder input: " <<
size <<
", " << nPages <<
" pages, " << mcin.
getIndexedSize() <<
" MC label sets for sector " << sectorHeader->sector();
128 size_t totalNumberOfClusters = 0;
129 for (
size_t page = 0; page < nPages; page++) {
134 LOG(info) <<
"Decoder input in page " << std::setw(2) << page <<
": "
135 <<
"CRU " << std::setw(3) << container.
CRU <<
" "
140 for (
size_t mccopyPos = 0;
142 mccopyPos++, mcinPos++) {
149 mcinCopiesFlatView.emplace_back(mcinCopiesFlat[page]);
153 if (mcin.
getBuffer().size() && mcinPos != totalNumberOfClusters) {
154 LOG(error) <<
"inconsistent number of MC label objects processed"
155 <<
", expecting MC label objects for " << totalNumberOfClusters <<
" cluster(s)"
160 char* outputBuffer =
nullptr;
161 auto outputAllocator = [&pc, &fanSpec, &outputBuffer, sectorHeader](
size_t size) ->
char* {
166 decoder->decodeClusters(inputList, outputAllocator, (mcin.
getBuffer().size() ? &mcinCopiesFlatView :
nullptr), &mcout);
178 <<
" label object(s)" << std::endl;
187 auto processingFct = [processAttributes, processSectorFunction](
ProcessingContext& pc) {
188 struct SectorInputDesc {
194 std::map<int, SectorInputDesc> inputs;
195 std::vector<InputSpec>
filter = {
200 auto const* sectorHeader = DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(inputRef);
201 if (sectorHeader ==
nullptr) {
202 LOG(error) <<
"sector header missing on header stack for input on " << inputRef.spec->binding;
205 const int sector = sectorHeader->sector();
207 inputs[sector].dataref = inputRef;
210 inputs[sector].mclabelref = inputRef;
213 for (
auto const& input : inputs) {
215 throw std::runtime_error(
"missing the required MC label data for sector " +
std::to_string(input.first));
217 processSectorFunction(pc, input.second.dataref, input.second.mclabelref);
223 return processingFct;
226 auto createInputSpecs = [](
bool makeMcInput) {
227 std::vector<InputSpec> inputSpecs{
235 return std::move(inputSpecs);
238 auto createOutputSpecs = [](
bool makeMcOutput) {
239 std::vector<OutputSpec> outputSpecs{
248 return std::move(outputSpecs);
252 {createInputSpecs(sendMC)},
253 {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.