65 mTimer[SWTot].Start(
false);
67 updateTimeDependentParams(pc);
69 gsl::span<const unsigned char> patterns = pc.
inputs().
get<gsl::span<unsigned char>>(
"patterns");
70 auto compClusters = pc.
inputs().
get<
const std::vector<o2::itsmft::CompClusterExt>>(
"compClusters");
77 auto rofsinput = pc.
inputs().
get<
const std::vector<o2::itsmft::ROFRecord>>(
"ROframes");
78 auto& rofs = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"MFT",
"MFTTrackROF", 0}, rofsinput.begin(), rofsinput.end());
82 LOG(info) <<
"MFTTracker pulled " << compClusters.size() <<
" compressed clusters in " << rofsinput.size() <<
" RO frames";
85 if (trackingParam.irFramesOnly) {
87 LOG(info) <<
"MFTTracker IRFrame filter enabled: loading ITS IR Frames. ";
88 auto irFrames = pc.
inputs().
get<gsl::span<o2::dataformats::IRFrame>>(
"IRFramesITS");
89 filter = createIRFrameFilter(irFrames);
91 if (fair::Logger::Logging(fair::Severity::debug)) {
92 for (
const auto& irf : irFrames) {
93 LOG(
debug) <<
"IRFrame.info = " << irf.info <<
" ; min = " << irf.getMin().bc <<
" ; max = " << irf.getMax().bc;
98 if (trackingParam.isMultCutRequested()) {
99 LOG(info) <<
"MFTTracker multiplicity filter enabled. ROF selection: Min nClusters = " << trackingParam.cutMultClusLow <<
" ; Max nClusters = " << trackingParam.cutMultClusHigh;
104 auto& allClusIdx = pc.
outputs().
make<std::vector<int>>(
Output{
"MFT",
"TRACKCLSID", 0});
105 std::vector<o2::MCCompLabel> trackLabels;
106 std::vector<o2::MCCompLabel> allTrackLabels;
107 std::vector<o2::mft::TrackLTF> tracks;
108 std::vector<o2::mft::TrackLTFL> tracksL;
109 auto& allTracksMFT = pc.
outputs().
make<std::vector<o2::mft::TrackMFT>>(
Output{
"MFT",
"TRACKS", 0});
111 std::uint32_t roFrameId = 0;
112 int nROFs = rofs.size();
113 auto rofsPerWorker = std::max(1, nROFs / mNThreads);
114 LOG(
debug) <<
"nROFs = " << nROFs <<
" rofsPerWorker = " << rofsPerWorker;
116 auto loadData = [&,
this](
auto& trackerVec,
auto& roFrameDataVec) {
117 auto& tracker = trackerVec[0];
118 gsl::span<const unsigned char>::iterator pattIt = patterns.begin();
122 for (
const auto& rof : rofs) {
123 int worker = std::min(
int(iROF / rofsPerWorker), mNThreads - 1);
124 auto& roFrameData = roFrameDataVec[worker].emplace_back();
126 LOG(
debug) <<
"ROframeId: " << iROF <<
", clusters loaded : " << nclUsed <<
" on worker " << worker;
131 auto launchTrackFinder = [](
auto* tracker,
auto* workerROFs) {
133 long tStart = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count(), tStartROF = tStart, tEnd = tStart;
136 for (
auto&
rofData : *workerROFs) {
139 long tEndROF = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
140 LOGP(info,
"launchTrackFinder| tracker:{} did {}-th ROF in {} mus: {} clusters -> {} tracks", tracker->getTrackerID(), ++rofCNT, tEndROF - tStartROF,
rofData.getTotalClusters(),
rofData.getTracks().size());
141 tStartROF = tEnd = tEndROF;
145 LOGP(info,
"launchTrackFinder| done: tracker:{} processed {} ROFS in {} mus", tracker->getTrackerID(), workerROFs->size(), tEnd - tStart);
149 auto launchFitter = [](
auto* tracker,
auto* workerROFs) {
151 long tStart = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
153 for (
auto&
rofData : *workerROFs) {
157 long tEnd = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
158 LOGP(info,
"launchTrackFitter| done: tracker:{} fitted {} ROFS in {} mus", tracker->getTrackerID(), workerROFs->size(), tEnd - tStart);
162 auto runMFTTrackFinder = [&,
this](
auto& trackerVec,
auto& roFrameDataVec) {
163 std::vector<std::future<void>> finder;
164 for (
int i = 0;
i < mNThreads;
i++) {
165 auto& tracker = trackerVec[
i];
166 auto& workerData = roFrameDataVec[
i];
167 auto f = std::async(std::launch::async, launchTrackFinder, tracker.get(), &workerData);
168 finder.push_back(std::move(
f));
171 for (
int i = 0;
i < mNThreads;
i++) {
176 auto runTrackFitter = [&,
this](
auto& trackerVec,
auto& roFrameDataVec) {
177 std::vector<std::future<void>> fitter;
178 for (
int i = 0;
i < mNThreads;
i++) {
179 auto& tracker = trackerVec[
i];
180 auto& workerData = roFrameDataVec[
i];
181 auto f = std::async(std::launch::async, launchFitter, tracker.get(), &workerData);
182 fitter.push_back(std::move(
f));
185 for (
int i = 0;
i < mNThreads;
i++) {
191 auto copyTracks = [](
auto& new_tracks,
auto& allTracks,
auto& allClusIdx) {
192 for (
auto& trc : new_tracks) {
193 trc.setExternalClusterIndexOffset(allClusIdx.size());
194 int ncl = trc.getNumberOfPoints();
195 for (
int ic = 0; ic < ncl; ic++) {
196 auto externalClusterID = trc.getExternalClusterIndex(ic);
198 auto clusterLayer = trc.getExternalClusterLayer(ic);
200 allClusIdx.push_back(externalClusterID);
202 allTracks.emplace_back(trc);
208 std::vector<std::vector<o2::mft::ROframe<TrackLTF>>> roFrameVec(mNThreads);
211 for (
auto& rof : roFrameVec) {
212 rof.reserve(rofsPerWorker);
214 LOG(
debug) <<
"Loading data into ROFs.";
216 mTimer[SWLoadData].Start(
false);
218 mTimer[SWLoadData].Stop();
220 LOG(
debug) <<
"Running MFT Track finder.";
222 mTimer[SWFindMFTTracks].Start(
false);
223 runMFTTrackFinder(mTrackerVec, roFrameVec);
224 mTimer[SWFindMFTTracks].Stop();
226 LOG(
debug) <<
"Runnig track fitter.";
228 mTimer[SWFitTracks].Start(
false);
229 runTrackFitter(mTrackerVec, roFrameVec);
230 mTimer[SWFitTracks].Stop();
233 LOG(
debug) <<
"Computing MC Labels.";
235 mTimer[SWComputeLabels].Start(
false);
236 auto& tracker = mTrackerVec[0];
238 for (
int i = 0;
i < mNThreads;
i++) {
239 for (
auto&
rofData : roFrameVec[
i]) {
240 tracker->computeTracksMClabels(
rofData.getTracks());
241 trackLabels.swap(tracker->getTrackLabels());
242 std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels));
246 mTimer[SWComputeLabels].Stop();
249 auto rof = rofs.begin();
251 for (
int i = 0;
i < mNThreads;
i++) {
252 for (
auto&
rofData : roFrameVec[
i]) {
253 int ntracksROF = 0, firstROFTrackEntry = allTracksMFT.size();
254 tracks.swap(
rofData.getTracks());
255 ntracksROF = tracks.size();
256 copyTracks(tracks, allTracksMFT, allClusIdx);
258 rof->setFirstEntry(firstROFTrackEntry);
259 rof->setNEntries(ntracksROF);
267 std::vector<std::vector<o2::mft::ROframe<TrackLTFL>>> roFrameVec(mNThreads);
270 for (
auto& rof : roFrameVec) {
271 rof.reserve(rofsPerWorker);
273 LOG(
debug) <<
"Loading data into ROFs.";
275 mTimer[SWLoadData].Start(
false);
277 mTimer[SWLoadData].Stop();
279 LOG(
debug) <<
"Running MFT Track finder.";
281 mTimer[SWFindMFTTracks].Start(
false);
282 runMFTTrackFinder(mTrackerLVec, roFrameVec);
283 mTimer[SWFindMFTTracks].Stop();
285 LOG(
debug) <<
"Runnig track fitter.";
287 mTimer[SWFitTracks].Start(
false);
288 runTrackFitter(mTrackerLVec, roFrameVec);
289 mTimer[SWFitTracks].Stop();
292 LOG(
debug) <<
"Computing MC Labels.";
294 mTimer[SWComputeLabels].Start(
false);
295 auto& tracker = mTrackerLVec[0];
297 for (
int i = 0;
i < mNThreads;
i++) {
298 for (
auto&
rofData : roFrameVec[
i]) {
299 tracker->computeTracksMClabels(
rofData.getTracks());
300 trackLabels.swap(tracker->getTrackLabels());
301 std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels));
305 mTimer[SWComputeLabels].Stop();
308 auto rof = rofs.begin();
310 for (
int i = 0;
i < mNThreads;
i++) {
311 for (
auto&
rofData : roFrameVec[
i]) {
312 int ntracksROF = 0, firstROFTrackEntry = allTracksMFT.size();
313 tracksL.swap(
rofData.getTracks());
314 ntracksROF = tracksL.size();
315 copyTracks(tracksL, allTracksMFT, allClusIdx);
316 rof->setFirstEntry(firstROFTrackEntry);
317 rof->setNEntries(ntracksROF);
324 LOG(info) <<
"MFTTracker pushed " << allTracksMFT.size() <<
" tracks in " << nROFs <<
" rofs";
330 mTimer[SWTot].Stop();
443 std::vector<InputSpec> inputs;
444 inputs.emplace_back(
"compClusters",
"MFT",
"COMPCLUSTERS", 0, Lifetime::Timeframe);
445 inputs.emplace_back(
"patterns",
"MFT",
"PATTERNS", 0, Lifetime::Timeframe);
446 inputs.emplace_back(
"ROframes",
"MFT",
"CLUSTERSROF", 0, Lifetime::Timeframe);
447 inputs.emplace_back(
"cldict",
"MFT",
"CLUSDICT", 0, Lifetime::Condition,
ccdbParamSpec(
"MFT/Calib/ClusterDictionary"));
450 if (trackingParam.irFramesOnly) {
451 inputs.emplace_back(
"IRFramesITS",
"ITS",
"IRFRAMES", 0, Lifetime::Timeframe);
454 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
463 ggRequest->addInput({
"mftTGeo",
"MFT",
"GEOMTGEO", 0, Lifetime::Condition,
framework::ccdbParamSpec(
"MFT/Config/Geometry")}, inputs);
465 std::vector<OutputSpec> outputs;
466 outputs.emplace_back(
"MFT",
"TRACKS", 0, Lifetime::Timeframe);
467 outputs.emplace_back(
"MFT",
"MFTTrackROF", 0, Lifetime::Timeframe);
468 outputs.emplace_back(
"MFT",
"TRACKCLSID", 0, Lifetime::Timeframe);
471 inputs.emplace_back(
"labels",
"MFT",
"CLUSTERSMCTR", 0, Lifetime::Timeframe);
472 outputs.emplace_back(
"MFT",
"TRACKSMCTR", 0, Lifetime::Timeframe);
475 outputs.emplace_back(
"META",
"MFTTRACKER", 0, Lifetime::Sporadic);
481 AlgorithmSpec{adaptFromTask<TrackerDPL>(ggRequest, useMC, nThreads)},