103 std::array<gsl::span<const itsmft::CompClusterExt>,
NLayers> compClusters;
104 std::array<gsl::span<const unsigned char>,
NLayers> patterns;
105 std::array<gsl::span<const itsmft::ROFRecord>,
NLayers> rofsinput;
106 std::array<const dataformats::MCTruthContainer<MCCompLabel>*,
NLayers>
labels{};
108 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
110 compClusters[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::CompClusterExt>>(
ref);
113 patterns[dh->subSpecification] = pc.
inputs().
get<gsl::span<unsigned char>>(
ref);
116 rofsinput[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::ROFRecord>>(
ref);
123 bool hasClusters =
false;
124 for (
int iLayer = 0; iLayer < ((mDoStaggering) ?
NLayers : 1); ++iLayer) {
125 LOGP(info,
"ITSTracker{} pulled {} clusters, {} RO frames", ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
""), compClusters[iLayer].
size(), rofsinput[iLayer].size());
126 if (compClusters[iLayer].
empty()) {
127 LOGP(warn,
" -> received no processable data{}", (mDoStaggering) ? std::format(
" on layer {}", iLayer) :
"");
132 LOG(info) <<
" -> " <<
labels[iLayer]->getIndexedSize() <<
" MC label objects";
137 gsl::span<const o2::itsmft::PhysTrigger> physTriggers;
138 std::vector<o2::itsmft::PhysTrigger> fromTRD;
139 if (mUseTriggers == 2) {
141 auto trdTriggers = pc.
inputs().
get<gsl::span<o2::trd::TriggerRecord>>(
"phystrig");
142 for (
const auto& trig : trdTriggers) {
143 if (trig.getBCData() >= irFirstTF && trig.getNumberOfTracklets()) {
144 irFirstTF = trig.getBCData();
148 physTriggers = gsl::span<const o2::itsmft::PhysTrigger>(fromTRD.data(), fromTRD.size());
149 }
else if (mUseTriggers == 1) {
150 physTriggers = pc.
inputs().
get<gsl::span<o2::itsmft::PhysTrigger>>(
"phystrig");
154 auto& irFrames = pc.
outputs().
make<std::vector<o2::dataformats::IRFrame>>(
Output{
"ITS",
"IRFRAMES", 0});
155 irFrames.reserve(rofsinput[clockLayerId].
size());
157 auto& allClusIdx = pc.
outputs().
make<std::vector<int>>(
Output{
"ITS",
"TRACKCLSID", 0});
158 auto& allTracks = pc.
outputs().
make<std::vector<o2::its::TrackITS>>(
Output{
"ITS",
"TRACKS", 0});
159 auto& allTrackROFs = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"ITSTrackROF", 0});
160 auto& vertices = pc.
outputs().
make<std::vector<Vertex>>(
Output{
"ITS",
"VERTICES", 0});
161 auto& vertROFvec = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"VERTICESROF", 0});
166 auto& allTrackLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"TRACKSMCTR", 0}) : dummyMCLabTracks;
167 auto& allVerticesLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"VERTICESMCTR", 0}) : dummyMCLabVerts;
168 auto& allVerticesPurities = mIsMC ? pc.
outputs().
make<std::vector<float>>(
Output{
"ITS",
"VERTICESMCPUR", 0}) : dummyMCPurVerts;
172 auto setBCData = [&](
auto& rofs) {
173 for (
size_t iROF{0}; iROF < rofs.size(); ++iROF) {
174 auto& rof = rofs[iROF];
179 rof.setROFrame(iROF);
181 rof.setFirstEntry(-1);
187 allTrackROFs.resize(clockLayer.mNROFsTF);
188 vertROFvec.resize(clockLayer.mNROFsTF);
189 setBCData(allTrackROFs);
190 setBCData(vertROFvec);
194 if (mOverrideBeamEstimation) {
197 mMeanVertex->getSigmaY2(),
198 mTracker->getParameters()[0].LayerResolution[0],
199 mTracker->getParameters()[0].SystErrorY2[0]);
203 mTracker->setTimeSlice(tfInfo.timeslice);
205 for (
int iLayer = 0; iLayer < ((mDoStaggering) ?
NLayers : 1); ++iLayer) {
206 gsl::span<const unsigned char>::iterator pattIt = patterns[iLayer].begin();
207 loadROF(rofsinput[iLayer], compClusters[iLayer], pattIt, ((mDoStaggering) ? iLayer : -1),
labels[iLayer]);
210 auto logger = [&](
const std::string& s) {
LOG(info) << s; };
211 auto fatalLogger = [&](
const std::string& s) {
LOG(fatal) << s; };
212 auto errorLogger = [&](
const std::string& s) {
LOG(error) << s; };
218 for (
int iLayer = 0; iLayer < ((mDoStaggering) ?
NLayers : 1); ++iLayer) {
222 float vertexerElapsedTime{0.f}, trackerElapsedTime{0.f};
225 vertexerElapsedTime = mVertexer->clustersToVertices(logger);
227 vertices.insert(vertices.begin(), vtx.begin(), vtx.end());
229 allVerticesLabels.reserve(vertices.size());
230 allVerticesPurities.reserve(vertices.size());
232 allVerticesLabels.push_back(lbl.first);
233 allVerticesPurities.push_back(lbl.second);
239 auto clockROFspan = rofsinput[clockLayerId];
241 for (
auto iRof{0}; iRof < clockROFspan.size(); ++iRof) {
242 auto& vtxROF = vertROFvec.emplace_back(clockROFspan[iRof]);
246 if (!vtxSpan.empty()) {
247 bool hasUPC = std::any_of(vtxSpan.begin(), vtxSpan.end(), [](
const auto&
v) { return v.isFlagSet(Vertex::UPCMode); });
249 LOGP(
debug,
"ROF {} rejected as vertices are from the UPC iteration", iRof);
250 processUPCMask.selectROF({clockTiming.getROFStartInBC(iRof), clockTiming.getROFEndInBC(iRof)});
251 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
253 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
256 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
259 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
264 if (mRunVertexer && hasClusters) {
268 if (mOverrideBeamEstimation) {
278 trackerElapsedTime = mTracker->clustersToTracks(logger, fatalLogger);
280 trackerElapsedTime = mTracker->clustersToTracks(logger, errorLogger);
287 logger(std::format(
"=== TimeSlice {} processing completed in: {:.2f} ms using {}/{} thread(s) ===", tfInfo.timeslice, trackerElapsedTime + vertexerElapsedTime, vertConf.nThreads, trackConf.nThreads));
292 allTracks.reserve(totTracks);
293 allClusIdx.reserve(totClusIDs);
296 LOG(warning) << fmt::format(
" + The processed timeframe had {} clusters with wild z coordinates, check the dictionaries",
mTimeFrame->
hasBogusClusters());
311 for (
const auto& trc : tracks) {
312 highestROF = std::max(highestROF, (
int)clockLayer.getROF(trc.getTimeStamp()));
314 for (
const auto& vtx : vertices) {
315 highestROF = std::max(highestROF, (
int)clockLayer.getROF(vtx.getTimeStamp().lower()));
317 highestROF = std::max(highestROF, (
int)clockLayer.mNROFsTF);
318 allTrackROFs.resize(highestROF);
319 vertROFvec.resize(highestROF);
320 setBCData(allTrackROFs);
321 setBCData(vertROFvec);
325 std::vector<int> rofEntries(highestROF + 1, 0);
326 for (
unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) {
327 auto& trc{tracks[iTrk]};
328 trc.setFirstClusterEntry((
int)allClusIdx.size());
329 int ncl = trc.getNumberOfClusters(), nclf = 0;
331 auto clid = trc.getClusterIndex(ic);
334 allClusIdx.push_back(clid);
339 allTracks.emplace_back(trc);
340 auto rof = clockLayer.getROF(trc.getTimeStamp());
343 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
344 for (
size_t iROF{0}; iROF < allTrackROFs.size(); ++iROF) {
345 allTrackROFs[iROF].setFirstEntry(rofEntries[iROF]);
346 allTrackROFs[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
348 auto& irFrame = irFrames.emplace_back(allTrackROFs[iROF].getBCData(), allTrackROFs[iROF].getBCData() + clockLayer.mROFLength - 1);
349 irFrame.info = allTrackROFs[iROF].getNEntries();
353 std::fill(rofEntries.begin(), rofEntries.end(), 0);
354 for (
const auto& vtx : vertices) {
355 auto rof = clockLayer.getROF(vtx.getTimeStamp().lower());
358 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
359 for (
size_t iROF{0}; iROF < vertROFvec.size(); ++iROF) {
360 vertROFvec[iROF].setFirstEntry(rofEntries[iROF]);
361 vertROFvec[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
364 LOGP(info,
"ITSTracker pushed {} tracks in {} rofs and {} vertices {}", allTracks.size(), allTrackROFs.size(), vertices.size(), ((mDoStaggering) ?
"in staggered-readout mode" :
""));
366 LOGP(info,
"ITSTracker pushed {} track labels", allTrackLabels.size());
367 LOGP(info,
"ITSTracker pushed {} vertex labels", allVerticesLabels.size());
368 LOGP(info,
"ITSTracker pushed {} vertex purities", allVerticesPurities.size());