140 constexpr double kZmin = 0.;
141 constexpr double kZmax = 300.;
142 constexpr double kXmin = -100.;
143 constexpr double kXmax = +100.;
144 constexpr double kYmin = -100.;
145 constexpr double kYmax = +100.;
146 constexpr std::array<Color_t, 11> kColorMC = {205, 209, 213, 217, 225, 208, 213, 216, 219, 224, 227};
147 constexpr std::array<Color_t, 3> kColorGhost = {201, 202, 203};
148 constexpr int kCanvX = 1920;
149 constexpr int kCanvY = 1080;
150 constexpr double kLMargin = 0.05;
151 constexpr double kVEMargin = 0.15;
152 constexpr double kRMarginDispl = 0.4;
153 constexpr double kVIMargin = 0.0001;
154 constexpr Marker_t kMarkerPointWHit = 25;
155 constexpr Marker_t kMarkerPointWOHit = 5;
156 constexpr Marker_t kMarkerHitWPoint = 24;
157 constexpr Marker_t kMarkerHitWOPoint = 28;
158 constexpr double kFontSize = 0.035;
159 constexpr Width_t kLineWidth = 1;
160 constexpr Style_t kLineMCTrackReconstructed = 9;
161 constexpr Style_t kLineMCTrackNotReconstructed = 10;
162 constexpr Style_t kLineRecoTrackGhost = 2;
163 constexpr Style_t kLineRecoTrackNotGhost = 1;
167 pCanv->Divide(1, 2, kVIMargin, kVIMargin);
169 gPad->SetMargin(kLMargin, kRMarginDispl, kVIMargin, kVEMargin);
171 auto* pHistX =
new TH2F(Form(
"hFrameX_%d", iEvent),
";z [cm];x [cm]", 2, kZmin, kZmax, 2, kXmin, kXmax);
172 pHistX->GetYaxis()->SetTitleOffset(0.6);
173 pHistX->GetXaxis()->SetLabelSize(kFontSize);
174 pHistX->GetYaxis()->SetLabelSize(kFontSize);
175 pHistX->GetXaxis()->SetTitleSize(kFontSize);
176 pHistX->GetYaxis()->SetTitleSize(kFontSize);
177 pHistX->SetStats(
false);
180 gPad->SetMargin(kLMargin, kRMarginDispl, kVEMargin, kVIMargin);
182 auto* pHistY =
new TH2F(Form(
"hFrameY_%d", iEvent),
";z [cm];y [cm]", 2, kZmin, kZmax, 2, kYmin, kYmax);
183 pHistY->GetYaxis()->SetTitleOffset(0.6);
184 pHistY->GetXaxis()->SetLabelSize(kFontSize);
185 pHistY->GetYaxis()->SetLabelSize(kFontSize);
186 pHistY->GetXaxis()->SetTitleSize(kFontSize);
187 pHistY->GetYaxis()->SetTitleSize(kFontSize);
188 pHistY->SetStats(
false);
193 auto* pHeader =
new TLegend(kLMargin, 1 - kVEMargin + 0.01, 0.99, 0.99);
194 pHeader->SetNColumns(6);
195 pHeader->SetTextSize(kFontSize);
196 pHeader->SetMargin(0.1);
197 pHeader->AddEntry(
static_cast<TObject*
>(
nullptr), Form(
"event #%d", iEvent),
"");
198 pHeader->AddEntry(
new TMarker(0, 0, kMarkerPointWHit),
"point w/ hit",
"p");
199 pHeader->AddEntry(
new TMarker(0, 0, kMarkerPointWOHit),
"point w/o hit",
"p");
200 pHeader->AddEntry(
new TMarker(0, 0, kMarkerHitWPoint),
"hit w/ point",
"p");
201 pHeader->AddEntry(
new TMarker(0, 0, kMarkerHitWOPoint),
"hit w/o point",
"p");
202 pHeader->Draw(
"same");
204 auto* pLegendReco =
new TLegend(1 - kRMarginDispl, kVIMargin, 0.99, 1 - kVEMargin,
"Reco tracks");
205 pLegendReco->SetMargin(0.1);
206 pLegendReco->SetTextSize(kFontSize);
209 auto* pLegendMC =
new TLegend(1 - kRMarginDispl, kVEMargin, 0.99, 1 - kVIMargin,
"MC tracks");
210 pLegendMC->SetMargin(0.1);
211 pLegendMC->SetTextSize(kFontSize);
218 std::map<int, Color_t> mMCtrkColors;
222 for (
int iTmc = 0; iTmc <
nMCTracks; ++iTmc) {
223 const auto& trk =
fMCData.GetTrack(iTmc);
224 int nPoints = trk.GetNofPoints();
228 std::vector<double> trkPointX(nPoints);
229 std::vector<double> trkPointY(nPoints);
230 std::vector<double> trkPointZ(nPoints);
231 for (
int iPLoc = 0; iPLoc < nPoints; ++iPLoc) {
232 const auto& point =
fMCData.GetPoint(trk.GetPointIndexes()[iPLoc]);
233 trkPointX[iPLoc] = point.GetX();
234 trkPointY[iPLoc] = point.GetY();
235 trkPointZ[iPLoc] = point.GetZ();
237 Color_t currColor = 1;
238 Style_t currStyle = trk.IsReconstructed() ? kLineMCTrackReconstructed : kLineMCTrackNotReconstructed;
239 currColor = kColorMC[iColorRec];
240 iColorRec = (iColorRec + 1) %
static_cast<int>(kColorMC.size());
241 mMCtrkColors[trk.GetId()] = currColor;
244 auto*
gr =
new TGraph(nPoints, trkPointZ.data(), trkPointX.data());
245 gr->SetMarkerStyle(1);
246 gr->SetMarkerColor(currColor);
247 gr->SetLineColor(currColor);
248 gr->SetLineStyle(currStyle);
249 gr->SetLineWidth(kLineWidth);
252 std::stringstream msg;
253 msg <<
"ID=" << trk.GetId() <<
", ";
254 msg <<
"PDG=" << trk.GetPdgCode() <<
", ";
255 msg <<
"p=" << trk.GetP() <<
" GeV/c, ";
256 msg <<
"rec-able=" << trk.IsReconstructable() <<
", ";
257 msg <<
"rec-ed=" << trk.IsReconstructed() <<
", ";
258 if (trk.GetNofRecoTracks() > 0) {
260 for (
int iTr : trk.GetRecoTrackIndexes()) {
265 if (trk.GetNofTouchTracks() > 0) {
266 msg <<
"touch_IDs=(";
267 for (
int iTr : trk.GetTouchTrackIndexes()) {
272 pLegendMC->AddEntry(
gr, msg.str().c_str(),
"l");
276 auto*
gr =
new TGraph(nPoints, trkPointZ.data(), trkPointY.data());
277 gr->SetMarkerStyle(1);
278 gr->SetMarkerColor(currColor);
279 gr->SetLineColor(currColor);
280 gr->SetLineStyle(currStyle);
281 gr->SetLineWidth(kLineWidth);
287 int nPoints =
fMCData.GetNofPoints();
288 for (
int iP = 0; iP < nPoints; ++iP) {
289 const auto& point =
fMCData.GetPoint(iP);
290 bool bHasHit = point.GetHitIndexes().size() > 0;
291 Marker_t style = bHasHit ? kMarkerPointWHit : kMarkerPointWOHit;
292 Color_t color = mMCtrkColors.at(point.GetTrackId());
295 auto* marker =
new TMarker(point.GetZ(), point.GetX(), style);
296 marker->SetMarkerColor(color);
297 marker->Draw(
"same");
299 auto* pText =
new TText(point.GetZ() + 2., point.GetX() + 2., Form(
"%d", point.GetActiveStationId()));
300 pText->SetTextColor(color);
301 pText->SetTextSize(kFontSize);
306 auto* marker =
new TMarker(point.GetZ(), point.GetY(), style);
307 marker->SetMarkerColor(color);
308 marker->Draw(
"same");
310 auto* pText =
new TText(point.GetZ() + 2., point.GetY() + 2., Form(
"%d", point.GetActiveStationId()));
311 pText->SetTextColor(color);
312 pText->SetTextSize(kFontSize);
319 std::vector<char> vbHitUsed(
fvHits.size());
320 std::vector<Color_t> vRecoTrkColors(
fvHits.size());
321 if (nRecoTracks > 0) {
322 for (
int iTr = 0; iTr < nRecoTracks; ++iTr) {
324 Color_t currColor = 1;
325 Style_t currStyle = trk.IsGhost() ? kLineRecoTrackGhost : kLineRecoTrackNotGhost;
327 currColor = kColorGhost[iColorGhost];
328 iColorGhost = (iColorGhost + 1) %
static_cast<int>(kColorGhost.size());
331 int iTmc = trk.GetMatchedMCTrackIndex();
332 currColor = iTmc > -1 ? mMCtrkColors[iTmc] : 1;
335 int nHits = trk.GetNofHits();
336 std::vector<double> trkHitX(nHits);
337 std::vector<double> trkHitY(nHits);
338 std::vector<double> trkHitZ(nHits);
339 for (
int iHLoc = 0; iHLoc < nHits; ++iHLoc) {
340 int iH = trk.GetHitIndexes()[iHLoc];
341 const auto& hit =
fvHits[iH];
342 vbHitUsed[iH] =
true;
343 trkHitX[iHLoc] = hit.GetX();
344 trkHitY[iHLoc] = hit.GetY();
345 trkHitZ[iHLoc] = hit.GetZ();
346 vRecoTrkColors[iH] = currColor;
351 auto*
gr =
new TGraph(nHits, trkHitZ.data(), trkHitX.data());
352 gr->SetMarkerStyle(1);
353 gr->SetMarkerColor(currColor);
354 gr->SetLineColor(currColor);
355 gr->SetLineStyle(currStyle);
356 gr->SetLineWidth(kLineWidth + 2);
361 auto*
gr =
new TGraph(nHits, trkHitZ.data(), trkHitY.data());
362 gr->SetMarkerStyle(1);
363 gr->SetMarkerColor(currColor);
364 gr->SetLineColor(currColor);
365 gr->SetLineStyle(currStyle);
366 gr->SetLineWidth(kLineWidth + 2);
368 std::stringstream msg;
369 msg <<
"ID=" << trk.index <<
", ";
371 for (
int iTmc : trk.GetMCTrackIndexes()) {
375 msg <<
"purity=" << trk.GetMaxPurity();
376 pLegendReco->AddEntry(
gr, msg.str().c_str(),
"l");
381 int nHits =
fvHits.size();
383 for (
int iH = 0; iH < nHits; ++iH) {
384 const auto& hit =
fvHits[iH];
385 bool bFake = hit.GetBestMcPointId() == -1;
386 bool bUsed = vbHitUsed[iH];
388 Marker_t style = bFake ? kMarkerHitWOPoint : kMarkerHitWPoint;
389 Color_t color = bUsed ? vRecoTrkColors[iH] : 1;
392 auto* marker =
new TMarker(hit.GetZ(), hit.GetX(), style);
393 marker->SetMarkerColor(color);
394 marker->Draw(
"same");
398 auto* marker =
new TMarker(hit.GetZ(), hit.GetY(), style);
399 marker->SetMarkerColor(color);
400 marker->Draw(
"same");
419 int nHits =
fvHits.size();
431 nMCPoints =
fMCData.GetNofPoints();
442 LOG_IF(info, fVerbose > 3) <<
": Data sample consists of " << nHits <<
" hits, " << nRecoTracks <<
" reco tracks, "
443 <<
nMCTracks <<
" MC tracks, " << nMCPoints <<
" MC points";
444 LOG_IF(info, fVerbose > 3) <<
"Using " <<
fNthreads
453 auto EstimateDcaRtOriginReco = [&](
const CbmL1Track& trk) ->
double {
455 std::vector<const cbm::algo::ca::McHitInfo*> vpStsHits;
456 for (
auto iHit : trk.GetHitIndexes()) {
457 const auto& hit =
fvHits[iHit];
459 vpStsHits.push_back(&hit);
462 std::sort(vpStsHits.begin(), vpStsHits.end(), [](
const auto* l,
const auto* r) { return l->GetZ() < r->GetZ(); });
463 if (vpStsHits.size() < 2) {
464 return std::numeric_limits<double>::quiet_NaN();
467 const auto* pHitFst = vpStsHits[0];
468 const auto* pHitSnd = vpStsHits[1];
469 double factor{(pHitFst->GetZ() - pTarget->GetZ()) / (pHitSnd->GetZ() - pHitFst->GetZ())};
470 double x{pHitFst->GetX() - pTarget->GetX() - factor * (pHitSnd->GetX() - pHitFst->GetX())};
471 double y{pHitFst->GetY() - pTarget->GetY() - factor * (pHitSnd->GetY() - pHitFst->GetY())};
472 return std::sqrt(
x *
x +
y *
y);
476 std::vector<TrackTypeQa::FitQaPointSet> allFitPoints(nRecoTracks + 1);
483 auto fitPointsThread = [&](
int iThread) {
484 for (
int iTrkReco = iThread; iTrkReco < nRecoTracks; iTrkReco +=
fNthreads) {
489 std::vector<std::thread> threads(
fNthreads);
491 threads[i] = std::thread(fitPointsThread, i);
493 for (
auto& th : threads) {
498 for (
int iTrkReco = 0; iTrkReco < nRecoTracks; iTrkReco++) {
503 if (recoTrk.GetNofHits() < 1) {
506 std::vector<ETrackType> vTrackTypes;
513 for (
auto iHit : recoTrk.GetHitIndexes()) {
514 const auto& hit =
fvHits[iHit];
515 ++nHitsDet[hit.GetDetectorType()];
521 double dcaRtOrigin = EstimateDcaRtOriginReco(recoTrk);
522 if (dcaRtOrigin < 0.5) {
533 if (recoTrk.IsGhost()) {
537 int iTrkMC = recoTrk.GetMatchedMCTrackIndex();
539 const auto& mcTrk =
fMCData.GetTrack(iTrkMC);
540 int pdg = mcTrk.GetPdgCode();
541 bool isPrimary = mcTrk.IsPrimary();
544 if (mcTrk.GetNofHits() == 0) {
545 LOG(error) <<
"Track #" << iTrkMC <<
" (ID=" << mcTrk.GetId()
546 <<
") has no hits in tracker, but is referenced by "
547 <<
"reco track #" << iTrkReco <<
" (ID=" << recoTrk.index <<
").";
553 bool bLong = mcTrk.GetTotNofStationsWithHit() ==
fpParameters->GetNstationsActive();
560 if (bLong && bFast) {
572 switch (std::abs(pdg)) {
632 for (
auto trType : vTrackTypes) {
645 auto EstimateDcaRtOriginMc = [&](
const McTrack& trk) ->
double {
647 std::vector<const cbm::algo::ca::McHitInfo*> vpStsHits;
648 for (
auto iHit : trk.GetHitIndexes()) {
649 const auto& hit =
fvHits[iHit];
651 vpStsHits.push_back(&hit);
654 std::sort(vpStsHits.begin(), vpStsHits.end(), [](
const auto* l,
const auto* r) { return l->GetZ() < r->GetZ(); });
655 if (vpStsHits.size() < 2) {
656 return std::numeric_limits<double>::quiet_NaN();
659 const auto* pHitFst = vpStsHits[0];
660 const auto* pHitSnd = vpStsHits[1];
661 double factor{(pHitFst->GetZ() - pTarget->GetZ()) / (pHitSnd->GetZ() - pHitFst->GetZ())};
662 double x{pHitFst->GetX() - pTarget->GetX() - factor * (pHitSnd->GetX() - pHitFst->GetX())};
663 double y{pHitFst->GetY() - pTarget->GetY() - factor * (pHitSnd->GetY() - pHitFst->GetY())};
664 return std::sqrt(
x *
x +
y *
y);
667 for (
int iTrkMC = 0; iTrkMC <
fMCData.GetNofTracks(); ++iTrkMC) {
668 const auto& mcTrk =
fMCData.GetTrack(iTrkMC);
672 if (mcTrk.GetNofHits() == 0) {
677 if (!mcTrk.IsReconstructable()) {
680 int pdg = mcTrk.GetPdgCode();
681 bool isPrimary = mcTrk.IsPrimary();
688 for (
auto iHit : mcTrk.GetHitIndexes()) {
689 const auto& hit =
fvHits[iHit];
690 ++nHitsDet[hit.GetDetectorType()];
696 double dcaRtOrigin = EstimateDcaRtOriginMc(mcTrk);
697 if (dcaRtOrigin < 0.5) {
709 bool bLong = mcTrk.GetTotNofStationsWithHit() ==
fpParameters->GetNstationsActive();
716 if (bLong && bFast) {
728 switch (std::abs(pdg)) {