35 #include <TRotation.h>
44 #include <Eigen/Dense>
49 #include <tracking/calibration/BeamSpotStandAlone.h>
50 #include <tracking/calibration/Splitter.h>
51 #include <tracking/calibration/tools.h>
53 #include <BeamSpotStandAlone.h>
61 using Eigen::VectorXd;
62 using Eigen::Vector3d;
63 using Eigen::MatrixXd;
64 using Eigen::Matrix3d;
72 namespace BeamSpotCalib {
75 inline double sqrS(
double x) {
return x >= 0 ? x * x : -x * x; }
76 inline double sqrtS(
double x) {
return x >= 0 ? sqrt(x) : -sqrt(-x); }
78 MatrixXd getRotatedSizeMatrix(vector<double> xySize,
double zzSize,
double kX,
double kY);
110 SpotParam(
const vector<double>& vals,
const vector<double>& errs,
const vector<vector<double>>& spls,
int order = 0)
112 auto getSize = [order](
const vector<double>& sp) {
117 B2ASSERT(
"There must be least one node at this place", sp.size() >= 1);
118 return int(sp.size() + 1);
119 }
else if (order == 1) {
120 B2ASSERT(
"Must be at least two nodes in lin. spline", sp.size() >= 2);
121 return int(sp.size());
123 B2FATAL(
"Unknown order");
128 int nx = getSize(spls[0]);
129 int ny = getSize(spls[1]);
132 x.vals =
slice(vals, 0, nx);
133 y.vals =
slice(vals, nx, ny);
134 x.errs =
slice(errs, 0, nx);
135 y.errs =
slice(errs, nx, ny);
137 if (spls.size() >= 4) {
138 int nkx = getSize(spls[2]);
139 int nky = getSize(spls[3]);
143 kY.
vals =
slice(vals, nx + ny + nkx, nky);
146 kY.
errs =
slice(errs, nx + ny + nkx, nky);
148 if (spls.size() >= 5) {
149 int nz = getSize(spls[4]);
151 z.vals =
slice(vals, nx + ny + nkx + nky, nz);
152 z.errs =
slice(errs, nx + ny + nkx + nky, nz);
164 void add(
Spline spl) { spls.push_back(spl); }
171 int nNd = spls[0].vals.size();
172 for (
int k = 0; k < nNd; ++k) {
173 double s = 0, ss = 0;
174 for (
unsigned i = 0; i < spls.size(); ++i) {
175 s += spls[i].vals[k];
179 for (
unsigned i = 0; i < spls.size(); ++i) {
180 ss += pow(spls[i].vals[k] - s, 2);
184 ss = sqrt(ss / (spls.size() - 1));
201 double indx = (spls.size() - 1) * v;
202 int nNd = spls[0].vals.size();
203 for (
int k = 0; k < nNd; ++k) {
205 for (
unsigned i = 0; i < spls.size(); ++i) {
206 vals.push_back(spls[i].vals[k]);
208 sort(vals.begin(), vals.end());
212 sLim.
vals[k] = vals[I] * (1 - r) + vals[I + 1] * r;
226 void add(
double x) { vars.push_back(x); }
231 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
232 return accumulate(vars.begin(), vars.end(), 0.) / vars.size();
238 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
239 double m = getMean();
244 return sqrt(s / (vars.size() - 1));
252 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
253 double indx = (vars.size() - 1) * v;
254 sort(vars.begin(), vars.end());
257 return vars[I] * (1 - r) + vars[I + 1] * r;
263 B2ASSERT(
"Must be at least one replica", vars.size() >= 1);
264 B2INFO(n <<
" : " << getMean() <<
"+-" << getSigma() <<
" : " << getLimit(0.50) <<
" (" << getLimit(0.16) <<
" , " << getLimit(
271 return {getLimit(0.50), getLimit(0.16), getLimit(1 - 0.16)};
282 double getAngle(
double SizeX,
double SizeY,
double SizeXY)
284 double C = sqrS(SizeXY);
287 double angle = 1. / 2 * atan2(2 * C, (pow(SizeX, 2) - pow(SizeY, 2)));
298 pair<double, double> getSizeMinMax(
double SizeX,
double SizeY,
double SizeXY)
300 double A = pow(SizeX, 2) + pow(SizeY, 2);
301 double B = pow(SizeX, 2) * pow(SizeY, 2) - pow(SizeXY, 4);
302 double D = pow(A, 2) - 4 * B;
305 B2FATAL(
"Problem with D value : " << D);
308 double Size2Min = 2 * B / (A + sqrt(D));
309 if (abs(Size2Min) < 1
e-7) Size2Min = 0;
311 B2FATAL(
"Negative BS eigen size : " << Size2Min);
313 double Size2Max = (A + sqrt(D)) / 2;
314 return {sqrtS(Size2Min), sqrtS(Size2Max)};
324 double getSize2MinMat(
double SizeXX,
double SizeYY,
double SizeXY)
326 double A = SizeXX + SizeYY;
327 double B = SizeXX * SizeYY - pow(SizeXY, 2);
328 double D = pow(A, 2) - 4 * B;
331 B2FATAL(
"Problem with D value : " << D);
334 double Size2Min = 2 * B / (A + sqrt(D));
370 void add(
SpotParam sPar,
double SizeX,
double SizeY,
double SizeXY,
double SizeZ)
386 double SizeMin, SizeMax;
387 tie(SizeMin, SizeMax) = getSizeMinMax(SizeX, SizeY, SizeXY);
389 sizeMin.add(SizeMin);
390 sizeMax.add(SizeMax);
393 double angle = 1e3 * getAngle(SizeX, SizeY, SizeXY);
399 MatrixXd matSize = getRotatedSizeMatrix({sqrS(SizeX), sqrS(SizeY), sqrS(SizeXY)}, sqrS(SizeZ), sPar.
kX.
val(sPar.
kX.
center()),
403 matXX.add(sqrtS(matSize(0, 0)));
404 matYY.add(sqrtS(matSize(1, 1)));
405 matZZ.add(sqrtS(matSize(2, 2)));
406 matXY.add(sqrtS(matSize(0, 1)));
408 matXZ.add(sqrtS(matSize(0, 2)));
409 matYZ.add(sqrtS(matSize(1, 2)));
413 double crossAngleVal = 1e3 * 2 * sqrtS(matSize(0, 0)) / sqrtS(matSize(2, 2));
414 crossAngle.add(crossAngleVal);
420 x.getMeanSigma().print(
"x");
421 y.getMeanSigma().print(
"y");
424 z.getMeanSigma().print(
"z");
447 void getOutput(vector<VectorXd>& vtxPos, vector<MatrixXd>& vtxErr, MatrixXd& sizeMat)
450 int nVals = x.spls[0].vals.size();
455 const double toCm = 1e-4;
457 for (
int i = 0; i < nVals; ++i) {
459 Vector3d vtx(x.spls[0].vals[i]*toCm, y.spls[0].vals[i]*toCm, z.spls[0].vals[i]*toCm);
462 Matrix3d mS = Matrix3d::Zero();
463 mS(0, 0) = sqrS(x.spls[0].errs[i] * toCm);
464 mS(1, 1) = sqrS(y.spls[0].errs[i] * toCm);
465 mS(2, 2) = sqrS(z.spls[0].errs[i] * toCm);
467 vtxPos.push_back(vtx);
468 vtxErr.push_back(mS);
473 sizeMat.resize(3, 3);
474 sizeMat(0, 0) = sqrS(matXX.
vars[0] * toCm);
475 sizeMat(1, 1) = sqrS(matYY.
vars[0] * toCm);
476 sizeMat(2, 2) = sqrS(matZZ.
vars[0] * toCm);
478 sizeMat(0, 1) = sqrS(matXY.
vars[0] * toCm);
479 sizeMat(0, 2) = sqrS(matXZ.
vars[0] * toCm);
480 sizeMat(1, 2) = sqrS(matYZ.
vars[0] * toCm);
482 sizeMat(1, 0) = sizeMat(0, 1);
483 sizeMat(2, 0) = sizeMat(0, 2);
484 sizeMat(2, 1) = sizeMat(1, 2);
491 T->Branch(n, &vec->at(0), n +
"/D");
492 T->Branch(n +
"_low", &vec->at(1), n +
"_low/D");
493 T->Branch(n +
"_high", &vec->at(2), n +
"_high/D");
499 T->Branch(n +
"_nodes", &spl->
nodes);
500 T->Branch(n +
"_vals", &spl->
vals);
501 T->Branch(n +
"_errs", &spl->
errs);
510 TTree* T =
new TTree(
"runs",
"beam conditions of runs");
513 T->Branch(
"run", &run,
"run/I");
515 Spline xAvg = x.getMeanSigma();
516 setBranchSpline(T, &xAvg,
"x");
517 Spline yAvg = y.getMeanSigma();
518 setBranchSpline(T, &yAvg,
"y");
519 Spline zAvg = z.getMeanSigma();
520 setBranchSpline(T, &zAvg,
"z");
523 setBranchSpline(T, &kxAvg,
"kX");
525 setBranchSpline(T, &kyAvg,
"kY");
527 vector<double> sizeXVar = sizeX.
getStats();
528 setBranchVal(T, &sizeXVar,
"sizeX");
529 vector<double> sizeYVar = sizeY.
getStats();
530 setBranchVal(T, &sizeYVar,
"sizeY");
531 vector<double> sizeXYVar = sizeXY.
getStats();
532 setBranchVal(T, &sizeXYVar,
"sizeXY");
533 vector<double> sizeZVar = sizeZ.
getStats();
534 setBranchVal(T, &sizeZVar,
"sizeZ");
536 vector<double> sizeMinVar = sizeMin.
getStats();
537 setBranchVal(T, &sizeMinVar,
"sizeMin");
538 vector<double> sizeMaxVar = sizeMax.
getStats();
539 setBranchVal(T, &sizeMaxVar,
"sizeMax");
540 vector<double> xyAngleVar = xyAngle.
getStats();
541 setBranchVal(T, &xyAngleVar,
"xyAngle");
543 vector<double> crossAngleVar = crossAngle.
getStats();
544 setBranchVal(T, &crossAngleVar,
"crossAngle");
547 vector<double> matXXVar = matXX.
getStats();
548 vector<double> matYYVar = matYY.
getStats();
549 vector<double> matZZVar = matZZ.
getStats();
550 vector<double> matXYVar = matXY.
getStats();
551 vector<double> matXZVar = matXZ.
getStats();
552 vector<double> matYZVar = matYZ.
getStats();
554 setBranchVal(T, &matXXVar,
"matXX");
555 setBranchVal(T, &matYYVar,
"matYY");
556 setBranchVal(T, &matZZVar,
"matZZ");
558 setBranchVal(T, &matXYVar,
"matXY");
559 setBranchVal(T, &matXZVar,
"matXZ");
560 setBranchVal(T, &matYZVar,
"matYZ");
578 double getZIPest(
const Track& tr,
double t,
const SpotParam& spotPar,
int nestMax = 5,
int nest = 0)
581 if (nest < nestMax) {
582 double zIP = getZIPest(tr, t, spotPar, nestMax, nest + 1);
584 x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
585 y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
587 x0 = spotPar.x.val(t);
588 y0 = spotPar.y.val(t);
591 double f0 = tr.tanlambda * (x0 * cos(tr.phi0) + y0 * sin(tr.phi0));
603 double getCorrD(
const Track& tr,
double t,
const SpotParam& spotPar)
605 double zIP = getZIPest(tr, t, spotPar);
607 double x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
608 double y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
610 double f0 = x0 * sin(tr.phi0) - y0 * cos(tr.phi0);
616 double getDtimeConst(
const Track& tr,
double t,
const SpotParam& spotPar)
618 double zIP = getZIPest(tr, t, spotPar);
619 double zIPM = getZIPest(tr, spotPar.z.center(), spotPar);
621 double x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
622 double y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
624 double xM = spotPar.x.val(spotPar.x.center()) + spotPar.kX.val(spotPar.kX.center()) * (zIPM - spotPar.z.val(spotPar.z.center()));
625 double yM = spotPar.y.val(spotPar.y.center()) + spotPar.kY.val(spotPar.kY.center()) * (zIPM - spotPar.z.val(spotPar.z.center()));
628 double f0 = (x0 - xM) * sin(tr.phi0) - (y0 - yM) * cos(tr.phi0);
640 double getCorrZ(
const Track& tr,
double t,
const SpotParam& spotPar)
642 double zIP = getZIPest(tr, t, spotPar);
644 double x0 = spotPar.x.val(t) + spotPar.kX.val(t) * (zIP - spotPar.z.val(t));
645 double y0 = spotPar.y.val(t) + spotPar.kY.val(t) * (zIP - spotPar.z.val(t));
646 double z0 = spotPar.z.val(t);
648 double f0 = z0 - tr.tanlambda * (x0 * cos(tr.phi0) + y0 * sin(tr.phi0));
661 pair<double, double> getStartStop(
const vector<Event>& evts)
663 double minT = 1e20, maxT = -1e20;
664 for (
auto ev : evts) {
665 minT = min(minT, ev.t);
666 maxT = max(maxT, ev.t);
672 vector<TString> extractFileNames(TString str)
674 vector<TString>
files;
675 auto tempVec = str.Tokenize(
",");
676 for (
int i = 0; i < tempVec->GetEntries(); ++i) {
677 TString s = ((TObjString*)tempVec->At(i))->GetString();
678 files.push_back(s.Strip());
684 vector<Event> getEvents(TTree* tr)
687 vector<Event> events;
688 events.reserve(tr->GetEntries());
692 tr->SetBranchAddress(
"run", &evt.run);
693 tr->SetBranchAddress(
"exp", &evt.exp);
694 tr->SetBranchAddress(
"event", &evt.evtNo);
695 tr->SetBranchAddress(
"mu0_d0", &evt.mu0.d0);
696 tr->SetBranchAddress(
"mu1_d0", &evt.mu1.d0);
697 tr->SetBranchAddress(
"mu0_z0", &evt.mu0.z0);
698 tr->SetBranchAddress(
"mu1_z0", &evt.mu1.z0);
700 tr->SetBranchAddress(
"mu0_tanlambda", &evt.mu0.tanlambda);
701 tr->SetBranchAddress(
"mu1_tanlambda", &evt.mu1.tanlambda);
704 tr->SetBranchAddress(
"mu0_phi0", &evt.mu0.phi0);
705 tr->SetBranchAddress(
"mu1_phi0", &evt.mu1.phi0);
707 tr->SetBranchAddress(
"time", &evt.t);
710 for (
int i = 0; i < tr->GetEntries(); ++i) {
716 events.push_back(evt);
720 sort(events.begin(), events.end(), [](Event e1, Event e2) {return e1.t < e2.t;});
727 void bootStrap(vector<Event>& evts)
730 e.nBootStrap = gRandom->Poisson(1);
741 VectorXd linearFit(MatrixXd mat, VectorXd r)
743 MatrixXd matT = mat.transpose();
744 MatrixXd A = matT * mat;
746 VectorXd v = matT * r;
747 MatrixXd Ainv = A.inverse();
760 pair<vector<double>, vector<double>> linearFitErr(MatrixXd m, VectorXd r,
double& err2Mean,
double& err2press,
double& err2pressErr)
762 MatrixXd mT = m.transpose();
763 MatrixXd mat = mT * m;
766 MatrixXd A = mat * mT;
767 VectorXd res = A * r;
768 VectorXd dataH = m * res;
772 double err2 = (dataH - r).squaredNorm() / (r.rows() - res.rows());
780 for (
int i = 0; i < r.rows(); ++i) {
782 for (
int k = 0; k < m.cols(); ++k)
783 Ahat += m(i, k) * A(k, i);
785 double v = pow((r(i) - dataH(i)) / (1 - Ahat), 2);
790 press2 /= (r.rows() - 1);
793 err2pressErr = sqrt((press2 - press * press) / r.rows()) / sqrt(r.rows());
798 MatrixXd AT = A.transpose();
799 MatrixXd errMat = err2 * A * AT;
800 VectorXd errs2(errMat.rows());
801 for (
int i = 0; i < errs2.rows(); ++i)
802 errs2(i) = errMat(i, i);
818 VectorXd linearFitPos(MatrixXd mat, VectorXd r)
820 const double s2MinLimit = pow(0.05, 2);
821 B2ASSERT(
"Matrix size for size fit should be 3", mat.cols() == 3);
822 MatrixXd matT = mat.transpose();
823 MatrixXd A = matT * mat;
824 VectorXd v = matT * r;
825 MatrixXd Ainv = A.inverse();
827 VectorXd pars = Ainv * v;
830 double s2Min = getSize2MinMat(pars[0], pars[1], pars[2]);
831 if (pars[0] >= 0 && pars[1] >= 0 && s2Min >= s2MinLimit)
838 int nDf = r.rows() - 3;
840 double err2 = (mat * pars - r).squaredNorm() / nDf;
842 MatrixXd wMat = Ainv * matT;
843 MatrixXd wMatT = wMat.transpose();
845 MatrixXd covMat = err2 * wMat * wMatT;
846 MatrixXd covMatI = covMat.inverse();
853 TF2 fEig(
rn(), [covMatI, pars, s2MinLimit](
double * x,
double*) {
855 double eig2 = s2MinLimit;
861 xVec[0] = eig1 * c * c + eig2 * s * s;
862 xVec[1] = eig1 * s * s + eig2 * c * c;
863 xVec[2] = s * c * (eig1 - eig2);
866 double res = (xVec - pars).transpose() * covMatI * (xVec - pars);
868 }, s2MinLimit, 400, 0, 2 * M_PI, 0);
871 fEig.GetMinimumXY(eigHigh, phi);
873 pars[0] = eigHigh * pow(cos(phi), 2) + s2MinLimit * pow(sin(phi), 2);
874 pars[1] = eigHigh * pow(sin(phi), 2) + s2MinLimit * pow(cos(phi), 2);
875 pars[2] = sin(phi) * cos(phi) * (eigHigh - s2MinLimit);
886 TH1D* getResolution(TH2D* hRes)
888 TH1D* hSigmaAll =
new TH1D(
rn(),
"", 50, -M_PI, M_PI);
889 for (
int i = 1; i <= hRes->GetNbinsX(); ++i) {
890 TH1D* hProj = hRes->ProjectionY(
rn(), i, i);
891 double rms = hProj->GetRMS();
892 double rmsErr = hProj->GetRMSError();
893 hSigmaAll->SetBinContent(i, rms * rms);
894 hSigmaAll->SetBinError(i, 2 * abs(rms)*rmsErr);
900 TH1D* getMean(
const TH2D* hRes)
902 TH1D* hMean =
new TH1D(
rn(),
"", 50, -M_PI, M_PI);
903 for (
int i = 1; i <= hRes->GetNbinsX(); ++i) {
904 TH1D* hProj = hRes->ProjectionY(
rn(), i, i);
905 double mean = hProj->GetMean();
906 double meanErr = hProj->GetMeanError();
907 hMean->SetBinContent(i, mean);
908 hMean->SetBinError(i, meanErr);
914 double getD12th(Event e, vector<double> sizesXY)
916 double sxx = sizesXY[0];
917 double syy = sizesXY[1];
918 double sxy = sizesXY[2];
920 double cc = cos(
e.mu0.phi0) * cos(
e.mu1.phi0);
921 double ss = sin(
e.mu0.phi0) * sin(
e.mu1.phi0);
922 double sc = -(sin(
e.mu0.phi0) * cos(
e.mu1.phi0) + sin(
e.mu1.phi0) * cos(
e.mu0.phi0));
924 return ss * sxx + cc * syy + sc * sxy;
928 double getZ12th(Event e, vector<double> sizesXY)
930 double sxx = sizesXY[0];
931 double syy = sizesXY[1];
933 double corr =
e.mu0.tanlambda *
e.mu1.tanlambda * (sxx * cos(
e.mu0.phi0) * cos(
e.mu1.phi0) + syy * sin(
e.mu0.phi0) * sin(
935 + (sin(
e.mu0.phi0) * cos(
e.mu1.phi0) + cos(
e.mu0.phi0) * sin(
e.mu1.phi0)));
945 void plotSpotPositionFit(
const vector<Event>& evts, SpotParam par, TString fName)
947 TGraph* gr =
new TGraph();
948 TProfile* dProf =
new TProfile(
rn(),
"dProf", 100, -M_PI, M_PI,
"S");
949 TProfile* dProfRes =
new TProfile(
rn(),
"dProfRes", 100, -M_PI, M_PI,
"S");
951 for (
auto e : evts) {
952 if (!
e.isSig)
continue;
954 double d1 = getDtimeConst(
e.mu0,
e.t, par);
955 double d2 = getDtimeConst(
e.mu1,
e.t, par);
957 gr->SetPoint(gr->GetN(),
e.mu0.phi0, d1);
958 gr->SetPoint(gr->GetN(),
e.mu1.phi0, d2);
960 dProf->Fill(
e.mu0.phi0, d1);
961 dProf->Fill(
e.mu1.phi0, d2);
964 double d1c = getCorrD(
e.mu0,
e.t, par);
965 double d2c = getCorrD(
e.mu1,
e.t, par);
967 dProfRes->Fill(
e.mu0.phi0, d1c);
968 dProfRes->Fill(
e.mu1.phi0, d2c);
970 TF1* f =
new TF1(
rn(),
"[0]*sin(x) - [1]*cos(x)", -M_PI, M_PI);
971 f->SetParameters(par.x.val(par.x.center()), par.y.val(par.y.center()));
973 TCanvas* c =
new TCanvas(
rn(),
"");
975 gr->GetXaxis()->SetRangeUser(-M_PI, M_PI);
976 gr->SetMaximum(+1.3 * f->GetMaximum());
977 gr->SetMinimum(-1.3 * f->GetMaximum());
979 gr->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
980 gr->GetYaxis()->SetTitle(
"d_{0} [#mum]");
983 c->SaveAs(fName +
"_dots.pdf");
986 TCanvas* d =
new TCanvas(
rn(),
"");
987 gStyle->SetOptStat(0);
989 dProf->GetXaxis()->SetRangeUser(-M_PI, M_PI);
990 dProf->SetMaximum(+1.3 * f->GetMaximum());
991 dProf->SetMinimum(-1.3 * f->GetMaximum());
993 dProf->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
994 dProf->GetYaxis()->SetTitle(
"d_{0} [#mum]");
998 B2INFO(
"Saving " << fName <<
" prof ");
999 d->SaveAs(fName +
"_prof.pdf");
1002 TCanvas*
e =
new TCanvas(
rn(),
"");
1003 gStyle->SetOptStat(0);
1005 dProfRes->GetXaxis()->SetRangeUser(-M_PI, M_PI);
1007 dProfRes->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1008 dProfRes->GetYaxis()->SetTitle(
"d_{0} res [#mum]");
1010 TH1D* errP =
new TH1D(
rn(),
"dErrP", 100, -M_PI, M_PI);
1011 TH1D* errM =
new TH1D(
rn(),
"dErrM", 100, -M_PI, M_PI);
1012 for (
int i = 1; i <= errP->GetNbinsX(); ++i) {
1013 errP->SetBinContent(i, dProfRes->GetBinError(i));
1014 errM->SetBinContent(i, -dProfRes->GetBinError(i));
1017 errP->Draw(
"hist same");
1018 errM->Draw(
"hist same");
1020 f->SetParameters(0, 0);
1023 B2INFO(
"Saving " << fName <<
" profRes ");
1024 e->SaveAs(fName +
"_profRes.pdf");
1030 void plotSpotZPositionFit(
const vector<Event>& evts, SpotParam par, TString fName)
1032 TProfile* zProf =
new TProfile(
rn(),
"dProf", 100, -M_PI, M_PI,
"S");
1033 TGraph* gr =
new TGraph();
1034 for (
auto e : evts) {
1035 if (!
e.isSig)
continue;
1038 double z1ip = getZIPest(
e.mu0,
e.t, par);
1039 double z2ip = getZIPest(
e.mu1,
e.t, par);
1041 double zipT = par.z.val(
e.t);
1042 double zipM = par.z.val(par.z.center());
1044 double val1 = z1ip - (zipT - zipM);
1045 double val2 = z2ip - (zipT - zipM);
1047 gr->SetPoint(gr->GetN(),
e.mu0.phi0, val1);
1048 gr->SetPoint(gr->GetN(),
e.mu1.phi0, val2);
1050 zProf->Fill(
e.mu0.phi0, val1);
1051 zProf->Fill(
e.mu1.phi0, val2);
1053 TF1* f =
new TF1(
rn(),
"[0]", -M_PI, M_PI);
1054 f->SetParameter(0, par.z.val(par.z.center()));
1056 TCanvas* c =
new TCanvas(
rn(),
"");
1057 c->SetLeftMargin(0.12);
1059 gr->GetXaxis()->SetRangeUser(-M_PI, M_PI);
1060 gr->SetMaximum(1000);
1061 gr->SetMinimum(-1000);
1063 gr->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1064 gr->GetYaxis()->SetTitle(
"z_{IP} estimate [#mum]");
1067 c->SaveAs(fName +
"_dots.pdf");
1070 TCanvas* d =
new TCanvas(
rn(),
"");
1071 gStyle->SetOptStat(0);
1072 d->SetLeftMargin(0.12);
1074 zProf->GetXaxis()->SetRangeUser(-M_PI, M_PI);
1075 zProf->SetMaximum(1000);
1076 zProf->SetMinimum(-1000);
1078 zProf->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1079 zProf->GetYaxis()->SetTitle(
"z_{IP} estimate [#mum]");
1082 d->SaveAs(fName + +
"_prof.pdf");
1091 void plotSpotPositionPull(
const vector<Event>& evts,
const SpotParam& par, TString fName,
double cut = 70)
1093 TH1D* hPull =
new TH1D(
rn(),
"", 200, -200, 200);
1095 for (
auto& e : evts) {
1096 if (!
e.isSig)
continue;
1098 double d0 = getCorrD(
e.mu0,
e.t, par);
1099 double d1 = getCorrD(
e.mu1,
e.t, par);
1105 TCanvas* c =
new TCanvas(
rn(),
"");
1106 gStyle->SetOptStat(2210);
1109 hPull->GetXaxis()->SetTitle(
"pull [#mum]");
1110 hPull->GetYaxis()->SetTitle(
"#tracks");
1112 TLine* l =
new TLine;
1113 l->SetLineColor(kRed);
1114 l->DrawLine(-cut, 0, -cut, 500);
1115 l->DrawLine(+cut, 0, +cut, 500);
1117 c->SaveAs(fName +
".pdf");
1122 void plotKxKyFit(
const vector<Event>& evts, SpotParam par, TString fName)
1124 TProfile* profRes =
new TProfile(
rn(),
"dProf", 100, -800, 800,
"S");
1125 TProfile* profResKx =
new TProfile(
rn(),
"dProfKx", 100, -800, 800,
"S");
1126 TProfile* profResKy =
new TProfile(
rn(),
"dProfKy", 100, -800, 800,
"S");
1128 SpotParam parNoKx = par;
1129 SpotParam parNoKy = par;
1130 parNoKx.kX.vals = {0};
1131 parNoKy.kY.vals = {0};
1132 parNoKx.kX.nodes = {};
1133 parNoKy.kY.nodes = {};
1135 for (
auto& e : evts) {
1136 if (!
e.isSig)
continue;
1138 double zDiff1 = getZIPest(
e.mu0,
e.t, par) - par.z.val(
e.t);
1139 double zDiff2 = getZIPest(
e.mu1,
e.t, par) - par.z.val(
e.t);
1142 double d1 = getCorrD(
e.mu0,
e.t, par);
1143 double d2 = getCorrD(
e.mu1,
e.t, par);
1145 double d1KX = getCorrD(
e.mu0,
e.t, parNoKx);
1146 double d2KX = getCorrD(
e.mu1,
e.t, parNoKx);
1149 profResKx->Fill(zDiff1 * sin(
e.mu0.phi0), d1KX);
1150 profResKx->Fill(zDiff2 * sin(
e.mu1.phi0), d2KX);
1152 double d1KY = getCorrD(
e.mu0,
e.t, parNoKy);
1153 double d2KY = getCorrD(
e.mu1,
e.t, parNoKy);
1154 profResKy->Fill(-zDiff1 * cos(
e.mu0.phi0), d1KY);
1155 profResKy->Fill(-zDiff2 * cos(
e.mu1.phi0), d2KY);
1157 profRes->Fill(zDiff1, d1);
1158 profRes->Fill(zDiff2, d2);
1163 TCanvas* cX =
new TCanvas(
rn(),
"");
1164 gStyle->SetOptStat(0);
1167 profResKx->GetXaxis()->SetTitle(
"(z_{IP} - z_{IP}^{0}) sin #phi_{0} [#mum]");
1168 profResKx->GetYaxis()->SetTitle(
"d_{0} res [#mum]");
1170 TF1* f =
new TF1(
rn(),
"[0]*x", -800, 800);
1171 f->SetParameter(0, par.kX.val(par.kX.center()));
1174 cX->SaveAs(fName +
"_kX.pdf");
1176 TCanvas* cY =
new TCanvas(
rn(),
"");
1177 gStyle->SetOptStat(0);
1180 profResKy->GetXaxis()->SetTitle(
"-(z_{IP} - z_{IP}^{0}) cos #phi_{0} [#mum]");
1181 profResKy->GetYaxis()->SetTitle(
"d_{0} res [#mum]");
1183 f->SetParameter(0, par.kY.val(par.kY.center()));
1186 cY->SaveAs(fName +
"_kY.pdf");
1192 void plotXYtimeDep(
const vector<Event>& evts, SpotParam par, TString fName)
1194 TProfile* profRes =
new TProfile(
rn(),
"dProf", 50, -0.5, 0.5);
1195 TProfile* profResTx =
new TProfile(
rn(),
"dProfTx", 50, -0.5, 0.5);
1196 TProfile* profResTy =
new TProfile(
rn(),
"dProfTy", 50, -0.5, 0.5);
1198 SpotParam parNoTx = par;
1199 SpotParam parNoTy = par;
1200 parNoTx.x.nodes = {};
1201 parNoTx.x.vals = {par.x.val(par.x.center())};
1202 parNoTy.y.nodes = {};
1203 parNoTy.y.vals = {par.y.val(par.y.center())};
1205 for (
auto& e : evts) {
1206 if (!
e.isSig)
continue;
1208 double tDiff = (
e.t - par.x.val(par.x.center()));
1212 double d1 = getCorrD(
e.mu0,
e.t, par);
1213 double d2 = getCorrD(
e.mu1,
e.t, par);
1215 double d1TX = getCorrD(
e.mu0,
e.t, parNoTx);
1216 double d2TX = getCorrD(
e.mu1,
e.t, parNoTx);
1218 profResTx->Fill(tDiff * sin(
e.mu0.phi0), d1TX);
1219 profResTx->Fill(tDiff * sin(
e.mu1.phi0), d2TX);
1221 double d1TY = getCorrD(
e.mu0,
e.t, parNoTy);
1222 double d2TY = getCorrD(
e.mu1,
e.t, parNoTy);
1224 profResTy->Fill(-tDiff * cos(
e.mu0.phi0), d1TY);
1225 profResTy->Fill(-tDiff * cos(
e.mu1.phi0), d2TY);
1228 profRes->Fill(tDiff * sin(
e.mu0.phi0), d1);
1229 profRes->Fill(tDiff * sin(
e.mu1.phi0), d2);
1234 TCanvas* cX =
new TCanvas(
rn(),
"");
1235 gStyle->SetOptStat(0);
1239 TF1* f =
new TF1(
rn(),
"[0]*x", -1, 1);
1240 f->SetParameter(0, (par.x.val(1) - par.x.val(0)));
1242 B2INFO(
"Table value " << par.x.val(1) - par.x.val(0));
1244 cX->SaveAs(fName +
"_tX.pdf");
1254 void plotSpotZpositionPull(
const vector<Event>& evts,
const SpotParam& par, TString fName,
double cut = 1000)
1256 TH1D* hPull =
new TH1D(
rn(),
"", 200, -2000, 2000);
1258 for (
auto& e : evts) {
1259 if (!
e.isSig)
continue;
1261 double z0 = getCorrZ(
e.mu0,
e.t, par);
1262 double z1 = getCorrZ(
e.mu1,
e.t, par);
1268 gStyle->SetOptStat(2210);
1269 TCanvas* c =
new TCanvas(
rn(),
"");
1272 hPull->GetXaxis()->SetTitle(
"pull [#mum]");
1273 hPull->GetYaxis()->SetTitle(
"#tracks");
1275 TLine* l =
new TLine;
1276 l->SetLineColor(kRed);
1277 l->DrawLine(-cut, 0, -cut, 500);
1278 l->DrawLine(+cut, 0, +cut, 500);
1280 c->SaveAs(fName +
".pdf");
1285 void removeSpotPositionOutliers(vector<Event>& evts,
const SpotParam& par,
double cut = 70)
1289 for (
auto& e : evts) {
1290 if (!
e.isSig)
continue;
1292 double d0 = getCorrD(
e.mu0,
e.t, par);
1293 double d1 = getCorrD(
e.mu1,
e.t, par);
1295 e.isSig = abs(d0) < cut && abs(d1) < cut;
1299 B2INFO(
"Removed fraction Position " << nRem / (nAll + 0.));
1304 void removeSpotZpositionOutliers(vector<Event>& evts,
const SpotParam& par,
double cut = 1000)
1308 for (
auto& e : evts) {
1309 if (!
e.isSig)
continue;
1311 double z0 = getCorrZ(
e.mu0,
e.t, par);
1312 double z1 = getCorrZ(
e.mu1,
e.t, par);
1314 e.isSig = abs(z0) < cut && abs(z1) < cut;
1318 B2INFO(
"Removed fraction Position " << nRem / (nAll + 0.));
1324 vector<vector<double>> fillSplineBasesLinear(
const vector<Event>& evts, vector<double> spl,
1325 std::function<
double(Track,
double)> fun)
1328 if (n == 0 || (n == 2 && spl[0] > spl[1]))
1331 vector<vector<double>> vecs(n);
1334 for (
const auto& e : evts) {
1335 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1336 vecs[0].push_back(1 * fun(
e.mu0,
e.t));
1337 vecs[0].push_back(1 * fun(
e.mu1,
e.t));
1341 for (
int k = 0; k < n; ++k) {
1342 double xCnt = spl[k];
1343 double xLow = (k == 0) ? spl[0] : spl[k - 1];
1344 double xHigh = (k == n - 1) ? spl[n - 1] : spl[k + 1];
1346 for (
const auto& e : evts) {
1349 if (xLow <= x && x < xCnt)
1350 v = (x - xLow) / (xCnt - xLow);
1351 else if (xCnt < x && x <= xHigh)
1352 v = (xHigh - x) / (xHigh - xCnt);
1355 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1356 vecs[k].push_back(v * fun(
e.mu0,
e.t));
1357 vecs[k].push_back(v * fun(
e.mu1,
e.t));
1368 vector<vector<double>> fillSplineBasesZero(
const vector<Event>& evts, vector<double> spl, std::function<
double(Track,
double)> fun)
1370 int n = spl.size() + 1;
1372 vector<vector<double>> vecs(n);
1375 for (
const auto& e : evts) {
1376 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1377 vecs[0].push_back(1 * fun(
e.mu0,
e.t));
1378 vecs[0].push_back(1 * fun(
e.mu1,
e.t));
1382 for (
int k = 0; k < n; ++k) {
1383 double xLow = -1e30;
1384 double xHigh = +1e30;
1388 }
else if (k == n - 1) {
1395 for (
const auto& e : evts) {
1398 if (xLow <= x && x < xHigh)
1401 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1402 vecs[k].push_back(v * fun(
e.mu0,
e.t));
1403 vecs[k].push_back(v * fun(
e.mu1,
e.t));
1418 double compareSplines(
const Spline& spl1,
const Spline& spl2)
1422 double step = 0.001;
1423 for (
double x = 0; x <= 1 + step / 2; x += step) {
1424 double v1 = spl1.val(x);
1425 double e1 = spl1.err(x);
1426 double v2 = spl2.val(x);
1427 double e2 = spl2.err(x);
1429 double d = pow(v2 - v1, 2) / pow(max(e1, e2), 2);
1436 double fitSpotZwidth(
const vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY)
1439 vector<double> dataVec;
1440 vector<double> zzVec;
1443 for (
auto e : evts) {
1444 double z0 = getCorrZ(
e.mu0,
e.t, spotPar);
1445 double z1 = getCorrZ(
e.mu1,
e.t, spotPar);
1447 double corr = getZ12th(e, sizesXY);
1448 double z0z1Corr = z0 * z1 - corr;
1451 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1452 dataVec.push_back(z0z1Corr);
1459 vector<double> pars, err2;
1460 double err2Mean, err2press, err2pressErr;
1461 tie(pars, err2) = linearFitErr(mat,
vec2vec(dataVec), err2Mean, err2press, err2pressErr);
1471 SpotParam fitSpotPositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY,
1472 const vector<double>& splKX,
const vector<double>& splKY)
1474 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return sin(tr.phi0);});
1475 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -cos(tr.phi0);});
1477 vector<vector<double>> basesKX = fillSplineBasesZero(evts, splKX, [](Track tr,
double) {
return sin(tr.phi0) * tr.z0;});
1478 vector<vector<double>> basesKY = fillSplineBasesZero(evts, splKY, [](Track tr,
double) {
return -cos(tr.phi0) * tr.z0;});
1481 vector<double> dataVec;
1482 for (
auto e : evts) {
1483 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1484 dataVec.push_back(
e.mu0.d0);
1485 dataVec.push_back(
e.mu1.d0);
1489 vector<vector<double>> allVecs =
merge({basesX, basesY, basesKX, basesKY});
1494 VectorXd vData =
vec2vec(dataVec);
1496 vector<double> pars(A.cols()), err2(A.cols());
1497 double err2Mean, err2press, err2pressErr;
1498 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1500 for (
auto& e : err2)
e = sqrt(e);
1501 return SpotParam(pars, err2, {splX, splY, splKX, splKY});
1505 SpotParam fitSpotPositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY,
1506 const vector<double>& splKX,
const vector<double>& splKY,
const SpotParam& spotPars)
1508 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return sin(tr.phi0);});
1509 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -cos(tr.phi0);});
1511 vector<vector<double>> basesKX = fillSplineBasesZero(evts, splKX, [ = ](Track tr,
double t) {
return sin(tr.phi0) * (getZIPest(tr, t, spotPars) - spotPars.z.val(t));});
1512 vector<vector<double>> basesKY = fillSplineBasesZero(evts, splKY, [ = ](Track tr,
double t) {
return -cos(tr.phi0) * (getZIPest(tr, t, spotPars) - spotPars.z.val(t));});
1515 vector<double> dataVec;
1516 for (
auto e : evts) {
1517 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1518 dataVec.push_back(
e.mu0.d0);
1519 dataVec.push_back(
e.mu1.d0);
1523 vector<vector<double>> allVecs =
merge({basesX, basesY, basesKX, basesKY});
1528 VectorXd vData =
vec2vec(dataVec);
1530 vector<double> pars(A.cols()), err2(A.cols());
1531 double err2Mean, err2press, err2pressErr;
1532 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1534 for (
auto& e : err2)
e = sqrt(e);
1535 auto res = SpotParam(pars, err2, {splX, splY, splKX, splKY});
1545 SpotParam fitSpotPositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY)
1547 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return sin(tr.phi0);});
1548 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -cos(tr.phi0);});
1550 vector<double> dataVec;
1551 for (
auto e : evts) {
1552 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1553 dataVec.push_back(
e.mu0.d0);
1554 dataVec.push_back(
e.mu1.d0);
1558 vector<vector<double>> allVecs =
merge({basesX, basesY});
1562 VectorXd vData =
vec2vec(dataVec);
1564 vector<double> pars(A.cols()), err2(A.cols());
1565 double err2Mean, err2press, err2pressErr;
1566 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1568 for (
auto& e : err2)
e = sqrt(e);
1569 return SpotParam(pars, err2, {splX, splY});
1578 SpotParam fitZpositionSplines(
const vector<Event>& evts,
const vector<double>& splX,
const vector<double>& splY,
1579 const vector<double>& splKX,
const vector<double>& splKY,
1580 const vector<double>& splZ)
1582 vector<vector<double>> basesX = fillSplineBasesZero(evts, splX, [](Track tr,
double) {
return -tr.tanlambda * cos(tr.phi0);});
1583 vector<vector<double>> basesY = fillSplineBasesZero(evts, splY, [](Track tr,
double) {
return -tr.tanlambda * sin(tr.phi0);});
1585 vector<vector<double>> basesKX = fillSplineBasesZero(evts, splKX, [](Track tr,
double) {
return -tr.z0 * tr.tanlambda * cos(tr.phi0);});
1586 vector<vector<double>> basesKY = fillSplineBasesZero(evts, splKY, [](Track tr,
double) {
return -tr.z0 * tr.tanlambda * sin(tr.phi0);});
1588 vector<vector<double>> basesZ = fillSplineBasesZero(evts, splZ, [](Track ,
double) {
return 1;});
1591 vector<double> dataVec;
1592 for (
auto e : evts) {
1593 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1594 dataVec.push_back(
e.mu0.z0);
1595 dataVec.push_back(
e.mu1.z0);
1599 vector<vector<double>> allVecs =
merge({basesX, basesY, basesKX, basesKY, basesZ});
1603 VectorXd vData =
vec2vec(dataVec);
1605 vector<double> pars(A.cols()), err2(A.cols());
1606 double err2Mean, err2press, err2pressErr;
1607 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1609 for (
auto& e : err2)
e = sqrt(e);
1610 return SpotParam(pars, err2, {splX, splY, splKX, splKY, splZ});
1616 SpotParam fitZpositionSplinesSimple(
const vector<Event>& evts,
const vector<double>& splZ,
const SpotParam& spotPars)
1618 vector<vector<double>> basesZ = fillSplineBasesZero(evts, splZ, [](Track,
double) {
return 1;});
1620 vector<double> dataVec;
1621 for (
auto e : evts) {
1622 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1623 double z1 = getZIPest(
e.mu0,
e.t, spotPars);
1624 double z2 = getZIPest(
e.mu1,
e.t, spotPars);
1625 dataVec.push_back(z1);
1626 dataVec.push_back(z2);
1632 VectorXd vData =
vec2vec(dataVec);
1634 vector<double> pars(A.cols()), err2(A.cols());
1635 double err2Mean, err2press, err2pressErr;
1636 tie(pars, err2) = linearFitErr(A, vData, err2Mean, err2press, err2pressErr);
1638 for (
auto& e : err2)
e = sqrt(e);
1640 SpotParam parsUpd = spotPars;
1641 parsUpd.z.vals = pars;
1642 parsUpd.z.errs = err2;
1643 parsUpd.z.nodes = splZ;
1651 vector<double> fitSpotWidthCMS(
const vector<Event>& evts,
const SpotParam& spotPar)
1654 vector<double> dataVec, ccVec, ssVec, scVec;
1657 for (
auto e : evts) {
1658 double d0 = getCorrD(
e.mu0,
e.t, spotPar);
1659 double d1 = getCorrD(
e.mu1,
e.t, spotPar);
1661 for (
int i = 0; i <
e.nBootStrap *
e.isSig; ++i) {
1662 dataVec.push_back(d0 * d1);
1664 ccVec.push_back(cos(
e.mu0.phi0)*cos(
e.mu1.phi0));
1665 ssVec.push_back(sin(
e.mu0.phi0)*sin(
e.mu1.phi0));
1666 scVec.push_back(-(sin(
e.mu0.phi0)*cos(
e.mu1.phi0) + sin(
e.mu1.phi0)*cos(
e.mu0.phi0)));
1671 MatrixXd mat =
vecs2mat({ssVec, ccVec, scVec});
1674 VectorXd resPhys = linearFitPos(mat,
vec2vec(dataVec));
1676 return {resPhys(0), resPhys(1), resPhys(2)};
1681 void plotSpotSizePull(
const vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY)
1683 TH1D* hPull =
new TH1D(
rn(),
"", 100, -2000, 2000);
1684 for (
auto& e : evts) {
1685 if (!
e.isSig)
continue;
1687 double d0 = getCorrD(
e.mu0,
e.t, spotPar);
1688 double d1 = getCorrD(
e.mu1,
e.t, spotPar);
1690 double d12Th = getD12th(e, sizesXY);
1692 hPull->Fill(d0 * d1 - d12Th);
1694 TCanvas* c =
new TCanvas(
rn(),
"");
1696 c->SaveAs(
"pullsSize.pdf");
1701 void plotSpotSizeZPull(
const vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY,
double sizeZZ)
1703 TH1D* hPull =
new TH1D(
rn(),
"", 100, -300e3, 600e3);
1704 for (
auto& e : evts) {
1705 if (!
e.isSig)
continue;
1707 double z0 = getCorrZ(
e.mu0,
e.t, spotPar);
1708 double z1 = getCorrZ(
e.mu1,
e.t, spotPar);
1710 double corr = getZ12th(e, sizesXY);
1711 double res = z0 * z1 - corr - sizeZZ;
1716 gStyle->SetOptStat(2210);
1717 TCanvas* c =
new TCanvas(
rn(),
"");
1719 B2INFO(
"zSizeFit mean " << hPull->GetMean());
1720 B2INFO(
"zSizeFit rms " << hPull->GetRMS());
1722 c->SaveAs(
"pullsZSize.pdf");
1729 void plotSpotSizeFit(
const vector<Event>& evts,
const SpotParam& par,
const vector<double>& sizeXY)
1731 double sxx = sizeXY[0];
1732 double syy = sizeXY[1];
1733 double sxy = sizeXY[2];
1735 gStyle->SetOptStat(0);
1737 TProfile* profSxx =
new TProfile(
rn(),
"", 50, -1, 1);
1738 TProfile* profSyy =
new TProfile(
rn(),
"", 50, -1, 1);
1739 TProfile* profSxy =
new TProfile(
rn(),
"", 50, -1, 1);
1740 for (
auto e : evts) {
1741 if (!
e.isSig)
continue;
1743 double cc = cos(
e.mu0.phi0) * cos(
e.mu1.phi0);
1744 double ss = sin(
e.mu0.phi0) * sin(
e.mu1.phi0);
1745 double sc = - (sin(
e.mu0.phi0) * cos(
e.mu1.phi0) + sin(
e.mu1.phi0) * cos(
e.mu0.phi0));
1747 double d0 = getCorrD(
e.mu0,
e.t, par);
1748 double d1 = getCorrD(
e.mu1,
e.t, par);
1750 double data = d0 * d1;
1752 profSxx->Fill(ss, data - syy * cc - sxy * sc);
1753 profSyy->Fill(cc, data - sxx * ss - sxy * sc);
1754 profSxy->Fill(sc, data - syy * cc - sxx * ss);
1757 TCanvas* c =
new TCanvas(
rn(),
"", 1200, 500);
1761 profSxx->GetXaxis()->SetTitle(
"sin #phi_{1} sin #phi_{2}");
1762 profSxx->GetYaxis()->SetTitle(
"#LTd_{1} d_{2}#GT - corr_{xx} [#mum^{2}]");
1763 TF1* fxx =
new TF1(
rn(),
"[0]*x", -1, 1);
1764 fxx->SetParameter(0, sxx);
1769 profSyy->GetXaxis()->SetTitle(
"cos #phi_{1} cos #phi_{2}");
1770 profSyy->GetYaxis()->SetTitle(
"#LTd_{1} d_{2}#GT - corr_{yy} [#mum^{2}]");
1771 TF1* fyy =
new TF1(
rn(),
"[0]*x", -1, 1);
1772 fyy->SetParameter(0, syy);
1777 profSxy->GetXaxis()->SetTitle(
"-(sin #phi_{1} cos #phi_{2} + sin #phi_{2} cos #phi_{1})");
1778 profSxy->GetYaxis()->SetTitle(
"#LTd_{1} d_{2}#GT - corr_{xy} [#mum^{2}]");
1779 TF1* fxy =
new TF1(
rn(),
"[0]*x", -1, 1);
1780 fxy->SetParameter(0, sxy);
1783 c->SaveAs(
"SizeFit.pdf");
1788 void plotSpotZSizeFit(
const vector<Event>& evts,
const SpotParam& par,
const vector<double>& sizesXY,
double sizeZZ)
1791 gStyle->SetOptStat(0);
1794 TProfile* zzProfPhi =
new TProfile(
rn(),
"", 100, -M_PI, M_PI);
1795 TProfile* zzProfXX =
new TProfile(
rn(),
"", 100, -M_PI / 4, 2 * M_PI);
1796 TProfile* zzProfYY =
new TProfile(
rn(),
"", 100, -M_PI / 4, 2 * M_PI);
1797 TProfile* zzProfXY =
new TProfile(
rn(),
"", 100, -2 * M_PI, 2 * M_PI);
1798 TProfile* zzProfXZ =
new TProfile(
rn(),
"", 100, -2 * M_PI, 2 * M_PI);
1799 TProfile* zzProfYZ =
new TProfile(
rn(),
"", 100, -2 * M_PI, 2 * M_PI);
1802 for (
auto e : evts) {
1803 double z0 = getCorrZ(
e.mu0,
e.t, par);
1804 double z1 = getCorrZ(
e.mu1,
e.t, par);
1806 double corr = getZ12th(e, sizesXY);
1807 double z0z1Corr = z0 * z1 - corr;
1811 double xx =
e.mu0.tanlambda *
e.mu1.tanlambda * cos(
e.mu0.phi0) * cos(
e.mu1.phi0);
1812 double yy =
e.mu0.tanlambda *
e.mu1.tanlambda * sin(
e.mu0.phi0) * sin(
e.mu1.phi0);
1813 double xy =
e.mu0.tanlambda *
e.mu1.tanlambda * (sin(
e.mu0.phi0) * cos(
e.mu1.phi0) + cos(
e.mu0.phi0) * sin(
e.mu1.phi0));
1814 double xz = - (
e.mu0.tanlambda * cos(
e.mu0.phi0) +
e.mu1.tanlambda * cos(
e.mu1.phi0));
1815 double yz = - (
e.mu0.tanlambda * sin(
e.mu0.phi0) +
e.mu1.tanlambda * sin(
e.mu1.phi0));
1818 zzProfPhi->Fill(
e.mu0.phi0, z0z1Corr);
1819 zzProfPhi->Fill(
e.mu1.phi0, z0z1Corr);
1820 zzProfXX->Fill(xx, z0z1Corr);
1821 zzProfYY->Fill(yy, z0z1Corr);
1822 zzProfXY->Fill(xy, z0z1Corr);
1823 zzProfXZ->Fill(xz, z0z1Corr);
1824 zzProfYZ->Fill(yz, z0z1Corr);
1828 TF1* f =
new TF1(
rn(),
"[0]", -2 * M_PI, 2 * M_PI);
1829 f->SetParameter(0, sizeZZ);
1831 TCanvas* c =
new TCanvas(
rn(),
"", 1200, 500);
1835 zzProfPhi->GetXaxis()->SetTitle(
"#phi_{0} [rad]");
1836 zzProfPhi->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1841 zzProfXX->GetXaxis()->SetTitle(
"xx sensitive");
1842 zzProfXX->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1847 zzProfYY->GetXaxis()->SetTitle(
"yy sensitive");
1848 zzProfYY->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1853 zzProfXY->GetXaxis()->SetTitle(
"xy sensitive");
1854 zzProfXY->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1859 zzProfXZ->GetXaxis()->SetTitle(
"xz sensitive");
1860 zzProfXZ->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1865 zzProfYZ->GetXaxis()->SetTitle(
"yz sensitive");
1866 zzProfYZ->GetYaxis()->SetTitle(
"#LTz_{1} z_{2}#GT - corr [#mum^{2}]");
1869 c->SaveAs(
"SizeZFit.pdf");
1875 void removeSpotSizeOutliers(vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY,
double cut = 1500)
1880 for (
auto& e : evts) {
1881 if (!
e.isSig)
continue;
1883 double d0 = getCorrD(
e.mu0,
e.t, spotPar);
1884 double d1 = getCorrD(
e.mu1,
e.t, spotPar);
1885 double d12Th = getD12th(e, sizesXY);
1887 e.isSig = abs(d0 * d1 - d12Th) < cut;
1891 B2INFO(
"Removed fraction Size " << nRem / (nAll + 0.));
1896 void removeSpotSizeZOutliers(vector<Event>& evts,
const SpotParam& spotPar,
const vector<double>& sizesXY,
double sizeZZ,
1897 double cut = 150000)
1902 for (
auto& e : evts) {
1903 if (!
e.isSig)
continue;
1905 double z0 = getCorrZ(
e.mu0,
e.t, spotPar);
1906 double z1 = getCorrZ(
e.mu1,
e.t, spotPar);
1908 double corr = getZ12th(e, sizesXY);
1909 double res = z0 * z1 - corr - sizeZZ;
1912 e.isSig = abs(res) < cut;
1916 B2INFO(
"Removed fraction Size " << nRem / (nAll + 0.));
1921 MatrixXd toMat(TRotation rot)
1923 MatrixXd rotM(3, 3);
1924 rotM(0, 0) = rot.XX();
1925 rotM(0, 1) = rot.XY();
1926 rotM(0, 2) = rot.XZ();
1927 rotM(1, 0) = rot.YX();
1928 rotM(1, 1) = rot.YY();
1929 rotM(1, 2) = rot.YZ();
1930 rotM(2, 0) = rot.ZX();
1931 rotM(2, 1) = rot.ZY();
1932 rotM(2, 2) = rot.ZZ();
1945 MatrixXd getRotatedSizeMatrix(vector<double> xySize,
double zzSize,
double kX,
double kY)
1951 MatrixXd rotM = toMat(rot);
1952 MatrixXd rotMT = rotM.transpose();
1954 Matrix3d eigenMat = Matrix3d::Zero();
1955 eigenMat(0, 0) = xySize[0];
1956 eigenMat(1, 1) = xySize[1];
1957 eigenMat(0, 1) = xySize[2];
1958 eigenMat(1, 0) = xySize[2];
1959 eigenMat(2, 2) = zzSize;
1961 return (rotM * eigenMat * rotMT);
1971 tuple<vector<VectorXd>, vector<MatrixXd>, MatrixXd> runBeamSpotAnalysis(vector<Event> evts,
1972 const vector<double>& splitPoints)
1974 const double xyPosLimit = 70;
1975 const double xySize2Limit = pow(40, 2);
1976 const double zPosLimit = 1200;
1979 vector<double> indX = splitPoints;
1980 vector<double> indY = splitPoints;
1981 vector<double> indZ = splitPoints;
1984 vector<double> indKX = {};
1985 vector<double> indKY = {};
1987 UnknownPars allPars, allParsZ;
1988 const int kPlot = -1;
1989 for (
int k = 0; k < 1; ++k) {
1990 for (
auto& e : evts)
e.isSig =
true;
1991 if (k != 0) bootStrap(evts);
1995 auto resTemp = fitSpotPositionSplines(evts, indX, indY);
1998 plotSpotPositionFit(evts, resTemp,
"positionFitSimpe");
1999 plotSpotPositionPull(evts, resTemp,
"pullsPositionSimple", xyPosLimit);
2001 removeSpotPositionOutliers(evts, resTemp, xyPosLimit);
2004 auto resFin = fitSpotPositionSplines(evts, indX, indY);
2006 plotSpotPositionFit(evts, resFin,
"positionFitSimpleC");
2007 plotSpotPositionPull(evts, resFin,
"pullsPositionSimpleC", xyPosLimit);
2008 plotXYtimeDep(evts, resFin,
"simplePosTimeDep");
2012 auto resZmy = fitZpositionSplinesSimple(evts, indZ, resFin);
2014 plotSpotZPositionFit(evts, resZmy,
"positionFitSimpleZ");
2015 plotSpotZpositionPull(evts, resZmy,
"zPositionPull", zPosLimit);
2018 removeSpotZpositionOutliers(evts, resZmy, zPosLimit);
2021 resZmy = fitZpositionSplinesSimple(evts, indZ, resZmy);
2025 auto resNew = fitSpotPositionSplines(evts, indX, indY, indKX, indKY, resZmy);
2027 plotSpotPositionFit(evts, resNew,
"positionFitFull");
2028 plotKxKyFit(evts, resNew,
"slopes");
2032 resZmy = fitZpositionSplinesSimple(evts, indZ, resNew);
2033 if (k == kPlot) plotSpotZPositionFit(evts, resZmy,
"positionFitSimpleZLast");
2037 resNew = fitSpotPositionSplines(evts, indX, indY, indKX, indKY, resZmy);
2040 resZmy = fitZpositionSplinesSimple(evts, indZ, resNew);
2041 resNew = fitSpotPositionSplines(evts, indX, indY, indKX, indKY, resZmy);
2045 auto vecXY = fitSpotWidthCMS(evts, resNew);
2046 if (k == kPlot) plotSpotSizePull(evts, resNew, vecXY);
2047 removeSpotSizeOutliers(evts, resNew, vecXY, xySize2Limit);
2048 vecXY = fitSpotWidthCMS(evts, resNew);
2049 if (k == kPlot) plotSpotSizeFit(evts, resNew, vecXY);
2053 double sizeZZ = fitSpotZwidth(evts, resNew, vecXY);
2056 plotSpotZSizeFit(evts, resNew, vecXY, sizeZZ);
2057 plotSpotSizeZPull(evts, resNew, vecXY, sizeZZ);
2063 allPars.add(resNew, sqrtS(vecXY[0]), sqrtS(vecXY[1]), sqrtS(vecXY[2]), sqrtS(sizeZZ));
2069 vector<VectorXd> vtxPos;
2070 vector<MatrixXd> vtxErr;
2073 allPars.getOutput(vtxPos, vtxErr, sizeMat);
2075 return make_tuple(vtxPos, vtxErr, sizeMat);