24#include <TFitResult.h>
25#include <TFitResultPtr.h>
26#include <TMatrixDSym.h>
30#include "Math/VectorUtil.h"
40 constexpr double GEV = 1000.0;
45using ROOT::Math::PtEtaPhiMVector;
46using ROOT::Math::PxPyPzMVector;
47using ROOT::Math::XYVector;
48using ROOT::Math::VectorUtil::DeltaR;
49using ROOT::Math::VectorUtil::Phi_mpi_pi;
85 Prob->SetUseTauProbability(
true);
86 Prob->SetUseMnuProbability(
false);
87 Prob->SetUseDphiLL(
false);
132 float hEmax = 3000.0;
142 m_fMfit_all = std::make_shared<TH1F>(
"MMC_h1",
"M", hNbins, 0.0,
149 std::make_shared<TH1F>(
"MMC_h1NoW",
"M no weight", hNbins, 0.0, hEmax);
151 m_fPXfit1 = std::make_shared<TH1F>(
"MMC_h2",
"Px1", 4 * hNbins, -hEmax,
153 m_fPYfit1 = std::make_shared<TH1F>(
"MMC_h3",
"Py1", 4 * hNbins, -hEmax,
155 m_fPZfit1 = std::make_shared<TH1F>(
"MMC_h4",
"Pz1", 4 * hNbins, -hEmax,
157 m_fPXfit2 = std::make_shared<TH1F>(
"MMC_h5",
"Px2", 4 * hNbins, -hEmax,
159 m_fPYfit2 = std::make_shared<TH1F>(
"MMC_h6",
"Py2", 4 * hNbins, -hEmax,
161 m_fPZfit2 = std::make_shared<TH1F>(
"MMC_h7",
"Pz2", 4 * hNbins, -hEmax,
178 m_fFitting->SetParNames(
"Max",
"Mean",
"InvWidth2");
202 Info(
"DiTauMassTools",
"------------- Raw Input for MissingMassCalculator --------------");
207 Info(
"DiTauMassTools",
"------------- Prepared Input for MissingMassCalculator--------------");
226 double dummy_METres =
229 dummy_METres * std::abs(cos(dummy_met.Phi() -
preparedInput.m_MetVec.Phi()));
231 dummy_METres * std::abs(sin(dummy_met.Phi() -
preparedInput.m_MetVec.Phi()));
247 Info(
"DiTauMassTools",
"Calling DitauMassCalculatorV9lfv");
253 TFile *outFile = TFile::Open(
"MMC_likelihoods.root",
"UPDATE");
256 if (!outFile->GetDirectory(path.c_str()))
257 outFile->mkdir(path.c_str());
258 outFile->cd(path.c_str());
268 TH1D *nosol =
new TH1D(
"nosol",
"nosol", 7, 0, 7);
276 nosol->Write(nosol->GetName(), TObject::kOverwrite);
291 fStuff.
nutau1 = PtEtaPhiMVector(0., 0., 0., 0.);
292 fStuff.
nutau2 = PtEtaPhiMVector(0., 0., 0., 0.);
293 fStuff.
vistau1 = PtEtaPhiMVector(0., 0., 0., 0.);
294 fStuff.
vistau2 = PtEtaPhiMVector(0., 0., 0., 0.);
306 Info(
"DiTauMassTools",
"Retrieving output from fDitauStuffFit");
311 double q1 = (1. - 0.68) / 2.;
338 PtEtaPhiMVector tlvdummy(0., 0., 0., 0.);
339 XYVector metdummy(0., 0.);
380 PtEtaPhiMVector dummy_vec1(0.0, 0.0, 0.0, 0.0);
381 PtEtaPhiMVector dummy_vec2(0.0, 0.0, 0.0, 0.0);
382 for (
int i = 0; i < 3; i++) {
404 Info(
"DiTauMassTools",
405 ".........................Other input.....................................");
406 Info(
"DiTauMassTools",
"%s",
407 (
"Beam energy =" + std::to_string(
preparedInput.m_beamEnergy) +
408 " sqrt(S) for collisions =" + std::to_string(2.0 *
preparedInput.m_beamEnergy))
410 Info(
"DiTauMassTools",
"%s",
413 Info(
"DiTauMassTools",
"%s",
414 (
"LFV mode " + std::to_string(
preparedInput.m_LFVmode) +
" seed=" + std::to_string(
m_seed))
416 Info(
"DiTauMassTools",
"%s", (
"usetauProbability=" + std::to_string(
Prob->GetUseTauProbability()) +
417 " useTailCleanup=" + std::to_string(
preparedInput.m_fUseTailCleanup))
421 Info(
"DiTauMassTools",
422 "tau1 and tau2 were internally swapped (visible on prepared input printout)");
424 Info(
"DiTauMassTools",
"tau1 and tau2 were NOT internally swapped");
427 Info(
"DiTauMassTools",
"%s",
428 (
" MEtLMin=" + std::to_string(
m_MEtLMin) +
" MEtLMax=" + std::to_string(
m_MEtLMax)).c_str());
429 Info(
"DiTauMassTools",
"%s",
430 (
" MEtPMin=" + std::to_string(
m_MEtPMin) +
" MEtPMax=" + std::to_string(
m_MEtPMax)).c_str());
431 Info(
"DiTauMassTools",
"%s",
432 (
" Phi1Min=" + std::to_string(
m_Phi1Min) +
" Phi1Max=" + std::to_string(
m_Phi1Max)).c_str());
433 Info(
"DiTauMassTools",
"%s",
434 (
" Phi2Min=" + std::to_string(
m_Phi2Min) +
" Phi2Max=" + std::to_string(
m_Phi2Max)).c_str());
435 Info(
"DiTauMassTools",
"%s",
436 (
" Mnu1Min=" + std::to_string(
m_Mnu1Min) +
" Mnu1Max=" + std::to_string(
m_Mnu1Max)).c_str());
437 Info(
"DiTauMassTools",
"%s",
438 (
" Mnu2Min=" + std::to_string(
m_Mnu2Min) +
" Mnu2Max=" + std::to_string(
m_Mnu2Max)).c_str());
447 const PtEtaPhiMVector *origVisTau1 = 0;
448 const PtEtaPhiMVector *origVisTau2 = 0;
461 Info(
"DiTauMassTools",
462 "------------- Printing Final Results for MissingMassCalculator --------------");
463 Info(
"DiTauMassTools",
464 ".............................................................................");
465 Info(
"DiTauMassTools",
"%s", (
"Fit status=" + std::to_string(
OutputInfo.m_FitStatus)).c_str());
468 Info(
"DiTauMassTools",
"%s",
471 Info(
"DiTauMassTools",
"%s",
472 (
" signif=" + std::to_string(
OutputInfo.m_FitSignificance[imeth])).c_str());
473 Info(
"DiTauMassTools",
"%s", (
" mass=" + std::to_string(
OutputInfo.m_FittedMass[imeth])).c_str());
474 Info(
"DiTauMassTools",
"%s", (
" rms/mpv=" + std::to_string(
OutputInfo.m_RMS2MPV)).c_str());
477 Info(
"DiTauMassTools",
" no 4-momentum or MET from this method ");
482 Info(
"DiTauMassTools",
" fit failed ");
485 const PtEtaPhiMVector &tlvnu1 =
OutputInfo.m_nuvec1[imeth];
486 const PtEtaPhiMVector &tlvnu2 =
OutputInfo.m_nuvec2[imeth];
487 const PtEtaPhiMVector &tlvo1 =
OutputInfo.m_objvec1[imeth];
488 const PtEtaPhiMVector &tlvo2 =
OutputInfo.m_objvec2[imeth];
489 const XYVector &tvmet =
OutputInfo.m_FittedMetVec[imeth];
491 Info(
"DiTauMassTools",
"%s",
492 (
" Neutrino-1: P=" + std::to_string(tlvnu1.P()) +
" Pt=" + std::to_string(tlvnu1.Pt()) +
493 " Eta=" + std::to_string(tlvnu1.Eta()) +
" Phi=" + std::to_string(tlvnu1.Phi()) +
494 " M=" + std::to_string(tlvnu1.M()) +
" Px=" + std::to_string(tlvnu1.Px()) +
495 " Py=" + std::to_string(tlvnu1.Py()) +
" Pz=" + std::to_string(tlvnu1.Pz()))
497 Info(
"DiTauMassTools",
"%s",
498 (
" Neutrino-2: P=" + std::to_string(tlvnu2.P()) +
" Pt=" + std::to_string(tlvnu2.Pt()) +
499 " Eta=" + std::to_string(tlvnu2.Eta()) +
" Phi=" + std::to_string(tlvnu2.Phi()) +
500 " M=" + std::to_string(tlvnu2.M()) +
" Px=" + std::to_string(tlvnu2.Px()) +
501 " Py=" + std::to_string(tlvnu2.Py()) +
" Pz=" + std::to_string(tlvnu2.Pz()))
503 Info(
"DiTauMassTools",
"%s",
504 (
" Tau-1: P=" + std::to_string(tlvo1.P()) +
" Pt=" + std::to_string(tlvo1.Pt()) +
505 " Eta=" + std::to_string(tlvo1.Eta()) +
" Phi=" + std::to_string(tlvo1.Phi()) +
506 " M=" + std::to_string(tlvo1.M()) +
" Px=" + std::to_string(tlvo1.Px()) +
507 " Py=" + std::to_string(tlvo1.Py()) +
" Pz=" + std::to_string(tlvo1.Pz()))
509 Info(
"DiTauMassTools",
"%s",
510 (
" Tau-2: P=" + std::to_string(tlvo2.P()) +
" Pt=" + std::to_string(tlvo2.Pt()) +
511 " Eta=" + std::to_string(tlvo2.Eta()) +
" Phi=" + std::to_string(tlvo2.Phi()) +
512 " M=" + std::to_string(tlvo2.M()) +
" Px=" + std::to_string(tlvo2.Px()) +
513 " Py=" + std::to_string(tlvo2.Py()) +
" Pz=" + std::to_string(tlvo2.Pz()))
516 Info(
"DiTauMassTools",
"%s",
517 (
" dR(nu1-visTau1)=" + std::to_string(DeltaR(tlvnu1,*origVisTau1))).c_str());
518 Info(
"DiTauMassTools",
"%s",
519 (
" dR(nu2-visTau2)=" + std::to_string(DeltaR(tlvnu2,*origVisTau2))).c_str());
521 Info(
"DiTauMassTools",
"%s",
522 (
" Fitted MET =" + std::to_string(tvmet.R()) +
" Phi=" + std::to_string(tlvnu1.Phi()) +
523 " Px=" + std::to_string(tvmet.X()) +
" Py=" + std::to_string(tvmet.Y()))
526 Info(
"DiTauMassTools",
"%s", (
" Resonance: P=" + std::to_string(
OutputInfo.m_totalvec[imeth].P()) +
527 " Pt=" + std::to_string(
OutputInfo.m_totalvec[imeth].Pt()) +
528 " Eta=" + std::to_string(
OutputInfo.m_totalvec[imeth].Eta()) +
529 " Phi=" + std::to_string(
OutputInfo.m_totalvec[imeth].Phi()) +
530 " M=" + std::to_string(
OutputInfo.m_totalvec[imeth].M()) +
531 " Px=" + std::to_string(
OutputInfo.m_totalvec[imeth].Px()) +
532 " Py=" + std::to_string(
OutputInfo.m_totalvec[imeth].Py()) +
533 " Pz=" + std::to_string(
OutputInfo.m_totalvec[imeth].Pz()))
548 const double &phi1,
const double &phi2,
549 int &nsol1,
int &nsol2) {
570 int solution_code = 0;
588 if (pTmiss2 * dPhiSign < 0) {
590 return solution_code;
596 if (pTmiss1 * (-dPhiSign) < 0) {
598 return solution_code;
607 double m4noma1 = m2noma1 * m2noma1;
609 double p2v1proj = std::pow(pv1proj, 2);
611 double pTmiss2CscDPhi = pTmiss2 / sinDPhi2;
612 double &pTn1 = pTmiss2CscDPhi;
613 double pT2miss2CscDPhi = pTmiss2CscDPhi * pTmiss2CscDPhi;
616 const double discri1 = m4noma1 + 4 * m2noma1 * pTmiss2CscDPhi * pv1proj -
617 4 * (
m_ET2v1 * (
m_m2Nu1 + pT2miss2CscDPhi) - (pT2miss2CscDPhi * p2v1proj));
622 return solution_code;
630 double m4noma2 = m2noma2 * m2noma2;
632 double p2v2proj = std::pow(pv2proj, 2);
633 double sinDPhi1 = -sinDPhi2;
634 double pTmiss1CscDPhi = pTmiss1 / sinDPhi1;
635 double &pTn2 = pTmiss1CscDPhi;
636 double pT2miss1CscDPhi = pTmiss1CscDPhi * pTmiss1CscDPhi;
638 const double discri2 = m4noma2 + 4 * m2noma2 * pTmiss1CscDPhi * pv2proj -
639 4 * (
m_ET2v2 * (
m_m2Nu2 + pT2miss1CscDPhi) - (pT2miss1CscDPhi * p2v2proj));
644 return solution_code;
650 double sqdiscri1 = sqrt(discri1);
656 double pn1Z = first1 + second1;
658 if (m2noma1 + 2 * pTmiss2CscDPhi * pv1proj + 2 * pn1Z *
m_tauVec1Pz >
662 sqrt(std::pow(pTn1, 2) + std::pow(pn1Z, 2) +
m_m2Nu1));
667 pn1Z = first1 - second1;
669 if (m2noma1 + 2 * pTmiss2CscDPhi * pv1proj + 2 * pn1Z *
m_tauVec1Pz >
674 sqrt(std::pow(pTn1, 2) + std::pow(pn1Z, 2) +
m_m2Nu1));
681 return solution_code;
686 double sqdiscri2 = sqrt(discri2);
692 double pn2Z = first2 + second2;
694 if (m2noma2 + 2 * pTmiss1CscDPhi * pv2proj + 2 * pn2Z *
m_tauVec2Pz >
698 sqrt(std::pow(pTn2, 2) + std::pow(pn2Z, 2) +
m_m2Nu2));
703 pn2Z = first2 - second2;
706 if (m2noma2 + 2 * pTmiss1CscDPhi * pv2proj + 2 * pn2Z *
m_tauVec2Pz >
710 sqrt(std::pow(pTn2, 2) + std::pow(pn2Z, 2) +
m_m2Nu2));
717 return solution_code;
733 if (std::abs(pnux - pTmissx) > 0.001 || std::abs(pnuy - pTmissy) > 0.001) {
734 Info(
"DiTauMassTools",
"%s", (
"NuPsolutionV3 ERROR Pnux-Met.X or Pnuy-Met.Y > 0.001 : " +
735 std::to_string(pnux - pTmissx) +
" and " +
736 std::to_string(pnuy - pTmissx) +
" " +
"Invalid solutions")
739 if (std::abs(mtau1plus -
m_mTau) > 0.001 || std::abs(mtau1moins -
m_mTau) > 0.001 ||
740 std::abs(mtau2plus -
m_mTau) > 0.001 || std::abs(mtau2moins -
m_mTau) > 0.001) {
741 Info(
"DiTauMassTools",
"%s", (
"NuPsolutionV3 ERROR tau mass not recovered : " +
742 std::to_string(mtau1plus) +
" " + std::to_string(mtau1moins) +
" " +
743 std::to_string(mtau2plus) +
" " + std::to_string(mtau2moins))
748 return solution_code;
753 const PtEtaPhiMVector &tau,
const double &l_nu,
754 std::vector<PtEtaPhiMVector> &nu_vec) {
755 int solution_code = 0;
758 PxPyPzMVector nu(met_vec.X(), met_vec.Y(), 0.0, l_nu);
759 PxPyPzMVector nu2(met_vec.X(), met_vec.Y(), 0.0, l_nu);
763 double msq = (Mtau * Mtau - tau.M() * tau.M() - l_nu * l_nu) /
765 double gamma = nu.Px() * nu.Px() + nu.Py() * nu.Py();
766 double beta = tau.Px() * nu.Px() + tau.Py() * nu.Py() + msq;
767 double a = tau.E() * tau.E() - tau.Pz() * tau.Pz();
768 double b = -2 * tau.Pz() * beta;
769 double c = tau.E() * tau.E() * gamma - beta * beta;
770 if ((b * b - 4 *
a * c) < 0)
771 return solution_code;
774 double pvz1 = (-b + sqrt(b * b - 4 *
a * c)) / (2 *
a);
775 double pvz2 = (-b - sqrt(b * b - 4 *
a * c)) / (2 *
a);
777 nu.SetCoordinates(met_vec.X(), met_vec.Y(), pvz1, l_nu);
778 nu2.SetCoordinates(met_vec.X(), met_vec.Y(), pvz2, l_nu);
780 PtEtaPhiMVector return_nu(nu.Pt(), nu.Eta(), nu.Phi(), nu.M());
781 PtEtaPhiMVector return_nu2(nu2.Pt(), nu2.Eta(), nu2.Phi(), nu2.M());
782 nu_vec.push_back(return_nu);
783 nu_vec.push_back(return_nu2);
784 return solution_code;
847 bool paramInsideRange =
false;
866 if (paramInsideRange)
890 if (nsuccesses > 0) {
896 double Px1, Py1, Pz1;
897 double Px2, Py2, Pz2;
898 if (nsuccesses > 0) {
919 if (prob_hist != 0.0)
943 PxPyPzMVector fulltau1, fulltau2;
965 Info(
"DiTauMassTools",
"Scanning ");
966 Info(
"DiTauMassTools",
" Markov ");
967 Info(
"DiTauMassTools",
"%s",
968 (
" V9W niters=" + std::to_string(
m_iter0) +
" " + std::to_string(
m_iter1)).c_str());
969 Info(
"DiTauMassTools",
"%s", (
" nFullScan " + std::to_string(
m_markovNFullScan)).c_str());
970 Info(
"DiTauMassTools",
"%s", (
" nRejectNoSol " + std::to_string(
m_markovNRejectNoSol)).c_str());
972 Info(
"DiTauMassTools",
"%s", (
" nAccept " + std::to_string(
m_markovNAccept)).c_str());
973 Info(
"DiTauMassTools",
"%s",
980 Info(
"DiTauMassTools",
"%s", (
"!!!----> Warning-3 in "
981 "MissingMassCalculator::DitauMassCalculatorV9Walk() : fit status=" +
982 std::to_string(fit_code))
984 Info(
"DiTauMassTools",
"%s",
"....... No solution is found. Printing input info .......");
986 Info(
"DiTauMassTools",
"%s", (
" vis Tau-1: Pt=" + std::to_string(
preparedInput.m_vistau1.Pt()) +
992 Info(
"DiTauMassTools",
"%s", (
" vis Tau-2: Pt=" + std::to_string(
preparedInput.m_vistau2.Pt()) +
998 Info(
"DiTauMassTools",
"%s", (
" MET=" + std::to_string(
preparedInput.m_MetVec.R()) +
1002 Info(
"DiTauMassTools",
" ---------------------------------------------------------- ");
1044 double METresX_binSize = 2 * N_METsigma * METresX / NiterMET;
1045 double METresY_binSize = 2 * N_METsigma * METresY / NiterMET;
1049 std::vector<PtEtaPhiMVector> nu_vec;
1054 double metprob = 1.0;
1055 double sign_tmp = 0.0;
1056 double tauprob = 1.0;
1057 double totalProb = 0.0;
1061 double met_smear_x = 0.0;
1062 double met_smear_y = 0.0;
1063 double met_smearL = 0.0;
1064 double met_smearP = 0.0;
1066 double angle1 = 0.0;
1090 const double met_coscovphi = cos(
preparedInput.m_METcovphi);
1091 const double met_sincovphi = sin(
preparedInput.m_METcovphi);
1106 Info(
"DiTauMassTools",
"Running in dilepton mode");
1111 PtEtaPhiMVector tau_tmp(0.0, 0.0, 0.0, 0.0);
1112 PtEtaPhiMVector lep_tmp(0.0, 0.0, 0.0, 0.0);
1152 double Mlep = tau_tmp.M();
1159 double MnuProb = 1.0;
1161 for (
int i3 = 0; i3 < NiterMnu; i3++)
1163 M_nu = Mnu_binSize * i3;
1164 if (M_nu >= (Mtau - Mlep))
1170 for (
int i4 = 0; i4 < NiterMET + 1; i4++)
1172 met_smearL = METresX_binSize * i4 - N_METsigma * METresX;
1173 for (
int i5 = 0; i5 < NiterMET + 1; i5++)
1175 met_smearP = METresY_binSize * i5 - N_METsigma * METresY;
1176 if (pow(met_smearL / METresX, 2) + pow(met_smearP / METresY, 2) > pow(N_METsigma, 2))
1178 met_smear_x = met_smearL * met_coscovphi - met_smearP * met_sincovphi;
1179 met_smear_y = met_smearL * met_sincovphi + met_smearP * met_coscovphi;
1180 metvec_tmp.SetXY(input_metX + met_smear_x, input_metY + met_smear_y);
1195 metprob =
Prob->MetProbability(
preparedInput, met_smearL, met_smearP, METresX, METresY);
1198 for (
unsigned int j1 = 0; j1 < nu_vec.size(); j1++) {
1199 if (tau_tmp.E() + nu_vec[j1].E() >=
preparedInput.m_beamEnergy)
1201 const double tau1_tmpp = (tau_tmp + nu_vec[j1]).
P();
1202 angle1 =
Angle(nu_vec[j1], tau_tmp);
1212 double tauvecprob1j =
1214 if (tauvecprob1j == 0.)
1216 tauprob =
Prob->TauProbabilityLFV(
preparedInput, tau_type_tmp, tau_tmp, nu_vec[j1]);
1217 totalProb = tauvecprob1j * metprob * MnuProb * tauprob;
1234 m_fPXfit1->Fill((tau_tmp + nu_vec[j1]).Px(), totalProb);
1235 m_fPYfit1->Fill((tau_tmp + nu_vec[j1]).Py(), totalProb);
1236 m_fPZfit1->Fill((tau_tmp + nu_vec[j1]).Pz(), totalProb);
1240 sign_tmp = -log10(totalProb);
1264 Info(
"DiTauMassTools",
"Running in lepton+tau mode");
1290 PtEtaPhiMVector tau_tmp(0.0, 0.0, 0.0, 0.0);
1291 PtEtaPhiMVector lep_tmp(0.0, 0.0, 0.0, 0.0);
1305 for (
int i4 = 0; i4 < NiterMET + 1; i4++)
1307 met_smearL = METresX_binSize * i4 - N_METsigma * METresX;
1308 for (
int i5 = 0; i5 < NiterMET + 1; i5++)
1310 met_smearP = METresY_binSize * i5 - N_METsigma * METresY;
1311 if (pow(met_smearL / METresX, 2) + pow(met_smearP / METresY, 2) > pow(N_METsigma, 2))
1315 metvec_tmp.SetXY(input_metX + met_smear_x, input_metY + met_smear_y);
1330 metprob =
Prob->MetProbability(
preparedInput, met_smearL, met_smearP, METresX, METresY);
1333 for (
unsigned int j1 = 0; j1 < nu_vec.size(); j1++) {
1334 if (tau_tmp.E() + nu_vec[j1].E() >=
preparedInput.m_beamEnergy)
1336 const double tau1_tmpp = (tau_tmp + nu_vec[j1]).
P();
1337 angle1 =
Angle(nu_vec[j1], tau_tmp);
1347 double tauvecprob1j =
1349 if (tauvecprob1j == 0.)
1351 tauprob =
Prob->TauProbabilityLFV(
preparedInput, tau_type_tmp, tau_tmp, nu_vec[j1]);
1352 totalProb = tauvecprob1j * metprob * tauprob;
1375 sign_tmp = -log10(totalProb);
1401 Info(
"DiTauMassTools",
"Running in an unknown mode?!?!");
1408 Info(
"DiTauMassTools",
"%s",
1409 (
"SpeedUp niters=" + std::to_string(iter0) +
" " + std::to_string(
m_iter1) +
" " +
1430 if (prob_hist != 0.0)
1448 PxPyPzMVector nu1_tmp(0.0, 0.0, 0.0, 0.0);
1449 PxPyPzMVector nu2_tmp(0.0, 0.0, 0.0, 0.0);
1469 if (fit_code == 0) {
1471 "DiTauMassTools",
"%s",
1472 (
"!!!----> Warning-3 in MissingMassCalculator::DitauMassCalculatorV9lfv() : fit status=" +
1473 std::to_string(fit_code))
1475 Info(
"DiTauMassTools",
"....... No solution is found. Printing input info .......");
1477 Info(
"DiTauMassTools",
"%s", (
" vis Tau-1: Pt="+std::to_string(
preparedInput.m_vistau1.Pt())
1480 +
" type="+std::to_string(
preparedInput.m_type_visTau1)).c_str());
1481 Info(
"DiTauMassTools",
"%s", (
" vis Tau-2: Pt="+std::to_string(
preparedInput.m_vistau2.Pt())
1484 +
" type="+std::to_string(
preparedInput.m_type_visTau2)).c_str());
1485 Info(
"DiTauMassTools",
"%s", (
" MET="+std::to_string(
preparedInput.m_MetVec.R())+
" Met_X="+std::to_string(
preparedInput.m_MetVec.X())
1486 +
" Met_Y="+std::to_string(
preparedInput.m_MetVec.Y())).c_str());
1487 Info(
"DiTauMassTools",
" ---------------------------------------------------------- ");
1498 const double mM =
x[0];
1499 const double mMax = par[0];
1500 const double mMean = par[1];
1501 const double mInvWidth2 = par[2];
1503 const double fitval = mMax * (1 - 4 * mInvWidth2 * std::pow(mM - mMean, 2));
1516 const int winHalfWidth,
bool debug) {
1522 throw std::runtime_error(
"MissingMassCalculator::maxFromHist: histogram pointer is null.");
1527 for (std::vector<double>::iterator itr = histInfo.begin(); itr != histInfo.end(); ++itr) {
1536 winHalfWidth == 0)) {
1540 int max_bin = theHist->GetMaximumBin();
1541 maxPos = theHist->GetBinCenter(max_bin);
1544 prob = theHist->GetBinContent(max_bin) / double(theHist->GetEntries());
1551 int hNbins = theHist->GetNbinsX();
1556 int max_bin = theHist->GetMaximumBin();
1557 int iBinMin = max_bin - winHalfWidth;
1560 int iBinMax = max_bin + winHalfWidth;
1561 if (iBinMax > hNbins)
1562 iBinMax = hNbins - 1;
1565 for (
int iBin = iBinMin; iBin <= iBinMax; ++iBin) {
1566 const double weight = theHist->GetBinContent(iBin);
1568 sumx += weight * theHist->GetBinCenter(iBin);
1570 maxPos = (sumw != 0.) ? (sumx / sumw) : 0.;
1573 prob = sumw / theHist->GetEntries();
1583 Error(
"DiTauMassTools",
"%s",
1584 (
"ERROR undefined maxHistStrategy:" + std::to_string(maxHistStrategy)).c_str());
1590 int lastNonZeroBin = -1;
1591 int firstNonZeroBin = -1;
1592 double totalSumw = 0.;
1593 bool firstNullPart =
true;
1594 for (
int iBin = 0; iBin < hNbins; ++iBin) {
1595 const double weight = theHist->GetBinContent(iBin);
1597 totalSumw += weight;
1598 lastNonZeroBin = iBin;
1599 if (firstNullPart) {
1600 firstNullPart =
false;
1601 firstNonZeroBin = iBin;
1608 firstNonZeroBin = std::max(0, firstNonZeroBin - winHalfWidth - 1);
1609 lastNonZeroBin = std::min(hNbins - 1, lastNonZeroBin + winHalfWidth + 1);
1618 const int nwidth = 2 * winHalfWidth + 1;
1621 for (
int ibin = 0; ibin < nwidth; ++ibin) {
1622 winsum += theHist->GetBinContent(ibin);
1624 double winmax = winsum;
1627 int iBinL = firstNonZeroBin;
1628 int iBinR = iBinL + 2 * winHalfWidth;
1629 bool goingUp =
true;
1634 const double deltawin = theHist->GetBinContent(iBinR) - theHist->GetBinContent(iBinL - 1);
1640 if (winsum > winmax) {
1643 max_bin = (iBinR + iBinL) / 2 - 1;
1654 }
while (iBinR < lastNonZeroBin);
1657 int iBinMin = max_bin - winHalfWidth;
1660 int iBinMax = max_bin + winHalfWidth;
1661 if (iBinMax >= hNbins)
1662 iBinMax = hNbins - 1;
1665 for (
int iBin = iBinMin; iBin <= iBinMax; ++iBin) {
1666 const double weight = theHist->GetBinContent(iBin);
1668 sumx += weight * theHist->GetBinCenter(iBin);
1671 double maxPosWin = -1.;
1674 maxPosWin = sumx / sumw;
1677 prob = sumw / totalSumw;
1681 const double h_rms = theHist->GetRMS(1);
1685 double numerator = 0;
1686 double denominator = 0;
1687 bool nullBin =
false;
1689 for (
int i = iBinMin; i < iBinMax; ++i) {
1690 double binError = theHist->GetBinError(i);
1691 if (binError < 1e-10) {
1694 double binErrorSquare = std::pow(binError, 2);
1695 num = theHist->GetBinContent(i) / (binErrorSquare);
1696 numerator = numerator + num;
1697 denominator = denominator + (1 / (binErrorSquare));
1699 if (numerator < 1e-10 || denominator < 1e-10 || nullBin ==
true) {
1702 histInfo[
HistInfo::MEANBIN] = sqrt(1 / denominator) / (numerator / denominator);
1715 const double binWidth = theHist->GetBinCenter(2) - theHist->GetBinCenter(1);
1716 double fitWidth = (winHalfWidth + 0.5) *
binWidth;
1729 TString fitOption =
debug ?
"QS" :
"QNS";
1732 m_fFitting->SetParameters(sumw / winHalfWidth, maxPos, 0.0025);
1735 TFitResultPtr fitRes =
1736 theHist->Fit(
m_fFitting, fitOption,
"", maxPos - fitWidth, maxPos + fitWidth);
1738 double maxPosFit = -1.;
1740 if (
int(fitRes) == 0) {
1743 const double mMax = fitRes->Parameter(0);
1744 const double mMean = fitRes->Parameter(1);
1745 const double mInvWidth2 = fitRes->Parameter(2);
1746 double mMaxError = fitRes->ParError(0);
1748 double mMeanError = fitRes->ParError(1);
1750 double mInvWidth2Error = fitRes->ParError(2);
1753 mInvWidth2Error = 0.;
1754 const double c = mMax * (1 - 4 * mMean * mMean * mInvWidth2);
1755 const double b = 8 * mMax * mMean * mInvWidth2;
1756 const double a = -4 * mMax * mInvWidth2;
1762 const double h_discri = b * b - 4 *
a * c;
1764 const double sqrth_discri = sqrt(h_discri);
1765 const double h_fitLength = sqrth_discri /
a;
1772 maxPosFit = -b / (2 *
a);
1776 if (maxPosFit >= 0. and std::abs(maxPosFit - maxPosWin) < 0.8 * fitWidth) {
1794 const double &M_nu1,
1795 const double &M_nu2) {
1801 const int solution =
NuPsolutionV3(M_nu1, M_nu2, phi1, phi2, nsol1, nsol2);
1820 const int nsol1,
const int nsol2,
1821 const double &Mvis,
const double &Meff)
1827 Error(
"DiTauMassTools",
"%s",
1828 (
"refineSolutions ERROR probFinalSolVec.size() should be " + std::to_string(
m_nsolfinalmax))
1831 Error(
"DiTauMassTools",
"%s",
1832 (
"refineSolutions ERROR mtautauSolVec.size() should be " + std::to_string(
m_nsolfinalmax))
1835 Error(
"DiTauMassTools",
"%s",
1836 (
"refineSolutions ERROR nu1FinalSolVec.size() should be " + std::to_string(
m_nsolfinalmax))
1839 Error(
"DiTauMassTools",
"%s",
1840 (
"refineSolutions ERROR nu2FinalSolVec.size() should be " + std::to_string(
m_nsolfinalmax))
1843 Error(
"DiTauMassTools",
"%s", (
"refineSolutions ERROR nsol1 " + std::to_string(nsol1) +
1844 " > nsolmax !" + std::to_string(
m_nsolmax))
1847 Error(
"DiTauMassTools",
"%s", (
"refineSolutions ERROR nsol1 " + std::to_string(nsol2) +
1848 " > nsolmax !" + std::to_string(
m_nsolmax))
1854 Prob->apply(
preparedInput, -99, -99, PtEtaPhiMVector(0, 0, 0, 0), PtEtaPhiMVector(0, 0, 0, 0),
1855 PtEtaPhiMVector(0, 0, 0, 0), PtEtaPhiMVector(0, 0, 0, 0),
true,
false,
false);
1857 for (
int j1 = 0; j1 < nsol1; ++j1) {
1867 const int pickInt = std::abs(10000 *
m_Phi1);
1868 const int pickDigit = pickInt - 10 * (pickInt / 10);
1876 nuvec1_tmpj.SetCoordinates(nuvec1_tmpj.Pt(), nuvec1_tmpj.Eta(), nuvec1_tmpj.Phi(), M_nu1);
1877 tauvecsol1j.SetPxPyPzE(0., 0., 0., 0.);
1878 tauvecsol1j += nuvec1_tmpj;
1883 PtEtaPhiMVector(0, 0, 0, 0), nuvec1_tmpj,
1884 PtEtaPhiMVector(0, 0, 0, 0),
false,
true,
false);
1888 for (
int j2 = 0; j2 < nsol2; ++j2) {
1899 const int pickInt = std::abs(10000 *
m_Phi2);
1900 const int pickDigit = pickInt - 10 * int(pickInt / 10);
1908 nuvec2_tmpj.SetCoordinates(nuvec2_tmpj.Pt(), nuvec2_tmpj.Eta(), nuvec2_tmpj.Phi(), M_nu2);
1909 tauvecsol2j.SetPxPyPzE(0., 0., 0., 0.);
1910 tauvecsol2j += nuvec2_tmpj;
1916 PtEtaPhiMVector(0, 0, 0, 0), nuvec2_tmpj,
false,
true,
false);
1920 if (tauvecprob1j == 0.)
1922 if (tauvecprob2j == 0.)
1925 double totalProb = 1.;
1938 (constProb * tauvecprob1j * tauvecprob2j *
1942 if (totalProb <= 0) {
1944 Warning(
"DiTauMassTools",
"%s",
1945 (
"null proba solution, rejected "+std::to_string(totalProb)).c_str());
1952 Error(
"DiTauMassTools",
"%s",
1953 (
"refineSolutions ERROR nsol getting larger than nsolfinalmax!!! " +
1956 Error(
"DiTauMassTools",
"%s",
1957 (
" j1 " + std::to_string(j1) +
" j2 " + std::to_string(j2) +
" nsol1 " +
1958 std::to_string(nsol1) +
" nsol2 " + std::to_string(nsol2))
1965 throw std::out_of_range(
"refineSolutions: index m_nsol out of range.");
1974 nu1Final.SetPxPyPzE(nuvec1_tmpj.Px(), nuvec1_tmpj.Py(), nuvec1_tmpj.Pz(), nuvec1_tmpj.E());
1975 nu2Final.SetPxPyPzE(nuvec2_tmpj.Px(), nuvec2_tmpj.Py(), nuvec2_tmpj.Pz(), nuvec2_tmpj.E());
1982 if (ngoodsol1 == 0) {
1985 if (ngoodsol2 == 0) {
1992 const PtEtaPhiMVector &nu1,
1993 const PtEtaPhiMVector &vis2,
1994 const PtEtaPhiMVector &nu2,
const double &mmc_mass,
1995 const double &vis_mass,
const double &eff_mass,
1996 const double &dphiTT) {
2007 const double MrecoMvis = mmc_mass / vis_mass;
2008 if (MrecoMvis > 2.6)
2010 const double MrecoMeff = mmc_mass / eff_mass;
2011 if (MrecoMeff > 1.9)
2013 const double e1p1 = nu1.E() / vis1.P();
2014 const double e2p2 = nu2.E() / vis2.P();
2015 if ((e1p1 + e2p2) > 4.5)
2034 if (
Prob->GetUseHT()) {
2035 const double MrecoMvis = mmc_mass / vis_mass;
2036 const double MrecoMeff = mmc_mass / eff_mass;
2037 const double x = dphiTT > 1.5 ? dphiTT : 1.5;
2038 if ((MrecoMeff + MrecoMvis) > 5.908 - 1.881 *
x + 0.2995 *
x *
x)
2051 double totalProbSumSol = 0.;
2052 double totalProbSumSolOld = 0.;
2053 bool firstPointWithSol =
false;
2055 for (
int isol = 0; isol <
m_nsol; ++isol) {
2060 bool notSureToKeep =
true;
2064 notSureToKeep =
false;
2071 firstPointWithSol =
true;
2083 if (notSureToKeep) {
2086 for (
int isol = 0; isol <
m_nsolOld; ++isol) {
2092 if (!firstPointWithSol && totalProbSumSolOld <= 0.) {
2093 Error(
"DiTauMassTools",
"%s",
2094 (
" ERROR null old probability !!! " + std::to_string(totalProbSumSolOld) +
" nsolOld " +
2098 }
else if (totalProbSumSol > totalProbSumSolOld) {
2103 }
else if (totalProbSumSol < totalProbSumSolOld * 1E-6) {
2107 }
else if (
m_nsol <= 0) {
2114 reject = (uMC > totalProbSumSol / totalProbSumSolOld);
2139 bool fillSolution =
true;
2140 bool oldToBeUsed =
false;
2148 fillSolution =
false;
2162 if (!firstPointWithSol) {
2163 fillSolution =
true;
2166 fillSolution =
false;
2173 if (!fillSolution) {
2174 if (firstPointWithSol) {
2177 for (
int isol = 0; isol <
m_nsol; ++isol) {
2189 double solSum2 = 0.;
2191 for (
int isol = 0; isol <
m_nsol; ++isol) {
2195 const PtEtaPhiMVector *pnuvec1_tmpj;
2196 const PtEtaPhiMVector *pnuvec2_tmpj;
2204 const PtEtaPhiMVector &nuvec1_tmpj = *pnuvec1_tmpj;
2205 const PtEtaPhiMVector &nuvec2_tmpj = *pnuvec2_tmpj;
2208 solSum2 += mtautau * mtautau;
2230 if (mtautau != 0. && weight != 0.)
2295 for (
int isol = 0; isol <
m_nsol; ++isol) {
2307 const double solRMS = sqrt(solSum2 /
m_nsol - std::pow(solSum /
m_nsol, 2));
2500 Info(
"DiTauMassTools",
" in m_meanbinToBeEvaluated && m_iterNsuc==500 ");
2515 double stopdouble = 500 * std::pow((meanbin /
m_meanbinStop), 2);
2516 int stopint = stopdouble;
2647 PtEtaPhiMVector Met4vec;
2720 const double &P_tau) {
2722#ifndef WITHDTHETA3DLIM
2724 if (limit_code == 0)
2726 if (limit_code == 1)
2728 if (limit_code == 2)
2734 if (limit_code == 0)
2736 double par[3] = {0.0, 0.0, 0.0};
2738 if (tau_type == 8) {
2739 if (limit_code == 0)
2745 if (limit_code == 1)
2751 if (limit_code == 2)
2759 if (tau_type >= 0 && tau_type <= 2) {
2760 if (limit_code == 0)
2764 par[2] = -0.0004859;
2766 if (limit_code == 1)
2772 if (limit_code == 2)
2780 if (tau_type >= 3 && tau_type <= 5) {
2781 if (limit_code == 0)
2785 par[2] = -0.0009458;
2787 if (limit_code == 1)
2793 if (limit_code == 2)
2801 if (std::abs(P_tau + par[1]) > 0.0)
2802 limit = par[0] / (P_tau + par[1]) + par[2];
2803 if (limit_code == 0) {
2806 }
else if (limit > 0.03) {
2810 if (limit < 0.0 || limit > 0.5 * TMath::Pi()) {
2811 limit = 0.5 * TMath::Pi();
2812 }
else if (limit < 0.05 && limit > 0.0) {
2841 if (LFVMode == -1) {
2843 }
else if (LFVMode != -2) {
2855 PtEtaPhiMVector fixedtau1;
2856 fixedtau1.SetCoordinates(tlvTau1.Pt() /
GEV, tlvTau1.Eta(), tlvTau1.Phi(), tlvTau1.M() /
GEV);
2857 PtEtaPhiMVector fixedtau2;
2858 fixedtau2.SetCoordinates(tlvTau2.Pt() /
GEV, tlvTau2.Eta(), tlvTau2.Phi(), tlvTau2.M() /
GEV);
2865 if (mmcType1 == 8 && mmcType2 == 8) {
2867 }
else if (mmcType1 >= 0 && mmcType1 <= 5 && mmcType2 >= 0 && mmcType2 <= 5) {
2873 Info(
"DiTauMassTools",
"%s", (
"running for tau types "+std::to_string(
preparedInput.m_type_visTau1)+
" "+std::to_string(
preparedInput.m_type_visTau2)).c_str());
2877 Info(
"DiTauMassTools",
"%s", (
"passing SumEt="+std::to_string(
met->sumet() /
GEV)).c_str());
2883 Error(
"DiTauMassTools",
"MMCCalibrationSet has not been set !. Please use "
2884 "fMMC.SetCalibrationSet(MMCCalibrationSet::MMC2019) or fMMC.SetCalibrationSet(MMCCalibrationSet::MMC2024)"
2919 for (
unsigned int i = 0; i <
preparedInput.m_jet4vecs.size(); i++) {
2926 Info(
"DiTauMassTools",
"correcting sumET");
3023 Info(
"DiTauMassTools",
"Substracting pt1 from sumEt");
3030 Info(
"DiTauMassTools",
"Substracting pt2 from sumEt");
3042 Prob->SetUseTauProbability(
true);
3045 Prob->SetUseTauProbability(
false);
3062 Prob->SetUseTauProbability(
false);
3064 Prob->SetUseTauProbability(
true);
3065 Prob->SetUseMnuProbability(
false);
3070 if (
Prob->GetUseHT())
3073 double HtOffset = 0.;
3078 HtOffset = 87.5 - 27.0 *
x;
3097 float hEmax = 3000.0;
3099 m_fMEtP_all = std::make_shared<TH1F>(
"MEtP_h1",
"M", hNbins, -100.0,
3101 m_fMEtL_all = std::make_shared<TH1F>(
"MEtL_h1",
"M", hNbins, -100.0,
3103 m_fMnu1_all = std::make_shared<TH1F>(
"Mnu1_h1",
"M", hNbins, 0.0,
3105 m_fMnu2_all = std::make_shared<TH1F>(
"Mnu2_h1",
"M", hNbins, 0.0,
3107 m_fPhi1_all = std::make_shared<TH1F>(
"Phi1_h1",
"M", hNbins, -10.0,
3109 m_fPhi2_all = std::make_shared<TH1F>(
"Phi2_h1",
"M", hNbins, -10.0,
3132 float hEmax = 3000.0;
3134 m_fMmass_split1 = std::make_shared<TH1F>(
"mass_h1_1",
"M", hNbins, 0.0, hEmax);
3135 m_fMEtP_split1 = std::make_shared<TH1F>(
"MEtP_h1_1",
"M", hNbins, -100.0, 100.0);
3136 m_fMEtL_split1 = std::make_shared<TH1F>(
"MEtL_h1_1",
"M", hNbins, -100.0, 100.0);
3137 m_fMnu1_split1 = std::make_shared<TH1F>(
"Mnu1_h1_1",
"M", hNbins, 0.0, hEmax);
3138 m_fMnu2_split1 = std::make_shared<TH1F>(
"Mnu2_h1_1",
"M", hNbins, 0.0, hEmax);
3139 m_fPhi1_split1 = std::make_shared<TH1F>(
"Phi1_h1_1",
"M", hNbins, -10.0, 10.0);
3140 m_fPhi2_split1 = std::make_shared<TH1F>(
"Phi2_h1_1",
"M", hNbins, -10.0, 10.0);
3141 m_fMmass_split2 = std::make_shared<TH1F>(
"mass_h1_2",
"M", hNbins, 0.0, hEmax);
3142 m_fMEtP_split2 = std::make_shared<TH1F>(
"MEtP_h1_2",
"M", hNbins, -100.0, 100.0);
3143 m_fMEtL_split2 = std::make_shared<TH1F>(
"MEtL_h1_2",
"M", hNbins, -100.0, 100.0);
3144 m_fMnu1_split2 = std::make_shared<TH1F>(
"Mnu1_h1_2",
"M", hNbins, 0.0, hEmax);
3145 m_fMnu2_split2 = std::make_shared<TH1F>(
"Mnu2_h1_2",
"M", hNbins, 0.0, hEmax);
3146 m_fPhi1_split2 = std::make_shared<TH1F>(
"Phi1_h1_2",
"M", hNbins, -10.0, 10.0);
3147 m_fPhi2_split2 = std::make_shared<TH1F>(
"Phi2_h1_2",
"M", hNbins, -10.0, 10.0);
3183 const bool kMMCsynchronize,
3184 double &mass,
double &xp1,
double &xp2) {
3186 TLorentzVector k1 = p0->p4();
3187 TLorentzVector k2 = p1->p4();
3190 if (kMMCsynchronize) {
3193 k1.SetPtEtaPhiM(k1.Pt(), k1.Eta(), k1.Phi(),
3194 tau0->nTracks() < 3 ? 800. : 1200.);
3199 k2.SetPtEtaPhiM(k2.Pt(), k2.Eta(), k2.Phi(),
3200 tau1->
nTracks() < 3 ? 800. : 1200.);
3210 if (K.Determinant() == 0)
3214 M(0, 0) =
met->mpx();
3215 M(1, 0) =
met->mpy();
3217 TMatrixD Kinv = K.Invert();
3222 double X1 = X(0, 0);
3223 double X2 = X(1, 0);
3224 double x1 = 1. / (1. + X1);
3225 double x2 = 1. / (1. + X2);
3227 TLorentzVector par1 = k1 * (1 / x1);
3228 TLorentzVector par2 = k2 * (1 / x2);
3230 double m = (par1 + par2).M();
3235 if (k1.Pt() > k2.Pt()) {
__HOSTDEV__ double Phi_mpi_pi(double)
A number of constexpr particle constants to avoid hardcoding them directly in various places.
Class providing the definition of the 4-vector interface.
size_t nTracks(TauJetParameters::TauTrackFlag flag=TauJetParameters::TauTrackFlag::classifiedCharged) const
constexpr double tauMassInMeV
the mass of the tau (in MeV)
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
@ Tau
The object is a tau (jet).
MissingET_v1 MissingET
Version control by type defintion.
TauJet_v3 TauJet
Definition of the current "tau version".