Skip to content

Commit 9c22ede

Browse files
committed
ITSMFT: staggered clusterization
Signed-off-by: Felix Schlepper <[email protected]>
1 parent f4c1c90 commit 9c22ede

File tree

4 files changed

+269
-144
lines changed

4 files changed

+269
-144
lines changed

Detectors/ITSMFT/ITS/workflow/src/ClusterWriterSpec.cxx

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#include <vector>
1515

16+
#include "Framework/ConcreteDataMatcher.h"
17+
#include "ITSMFTBase/DPLAlpideParam.h"
1618
#include "ITSWorkflow/ClusterWriterSpec.h"
1719
#include "DPLUtils/MakeRootTreeWriterSpec.h"
1820
#include "DataFormatsITSMFT/CompCluster.h"
@@ -47,25 +49,48 @@ DataProcessorSpec getClusterWriterSpec(bool useMC)
4749
auto logger = [compClustersSize](std::vector<o2::itsmft::ROFRecord> const& rofs) {
4850
LOG(info) << "ITSClusterWriter pulled " << *compClustersSize << " clusters, in " << rofs.size() << " RO frames";
4951
};
52+
auto getIndex = [](DataRef const& ref) -> size_t {
53+
auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
54+
return static_cast<size_t>(dh->subSpecification);
55+
};
56+
const auto& par = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance();
57+
const int nLayers = par.roFrameLayerRef > 0 ? par.getNLayers() : 1;
58+
auto getName = [nLayers](std::string base, size_t index) -> std::string {
59+
if (nLayers > 1) {
60+
base += "_" + std::to_string(index);
61+
}
62+
return base;
63+
};
5064
return MakeRootTreeWriterSpec("its-cluster-writer",
5165
"o2clus_its.root",
52-
MakeRootTreeWriterSpec::TreeAttributes{"o2sim", "Tree with ITS clusters"},
53-
BranchDefinition<CompClusType>{InputSpec{"compclus", "ITS", "COMPCLUSTERS", 0},
54-
"ITSClusterComp",
55-
compClustersSizeGetter},
56-
BranchDefinition<PatternsType>{InputSpec{"patterns", "ITS", "PATTERNS", 0},
57-
"ITSClusterPatt"},
58-
BranchDefinition<ROFrameRType>{InputSpec{"ROframes", "ITS", "CLUSTERSROF", 0},
59-
"ITSClustersROF",
60-
logger},
61-
BranchDefinition<LabelsType>{InputSpec{"labels", "ITS", "CLUSTERSMCTR", 0},
62-
"ITSClusterMCTruth",
63-
(useMC ? 1 : 0), // one branch if mc labels enabled
64-
""},
65-
BranchDefinition<ROFRecLblT>{InputSpec{"MC2ROframes", "ITS", "CLUSTERSMC2ROF", 0},
66-
"ITSClustersMC2ROF",
67-
(useMC ? 1 : 0), // one branch if mc labels enabled
68-
""})();
66+
MakeRootTreeWriterSpec::TreeAttributes{.name = "o2sim", .title = "Tree with ITS clusters"},
67+
BranchDefinition<CompClusType>{InputSpec{"compclus", ConcreteDataTypeMatcher{"ITS", "COMPCLUSTERS"}},
68+
"ITSClusterComp", "compact-cluster-branch",
69+
nLayers,
70+
compClustersSizeGetter,
71+
getIndex,
72+
getName},
73+
BranchDefinition<PatternsType>{InputSpec{"patterns", ConcreteDataTypeMatcher{"ITS", "PATTERNS"}},
74+
"ITSClusterPatt", "cluster-pattern-branch",
75+
nLayers,
76+
getIndex,
77+
getName},
78+
BranchDefinition<ROFrameRType>{InputSpec{"ROframes", ConcreteDataTypeMatcher{"ITS", "CLUSTERSROF"}},
79+
"ITSClustersROF", "cluster-rof-branch",
80+
nLayers,
81+
logger,
82+
getIndex,
83+
getName},
84+
BranchDefinition<LabelsType>{InputSpec{"labels", ConcreteDataTypeMatcher{"ITS", "CLUSTERSMCTR"}},
85+
"ITSClusterMCTruth", "cluster-label-branch",
86+
(useMC ? nLayers : 0),
87+
getIndex,
88+
getName},
89+
BranchDefinition<ROFRecLblT>{InputSpec{"MC2ROframes", ConcreteDataTypeMatcher{"ITS", "CLUSTERSMC2ROF"}},
90+
"ITSClustersMC2ROF", "cluster-mc2rof-branch",
91+
(useMC ? nLayers : 0),
92+
getIndex,
93+
getName})();
6994
}
7095

7196
} // namespace its

Detectors/ITSMFT/ITS/workflow/src/ClustererSpec.cxx

Lines changed: 98 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@
1313

1414
#include <vector>
1515

16+
#include "Framework/ConcreteDataMatcher.h"
1617
#include "Framework/ControlService.h"
1718
#include "Framework/ConfigParamRegistry.h"
1819
#include "Framework/CCDBParamSpec.h"
20+
#include "Framework/DataRefUtils.h"
21+
#include "Framework/InputRecordWalker.h"
22+
#include "Framework/ConcreteDataMatcher.h"
1923
#include "ITSWorkflow/ClustererSpec.h"
2024
#include "DataFormatsITSMFT/Digit.h"
25+
#include "Framework/Lifetime.h"
2126
#include "ITSMFTReconstruction/ChipMappingITS.h"
2227
#include "ITSMFTReconstruction/ClustererParam.h"
2328
#include "DataFormatsITSMFT/TopologyDictionary.h"
@@ -53,58 +58,86 @@ void ClustererDPL::init(InitContext& ic)
5358
void ClustererDPL::run(ProcessingContext& pc)
5459
{
5560
updateTimeDependentParams(pc);
56-
auto digits = pc.inputs().get<gsl::span<o2::itsmft::Digit>>("digits");
57-
auto rofs = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
58-
59-
gsl::span<const o2::itsmft::MC2ROFRecord> mc2rofs;
60-
gsl::span<const char> labelbuffer;
61-
if (mUseMC) {
62-
labelbuffer = pc.inputs().get<gsl::span<char>>("labels");
63-
mc2rofs = pc.inputs().get<gsl::span<o2::itsmft::MC2ROFRecord>>("MC2ROframes");
64-
}
65-
o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel> labels(labelbuffer);
66-
67-
LOG(info) << "ITSClusterer pulled " << digits.size() << " digits, in "
68-
<< rofs.size() << " RO frames";
69-
LOG(info) << "ITSClusterer pulled " << labels.getNElements() << " labels ";
70-
71-
o2::itsmft::DigitPixelReader reader;
72-
reader.setSquashingDepth(mClusterer->getMaxROFDepthToSquash());
73-
reader.setSquashingDist(mClusterer->getMaxRowColDiffToMask()); // Sharing same parameter/logic with masking
74-
reader.setMaxBCSeparationToSquash(mClusterer->getMaxBCSeparationToSquash());
75-
reader.setDigits(digits);
76-
reader.setROFRecords(rofs);
77-
if (mUseMC) {
78-
reader.setMC2ROFRecords(mc2rofs);
79-
reader.setDigitsMCTruth(labels.getIndexedSize() > 0 ? &labels : nullptr);
80-
}
81-
reader.init();
82-
auto orig = o2::header::gDataOriginITS;
83-
std::vector<o2::itsmft::CompClusterExt> clusCompVec;
84-
std::vector<o2::itsmft::ROFRecord> clusROFVec;
85-
std::vector<unsigned char> clusPattVec;
86-
87-
std::unique_ptr<o2::dataformats::MCTruthContainer<o2::MCCompLabel>> clusterLabels;
88-
if (mUseMC) {
89-
clusterLabels = std::make_unique<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>();
61+
62+
const auto& par = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance();
63+
const int nLayers = par.roFrameLayerRef >= 0 ? par.getNLayers() : 1;
64+
std::vector<gsl::span<const o2::itsmft::Digit>> digits(nLayers);
65+
std::vector<gsl::span<const o2::itsmft::ROFRecord>> rofs(nLayers);
66+
std::vector<gsl::span<const char>> labelsbuffer(nLayers);
67+
std::vector<gsl::span<const o2::itsmft::MC2ROFRecord>> mc2rofs(nLayers);
68+
69+
// built input
70+
std::vector<InputSpec> filter;
71+
for (int iLayer = 0; iLayer < nLayers; ++iLayer) {
72+
filter.emplace_back("digits", "ITS", "DIGITS", iLayer, Lifetime::Timeframe);
73+
filter.emplace_back("ROframe", "ITS", "DIGITSROF", iLayer, Lifetime::Timeframe);
74+
if (mUseMC) {
75+
filter.emplace_back("labels", "ITS", "DIGITSMCTR", iLayer, Lifetime::Timeframe);
76+
filter.emplace_back("MC2ROframes", "ITS", "DIGITSMC2ROF", iLayer, Lifetime::Timeframe);
77+
}
9078
}
91-
mClusterer->process(mNThreads, reader, &clusCompVec, &clusPattVec, &clusROFVec, clusterLabels.get());
92-
pc.outputs().snapshot(Output{orig, "COMPCLUSTERS", 0}, clusCompVec);
93-
pc.outputs().snapshot(Output{orig, "CLUSTERSROF", 0}, clusROFVec);
94-
pc.outputs().snapshot(Output{orig, "PATTERNS", 0}, clusPattVec);
95-
96-
if (mUseMC) {
97-
pc.outputs().snapshot(Output{orig, "CLUSTERSMCTR", 0}, *clusterLabels.get()); // at the moment requires snapshot
98-
std::vector<o2::itsmft::MC2ROFRecord> clusterMC2ROframes(mc2rofs.size());
99-
for (int i = mc2rofs.size(); i--;) {
100-
clusterMC2ROframes[i] = mc2rofs[i]; // Simply, replicate it from digits ?
79+
for (const DataRef& ref : InputRecordWalker{pc.inputs(), filter}) {
80+
auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
81+
if (DataRefUtils::match(ref, {"digits", ConcreteDataTypeMatcher{"ITS", "DIGITS"}})) {
82+
digits[dh->subSpecification] = pc.inputs().get<gsl::span<o2::itsmft::Digit>>(ref);
83+
}
84+
if (DataRefUtils::match(ref, {"ROframe", ConcreteDataTypeMatcher{"ITS", "DIGITSROF"}})) {
85+
rofs[dh->subSpecification] = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>(ref);
86+
}
87+
if (DataRefUtils::match(ref, {"labels", ConcreteDataTypeMatcher{"ITS", "DIGITSMCTR"}})) {
88+
labelsbuffer[dh->subSpecification] = pc.inputs().get<gsl::span<char>>(ref);
89+
}
90+
if (DataRefUtils::match(ref, {"MC2ROframes", ConcreteDataTypeMatcher{"ITS", "DIGITSMC2ROF"}})) {
91+
mc2rofs[dh->subSpecification] = pc.inputs().get<gsl::span<o2::itsmft::MC2ROFRecord>>(ref);
10192
}
102-
pc.outputs().snapshot(Output{orig, "CLUSTERSMC2ROF", 0}, clusterMC2ROframes);
10393
}
10494

105-
// TODO: in principle, after masking "overflow" pixels the MC2ROFRecord maxROF supposed to change, nominally to minROF
106-
// -> consider recalculationg maxROF
107-
LOG(info) << "ITSClusterer pushed " << clusCompVec.size() << " clusters, in " << clusROFVec.size() << " RO frames";
95+
// process received inputs
96+
for (int iLayer = 0; iLayer < nLayers; ++iLayer) {
97+
98+
LOG(info) << "ITSClusterer pulled " << digits[iLayer].size() << " digits, in "
99+
<< rofs[iLayer].size() << " RO frames " << iLayer << "/" << nLayers;
100+
101+
o2::dataformats::ConstMCTruthContainerView<o2::MCCompLabel> labels(labelsbuffer[iLayer]);
102+
o2::itsmft::DigitPixelReader reader;
103+
reader.setSquashingDepth(mClusterer->getMaxROFDepthToSquash());
104+
reader.setSquashingDist(mClusterer->getMaxRowColDiffToMask()); // Sharing same parameter/logic with masking
105+
reader.setMaxBCSeparationToSquash(mClusterer->getMaxBCSeparationToSquash());
106+
reader.setDigits(digits[iLayer]);
107+
reader.setROFRecords(rofs[iLayer]);
108+
if (mUseMC) {
109+
reader.setMC2ROFRecords(mc2rofs[iLayer]);
110+
LOG(info) << "ITSClusterer pulled " << labels.getNElements() << " labels ";
111+
reader.setDigitsMCTruth(labels.getIndexedSize() > 0 ? &labels : nullptr);
112+
}
113+
reader.init();
114+
auto orig = o2::header::gDataOriginITS;
115+
std::vector<o2::itsmft::CompClusterExt> clusCompVec;
116+
std::vector<o2::itsmft::ROFRecord> clusROFVec;
117+
std::vector<unsigned char> clusPattVec;
118+
119+
std::unique_ptr<o2::dataformats::MCTruthContainer<o2::MCCompLabel>> clusterLabels;
120+
if (mUseMC) {
121+
clusterLabels = std::make_unique<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>();
122+
}
123+
mClusterer->process(mNThreads, reader, &clusCompVec, &clusPattVec, &clusROFVec, clusterLabels.get());
124+
pc.outputs().snapshot(Output{orig, "COMPCLUSTERS", uint32_t(iLayer)}, clusCompVec);
125+
pc.outputs().snapshot(Output{orig, "CLUSTERSROF", uint32_t(iLayer)}, clusROFVec);
126+
pc.outputs().snapshot(Output{orig, "PATTERNS", uint32_t(iLayer)}, clusPattVec);
127+
128+
if (mUseMC) {
129+
pc.outputs().snapshot(Output{orig, "CLUSTERSMCTR", uint32_t(iLayer)}, *clusterLabels.get()); // at the moment requires snapshot
130+
std::vector<o2::itsmft::MC2ROFRecord> clusterMC2ROframes(mc2rofs[iLayer].size());
131+
for (int i = mc2rofs[iLayer].size(); i--;) {
132+
clusterMC2ROframes[i] = mc2rofs[iLayer][i]; // Simply, replicate it from digits ?
133+
}
134+
pc.outputs().snapshot(Output{orig, "CLUSTERSMC2ROF", uint32_t(iLayer)}, clusterMC2ROframes);
135+
}
136+
137+
// TODO: in principle, after masking "overflow" pixels the MC2ROFRecord maxROF supposed to change, nominally to minROF
138+
// -> consider recalculationg maxROF
139+
LOG(info) << "ITSClusterer pushed " << clusCompVec.size() << " clusters, in " << clusROFVec.size() << " RO frames";
140+
}
108141
}
109142

110143
///_______________________________________
@@ -173,8 +206,12 @@ void ClustererDPL::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
173206
DataProcessorSpec getClustererSpec(bool useMC)
174207
{
175208
std::vector<InputSpec> inputs;
176-
inputs.emplace_back("digits", "ITS", "DIGITS", 0, Lifetime::Timeframe);
177-
inputs.emplace_back("ROframes", "ITS", "DIGITSROF", 0, Lifetime::Timeframe);
209+
const auto& par = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance();
210+
uint32_t nLayers = par.roFrameLayerRef >= 0 ? par.getNLayers() : 1;
211+
for (uint32_t iLayer = 0; iLayer < nLayers; ++iLayer) {
212+
inputs.emplace_back("digits", "ITS", "DIGITS", iLayer, Lifetime::Timeframe);
213+
inputs.emplace_back("ROframes", "ITS", "DIGITSROF", iLayer, Lifetime::Timeframe);
214+
}
178215
inputs.emplace_back("cldict", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary"));
179216
inputs.emplace_back("cluspar", "ITS", "CLUSPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/ClustererParam"));
180217
inputs.emplace_back("alppar", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam"));
@@ -187,15 +224,17 @@ DataProcessorSpec getClustererSpec(bool useMC)
187224
inputs,
188225
true);
189226
std::vector<OutputSpec> outputs;
190-
outputs.emplace_back("ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe);
191-
outputs.emplace_back("ITS", "PATTERNS", 0, Lifetime::Timeframe);
192-
outputs.emplace_back("ITS", "CLUSTERSROF", 0, Lifetime::Timeframe);
193-
194-
if (useMC) {
195-
inputs.emplace_back("labels", "ITS", "DIGITSMCTR", 0, Lifetime::Timeframe);
196-
inputs.emplace_back("MC2ROframes", "ITS", "DIGITSMC2ROF", 0, Lifetime::Timeframe);
197-
outputs.emplace_back("ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe);
198-
outputs.emplace_back("ITS", "CLUSTERSMC2ROF", 0, Lifetime::Timeframe);
227+
for (uint32_t iLayer = 0; iLayer < nLayers; ++iLayer) {
228+
outputs.emplace_back("ITS", "COMPCLUSTERS", iLayer, Lifetime::Timeframe);
229+
outputs.emplace_back("ITS", "PATTERNS", iLayer, Lifetime::Timeframe);
230+
outputs.emplace_back("ITS", "CLUSTERSROF", iLayer, Lifetime::Timeframe);
231+
232+
if (useMC) {
233+
inputs.emplace_back("labels", "ITS", "DIGITSMCTR", iLayer, Lifetime::Timeframe);
234+
inputs.emplace_back("MC2ROframes", "ITS", "DIGITSMC2ROF", iLayer, Lifetime::Timeframe);
235+
outputs.emplace_back("ITS", "CLUSTERSMCTR", iLayer, Lifetime::Timeframe);
236+
outputs.emplace_back("ITS", "CLUSTERSMC2ROF", iLayer, Lifetime::Timeframe);
237+
}
199238
}
200239

201240
return DataProcessorSpec{

0 commit comments

Comments
 (0)