103 int caClusterer,
int zsOnTheFly,
bool askDISTSTF,
bool selIR,
bool filteredInp,
int deadMapSources,
bool useMCTimeGain)
108 }
catch (std::out_of_range&) {
109 throw std::invalid_argument(std::string(
"invalid input type: ") + cfgInput);
111 std::vector<OutputType> outputTypes;
113 outputTypes = RangeTokenizer::tokenize<OutputType>(cfgOutput, [](std::string
const& token) {
return OutputMap.at(token); });
114 }
catch (std::out_of_range&) {
115 throw std::invalid_argument(std::string(
"invalid output type: ") + cfgOutput);
118 return std::find(outputTypes.begin(), outputTypes.end(),
type) != outputTypes.end();
122 throw std::invalid_argument(
"filtered-input option must be provided only with pass-through input and clusters,tracks,send-clusters-per-sector output");
145 throw std::invalid_argument(
"input/output type mismatch, can not produce 'digits' from 'clustershardware'");
148 throw std::invalid_argument(
"input/output type mismatch, can not produce 'digits', nor 'clustershardware' from 'clusters'");
151 throw std::invalid_argument(
"input/output type mismatch, can not produce 'clustershardware' from 'zsraw'");
154 throw std::invalid_argument(
"ca-clusterer requires digits as input");
157 throw std::invalid_argument(
"ca-clusterer cannot produce clustershardware output");
168 if (TString(
name.data()).Contains(
"TPCDigitMCTruth") || TString(
name.data()).Contains(
"TPCClusterHwMCTruth") || TString(
name.data()).Contains(
"TPCClusterNativeMCTruth")) {
171 storedlabels->copyandflatten(flatlabels);
173 context.outputs().snapshot(
output, flatlabels);
184 using Type = std::vector<o2::tpc::Digit>;
186 specs.emplace_back(o2::tpc::getPublisherSpec<Type>(
PublisherConf{
190 {
"digitbranch",
"TPCDigit",
"Digit branch"},
191 {
"mcbranch",
"TPCDigitMCTruth",
"MC label branch"},
206 "tpc-clusterhardware-reader",
207 "tpc-clusterhardware.root",
208 "tpcclustershardware",
209 {
"databranch",
"TPCClusterHw",
"Branch with TPC ClustersHardware"},
210 {
"mcbranch",
"TPCClusterHwMCTruth",
"MC label branch"},
219 if (!getenv(
"DPL_DISABLE_TPC_TRIGGER_READER") || atoi(getenv(
"DPL_DISABLE_TPC_TRIGGER_READER")) != 1) {
234 "tpc-compressed-cluster-reader",
235 "tpc-compclusters.root",
237 {
"clusterbranch",
"TPCCompClusters",
"Branch with TPC compressed clusters"},
241 std::vector<int>(1, 0),
242 std::vector<int>(1, 0),
261 runGPUReco &= caClusterer || runHWDecoder || inputType ==
InputType::Clusters || decompressTPC;
268 runGPUReco = runHWDecoder = runClusterer = runClusterEncoder = zsToDigit =
false;
298 parallelProcessors, nLanes,
299 [&laneConfiguration]() {
return laneConfiguration.size(); },
300 [&laneConfiguration](
size_t index) {
return laneConfiguration[
index]; });
301 specs.insert(specs.end(), parallelProcessors.begin(), parallelProcessors.end());
315 auto const* tpcSectorHeader = o2::framework::DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(
ref);
316 if (!tpcSectorHeader) {
317 throw std::runtime_error(
"TPC sector header missing in header stack");
319 if (tpcSectorHeader->sector() < 0) {
324 for (
auto const& sector : tpcSectors) {
325 if (sector == tpcSectorHeader->sector()) {
330 throw std::runtime_error(
"sector " +
std::to_string(tpcSectorHeader->sector()) +
" not configured for writing");
332 auto getName = [tpcSectors](std::string base,
size_t index) {
338 auto fillLabels = [](TBranch& branch, std::vector<char>
const& labelbuffer,
DataRef const& ) {
341 auto ptr = &outputcontainer;
343 outputcontainer.
adopt(labelbuffer);
348 auto makeWriterSpec = [tpcSectors, laneConfiguration, propagateMC, getIndex,
getName](
const char* processName,
349 const char* defaultFileName,
350 const char* defaultTreeName,
353 bool singleBranch =
false) {
354 if (tpcSectors.size() == 0) {
355 throw std::invalid_argument(std::string(
"writer process configuration needs list of TPC sectors"));
358 auto amendInput = [tpcSectors, laneConfiguration](
InputSpec& input,
size_t index) {
362 auto amendBranchDef = [laneConfiguration, amendInput, tpcSectors, getIndex,
getName, singleBranch](
auto&& def,
bool enableMC =
true) {
364 def.keys =
mergeInputs(def.keys, laneConfiguration.size(), amendInput);
366 def.nofBranches = enableMC ? tpcSectors.size() : 0;
367 def.getIndex = getIndex;
371 def.nofBranches = enableMC ? 1 : 0;
373 return std::move(def);
377 std::move(amendBranchDef(databranch)),
378 std::move(amendBranchDef(mcbranch, propagateMC)))());
387 using DigitOutputType = std::vector<o2::tpc::Digit>;
388 specs.push_back(makeWriterSpec(
"tpc-digits-writer",
394 "digit-branch-name"},
397 "digitmc-branch-name"}));
406 specs.push_back(makeWriterSpec(
"tpc-clusterhardware-writer",
408 "tpcclustershardware",
413 "TPCClusterHwMCTruth",
425 specs.push_back(makeWriterSpec(filteredInp ?
"tpc-native-cluster-writer_filtered" :
"tpc-native-cluster-writer",
426 (inputType ==
InputType::Clusters || filteredInp) ?
"tpc-filtered-native-clusters.root" :
"tpc-native-clusters.root",
432 "TPCClusterNativeMCTruth",
433 "mcbranch", fillLabels},
482 auto task = std::make_shared<o2::gpu::GPURecoWorkflowSpec>(policyData, cfg, tpcSectors, tpcSectorMask, ggRequest);
484 Inputs taskInputs = task->inputs();
485 Options taskOptions = task->options();
486 std::move(ggInputs.begin(), ggInputs.end(), std::back_inserter(taskInputs));
492 AlgorithmSpec{adoptTask<o2::gpu::GPURecoWorkflowSpec>(task)},
501 if (runClusterEncoder) {
514 const char* processName = filteredInp ?
"tpc-track-writer_filtered" :
"tpc-track-writer";
515 const char* defaultFileName = filteredInp ?
"tpctracks_filtered.root" :
"tpctracks.root";
516 const char* defaultTreeName =
"tpcrec";
519 using TrackOutputType = std::vector<o2::tpc::TrackTPC>;
521 using ClusRefsOutputType = std::vector<o2::tpc::TPCClRefElem>;
525 LOG(info) <<
"writing " << tracks.size() <<
" track(s)";
528 "TPCTracks",
"track-branch-name",
532 "ClusRefs",
"trackclusref-branch-name"};
535 (propagateMC ? 1 : 0),
536 "trackmc-branch-name"};
540 std::move(tracksdef), std::move(clrefdef),
541 std::move(mcdef))());
553 const char* processName =
"tpc-compcluster-writer";
554 const char* defaultFileName =
"tpc-compclusters.root";
555 const char* defaultTreeName =
"tpcrec";
560 "TPCCompClusters_0",
"compcluster-branch-name"};
563 std::move(ccldef))());
566 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