110 std::array<gsl::span<const itsmft::CompClusterExt>,
NLayers> compClusters;
111 std::array<gsl::span<const unsigned char>,
NLayers> patterns;
112 std::array<gsl::span<const itsmft::ROFRecord>,
NLayers> rofsinput;
113 std::array<const dataformats::MCTruthContainer<MCCompLabel>*,
NLayers>
labels{};
115 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
117 compClusters[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::CompClusterExt>>(
ref);
120 patterns[dh->subSpecification] = pc.
inputs().
get<gsl::span<unsigned char>>(
ref);
123 rofsinput[dh->subSpecification] = pc.
inputs().
get<gsl::span<o2::itsmft::ROFRecord>>(
ref);
130 bool hasClusters =
false;
131 for (
int iLayer = 0; iLayer < ((mDoStaggering) ?
NLayers : 1); ++iLayer) {
132 LOGP(info,
"ITSTracker{} pulled {} clusters, {} RO frames", ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
""), compClusters[iLayer].
size(), rofsinput[iLayer].size());
133 if (compClusters[iLayer].
empty()) {
134 LOGP(warn,
" -> received no processable data{}", (mDoStaggering) ? std::format(
" on layer {}", iLayer) :
"");
139 LOG(info) <<
" -> " <<
labels[iLayer]->getIndexedSize() <<
" MC label objects";
144 gsl::span<const o2::itsmft::PhysTrigger> physTriggers;
145 std::vector<o2::itsmft::PhysTrigger> fromTRD;
146 if (mUseTriggers == 2) {
148 auto trdTriggers = pc.
inputs().
get<gsl::span<o2::trd::TriggerRecord>>(
"phystrig");
149 for (
const auto& trig : trdTriggers) {
150 if (trig.getBCData() >= irFirstTF && trig.getNumberOfTracklets()) {
151 irFirstTF = trig.getBCData();
155 physTriggers = gsl::span<const o2::itsmft::PhysTrigger>(fromTRD.data(), fromTRD.size());
156 }
else if (mUseTriggers == 1) {
157 physTriggers = pc.
inputs().
get<gsl::span<o2::itsmft::PhysTrigger>>(
"phystrig");
161 auto& irFrames = pc.
outputs().
make<std::vector<o2::dataformats::IRFrame>>(
Output{
"ITS",
"IRFRAMES", 0});
162 irFrames.reserve(rofsinput[clockLayerId].
size());
164 auto& allClusIdx = pc.
outputs().
make<std::vector<int>>(
Output{
"ITS",
"TRACKCLSID", 0});
165 auto& allTracks = pc.
outputs().
make<std::vector<o2::its::TrackITS>>(
Output{
"ITS",
"TRACKS", 0});
166 auto& allTrackROFs = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"ITSTrackROF", 0});
167 auto& vertices = pc.
outputs().
make<std::vector<Vertex>>(
Output{
"ITS",
"VERTICES", 0});
168 auto& vertROFvec = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"ITS",
"VERTICESROF", 0});
173 auto& allTrackLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"TRACKSMCTR", 0}) : dummyMCLabTracks;
174 auto& allVerticesLabels = mIsMC ? pc.
outputs().
make<std::vector<o2::MCCompLabel>>(
Output{
"ITS",
"VERTICESMCTR", 0}) : dummyMCLabVerts;
175 auto& allVerticesPurities = mIsMC ? pc.
outputs().
make<std::vector<float>>(
Output{
"ITS",
"VERTICESMCPUR", 0}) : dummyMCPurVerts;
179 auto setBCData = [&](
auto& rofs) {
180 for (
size_t iROF{0}; iROF < rofs.size(); ++iROF) {
181 auto& rof = rofs[iROF];
182 int orb = (iROF *
par.getROFLengthInBC(clock) / o2::constants::lhc::LHCMaxBunches) + tfInfo.firstTForbit;
183 int bc = (iROF *
par.getROFLengthInBC(clock) % o2::constants::lhc::LHCMaxBunches) +
par.getROFDelayInBC(clock);
186 rof.setROFrame(iROF);
188 rof.setFirstEntry(-1);
194 allTrackROFs.resize(clockLayer.mNROFsTF);
195 vertROFvec.resize(clockLayer.mNROFsTF);
196 setBCData(allTrackROFs);
197 setBCData(vertROFvec);
201 if (mOverrideBeamEstimation) {
204 mMeanVertex->getSigmaY2(),
205 mTracker->getParameters()[0].LayerResolution[0],
206 mTracker->getParameters()[0].SystErrorY2[0]);
210 mTracker->setTimeSlice(tfInfo.timeslice);
212 for (
int iLayer = 0; iLayer < ((mDoStaggering) ?
NLayers : 1); ++iLayer) {
213 gsl::span<const unsigned char>::iterator pattIt = patterns[iLayer].begin();
214 loadROF(rofsinput[iLayer], compClusters[iLayer], pattIt, ((mDoStaggering) ? iLayer : -1),
labels[iLayer]);
217 auto logger = [&](
const std::string& s) {
LOG(info) << s; };
218 auto fatalLogger = [&](
const std::string& s) {
LOG(fatal) << s; };
219 auto errorLogger = [&](
const std::string& s) {
LOG(error) << s; };
225 for (
int iLayer = 0; iLayer < ((mDoStaggering) ?
NLayers : 1); ++iLayer) {
229 float vertexerElapsedTime{0.f}, trackerElapsedTime{0.f};
232 ? mTracker->clustersToVertices(logger)
233 : mVertexer->clustersToVertices(logger);
235 vertices.insert(vertices.begin(), vtx.begin(), vtx.end());
237 allVerticesLabels.reserve(vertices.size());
238 allVerticesPurities.reserve(vertices.size());
240 allVerticesLabels.push_back(lbl.first);
241 allVerticesPurities.push_back(lbl.second);
247 auto clockROFspan = rofsinput[clockLayerId];
249 for (
auto iRof{0}; iRof < clockROFspan.size(); ++iRof) {
250 auto& vtxROF = vertROFvec.emplace_back(clockROFspan[iRof]);
254 if (!vtxSpan.empty()) {
255 bool hasUPC = std::any_of(vtxSpan.begin(), vtxSpan.end(), [](
const auto&
v) { return v.isFlagSet(Vertex::UPCMode); });
257 LOGP(
debug,
"ROF {} accepted as vertices are from the UPC iteration", iRof);
258 const auto startBC = clockTiming.getROFStartInBC(iRof);
259 const auto endBC = clockTiming.getROFEndInBC(iRof);
260 processUPCMask.selectROF({startBC, endBC - startBC});
261 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
263 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
266 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxUPCMode);
269 vtxROF.setFlag(o2::itsmft::ROFRecord::VtxStdMode);
274 if (mRunVertexer && hasClusters) {
278 if (mOverrideBeamEstimation) {
288 trackerElapsedTime = mTracker->clustersToTracks(logger, fatalLogger);
290 trackerElapsedTime = mTracker->clustersToTracks(logger, errorLogger);
297 logger(std::format(
"=== TimeSlice {} processing completed in: {:.2f} ms using {}/{} thread(s) ===", tfInfo.timeslice, trackerElapsedTime + vertexerElapsedTime, vertConf.nThreads, trackConf.nThreads));
302 allTracks.reserve(totTracks);
303 allClusIdx.reserve(totClusIDs);
306 LOG(warning) << fmt::format(
" + The processed timeframe had {} clusters with wild z coordinates, check the dictionaries",
mTimeFrame->
hasBogusClusters());
321 for (
const auto& trc :
tracks) {
322 highestROF = std::max(highestROF, (
int)clockLayer.getROF(trc.getTimeStamp()));
324 for (
const auto& vtx : vertices) {
325 highestROF = std::max(highestROF, (
int)clockLayer.getROF(vtx.getTimeStamp().lower()));
327 highestROF = std::max(highestROF, (
int)clockLayer.mNROFsTF);
328 allTrackROFs.resize(highestROF);
329 vertROFvec.resize(highestROF);
330 setBCData(allTrackROFs);
331 setBCData(vertROFvec);
335 std::vector<int> rofEntries(highestROF + 1, 0);
336 for (
unsigned int iTrk{0}; iTrk <
tracks.size(); ++iTrk) {
338 trc.setFirstClusterEntry((
int)allClusIdx.size());
339 int ncl = trc.getNumberOfClusters(), nclf = 0;
341 auto clid = trc.getClusterIndex(ic);
351 allTracks.emplace_back(trc);
352 auto rof = clockLayer.getROF(trc.getTimeStamp());
355 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
356 for (
size_t iROF{0}; iROF < allTrackROFs.size(); ++iROF) {
357 allTrackROFs[iROF].setFirstEntry(rofEntries[iROF]);
358 allTrackROFs[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
359 allTrackROFs[iROF].setFlags(vertROFvec[iROF].getFlags());
361 auto& irFrame = irFrames.emplace_back(allTrackROFs[iROF].getBCData(), allTrackROFs[iROF].getBCData() + clockLayer.mROFLength - 1);
362 irFrame.info = allTrackROFs[iROF].getNEntries();
366 std::fill(rofEntries.begin(), rofEntries.end(), 0);
367 for (
const auto& vtx : vertices) {
368 auto rof = clockLayer.getROF(vtx.getTimeStamp().lower());
371 std::exclusive_scan(rofEntries.begin(), rofEntries.end(), rofEntries.begin(), 0);
372 for (
size_t iROF{0}; iROF < vertROFvec.size(); ++iROF) {
373 vertROFvec[iROF].setFirstEntry(rofEntries[iROF]);
374 vertROFvec[iROF].setNEntries(rofEntries[iROF + 1] - rofEntries[iROF]);
377 LOGP(info,
"ITSTracker pushed {} tracks in {} rofs and {} vertices {}", allTracks.size(), allTrackROFs.size(), vertices.size(), ((mDoStaggering) ?
"in staggered-readout mode" :
""));
379 LOGP(info,
"ITSTracker pushed {} track labels", allTrackLabels.size());
380 LOGP(info,
"ITSTracker pushed {} vertex labels", allVerticesLabels.size());
381 LOGP(info,
"ITSTracker pushed {} vertex purities", allVerticesPurities.size());