17#include <TStopwatch.h>
48#include <TLegendEntry.h>
79 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(
src), mDrawOnly(drawOnly), mPostProcOnly(postProcOnly)
91 bool refitPV(
o2::dataformats::PrimaryVertex& pv,
int vid);
93 bool processITSTrack(const
o2::its::
TrackITS& iTrack, const
o2::dataformats::PrimaryVertex& pv,
o2::checkresid::
Track& resTrack);
95 void fillHistos(const
o2::checkresid::
Track& trc);
96 void postProcessHistos();
99 o2::globaltracking::RecoContainer* mRecoData =
nullptr;
101 bool mMeanVertexUpdated = false;
102 float mITSROFrameLengthMUS = 0.
f;
103 o2::dataformats::MeanVertexObject mMeanVtx{};
104 std::vector<o2::BaseCluster<float>> mITSClustersArray;
107 std::shared_ptr<DataRequest> mDataRequest;
108 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
109 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
112 bool mDrawOnly =
false;
113 bool mPostProcOnly =
false;
115 bool mFillHistos =
true;
116 bool mFillTree =
true;
117 std::vector<std::unique_ptr<o2::HistoManager>> mHManV{};
125 mDraw = ic.
options().
get<
bool>(
"draw-report");
126 mFillHistos = !ic.
options().
get<
bool>(
"no-hist");
127 mFillTree = !ic.
options().
get<
bool>(
"no-tree");
128 mNThreads = ic.
options().
get<
int>(
"nthreads");
133 std::string nm =
params.outname;
140 if (!mDrawOnly && mFillHistos) {
143 if (!
params.ext_hm_list.empty()) {
147 if (vecNames.size() != vecLegends.size()) {
148 LOGP(warn,
"{} legend names provided for {} external histomanagers, will use file names as legends", vecLegends.size(), vecNames.size());
152 for (
const auto& vn : vecNames) {
153 LOGP(info,
"Loading external HistoManager {}", vn);
154 mHManV.emplace_back() = std::make_unique<o2::HistoManager>(
"", vn,
true);
155 auto hm = mHManV.back().get();
157 LOGP(error,
"Failed to load histograms from {}", vn);
160 hm->SetName(useLeg ? vecLegends[cntH].c_str() : vn.c_str());
171 LOGP(warn,
"No OpenMP");
177 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(nm.c_str(),
"recreate");
199 mRecoData = &recoData;
201 mRecoData = &recoData;
202 updateTimeDependentParams(pc);
211 static bool initOnceDone =
false;
218 if (!grp->isDetContinuousReadOut(
DetID::ITS)) {
219 mITSROFrameLengthMUS = alpParams.roFrameLengthTrig / 1.e3;
228 if (mMeanVertexUpdated) {
229 mMeanVertexUpdated =
false;
238 LOGP(fatal,
"ITS data is not loaded");
246 auto pattIt = patterns.begin();
247 mITSClustersArray.clear();
248 mITSClustersArray.reserve(clusITS.size());
256 static int TFCount = 0;
257 int nv = vtxRefs.size() - 1;
258 std::vector<std::vector<checkresid::Track>> slots;
259 slots.resize(mNThreads);
260 int nvGood = 0, nvUse = 0, nvRefFail = 0;
261 long pvFitDuration{};
262 for (
int iv = 0; iv < nv; iv++) {
263 const auto& vtref = vtxRefs[iv];
264 auto pve = pvvec[iv];
265 if (pve.getNContributors() <
params.minPVContributors) {
270 LOGP(
debug,
"Refitting PV#{} of {} tracks", iv, pve.getNContributors());
271 auto tStartPVF = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
272 bool res = refitPV(pve, iv);
273 pvFitDuration += std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count() - tStartPVF;
284 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
290 LOGP(fatal,
"Cut on TPC tracks is requested by they are not loaded");
293#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
295 for (
int i = idMin;
i < idMax;
i++) {
296 auto vid = trackIndex[
i];
297 bool pvCont = vid.isPVContributor();
298 if (!pvCont &&
params.pvcontribOnly) {
309 const auto& itsTrack = mRecoData->
getITSTrack(gidITS);
310 if (itsTrack.getNClusters() <
params.minITSCl) {
313 auto pt = trc.getPt();
314 if (pt < params.minPt || pt >
params.maxPt) {
317 if (std::abs(trc.getTgl()) >
params.maxTgl) {
322 auto& accum = slots[omp_get_thread_num()];
324 auto& accum = slots[0];
326 auto& resTrack = accum.emplace_back();
328 if (!processITSTrack(itsTrack, pve, resTrack)) {
336 for (
const auto& accum : slots) {
337 for (
const auto& tr : accum) {
339 (*mDBGOut) <<
"res" <<
"tr=" << tr <<
"\n";
346 LOGP(info,
"processed {} PVs out of {} good vertices (out of {} in total), PV refits took {} mus, {} refits failed", nvUse, nvGood, nv, pvFitDuration, nvRefFail);
353 auto trFitInw = iTrack.getParamOut();
354 auto trFitOut = iTrack.getParamIn();
358 float bz = prop->getNominalBz();
359 std::array<const o2::BaseCluster<float>*, 8> clArr{};
361 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
364 return refLin ? tr.rotate(
alpha, *refLin, bz) : tr.rotate(
alpha);
369 if (!rotateTrack(tr,
i == 0 ? pvAlpha : geom->getSensorRefAlpha(clArr[
i]->getSensorID()), refLin) ||
370 !prop->propagateTo(tr, refLin, clArr[
i]->getX(), true)) {
374 if (!tr.update(*clArr[
i])) {
378 extrapDest[
i].invalidate();
384 auto inv2d = [](
float s00,
float s11,
float s01) -> std::array<float, 3> {
385 auto det = s00 * s11 - s01 * s01;
387 LOGP(error,
"Singular det {}, input: {} {} {}", det, s00, s11, s01);
388 return {0.f, 0.f, 0.f};
391 return {s11 * det, s00 * det, -s01 * det};
395 if (!prop->propagateToDCA(pv, trFitOut, bz)) {
396 LOGP(
debug,
"Failed to propagateToDCA, {}", trFitOut.asString());
400 if (
params.addPVAsCluster) {
401 float cosAlp, sinAlp;
402 pvAlpha = trFitOut.getAlpha();
403 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
404 bcPV.
setXYZ(pv.getX() * cosAlp + pv.getY() * sinAlp, -pv.getX() * sinAlp + pv.getY() * cosAlp, pv.getZ());
405 bcPV.
setSigmaY2(0.5 * (pv.getSigmaX2() + pv.getSigmaY2()));
411 int nCl = iTrack.getNClusters();
412 for (
int i = 0;
i <
nCl;
i++) {
413 const auto& curClu = mITSClustersArray[itsClRefs[iTrack.
getClusterEntry(
i)]];
415 int llr = geom->getLayer(curClu.getSensorID());
416 if (clArr[1 + llr]) {
417 LOGP(error,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), curClu.getSensorID());
419 clArr[1 + geom->getLayer(curClu.getSensorID())] = &curClu;
422 o2::track::TrackPar refLinIBOut0, refLinOBInw0, *refLinOBInw =
nullptr, *refLinIBOut =
nullptr;
423 if (
params.useStableRef) {
424 refLinOut = &(refLinOut0 = trFitOut);
425 refLinInw = &(refLinInw0 = trFitInw);
427 trFitOut.resetCovariance();
428 trFitOut.setCov(trFitOut.getQ2Pt() * trFitOut.getQ2Pt() * trFitOut.getCov()[14], 14);
429 trFitInw.resetCovariance();
430 trFitInw.setCov(trFitInw.getQ2Pt() * trFitInw.getQ2Pt() * trFitInw.getCov()[14], 14);
432 for (
int i = 0;
i <= 7;
i++) {
435 if (!(resOut = accountCluster(
i, extrapOut, trFitOut, refLinOut)) || !(resInw = accountCluster(7 -
i, extrapInw, trFitInw, refLinInw))) {
441 if (
i == 3 && resOut == 1 && resInw == 1 &&
params.doIBOB && nCl == 7) {
446 refLinIBOut = &(refLinIBOut0 = refLinOut0);
447 refLinOBInw = &(refLinOBInw0 = refLinInw0);
450 if (!resTrack.
trOBInw.getXatLabR(
params.rCompIBOB, xRref, bz) ||
451 !prop->propagateTo(resTrack.
trOBInw, refLinOBInw, xRref,
true) ||
452 !rotateTrack(resTrack.
trOBInw, resTrack.
trOBInw.getPhiPos(), refLinOBInw) ||
453 !rotateTrack(resTrack.
trIBOut, resTrack.
trOBInw.getAlpha(), refLinIBOut) ||
454 !prop->propagateTo(resTrack.
trIBOut, refLinIBOut, resTrack.
trOBInw.getX(),
true)) {
461 bool innerDone =
false;
463 for (
int i = 0;
i <= 7;
i++) {
466 const auto &tInw = extrapInw[
i], &tOut = extrapOut[
i];
467 auto wInw = inv2d(tInw.getSigmaY2(), tInw.getSigmaZ2(), tInw.getSigmaZY());
468 auto wOut = inv2d(tOut.getSigmaY2(), tOut.getSigmaZ2(), tOut.getSigmaZY());
469 if (wInw[0] == 0.f || wOut[0] == 0.f) {
472 std::array<float, 3> wTot = {wInw[0] + wOut[0], wInw[1] + wOut[1], wInw[2] + wOut[2]};
473 auto cTot = inv2d(wTot[0], wTot[1], wTot[2]);
474 auto ywi = wInw[0] * tInw.getY() + wInw[2] * tInw.getZ() + wOut[0] * tOut.getY() + wOut[2] * tOut.getZ();
475 auto zwi = wInw[2] * tInw.getY() + wInw[1] * tInw.getZ() + wOut[2] * tOut.getY() + wOut[1] * tOut.getZ();
476 auto yw = ywi * cTot[0] + zwi * cTot[2];
477 auto zw = ywi * cTot[2] + zwi * cTot[1];
479 auto phi =
i == 0 ? tInw.getPhi() : tInw.getPhiPos();
480 o2::math_utils::bringTo02Pi(phi);
481 resTrack.
points.emplace_back(clArr[
i]->
getY() - yw, clArr[
i]->getZ() - zw, cTot[0] + clArr[
i]->getSigmaY2(), cTot[1] + clArr[
i]->getSigmaZ2(), phi, clArr[
i]->getZ(), clArr[
i]->
getSensorID(),
i - 1);
483 resTrack.
track = tInw;
487 LOGP(
debug,
"No cluster on lr {}",
i);
497 std::vector<o2::track::TrackParCov>
tracks;
498 std::vector<bool> useTrack;
499 std::vector<GTrackID> gidsITS;
500 int ntr = pv.getNContributors(), ntrIni = ntr;
502 useTrack.reserve(ntr);
503 gidsITS.reserve(ntr);
506 int itr = vtref.getFirstEntry(), itLim = itr + vtref.getEntries();
507 for (; itr < itLim; itr++) {
508 auto tid = trackIndex[itr];
515 useTrack.resize(ntr);
517#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
519 for (
int itr = 0; itr < ntr; itr++) {
520 if (!(useTrack[itr] = refitITStrack(tracks[itr], gidsITS[itr]))) {
525 for (
auto v : useTrack) {
529 LOGP(warn,
"Abandon vertex refit: NcontribNew = {} vs NcontribOld = {}", ntr, ntrIni);
532 LOGP(
debug,
"Original vtx: Nc:{} {}, chi2={}", pv.getNContributors(), pv.
asString(), pv.getChi2());
535 LOGP(
debug,
"Refitted vtx: Nc:{} {}, chi2={}", ntr, pv.
asString(), pv.getChi2());
536 if (pv.getChi2() < 0.f) {
537 LOGP(warn,
"Failed to refit PV {}", pvSave.asString());
549 auto pid = track.getPID();
550 track = trkITS.getParamOut();
551 track.resetCovariance();
552 track.setCov(track.getQ2Pt() * track.getQ2Pt() * track.getCov()[14], 14);
554 auto nCl = trkITS.getNumberOfClusters();
557 float bz = prop->getNominalBz();
560 for (
int iCl = 0; iCl <
nCl; iCl++) {
561 const auto& cls = mITSClustersArray[itsClRefs[trkITS.getClusterEntry(iCl)]];
562 auto alpha = geom->getSensorRefAlpha(cls.getSensorID());
563 if (!(
params.useStableRef ? track.rotate(
alpha, refLin, bz) : track.rotate(
alpha)) ||
564 !prop->propagateTo(track,
params.useStableRef ? &refLin : nullptr, cls.
getX(), true)) {
565 LOGP(
debug,
"refitITStrack failed on propagation to cl#{}, alpha={}, x={} | {}", iCl,
alpha, cls.getX(), track.asString());
568 if (!track.update(cls)) {
569 LOGP(
debug,
"refitITStrack failed on update with cl#{}, | {}", iCl, track.asString());
579 int np = trc.
points.size();
580 auto pt = trc.
track.getPt();
581 if (pt < params.minPt || pt >
params.maxPt) {
584 for (
int ip = 0; ip < np; ip++) {
585 const auto& pnt = trc.
points[ip];
586 int il = pnt.lr >= 0 ? pnt.lr + 1 : 0;
587 mHMan->
getHisto2F(il * 10 + 0 * 100)->Fill(pnt.phi, pnt.dy);
588 mHMan->
getHisto2F(il * 10 + 0 * 100 + 1000)->Fill(pnt.z, pnt.dy);
589 mHMan->
getHisto2F(il * 10 + 0 * 100 + 2000)->Fill(pt, pnt.dy);
590 mHMan->
getHisto2F(il * 10 + 0 * 100 + 3000)->Fill(trc.
track.getTgl(), pnt.dy);
592 auto pull = pnt.dy / std::sqrt(pnt.sig2y);
593 mHMan->
getHisto2F(il * 10 + 0 * 100 + 5)->Fill(pnt.phi, pull);
594 mHMan->
getHisto2F(il * 10 + 0 * 100 + 5 + 1000)->Fill(pnt.z, pull);
595 mHMan->
getHisto2F(il * 10 + 0 * 100 + 5 + 2000)->Fill(pt, pull);
596 mHMan->
getHisto2F(il * 10 + 0 * 100 + 5 + 3000)->Fill(trc.
track.getTgl(), pull);
598 mHMan->
getHisto2F(il * 10 + 1 * 100)->Fill(pnt.phi, pnt.dz);
599 mHMan->
getHisto2F(il * 10 + 1 * 100 + 1000)->Fill(pnt.z, pnt.dz);
600 mHMan->
getHisto2F(il * 10 + 1 * 100 + 2000)->Fill(pt, pnt.dz);
601 mHMan->
getHisto2F(il * 10 + 1 * 100 + 3000)->Fill(trc.
track.getTgl(), pnt.dz);
603 auto pull = pnt.dz / std::sqrt(pnt.sig2z);
604 mHMan->
getHisto2F(il * 10 + 1 * 100 + 5)->Fill(pnt.phi, pull);
605 mHMan->
getHisto2F(il * 10 + 1 * 100 + 5 + 1000)->Fill(pnt.z, pull);
606 mHMan->
getHisto2F(il * 10 + 1 * 100 + 5 + 2000)->Fill(pt, pull);
607 mHMan->
getHisto2F(il * 10 + 1 * 100 + 5 + 3000)->Fill(trc.
track.getTgl(), pull);
612 for (
int ip = 0; ip < 5; ip++) {
616 mHMan->
getHisto2F(12000 + ip * 10)->Fill(pt, d);
618 float sg = trc.
trIBOut.getCovarElem(ip, ip) + trc.
trOBInw.getCovarElem(ip, ip);
620 auto pull = d / std::sqrt(sg);
623 mHMan->
getHisto2F(12000 + ip * 10 + 5)->Fill(pt, pull);
624 mHMan->
getHisto2F(13000 + ip * 10 + 5)->Fill(trc.
track.getTgl(), pull);
630void CheckResidSpec::bookHistos()
633 mHManV.emplace_back() = std::make_unique<o2::HistoManager>(
"", fmt::format(
"{}_hman.root",
params.outname));
634 mHMan = mHManV.back().get();
635 mHMan->SetName(
params.outname.c_str());
636 auto defLogAxis = [](
float xMn,
float xMx,
int nbin) {
637 if (xMn <= 0 || xMx <= xMn || nbin < 2) {
638 LOGP(fatal,
"Wrong log axis request: xmin = {} xmax = {} nbins = {}", xMn, xMx, nbin);
640 auto dx = std::log(xMx / xMn) / nbin;
641 std::vector<double> xax(nbin + 1);
642 for (
int i = 0;
i <= nbin;
i++) {
643 xax[
i] = xMn * std::exp(dx *
i);
647 float minPt = std::max(0.1f,
params.minPt), maxPt = std::min(50.f,
params.maxPt);
648 auto ptax = defLogAxis(minPt, maxPt,
params.nBinsPt);
650 for (
int il = 0; il < 8; il++) {
651 std::string lrName = il == 0 ?
"Vtx" : fmt::format(
"Lr{}", il - 1);
652 for (
int iyz = 0; iyz < 2; iyz++) {
653 std::string dname = iyz == 0 ?
"dy" :
"dz", dtit = iyz == 0 ?
"#DeltaY" :
"#DeltaZ";
654 auto h2 =
new TH2F(fmt::format(
"{}_{}_{}", dname, lrName,
"phi").c_str(), fmt::format(
"{}_{{{}}} vs {};#phi;{}", dtit, lrName,
"#phi", dtit).c_str(),
params.nBinsPhi, 0, TMath::Pi() * 2,
params.nBinsRes, -
params.maxDYZ[il],
params.maxDYZ[il]);
655 mHMan->
addHisto(h2, il * 10 + iyz * 100);
656 auto h2p =
new TH2F(fmt::format(
"{}_{}_{}_pull", dname, lrName,
"phi").c_str(), fmt::format(
"pull {}_{{{}}} vs {};#phi; pull{}", dtit, lrName,
"phi", dtit).c_str(),
params.nBinsPhi, 0, TMath::Pi() * 2,
params.nBinsRes, -
params.maxPull,
params.maxPull);
657 mHMan->
addHisto(h2p, il * 10 + iyz * 100 + 5);
659 auto hz2 =
new TH2F(fmt::format(
"{}_{}_{}", dname, lrName,
"Z").c_str(), fmt::format(
"{}_{{{}}} vs {};Z;{}", dtit, lrName,
"Z", dtit).c_str(),
params.nBinsZ, -
params.zranges[il],
params.zranges[il],
params.nBinsRes, -
params.maxDYZ[il],
params.maxDYZ[il]);
660 mHMan->
addHisto(hz2, il * 10 + iyz * 100 + 1000);
661 auto hz2p =
new TH2F(fmt::format(
"{}_{}_{}_pull", dname, lrName,
"Z").c_str(), fmt::format(
"pull {}_{{{}}} vs {};Z; pull{}", dtit, lrName,
"Z", dtit).c_str(),
params.nBinsZ, -
params.zranges[il],
params.zranges[il],
params.nBinsRes, -
params.maxPull,
params.maxPull);
662 mHMan->
addHisto(hz2p, il * 10 + iyz * 100 + 5 + 1000);
664 auto hpt2 =
new TH2F(fmt::format(
"{}_{}_{}", dname, lrName,
"Pt").c_str(), fmt::format(
"{}_{{{}}} vs {};p_{{T}};{}", dtit, lrName,
"p_{T}", dtit).c_str(),
params.nBinsPt, ptax.data(),
params.nBinsRes, -
params.maxDYZ[il],
params.maxDYZ[il]);
665 mHMan->
addHisto(hpt2, il * 10 + iyz * 100 + 2000);
666 auto hpt2p =
new TH2F(fmt::format(
"{}_{}_{}_pull", dname, lrName,
"Pt").c_str(), fmt::format(
"pull {}_{{{}}} vs {};p_{{T}}; pull{}", dtit, lrName,
"p_{T}", dtit).c_str(),
params.nBinsPt, ptax.data(),
params.nBinsRes, -
params.maxPull,
params.maxPull);
667 mHMan->
addHisto(hpt2p, il * 10 + iyz * 100 + 5 + 2000);
669 auto htgl2 =
new TH2F(fmt::format(
"{}_{}_{}", dname, lrName,
"tgl").c_str(), fmt::format(
"{}_{{{}}} vs {};tg#lambda;{}", dtit, lrName,
"tg#lambda", dtit).c_str(),
params.nBinsTgl, -
params.maxTgl,
params.maxTgl,
params.nBinsRes, -
params.maxDYZ[il],
params.maxDYZ[il]);
670 mHMan->
addHisto(htgl2, il * 10 + iyz * 100 + 3000);
671 auto htgl2p =
new TH2F(fmt::format(
"{}_{}_{}_pull", dname, lrName,
"tgl").c_str(), fmt::format(
"pull {}_{{{}}} vs {};tg#lambda; pull{}", dtit, lrName,
"tg#lambda", dtit).c_str(),
params.nBinsTgl, -
params.maxTgl,
params.maxTgl,
params.nBinsRes, -
params.maxPull,
params.maxPull);
672 mHMan->
addHisto(htgl2p, il * 10 + iyz * 100 + 5 + 3000);
676 for (
int ip = 0; ip < 5; ip++) {
677 auto h2 =
new TH2F(fmt::format(
"dPar{}_IBOBphi", ip).c_str(), fmt::format(
"#Delta par{} IB-OB vs phi;#phi;#Delta par{}", ip, ip).c_str(),
params.nBinsPhi, 0, TMath::Pi() * 2,
params.nBinsRes, -
params.maxDPar[ip],
params.maxDPar[ip]);
678 mHMan->
addHisto(h2, 10000 + ip * 10);
679 auto h2p =
new TH2F(fmt::format(
"dPar{}_IBOBphi_pull", ip).c_str(), fmt::format(
"pull #Delta par{} IB-OB vs phi;#phi;pull #Delta par{}", ip, ip).c_str(),
params.nBinsPhi, 0, TMath::Pi() * 2,
params.nBinsRes, -
params.maxPull,
params.maxPull);
680 mHMan->
addHisto(h2p, 10000 + ip * 10 + 5);
682 auto hz2 =
new TH2F(fmt::format(
"dPar{}_IBOBz", ip).c_str(), fmt::format(
"#Delta par{} IB-OB vs Z;Z;#Delta par{}", ip, ip).c_str(),
params.nBinsZ, -20., 20.,
params.nBinsRes, -
params.maxDPar[ip],
params.maxDPar[ip]);
683 mHMan->
addHisto(hz2, 11000 + ip * 10);
684 auto hz2p =
new TH2F(fmt::format(
"dPar{}_IBOBz_pull", ip).c_str(), fmt::format(
"pull #Delta par{} IB-OB vs Z;Z;pull #Delta par{}", ip, ip).c_str(),
params.nBinsZ, -20., 20.,
params.nBinsRes, -
params.maxPull,
params.maxPull);
685 mHMan->
addHisto(hz2p, 11000 + ip * 10 + 5);
687 auto hpt2 =
new TH2F(fmt::format(
"dPar{}_IBOBpt", ip).c_str(), fmt::format(
"#Delta par{} IB-OB vs pT;p_{{T}};#Delta par{}", ip, ip).c_str(),
params.nBinsPt, ptax.data(),
params.nBinsRes, -
params.maxDPar[ip],
params.maxDPar[ip]);
688 mHMan->
addHisto(hpt2, 12000 + ip * 10);
689 auto hpt2p =
new TH2F(fmt::format(
"dPar{}_IBOBpt_pull", ip).c_str(), fmt::format(
"pull #Delta par{} IB-OB vs pT;p_{{T}};pull #Delta par{}", ip, ip).c_str(),
params.nBinsPt, ptax.data(),
params.nBinsRes, -
params.maxPull,
params.maxPull);
690 mHMan->
addHisto(hpt2p, 12000 + ip * 10 + 5);
692 auto htgl2 =
new TH2F(fmt::format(
"dPar{}_IBOBtgl", ip).c_str(), fmt::format(
"#Delta par{} IB-OB vs tg#lambda;tg#lambda;#Delta par{}", ip, ip).c_str(),
params.nBinsTgl, -
params.maxTgl,
params.maxTgl,
params.nBinsRes, -
params.maxDPar[ip],
params.maxDPar[ip]);
693 mHMan->
addHisto(htgl2, 13000 + ip * 10);
694 auto htgl2p =
new TH2F(fmt::format(
"dPar{}_IBOBtgl_pull", ip).c_str(), fmt::format(
"pull #Delta par{} IB-OB vs tg#lambda;tg#lambda;pull #Delta par{}", ip, ip).c_str(),
params.nBinsTgl, -
params.maxTgl,
params.maxTgl,
params.nBinsRes, -
params.maxPull,
params.maxPull);
695 mHMan->
addHisto(htgl2p, 13000 + ip * 10 + 5);
699void CheckResidSpec::postProcessHistos()
701 printf(
"Fitting histos\n");
703 if (mHManV.empty()) {
704 LOGP(warn,
"nothing to process");
707 mHMan = mHManV[0].get();
710 auto gs =
new TF1(
"gs",
"gaus", -1, 1);
711 int maxH = mPostProcOnly ? mHManV.size() : 1;
713 for (
int ihm = 0; ihm < maxH; ihm++) {
714 auto* histm = mHManV[ihm].get();
715 auto fitSlices = [&](
int id) {
716 auto h2 = histm->getHisto2F(
id);
717 if (!h2 || h2->GetEntries() <
params.minHistoStat2Fit) {
720 h2->FitSlicesY(gs, 0, -1, 0,
"QNR", &arr);
722 TH1* hmean = (TH1*)arr.RemoveAt(1);
724 hmean->SetTitle(Form(
"<%s>", h2->GetTitle()));
725 histm->addHisto(hmean,
id + 1);
727 TH1* hsig = (TH1*)arr.RemoveAt(2);
729 hsig->SetTitle(Form(
"#sigma(%s)", h2->GetTitle()));
730 histm->addHisto(hsig,
id + 2);
733 for (
int ioffs = 0; ioffs <= 3; ioffs++) {
734 int offs = ioffs * 1000;
735 for (
int iht = 0; iht < 2; iht++) {
736 int offsV = iht == 0 ? 0 : 5;
737 for (
int il = 0; il < 8; il++) {
738 for (
int iyz = 0; iyz < 2; iyz++) {
739 fitSlices(il * 10 + iyz * 100 + offsV + offs);
742 for (
int ip = 0; ip < 5; ip++) {
743 fitSlices(10000 + ip * 10 + offsV + offs);
752void CheckResidSpec::drawHistos()
754 gROOT->SetBatch(
true);
755 gStyle->SetTitleX(0.2);
756 gStyle->SetTitleY(0.88);
757 gStyle->SetTitleW(0.25);
758 gStyle->SetOptStat(0);
759 int nhm = mHManV.size();
760 std::array<unsigned int, 3> hcol{EColor::kRed, EColor::kBlue, EColor::kGreen + 2};
761 std::unique_ptr<TLegend> lg;
762 lg = std::make_unique<TLegend>(0.12, 0.13, 0.9, 0.13 + std::min(0.5f, nhm * 0.2f / 3.f));
764 lg->SetBorderSize(0);
765 for (
int i = 0;
i < nhm;
i++) {
766 auto hman = mHManV[
i].get();
767 if (!hman || hman->GetLast() < 1) {
770 hman->setMarkerStyle(20 +
i + (
i % 2) * 4, 0.5);
771 hman->setColor(hcol[
i % hcol.size()]);
772 auto le = lg->AddEntry(hman->getHisto(1), hman->GetName(),
"lp");
773 le->SetTextColor(hcol[
i % hcol.size()]);
775 TCanvas cly(
"cly",
"", 600, 800), clz(
"clz",
"", 600, 800), clpar(
"clpar",
"", 600, 800);
776 TCanvas czly(
"czly",
"", 600, 800), czlz(
"czlz",
"", 600, 800), czlpar(
"czlpar",
"", 600, 800);
779 auto AddLabel = [](
const char* txt,
float x = 0.1,
float y = 0.9,
int color = kBlack,
float size = 0.04) {
780 TLatex* lt =
new TLatex(
x,
y, txt);
782 lt->SetTextColor(
color);
783 lt->SetTextSize(
size);
788 auto drawResLr = [
this](TCanvas& canv,
int offs,
const float resMM[8],
bool logX) {
791 int nh = this->mHManV.size();
792 for (
int i = 0;
i < 8;
i++) {
795 for (
int j = 0;
j < nh;
j++) {
796 auto hman = this->mHManV[
j].get();
797 if (!hman || hman->GetLast() < 1) {
800 if (
auto histo = hman->getHisto(10 *
i + offs)) {
801 histo->Draw(same ?
"same" :
"");
803 histo->SetMinimum(-resMM[
i]);
804 histo->SetMaximum(resMM[
i]);
814 auto drawResPar = [
this](TCanvas& canv,
int offs,
const float resMM[8],
bool logX) {
817 int nh = this->mHManV.size();
818 for (
int i = 0;
i < 5;
i++) {
821 for (
int j = 0;
j < nh;
j++) {
822 auto hman = this->mHManV[
j].get();
823 if (!hman || hman->GetLast() < 1) {
826 if (
auto histo = hman->getHisto(10 *
i + offs)) {
827 histo->Draw(same ?
"same" :
"");
829 histo->SetMinimum(-resMM[
i]);
830 histo->SetMaximum(resMM[
i]);
840 cly.Print(Form(
"%s_hman.pdf[",
params.outname.c_str()));
841 drawResLr(cly, 1,
params.resMMLrY,
false);
844 AddLabel(
"Y residuals", 0.1, 0.95);
845 cly.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
847 drawResLr(clz, 101,
params.resMMLrZ,
false);
850 AddLabel(
"Z residuals", 0.1, 0.95);
851 clz.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
853 drawResLr(czly, 1001,
params.resMMLrY,
false);
856 AddLabel(
"Y residuals", 0.1, 0.95);
857 czly.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
859 drawResLr(czlz, 1101,
params.resMMLrZ,
false);
862 AddLabel(
"Z residuals", 0.1, 0.95);
863 czlz.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
865 drawResLr(czly, 2001,
params.resMMLrY,
true);
868 AddLabel(
"Y residuals", 0.1, 0.95);
869 czly.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
871 drawResLr(czlz, 2101,
params.resMMLrZ,
true);
874 AddLabel(
"Z residuals", 0.1, 0.95);
875 czlz.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
877 drawResLr(czly, 3001,
params.resMMLrY,
false);
880 AddLabel(
"Y residuals", 0.1, 0.95);
881 czly.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
883 drawResLr(czlz, 3101,
params.resMMLrZ,
false);
886 AddLabel(
"Z residuals", 0.1, 0.95);
887 czlz.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
889 drawResPar(clpar, 10001,
params.resMMPar,
false);
892 AddLabel(
"IB-OB tracks params differences at R = 12 cm", 0.2, 0.8);
893 clpar.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
895 drawResPar(czlpar, 11001,
params.resMMPar,
false);
898 AddLabel(
"IB-OB tracks params differences at R = 12 cm", 0.2, 0.8);
899 czlpar.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
901 drawResPar(czlpar, 12001,
params.resMMPar,
true);
904 AddLabel(
"IB-OB tracks params differences at R = 12 cm", 0.2, 0.8);
905 czlpar.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
907 drawResPar(czlpar, 13001,
params.resMMPar,
false);
910 AddLabel(
"IB-OB tracks params differences at R = 12 cm", 0.2, 0.8);
911 czlpar.Print(Form(
"%s_hman.pdf",
params.outname.c_str()));
913 cly.Print(Form(
"%s_hman.pdf]",
params.outname.c_str()));
935 mMeanVertexUpdated =
true;
939 LOG(info) <<
"cluster dictionary updated";
947 std::vector<OutputSpec> outputs;
948 auto dataRequest = std::make_shared<DataRequest>();
949 if (!drawOnly && !postProcOnly) {
951 dataRequest->requestTracks(srcTracks, useMC);
952 dataRequest->requestClusters(srcClusters, useMC);
953 dataRequest->requestPrimaryVertices(useMC);
954 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
956 auto ggRequest = drawOnly ? std::make_shared<o2::base::GRPGeomRequest>(
false,
false,
false,
false,
false,
o2::base::GRPGeomRequest::None, dataRequest->inputs) : std::make_shared<o2::base::GRPGeomRequest>(
false,
962 dataRequest->inputs,
true);
966 {
"nthreads", VariantType::Int, 1, {
"number of threads"}},
967 {
"no-tree", VariantType::Bool,
false, {
"do not fill residuals tree"}},
968 {
"no-hist", VariantType::Bool,
false, {
"do not fill residuals histograms"}},
969 {
"draw-report", VariantType::Bool,
false, {
"fill residuals report"}},
977 AlgorithmSpec{adaptFromTask<CheckResidSpec>(dataRequest, ggRequest, srcTracks, drawOnly, postProcOnly)},
Definition of the GeometryManager class.
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the GeometryTGeo class.
Utility functions for MC particles.
Definition of the Names Generator class.
Wrapper container for different reconstructed object types.
o2::track::TrackParCov TrackParCov
Result of refitting TPC-ITS matched track.
Reference on ITS/MFT clusters set.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
void setSensorID(std::int16_t sid)
void setXYZ(T x, T y, T z)
int addHisto(TH1 *histo, int at=-1)
TH2F * getHisto2F(int id) const
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
~CheckResidSpec() final=default
void run(ProcessingContext &pc) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
CheckResidSpec(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, GTrackID::mask_t src, bool drawOnly, bool postProcOnly)
void init(InitContext &ic) final
static const CheckResidConfig & Instance()
static void updateFromString(std::string const &)
Static class with identifiers, bitmasks and names for ALICE detectors.
T get(const char *key) const
ServiceRegistryRef services()
ConfigParamRegistry const & options()
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static GeometryTGeo * Instance()
int getClusterEntry(int i) const
void initMeanVertexConstraint()
PVertex refitVertexFull(const std::vector< bool > useTrack, const o2d::VertexBase &vtxSeed)
bool prepareVertexRefit(const TR &tracks, const o2d::VertexBase &vtxSeed)
void setMeanVertex(const o2d::MeanVertexObject *v)
GLfloat GLfloat GLfloat alpha
GLenum const GLfloat * params
o2::framework::DataProcessorSpec getCheckResidSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool drawOnly, bool postProcOnly)
create a processor spec
constexpr double LHCBunchSpacingNS
Defining ITS Vertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const itsmft::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints
int int int float float float int nCl
const TrackingFrameInfo *const const Cluster *const const float const float bz
double * getX(double *xyDxy, int N)
double * getY(double *xyDxy, int N)
struct o2::upgrades_utils::@469 tracks
structure to keep trigger-related info
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
o2::track::TrackPar track
o2::track::TrackParCov trIBOut
o2::track::TrackParCov trOBInw
std::vector< Point > points
auto getITSTracks() const
GTrackID getITSContributorGID(GTrackID source) const
bool isTrackSourceLoaded(int src) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
auto getITSTracksClusterRefs() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getPrimaryVertexMatchedTrackRefs() const
auto getITSClustersPatterns() const
GTrackID getTPCContributorGID(GTrackID source) const
const o2::track::TrackParCov & getTrackParam(GTrackID gidx) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
auto getITSClusters() const
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"