51 #include "valgrind/callgrind.h" 57 return (0.5 * par[0] * par[1] /
TMath::Pi()) /
58 TMath::Max(1.
e-10, (
x[0] - par[2]) * (
x[0] - par[2]) + .25 * par[1] * par[1]);
64 return par[0] *
exp(-0.5 * ((
x[0] - par[1]) / par[2]) * ((
x[0] - par[1]) / par[2]));
84 "GL",
"0.5/3.1415926*[0]/(pow(x-[1],2)+pow(0.5*[0],2))*exp(-0.5*pow((x-[2])/[3],2))/([3]*sqrt(6.283185))", 0, 1000);
86 TF2 *
GL2 =
new TF2(
"GL2",
87 "0.5/3.1415926*[0]/(pow(x-[1],2)+pow(0.5*[0],2))*exp(-0.5*pow((x-y)/[2],2))/([2]*sqrt(6.283185))",
170 std::vector<std::pair<lorentzVector, lorentzVector> >
172 std::vector<std::pair<lorentzVector, lorentzVector> >
174 std::vector<std::pair<lorentzVector, lorentzVector> >
176 std::vector<std::pair<MuScleFitMuon, MuScleFitMuon> >
178 std::vector<std::pair<MuScleFitMuon, MuScleFitMuon> >
181 std::vector<std::pair<lorentzVector, lorentzVector> >
280 std::pair<SimTrack, SimTrack> simMuFromBestRes;
281 double maxprob = -0.1;
285 for (std::vector<SimTrack>::const_iterator simMu1 = simMuons.begin(); simMu1 != simMuons.end(); simMu1++) {
286 for (std::vector<SimTrack>::const_iterator simMu2 = simMu1 + 1; simMu2 != simMuons.end(); simMu2++) {
287 if (((*simMu1).charge() * (*simMu2).charge()) > 0) {
292 double mcomb = ((*simMu1).momentum() + (*simMu2).momentum()).
mass();
293 double Y = ((*simMu1).momentum() + (*simMu2).momentum()).Rapidity();
294 for (
int ires = 0; ires < 6; ires++) {
297 if (
prob > maxprob) {
298 simMuFromBestRes.first = (*simMu1);
299 simMuFromBestRes.second = (*simMu2);
309 return simMuFromBestRes;
320 std::cout <<
"In findBestRecoRes" << std::endl;
322 std::pair<MuScleFitMuon, MuScleFitMuon> recMuFromBestRes;
326 double maxprob = -0.1;
327 double minDeltaMass = 999999;
328 std::pair<MuScleFitMuon, MuScleFitMuon> bestMassMuons;
332 std::cout <<
"muon_1_charge:" << (*Muon1).charge() << std::endl;
333 for (std::vector<MuScleFitMuon>::const_iterator Muon2 =
Muon1 + 1; Muon2 !=
muons.end(); ++Muon2) {
337 if ((((*Muon1).charge()) * ((*Muon2).charge())) > 0) {
342 double ch1 = (*Muon1).charge();
343 double ch2 = (*Muon2).charge();
344 double pt1 = (*Muon1).Pt();
345 double pt2 = (*Muon2).Pt();
346 double eta1 = (*Muon1).Eta();
347 double eta2 = (*Muon2).Eta();
350 eta2 < maxMuonEtaSecondRange_ && ch1 >= ch2
354 double mcomb = ((*Muon1).p4() + (*Muon2).p4()).
mass();
355 double Y = ((*Muon1).p4() + (*Muon2).p4()).Rapidity();
357 std::cout <<
"muon1 " << (*Muon1).p4().Px() <<
", " << (*Muon1).p4().Py() <<
", " << (*Muon1).p4().Pz()
358 <<
", " << (*Muon1).p4().E() <<
", " << (*Muon1).charge() << std::endl;
359 std::cout <<
"muon2 " << (*Muon2).p4().Px() <<
", " << (*Muon2).p4().Py() <<
", " << (*Muon2).p4().Pz()
360 <<
", " << (*Muon2).p4().E() <<
", " << (*Muon2).charge() << std::endl;
361 std::cout <<
"mcomb " << mcomb << std::endl;
363 double massResol = 0.;
368 for (
int ires = 0; ires < 6; ires++) {
373 if (
prob > maxprob) {
375 recMuFromBestRes.first = (*Muon1);
376 recMuFromBestRes.second = (*Muon2);
378 recMuFromBestRes.first = (*Muon2);
379 recMuFromBestRes.second = (*Muon1);
382 std::cout <<
"muon_1_charge (after swapping):" << recMuFromBestRes.first.charge() << std::endl;
391 if (deltaMass < minDeltaMass) {
392 bestMassMuons = std::make_pair((*
Muon1), (*Muon2));
393 minDeltaMass = deltaMass;
403 if (bestMassMuons.first.charge() < 0) {
404 recMuFromBestRes.first = bestMassMuons.first;
405 recMuFromBestRes.second = bestMassMuons.second;
407 recMuFromBestRes.second = bestMassMuons.first;
408 recMuFromBestRes.first = bestMassMuons.second;
411 return recMuFromBestRes;
431 std::cout <<
"Smearing Pt,eta,phi = " <<
pt <<
" " <<
eta <<
" " <<
phi <<
"; x = ";
438 double ptEtaPhiE[4] = {
pt,
eta,
phi, E};
448 std::cout <<
"pt before bias = " << ptEtaPhiE[0] << std::endl;
458 std::cout <<
"pt after bias = " << ptEtaPhiE[0] << std::endl;
466 double *
p =
new double[(
int)(parval.size())];
471 for (std::vector<double>::const_iterator it = parval.begin(); it != parval.end(); ++it, ++
id) {
488 std::cout <<
"pt before scale = " << ptEtaPhiE[0] << std::endl;
495 std::cout <<
"pt after scale = " << ptEtaPhiE[0] << std::endl;
503 double px = ptEtaPhiE[0] *
cos(ptEtaPhiE[2]);
504 double py = ptEtaPhiE[0] *
sin(ptEtaPhiE[2]);
505 double tmp = 2 * atan(
exp(-ptEtaPhiE[1]));
519 return (mu1 + mu2).mass();
526 const std::vector<double> &parval) {
538 double *
p =
new double[(
int)(parval.size())];
539 std::vector<double>::const_iterator it = parval.begin();
541 for (; it != parval.end(); ++it, ++
id) {
569 double pt1 = mu1.Pt();
570 double phi1 = mu1.Phi();
571 double eta1 = mu1.Eta();
572 double theta1 = 2 * atan(
exp(-
eta1));
573 double pt2 = mu2.Pt();
574 double phi2 = mu2.Phi();
575 double eta2 = mu2.Eta();
576 double theta2 = 2 * atan(
exp(-
eta2));
588 double dmdcotgth1 = (
pt1 *
pt1 *
cos(theta1) /
sin(theta1) *
592 double dmdcotgth2 = (
pt2 *
pt2 *
cos(theta2) /
sin(theta2) *
620 std::pow(dmdcotgth1 * sigma_cotgth1, 2) +
std::pow(dmdcotgth2 * sigma_cotgth2, 2) +
621 2 * dmdpt1 * dmdpt2 * cov_pt1pt2 * sigma_pt1 * sigma_pt2);
624 std::cout <<
" Pt1=" <<
pt1 <<
" phi1=" << phi1 <<
" cotgth1=" <<
cos(theta1) /
sin(theta1) <<
" - Pt2=" <<
pt2 625 <<
" phi2=" << phi2 <<
" cotgth2=" <<
cos(theta2) /
sin(theta2) << std::endl;
626 std::cout <<
" P[0]=" << parval[0] <<
" P[1]=" << parval[1] <<
"P[2]=" << parval[2] <<
" P[3]=" << parval[3]
628 std::cout <<
" Dmdpt1= " << dmdpt1 <<
" dmdpt2= " << dmdpt2 <<
" sigma_pt1=" << sigma_pt1
629 <<
" sigma_pt2=" << sigma_pt2 << std::endl;
630 std::cout <<
" Dmdphi1= " << dmdphi1 <<
" dmdphi2= " << dmdphi2 <<
" sigma_phi1=" << sigma_phi1
631 <<
" sigma_phi2=" << sigma_phi2 << std::endl;
632 std::cout <<
" Dmdcotgth1= " << dmdcotgth1 <<
" dmdcotgth2= " << dmdcotgth2 <<
" sigma_cotgth1=" << sigma_cotgth1
633 <<
" sigma_cotgth2=" << sigma_cotgth2 << std::endl;
634 std::cout <<
" Mass resolution (pval) for muons of Pt = " <<
pt1 <<
" " <<
pt2 <<
" : " <<
mass <<
" +- " 635 << mass_res << std::endl;
641 for (
int ires = 0; ires < 6; ires++) {
645 LogDebug(
"MuScleFitUtils") <<
"RESOLUTION PROBLEM: ires=" << ires << std::endl;
662 double pt1 = mu1.Pt();
663 double phi1 = mu1.Phi();
664 double eta1 = mu1.Eta();
665 double theta1 = 2 * atan(
exp(-
eta1));
666 double pt2 = mu2.Pt();
667 double phi2 = mu2.Phi();
668 double eta2 = mu2.Eta();
669 double theta2 = 2 * atan(
exp(-
eta2));
681 double dmdcotgth1 = (
pt1 *
pt1 *
cos(theta1) /
sin(theta1) *
685 double dmdcotgth2 = (
pt2 *
pt2 *
cos(theta2) /
sin(theta2) *
692 double sigma_pt1 = resolFunc.
sigmaPt(mu1);
693 double sigma_pt2 = resolFunc.
sigmaPt(mu2);
694 double sigma_phi1 = resolFunc.
sigmaPhi(mu1);
695 double sigma_phi2 = resolFunc.
sigmaPhi(mu2);
703 std::pow(dmdcotgth1 * sigma_cotgth1, 2) +
std::pow(dmdcotgth2 * sigma_cotgth2, 2));
711 const double &resEta,
712 const double &rapidity,
713 const double &massResol,
714 const std::vector<double> &parval,
715 const bool doUseBkgrWindow,
717 const double &
eta2) {
719 CALLGRIND_START_INSTRUMENTATION;
722 double *
p =
new double[(
int)(parval.size())];
727 std::vector<double>::const_iterator it = parval.begin();
729 for (; it != parval.end(); ++it, ++
id) {
734 double massProbability =
massProb(
mass, resEta, rapidity, massResol,
p, doUseBkgrWindow,
eta1,
eta2);
738 CALLGRIND_STOP_INSTRUMENTATION;
739 CALLGRIND_DUMP_STATS;
742 return massProbability;
751 const double &massResol,
752 const double GLvalue[][1001][1001],
753 const double GLnorm[][1001],
756 if (iRes == 0 && iY > 23) {
757 std::cout <<
"WARNING: rapidity bin selected = " << iY <<
" but there are only histograms for the first 24 bins" 762 bool insideProbMassWindow =
true;
771 std::cout << std::setprecision(9) <<
"mass ResMinMass[iRes] ResHalfWidth[iRes] ResHalfWidth[iRes]" <<
mass <<
" " 773 int iMassLeft = (
int)(fracMass * (
double)
nbins);
774 int iMassRight = iMassLeft + 1;
775 double fracMassStep = (double)
nbins * (fracMass - (
double)iMassLeft / (double)
nbins);
777 std::cout <<
"nbins iMassLeft fracMass " <<
nbins <<
" " << iMassLeft <<
" " << fracMass << std::endl;
783 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassLeft=" << iMassLeft
784 <<
"; mass = " <<
mass <<
" and bounds are " <<
ResMinMass[iRes] <<
":" 788 insideProbMassWindow =
false;
790 if (iMassRight >
nbins) {
791 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassRight=" << iMassRight
792 <<
"; mass = " <<
mass <<
" and bounds are " <<
ResMinMass[iRes] <<
":" 795 iMassLeft =
nbins - 1;
797 insideProbMassWindow =
false;
799 double fracSigma = (massResol /
ResMaxSigma[iRes]);
800 int iSigmaLeft = (
int)(fracSigma * (
double)
nbins);
801 int iSigmaRight = iSigmaLeft + 1;
802 double fracSigmaStep = (double)
nbins * (fracSigma - (
double)iSigmaLeft / (double)
nbins);
815 if (iSigmaLeft < 0) {
816 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaLeft=" << iSigmaLeft
817 <<
", with massResol = " << massResol
818 <<
" and ResMaxSigma[iRes] = " <<
ResMaxSigma[iRes] <<
" - iSigmaLeft set to 0" 823 if (iSigmaRight >
nbins) {
825 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaRight=" << iSigmaRight
826 <<
", with massResol = " << massResol
827 <<
" and ResMaxSigma[iRes] = " <<
ResMaxSigma[iRes] <<
" - iSigmaRight set to " 828 <<
nbins - 1 << std::endl;
829 iSigmaLeft =
nbins - 1;
836 if (insideProbMassWindow) {
838 if (GLnorm[iY][iSigmaLeft] > 0)
839 f11 = GLvalue[iY][iMassLeft][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
841 if (GLnorm[iY][iSigmaRight] > 0)
842 f12 = GLvalue[iY][iMassLeft][iSigmaRight] / GLnorm[iY][iSigmaRight];
844 if (GLnorm[iY][iSigmaLeft] > 0)
845 f21 = GLvalue[iY][iMassRight][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
847 if (GLnorm[iY][iSigmaRight] > 0)
848 f22 = GLvalue[iY][iMassRight][iSigmaRight] / GLnorm[iY][iSigmaRight];
849 PS = f11 + (f12 - f11) * fracSigmaStep + (f21 - f11) * fracMassStep +
850 (f22 - f21 - f12 + f11) * fracMassStep * fracSigmaStep;
851 if (PS > 0.1 ||
debug > 1)
852 LogDebug(
"MuScleFitUtils") <<
"iRes = " << iRes <<
" PS=" << PS <<
" f11,f12,f21,f22=" << f11 <<
" " << f12 <<
" " 853 << f21 <<
" " << f22 <<
" " 854 <<
" fSS=" << fracSigmaStep <<
" fMS=" << fracMassStep <<
" iSL, iSR=" << iSigmaLeft
855 <<
" " << iSigmaRight <<
" GLvalue[" << iY <<
"][" << iMassLeft
856 <<
"] = " << GLvalue[iY][iMassLeft][iSigmaLeft] <<
" GLnorm[" << iY <<
"][" 857 << iSigmaLeft <<
"] = " << GLnorm[iY][iSigmaLeft] << std::endl;
867 edm::LogInfo(
"probability") <<
"outside mass probability window. Setting PS[" << iRes <<
"] = 0" << std::endl;
890 const double &resEta,
891 const double &rapidity,
892 const double &massResol,
894 const bool doUseBkgrWindow,
896 const double &
eta2) {
959 std::vector<double> relativeCrossSections =
987 double PStot[6] = {0.};
990 bool resConsidered[6] = {
false};
1016 std::cout <<
"massProb:resFound = 0, rapidity bin =" << iY << std::endl;
1021 if (PS[0] != PS[0]) {
1022 std::cout <<
"ERROR: PS[0] = nan, setting it to 0" << std::endl;
1031 &(parval[bgrParShift]),
1042 Bgrp1 = bgrResult.first;
1046 PB = bgrResult.second;
1049 PStot[0] = (1 - Bgrp1) * PS[0] + Bgrp1 * PB;
1053 PStot[0] *= relativeCrossSections[0];
1056 <<
"(1-" << Bgrp1 <<
")*" << PS[0] <<
" + " << Bgrp1 <<
"*" << PB <<
" = " << PStot[0]
1057 <<
" (reletiveXS = )" << relativeCrossSections[0] << std::endl;
1060 std::cout <<
"Mass = " <<
mass <<
" outside range with rapidity = " << rapidity << std::endl;
1062 <<
" and left border = " << windowBorders.first <<
" right border = " << windowBorders.second
1072 for (
int ires = firstRes; ires < 6; ++ires) {
1079 std::cout <<
"massProb:resFound = " << ires << std::endl;
1084 std::pair<double, double> bgrResult =
1086 &(parval[bgrParShift]),
1097 Bgrp1 = bgrResult.first;
1098 PB = bgrResult.second;
1102 PStot[ires] = (1 - Bgrp1) * PS[ires] + Bgrp1 * PB;
1105 <<
"(1-" << Bgrp1 <<
")*" << PS[ires] <<
" + " << Bgrp1 <<
"*" << PB <<
" = " << PStot[ires]
1108 PStot[ires] *= relativeCrossSections[ires];
1113 for (
int i = 0;
i < 6; ++
i) {
1118 double PStotTemp = 0.;
1119 for (
int i = 0;
i < 6; ++
i) {
1120 PStotTemp += PS[
i] * relativeCrossSections[
i];
1122 if (PStotTemp != PStotTemp) {
1123 std::cout <<
"ERROR: PStotTemp = nan!!!!!!!!!" << std::endl;
1125 for (
int i = 0;
i < 6; ++
i) {
1126 std::cout <<
"PS[i] = " << PS[
i] << std::endl;
1127 if (PS[
i] != PS[
i]) {
1129 std::cout <<
"massResol = " << massResol << std::endl;
1130 for (
int j = 0;
j < parnumber; ++
j) {
1131 std::cout <<
"parval[" <<
j <<
"] = " << parval[
j] << std::endl;
1136 if (PStotTemp == PStotTemp) {
1142 std::cout <<
"mass = " <<
mass <<
", P = " <<
P <<
", PStot = " << PStotTemp <<
", PB = " << PB
1143 <<
", bgrp1 = " << Bgrp1 << std::endl;
1158 return ((
mass > leftBorder) && (
mass < rightBorder));
1173 if (doUseBkgrWindow && (
debug > 0))
1174 std::cout <<
"using backgrond window for mass = " <<
mass << std::endl;
1178 for (
int ires = 0; ires < 6; ires++) {
1186 if (doUseBkgrWindow && (
debug > 0))
1200 std::ofstream FitParametersFile;
1201 FitParametersFile.open(
"FitParameters.txt", std::ios::app);
1202 FitParametersFile <<
"Fitting with resolution, scale, bgr function # " <<
ResolFitType <<
" " <<
ScaleFitType <<
" " 1214 int parForResonanceWindows = 0;
1223 std::vector<double> *tmpVec = &(
parvalue.back());
1230 std::cout <<
"scaleFitNotDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1233 std::cout <<
"scaleFitDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1236 tmpVec->insert(tmpVec->end(),
parBgr.begin(),
parBgr.end());
1238 std::vector<double>::const_iterator it = tmpVec->begin();
1239 for (; it != tmpVec->end(); ++it, ++
i) {
1240 std::cout <<
"tmpVec[" <<
i <<
"] = " << *it << std::endl;
1250 parfix.insert(
parfix.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end());
1255 parorder.insert(
parorder.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end());
1259 std::vector<double> parerr(3 * parnumberAll, 0.);
1262 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters before likelihood " << std::endl;
1263 for (
unsigned int i = 0;
i < (
unsigned int)parnumberAll;
i++) {
1265 <<
"; order = " <<
parorder[
i] << std::endl;
1282 TMinuit rmin(parnumber);
1288 rmin.mninit(5, 6, 7);
1295 rmin.mnexcm(
"SET STR", arglis, 1, ierror);
1299 rmin.mnexcm(
"SET RAN", arglis, 1, ierror);
1303 double *Start =
new double[parnumberAll];
1304 double *Step =
new double[parnumberAll];
1305 double *Mini =
new double[parnumberAll];
1306 double *Maxi =
new double[parnumberAll];
1307 int *ind =
new int[parnumberAll];
1308 TString *parname =
new TString[parnumberAll];
1312 Start, Step, Mini, Maxi, ind, parname,
parResol,
parResolOrder,
parResolStep,
parResolMin,
parResolMax,
MuonType);
1327 &(parname[resParNum]),
1340 &(parname[resParNum]),
1349 &(Step[crossSectionParShift]),
1350 &(Mini[crossSectionParShift]),
1351 &(Maxi[crossSectionParShift]),
1352 &(ind[crossSectionParShift]),
1353 &(parname[crossSectionParShift]),
1361 &(Step[bgrParShift]),
1362 &(Mini[bgrParShift]),
1363 &(Maxi[bgrParShift]),
1364 &(ind[bgrParShift]),
1365 &(parname[bgrParShift]),
1370 for (
int ipar = 0; ipar < parnumber; ++ipar) {
1371 std::cout <<
"parname[" << ipar <<
"] = " << parname[ipar] << std::endl;
1372 std::cout <<
"Start[" << ipar <<
"] = " << Start[ipar] << std::endl;
1373 std::cout <<
"Step[" << ipar <<
"] = " << Step[ipar] << std::endl;
1374 std::cout <<
"Mini[" << ipar <<
"] = " << Mini[ipar] << std::endl;
1375 std::cout <<
"Maxi[" << ipar <<
"] = " << Maxi[ipar] << std::endl;
1377 rmin.mnparm(ipar, parname[ipar], Start[ipar], Step[ipar], Mini[ipar], Maxi[ipar], ierror);
1386 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Starting minimization" << std::endl;
1392 rmin.mnexcm(
"CALL FCN", arglis, 1, ierror);
1397 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: First fix all parameters ...";
1398 for (
int ipar = 0; ipar < parnumber; ipar++) {
1399 rmin.FixParameter(ipar);
1405 std::cout <<
" Then release them in order..." << std::endl;
1421 std::cout <<
"Before scale parNum" << std::endl;
1424 std::cout <<
"After scale parNum" << std::endl;
1429 std::cout <<
"number of parameters for scaleFunction = " << scaleParNum << std::endl;
1430 std::cout <<
"number of parameters for resolutionFunction = " << resParNum << std::endl;
1432 std::cout <<
"number of parameters for backgroundFunction = " <<
parBgr.size() << std::endl;
1435 for (
int i = 0;
i < parnumber;
i++) {
1437 if (n_times < ind[
i]) {
1438 edm::LogInfo(
"minimizeLikelihood") <<
"n_times = " << n_times <<
", ind[" <<
i <<
"] = " << ind[
i]
1439 <<
", scaleParNum = " << scaleParNum <<
", doScaleFit[" <<
loopCounter 1442 if (
i < resParNum) {
1445 }
else if (
i < resParNum + scaleParNum) {
1452 for (
int iorder = 0; iorder < n_times + 1; iorder++) {
1453 std::cout <<
"Starting minimization " << iorder <<
" of " << n_times << std::endl;
1455 bool somethingtodo =
false;
1462 for (
unsigned int ipar = 0; ipar <
parResol.size(); ++ipar) {
1463 if (
parfix[ipar] == 0 && ind[ipar] == iorder) {
1465 somethingtodo =
true;
1473 if (
parfix[ipar] == 0 && ind[ipar] == iorder) {
1475 somethingtodo =
true;
1485 bool doCrossSection =
1488 somethingtodo =
true;
1498 if (
parfix[ipar] == 0 && ind[ipar] == iorder &&
1501 somethingtodo =
true;
1508 if (somethingtodo) {
1511 std::stringstream fileNum;
1517 TH1D *tempLikelihoodInLoop =
new TH1D(
name,
"likelihood value in minuit loop", 10000, 0, 10000);
1519 char signalProbName[50];
1520 sprintf(signalProbName,
"signalProb_%d_%d",
loopCounter, iorder);
1521 TH1D *tempSignalProb =
new TH1D(signalProbName,
"signal probability", 10000, 0, 10000);
1523 char backgroundProbName[50];
1524 sprintf(backgroundProbName,
"backgroundProb_%d_%d",
loopCounter, iorder);
1525 TH1D *tempBackgroundProb =
new TH1D(backgroundProbName,
"background probability", 10000, 0, 10000);
1534 double protectionFactor = 0.9;
1543 for (
int ires = 0; ires < 6; ++ires) {
1551 double windowBorderShift = (windowBorder.second - windowBorder.first) * (1 - protectionFactor) / 2.;
1552 double windowBorderLeft = windowBorder.first + windowBorderShift;
1553 double windowBorderRight = windowBorder.second - windowBorderShift;
1567 std::cout <<
"MINUIT is starting the minimization for the iteration number " <<
loopCounter << std::endl;
1572 std::cout <<
"maxNumberOfIterations (just set) = " << rmin.GetMaxIterations() << std::endl;
1583 rmin.mnexcm(
"SIMPLEX", arglis, 0, ierror);
1586 rmin.mnexcm(
"MIGRAD", arglis, 2, ierror);
1592 delete tempLikelihoodInLoop;
1593 delete tempSignalProb;
1594 delete tempBackgroundProb;
1601 rmin.mnexcm(
"HESSE", arglis, 0, ierror);
1606 rmin.mnexcm(
"MINOS", arglis, 0, ierror);
1611 std::cout <<
"WARNING: normalization changed during fit meaning that events exited from the mass window. This " 1612 "causes a discontinuity in the likelihood function. Please check the scan of the likelihood as a " 1613 "function of the parameters to see if there are discontinuities around the minimum." 1619 for (
int ipar = 0; ipar < parnumber; ipar++) {
1620 rmin.mnpout(ipar,
name, pval, erro,
pmin, pmax, ivar);
1623 if (ierror != 0 &&
debug > 0) {
1624 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: ierror!=0, bogus pars" << std::endl;
1634 rmin.mnerrs(ipar, errh, errl, errp, cglo);
1639 parerr[3 * ipar] = errp;
1641 parerr[3 * ipar] = (((errh) > (
std::abs(errl))) ? (errh) : (
std::abs(errl)));
1643 parerr[3 * ipar + 1] = errl;
1644 parerr[3 * ipar + 2] = errh;
1647 FitParametersFile <<
" Resolution fit parameters:" << std::endl;
1649 if (ipar ==
int(
parResol.size())) {
1650 FitParametersFile <<
" Scale fit parameters:" << std::endl;
1653 FitParametersFile <<
" Cross section fit parameters:" << std::endl;
1656 FitParametersFile <<
" Background fit parameters:" << std::endl;
1672 FitParametersFile <<
" Results of the fit: parameter " << ipar <<
" has value " << pval <<
"+-" 1673 << parerr[3 * ipar] <<
" + " << parerr[3 * ipar + 1] <<
" - " 1674 << parerr[3 * ipar + 2]
1678 rmin.mnstat(fmin, fdem, errdef, npari, nparx, istat);
1679 FitParametersFile << std::endl;
1685 if (somethingtodo) {
1686 std::stringstream iorderString;
1687 iorderString << iorder;
1688 std::stringstream iLoopString;
1691 for (
int ipar = 0; ipar < parnumber; ipar++) {
1694 std::cout <<
"plotting parameter = " << ipar + 1 << std::endl;
1695 std::stringstream iparString;
1696 iparString << ipar + 1;
1697 std::stringstream iparStringName;
1698 iparStringName << ipar;
1699 rmin.mncomd((
"scan " + iparString.str()).c_str(), ierror);
1701 TCanvas *
canvas =
new TCanvas((
"likelihoodCanvas_loop_" + iLoopString.str() +
"_oder_" +
1702 iorderString.str() +
"_par_" + iparStringName.str())
1704 (
"likelihood_" + iparStringName.str()).c_str(),
1710 TGraph *graph = (TGraph *)rmin.GetPlot();
1713 graph->SetTitle(parname[ipar]);
1735 FitParametersFile.close();
1737 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters after likelihood " << std::endl;
1738 for (
unsigned int ipar = 0; ipar < (
unsigned int)parnumber; ipar++) {
1740 <<
"; order = " <<
parorder[ipar] << std::endl;
1758 for (
unsigned int i = 0;
i < (
parBgr.size() - parForResonanceWindows); ++
i) {
1786 std::cout <<
"[MuScleFitUtils-likelihood]: In likelihood function" << std::endl;
1852 double Y = (corrMu1 + corrMu2).Rapidity();
1853 double resEta = (corrMu1 + corrMu2).Eta();
1855 std::cout <<
"[MuScleFitUtils-likelihood]: Original/Corrected resonance mass = " <<
mass <<
" / " << corrMass
1863 std::cout <<
"[MuScleFitUtils-likelihood]: Resolution is " << massResol << std::endl;
1868 std::cout <<
"calling massProb inside likelihood function" << std::endl;
1883 std::cout <<
"WARNING: corrMass = " << corrMass
1884 <<
" outside window, this will cause a discontinuity in the likelihood. Consider increasing the " 1885 "safety bands which are now set to 90% of the normalization window to avoid this problem" 1888 std::cout <<
"WARNING: massResol = " << massResol <<
" outside window" << std::endl;
1893 std::cout <<
"[MuScleFitUtils-likelihood]: Mass probability = " <<
prob << std::endl;
1916 if (evtsinlik != 0) {
1922 double normalizationArg[] = {1 / double(evtsinlik)};
1937 fval = -2. * flike / double(evtsinlik);
1946 std::cout <<
"Problem: Events in likelihood = " << evtsinlik << std::endl;
1951 std::cout <<
"[MuScleFitUtils-likelihood]: End tree loop with likelihood value = " << fval << std::endl;
1976 std::cout <<
"Events in likelihood = " << evtsinlik << std::endl;
1977 std::cout <<
"Events out likelihood = " << evtsoutlik << std::endl;
1989 std::vector<TGraphErrors *>
results;
1993 std::vector<double> Ftop;
1994 std::vector<double> Fwidth;
1995 std::vector<double> Fmass;
1996 std::vector<double> Etop;
1997 std::vector<double> Ewidth;
1998 std::vector<double> Emass;
1999 std::vector<double> Fchi2;
2002 std::vector<double> Xcenter;
2003 std::vector<double> Ex;
2008 fitFcn->SetParameters(100, 3, 91);
2009 fitFcn->SetParNames(
"Ftop",
"Fwidth",
"Fmass");
2010 fitFcn->SetLineWidth(2);
2014 double cont_min = 20;
2015 Int_t binx =
histo->GetXaxis()->GetNbins();
2018 for (
int i = 1;
i <= binx;
i++) {
2019 TH1 *histoY =
histo->ProjectionY(
"",
i,
i);
2021 double cont = histoY->GetEntries();
2022 if (
cont > cont_min) {
2023 histoY->Fit(
"fitFcn",
"0",
"", 70, 110);
2024 double *par = fitFcn->GetParameters();
2025 const double *
err = fitFcn->GetParErrors();
2027 Ftop.push_back(par[0]);
2028 Fwidth.push_back(par[1]);
2029 Fmass.push_back(par[2]);
2030 Etop.push_back(
err[0]);
2031 Ewidth.push_back(
err[1]);
2032 Emass.push_back(
err[2]);
2034 double chi2 = fitFcn->GetChisquare();
2035 Fchi2.push_back(
chi2);
2037 double xx =
histo->GetXaxis()->GetBinCenter(
i);
2038 Xcenter.push_back(
xx);
2047 const int nn = Fmass.size();
2048 double *
x =
new double[
nn];
2049 double *ym =
new double[
nn];
2050 double *
e =
new double[
nn];
2051 double *eym =
new double[
nn];
2052 double *yw =
new double[
nn];
2053 double *eyw =
new double[
nn];
2054 double *yc =
new double[
nn];
2056 for (
int j = 0;
j <
nn;
j++) {
2069 TGraphErrors *grM =
new TGraphErrors(
nn,
x, ym,
e, eym);
2070 grM->SetTitle(
name +
"_M");
2071 grM->SetName(
name +
"_M");
2072 TGraphErrors *grW =
new TGraphErrors(
nn,
x, yw,
e, eyw);
2073 grW->SetTitle(
name +
"_W");
2074 grW->SetName(
name +
"_W");
2075 TGraphErrors *grC =
new TGraphErrors(
nn,
x, yc,
e,
e);
2076 grC->SetTitle(
name +
"_chi2");
2077 grC->SetName(
name +
"_chi2");
2100 std::vector<TGraphErrors *>
results;
2104 std::vector<double> maxs;
2105 std::vector<double>
means;
2106 std::vector<double> sigmas;
2107 std::vector<double> chi2s;
2108 std::vector<double> Emaxs;
2109 std::vector<double> Emeans;
2110 std::vector<double> Esigmas;
2114 std::vector<double> Xcenter;
2115 std::vector<double> Ex;
2119 TF1 *fitFcn =
new TF1(
"fitFunc",
Gaussian, -0.2, 0.2, 3);
2120 fitFcn->SetParameters(100, 0, 0.02);
2121 fitFcn->SetParNames(
"max",
"mean",
"sigma");
2122 fitFcn->SetLineWidth(2);
2126 double cont_min = 20;
2127 Int_t binx =
histo->GetXaxis()->GetNbins();
2128 for (
int i = 1;
i <= binx;
i++) {
2129 TH1 *histoY =
histo->ProjectionY(
"",
i,
i);
2130 double cont = histoY->GetEntries();
2131 if (
cont > cont_min) {
2132 histoY->Fit(
"fitFunc",
"0",
"", -0.2, 0.2);
2133 double *par = fitFcn->GetParameters();
2134 const double *
err = fitFcn->GetParErrors();
2136 maxs.push_back(par[0]);
2137 means.push_back(par[1]);
2138 sigmas.push_back(par[2]);
2139 Emaxs.push_back(
err[0]);
2140 Emeans.push_back(
err[1]);
2141 Esigmas.push_back(
err[2]);
2143 double chi2 = fitFcn->GetChisquare();
2144 chi2s.push_back(
chi2);
2146 double xx =
histo->GetXaxis()->GetBinCenter(
i);
2147 Xcenter.push_back(
xx);
2156 double *
x =
new double[
nn];
2157 double *ym =
new double[
nn];
2158 double *
e =
new double[
nn];
2159 double *eym =
new double[
nn];
2160 double *yw =
new double[
nn];
2161 double *eyw =
new double[
nn];
2162 double *yc =
new double[
nn];
2164 for (
int j = 0;
j <
nn;
j++) {
2171 eyw[
j] = Esigmas[
j];
2179 TGraphErrors *grM =
new TGraphErrors(
nn,
x, ym,
e, eym);
2180 grM->SetTitle(
name +
"_mean");
2181 grM->SetName(
name +
"_mean");
2182 TGraphErrors *grW =
new TGraphErrors(
nn,
x, yw,
e, eyw);
2183 grW->SetTitle(
name +
"_sigma");
2184 grW->SetName(
name +
"_sigma");
2185 TGraphErrors *grC =
new TGraphErrors(
nn,
x, yc,
e,
e);
2186 grC->SetTitle(
name +
"_chi2");
2187 grC->SetName(
name +
"_chi2");
2217 if (massResol == 0.) {
2220 << massResol <<
" : used Lorentz P-value" << std::endl;
2241 double *
x =
new double[
np];
2242 double *
w =
new double[
np];
2244 GL->CalcGaussLegendreSamplingPoints(
np,
x,
w, 0.1
e-15);
2255 << massResol <<
": used epsilon" << std::endl;
2261 << massResol <<
" " <<
P << std::endl;
2268 std::pair<lorentzVector, lorentzVector> simMuFromRes;
2271 if (
std::abs((*simTrack).type()) == 13) {
2273 if ((*simTrack).genpartIndex() > 0) {
2275 if (
gp !=
nullptr) {
2276 for (HepMC::GenVertex::particle_iterator mother =
gp->production_vertex()->particles_begin(HepMC::ancestors);
2277 mother !=
gp->production_vertex()->particles_end(HepMC::ancestors);
2279 bool fromRes =
false;
2280 unsigned int motherPdgId = (*mother)->pdg_id();
2281 for (
int ires = 0; ires < 6; ++ires) {
2286 if (
gp->pdg_id() == 13)
2303 return simMuFromRes;
2308 std::pair<lorentzVector, lorentzVector> muFromRes;
2310 for (HepMC::GenEvent::particle_const_iterator
part = Evt->particles_begin();
part != Evt->particles_end();
part++) {
2311 if (
std::abs((*part)->pdg_id()) == 13 && (*part)->status() == 1) {
2312 bool fromRes =
false;
2313 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
2314 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors);
2316 unsigned int motherPdgId = (*mother)->pdg_id();
2321 if (motherPdgId == 13 && (*mother)->status() == 3)
2324 for (
int ires = 0; ires < 6; ++ires) {
2331 if ((*part)->pdg_id() == 13)
2334 (*part)->momentum().px(), (*part)->momentum().py(), (*part)->momentum().pz(), (*part)->momentum().e()));
2337 (*part)->momentum().px(), (*part)->momentum().py(), (*part)->momentum().pz(), (*part)->momentum().e()));
2346 std::pair<lorentzVector, lorentzVector> muFromRes;
2353 bool fromRes =
false;
2354 unsigned int motherPdgId =
part->mother()->pdgId();
2356 std::cout <<
"Found a muon with mother: " << motherPdgId << std::endl;
2358 for (
int ires = 0; ires < 6; ++ires) {
2363 if (
part->pdgId() == 13) {
2364 muFromRes.first =
part->p4();
2366 std::cout <<
"Found a genMuon + : " << muFromRes.first << std::endl;
2370 muFromRes.second =
part->p4();
2372 std::cout <<
"Found a genMuon - : " << muFromRes.second << std::endl;
static std::vector< std::pair< lorentzVector, lorentzVector > > simPair
static std::vector< int > doScaleFit
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
static std::vector< int > doResolFit
static std::pair< lorentzVector, lorentzVector > findGenMuFromRes(const reco::GenParticleCollection *genParticles)
static double GLValue[6][1001][1001]
static std::vector< double > parBias
static std::vector< int > parCrossSectionOrder
static smearFunctionBase * smearFunction
static std::vector< int > parScaleOrder
double sigmaCotgTh(const U &track, const int i=0) const
The second, optional, parameter is the iteration number.
static std::vector< int > doCrossSectionFit
static void minimizeLikelihood()
static double maxMuonEtaSecondRange_
Double_t Gaussian(Double_t *x, Double_t *par)
int regionsParNum()
Returns the total number of parameters used for the regions.
static std::vector< int > parBgrOrder
static std::vector< int > parfix
static double deltaPhiMaxCut_
static unsigned int loopCounter
static std::vector< double > parResolMax
static std::pair< lorentzVector, lorentzVector > findSimMuFromRes(const edm::Handle< edm::HepMCProduct > &evtMC, const edm::Handle< edm::SimTrackContainer > &simTracks)
static std::vector< std::pair< MuScleFitMuon, MuScleFitMuon > > SavedPairMuScleFitMuons
void likelihood(int &npar, double *grad, double &fval, double *xval, int flag)
static std::vector< std::pair< MuScleFitMuon, MuScleFitMuon > > genMuscleFitPair
static bool startWithSimplex_
static std::vector< int > doBackgroundFit
static std::vector< double > parResol
static bool debugMassResol_
void setParameters(double *Start, double *Step, double *Mini, double *Maxi, int *ind, TString *parname, const std::vector< double > &parCrossSection, const std::vector< int > &parCrossSectionOrder, const std::vector< int > &resfind)
Initializes the arrays needed by Minuit.
Sin< T >::type sin(const T &t)
static double ResMinMass[6]
static TH1D * backgroundProb_
virtual void smear(double &pt, double &eta, double &phi, const double *y, const std::vector< double > &parSmear)=0
static BackgroundHandler * backgroundHandler
static double x[7][10000]
std::pair< double, double > backgroundFunction(const bool doBackgroundFit, const double *parval, const int resTotNum, const int ires, const bool *resConsidered, const double *ResMass, const double ResHalfWidth[], const int MuonType, const double &mass, const double &eta1, const double &eta2)
static std::vector< TGraphErrors * > fitMass(TH2F *histo)
static double massWindowHalfWidth[3][6]
TkSoAView< TrackerTraits > HitToTuple< TrackerTraits > const *__restrict__ int32_t int32_t int iev
static bool scaleFitNotDone_
double sigmaPt(const U &track, const int i=0) const
The second, optional, parameter is the iteration number.
static unsigned int normalizationChanged_
static scaleFunctionBase< std::vector< double > > * biasFunction
static bool checkMassWindow(const double &mass, const double &leftBorder, const double &rightBorder)
Method to check if the mass value is within the mass window of the i-th resonance.
static std::vector< int > parBgrFix
static std::vector< double > parResolMin
static bool minimumShapePlots_
static int MuonTypeForCheckMassWindow
static double minMuonEtaFirstRange_
static double massProb(const double &mass, const double &rapidity, const int ires, const double &massResol)
static struct MuScleFitUtils::massResolComponentsStruct massResolComponents
static std::vector< int > parScaleFix
static bool computeMinosErrors_
reco::Particle::LorentzVector lorentzVector
static scaleFunctionBase< std::vector< double > > * scaleFunctionForVec
static std::pair< SimTrack, SimTrack > findBestSimuRes(const std::vector< SimTrack > &simMuons)
static std::vector< std::vector< double > > parvalue
virtual double sigmaPt(const double &pt, const double &eta, const T &parval)=0
static std::pair< MuScleFitMuon, MuScleFitMuon > findBestRecoRes(const std::vector< MuScleFitMuon > &muons)
static std::vector< std::pair< lorentzVector, lorentzVector > > genPair
static std::vector< std::pair< lorentzVector, lorentzVector > > ReducedSavedPair
static const int totalResNum
static const double muMass
static double massResolution(const lorentzVector &mu1, const lorentzVector &mu2)
static const unsigned int motherPdgIdArray[6]
static std::vector< double > parScaleMin
static lorentzVector applyBias(const lorentzVector &muon, const int charge)
void rescale(std::vector< double > &parBgr, const double *ResMass, const double *massWindowHalfWidth, const std::vector< std::pair< reco::Particle::LorentzVector, reco::Particle::LorentzVector > > &muonPairs, const double &weight=1.)
static double GLZNorm[40][1001]
static std::vector< double > parBgr
virtual void setParameters(double *Start, double *Step, double *Mini, double *Maxi, int *ind, TString *parname, const T &parScale, const std::vector< int > &parScaleOrder, const int muonType)=0
This method is used to differentiate parameters among the different functions.
static lorentzVector fromPtEtaPhiToPxPyPz(const double *ptEtaPhiE)
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
virtual double covPt1Pt2(const double &pt1, const double &eta1, const double &pt2, const double &eta2, const T &parval)
bool releaseParameters(TMinuit &rmin, const std::vector< int > &resfind, const std::vector< int > &parfix, const int *ind, const int iorder, const unsigned int shift)
Use the information in resfind, parorder and parfix to release the N-1 variables. ...
static double ResMaxSigma[6]
static double computeWeight(const double &mass, const int iev, const bool doUseBkgrWindow=false)
static std::vector< double > parScaleStep
static std::vector< std::pair< lorentzVector, lorentzVector > > SavedPair
static double invDimuonMass(const lorentzVector &mu1, const lorentzVector &mu2)
static lorentzVector applyScale(const lorentzVector &muon, const std::vector< double > &parval, const int charge)
static TH1D * signalProb_
static std::vector< int > parResolFix
static double GLZValue[40][1001][1001]
static TMinuit * rminPtr_
static std::vector< double > parSmear
const HepMC::GenEvent * GetEvent() const
virtual double scale(const double &pt, const double &eta, const double &phi, const int chg, const T &parScale) const =0
static std::vector< int > parResolOrder
double resMass(const bool doBackgroundFit, const int ires)
virtual int parNum() const
static TH1D * likelihoodInLoop_
Log< level::Info, false > LogInfo
static std::vector< double > parScaleMax
static std::vector< double > parScale
static double oldNormalization_
virtual int parNum() const
virtual double sigmaCotgTh(const double &pt, const double &eta, const T &parval)=0
std::vector< double > relativeCrossSections(const double *variables, const std::vector< int > &resfind)
Perform a variable transformation from N-1 to relative cross sections.
void setParameters(double *Start, double *Step, double *Mini, double *Maxi, int *ind, TString *parname, const std::vector< double > &parBgr, const std::vector< int > &parBgrOrder, const int muonType)
Sets initial parameters for all the functions.
virtual void resetParameters(std::vector< double > *scaleVec) const
This method is used to reset the scale parameters to neutral values (useful for iterations > 0) ...
static double ResGamma[6]
static double deltaPhiMinCut_
Double_t lorentzianPeak(Double_t *x, Double_t *par)
std::pair< OmniClusterRef, TrackingParticleRef > P
static bool rapidityBinsForZ_
static bool separateRanges_
static double minMuonEtaSecondRange_
static std::vector< double > parCrossSection
static double GLNorm[6][1001]
static std::vector< TGraphErrors * > fitReso(TH2F *histo)
double sigmaPhi(const U &track, const int i=0) const
The second, optional, parameter is the iteration number.
static lorentzVector applySmearing(const lorentzVector &muon)
std::pair< double, double > windowBorders(const bool doBackgroundFit, const int ires)
Returns the appropriate window borders depending on whether the background is being fitted and on the...
static bool normalizeLikelihoodByEventNumber_
bool unlockParameter(const std::vector< int > &resfind, const unsigned int ipar)
returns true if the parameter is to be unlocked
static unsigned int const shift
virtual void setParameters(double *Start, double *Step, double *Mini, double *Maxi, int *ind, TString *parname, const T &parResol, const std::vector< int > &parResolOrder, const int muonType)
This method is used to differentiate parameters among the different functions.
static double probability(const double &mass, const double &massResol, const double GLvalue[][1001][1001], const double GLnorm[][1001], const int iRes, const int iY)
Computes the probability given the mass, mass resolution and the arrays with the probabilities and th...
virtual double sigmaPhi(const double &pt, const double &eta, const T &parval)=0
static scaleFunctionBase< double * > * scaleFunction
static bool useProbsFile_
static std::vector< int > resfind
static double ResHalfWidth[6]
static int counter_resprob
static resolutionFunctionBase< std::vector< double > > * resolutionFunctionForVec
static std::vector< int > parorder
static double maxMuonEtaFirstRange_
Power< A, B >::type pow(const A &a, const B &b)
cont
load Luminosity info ##
static CrossSectionHandler * crossSectionHandler
static std::vector< double > parResolStep
static std::vector< int > parCrossSectionFix
static resolutionFunctionBase< double * > * resolutionFunction