64 mTimer[SWTot].Start(
false);
66 updateTimeDependentParams(pc);
67 gsl::span<const unsigned char> patterns = pc.
inputs().
get<gsl::span<unsigned char>>(
"patterns");
68 auto compClusters = pc.
inputs().
get<
const std::vector<o2::itsmft::CompClusterExt>>(
"compClusters");
75 auto rofsinput = pc.
inputs().
get<
const std::vector<o2::itsmft::ROFRecord>>(
"ROframes");
76 auto& rofs = pc.
outputs().
make<std::vector<o2::itsmft::ROFRecord>>(
Output{
"MFT",
"MFTTrackROF", 0}, rofsinput.begin(), rofsinput.end());
80 LOG(info) <<
"MFTTracker pulled " << compClusters.size() <<
" compressed clusters in " << rofsinput.size() <<
" RO frames";
83 if (trackingParam.irFramesOnly) {
85 LOG(info) <<
"MFTTracker IRFrame filter enabled: loading ITS IR Frames. ";
86 auto irFrames = pc.
inputs().
get<gsl::span<o2::dataformats::IRFrame>>(
"IRFramesITS");
87 filter = createIRFrameFilter(irFrames);
89 if (fair::Logger::Logging(fair::Severity::debug)) {
90 for (
const auto& irf : irFrames) {
91 LOG(
debug) <<
"IRFrame.info = " << irf.info <<
" ; min = " << irf.getMin().bc <<
" ; max = " << irf.getMax().bc;
96 if (trackingParam.isMultCutRequested()) {
97 LOG(info) <<
"MFTTracker multiplicity filter enabled. ROF selection: Min nClusters = " << trackingParam.cutMultClusLow <<
" ; Max nClusters = " << trackingParam.cutMultClusHigh;
102 auto& allClusIdx = pc.
outputs().
make<std::vector<int>>(
Output{
"MFT",
"TRACKCLSID", 0});
103 std::vector<o2::MCCompLabel> trackLabels;
104 std::vector<o2::MCCompLabel> allTrackLabels;
105 std::vector<o2::mft::TrackLTF> tracks;
106 std::vector<o2::mft::TrackLTFL> tracksL;
107 auto& allTracksMFT = pc.
outputs().
make<std::vector<o2::mft::TrackMFT>>(
Output{
"MFT",
"TRACKS", 0});
109 std::uint32_t roFrameId = 0;
110 int nROFs = rofs.size();
111 auto rofsPerWorker = std::max(1, nROFs / mNThreads);
112 LOG(
debug) <<
"nROFs = " << nROFs <<
" rofsPerWorker = " << rofsPerWorker;
114 auto loadData = [&,
this](
auto& trackerVec,
auto& roFrameDataVec) {
115 auto& tracker = trackerVec[0];
116 gsl::span<const unsigned char>::iterator pattIt = patterns.begin();
120 for (
const auto& rof : rofs) {
121 int worker = std::min(
int(iROF / rofsPerWorker), mNThreads - 1);
122 auto& roFrameData = roFrameDataVec[worker].emplace_back();
124 LOG(
debug) <<
"ROframeId: " << iROF <<
", clusters loaded : " << nclUsed <<
" on worker " << worker;
129 auto launchTrackFinder = [](
auto* tracker,
auto* workerROFs) {
131 long tStart = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count(), tStartROF = tStart, tEnd = tStart;
134 for (
auto&
rofData : *workerROFs) {
137 long tEndROF = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
138 LOGP(info,
"launchTrackFinder| tracker:{} did {}-th ROF in {} mus: {} clusters -> {} tracks", tracker->getTrackerID(), ++rofCNT, tEndROF - tStartROF,
rofData.getTotalClusters(),
rofData.getTracks().size());
139 tStartROF = tEnd = tEndROF;
143 LOGP(info,
"launchTrackFinder| done: tracker:{} processed {} ROFS in {} mus", tracker->getTrackerID(), workerROFs->size(), tEnd - tStart);
147 auto launchFitter = [](
auto* tracker,
auto* workerROFs) {
149 long tStart = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
151 for (
auto&
rofData : *workerROFs) {
155 long tEnd = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
156 LOGP(info,
"launchTrackFitter| done: tracker:{} fitted {} ROFS in {} mus", tracker->getTrackerID(), workerROFs->size(), tEnd - tStart);
160 auto runMFTTrackFinder = [&,
this](
auto& trackerVec,
auto& roFrameDataVec) {
161 std::vector<std::future<void>> finder;
162 for (
int i = 0;
i < mNThreads;
i++) {
163 auto& tracker = trackerVec[
i];
164 auto& workerData = roFrameDataVec[
i];
165 auto f = std::async(std::launch::async, launchTrackFinder, tracker.get(), &workerData);
166 finder.push_back(std::move(
f));
169 for (
int i = 0;
i < mNThreads;
i++) {
174 auto runTrackFitter = [&,
this](
auto& trackerVec,
auto& roFrameDataVec) {
175 std::vector<std::future<void>> fitter;
176 for (
int i = 0;
i < mNThreads;
i++) {
177 auto& tracker = trackerVec[
i];
178 auto& workerData = roFrameDataVec[
i];
179 auto f = std::async(std::launch::async, launchFitter, tracker.get(), &workerData);
180 fitter.push_back(std::move(
f));
183 for (
int i = 0;
i < mNThreads;
i++) {
189 auto copyTracks = [](
auto& new_tracks,
auto& allTracks,
auto& allClusIdx) {
190 for (
auto& trc : new_tracks) {
191 trc.setExternalClusterIndexOffset(allClusIdx.size());
192 int ncl = trc.getNumberOfPoints();
193 for (
int ic = 0; ic < ncl; ic++) {
194 auto externalClusterID = trc.getExternalClusterIndex(ic);
196 auto clusterLayer = trc.getExternalClusterLayer(ic);
198 allClusIdx.push_back(externalClusterID);
200 allTracks.emplace_back(trc);
206 std::vector<std::vector<o2::mft::ROframe<TrackLTF>>> roFrameVec(mNThreads);
209 for (
auto& rof : roFrameVec) {
210 rof.reserve(rofsPerWorker);
212 LOG(
debug) <<
"Loading data into ROFs.";
214 mTimer[SWLoadData].Start(
false);
216 mTimer[SWLoadData].Stop();
218 LOG(
debug) <<
"Running MFT Track finder.";
220 mTimer[SWFindMFTTracks].Start(
false);
221 runMFTTrackFinder(mTrackerVec, roFrameVec);
222 mTimer[SWFindMFTTracks].Stop();
224 LOG(
debug) <<
"Runnig track fitter.";
226 mTimer[SWFitTracks].Start(
false);
227 runTrackFitter(mTrackerVec, roFrameVec);
228 mTimer[SWFitTracks].Stop();
231 LOG(
debug) <<
"Computing MC Labels.";
233 mTimer[SWComputeLabels].Start(
false);
234 auto& tracker = mTrackerVec[0];
236 for (
int i = 0;
i < mNThreads;
i++) {
237 for (
auto&
rofData : roFrameVec[
i]) {
238 tracker->computeTracksMClabels(
rofData.getTracks());
239 trackLabels.swap(tracker->getTrackLabels());
240 std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels));
244 mTimer[SWComputeLabels].Stop();
247 auto rof = rofs.begin();
249 for (
int i = 0;
i < mNThreads;
i++) {
250 for (
auto&
rofData : roFrameVec[
i]) {
251 int ntracksROF = 0, firstROFTrackEntry = allTracksMFT.size();
252 tracks.swap(
rofData.getTracks());
253 ntracksROF = tracks.size();
254 copyTracks(tracks, allTracksMFT, allClusIdx);
256 rof->setFirstEntry(firstROFTrackEntry);
257 rof->setNEntries(ntracksROF);
265 std::vector<std::vector<o2::mft::ROframe<TrackLTFL>>> roFrameVec(mNThreads);
268 for (
auto& rof : roFrameVec) {
269 rof.reserve(rofsPerWorker);
271 LOG(
debug) <<
"Loading data into ROFs.";
273 mTimer[SWLoadData].Start(
false);
275 mTimer[SWLoadData].Stop();
277 LOG(
debug) <<
"Running MFT Track finder.";
279 mTimer[SWFindMFTTracks].Start(
false);
280 runMFTTrackFinder(mTrackerLVec, roFrameVec);
281 mTimer[SWFindMFTTracks].Stop();
283 LOG(
debug) <<
"Runnig track fitter.";
285 mTimer[SWFitTracks].Start(
false);
286 runTrackFitter(mTrackerLVec, roFrameVec);
287 mTimer[SWFitTracks].Stop();
290 LOG(
debug) <<
"Computing MC Labels.";
292 mTimer[SWComputeLabels].Start(
false);
293 auto& tracker = mTrackerLVec[0];
295 for (
int i = 0;
i < mNThreads;
i++) {
296 for (
auto&
rofData : roFrameVec[
i]) {
297 tracker->computeTracksMClabels(
rofData.getTracks());
298 trackLabels.swap(tracker->getTrackLabels());
299 std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels));
303 mTimer[SWComputeLabels].Stop();
306 auto rof = rofs.begin();
308 for (
int i = 0;
i < mNThreads;
i++) {
309 for (
auto&
rofData : roFrameVec[
i]) {
310 int ntracksROF = 0, firstROFTrackEntry = allTracksMFT.size();
311 tracksL.swap(
rofData.getTracks());
312 ntracksROF = tracksL.size();
313 copyTracks(tracksL, allTracksMFT, allClusIdx);
314 rof->setFirstEntry(firstROFTrackEntry);
315 rof->setNEntries(ntracksROF);
322 LOG(info) <<
"MFTTracker pushed " << allTracksMFT.size() <<
" tracks in " << nROFs <<
" rofs";
328 static bool first =
true;
336 mTimer[SWTot].Stop();
433 std::vector<InputSpec> inputs;
434 inputs.emplace_back(
"compClusters",
"MFT",
"COMPCLUSTERS", 0, Lifetime::Timeframe);
435 inputs.emplace_back(
"patterns",
"MFT",
"PATTERNS", 0, Lifetime::Timeframe);
436 inputs.emplace_back(
"ROframes",
"MFT",
"CLUSTERSROF", 0, Lifetime::Timeframe);
437 inputs.emplace_back(
"cldict",
"MFT",
"CLUSDICT", 0, Lifetime::Condition,
ccdbParamSpec(
"MFT/Calib/ClusterDictionary"));
440 if (trackingParam.irFramesOnly) {
441 inputs.emplace_back(
"IRFramesITS",
"ITS",
"IRFRAMES", 0, Lifetime::Timeframe);
444 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
453 ggRequest->addInput({
"mftTGeo",
"MFT",
"GEOMTGEO", 0, Lifetime::Condition,
framework::ccdbParamSpec(
"MFT/Config/Geometry")}, inputs);
455 std::vector<OutputSpec> outputs;
456 outputs.emplace_back(
"MFT",
"TRACKS", 0, Lifetime::Timeframe);
457 outputs.emplace_back(
"MFT",
"MFTTrackROF", 0, Lifetime::Timeframe);
458 outputs.emplace_back(
"MFT",
"TRACKCLSID", 0, Lifetime::Timeframe);
461 inputs.emplace_back(
"labels",
"MFT",
"CLUSTERSMCTR", 0, Lifetime::Timeframe);
462 outputs.emplace_back(
"MFT",
"TRACKSMCTR", 0, Lifetime::Timeframe);
469 AlgorithmSpec{adaptFromTask<TrackerDPL>(ggRequest, useMC, nThreads)},