96 std::array<gsl::span<const itsmft::CompClusterExt>, NLayers> compClusters;
97 std::array<gsl::span<const unsigned char>, NLayers> patterns;
98 std::array<gsl::span<const itsmft::ROFRecord>, NLayers> rofsinput;
99 std::array<const dataformats::MCTruthContainer<MCCompLabel>*, NLayers>
labels{};
101 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
103 compClusters[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::CompClusterExt>>(
ref);
106 patterns[dh->subSpecification] = pc.
inputs().
get<gsl::span<unsigned char>>(
ref);
109 rofsinput[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::ROFRecord>>(
ref);
116 bool hasClusters =
false;
117 for (
int iLayer = 0; iLayer < ((mDoStaggering) ? NLayers : 1); ++iLayer) {
118 LOGP(info,
"ITSTracker{} pulled {} clusters, {} RO frames", ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
""), compClusters[iLayer].
size(), rofsinput[iLayer].size());
119 if (compClusters[iLayer].
empty()) {
120 LOGP(warn,
" -> received no processable data{}", (mDoStaggering) ? std::format(
" on layer {}", iLayer) :
"");
125 LOG(info) <<
" -> " <<
labels[iLayer]->getIndexedSize() <<
" MC label objects";
130 gsl::span<const o2::itsmft::PhysTrigger> physTriggers;
131 std::vector<o2::itsmft::PhysTrigger> fromTRD;
132 if (mUseTriggers == 2) {
134 auto trdTriggers = pc.
inputs().
get<gsl::span<o2::trd::TriggerRecord>>(
"phystrig");
135 for (
const auto& trig : trdTriggers) {
136 if (trig.getBCData() >= irFirstTF && trig.getNumberOfTracklets()) {
137 irFirstTF = trig.getBCData();
141 physTriggers = gsl::span<const o2::itsmft::PhysTrigger>(fromTRD.data(), fromTRD.size());
142 }
else if (mUseTriggers == 1) {
143 physTriggers = pc.
inputs().
get<gsl::span<o2::itsmft::PhysTrigger>>(
"phystrig");
147 auto& irFrames = pc.
outputs().
make<std::vector<o2::dataformats::IRFrame>>(
Output{
"ITS",
"IRFRAMES", 0});
148 irFrames.reserve(rofsinput[clockLayerId].
size());
150 auto& allClusIdx = pc.
outputs().
make<std::vector<int>>(
Output{
"ITS",
"TRACKCLSID", 0});
151 auto& allTracks = pc.
outputs().
make<std::vector<o2::its::TrackITS>>(
Output{
"ITS",
"TRACKS", 0});
152 auto& allTrackROFs = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"ITSTrackROF", 0});
153 auto& vertices = pc.
outputs().
make<std::vector<Vertex>>(
Output{
"ITS",
"VERTICES", 0});
154 auto& vertROFvec = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"VERTICESROF", 0});
159 auto& allTrackLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"TRACKSMCTR", 0}) : dummyMCLabTracks;
160 auto& allVerticesLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"VERTICESMCTR", 0}) : dummyMCLabVerts;
161 auto& allVerticesPurities = mIsMC ? pc.
outputs().
make<std::vector<float>>(
Output{
"ITS",
"VERTICESMCPUR", 0}) : dummyMCPurVerts;
168 if (mOverrideBeamEstimation) {
171 mMeanVertex->getSigmaY2(),
172 mTracker->getParameters()[0].LayerResolution[0],
173 mTracker->getParameters()[0].SystErrorY2[0]);
177 mTracker->setTimeSlice(tfInfo.timeslice);
179 for (
int iLayer = 0; iLayer < ((mDoStaggering) ? NLayers : 1); ++iLayer) {
180 gsl::span<const unsigned char>::iterator pattIt = patterns[iLayer].begin();
181 loadROF(rofsinput[iLayer], compClusters[iLayer], pattIt, ((mDoStaggering) ? iLayer : -1),
labels[iLayer]);
184 auto logger = [&](
const std::string& s) {
LOG(info) << s; };
185 auto fatalLogger = [&](
const std::string& s) {
LOG(fatal) << s; };
186 auto errorLogger = [&](
const std::string& s) {
LOG(error) << s; };
192 for (
int iLayer = 0; iLayer < ((mDoStaggering) ? NLayers : 1); ++iLayer) {
196 float vertexerElapsedTime{0.f}, trackerElapsedTime{0.f};
199 vertexerElapsedTime = mVertexer->clustersToVertices(logger);
201 vertices.insert(vertices.begin(), vtx.begin(), vtx.end());
203 allVerticesLabels.reserve(vertices.size());
204 allVerticesPurities.reserve(vertices.size());
206 allVerticesLabels.push_back(lbl.first);
207 allVerticesPurities.push_back(lbl.second);
213 auto clockROFspan = rofsinput[clockLayerId];
215 for (
auto iRof{0}; iRof < clockROFspan.size(); ++iRof) {
216 auto& vtxROF = vertROFvec.emplace_back(clockROFspan[iRof]);
220 if (!vtxSpan.empty()) {
221 bool hasUPC = std::any_of(vtxSpan.begin(), vtxSpan.end(), [](
const auto&
v) { return v.isFlagSet(Vertex::UPCMode); });
223 LOGP(
debug,
"ROF {} rejected as vertices are from the UPC iteration", iRof);
224 processUPCMask.selectROF({clockTiming.getROFStartInBC(iRof), clockTiming.getROFEndInBC(iRof)});
225 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
227 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
230 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
233 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
238 if (mRunVertexer && hasClusters) {
242 if (mOverrideBeamEstimation) {
252 trackerElapsedTime = mTracker->clustersToTracks(logger, fatalLogger);
254 trackerElapsedTime = mTracker->clustersToTracks(logger, errorLogger);
261 logger(std::format(
"=== TimeSlice {} processing completed in: {:.2f} ms using {}/{} thread(s) ===", tfInfo.timeslice, trackerElapsedTime + vertexerElapsedTime, vertConf.nThreads, trackConf.nThreads));
266 allTracks.reserve(totTracks);
267 allClusIdx.reserve(totClusIDs);
270 LOG(warning) << fmt::format(
" + The processed timeframe had {} clusters with wild z coordinates, check the dictionaries",
mTimeFrame->
hasBogusClusters());
284 auto setBCData = [&](
auto& rofs) {
285 for (
size_t iROF{0}; iROF < rofs.size(); ++iROF) {
286 auto& rof = rofs[iROF];
291 rof.setROFrame(iROF);
293 rof.setFirstEntry(-1);
299 for (
const auto& trc : tracks) {
300 highestROF = std::max(highestROF, (
int)clockLayer.getROF(trc.getTimeStamp()));
302 for (
const auto& vtx : vertices) {
303 highestROF = std::max(highestROF, (
int)clockLayer.getROF(vtx.getTimeStamp().lower()));
305 highestROF = std::max(highestROF, (
int)clockLayer.mNROFsTF);
306 allTrackROFs.resize(highestROF);
307 vertROFvec.resize(highestROF);
308 setBCData(allTrackROFs);
309 setBCData(vertROFvec);
313 std::vector<int> rofEntries(highestROF + 1, 0);
314 for (
unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) {
315 auto& trc{tracks[iTrk]};
316 trc.setFirstClusterEntry((
int)allClusIdx.size());
317 int ncl = trc.getNumberOfClusters(), nclf = 0;
319 auto clid = trc.getClusterIndex(ic);
322 allClusIdx.push_back(clid);
327 allTracks.emplace_back(trc);
328 auto rof = clockLayer.getROF(trc.getTimeStamp());
331 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
332 for (
size_t iROF{0}; iROF < allTrackROFs.size(); ++iROF) {
333 allTrackROFs[iROF].setFirstEntry(rofEntries[iROF]);
334 allTrackROFs[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
336 auto& irFrame = irFrames.emplace_back(allTrackROFs[iROF].getBCData(), allTrackROFs[iROF].getBCData() + clockLayer.mROFLength - 1);
337 irFrame.info = allTrackROFs[iROF].getNEntries();
341 std::fill(rofEntries.begin(), rofEntries.end(), 0);
342 for (
const auto& vtx : vertices) {
343 auto rof = clockLayer.getROF(vtx.getTimeStamp().lower());
346 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
347 for (
size_t iROF{0}; iROF < vertROFvec.size(); ++iROF) {
348 vertROFvec[iROF].setFirstEntry(rofEntries[iROF]);
349 vertROFvec[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
354 LOGP(info,
"ITSTracker pushed {} tracks in {} rofs and {} vertices {}", allTracks.size(), allTrackROFs.size(), vertices.size(), ((mDoStaggering) ?
"in staggered-readout mode" :
""));
356 LOGP(info,
"ITSTracker pushed {} track labels", allTrackLabels.size());
357 LOGP(info,
"ITSTracker pushed {} vertex labels", allVerticesLabels.size());
358 LOGP(info,
"ITSTracker pushed {} vertex purities", allVerticesPurities.size());