Project
Loading...
Searching...
No Matches
digits-sink-workflow.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
21#include "DigitFileFormat.h"
22#include "DigitIOBaseTask.h"
23#include "DigitSink.h"
28#include "Framework/Lifetime.h"
29#include "Framework/Output.h"
30#include "Framework/Task.h"
34#include <fstream>
35#include <iostream>
36#include <random>
37#include <set>
38#include <sstream>
39#include <stdexcept>
40#include <string>
41
42using namespace o2::framework;
43using namespace o2::mch;
44
45constexpr const char* OPTNAME_OUTFILE = "outfile";
46constexpr const char* OPTNAME_TXT = "txt";
47constexpr const char* OPTNAME_NO_FILE = "no-file";
48constexpr const char* OPTNAME_BINARY_FORMAT = "binary-file-format";
49constexpr const char* OPTNAME_WITHOUT_ORBITS = "without-orbits";
50constexpr const char* OPTNAME_MAX_SIZE = "max-size";
51
52void customize(std::vector<o2::framework::CompletionPolicy>& policies)
53{
54 // ordered policies for the writers
55 policies.push_back(CompletionPolicyHelpers::consumeWhenAllOrdered(".*(?:MCH|mch).*[W,w]riter.*"));
56}
57
58template <typename T>
60
62{
63 public:
64 DigitsSinkTask(bool withOrbits) : mWithOrbits{withOrbits} {}
65
66 //_________________________________________________________________________________________________
67 void init(InitContext& ic)
68 {
73 DigitIOBaseTask::init(ic);
74
75 mNoFile = ic.options().get<bool>(OPTNAME_NO_FILE);
76 mBinary = not ic.options().get<bool>(OPTNAME_TXT);
77
78 if (!mNoFile) {
79 auto outputFileName = ic.options().get<std::string>(OPTNAME_OUTFILE);
80 mStream = std::make_unique<std::fstream>(outputFileName, mBinary ? std::ios::out | std::ios::binary : std::ios::out);
81 if (mBinary) {
82 auto binaryFileFormat = ic.options().get<int>(OPTNAME_BINARY_FORMAT);
83 if (binaryFileFormat >= o2::mch::io::digitFileFormats.size()) {
84 throw std::invalid_argument(fmt::format("file version {} is unknown", binaryFileFormat));
85 }
86 auto maxsize = ic.options().get<int>(OPTNAME_MAX_SIZE);
87 LOGP(warn,
88 "Will dump binary information (version {}) up to a maximum size of {} KB",
89 binaryFileFormat, maxsize);
90 mWriter = std::make_unique<io::DigitSink>(*mStream,
91 io::digitFileFormats[binaryFileFormat],
92 static_cast<size_t>(maxsize));
93 } else {
94 LOGP(warn, "Will dump textual information");
95 mWriter = std::make_unique<io::DigitSink>(*mStream);
96 }
97 }
98 }
99
100 void writeOrbits(gsl::span<const o2::mch::OrbitInfo> orbits)
101 {
102 if (orbits.size() && !mBinary) {
103 std::set<OrbitInfo> orderedOrbits(orbits.begin(), orbits.end());
104 for (auto o : orderedOrbits) {
105 (*mStream) << " FEEID " << o.getFeeID() << " LINK " << (int)o.getLinkID() << " ORBIT " << o.getOrbit() << std::endl;
106 }
107 }
108 }
109
110 void write(gsl::span<const o2::mch::Digit> digits,
111 gsl::span<const o2::mch::ROFRecord> rofs,
112 gsl::span<const o2::mch::OrbitInfo> orbits)
113 {
114 if (mNoFile) {
115 return;
116 }
117 writeOrbits(orbits);
118 mWriter->write(digits, rofs);
119 }
120
122 {
123 gsl::span<o2::mch::OrbitInfo> voidOrbitInfos;
124
125 auto digits = pc.inputs().get<gsl::span<Digit>>("digits");
126 auto rofs = pc.inputs().get<gsl::span<o2::mch::ROFRecord>>("rofs");
127 auto orbits = mWithOrbits ? pc.inputs().get<gsl::span<o2::mch::OrbitInfo>>("orbits") : voidOrbitInfos;
128
129 if (shouldProcess()) {
131 printSummary(digits, rofs, fmt::format("{:4d} orbits", orbits.size()).c_str());
132 printFull(digits, rofs);
133 write(digits, rofs, orbits);
134 }
135 incTFid();
136 }
137
138 private:
139 std::unique_ptr<io::DigitSink> mWriter = nullptr; // actual digit writer
140 std::unique_ptr<std::iostream> mStream = nullptr; // output stream
141 bool mNoFile = false; // disable output to file
142 bool mWithOrbits = false; // expect ORBITs as input (in addition to just digits)
143 bool mBinary = true; // output is a binary file
144};
145
150void customize(std::vector<ConfigParamSpec>& workflowOptions)
151{
152 workflowOptions.emplace_back(OPTNAME_WITHOUT_ORBITS, VariantType::Bool, true,
153 ConfigParamSpec::HelpString{"do not expect, in addition to digits and rofs, to get Orbits at the input"});
154 workflowOptions.emplace_back(ConfigParamSpec{"input-digits-data-description", VariantType::String, "DIGITS", {"description string for the input digits data"}});
155 workflowOptions.emplace_back(ConfigParamSpec{"input-digitrofs-data-description", VariantType::String, "DIGITROFS", {"description string for the input digit rofs data"}});
156}
157
159
161{
162 WorkflowSpec specs;
163
164 bool withOrbits = not cc.options().get<bool>(OPTNAME_WITHOUT_ORBITS);
165
166 std::string input =
167 fmt::format("digits:MCH/{};rofs:MCH/{}",
168 cc.options().get<std::string>("input-digits-data-description"),
169 cc.options().get<std::string>("input-digitrofs-data-description"));
170 if (withOrbits) {
171 input += ";orbits:MCH/ORBITS";
172 }
173
174 auto commonOptions = o2::mch::io::getCommonOptions();
175 auto options = Options{
176 {OPTNAME_OUTFILE, VariantType::String, "digits.out", {"output file name"}},
177 {OPTNAME_NO_FILE, VariantType::Bool, false, {"no output to file"}},
178 {OPTNAME_BINARY_FORMAT, VariantType::Int, 0, {"digit binary format to use"}},
179 {OPTNAME_TXT, VariantType::Bool, false, {"output digits in text format"}},
180 {OPTNAME_MAX_SIZE, VariantType::Int, std::numeric_limits<int>::max(), {"max output size (in KB)"}}};
181 options.insert(options.end(), commonOptions.begin(), commonOptions.end());
182
183 Inputs inputs{o2::framework::select(input.c_str())};
184 const char* specName = "mch-digits-sink";
185
186 return {{specName,
187 inputs,
188 Outputs{},
189 AlgorithmSpec{adaptFromTask<DigitsSinkTask>(withOrbits)},
190 options}};
191}
A raw page parser for DPL input.
bool o
Definition of the MCH ROFrame record.
Configurable generator for RootTreeWriter processor spec.
const char * specName
void write(gsl::span< const o2::mch::Digit > digits, gsl::span< const o2::mch::ROFRecord > rofs, gsl::span< const o2::mch::OrbitInfo > orbits)
void run(ProcessingContext &pc)
DigitsSinkTask(bool withOrbits)
void writeOrbits(gsl::span< const o2::mch::OrbitInfo > orbits)
void init(InitContext &ic)
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
void printFull(gsl::span< const Digit > digits, gsl::span< const ROFRecord > rofs) const
void printSummary(gsl::span< const Digit > digits, gsl::span< const ROFRecord > rofs, const char *suffix="") const
WorkflowSpec defineDataProcessing(const ConfigContext &cc)
constexpr const char * OPTNAME_NO_FILE
constexpr const char * OPTNAME_OUTFILE
constexpr const char * OPTNAME_TXT
constexpr const char * OPTNAME_WITHOUT_ORBITS
constexpr const char * OPTNAME_BINARY_FORMAT
constexpr const char * OPTNAME_MAX_SIZE
void customize(std::vector< o2::framework::CompletionPolicy > &policies)
GLsizeiptr size
Definition glcorearb.h:659
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< DataProcessorSpec > WorkflowSpec
std::vector< InputSpec > select(char const *matcher="")
std::vector< InputSpec > Inputs
std::vector< OutputSpec > Outputs
std::vector< ConfigParamSpec > getCommonOptions()
std::array< DigitFileFormat, 5 > digitFileFormats
static CompletionPolicy consumeWhenAllOrdered(const char *name, CompletionPolicy::Matcher matcher)
as consumeWhenAll, but ensures that records are processed with incremental timeSlice (DataHeader::sta...
std::vector< o2::mch::ChannelCode > cc
std::vector< Digit > digits