52 #include "valgrind/callgrind.h"
59 TMath::Max(1.
e-10,(x[0]-par[2])*(x[0]-par[2]) + .25*par[1]*par[1]);
65 return par[0]*
exp(-0.5*((x[0]-par[1])/par[2])*((x[0]-par[1])/par[2]));
84 TF1 *
GL =
new TF1 (
"GL",
85 "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))",
88 TF2 *
GL2=
new TF2 (
"GL2",
89 "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))",
262 std::pair<SimTrack, SimTrack> simMuFromBestRes;
263 double maxprob = -0.1;
267 for (std::vector<SimTrack>::const_iterator simMu1=simMuons.begin(); simMu1!=simMuons.end(); simMu1++) {
268 for (std::vector<SimTrack>::const_iterator simMu2=simMu1+1; simMu2!=simMuons.end(); simMu2++) {
269 if (((*simMu1).charge()*(*simMu2).charge())>0) {
274 double mcomb = ((*simMu1).momentum()+(*simMu2).momentum()).mass();
275 double Y = ((*simMu1).momentum()+(*simMu2).momentum()).Rapidity();
276 for (
int ires=0; ires<6; ires++) {
278 double prob =
massProb( mcomb, Y, ires, 0. );
280 simMuFromBestRes.first = (*simMu1);
281 simMuFromBestRes.second = (*simMu2);
291 return simMuFromBestRes;
303 std::pair<lorentzVector, lorentzVector> recMuFromBestRes;
307 double maxprob = -0.1;
308 double minDeltaMass = 999999;
309 std::pair<reco::LeafCandidate,reco::LeafCandidate> bestMassMuons;
310 for (std::vector<reco::LeafCandidate>::const_iterator Muon1=muons.begin(); Muon1!=muons.end(); ++Muon1) {
311 for (std::vector<reco::LeafCandidate>::const_iterator Muon2=Muon1+1; Muon2!=muons.end(); ++Muon2) {
312 if (((*Muon1).charge()*(*Muon2).charge())>0) {
319 double pt1 = (*Muon1).p4().Pt();
320 double pt2 = (*Muon2).p4().Pt();
321 double eta1 = (*Muon1).p4().Eta();
322 double eta2 = (*Muon2).p4().Eta();
329 double mcomb = ((*Muon1).p4()+(*Muon2).p4()).mass();
330 double Y = ((*Muon1).p4()+(*Muon2).p4()).Rapidity();
332 std::cout<<
"muon1 "<<(*Muon1).p4().Px()<<
", "<<(*Muon1).p4().Py()<<
", "<<(*Muon1).p4().Pz()<<
", "<<(*Muon1).p4().E()<<std::endl;
333 std::cout<<
"muon2 "<<(*Muon2).p4().Px()<<
", "<<(*Muon2).p4().Py()<<
", "<<(*Muon2).p4().Pz()<<
", "<<(*Muon2).p4().E()<<std::endl;
335 double massResol = 0.;
340 for(
int ires=0; ires<6; ires++ ) {
343 prob =
massProb( mcomb, Y, ires, massResol );
346 if( (*Muon1).charge()<0 ) {
347 recMuFromBestRes.first = (*Muon1).p4();
348 recMuFromBestRes.second = (*Muon2).p4();
350 recMuFromBestRes.first = (*Muon2).p4();
351 recMuFromBestRes.second = (*Muon1).p4();
361 if( deltaMass<minDeltaMass ){
362 bestMassMuons = std::make_pair((*Muon1),(*Muon2));
363 minDeltaMass = deltaMass;
373 if(bestMassMuons.first.charge()<0){
374 recMuFromBestRes.first = bestMassMuons.first.p4();
375 recMuFromBestRes.second = bestMassMuons.second.p4();
378 recMuFromBestRes.second = bestMassMuons.first.p4();
379 recMuFromBestRes.first = bestMassMuons.second.p4();
382 return recMuFromBestRes;
389 double pt = muon.Pt();
390 double eta = muon.Eta();
391 double phi = muon.Phi();
403 std::cout <<
"Smearing Pt,eta,phi = " << pt <<
" " << eta <<
" "
405 for (
int i=0;
i<SmearType+3;
i++) {
411 double ptEtaPhiE[4] = {
pt,
eta,
phi, E};
419 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
438 const std::vector<double> & parval,
const int chg)
440 double *
p =
new double[(int)(parval.size())];
445 for (std::vector<double>::const_iterator it=parval.begin(); it!=parval.end(); ++it, ++
id) {
458 double* parval,
const int chg)
460 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
467 ptEtaPhiE[0] =
scaleFunction->
scale(ptEtaPhiE[0], ptEtaPhiE[1], ptEtaPhiE[2], chg, &(parval[shift]));
478 double px = ptEtaPhiE[0]*
cos(ptEtaPhiE[2]);
479 double py = ptEtaPhiE[0]*
sin(ptEtaPhiE[2]);
480 double tmp = 2*atan(
exp(-ptEtaPhiE[1]));
481 double pz = ptEtaPhiE[0]*
cos(tmp)/
sin(tmp);
496 return (mu1+mu2).mass();
503 const std::vector<double> & parval )
516 double *
p =
new double[(int)(parval.size())];
517 std::vector<double>::const_iterator it = parval.begin();
519 for ( ; it!=parval.end(); ++it, ++
id) {
548 double mass = (mu1+mu2).mass();
549 double pt1 = mu1.Pt();
550 double phi1 = mu1.Phi();
551 double eta1 = mu1.Eta();
552 double theta1 = 2*atan(
exp(-eta1));
554 double pt2 = mu2.Pt();
555 double phi2 = mu2.Phi();
556 double eta2 = mu2.Eta();
557 double theta2 = 2*atan(
exp(-eta2));
566 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
568 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
569 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
570 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
577 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
579 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
580 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
582 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
608 2*dmdpt1*dmdpt2*cov_pt1pt2);
619 std::cout <<
" Pt1=" << pt1 <<
" phi1=" << phi1 <<
" cotgth1=" <<
cos(theta1)/
sin(theta1) <<
" - Pt2=" << pt2
620 <<
" phi2=" << phi2 <<
" cotgth2=" <<
cos(theta2)/
sin(theta2) << std::endl;
622 << parval[0] <<
" P[1]=" << parval[1] <<
"P[2]=" << parval[2] <<
" P[3]=" << parval[3] << std::endl;
623 std::cout <<
" Dmdpt1= " << dmdpt1 <<
" dmdpt2= " << dmdpt2 <<
" sigma_pt1="
624 << sigma_pt1 <<
" sigma_pt2=" << sigma_pt2 << std::endl;
625 std::cout <<
" Dmdphi1= " << dmdphi1 <<
" dmdphi2= " << dmdphi2 <<
" sigma_phi1="
626 << sigma_phi1 <<
" sigma_phi2=" << sigma_phi2 << std::endl;
627 std::cout <<
" Dmdcotgth1= " << dmdcotgth1 <<
" dmdcotgth2= " << dmdcotgth2
629 << sigma_cotgth1 <<
" sigma_cotgth2=" << sigma_cotgth2 << std::endl;
630 std::cout <<
" Mass resolution (pval) for muons of Pt = " << pt1 <<
" " << pt2
631 <<
" : " << mass <<
" +- " << mass_res << std::endl;
637 for (
int ires=0; ires<6; ires++) {
641 LogDebug(
"MuScleFitUtils") <<
"RESOLUTION PROBLEM: ires=" << ires << std::endl;
686 double MuScleFitUtils::massProb(
const double & mass,
const double & resEta,
const double & rapidity,
const double & massResol,
const std::vector<double> & parval,
const bool doUseBkgrWindow )
689 CALLGRIND_START_INSTRUMENTATION;
692 double *
p =
new double[(int)(parval.size())];
697 std::vector<double>::const_iterator it = parval.begin();
699 for ( ; it!=parval.end(); ++it, ++
id) {
704 double massProbability =
massProb( mass, resEta, rapidity, massResol, p, doUseBkgrWindow );
708 CALLGRIND_STOP_INSTRUMENTATION;
709 CALLGRIND_DUMP_STATS;
712 return massProbability;
721 const double GLvalue[][1001][1001],
const double GLnorm[][1001],
722 const int iRes,
const int iY )
724 if( iRes == 0 && iY > 23 ) {
725 std::cout <<
"WARNING: rapidity bin selected = " << iY <<
" but there are only histograms for the first 24 bins" << std::endl;
729 bool insideProbMassWindow =
true;
737 if (
debug>1)
std::cout << std::setprecision(9)<<
"mass ResMinMass[iRes] ResHalfWidth[iRes] ResHalfWidth[iRes]"
739 int iMassLeft = (int)(fracMass*(
double)
nbins);
740 int iMassRight = iMassLeft+1;
741 double fracMassStep = (double)
nbins*(fracMass - (
double)iMassLeft/(double)
nbins);
742 if (
debug>1)
std::cout<<
"nbins iMassLeft fracMass "<<nbins<<
" "<<iMassLeft<<
" "<<fracMass<<std::endl;
748 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassLeft="
749 << iMassLeft <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
753 insideProbMassWindow =
false;
755 if (iMassRight>nbins) {
756 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassRight="
757 << iMassRight <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
758 <<
":" <<
ResMass[iRes]+2*
ResHalfWidth[iRes] <<
" - iMassRight set to " << nbins-1 << std::endl;
761 insideProbMassWindow =
false;
764 int iSigmaLeft = (int)(fracSigma*(
double)
nbins);
765 int iSigmaRight = iSigmaLeft+1;
766 double fracSigmaStep = (double)nbins * (fracSigma - (
double)iSigmaLeft/(double)nbins);
780 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaLeft="
781 << iSigmaLeft <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = "
782 <<
ResMaxSigma[iRes] <<
" - iSigmaLeft set to 0" << std::endl;
786 if (iSigmaRight>nbins ) {
788 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaRight="
789 << iSigmaRight <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = "
790 <<
ResMaxSigma[iRes] <<
" - iSigmaRight set to " << nbins-1 << std::endl;
791 iSigmaLeft = nbins-1;
798 if( insideProbMassWindow ) {
800 if (GLnorm[iY][iSigmaLeft]>0)
801 f11 = GLvalue[iY][iMassLeft][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
803 if (GLnorm[iY][iSigmaRight]>0)
804 f12 = GLvalue[iY][iMassLeft][iSigmaRight] / GLnorm[iY][iSigmaRight];
806 if (GLnorm[iY][iSigmaLeft]>0)
807 f21 = GLvalue[iY][iMassRight][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
809 if (GLnorm[iY][iSigmaRight]>0)
810 f22 = GLvalue[iY][iMassRight][iSigmaRight] / GLnorm[iY][iSigmaRight];
811 PS = f11 + (f12-f11)*fracSigmaStep + (f21-f11)*fracMassStep +
812 (f22-f21-f12+f11)*fracMassStep*fracSigmaStep;
813 if (PS>0.1 ||
debug>1)
LogDebug(
"MuScleFitUtils") <<
"iRes = " << iRes <<
" PS=" << PS <<
" f11,f12,f21,f22="
814 << f11 <<
" " << f12 <<
" " << f21 <<
" " << f22 <<
" "
815 <<
" fSS=" << fracSigmaStep <<
" fMS=" << fracMassStep <<
" iSL, iSR="
816 << iSigmaLeft <<
" " << iSigmaRight
817 <<
" GLvalue["<<iY<<
"]["<<iMassLeft<<
"] = " << GLvalue[iY][iMassLeft][iSigmaLeft]
818 <<
" GLnorm["<<iY<<
"]["<<iSigmaLeft<<
"] = " << GLnorm[iY][iSigmaLeft] << std::endl;
829 edm::LogInfo(
"probability") <<
"outside mass probability window. Setting PS["<<iRes<<
"] = 0" << std::endl;
851 double MuScleFitUtils::massProb(
const double & mass,
const double & resEta,
const double & rapidity,
const double & massResol,
double * parval,
const bool doUseBkgrWindow ) {
942 double PStot[6] = {0.};
945 bool resConsidered[6] = {
false};
967 int iY = (int)(fabs(rapidity)*10.);
968 if( iY > 23 ) iY = 23;
975 if( PS[0] != PS[0] ) {
976 std::cout <<
"ERROR: PS[0] = nan, setting it to 0" << std::endl;
983 Bgrp1 = bgrResult.first;
987 PB = bgrResult.second;
988 if( PB != PB ) PB = 0;
989 PStot[0] = (1-Bgrp1)*PS[0] + Bgrp1*PB;
993 PStot[0] *= relativeCrossSections[0];
998 std::cout <<
"Mass = " << mass <<
" outside range with rapidity = " << rapidity << std::endl;
999 std::cout <<
"with resMass = " <<
backgroundHandler->
resMass( useBackgroundWindow, 0 ) <<
" and left border = " << windowBorders.first <<
" right border = " << windowBorders.second << std::endl;
1007 for(
int ires=firstRes; ires<6; ++ires ) {
1012 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1021 Bgrp1 = bgrResult.first;
1022 PB = bgrResult.second;
1024 if( PB != PB ) PB = 0;
1025 PStot[ires] = (1-Bgrp1)*PS[ires] + Bgrp1*PB;
1026 if(
MuScleFitUtils::debug>0 )
std::cout <<
"PStot["<<ires<<
"] = " <<
"(1-"<<Bgrp1<<
")*"<<PS[ires]<<
" + "<<Bgrp1<<
"*"<<PB<<
" = " << PStot[ires] << std::endl;
1028 PStot[ires] *= relativeCrossSections[ires];
1033 for(
int i=0;
i<6; ++
i ) {
1038 double PStotTemp = 0.;
1039 for(
int i=0;
i<6; ++
i ) {
1040 PStotTemp += PS[
i]*relativeCrossSections[
i];
1042 if( PStotTemp != PStotTemp ) {
1043 std::cout <<
"ERROR: PStotTemp = nan!!!!!!!!!" << std::endl;
1045 for(
int i=0;
i<6; ++
i ) {
1046 std::cout <<
"PS[i] = " << PS[
i] << std::endl;
1047 if( PS[
i] != PS[
i] ) {
1048 std::cout <<
"mass = " << mass << std::endl;
1049 std::cout <<
"massResol = " << massResol << std::endl;
1050 for(
int j=0;
j<parnumber; ++
j ) {
1051 std::cout <<
"parval["<<
j<<
"] = " << parval[
j] << std::endl;
1056 if( PStotTemp == PStotTemp ) {
1059 if (
debug>0)
std::cout <<
"mass = " << mass <<
", P = " << P <<
", PStot = " << PStotTemp <<
", PB = " << PB <<
", bgrp1 = " << Bgrp1 << std::endl;
1074 return( (mass > leftBorder) && (mass < rightBorder) );
1090 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"using backgrond window for mass = " << mass << std::endl;
1094 for (
int ires=0; ires<6; ires++) {
1095 if (
resfind[ires]>0 && weight==0.) {
1100 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1102 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"setting weight to = " << weight << std::endl;
1116 ofstream FitParametersFile;
1117 FitParametersFile.open (
"FitParameters.txt", std::ios::app);
1118 FitParametersFile <<
"Fitting with resolution, scale, bgr function # "
1135 int parForResonanceWindows = 0;
1148 std::vector<double> *tmpVec = &(
parvalue.back());
1155 std::cout <<
"scaleFitNotDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1159 std::cout <<
"scaleFitDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1162 tmpVec->insert( tmpVec->end(),
parBgr.begin(),
parBgr.end() );
1164 std::vector<double>::const_iterator it = tmpVec->begin();
1165 for( ; it != tmpVec->end(); ++it, ++
i ) {
1166 std::cout <<
"tmpVec["<<i<<
"] = " << *it << std::endl;
1172 std::vector<int> crossSectionParNumSizeVec( MuScleFitUtils::crossSectionHandler->parNum(), 0 );
1176 parfix.insert( parfix.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1181 parorder.insert( parorder.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1185 std::vector<double> parerr(3*parnumberAll,0.);
1188 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters before likelihood " << std::endl;
1189 for (
unsigned int i=0; i<(
unsigned int)parnumberAll; i++) {
1191 << parorder[
i] << std::endl;
1208 TMinuit rmin (parnumber);
1214 rmin.mninit (5, 6, 7);
1221 rmin.mnexcm (
"SET STR", arglis, 1, ierror);
1225 rmin.mnexcm(
"SET RAN", arglis, 1, ierror);
1229 double * Start =
new double[parnumberAll];
1230 double *
Step =
new double[parnumberAll];
1231 double * Mini =
new double[parnumberAll];
1232 double * Maxi =
new double[parnumberAll];
1233 int * ind =
new int[parnumberAll];
1234 TString * parname =
new TString[parnumberAll];
1239 int resParNum = MuScleFitUtils::resolutionFunctionForVec->
parNum();
1241 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]), &(Mini[resParNum]), &(Maxi[resParNum]),
1245 int crossSectionParShift = resParNum + MuScleFitUtils::scaleFunctionForVec->
parNum();
1246 MuScleFitUtils::crossSectionHandler->
setParameters( &(Start[crossSectionParShift]), &(Step[crossSectionParShift]), &(Mini[crossSectionParShift]),
1247 &(Maxi[crossSectionParShift]), &(ind[crossSectionParShift]), &(parname[crossSectionParShift]),
1252 MuScleFitUtils::backgroundHandler->
setParameters( &(Start[bgrParShift]), &(Step[bgrParShift]), &(Mini[bgrParShift]), &(Maxi[bgrParShift]),
1255 for(
int ipar=0; ipar<parnumber; ++ipar ) {
1256 std::cout <<
"parname["<<ipar<<
"] = " << parname[ipar] << std::endl;
1257 std::cout <<
"Start["<<ipar<<
"] = " << Start[ipar] << std::endl;
1258 std::cout <<
"Step["<<ipar<<
"] = " << Step[ipar] << std::endl;
1259 std::cout <<
"Mini["<<ipar<<
"] = " << Mini[ipar] << std::endl;
1260 std::cout <<
"Maxi["<<ipar<<
"] = " << Maxi[ipar] << std::endl;
1263 rmin.mnparm( ipar, parname[ipar], Start[ipar], Step[ipar], Mini[ipar], Maxi[ipar], ierror );
1275 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Starting minimization" << std::endl;
1281 rmin.mnexcm (
"call fcn", arglis, 1, ierror);
1286 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: First fix all parameters ...";
1287 for (
int ipar=0; ipar<parnumber; ipar++) {
1288 rmin.FixParameter (ipar);
1293 if (
debug>19)
std::cout <<
" Then release them in order..." << std::endl;
1315 std::cout <<
"number of parameters for scaleFunction = " << scaleParNum << std::endl;
1316 std::cout <<
"number of parameters for resolutionFunction = " << resParNum << std::endl;
1318 std::cout <<
"number of parameters for backgroundFunction = " <<
parBgr.size() << std::endl;
1321 for (
int i=0; i<parnumber; i++) {
1323 if (n_times<ind[i]) {
1326 if ( i<resParNum ) {
1329 else if( i<resParNum+scaleParNum ) {
1335 for (
int iorder=0; iorder<n_times+1; iorder++) {
1336 std::cout <<
"Starting minimization " << iorder <<
" of " << n_times << std::endl;
1338 bool somethingtodo =
false;
1345 for(
unsigned int ipar=0; ipar<
parResol.size(); ++ipar ) {
1346 if( parfix[ipar]==0 && ind[ipar]==iorder ) {
1347 rmin.Release( ipar );
1348 somethingtodo =
true;
1356 if( parfix[ipar]==0 && ind[ipar]==iorder ) {
1357 rmin.Release( ipar );
1358 somethingtodo =
true;
1369 if( doCrossSection ) somethingtodo =
true;
1380 rmin.Release( ipar );
1381 somethingtodo =
true;
1388 if( somethingtodo ) {
1391 std::stringstream fileNum;
1396 sprintf(name,
"likelihoodInLoop_%d_%d", loopCounter, iorder);
1397 TH1D * tempLikelihoodInLoop =
new TH1D(name,
"likelihood value in minuit loop", 10000, 0, 10000);
1399 char signalProbName[50];
1400 sprintf(signalProbName,
"signalProb_%d_%d", loopCounter, iorder);
1401 TH1D * tempSignalProb =
new TH1D(signalProbName,
"signal probability", 10000, 0, 10000);
1403 char backgroundProbName[50];
1404 sprintf(backgroundProbName,
"backgroundProb_%d_%d", loopCounter, iorder);
1405 TH1D * tempBackgroundProb =
new TH1D(backgroundProbName,
"background probability", 10000, 0, 10000);
1416 double protectionFactor = 0.9;
1425 for(
int ires = 0; ires < 6; ++ires ) {
1431 double windowBorderLeft = resMassValue - protectionFactor*(resMassValue - windowBorder.first);
1432 double windowBorderRight = resMassValue + protectionFactor*(windowBorder.second - resMassValue);
1453 rmin.mnexcm(
"simplex", arglis, 0, ierror );
1456 rmin.mnexcm(
"mini", arglis, 0, ierror );
1463 delete tempLikelihoodInLoop;
1464 delete tempSignalProb;
1465 delete tempBackgroundProb;
1473 rmin.mnexcm(
"hesse", arglis, 0, ierror );
1478 rmin.mnexcm(
"minos", arglis, 0, ierror );
1483 std::cout <<
"WARNING: normalization changed during fit meaning that events exited from the mass window. This causes a discontinuity in the likelihood function. Please check the scan of the likelihood as a function of the parameters to see if there are discontinuities around the minimum." << std::endl;
1488 for (
int ipar=0; ipar<parnumber; ipar++) {
1490 rmin.mnpout (ipar, name, pval, erro, pmin, pmax, ivar);
1493 if (ierror!=0 &&
debug>0) {
1494 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: ierror!=0, bogus pars" << std::endl;
1505 rmin.mnerrs (ipar, errh, errl, errp, cglo);
1511 parerr[3*ipar] = errp;
1513 parerr[3*ipar] = (((errh)>(fabs(errl)))?(errh):(fabs(errl)));
1515 parerr[3*ipar+1] = errl;
1516 parerr[3*ipar+2] = errh;
1519 FitParametersFile <<
" Resolution fit parameters:" << std::endl;
1521 if( ipar ==
int(
parResol.size()) ) {
1522 FitParametersFile <<
" Scale fit parameters:" << std::endl;
1525 FitParametersFile <<
" Cross section fit parameters:" << std::endl;
1528 FitParametersFile <<
" Background fit parameters:" << std::endl;
1544 FitParametersFile <<
" Results of the fit: parameter " << ipar <<
" has value "
1545 << pval <<
"+-" << parerr[3*ipar]
1546 <<
" + " << parerr[3*ipar+1] <<
" - " << parerr[3*ipar+2]
1551 rmin.mnstat (fmin, fdem, errdef, npari, nparx, istat);
1552 FitParametersFile << std::endl;
1558 if( somethingtodo ) {
1559 std::stringstream iorderString;
1560 iorderString << iorder;
1561 std::stringstream iLoopString;
1564 for (
int ipar=0; ipar<parnumber; ipar++) {
1565 if( parfix[ipar] == 1 )
continue;
1566 std::cout <<
"plotting parameter = " << ipar+1 << std::endl;
1567 std::stringstream iparString;
1568 iparString << ipar+1;
1569 rmin.mncomd( (
"scan "+iparString.str()).c_str(), ierror );
1571 TCanvas *
canvas =
new TCanvas((
"likelihoodCanvas_loop_"+iLoopString.str()+
"_oder_"+iorderString.str()+
"_par_"+iparString.str()).c_str(), (
"likelihood_"+iparString.str()).c_str(), 1000, 800);
1575 TGraph *
graph = (TGraph*)rmin.GetPlot();
1578 graph->SetTitle(parname[ipar]);
1600 FitParametersFile.close();
1602 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters after likelihood " << std::endl;
1603 for (
unsigned int ipar=0; ipar<(
unsigned int)parnumber; ipar++) {
1605 << parfix[ipar] <<
"; order = " << parorder[ipar] << std::endl;
1610 for(
int i=0; i<(int)(
parResol.size()); ++
i ) {
1613 for(
int i=0; i<(int)(
parScale.size()); ++
i ) {
1622 for(
unsigned int i = 0; i<(
parBgr.size() - parForResonanceWindows); ++
i ) {
1632 if(
MuonType > 2 ) localMuonType = 2;
1648 extern "C" void likelihood(
int& npar,
double* grad,
double& fval,
double* xval,
int flag ) {
1718 double Y = (corrMu1+corrMu2).Rapidity();
1719 double resEta = (corrMu1+corrMu2).
Eta();
1721 std::cout <<
"[MuScleFitUtils-likelihood]: Original/Corrected resonance mass = " << mass
1722 <<
" / " << corrMass << std::endl;
1729 std::cout <<
"[MuScleFitUtils-likelihood]: Resolution is " << massResol << std::endl;
1746 std::cout <<
"WARNING: corrMass = " << corrMass <<
" outside window, this will cause a discontinuity in the likelihood. Consider increasing the safety bands which are now set to 90% of the normalization window to avoid this problem" << std::endl;
1747 std::cout <<
"Original mass was = " << mass << std::endl;
1748 std::cout <<
"WARNING: massResol = " << massResol <<
" outside window" << std::endl;
1753 std::cout <<
"[MuScleFitUtils-likelihood]: Mass probability = " << prob << std::endl;
1776 if( evtsinlik != 0 ) {
1783 double normalizationArg[] = {1/double(evtsinlik)};
1797 fval = -2.*flike/double(evtsinlik);
1808 std::cout <<
"Problem: Events in likelihood = " << evtsinlik << std::endl;
1813 std::cout <<
"[MuScleFitUtils-likelihood]: End tree loop with likelihood value = " << fval << std::endl;
1836 std::cout <<
"Events in likelihood = " << evtsinlik << std::endl;
1837 std::cout <<
"Events out likelihood = " << evtsoutlik << std::endl;
1849 std::vector<TGraphErrors *>
results;
1853 std::vector<double> Ftop;
1854 std::vector<double> Fwidth;
1855 std::vector<double> Fmass;
1856 std::vector<double> Etop;
1857 std::vector<double> Ewidth;
1858 std::vector<double> Emass;
1859 std::vector<double> Fchi2;
1862 std::vector<double> Xcenter;
1863 std::vector<double> Ex;
1868 fitFcn->SetParameters (100, 3, 91);
1869 fitFcn->SetParNames (
"Ftop",
"Fwidth",
"Fmass");
1870 fitFcn->SetLineWidth (2);
1874 double cont_min = 20;
1875 Int_t binx = histo->GetXaxis()->GetNbins();
1878 for (
int i=1;
i<=binx;
i++) {
1879 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
1881 double cont = histoY->GetEntries();
1882 if (cont>cont_min) {
1883 histoY->Fit (
"fitFcn",
"0",
"", 70, 110);
1884 double *
par = fitFcn->GetParameters();
1885 double *err = fitFcn->GetParErrors();
1887 Ftop.push_back(par[0]);
1888 Fwidth.push_back(par[1]);
1889 Fmass.push_back(par[2]);
1890 Etop.push_back(err[0]);
1891 Ewidth.push_back(err[1]);
1892 Emass.push_back(err[2]);
1894 double chi2 = fitFcn->GetChisquare();
1895 Fchi2.push_back(chi2);
1897 double xx = histo->GetXaxis()->GetBinCenter(
i);
1898 Xcenter.push_back(xx);
1907 const int nn = Fmass.size();
1908 double *
x =
new double[nn];
1909 double *ym =
new double[nn];
1910 double *
e =
new double[nn];
1911 double *eym =
new double[nn];
1912 double *yw =
new double[nn];
1913 double *eyw =
new double[nn];
1914 double *yc =
new double[nn];
1916 for (
int j=0;
j<nn;
j++) {
1928 TString
name = histo->GetName();
1929 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
1930 grM->SetTitle (name+
"_M");
1931 grM->SetName (name+
"_M");
1932 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
1933 grW->SetTitle (name+
"_W");
1934 grW->SetName (name+
"_W");
1935 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
1936 grC->SetTitle (name+
"_chi2");
1937 grC->SetName (name+
"_chi2");
1950 results.push_back(grM);
1951 results.push_back(grW);
1952 results.push_back(grC);
1959 std::cout <<
"Fitting " << histo->GetName() << std::endl;
1960 std::vector<TGraphErrors *>
results;
1964 std::vector<double> maxs;
1965 std::vector<double> means;
1966 std::vector<double> sigmas;
1967 std::vector<double> chi2s;
1968 std::vector<double> Emaxs;
1969 std::vector<double> Emeans;
1970 std::vector<double> Esigmas;
1974 std::vector<double> Xcenter;
1975 std::vector<double> Ex;
1979 TF1 *fitFcn =
new TF1 (
"fitFunc",
Gaussian, -0.2, 0.2, 3);
1980 fitFcn->SetParameters (100, 0, 0.02);
1981 fitFcn->SetParNames (
"max",
"mean",
"sigma");
1982 fitFcn->SetLineWidth (2);
1986 double cont_min = 20;
1987 Int_t binx = histo->GetXaxis()->GetNbins();
1988 for (
int i=1;
i<=binx;
i++) {
1989 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
1990 double cont = histoY->GetEntries();
1991 if (cont>cont_min) {
1992 histoY->Fit (
"fitFunc",
"0",
"", -0.2, 0.2);
1993 double *
par = fitFcn->GetParameters();
1994 double *err = fitFcn->GetParErrors();
1996 maxs.push_back (par[0]);
1997 means.push_back (par[1]);
1998 sigmas.push_back (par[2]);
1999 Emaxs.push_back (err[0]);
2000 Emeans.push_back (err[1]);
2001 Esigmas.push_back (err[2]);
2003 double chi2 = fitFcn->GetChisquare();
2004 chi2s.push_back (chi2);
2006 double xx = histo->GetXaxis()->GetBinCenter(
i);
2007 Xcenter.push_back (xx);
2015 const int nn = means.size();
2016 double *
x =
new double[nn];
2017 double *ym =
new double[nn];
2018 double *
e =
new double[nn];
2019 double *eym =
new double[nn];
2020 double *yw =
new double[nn];
2021 double *eyw =
new double[nn];
2022 double *yc =
new double[nn];
2024 for (
int j=0;
j<nn;
j++) {
2031 eyw[
j] = Esigmas[
j];
2038 TString
name = histo->GetName();
2039 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
2040 grM->SetTitle (name+
"_mean");
2041 grM->SetName (name+
"_mean");
2042 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
2043 grW->SetTitle (name+
"_sigma");
2044 grW->SetName (name+
"_sigma");
2045 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
2046 grC->SetTitle (name+
"_chi2");
2047 grC->SetName (name+
"_chi2");
2060 results.push_back (grM);
2061 results.push_back (grW);
2062 results.push_back (grC);
2078 if (massResol==0.) {
2079 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2081 <<
" : used Lorentz P-value" << std::endl;
2102 double *
x =
new double[
np];
2103 double * w =
new double[
np];
2105 GL->CalcGaussLegendreSamplingPoints (np, x, w, 0.1
e-15);
2114 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2116 <<
": used epsilon" << std::endl;
2120 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2122 <<
" " << P << std::endl;
2130 std::pair<lorentzVector, lorentzVector> simMuFromRes;
2131 for( edm::SimTrackContainer::const_iterator simTrack=simTracks->begin(); simTrack!=simTracks->end(); ++simTrack ) {
2133 if (fabs((*simTrack).type())==13) {
2135 if ((*simTrack).genpartIndex()>0) {
2136 HepMC::GenParticle* gp = evtMC->GetEvent()->barcode_to_particle ((*simTrack).genpartIndex());
2139 for (HepMC::GenVertex::particle_iterator mother = gp->production_vertex()->particles_begin(HepMC::ancestors);
2140 mother!=gp->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2142 bool fromRes =
false;
2143 unsigned int motherPdgId = (*mother)->pdg_id();
2144 for(
int ires = 0; ires < 6; ++ires ) {
2148 if(gp->pdg_id() == 13)
2149 simMuFromRes.first =
lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
2150 simTrack->momentum().pz(),simTrack->momentum().e());
2152 simMuFromRes.second =
lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
2153 simTrack->momentum().pz(),simTrack->momentum().e());
2161 return simMuFromRes;
2166 const HepMC::GenEvent* Evt = evtMC->
GetEvent();
2167 std::pair<lorentzVector,lorentzVector> muFromRes;
2169 for (HepMC::GenEvent::particle_const_iterator
part=Evt->particles_begin();
2170 part!=Evt->particles_end();
part++) {
2171 if (fabs((*part)->pdg_id())==13 && (*part)->status()==1) {
2172 bool fromRes =
false;
2173 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
2174 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2175 unsigned int motherPdgId = (*mother)->pdg_id();
2180 if( motherPdgId == 13 && (*mother)->status() == 3 ) fromRes =
true;
2183 for(
int ires = 0; ires < 6; ++ires ) {
2189 if((*part)->pdg_id()==13)
2191 muFromRes.first = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2192 (*part)->momentum().pz(),(*part)->momentum().e()));
2194 muFromRes.second = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2195 (*part)->momentum().pz(),(*part)->momentum().e()));
2204 std::pair<lorentzVector,lorentzVector> muFromRes;
2207 if(
debug>0 )
std::cout <<
"Starting loop on " << genParticles->size() <<
" genParticles" << std::endl;
2208 for( reco::GenParticleCollection::const_iterator
part=genParticles->begin();
part!=genParticles->end(); ++
part ) {
2209 if (fabs(
part->pdgId())==13 &&
part->status()==1) {
2210 bool fromRes =
false;
2211 unsigned int motherPdgId =
part->mother()->pdgId();
2213 std::cout <<
"Found a muon with mother: " << motherPdgId << std::endl;
2215 for(
int ires = 0; ires < 6; ++ires ) {
2219 if(
part->pdgId()==13) {
2220 muFromRes.first =
part->p4();
2221 if(
debug>0 )
std::cout <<
"Found a genMuon + : " << muFromRes.first << std::endl;
2226 muFromRes.second =
part->p4();
2227 if(
debug>0 )
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
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 unsigned int loopCounter
static std::pair< lorentzVector, lorentzVector > findSimMuFromRes(const edm::Handle< edm::HepMCProduct > &evtMC, const edm::Handle< edm::SimTrackContainer > &simTracks)
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
void likelihood(int &npar, double *grad, double &fval, double *xval, int flag)
static double x[7][10000]
static std::vector< TGraphErrors * > fitMass(TH2F *histo)
static double massWindowHalfWidth[3][6]
static bool scaleFitNotDone_
static unsigned int normalizationChanged_
static scaleFunctionBase< std::vector< double > > * biasFunction
Exp< T >::type exp(const T &t)
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 bool minimumShapePlots_
static int MuonTypeForCheckMassWindow
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 &resEta)
static double minMuonEtaFirstRange_
static double massProb(const double &mass, const double &rapidity, const int ires, const double &massResol)
static struct MuScleFitUtils::massResolComponentsStruct massResolComponents
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
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
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)=0
This method is used to differentiate parameters among the different functions.
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]
virtual int parNum() const
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
bool check(const DataFrame &df, bool capcheck, bool dvercheck)
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)
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< 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
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)
static TH1D * likelihoodInLoop_
static std::vector< double > parScale
static double oldNormalization_
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.
const HepMC::GenEvent * GetEvent() const
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.
Log< T >::type log(const T &t)
static double ResGamma[6]
Double_t lorentzianPeak(Double_t *x, Double_t *par)
static bool rapidityBinsForZ_
static double minMuonEtaSecondRange_
static std::vector< double > parCrossSection
std::vector< std::vector< double > > tmp
static double GLNorm[6][1001]
static std::vector< TGraphErrors * > fitReso(TH2F *histo)
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
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
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 ResHalfWidth[6]
static int counter_resprob
static resolutionFunctionBase< std::vector< double > > * resolutionFunctionForVec
static std::vector< int > parorder
virtual int parNum() const
static double maxMuonEtaFirstRange_
static std::pair< lorentzVector, lorentzVector > findBestRecoRes(const std::vector< reco::LeafCandidate > &muons)
Power< A, B >::type pow(const A &a, const B &b)
static CrossSectionHandler * crossSectionHandler
static std::vector< int > parCrossSectionFix
static resolutionFunctionBase< double * > * resolutionFunction
const double par[8 *NPar][4]