104 int caClusterer,
int zsOnTheFly,
bool askDISTSTF,
bool selIR,
bool filteredInp,
int deadMapSources,
bool useMCTimeGain)
109 }
catch (std::out_of_range&) {
110 throw std::invalid_argument(std::string(
"invalid input type: ") + cfgInput);
112 std::vector<OutputType> outputTypes;
114 outputTypes = RangeTokenizer::tokenize<OutputType>(cfgOutput, [](std::string
const& token) {
return OutputMap.at(token); });
115 }
catch (std::out_of_range&) {
116 throw std::invalid_argument(std::string(
"invalid output type: ") + cfgOutput);
119 return std::find(outputTypes.begin(), outputTypes.end(),
type) != outputTypes.end();
123 throw std::invalid_argument(
"filtered-input option must be provided only with pass-through input");
151 throw std::invalid_argument(
"input/output type mismatch, can not produce 'digits' from 'clustershardware'");
154 throw std::invalid_argument(
"input/output type mismatch, can not produce 'digits', nor 'clustershardware' from 'clusters'");
157 throw std::invalid_argument(
"input/output type mismatch, can not produce 'clustershardware' from 'zsraw'");
160 throw std::invalid_argument(
"ca-clusterer requires digits as input");
163 throw std::invalid_argument(
"ca-clusterer cannot produce clustershardware output");
174 if (TString(
name.data()).Contains(
"TPCDigitMCTruth") || TString(
name.data()).Contains(
"TPCClusterHwMCTruth") || TString(
name.data()).Contains(
"TPCClusterNativeMCTruth")) {
177 storedlabels->copyandflatten(flatlabels);
179 context.outputs().snapshot(
output, flatlabels);
190 using Type = std::vector<o2::tpc::Digit>;
192 specs.emplace_back(o2::tpc::getPublisherSpec<Type>(
PublisherConf{
196 {
"digitbranch",
"TPCDigit",
"Digit branch"},
197 {
"mcbranch",
"TPCDigitMCTruth",
"MC label branch"},
212 "tpc-clusterhardware-reader",
213 "tpc-clusterhardware.root",
214 "tpcclustershardware",
215 {
"databranch",
"TPCClusterHw",
"Branch with TPC ClustersHardware"},
216 {
"mcbranch",
"TPCClusterHwMCTruth",
"MC label branch"},
225 if (!getenv(
"DPL_DISABLE_TPC_TRIGGER_READER") || atoi(getenv(
"DPL_DISABLE_TPC_TRIGGER_READER")) != 1) {
240 "tpc-compressed-cluster-reader",
241 "tpc-compclusters.root",
243 {
"clusterbranch",
"TPCCompClusters",
"Branch with TPC compressed clusters"},
247 std::vector<int>(1, 0),
248 std::vector<int>(1, 0),
268 runGPUReco &= caClusterer || runHWDecoder || inputType ==
InputType::Clusters || decompressTPC;
275 runGPUReco = runHWDecoder = runClusterer = runClusterEncoder = zsToDigit =
false;
305 parallelProcessors, nLanes,
306 [&laneConfiguration]() {
return laneConfiguration.size(); },
307 [&laneConfiguration](
size_t index) {
return laneConfiguration[
index]; });
308 specs.insert(specs.end(), parallelProcessors.begin(), parallelProcessors.end());
322 auto const* tpcSectorHeader = o2::framework::DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(
ref);
323 if (!tpcSectorHeader) {
324 throw std::runtime_error(
"TPC sector header missing in header stack");
326 if (tpcSectorHeader->sector() < 0) {
331 for (
auto const& sector : tpcSectors) {
332 if (sector == tpcSectorHeader->sector()) {
337 throw std::runtime_error(
"sector " +
std::to_string(tpcSectorHeader->sector()) +
" not configured for writing");
339 auto getName = [tpcSectors](std::string base,
size_t index) {
345 auto fillLabels = [](TBranch& branch, std::vector<char>
const& labelbuffer,
DataRef const& ) {
348 auto ptr = &outputcontainer;
350 outputcontainer.
adopt(labelbuffer);
355 auto makeWriterSpec = [tpcSectors, laneConfiguration, propagateMC, getIndex,
getName](
const char* processName,
356 const char* defaultFileName,
357 const char* defaultTreeName,
360 bool singleBranch =
false) {
361 if (tpcSectors.size() == 0) {
362 throw std::invalid_argument(std::string(
"writer process configuration needs list of TPC sectors"));
365 auto amendInput = [tpcSectors, laneConfiguration](
InputSpec& input,
size_t index) {
369 auto amendBranchDef = [laneConfiguration, amendInput, tpcSectors, getIndex,
getName, singleBranch](
auto&& def,
bool enableMC =
true) {
371 def.keys =
mergeInputs(def.keys, laneConfiguration.size(), amendInput);
373 def.nofBranches = enableMC ? tpcSectors.size() : 0;
374 def.getIndex = getIndex;
378 def.nofBranches = enableMC ? 1 : 0;
380 return std::move(def);
384 std::move(amendBranchDef(databranch)),
385 std::move(amendBranchDef(mcbranch, propagateMC)))());
394 using DigitOutputType = std::vector<o2::tpc::Digit>;
395 specs.push_back(makeWriterSpec(
"tpc-digits-writer",
401 "digit-branch-name"},
404 "digitmc-branch-name"}));
413 specs.push_back(makeWriterSpec(
"tpc-clusterhardware-writer",
415 "tpcclustershardware",
420 "TPCClusterHwMCTruth",
432 specs.push_back(makeWriterSpec(filteredInp ?
"tpc-native-cluster-writer_filtered" :
"tpc-native-cluster-writer",
433 (inputType ==
InputType::Clusters || filteredInp) ?
"tpc-filtered-native-clusters.root" :
"tpc-native-clusters.root",
439 "TPCClusterNativeMCTruth",
440 "mcbranch", fillLabels},
490 auto task = std::make_shared<o2::gpu::GPURecoWorkflowSpec>(policyData, cfg, tpcSectors, tpcSectorMask, ggRequest);
492 Inputs taskInputs = task->inputs();
493 Options taskOptions = task->options();
494 std::move(ggInputs.begin(), ggInputs.end(), std::back_inserter(taskInputs));
500 AlgorithmSpec{adoptTask<o2::gpu::GPURecoWorkflowSpec>(task)},
509 if (runClusterEncoder) {
522 const char* processName = filteredInp ?
"tpc-track-writer_filtered" :
"tpc-track-writer";
523 const char* defaultFileName = filteredInp ?
"tpctracks_filtered.root" :
"tpctracks.root";
524 const char* defaultTreeName =
"tpcrec";
527 using TrackOutputType = std::vector<o2::tpc::TrackTPC>;
529 using ClusRefsOutputType = std::vector<o2::tpc::TPCClRefElem>;
533 LOG(info) <<
"writing " << tracks.size() <<
" track(s)";
536 "TPCTracks",
"track-branch-name",
540 "ClusRefs",
"trackclusref-branch-name"};
543 (propagateMC ? 1 : 0),
544 "trackmc-branch-name"};
548 std::move(tracksdef), std::move(clrefdef),
549 std::move(mcdef))());
561 const char* processName =
"tpc-compcluster-writer";
562 const char* defaultFileName =
"tpc-compclusters.root";
563 const char* defaultTreeName =
"tpcrec";
568 "TPCCompClusters_0",
"compcluster-branch-name"};
571 std::move(ccldef))());
574 return std::move(specs);
framework::WorkflowSpec getWorkflow(CompletionPolicyData *policyData, std::vector< int > const &tpcSectors, unsigned long tpcSectorMask, std::vector< int > const &laneConfiguration, const o2::tpc::CorrectionMapsLoaderGloOpts &sclOpts, bool propagateMC=true, unsigned nLanes=1, std::string const &cfgInput="digitizer", std::string const &cfgOutput="tracks", bool disableRootInput=false, int caClusterer=0, int zsOnTheFly=0, bool askDISTSTF=true, bool selIR=false, bool filteredInp=false, int deadMapSources=-1, bool useMCTimeGain=false)
create the workflow for TPC reconstruction