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");
166 if (TString(
name.data()).Contains(
"TPCDigitMCTruth") || TString(
name.data()).Contains(
"TPCClusterHwMCTruth") || TString(
name.data()).Contains(
"TPCClusterNativeMCTruth")) {
169 storedlabels->copyandflatten(flatlabels);
171 context.outputs().snapshot(
output, flatlabels);
182 using Type = std::vector<o2::tpc::Digit>;
184 specs.emplace_back(o2::tpc::getPublisherSpec<Type>(
PublisherConf{
188 {
"digitbranch",
"TPCDigit",
"Digit branch"},
189 {
"mcbranch",
"TPCDigitMCTruth",
"MC label branch"},
204 "tpc-clusterhardware-reader",
205 "tpc-clusterhardware.root",
206 "tpcclustershardware",
207 {
"databranch",
"TPCClusterHw",
"Branch with TPC ClustersHardware"},
208 {
"mcbranch",
"TPCClusterHwMCTruth",
"MC label branch"},
217 if (!getenv(
"DPL_DISABLE_TPC_TRIGGER_READER") || atoi(getenv(
"DPL_DISABLE_TPC_TRIGGER_READER")) != 1) {
232 "tpc-compressed-cluster-reader",
233 "tpc-compclusters.root",
235 {
"clusterbranch",
"TPCCompClusters",
"Branch with TPC compressed clusters"},
239 std::vector<int>(1, 0),
240 std::vector<int>(1, 0),
260 runGPUReco &= caClusterer || runHWDecoder || inputType ==
InputType::Clusters || decompressTPC;
267 runGPUReco = runHWDecoder = runClusterer = runClusterEncoder = zsToDigit =
false;
297 parallelProcessors, nLanes,
298 [&laneConfiguration]() {
return laneConfiguration.size(); },
299 [&laneConfiguration](
size_t index) {
return laneConfiguration[
index]; });
300 specs.insert(specs.end(), parallelProcessors.begin(), parallelProcessors.end());
314 auto const* tpcSectorHeader = o2::framework::DataRefUtils::getHeader<o2::tpc::TPCSectorHeader*>(
ref);
315 if (!tpcSectorHeader) {
316 throw std::runtime_error(
"TPC sector header missing in header stack");
318 if (tpcSectorHeader->sector() < 0) {
323 for (
auto const& sector : tpcSectors) {
324 if (sector == tpcSectorHeader->sector()) {
329 throw std::runtime_error(
"sector " +
std::to_string(tpcSectorHeader->sector()) +
" not configured for writing");
331 auto getName = [tpcSectors](std::string base,
size_t index) {
337 auto fillLabels = [](TBranch& branch, std::vector<char>
const& labelbuffer,
DataRef const& ) {
340 auto ptr = &outputcontainer;
342 outputcontainer.
adopt(labelbuffer);
347 auto makeWriterSpec = [tpcSectors, laneConfiguration, propagateMC, getIndex,
getName](
const char* processName,
348 const char* defaultFileName,
349 const char* defaultTreeName,
352 bool singleBranch =
false) {
353 if (tpcSectors.size() == 0) {
354 throw std::invalid_argument(std::string(
"writer process configuration needs list of TPC sectors"));
357 auto amendInput = [tpcSectors, laneConfiguration](
InputSpec& input,
size_t index) {
361 auto amendBranchDef = [laneConfiguration, amendInput, tpcSectors, getIndex,
getName, singleBranch](
auto&& def,
bool enableMC =
true) {
363 def.keys =
mergeInputs(def.keys, laneConfiguration.size(), amendInput);
365 def.nofBranches = enableMC ? tpcSectors.size() : 0;
366 def.getIndex = getIndex;
370 def.nofBranches = enableMC ? 1 : 0;
372 return std::move(def);
376 std::move(amendBranchDef(databranch)),
377 std::move(amendBranchDef(mcbranch, propagateMC)))());
386 using DigitOutputType = std::vector<o2::tpc::Digit>;
387 specs.push_back(makeWriterSpec(
"tpc-digits-writer",
393 "digit-branch-name"},
396 "digitmc-branch-name"}));
405 specs.push_back(makeWriterSpec(
"tpc-clusterhardware-writer",
407 "tpcclustershardware",
412 "TPCClusterHwMCTruth",
424 specs.push_back(makeWriterSpec(filteredInp ?
"tpc-native-cluster-writer_filtered" :
"tpc-native-cluster-writer",
425 (inputType ==
InputType::Clusters || filteredInp) ?
"tpc-filtered-native-clusters.root" :
"tpc-native-clusters.root",
431 "TPCClusterNativeMCTruth",
432 "mcbranch", fillLabels},
481 auto task = std::make_shared<o2::gpu::GPURecoWorkflowSpec>(policyData, cfg, tpcSectors, tpcSectorMask, ggRequest);
483 Inputs taskInputs = task->inputs();
484 Options taskOptions = task->options();
485 std::move(ggInputs.begin(), ggInputs.end(), std::back_inserter(taskInputs));
491 AlgorithmSpec{adoptTask<o2::gpu::GPURecoWorkflowSpec>(task)},
500 if (runClusterEncoder) {
513 const char* processName = filteredInp ?
"tpc-track-writer_filtered" :
"tpc-track-writer";
514 const char* defaultFileName = filteredInp ?
"tpctracks_filtered.root" :
"tpctracks.root";
515 const char* defaultTreeName =
"tpcrec";
518 using TrackOutputType = std::vector<o2::tpc::TrackTPC>;
520 using ClusRefsOutputType = std::vector<o2::tpc::TPCClRefElem>;
524 LOG(info) <<
"writing " << tracks.size() <<
" track(s)";
527 "TPCTracks",
"track-branch-name",
531 "ClusRefs",
"trackclusref-branch-name"};
534 (propagateMC ? 1 : 0),
535 "trackmc-branch-name"};
539 std::move(tracksdef), std::move(clrefdef),
540 std::move(mcdef))());
552 const char* processName =
"tpc-compcluster-writer";
553 const char* defaultFileName =
"tpc-compclusters.root";
554 const char* defaultTreeName =
"tpcrec";
559 "TPCCompClusters_0",
"compcluster-branch-name"};
562 std::move(ccldef))());
565 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