30 #include <TRotation.h>
32 #include <TObjString.h>
40 #include <Eigen/Dense>
45 #include <tracking/calibration/BeamSpotStandAlone.h>
46 #include <tracking/calibration/Splitter.h>
47 #include <tracking/calibration/tools.h>
49 #include <BeamSpotStandAlone.h>
57 using Eigen::VectorXd;
58 using Eigen::Vector3d;
59 using Eigen::MatrixXd;
60 using Eigen::Matrix3d;
63 namespace Belle2::BeamSpotCalib {
66 inline double sqrS(
double x) {
return x >= 0 ? x * x : -x * x; }
67 inline double sqrtS(
double x) {
return x >= 0 ? sqrt(x) : -sqrt(-x); }
69 MatrixXd getRotatedSizeMatrix(vector<double> xySize,
double zzSize,
double kX,
double kY);
101 SpotParam(
const vector<double>& vals,
const vector<double>& errs,
const vector<vector<double>>& spls,
int order = 0)
103 auto getSize = [order](
const vector<double>& sp) {
108 B2ASSERT(
"There must be least one node at this place", sp.size() >= 1);
109 return int(sp.size() + 1);
110 }
else if (order == 1) {
111 B2ASSERT(
"Must be at least two nodes in lin. spline", sp.size() >= 2);
112 return int(sp.size());
114 B2FATAL(
"Unknown order");
119 int nx = getSize(spls[0]);
120 int ny = getSize(spls[1]);
123 x.vals =
slice(vals, 0, nx);
124 y.vals =
slice(vals, nx, ny);
125 x.errs =
slice(errs, 0, nx);
126 y.errs =
slice(errs, nx, ny);
128 if (spls.size() >= 4) {
129 int nkx = getSize(spls[2]);
130 int nky = getSize(spls[3]);
134 kY.
vals =
slice(vals, nx + ny + nkx, nky);
137 kY.
errs =
slice(errs, nx + ny + nkx, nky);
139 if (spls.size() >= 5) {
140 int nz = getSize(spls[4]);
142 z.vals =
slice(vals, nx + ny + nkx + nky, nz);
143 z.errs =
slice(errs, nx + ny + nkx + nky, nz);
162 int nNd = spls[0].
vals.size();
163 for (
int k = 0; k < nNd; ++k) {
164 double s = 0, ss = 0;
165 for (
unsigned i = 0; i < spls.size(); ++i) {
166 s += spls[i].vals[k];
170 for (
unsigned i = 0; i < spls.size(); ++i) {
171 ss += pow(spls[i].vals[k] - s, 2);
175 ss = sqrt(ss / (spls.size() - 1));
192 double indx = (spls.size() - 1) * v;
193 int nNd = spls[0].vals.size();
194 for (
int k = 0; k < nNd; ++k) {
196 for (
unsigned i = 0; i < spls.size(); ++i) {
197 vals.push_back(spls[i].vals[k]);
199 sort(vals.begin(), vals.end());
203 sLim.
vals[k] = vals[I] * (1 - r) + vals[I + 1] * r;
217 void add(
double x) { vars.push_back(x); }
222 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
223 return accumulate(vars.begin(), vars.end(), 0.) / vars.size();
229 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
230 double m = getMean();
235 return sqrt(s / (vars.size() - 1));
243 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
244 double indx = (vars.size() - 1) * v;
245 sort(vars.begin(), vars.end());
248 return vars[I] * (1 - r) + vars[I + 1] * r;
254 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
255 B2INFO(n <<
" : " << getMean() <<
"+-" << getSigma() <<
" : " << getLimit(0.50) <<
" (" << getLimit(0.16) <<
" , " << getLimit(
262 return {getLimit(0.50), getLimit(0.16), getLimit(1 - 0.16)};
273 double getAngle(
double SizeX,
double SizeY,
double SizeXY)
275 double C = sqrS(SizeXY);
278 double angle = 1. / 2 * atan2(2 * C, (pow(SizeX, 2) - pow(SizeY, 2)));
289 pair<double, double> getSizeMinMax(
double SizeX,
double SizeY,
double SizeXY)
291 double A = pow(SizeX, 2) + pow(SizeY, 2);
292 double B = pow(SizeX, 2) * pow(SizeY, 2) - pow(SizeXY, 4);
293 double D = pow(A, 2) - 4 * B;
296 B2FATAL(
"Problem with D value : " << D);
299 double Size2Min = 2 * B / (A + sqrt(D));
300 if (abs(Size2Min) < 1e-7) Size2Min = 0;
302 B2FATAL(
"Negative BS eigen size : " << Size2Min);
304 double Size2Max = (A + sqrt(D)) / 2;
305 return {sqrtS(Size2Min), sqrtS(Size2Max)};
315 double getSize2MinMat(
double SizeXX,
double SizeYY,
double SizeXY)
317 double A = SizeXX + SizeYY;
318 double B = SizeXX * SizeYY - pow(SizeXY, 2);
319 double D = pow(A, 2) - 4 * B;
322 B2FATAL(
"Problem with D value : " << D);
325 double Size2Min = 2 * B / (A + sqrt(D));
361 void add(
SpotParam sPar,
double SizeX,
double SizeY,
double SizeXY,
double SizeZ)
377 double SizeMin, SizeMax;
378 tie(SizeMin, SizeMax) = getSizeMinMax(SizeX, SizeY, SizeXY);
380 sizeMin.
add(SizeMin);
381 sizeMax.
add(SizeMax);
384 double angle = 1e3 * getAngle(SizeX, SizeY, SizeXY);
390 MatrixXd matSize = getRotatedSizeMatrix({sqrS(SizeX), sqrS(SizeY), sqrS(SizeXY)}, sqrS(SizeZ), sPar.
kX.
val(sPar.
kX.
center()),
394 matXX.
add(sqrtS(matSize(0, 0)));
395 matYY.
add(sqrtS(matSize(1, 1)));
396 matZZ.
add(sqrtS(matSize(2, 2)));
397 matXY.
add(sqrtS(matSize(0, 1)));
399 matXZ.
add(sqrtS(matSize(0, 2)));
400 matYZ.
add(sqrtS(matSize(1, 2)));
404 double crossAngleVal = 1e3 * 2 * sqrtS(matSize(0, 0)) / sqrtS(matSize(2, 2));
405 crossAngle.
add(crossAngleVal);
411 x.getMeanSigma().print(
"x");
412 y.getMeanSigma().print(
"y");
415 z.getMeanSigma().print(
"z");
438 void getOutput(vector<VectorXd>& vtxPos, vector<MatrixXd>& vtxErr, MatrixXd& sizeMat)
441 int nVals = x.spls[0].vals.size();
446 const double toCm = 1e-4;
448 for (
int i = 0; i < nVals; ++i) {
450 Vector3d vtx(x.spls[0].vals[i]*toCm, y.spls[0].vals[i]*toCm, z.spls[0].vals[i]*toCm);
453 Matrix3d mS = Matrix3d::Zero();
454 mS(0, 0) = sqrS(x.spls[0].errs[i] * toCm);
455 mS(1, 1) = sqrS(y.spls[0].errs[i] * toCm);
456 mS(2, 2) = sqrS(z.spls[0].errs[i] * toCm);
458 vtxPos.push_back(vtx);
459 vtxErr.push_back(mS);
464 sizeMat.resize(3, 3);
465 sizeMat(0, 0) = sqrS(matXX.
vars[0] * toCm);
466 sizeMat(1, 1) = sqrS(matYY.
vars[0] * toCm);
467 sizeMat(2, 2) = sqrS(matZZ.
vars[0] * toCm);
469 sizeMat(0, 1) = sqrS(matXY.
vars[0] * toCm);
470 sizeMat(0, 2) = sqrS(matXZ.
vars[0] * toCm);
471 sizeMat(1, 2) = sqrS(matYZ.
vars[0] * toCm);
473 sizeMat(1, 0) = sizeMat(0, 1);
474 sizeMat(2, 0) = sizeMat(0, 2);
475 sizeMat(2, 1) = sizeMat(1, 2);
482 T->Branch(n, &vec->at(0), n +
"/D");
483 T->Branch(n +
"_low", &vec->at(1), n +
"_low/D");
484 T->Branch(n +
"_high", &vec->at(2), n +
"_high/D");
490 T->Branch(n +
"_nodes", &spl->
nodes);
491 T->Branch(n +
"_vals", &spl->
vals);
492 T->Branch(n +
"_errs", &spl->
errs);
501 TTree* T =
new TTree(
"runs",
"beam conditions of runs");
504 T->Branch(
"run", &run,
"run/I");
506 Spline xAvg = x.getMeanSigma();
507 setBranchSpline(T, &xAvg,
"x");
508 Spline yAvg = y.getMeanSigma();
509 setBranchSpline(T, &yAvg,
"y");
510 Spline zAvg = z.getMeanSigma();
511 setBranchSpline(T, &zAvg,
"z");
514 setBranchSpline(T, &kxAvg,
"kX");
516 setBranchSpline(T, &kyAvg,
"kY");
518 vector<double> sizeXVar = sizeX.
getStats();
519 setBranchVal(T, &sizeXVar,
"sizeX");
520 vector<double> sizeYVar = sizeY.
getStats();
521 setBranchVal(T, &sizeYVar,
"sizeY");
522 vector<double> sizeXYVar = sizeXY.
getStats();
523 setBranchVal(T, &sizeXYVar,
"sizeXY");
524 vector<double> sizeZVar = sizeZ.
getStats();
525 setBranchVal(T, &sizeZVar,
"sizeZ");
527 vector<double> sizeMinVar = sizeMin.
getStats();
528 setBranchVal(T, &sizeMinVar,
"sizeMin");
529 vector<double> sizeMaxVar = sizeMax.
getStats();
530 setBranchVal(T, &sizeMaxVar,
"sizeMax");
531 vector<double> xyAngleVar = xyAngle.
getStats();
532 setBranchVal(T, &xyAngleVar,
"xyAngle");
534 vector<double> crossAngleVar = crossAngle.
getStats();
535 setBranchVal(T, &crossAngleVar,
"crossAngle");
538 vector<double> matXXVar = matXX.
getStats();
539 vector<double> matYYVar = matYY.
getStats();
540 vector<double> matZZVar = matZZ.
getStats();
541 vector<double> matXYVar = matXY.
getStats();
542 vector<double> matXZVar = matXZ.
getStats();
543 vector<double> matYZVar = matYZ.
getStats();
545 setBranchVal(T, &matXXVar,
"matXX");
546 setBranchVal(T, &matYYVar,
"matYY");
547 setBranchVal(T, &matZZVar,
"matZZ");
549 setBranchVal(T, &matXYVar,
"matXY");
550 setBranchVal(T, &matXZVar,
"matXZ");
551 setBranchVal(T, &matYZVar,
"matYZ");
569 double getZIPest(
const Track& tr,
double t,
const SpotParam& spotPar,
int nestMax = 5,
int nest = 0)
572 if (nest < nestMax) {
573 double zIP = getZIPest(tr, t, spotPar, nestMax, nest + 1);
575 x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
576 y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
578 x0 = spotPar.x.val(t);
579 y0 = spotPar.y.val(t);
582 double f0 = tr.tanlambda * (x0 * cos(tr.phi0) + y0 * sin(tr.phi0));
594 double getCorrD(
const Track& tr,
double t,
const SpotParam& spotPar)
596 double zIP = getZIPest(tr, t, spotPar);
598 double x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
599 double y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
601 double f0 = x0 * sin(tr.phi0) - y0 * cos(tr.phi0);
607 double getDtimeConst(
const Track& tr,
double t,
const SpotParam& spotPar)
609 double zIP = getZIPest(tr, t, spotPar);
610 double zIPM = getZIPest(tr, spotPar.z.center(), spotPar);
612 double x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
613 double y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
615 double xM = spotPar.x.val(spotPar.x.center()) + spotPar.kX.val(spotPar.kX.center()) * (zIPM - spotPar.z.val(spotPar.z.center()));
616 double yM = spotPar.y.val(spotPar.y.center()) + spotPar.kY.val(spotPar.kY.center()) * (zIPM - spotPar.z.val(spotPar.z.center()));
619 double f0 = (x0 - xM) * sin(tr.phi0) - (y0 - yM) * cos(tr.phi0);
631 double getCorrZ(
const Track& tr,
double t,
const SpotParam& spotPar)
633 double zIP = getZIPest(tr, t, spotPar);
635 double x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
636 double y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
637 double z0 = spotPar.z.val(t);
639 double f0 = z0 - tr.tanlambda * (x0 * cos(tr.phi0) + y0 * sin(tr.phi0));
652 pair<double, double> getStartStop(
const vector<Event>& evts)
654 double minT = 1e20, maxT = -1e20;
655 for (
auto ev : evts) {
656 minT = min(minT, ev.t);
657 maxT = max(maxT, ev.t);
663 vector<TString> extractFileNames(TString str)
665 vector<TString> files;
666 auto tempVec = str.Tokenize(
",");
667 for (
int i = 0; i < tempVec->GetEntries(); ++i) {
668 TString s = ((TObjString*)tempVec->At(i))->GetString();
669 files.push_back(s.Strip());
675 vector<Event> getEvents(TTree* tr)
678 vector<Event> events;
679 events.reserve(tr->GetEntries());
683 tr->SetBranchAddress(
"run", &evt.run);
684 tr->SetBranchAddress(
"exp", &evt.exp);
685 tr->SetBranchAddress(
"event", &evt.evtNo);
686 tr->SetBranchAddress(
"mu0_d0", &evt.mu0.d0);
687 tr->SetBranchAddress(
"mu1_d0", &evt.mu1.d0);
688 tr->SetBranchAddress(
"mu0_z0", &evt.mu0.z0);
689 tr->SetBranchAddress(
"mu1_z0", &evt.mu1.z0);
691 tr->SetBranchAddress(
"mu0_tanlambda", &evt.mu0.tanlambda);
692 tr->SetBranchAddress(
"mu1_tanlambda", &evt.mu1.tanlambda);
695 tr->SetBranchAddress(
"mu0_phi0", &evt.mu0.phi0);
696 tr->SetBranchAddress(
"mu1_phi0", &evt.mu1.phi0);
698 tr->SetBranchAddress(
"time", &evt.t);
701 for (
int i = 0; i < tr->GetEntries(); ++i) {
707 events.push_back(evt);
711 sort(events.begin(), events.end(), [](Event e1, Event e2) {return e1.t < e2.t;});
718 void bootStrap(vector<Event>& evts)
721 e.nBootStrap = gRandom->Poisson(1);
732 VectorXd linearFit(MatrixXd mat, VectorXd r)
734 MatrixXd matT = mat.transpose();
735 MatrixXd A = matT * mat;
737 VectorXd v = matT * r;
738 MatrixXd Ainv = A.inverse();
751 pair<vector<double>, vector<double>> linearFitErr(MatrixXd m, VectorXd r,
double& err2Mean,
double& err2press,
double& err2pressErr)
753 MatrixXd mT = m.transpose();
754 MatrixXd mat = mT * m;
757 MatrixXd A = mat * mT;
758 VectorXd res = A * r;
759 VectorXd dataH = m * res;
763 double err2 = (dataH - r).squaredNorm() / (r.rows() - res.rows());
771 for (
int i = 0; i < r.rows(); ++i) {
773 for (
int k = 0; k < m.cols(); ++k)
774 Ahat += m(i, k) * A(k, i);
776 double v = pow((r(i) - dataH(i)) / (1 - Ahat), 2);
781 press2 /= (r.rows() - 1);
784 err2pressErr = sqrt((press2 - press * press) / r.rows()) / sqrt(r.rows());
789 MatrixXd AT = A.transpose();
790 MatrixXd errMat = err2 * A * AT;
791 VectorXd errs2(errMat.rows());
792 for (
int i = 0; i < errs2.rows(); ++i)
793 errs2(i) = errMat(i, i);
809 VectorXd linearFitPos(MatrixXd mat, VectorXd r)
811 const double s2MinLimit = pow(0.05, 2);
812 B2ASSERT(
"Matrix size for size fit should be 3", mat.cols() == 3);
813 MatrixXd matT = mat.transpose();
814 MatrixXd A = matT * mat;
815 VectorXd v = matT * r;
816 MatrixXd Ainv = A.inverse();
818 VectorXd pars = Ainv * v;
821 double s2Min = getSize2MinMat(pars[0], pars[1], pars[2]);
822 if (pars[0] >= 0 && pars[1] >= 0 && s2Min >= s2MinLimit)
829 int nDf = r.rows() - 3;
831 double err2 = (mat * pars - r).squaredNorm() / nDf;
833 MatrixXd wMat = Ainv * matT;
834 MatrixXd wMatT = wMat.transpose();
836 MatrixXd covMat = err2 * wMat * wMatT;
837 MatrixXd covMatI = covMat.inverse();
844 TF2 fEig(
rn(), [covMatI, pars, s2MinLimit](
double * x,
double*) {
846 double eig2 = s2MinLimit;
852 xVec[0] = eig1 * c * c + eig2 * s * s;
853 xVec[1] = eig1 * s * s + eig2 * c * c;
854 xVec[2] = s * c * (eig1 - eig2);
857 double res = (xVec - pars).transpose() * covMatI * (xVec - pars);
859 }, s2MinLimit, 400, 0, 2 * M_PI, 0);
862 fEig.GetMinimumXY(eigHigh, phi);
864 pars[0] = eigHigh * pow(cos(phi), 2) + s2MinLimit * pow(sin(phi), 2);
865 pars[1] = eigHigh * pow(sin(phi), 2) + s2MinLimit * pow(cos(phi), 2);
866 pars[2] = sin(phi) * cos(phi) * (eigHigh - s2MinLimit);
877 TH1D* getResolution(TH2D* hRes)
879 TH1D* hSigmaAll =
new TH1D(
rn(),
"", 50, -M_PI, M_PI);
880 for (
int i = 1; i <= hRes->GetNbinsX(); ++i) {
881 TH1D* hProj = hRes->ProjectionY(
rn(), i, i);
882 double rms = hProj->GetRMS();
883 double rmsErr = hProj->GetRMSError();
884 hSigmaAll->SetBinContent(i, rms * rms);
885 hSigmaAll->SetBinError(i, 2 * abs(rms)*rmsErr);
891 TH1D* getMean(
const TH2D* hRes)
893 TH1D* hMean =
new TH1D(
rn(),
"", 50, -M_PI, M_PI);
894 for (
int i = 1; i <= hRes->GetNbinsX(); ++i) {
895 TH1D* hProj = hRes->ProjectionY(
rn(), i, i);
896 double mean = hProj->GetMean();
897 double meanErr = hProj->GetMeanError();
898 hMean->SetBinContent(i, mean);
899 hMean->SetBinError(i, meanErr);
905 double getD12th(Event e, vector<double> sizesXY)
907 double sxx = sizesXY[0];
908 double syy = sizesXY[1];
909 double sxy = sizesXY[2];
911 double cc = cos(e.mu0.phi0) * cos(e.mu1.phi0);
912 double ss = sin(e.mu0.phi0) * sin(e.mu1.phi0);
913 double sc = -(sin(e.mu0.phi0) * cos(e.mu1.phi0) + sin(e.mu1.phi0) * cos(e.mu0.phi0));
915 return ss * sxx + cc * syy + sc * sxy;
919 double getZ12th(Event e, vector<double> sizesXY)
921 double sxx = sizesXY[0];
922 double syy = sizesXY[1];
924 double corr = e.mu0.tanlambda * e.mu1.tanlambda * (sxx * cos(e.mu0.phi0) * cos(e.mu1.phi0) + syy * sin(e.mu0.phi0) * sin(
926 + (sin(e.mu0.phi0) * cos(e.mu1.phi0) + cos(e.mu0.phi0) * sin(e.mu1.phi0)));
936 void plotSpotPositionFit(
const vector<Event>& evts, SpotParam par, TString fName)
938 TGraph* gr =
new TGraph();
939 TProfile* dProf =
new TProfile(
rn(),
"dProf", 100, -M_PI, M_PI,
"S");
940 TProfile* dProfRes =
new TProfile(
rn(),
"dProfRes", 100, -M_PI, M_PI,
"S");
942 for (
auto e : evts) {
943 if (!e.isSig)
continue;
945 double d1 = getDtimeConst(e.mu0, e.t, par);
946 double d2 = getDtimeConst(e.mu1, e.t, par);
948 gr->SetPoint(gr->GetN(), e.mu0.phi0, d1);
949 gr->SetPoint(gr->GetN(), e.mu1.phi0, d2);
951 dProf->Fill(e.mu0.phi0, d1);
952 dProf->Fill(e.mu1.phi0, d2);
955 double d1c = getCorrD(e.mu0, e.t, par);
956 double d2c = getCorrD(e.mu1, e.t, par);
958 dProfRes->Fill(e.mu0.phi0, d1c);
959 dProfRes->Fill(e.mu1.phi0, d2c);
961 TF1* f =
new TF1(
rn(),
"[0]*sin(x) - [1]*cos(x)", -M_PI, M_PI);
962 f->SetParameters(par.x.val(par.x.center()), par.y.val(par.y.center()));
964 TCanvas* c =
new TCanvas(
rn(),
"");
966 gr->GetXaxis()->SetRangeUser(-M_PI, M_PI);
967 gr->SetMaximum(+1.3 * f->GetMaximum());
968 gr->SetMinimum(-1.3 * f->GetMaximum());
970 gr->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
971 gr->GetYaxis()->SetTitle(
"d_{0} [#mum]");
974 c->SaveAs(fName +
"_dots.pdf");
977 TCanvas* d =
new TCanvas(
rn(),
"");
978 gStyle->SetOptStat(0);
980 dProf->GetXaxis()->SetRangeUser(-M_PI, M_PI);
981 dProf->SetMaximum(+1.3 * f->GetMaximum());
982 dProf->SetMinimum(-1.3 * f->GetMaximum());
984 dProf->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
985 dProf->GetYaxis()->SetTitle(
"d_{0} [#mum]");
989 B2INFO(
"Saving " << fName <<
" prof ");
990 d->SaveAs(fName +
"_prof.pdf");
993 TCanvas* e =
new TCanvas(
rn(),
"");
994 gStyle->SetOptStat(0);
996 dProfRes->GetXaxis()->SetRangeUser(-M_PI, M_PI);
998 dProfRes->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
999 dProfRes->GetYaxis()->SetTitle(
"d_{0} res [#mum]");
1001 TH1D* errP =
new TH1D(
rn(),
"dErrP", 100, -M_PI, M_PI);
1002 TH1D* errM =
new TH1D(
rn(),
"dErrM", 100, -M_PI, M_PI);
1003 for (
int i = 1; i <= errP->GetNbinsX(); ++i) {
1004 errP->SetBinContent(i, dProfRes->GetBinError(i));
1005 errM->SetBinContent(i, -dProfRes->GetBinError(i));
1008 errP->Draw(
"hist same");
1009 errM->Draw(
"hist same");
1011 f->SetParameters(0, 0);
1014 B2INFO(
"Saving " << fName <<
" profRes ");
1015 e->SaveAs(fName +
"_profRes.pdf");
1021 void plotSpotZPositionFit(
const vector<Event>& evts, SpotParam par, TString fName)
1023 TProfile* zProf =
new TProfile(
rn(),
"dProf", 100, -M_PI, M_PI,
"S");
1024 TGraph* gr =
new TGraph();
1025 for (
auto e : evts) {
1026 if (!e.isSig)
continue;
1029 double z1ip = getZIPest(e.mu0, e.t, par);
1030 double z2ip = getZIPest(e.mu1, e.t, par);
1032 double zipT = par.z.val(e.t);
1033 double zipM = par.z.val(par.z.center());
1035 double val1 = z1ip - (zipT - zipM);
1036 double val2 = z2ip - (zipT - zipM);
1038 gr->SetPoint(gr->GetN(), e.mu0.phi0, val1);
1039 gr->SetPoint(gr->GetN(), e.mu1.phi0, val2);
1041 zProf->Fill(e.mu0.phi0, val1);
1042 zProf->Fill(e.mu1.phi0, val2);
1044 TF1* f =
new TF1(
rn(),
"[0]", -M_PI, M_PI);
1045 f->SetParameter(0, par.z.val(par.z.center()));
1047 TCanvas* c =
new TCanvas(
rn(),
"");
1048 c->SetLeftMargin(0.12);
1050 gr->GetXaxis()->SetRangeUser(-M_PI, M_PI);
1051 gr->SetMaximum(1000);
1052 gr->SetMinimum(-1000);
1054 gr->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1055 gr->GetYaxis()->SetTitle(
"z_{IP} estimate [#mum]");
1058 c->SaveAs(fName +
"_dots.pdf");
1061 TCanvas* d =
new TCanvas(
rn(),
"");
1062 gStyle->SetOptStat(0);
1063 d->SetLeftMargin(0.12);
1065 zProf->GetXaxis()->SetRangeUser(-M_PI, M_PI);
1066 zProf->SetMaximum(1000);
1067 zProf->SetMinimum(-1000);
1069 zProf->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1070 zProf->GetYaxis()->SetTitle(
"z_{IP} estimate [#mum]");
1073 d->SaveAs(fName + +
"_prof.pdf");
1082 void plotSpotPositionPull(
const vector<Event>& evts,
const SpotParam& par, TString fName,
double cut = 70)
1084 TH1D* hPull =
new TH1D(
rn(),
"", 200, -200, 200);
1086 for (
auto& e : evts) {
1087 if (!e.isSig)
continue;
1089 double d0 = getCorrD(e.mu0, e.t, par);
1090 double d1 = getCorrD(e.mu1, e.t, par);
1096 TCanvas* c =
new TCanvas(
rn(),
"");
1097 gStyle->SetOptStat(2210);
1100 hPull->GetXaxis()->SetTitle(
"pull [#mum]");
1101 hPull->GetYaxis()->SetTitle(
"#tracks");
1103 TLine* l =
new TLine;
1104 l->SetLineColor(kRed);
1105 l->DrawLine(-cut, 0, -cut, 500);
1106 l->DrawLine(+cut, 0, +cut, 500);
1108 c->SaveAs(fName +
".pdf");
1113 void plotKxKyFit(
const vector<Event>& evts, SpotParam par, TString fName)
1115 TProfile* profRes =
new TProfile(
rn(),
"dProf", 100, -800, 800,
"S");
1116 TProfile* profResKx =
new TProfile(
rn(),
"dProfKx", 100, -800, 800,
"S");
1117 TProfile* profResKy =
new TProfile(
rn(),
"dProfKy", 100, -800, 800,
"S");
1119 SpotParam parNoKx = par;
1120 SpotParam parNoKy = par;
1121 parNoKx.kX.vals = {0};
1122 parNoKy.kY.vals = {0};
1123 parNoKx.kX.nodes = {};
1124 parNoKy.kY.nodes = {};
1126 for (
auto& e : evts) {
1127 if (!e.isSig)
continue;
1129 double zDiff1 = getZIPest(e.mu0, e.t, par) - par.z.val(e.t);
1130 double zDiff2 = getZIPest(e.mu1, e.t, par) - par.z.val(e.t);
1133 double d1 = getCorrD(e.mu0, e.t, par);
1134 double d2 = getCorrD(e.mu1, e.t, par);
1136 double d1KX = getCorrD(e.mu0, e.t, parNoKx);
1137 double d2KX = getCorrD(e.mu1, e.t, parNoKx);
1140 profResKx->Fill(zDiff1 * sin(e.mu0.phi0), d1KX);
1141 profResKx->Fill(zDiff2 * sin(e.mu1.phi0), d2KX);
1143 double d1KY = getCorrD(e.mu0, e.t, parNoKy);
1144 double d2KY = getCorrD(e.mu1, e.t, parNoKy);
1145 profResKy->Fill(-zDiff1 * cos(e.mu0.phi0), d1KY);
1146 profResKy->Fill(-zDiff2 * cos(e.mu1.phi0), d2KY);
1148 profRes->Fill(zDiff1, d1);
1149 profRes->Fill(zDiff2, d2);
1154 TCanvas* cX =
new TCanvas(
rn(),
"");
1155 gStyle->SetOptStat(0);
1158 profResKx->GetXaxis()->SetTitle(
"(z_{IP} - z_{IP}^{0}) sin #phi_{0} [#mum]");
1159 profResKx->GetYaxis()->SetTitle(
"d_{0} res [#mum]");
1161 TF1* f =
new TF1(
rn(),
"[0]*x", -800, 800);
1162 f->SetParameter(0, par.kX.val(par.kX.center()));
1165 cX->SaveAs(fName +
"_kX.pdf");
1167 TCanvas* cY =
new TCanvas(
rn(),
"");
1168 gStyle->SetOptStat(0);
1171 profResKy->GetXaxis()->SetTitle(
"-(z_{IP} - z_{IP}^{0}) cos #phi_{0} [#mum]");
1172 profResKy->GetYaxis()->SetTitle(
"d_{0} res [#mum]");
1174 f->SetParameter(0, par.kY.val(par.kY.center()));
1177 cY->SaveAs(fName +
"_kY.pdf");
1183 void plotXYtimeDep(
const vector<Event>& evts, SpotParam par, TString fName)
1185 TProfile* profRes =
new TProfile(
rn(),
"dProf", 50, -0.5, 0.5);
1186 TProfile* profResTx =
new TProfile(
rn(),
"dProfTx", 50, -0.5, 0.5);
1187 TProfile* profResTy =
new TProfile(
rn(),
"dProfTy", 50, -0.5, 0.5);
1189 SpotParam parNoTx = par;
1190 SpotParam parNoTy = par;
1191 parNoTx.x.nodes = {};
1192 parNoTx.x.vals = {par.x.val(par.x.center())};
1193 parNoTy.y.nodes = {};
1194 parNoTy.y.vals = {par.y.val(par.y.center())};
1196 for (
auto& e : evts) {
1197 if (!e.isSig)
continue;
1199 double tDiff = (e.t - par.x.val(par.x.center()));
1203 double d1 = getCorrD(e.mu0, e.t, par);
1204 double d2 = getCorrD(e.mu1, e.t, par);
1206 double d1TX = getCorrD(e.mu0, e.t, parNoTx);
1207 double d2TX = getCorrD(e.mu1, e.t, parNoTx);
1209 profResTx->Fill(tDiff * sin(e.mu0.phi0), d1TX);
1210 profResTx->Fill(tDiff * sin(e.mu1.phi0), d2TX);
1212 double d1TY = getCorrD(e.mu0, e.t, parNoTy);
1213 double d2TY = getCorrD(e.mu1, e.t, parNoTy);
1215 profResTy->Fill(-tDiff * cos(e.mu0.phi0), d1TY);
1216 profResTy->Fill(-tDiff * cos(e.mu1.phi0), d2TY);
1219 profRes->Fill(tDiff * sin(e.mu0.phi0), d1);
1220 profRes->Fill(tDiff * sin(e.mu1.phi0), d2);
1225 TCanvas* cX =
new TCanvas(
rn(),
"");
1226 gStyle->SetOptStat(0);
1230 TF1* f =
new TF1(
rn(),
"[0]*x", -1, 1);
1231 f->SetParameter(0, (par.x.val(1) - par.x.val(0)));
1233 B2INFO(
"Table value " << par.x.val(1) - par.x.val(0));
1235 cX->SaveAs(fName +
"_tX.pdf");
1245 void plotSpotZpositionPull(
const vector<Event>& evts,
const SpotParam& par, TString fName,
double cut = 1000)
1247 TH1D* hPull =
new TH1D(
rn(),
"", 200, -2000, 2000);
1249 for (
auto& e : evts) {
1250 if (!e.isSig)
continue;
1252 double z0 = getCorrZ(e.mu0, e.t, par);
1253 double z1 = getCorrZ(e.mu1, e.t, par);
1259 gStyle->SetOptStat(2210);
1260 TCanvas* c =
new TCanvas(
rn(),
"");
1263 hPull->GetXaxis()->SetTitle(
"pull [#mum]");
1264 hPull->GetYaxis()->SetTitle(
"#tracks");
1266 TLine* l =
new TLine;
1267 l->SetLineColor(kRed);
1268 l->DrawLine(-cut, 0, -cut, 500);
1269 l->DrawLine(+cut, 0, +cut, 500);
1271 c->SaveAs(fName +
".pdf");
1276 void removeSpotPositionOutliers(vector<Event>& evts,
const SpotParam& par,
double cut = 70)
1280 for (
auto& e : evts) {
1281 if (!e.isSig)
continue;
1283 double d0 = getCorrD(e.mu0, e.t, par);
1284 double d1 = getCorrD(e.mu1, e.t, par);
1286 e.isSig = abs(d0) < cut && abs(d1) < cut;
1290 B2INFO(
"Removed fraction Position " << nRem / (nAll + 0.));
1295 void removeSpotZpositionOutliers(vector<Event>& evts,
const SpotParam& par,
double cut = 1000)
1299 for (
auto& e : evts) {
1300 if (!e.isSig)
continue;
1302 double z0 = getCorrZ(e.mu0, e.t, par);
1303 double z1 = getCorrZ(e.mu1, e.t, par);
1305 e.isSig = abs(z0) < cut && abs(z1) < cut;
1309 B2INFO(
"Removed fraction Position " << nRem / (nAll + 0.));
1315 vector<vector<double>> fillSplineBasesLinear(
const vector<Event>& evts, vector<double> spl,
1316 std::function<
double(Track,
double)> fun)
1319 if (n == 0 || (n == 2 && spl[0] > spl[1]))
1322 vector<vector<double>> vecs(n);
1325 for (
const auto& e : evts) {
1326 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1327 vecs[0].push_back(1 * fun(e.mu0, e.t));
1328 vecs[0].push_back(1 * fun(e.mu1, e.t));
1332 for (
int k = 0; k < n; ++k) {
1333 double xCnt = spl[k];
1334 double xLow = (k == 0) ? spl[0] : spl[k - 1];
1335 double xHigh = (k == n - 1) ? spl[n - 1] : spl[k + 1];
1337 for (
const auto& e : evts) {
1340 if (xLow <= x && x < xCnt)
1341 v = (x - xLow) / (xCnt - xLow);
1342 else if (xCnt < x && x <= xHigh)
1343 v = (xHigh - x) / (xHigh - xCnt);
1346 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1347 vecs[k].push_back(v * fun(e.mu0, e.t));
1348 vecs[k].push_back(v * fun(e.mu1, e.t));
1359 vector<vector<double>> fillSplineBasesZero(
const vector<Event>& evts, vector<double> spl, std::function<
double(Track,
double)> fun)
1361 int n = spl.size() + 1;
1363 vector<vector<double>> vecs(n);
1366 for (
const auto& e : evts) {
1367 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1368 vecs[0].push_back(1 * fun(e.mu0, e.t));
1369 vecs[0].push_back(1 * fun(e.mu1, e.t));
1373 for (
int k = 0; k < n; ++k) {
1374 double xLow = -1e30;
1375 double xHigh = +1e30;
1379 }
else if (k == n - 1) {
1386 for (
const auto& e : evts) {
1389 if (xLow <= x && x < xHigh)
1392 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1393 vecs[k].push_back(v * fun(e.mu0, e.t));
1394 vecs[k].push_back(v * fun(e.mu1, e.t));
1409 double compareSplines(
const Spline& spl1,
const Spline& spl2)
1413 double step = 0.001;
1414 for (
double x = 0; x <= 1 + step / 2; x += step) {
1415 double v1 = spl1.val(x);
1416 double e1 = spl1.err(x);
1417 double v2 = spl2.val(x);
1418 double e2 = spl2.err(x);
1420 double d = pow(v2 - v1, 2) / pow(max(e1, e2), 2);
1427 double fitSpotZwidth(
const vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY)
1430 vector<double> dataVec;
1431 vector<double> zzVec;
1434 for (
auto e : evts) {
1435 double z0 = getCorrZ(e.mu0, e.t, spotPar);
1436 double z1 = getCorrZ(e.mu1, e.t, spotPar);
1438 double corr = getZ12th(e, sizesXY);
1439 double z0z1Corr = z0 * z1 - corr;
1442 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1443 dataVec.push_back(z0z1Corr);
1450 vector<double> pars, err2;
1451 double err2Mean, err2press, err2pressErr;
1452 tie(pars, err2) = linearFitErr(mat,
vec2vec(dataVec), err2Mean, err2press, err2pressErr);
1462 SpotParam fitSpotPositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY,
1463 const vector<double>& splKX,
const vector<double>& splKY)
1465 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return sin(tr.phi0);});
1466 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -cos(tr.phi0);});
1468 vector<vector<double>> basesKX = fillSplineBasesZero(evts, splKX, [](Track tr,
double) {
return sin(tr.phi0) * tr.z0;});
1469 vector<vector<double>> basesKY = fillSplineBasesZero(evts, splKY, [](Track tr,
double) {
return -cos(tr.phi0) * tr.z0;});
1472 vector<double> dataVec;
1473 for (
auto e : evts) {
1474 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1475 dataVec.push_back(e.mu0.d0);
1476 dataVec.push_back(e.mu1.d0);
1480 vector<vector<double>> allVecs =
merge({basesX, basesY, basesKX, basesKY});
1485 VectorXd vData =
vec2vec(dataVec);
1487 vector<double> pars(A.cols()), err2(A.cols());
1488 double err2Mean, err2press, err2pressErr;
1489 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1491 for (
auto& e : err2) e = sqrt(e);
1492 return SpotParam(pars, err2, {splX, splY, splKX, splKY});
1496 SpotParam fitSpotPositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY,
1497 const vector<double>& splKX,
const vector<double>& splKY,
const SpotParam& spotPars)
1499 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return sin(tr.phi0);});
1500 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -cos(tr.phi0);});
1502 vector<vector<double>> basesKX = fillSplineBasesZero(evts, splKX, [ = ](Track tr,
double t) {
return sin(tr.phi0) * (getZIPest(tr, t, spotPars) - spotPars.z.val(t));});
1503 vector<vector<double>> basesKY = fillSplineBasesZero(evts, splKY, [ = ](Track tr,
double t) {
return -cos(tr.phi0) * (getZIPest(tr, t, spotPars) - spotPars.z.val(t));});
1506 vector<double> dataVec;
1507 for (
auto e : evts) {
1508 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1509 dataVec.push_back(e.mu0.d0);
1510 dataVec.push_back(e.mu1.d0);
1514 vector<vector<double>> allVecs =
merge({basesX, basesY, basesKX, basesKY});
1519 VectorXd vData =
vec2vec(dataVec);
1521 vector<double> pars(A.cols()), err2(A.cols());
1522 double err2Mean, err2press, err2pressErr;
1523 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1525 for (
auto& e : err2) e = sqrt(e);
1526 auto res = SpotParam(pars, err2, {splX, splY, splKX, splKY});
1536 SpotParam fitSpotPositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY)
1538 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return sin(tr.phi0);});
1539 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -cos(tr.phi0);});
1541 vector<double> dataVec;
1542 for (
auto e : evts) {
1543 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1544 dataVec.push_back(e.mu0.d0);
1545 dataVec.push_back(e.mu1.d0);
1549 vector<vector<double>> allVecs =
merge({basesX, basesY});
1553 VectorXd vData =
vec2vec(dataVec);
1555 vector<double> pars(A.cols()), err2(A.cols());
1556 double err2Mean, err2press, err2pressErr;
1557 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1559 for (
auto& e : err2) e = sqrt(e);
1560 return SpotParam(pars, err2, {splX, splY});
1569 SpotParam fitZpositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY,
1570 const vector<double>& splKX,
const vector<double>& splKY,
1571 const vector<double>& splZ)
1573 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return -tr.tanlambda * cos(tr.phi0);});
1574 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -tr.tanlambda * sin(tr.phi0);});
1576 vector<vector<double>> basesKX = fillSplineBasesZero(evts, splKX, [](Track tr,
double) {
return -tr.z0 * tr.tanlambda * cos(tr.phi0);});
1577 vector<vector<double>> basesKY = fillSplineBasesZero(evts, splKY, [](Track tr,
double) {
return -tr.z0 * tr.tanlambda * sin(tr.phi0);});
1579 vector<vector<double>> basesZ = fillSplineBasesZero(evts, splZ, [](Track ,
double) {
return 1;});
1582 vector<double> dataVec;
1583 for (
auto e : evts) {
1584 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1585 dataVec.push_back(e.mu0.z0);
1586 dataVec.push_back(e.mu1.z0);
1590 vector<vector<double>> allVecs =
merge({basesX, basesY, basesKX, basesKY, basesZ});
1594 VectorXd vData =
vec2vec(dataVec);
1596 vector<double> pars(A.cols()), err2(A.cols());
1597 double err2Mean, err2press, err2pressErr;
1598 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1600 for (
auto& e : err2) e = sqrt(e);
1601 return SpotParam(pars, err2, {splX, splY, splKX, splKY, splZ});
1607 SpotParam fitZpositionSplinesSimple(
const vector<Event>& evts,
const vector<double>& splZ,
const SpotParam& spotPars)
1609 vector<vector<double>> basesZ = fillSplineBasesZero(evts, splZ, [](Track,
double) {
return 1;});
1611 vector<double> dataVec;
1612 for (
auto e : evts) {
1613 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1614 double z1 = getZIPest(e.mu0, e.t, spotPars);
1615 double z2 = getZIPest(e.mu1, e.t, spotPars);
1616 dataVec.push_back(z1);
1617 dataVec.push_back(z2);
1623 VectorXd vData =
vec2vec(dataVec);
1625 vector<double> pars(A.cols()), err2(A.cols());
1626 double err2Mean, err2press, err2pressErr;
1627 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1629 for (
auto& e : err2) e = sqrt(e);
1631 SpotParam parsUpd = spotPars;
1632 parsUpd.z.vals = pars;
1633 parsUpd.z.errs = err2;
1634 parsUpd.z.nodes = splZ;
1642 vector<double> fitSpotWidthCMS(
const vector<Event>& evts,
const SpotParam& spotPar)
1645 vector<double> dataVec, ccVec, ssVec, scVec;
1648 for (
auto e : evts) {
1649 double d0 = getCorrD(e.mu0, e.t, spotPar);
1650 double d1 = getCorrD(e.mu1, e.t, spotPar);
1652 for (
int i = 0; i < e.nBootStrap * e.isSig; ++i) {
1653 dataVec.push_back(d0 * d1);
1655 ccVec.push_back(cos(e.mu0.phi0)*cos(e.mu1.phi0));
1656 ssVec.push_back(sin(e.mu0.phi0)*sin(e.mu1.phi0));
1657 scVec.push_back(-(sin(e.mu0.phi0)*cos(e.mu1.phi0) + sin(e.mu1.phi0)*cos(e.mu0.phi0)));
1662 MatrixXd mat =
vecs2mat({ssVec, ccVec, scVec});
1665 VectorXd resPhys = linearFitPos(mat,
vec2vec(dataVec));
1667 return {resPhys(0), resPhys(1), resPhys(2)};
1672 void plotSpotSizePull(
const vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY)
1674 TH1D* hPull =
new TH1D(
rn(),
"", 100, -2000, 2000);
1675 for (
auto& e : evts) {
1676 if (!e.isSig)
continue;
1678 double d0 = getCorrD(e.mu0, e.t, spotPar);
1679 double d1 = getCorrD(e.mu1, e.t, spotPar);
1681 double d12Th = getD12th(e, sizesXY);
1683 hPull->Fill(d0 * d1 - d12Th);
1685 TCanvas* c =
new TCanvas(
rn(),
"");
1687 c->SaveAs(
"pullsSize.pdf");
1692 void plotSpotSizeZPull(
const vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY,
double sizeZZ)
1694 TH1D* hPull =
new TH1D(
rn(),
"", 100, -300e3, 600e3);
1695 for (
auto& e : evts) {
1696 if (!e.isSig)
continue;
1698 double z0 = getCorrZ(e.mu0, e.t, spotPar);
1699 double z1 = getCorrZ(e.mu1, e.t, spotPar);
1701 double corr = getZ12th(e, sizesXY);
1702 double res = z0 * z1 - corr - sizeZZ;
1707 gStyle->SetOptStat(2210);
1708 TCanvas* c =
new TCanvas(
rn(),
"");
1710 B2INFO(
"zSizeFit mean " << hPull->GetMean());
1711 B2INFO(
"zSizeFit rms " << hPull->GetRMS());
1713 c->SaveAs(
"pullsZSize.pdf");
1720 void plotSpotSizeFit(
const vector<Event>& evts,
const SpotParam& par,
const vector<double>& sizeXY)
1722 double sxx = sizeXY[0];
1723 double syy = sizeXY[1];
1724 double sxy = sizeXY[2];
1726 gStyle->SetOptStat(0);
1728 TProfile* profSxx =
new TProfile(
rn(),
"", 50, -1, 1);
1729 TProfile* profSyy =
new TProfile(
rn(),
"", 50, -1, 1);
1730 TProfile* profSxy =
new TProfile(
rn(),
"", 50, -1, 1);
1731 for (
auto e : evts) {
1732 if (!e.isSig)
continue;
1734 double cc = cos(e.mu0.phi0) * cos(e.mu1.phi0);
1735 double ss = sin(e.mu0.phi0) * sin(e.mu1.phi0);
1736 double sc = - (sin(e.mu0.phi0) * cos(e.mu1.phi0) + sin(e.mu1.phi0) * cos(e.mu0.phi0));
1738 double d0 = getCorrD(e.mu0, e.t, par);
1739 double d1 = getCorrD(e.mu1, e.t, par);
1741 double data = d0 * d1;
1743 profSxx->Fill(ss, data - syy * cc - sxy * sc);
1744 profSyy->Fill(cc, data - sxx * ss - sxy * sc);
1745 profSxy->Fill(sc, data - syy * cc - sxx * ss);
1748 TCanvas* c =
new TCanvas(
rn(),
"", 1200, 500);
1752 profSxx->GetXaxis()->SetTitle(
"sin #phi_{1} sin #phi_{2}");
1753 profSxx->GetYaxis()->SetTitle(
"#LTd_{1} d_{2}#GT - corr_{xx} [#mum^{2}]");
1754 TF1* fxx =
new TF1(
rn(),
"[0]*x", -1, 1);
1755 fxx->SetParameter(0, sxx);
1760 profSyy->GetXaxis()->SetTitle(
"cos #phi_{1} cos #phi_{2}");
1761 profSyy->GetYaxis()->SetTitle(
"#LTd_{1} d_{2}#GT - corr_{yy} [#mum^{2}]");
1762 TF1* fyy =
new TF1(
rn(),
"[0]*x", -1, 1);
1763 fyy->SetParameter(0, syy);
1768 profSxy->GetXaxis()->SetTitle(
"-(sin #phi_{1} cos #phi_{2} + sin #phi_{2} cos #phi_{1})");
1769 profSxy->GetYaxis()->SetTitle(
"#LTd_{1} d_{2}#GT - corr_{xy} [#mum^{2}]");
1770 TF1* fxy =
new TF1(
rn(),
"[0]*x", -1, 1);
1771 fxy->SetParameter(0, sxy);
1774 c->SaveAs(
"SizeFit.pdf");
1779 void plotSpotZSizeFit(
const vector<Event>& evts,
const SpotParam& par,
const vector<double>& sizesXY,
double sizeZZ)
1782 gStyle->SetOptStat(0);
1785 TProfile* zzProfPhi =
new TProfile(
rn(),
"", 100, -M_PI, M_PI);
1786 TProfile* zzProfXX =
new TProfile(
rn(),
"", 100, -M_PI / 4, 2 * M_PI);
1787 TProfile* zzProfYY =
new TProfile(
rn(),
"", 100, -M_PI / 4, 2 * M_PI);
1788 TProfile* zzProfXY =
new TProfile(
rn(),
"", 100, -2 * M_PI, 2 * M_PI);
1789 TProfile* zzProfXZ =
new TProfile(
rn(),
"", 100, -2 * M_PI, 2 * M_PI);
1790 TProfile* zzProfYZ =
new TProfile(
rn(),
"", 100, -2 * M_PI, 2 * M_PI);
1793 for (
auto e : evts) {
1794 double z0 = getCorrZ(e.mu0, e.t, par);
1795 double z1 = getCorrZ(e.mu1, e.t, par);
1797 double corr = getZ12th(e, sizesXY);
1798 double z0z1Corr = z0 * z1 - corr;
1802 double xx = e.mu0.tanlambda * e.mu1.tanlambda * cos(e.mu0.phi0) * cos(e.mu1.phi0);
1803 double yy = e.mu0.tanlambda * e.mu1.tanlambda * sin(e.mu0.phi0) * sin(e.mu1.phi0);
1804 double xy = e.mu0.tanlambda * e.mu1.tanlambda * (sin(e.mu0.phi0) * cos(e.mu1.phi0) + cos(e.mu0.phi0) * sin(e.mu1.phi0));
1805 double xz = - (e.mu0.tanlambda * cos(e.mu0.phi0) + e.mu1.tanlambda * cos(e.mu1.phi0));
1806 double yz = - (e.mu0.tanlambda * sin(e.mu0.phi0) + e.mu1.tanlambda * sin(e.mu1.phi0));
1809 zzProfPhi->Fill(e.mu0.phi0, z0z1Corr);
1810 zzProfPhi->Fill(e.mu1.phi0, z0z1Corr);
1811 zzProfXX->Fill(xx, z0z1Corr);
1812 zzProfYY->Fill(yy, z0z1Corr);
1813 zzProfXY->Fill(xy, z0z1Corr);
1814 zzProfXZ->Fill(xz, z0z1Corr);
1815 zzProfYZ->Fill(yz, z0z1Corr);
1819 TF1* f =
new TF1(
rn(),
"[0]", -2 * M_PI, 2 * M_PI);
1820 f->SetParameter(0, sizeZZ);
1822 TCanvas* c =
new TCanvas(
rn(),
"", 1200, 500);
1826 zzProfPhi->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1827 zzProfPhi->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1832 zzProfXX->GetXaxis()->SetTitle(
"xx sensitive");
1833 zzProfXX->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1838 zzProfYY->GetXaxis()->SetTitle(
"yy sensitive");
1839 zzProfYY->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1844 zzProfXY->GetXaxis()->SetTitle(
"xy sensitive");
1845 zzProfXY->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1850 zzProfXZ->GetXaxis()->SetTitle(
"xz sensitive");
1851 zzProfXZ->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1856 zzProfYZ->GetXaxis()->SetTitle(
"yz sensitive");
1857 zzProfYZ->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1860 c->SaveAs(
"SizeZFit.pdf");
1866 void removeSpotSizeOutliers(vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY,
double cut = 1500)
1871 for (
auto& e : evts) {
1872 if (!e.isSig)
continue;
1874 double d0 = getCorrD(e.mu0, e.t, spotPar);
1875 double d1 = getCorrD(e.mu1, e.t, spotPar);
1876 double d12Th = getD12th(e, sizesXY);
1878 e.isSig = abs(d0 * d1 - d12Th) < cut;
1882 B2INFO(
"Removed fraction Size " << nRem / (nAll + 0.));
1887 void removeSpotSizeZOutliers(vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY,
double sizeZZ,
1888 double cut = 150000)
1893 for (
auto& e : evts) {
1894 if (!e.isSig)
continue;
1896 double z0 = getCorrZ(e.mu0, e.t, spotPar);
1897 double z1 = getCorrZ(e.mu1, e.t, spotPar);
1899 double corr = getZ12th(e, sizesXY);
1900 double res = z0 * z1 - corr - sizeZZ;
1903 e.isSig = abs(res) < cut;
1907 B2INFO(
"Removed fraction Size " << nRem / (nAll + 0.));
1912 MatrixXd toMat(TRotation rot)
1914 MatrixXd rotM(3, 3);
1915 rotM(0, 0) = rot.XX();
1916 rotM(0, 1) = rot.XY();
1917 rotM(0, 2) = rot.XZ();
1918 rotM(1, 0) = rot.YX();
1919 rotM(1, 1) = rot.YY();
1920 rotM(1, 2) = rot.YZ();
1921 rotM(2, 0) = rot.ZX();
1922 rotM(2, 1) = rot.ZY();
1923 rotM(2, 2) = rot.ZZ();
1936 MatrixXd getRotatedSizeMatrix(vector<double> xySize,
double zzSize,
double kX,
double kY)
1942 MatrixXd rotM = toMat(rot);
1943 MatrixXd rotMT = rotM.transpose();
1945 Matrix3d eigenMat = Matrix3d::Zero();
1946 eigenMat(0, 0) = xySize[0];
1947 eigenMat(1, 1) = xySize[1];
1948 eigenMat(0, 1) = xySize[2];
1949 eigenMat(1, 0) = xySize[2];
1950 eigenMat(2, 2) = zzSize;
1952 return (rotM * eigenMat * rotMT);
1962 tuple<vector<VectorXd>, vector<MatrixXd>, MatrixXd> runBeamSpotAnalysis(vector<Event> evts,
1963 const vector<double>& splitPoints)
1965 const double xyPosLimit = 70;
1966 const double xySize2Limit = pow(40, 2);
1967 const double zPosLimit = 1200;
1970 vector<double> indX = splitPoints;
1971 vector<double> indY = splitPoints;
1972 vector<double> indZ = splitPoints;
1975 vector<double> indKX = {};
1976 vector<double> indKY = {};
1978 UnknownPars allPars;
1979 const int kPlot = -1;
1980 for (
int k = 0; k < 1; ++k) {
1981 for (
auto& e : evts) e.isSig =
true;
1982 if (k != 0) bootStrap(evts);
1986 auto resTemp = fitSpotPositionSplines(evts, indX, indY);
1989 plotSpotPositionFit(evts, resTemp,
"positionFitSimpe");
1990 plotSpotPositionPull(evts, resTemp,
"pullsPositionSimple", xyPosLimit);
1992 removeSpotPositionOutliers(evts, resTemp, xyPosLimit);
1995 auto resFin = fitSpotPositionSplines(evts, indX, indY);
1997 plotSpotPositionFit(evts, resFin,
"positionFitSimpleC");
1998 plotSpotPositionPull(evts, resFin,
"pullsPositionSimpleC", xyPosLimit);
1999 plotXYtimeDep(evts, resFin,
"simplePosTimeDep");
2003 auto resZmy = fitZpositionSplinesSimple(evts, indZ, resFin);
2005 plotSpotZPositionFit(evts, resZmy,
"positionFitSimpleZ");
2006 plotSpotZpositionPull(evts, resZmy,
"zPositionPull", zPosLimit);
2009 removeSpotZpositionOutliers(evts, resZmy, zPosLimit);
2012 resZmy = fitZpositionSplinesSimple(evts, indZ, resZmy);
2016 auto resNew = fitSpotPositionSplines(evts, indX, indY, indKX, indKY, resZmy);
2018 plotSpotPositionFit(evts, resNew,
"positionFitFull");
2019 plotKxKyFit(evts, resNew,
"slopes");
2023 resZmy = fitZpositionSplinesSimple(evts, indZ, resNew);
2024 if (k == kPlot) plotSpotZPositionFit(evts, resZmy,
"positionFitSimpleZLast");
2028 resNew = fitSpotPositionSplines(evts, indX, indY, indKX, indKY, resZmy);
2031 resZmy = fitZpositionSplinesSimple(evts, indZ, resNew);
2032 resNew = fitSpotPositionSplines(evts, indX, indY, indKX, indKY, resZmy);
2036 auto vecXY = fitSpotWidthCMS(evts, resNew);
2037 if (k == kPlot) plotSpotSizePull(evts, resNew, vecXY);
2038 removeSpotSizeOutliers(evts, resNew, vecXY, xySize2Limit);
2039 vecXY = fitSpotWidthCMS(evts, resNew);
2040 if (k == kPlot) plotSpotSizeFit(evts, resNew, vecXY);
2044 double sizeZZ = fitSpotZwidth(evts, resNew, vecXY);
2047 plotSpotZSizeFit(evts, resNew, vecXY, sizeZZ);
2048 plotSpotSizeZPull(evts, resNew, vecXY, sizeZZ);
2054 allPars.add(resNew, sqrtS(vecXY[0]), sqrtS(vecXY[1]), sqrtS(vecXY[2]), sqrtS(sizeZZ));
2060 vector<VectorXd> vtxPos;
2061 vector<MatrixXd> vtxErr;
2064 allPars.getOutput(vtxPos, vtxErr, sizeMat);
2066 return make_tuple(vtxPos, vtxErr, sizeMat);
Class that bundles various TrackFitResults.
TString rn()
Get random string.
std::vector< Atom > slice(std::vector< Atom > vec, int s, int e)
Slice the vector to contain only elements with indexes s .. e (included)
std::vector< std::vector< double > > merge(std::vector< std::vector< std::vector< double >>> toMerge)
merge { vector<double> a, vector<double> b} into {a, b}
Eigen::MatrixXd vecs2mat(std::vector< std::vector< double >> vecs)
merge columns (from std::vectors) into ROOT matrix
Eigen::VectorXd vec2vec(std::vector< double > vec)
std vector -> ROOT vector
const std::vector< double > v2
MATLAB generated random vector.
const std::vector< double > v1
MATLAB generated random vector.
structure containing most of the beam spot parameters
void print()
Print BeamSpot parameters.
Spline z
spline for BS center position as a function of time (z coordinate)
Spline x
spline for BS center position as a function of time (x coordinate)
Spline kX
spline for BS angle in the xz plane as a function of time
SpotParam(const vector< double > &vals, const vector< double > &errs, const vector< vector< double >> &spls, int order=0)
Constructor based output of the linear regression, assuming zero-order splines vals,...
Spline kY
spline for BS angle in the yz plane as a function of time
Spline y
spline for BS center position as a function of time (y coordinate)
Spline with uncertainty obtained from the boot-strap replicas.
vector< Spline > spls
vector with replicas
void add(Spline spl)
add boot-strap replica
Spline getMeanSigma()
Get mean and 1-sigma errors of the spline values.
Spline getLimit(double v)
quantile of all points in spline, v=0.5 : median, v=0.16: lower 68% bound, v=0.84 : upper 68% bound
variable with uncertainty from boot-strap replicas
double getMean()
Get mean value.
double getLimit(double v)
Get quantile (v=0.5 -> median, v=0.16,v=0.84 68% confidence interval)
void add(double x)
add value to the replicas
vector< double > getStats()
Get basic stats.
vector< double > vars
vector of variable values for all replicas
double getSigma()
Get standard deviation.
void printStat(TString n)
Print variable of name n with stat-info.
structure including all variables of interest with uncertainties from boot-strap
void setBranchVal(TTree *T, vector< double > *vec, TString n)
save bootstrap variable to TTree
UnknowSpline kY
BS angle in yz plane.
UnknowVar crossAngle
derived value of the crossing angle of the HER & LER beams
UnknowVar matZZ
ZZ element of BS size cov matrix.
UnknowVar sizeMin
smallest eigenvalue of the BS size cov matrix (similar to sizeY)
void printStat()
Print interesting statistics from boot-strap.
UnknowVar matYY
YY element of BS size cov matrix.
UnknowVar sizeZ
BS size in z direction.
UnknowSpline z
BS position (z coordinate)
void add(SpotParam sPar, double SizeX, double SizeY, double SizeXY, double SizeZ)
add next boot-strap replica of the BS parameters
void getOutput(vector< VectorXd > &vtxPos, vector< MatrixXd > &vtxErr, MatrixXd &sizeMat)
get output in Belle2-like format
UnknowVar sizeY
BS size in y direction.
UnknowVar matXZ
XZ element of BS size cov matrix.
UnknowVar matXY
XY element of BS size cov matrix.
UnknowSpline y
BS position (y coordinate)
UnknowVar sizeX
BS size in x direction.
UnknowVar matXX
XX element of BS size cov matrix.
void save2tree(TString fName)
save everything to TTree
UnknowVar sizeMax
middle eigenvalue of the BS size cov matrix (similar to sizeX)
void setBranchSpline(TTree *T, Spline *spl, TString n)
save bootstrap spline to TTree
UnknowVar sizeXY
off-diagonal component of BS size cov matrix in frame where z' is aligned with z
UnknowSpline x
BS position (x coordinate)
UnknowVar xyAngle
angle of the BS in xy plane when z' is aligned with z
UnknowVar matYZ
YZ element of BS size cov matrix.
UnknowSpline kX
BS angle in xz plane.
Spline structure for zero-order & linear splines.
double val(double x) const
get value of spline at point x
std::vector< double > nodes
vector of spline nodes
std::vector< double > errs
vector of spline errors
std::vector< double > vals
vector of spline values
void print(TString tag="")
print the spline
double center() const
Get center of the spline domain.