50 #include "valgrind/callgrind.h"
57 TMath::Max(1.
e-10,(x[0]-par[2])*(x[0]-par[2]) + .25*par[1]*par[1]);
63 return par[0]*
exp(-0.5*((x[0]-par[1])/par[2])*((x[0]-par[1])/par[2]));
82 TF1 *
GL =
new TF1 (
"GL",
83 "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))",
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))",
269 std::pair<SimTrack, SimTrack> simMuFromBestRes;
270 double maxprob = -0.1;
274 for (std::vector<SimTrack>::const_iterator simMu1=simMuons.begin(); simMu1!=simMuons.end(); simMu1++) {
275 for (std::vector<SimTrack>::const_iterator simMu2=simMu1+1; simMu2!=simMuons.end(); simMu2++) {
276 if (((*simMu1).charge()*(*simMu2).charge())>0) {
281 double mcomb = ((*simMu1).momentum()+(*simMu2).momentum()).mass();
282 double Y = ((*simMu1).momentum()+(*simMu2).momentum()).Rapidity();
287 simMuFromBestRes.first = (*simMu1);
288 simMuFromBestRes.second = (*simMu2);
298 return simMuFromBestRes;
310 std::pair<lorentzVector, lorentzVector> recMuFromBestRes;
314 double maxprob = -0.1;
315 double minDeltaMass = 999999;
316 std::pair<reco::LeafCandidate,reco::LeafCandidate> bestMassMuons;
317 for (std::vector<reco::LeafCandidate>::const_iterator Muon1=muons.begin(); Muon1!=muons.end(); ++Muon1) {
319 if (
debug>0)
std::cout <<
"muon_1_charge:"<<(*Muon1).charge() << std::endl;
320 for (std::vector<reco::LeafCandidate>::const_iterator Muon2=Muon1+1; Muon2!=muons.end(); ++Muon2) {
323 if (((*Muon1).charge()*(*Muon2).charge())>0) {
330 double pt1 = (*Muon1).p4().Pt();
331 double pt2 = (*Muon2).p4().Pt();
332 double eta1 = (*Muon1).p4().Eta();
333 double eta2 = (*Muon2).p4().Eta();
340 double mcomb = ((*Muon1).p4()+(*Muon2).p4()).mass();
341 double Y = ((*Muon1).p4()+(*Muon2).p4()).Rapidity();
343 std::cout<<
"muon1 "<<(*Muon1).p4().Px()<<
", "<<(*Muon1).p4().Py()<<
", "<<(*Muon1).p4().Pz()<<
", "<<(*Muon1).p4().E()<<std::endl;
344 std::cout<<
"muon2 "<<(*Muon2).p4().Px()<<
", "<<(*Muon2).p4().Py()<<
", "<<(*Muon2).p4().Pz()<<
", "<<(*Muon2).p4().E()<<std::endl;
346 double massResol = 0.;
357 if( (*Muon1).charge()<0 ) {
358 recMuFromBestRes.first = (*Muon1).p4();
359 recMuFromBestRes.second = (*Muon2).p4();
361 recMuFromBestRes.first = (*Muon2).p4();
362 recMuFromBestRes.second = (*Muon1).p4();
372 if( deltaMass<minDeltaMass ){
373 bestMassMuons = std::make_pair((*Muon1),(*Muon2));
374 minDeltaMass = deltaMass;
384 if(bestMassMuons.first.charge()<0){
385 recMuFromBestRes.first = bestMassMuons.first.p4();
386 recMuFromBestRes.second = bestMassMuons.second.p4();
389 recMuFromBestRes.second = bestMassMuons.first.p4();
390 recMuFromBestRes.first = bestMassMuons.second.p4();
393 return recMuFromBestRes;
400 double pt = muon.Pt();
401 double eta = muon.Eta();
402 double phi = muon.Phi();
414 std::cout <<
"Smearing Pt,eta,phi = " << pt <<
" " << eta <<
" "
416 for (
int i=0;
i<SmearType+3;
i++) {
422 double ptEtaPhiE[4] = {
pt,
eta,
phi, E};
430 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
449 const std::vector<double> & parval,
const int chg)
451 double *
p =
new double[(int)(parval.size())];
456 for (std::vector<double>::const_iterator it=parval.begin(); it!=parval.end(); ++it, ++id) {
469 double* parval,
const int chg)
471 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
478 ptEtaPhiE[0] =
scaleFunction->
scale(ptEtaPhiE[0], ptEtaPhiE[1], ptEtaPhiE[2], chg, &(parval[shift]));
489 double px = ptEtaPhiE[0]*
cos(ptEtaPhiE[2]);
490 double py = ptEtaPhiE[0]*
sin(ptEtaPhiE[2]);
491 double tmp = 2*atan(
exp(-ptEtaPhiE[1]));
492 double pz = ptEtaPhiE[0]*
cos(tmp)/
sin(tmp);
507 return (mu1+mu2).mass();
514 const std::vector<double> & parval )
527 double *
p =
new double[(int)(parval.size())];
528 std::vector<double>::const_iterator it = parval.begin();
530 for ( ; it!=parval.end(); ++it, ++id) {
560 double mass = (mu1+mu2).mass();
561 double pt1 = mu1.Pt();
562 double phi1 = mu1.Phi();
563 double eta1 = mu1.Eta();
564 double theta1 = 2*atan(
exp(-eta1));
565 double pt2 = mu2.Pt();
566 double phi2 = mu2.Phi();
567 double eta2 = mu2.Eta();
568 double theta2 = 2*atan(
exp(-eta2));
571 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
573 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
574 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
575 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
576 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
578 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
579 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
581 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
607 2*dmdpt1*dmdpt2*cov_pt1pt2*sigma_pt1*sigma_pt2);
610 std::cout <<
" Pt1=" << pt1 <<
" phi1=" << phi1 <<
" cotgth1=" <<
cos(theta1)/
sin(theta1) <<
" - Pt2=" << pt2
611 <<
" phi2=" << phi2 <<
" cotgth2=" <<
cos(theta2)/
sin(theta2) << std::endl;
613 << parval[0] <<
" P[1]=" << parval[1] <<
"P[2]=" << parval[2] <<
" P[3]=" << parval[3] << std::endl;
614 std::cout <<
" Dmdpt1= " << dmdpt1 <<
" dmdpt2= " << dmdpt2 <<
" sigma_pt1="
615 << sigma_pt1 <<
" sigma_pt2=" << sigma_pt2 << std::endl;
616 std::cout <<
" Dmdphi1= " << dmdphi1 <<
" dmdphi2= " << dmdphi2 <<
" sigma_phi1="
617 << sigma_phi1 <<
" sigma_phi2=" << sigma_phi2 << std::endl;
618 std::cout <<
" Dmdcotgth1= " << dmdcotgth1 <<
" dmdcotgth2= " << dmdcotgth2
620 << sigma_cotgth1 <<
" sigma_cotgth2=" << sigma_cotgth2 << std::endl;
621 std::cout <<
" Mass resolution (pval) for muons of Pt = " << pt1 <<
" " << pt2
622 <<
" : " << mass <<
" +- " << mass_res << std::endl;
632 LogDebug(
"MuScleFitUtils") <<
"RESOLUTION PROBLEM: ires=" << ires << std::endl;
649 double mass = (mu1+mu2).mass();
650 double pt1 = mu1.Pt();
651 double phi1 = mu1.Phi();
652 double eta1 = mu1.Eta();
653 double theta1 = 2*atan(
exp(-eta1));
654 double pt2 = mu2.Pt();
655 double phi2 = mu2.Phi();
656 double eta2 = mu2.Eta();
657 double theta2 = 2*atan(
exp(-eta2));
660 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
662 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
663 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
664 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
665 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
667 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
668 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
670 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
674 double sigma_pt1 = resolFunc.
sigmaPt( mu1 );
675 double sigma_pt2 = resolFunc.
sigmaPt( mu2 );
676 double sigma_phi1 = resolFunc.
sigmaPhi( mu1 );
677 double sigma_phi2 = resolFunc.
sigmaPhi( mu2 );
678 double sigma_cotgth1 = resolFunc.
sigmaCotgTh( mu1 );
679 double sigma_cotgth2 = resolFunc.
sigmaCotgTh( mu2 );
693 double MuScleFitUtils::massProb(
const double & mass,
const double & resEta,
const double & rapidity,
const double & massResol,
const std::vector<double> & parval,
const bool doUseBkgrWindow,
const double & eta1,
const double & eta2 )
696 CALLGRIND_START_INSTRUMENTATION;
699 double *
p =
new double[(int)(parval.size())];
704 std::vector<double>::const_iterator it = parval.begin();
706 for ( ; it!=parval.end(); ++it, ++id) {
711 double massProbability =
massProb( mass, resEta, rapidity, massResol, p, doUseBkgrWindow, eta1, eta2 );
715 CALLGRIND_STOP_INSTRUMENTATION;
716 CALLGRIND_DUMP_STATS;
719 return massProbability;
728 const double GLvalue[][1001][1001],
const double GLnorm[][1001],
729 const int iRes,
const int iY )
731 if( iRes == 0 && iY > 23 ) {
732 std::cout <<
"WARNING: rapidity bin selected = " << iY <<
" but there are only histograms for the first 24 bins" << std::endl;
736 bool insideProbMassWindow =
true;
744 if (
debug>1)
std::cout << std::setprecision(9)<<
"mass ResMinMass[iRes] ResHalfWidth[iRes] ResHalfWidth[iRes]"
746 int iMassLeft = (int)(fracMass*(
double)
nbins);
747 int iMassRight = iMassLeft+1;
748 double fracMassStep = (double)
nbins*(fracMass - (
double)iMassLeft/(double)
nbins);
749 if (
debug>1)
std::cout<<
"nbins iMassLeft fracMass "<<nbins<<
" "<<iMassLeft<<
" "<<fracMass<<std::endl;
755 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassLeft="
756 << iMassLeft <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
760 insideProbMassWindow =
false;
762 if (iMassRight>nbins) {
763 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassRight="
764 << iMassRight <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
765 <<
":" <<
ResMass[iRes]+2*
ResHalfWidth[iRes] <<
" - iMassRight set to " << nbins-1 << std::endl;
768 insideProbMassWindow =
false;
771 int iSigmaLeft = (int)(fracSigma*(
double)
nbins);
772 int iSigmaRight = iSigmaLeft+1;
773 double fracSigmaStep = (double)nbins * (fracSigma - (
double)iSigmaLeft/(double)nbins);
787 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaLeft="
788 << iSigmaLeft <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = "
789 <<
ResMaxSigma[iRes] <<
" - iSigmaLeft set to 0" << std::endl;
793 if (iSigmaRight>nbins ) {
795 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaRight="
796 << iSigmaRight <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = "
797 <<
ResMaxSigma[iRes] <<
" - iSigmaRight set to " << nbins-1 << std::endl;
798 iSigmaLeft = nbins-1;
805 if( insideProbMassWindow ) {
807 if (GLnorm[iY][iSigmaLeft]>0)
808 f11 = GLvalue[iY][iMassLeft][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
810 if (GLnorm[iY][iSigmaRight]>0)
811 f12 = GLvalue[iY][iMassLeft][iSigmaRight] / GLnorm[iY][iSigmaRight];
813 if (GLnorm[iY][iSigmaLeft]>0)
814 f21 = GLvalue[iY][iMassRight][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
816 if (GLnorm[iY][iSigmaRight]>0)
817 f22 = GLvalue[iY][iMassRight][iSigmaRight] / GLnorm[iY][iSigmaRight];
818 PS = f11 + (f12-f11)*fracSigmaStep + (f21-f11)*fracMassStep +
819 (f22-f21-f12+f11)*fracMassStep*fracSigmaStep;
820 if (PS>0.1 ||
debug>1)
LogDebug(
"MuScleFitUtils") <<
"iRes = " << iRes <<
" PS=" << PS <<
" f11,f12,f21,f22="
821 << f11 <<
" " << f12 <<
" " << f21 <<
" " << f22 <<
" "
822 <<
" fSS=" << fracSigmaStep <<
" fMS=" << fracMassStep <<
" iSL, iSR="
823 << iSigmaLeft <<
" " << iSigmaRight
824 <<
" GLvalue["<<iY<<
"]["<<iMassLeft<<
"] = " << GLvalue[iY][iMassLeft][iSigmaLeft]
825 <<
" GLnorm["<<iY<<
"]["<<iSigmaLeft<<
"] = " << GLnorm[iY][iSigmaLeft] << std::endl;
836 edm::LogInfo(
"probability") <<
"outside mass probability window. Setting PS["<<iRes<<
"] = 0" << std::endl;
858 double MuScleFitUtils::massProb(
const double & mass,
const double & resEta,
const double & rapidity,
const double & massResol,
double * parval,
const bool doUseBkgrWindow,
const double & eta1,
const double & eta2 ) {
949 double PStot[6] = {0.};
952 bool resConsidered[6] = {
false};
974 int iY = (int)(fabs(rapidity)*10.);
975 if( iY > 23 ) iY = 23;
982 if( PS[0] != PS[0] ) {
983 std::cout <<
"ERROR: PS[0] = nan, setting it to 0" << std::endl;
995 Bgrp1 = bgrResult.first;
999 PB = bgrResult.second;
1000 if( PB != PB ) PB = 0;
1001 PStot[0] = (1-Bgrp1)*PS[0] + Bgrp1*PB;
1005 PStot[0] *= relativeCrossSections[0];
1010 std::cout <<
"Mass = " << mass <<
" outside range with rapidity = " << rapidity << std::endl;
1011 std::cout <<
"with resMass = " <<
backgroundHandler->
resMass( useBackgroundWindow, 0 ) <<
" and left border = " << windowBorders.first <<
" right border = " << windowBorders.second << std::endl;
1024 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1034 Bgrp1 = bgrResult.first;
1035 PB = bgrResult.second;
1037 if( PB != PB ) PB = 0;
1038 PStot[
ires] = (1-Bgrp1)*PS[
ires] + Bgrp1*PB;
1041 PStot[
ires] *= relativeCrossSections[
ires];
1046 for(
int i=0;
i<6; ++
i ) {
1051 double PStotTemp = 0.;
1052 for(
int i=0;
i<6; ++
i ) {
1053 PStotTemp += PS[
i]*relativeCrossSections[
i];
1055 if( PStotTemp != PStotTemp ) {
1056 std::cout <<
"ERROR: PStotTemp = nan!!!!!!!!!" << std::endl;
1058 for(
int i=0;
i<6; ++
i ) {
1059 std::cout <<
"PS[i] = " << PS[
i] << std::endl;
1060 if( PS[
i] != PS[
i] ) {
1061 std::cout <<
"mass = " << mass << std::endl;
1062 std::cout <<
"massResol = " << massResol << std::endl;
1063 for(
int j=0;
j<parnumber; ++
j ) {
1064 std::cout <<
"parval["<<
j<<
"] = " << parval[
j] << std::endl;
1069 if( PStotTemp == PStotTemp ) {
1072 if (
debug>0)
std::cout <<
"mass = " << mass <<
", P = " << P <<
", PStot = " << PStotTemp <<
", PB = " << PB <<
", bgrp1 = " << Bgrp1 << std::endl;
1087 return( (mass > leftBorder) && (mass < rightBorder) );
1103 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"using backgrond window for mass = " << mass << std::endl;
1113 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1115 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"setting weight to = " << weight << std::endl;
1129 std::ofstream FitParametersFile;
1130 FitParametersFile.open (
"FitParameters.txt", std::ios::app);
1131 FitParametersFile <<
"Fitting with resolution, scale, bgr function # "
1148 int parForResonanceWindows = 0;
1161 std::vector<double> *tmpVec = &(
parvalue.back());
1168 std::cout <<
"scaleFitNotDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1172 std::cout <<
"scaleFitDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1175 tmpVec->insert( tmpVec->end(),
parBgr.begin(),
parBgr.end() );
1177 std::vector<double>::const_iterator it = tmpVec->begin();
1178 for( ; it != tmpVec->end(); ++it, ++
i ) {
1179 std::cout <<
"tmpVec["<<i<<
"] = " << *it << std::endl;
1185 std::vector<int> crossSectionParNumSizeVec( MuScleFitUtils::crossSectionHandler->parNum(), 0 );
1189 parfix.insert( parfix.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1194 parorder.insert( parorder.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1198 std::vector<double> parerr(3*parnumberAll,0.);
1201 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters before likelihood " << std::endl;
1202 for (
unsigned int i=0; i<(
unsigned int)parnumberAll; i++) {
1204 << parorder[
i] << std::endl;
1221 TMinuit rmin (parnumber);
1227 rmin.mninit (5, 6, 7);
1234 rmin.mnexcm (
"SET STR", arglis, 1, ierror);
1238 rmin.mnexcm(
"SET RAN", arglis, 1, ierror);
1242 double * Start =
new double[parnumberAll];
1243 double *
Step =
new double[parnumberAll];
1244 double * Mini =
new double[parnumberAll];
1245 double * Maxi =
new double[parnumberAll];
1246 int * ind =
new int[parnumberAll];
1247 TString * parname =
new TString[parnumberAll];
1250 MuScleFitUtils::resolutionFunctionForVec->
setParameters( Start, Step, Mini, Maxi, ind, parname,
parResol,
parResolOrder,
parResolStep,
parResolMin,
parResolMax,
MuonType );
1257 int resParNum = MuScleFitUtils::resolutionFunctionForVec->
parNum();
1260 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]),
1261 &(Mini[resParNum]), &(Maxi[resParNum]),
1262 &(ind[resParNum]), &(parname[resParNum]),
1267 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]),
1268 &(Mini[resParNum]), &(Maxi[resParNum]),
1269 &(ind[resParNum]), &(parname[resParNum]),
1274 int crossSectionParShift = resParNum + MuScleFitUtils::scaleFunctionForVec->
parNum();
1275 MuScleFitUtils::crossSectionHandler->
setParameters( &(Start[crossSectionParShift]), &(Step[crossSectionParShift]), &(Mini[crossSectionParShift]),
1276 &(Maxi[crossSectionParShift]), &(ind[crossSectionParShift]), &(parname[crossSectionParShift]),
1281 MuScleFitUtils::backgroundHandler->
setParameters( &(Start[bgrParShift]), &(Step[bgrParShift]), &(Mini[bgrParShift]), &(Maxi[bgrParShift]),
1284 for(
int ipar=0; ipar<parnumber; ++ipar ) {
1285 std::cout <<
"parname["<<ipar<<
"] = " << parname[ipar] << std::endl;
1286 std::cout <<
"Start["<<ipar<<
"] = " << Start[ipar] << std::endl;
1287 std::cout <<
"Step["<<ipar<<
"] = " << Step[ipar] << std::endl;
1288 std::cout <<
"Mini["<<ipar<<
"] = " << Mini[ipar] << std::endl;
1289 std::cout <<
"Maxi["<<ipar<<
"] = " << Maxi[ipar] << std::endl;
1292 rmin.mnparm( ipar, parname[ipar], Start[ipar], Step[ipar], Mini[ipar], Maxi[ipar], ierror );
1304 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Starting minimization" << std::endl;
1310 rmin.mnexcm (
"CALL FCN", arglis, 1, ierror);
1315 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: First fix all parameters ...";
1316 for (
int ipar=0; ipar<parnumber; ipar++) {
1317 rmin.FixParameter (ipar);
1322 if (
debug>19)
std::cout <<
" Then release them in order..." << std::endl;
1344 std::cout <<
"number of parameters for scaleFunction = " << scaleParNum << std::endl;
1345 std::cout <<
"number of parameters for resolutionFunction = " << resParNum << std::endl;
1347 std::cout <<
"number of parameters for backgroundFunction = " <<
parBgr.size() << std::endl;
1350 for (
int i=0; i<parnumber; i++) {
1352 if (n_times<ind[i]) {
1355 if ( i<resParNum ) {
1358 else if( i<resParNum+scaleParNum ) {
1365 std::cout <<
"Starting minimization " <<
iorder <<
" of " << n_times << std::endl;
1367 bool somethingtodo =
false;
1374 for(
unsigned int ipar=0; ipar<
parResol.size(); ++ipar ) {
1375 if( parfix[ipar]==0 && ind[ipar]==
iorder ) {
1376 rmin.Release( ipar );
1377 somethingtodo =
true;
1385 if( parfix[ipar]==0 && ind[ipar]==
iorder ) {
1386 rmin.Release( ipar );
1387 somethingtodo =
true;
1398 if( doCrossSection ) somethingtodo =
true;
1409 rmin.Release( ipar );
1410 somethingtodo =
true;
1417 if( somethingtodo ) {
1420 std::stringstream fileNum;
1425 sprintf(name,
"likelihoodInLoop_%d_%d", loopCounter,
iorder);
1426 TH1D * tempLikelihoodInLoop =
new TH1D(name,
"likelihood value in minuit loop", 10000, 0, 10000);
1428 char signalProbName[50];
1429 sprintf(signalProbName,
"signalProb_%d_%d", loopCounter,
iorder);
1430 TH1D * tempSignalProb =
new TH1D(signalProbName,
"signal probability", 10000, 0, 10000);
1432 char backgroundProbName[50];
1433 sprintf(backgroundProbName,
"backgroundProb_%d_%d", loopCounter,
iorder);
1434 TH1D * tempBackgroundProb =
new TH1D(backgroundProbName,
"background probability", 10000, 0, 10000);
1445 double protectionFactor = 0.9;
1462 double windowBorderShift = (windowBorder.second - windowBorder.first)*(1-protectionFactor)/2.;
1463 double windowBorderLeft = windowBorder.first + windowBorderShift;
1464 double windowBorderRight = windowBorder.second - windowBorderShift;
1479 std::cout<<
"MINUIT is starting the minimization for the iteration number "<<loopCounter<<std::endl;
1484 std::cout<<
"maxNumberOfIterations (just set) = "<<rmin.GetMaxIterations()<<std::endl;
1495 rmin.mnexcm(
"SIMPLEX", arglis, 0, ierror );
1498 rmin.mnexcm(
"MIGRAD", arglis, 2, ierror );
1507 delete tempLikelihoodInLoop;
1508 delete tempSignalProb;
1509 delete tempBackgroundProb;
1517 rmin.mnexcm(
"HESSE", arglis, 0, ierror );
1522 rmin.mnexcm(
"MINOS", arglis, 0, ierror );
1527 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;
1532 for (
int ipar=0; ipar<parnumber; ipar++) {
1534 rmin.mnpout (ipar, name, pval, erro, pmin, pmax, ivar);
1537 if (ierror!=0 &&
debug>0) {
1538 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: ierror!=0, bogus pars" << std::endl;
1549 rmin.mnerrs (ipar, errh, errl, errp, cglo);
1555 parerr[3*ipar] = errp;
1557 parerr[3*ipar] = (((errh)>(fabs(errl)))?(errh):(fabs(errl)));
1559 parerr[3*ipar+1] = errl;
1560 parerr[3*ipar+2] = errh;
1563 FitParametersFile <<
" Resolution fit parameters:" << std::endl;
1565 if( ipar ==
int(
parResol.size()) ) {
1566 FitParametersFile <<
" Scale fit parameters:" << std::endl;
1569 FitParametersFile <<
" Cross section fit parameters:" << std::endl;
1572 FitParametersFile <<
" Background fit parameters:" << std::endl;
1588 FitParametersFile <<
" Results of the fit: parameter " << ipar <<
" has value "
1589 << pval <<
"+-" << parerr[3*ipar]
1590 <<
" + " << parerr[3*ipar+1] <<
" - " << parerr[3*ipar+2]
1597 rmin.mnstat (fmin, fdem, errdef, npari, nparx, istat);
1598 FitParametersFile << std::endl;
1604 if( somethingtodo ) {
1605 std::stringstream iorderString;
1607 std::stringstream iLoopString;
1610 for (
int ipar=0; ipar<parnumber; ipar++) {
1611 if( parfix[ipar] == 1 )
continue;
1612 std::cout <<
"plotting parameter = " << ipar+1 << std::endl;
1613 std::stringstream iparString;
1614 iparString << ipar+1;
1615 std::stringstream iparStringName;
1616 iparStringName << ipar;
1617 rmin.mncomd( (
"scan "+iparString.str()).c_str(), ierror );
1619 TCanvas *
canvas =
new TCanvas((
"likelihoodCanvas_loop_"+iLoopString.str()+
"_oder_"+iorderString.str()+
"_par_"+iparStringName.str()).c_str(), (
"likelihood_"+iparStringName.str()).c_str(), 1000, 800);
1623 TGraph *
graph = (TGraph*)rmin.GetPlot();
1626 graph->SetTitle(parname[ipar]);
1648 FitParametersFile.close();
1650 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters after likelihood " << std::endl;
1651 for (
unsigned int ipar=0; ipar<(
unsigned int)parnumber; ipar++) {
1653 << parfix[ipar] <<
"; order = " << parorder[ipar] << std::endl;
1658 for(
int i=0; i<(int)(
parResol.size()); ++
i ) {
1661 for(
int i=0; i<(int)(
parScale.size()); ++
i ) {
1670 for(
unsigned int i = 0; i<(
parBgr.size() - parForResonanceWindows); ++
i ) {
1680 if(
MuonType > 2 ) localMuonType = 2;
1696 extern "C" void likelihood(
int& npar,
double* grad,
double& fval,
double* xval,
int flag ) {
1766 double Y = (corrMu1+corrMu2).Rapidity();
1767 double resEta = (corrMu1+corrMu2).
Eta();
1769 std::cout <<
"[MuScleFitUtils-likelihood]: Original/Corrected resonance mass = " << mass
1770 <<
" / " << corrMass << std::endl;
1777 std::cout <<
"[MuScleFitUtils-likelihood]: Resolution is " << massResol << std::endl;
1795 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;
1796 std::cout <<
"Original mass was = " << mass << std::endl;
1797 std::cout <<
"WARNING: massResol = " << massResol <<
" outside window" << std::endl;
1802 std::cout <<
"[MuScleFitUtils-likelihood]: Mass probability = " << prob << std::endl;
1825 if( evtsinlik != 0 ) {
1832 double normalizationArg[] = {1/double(evtsinlik)};
1846 fval = -2.*flike/double(evtsinlik);
1857 std::cout <<
"Problem: Events in likelihood = " << evtsinlik << std::endl;
1862 std::cout <<
"[MuScleFitUtils-likelihood]: End tree loop with likelihood value = " << fval << std::endl;
1887 std::cout <<
"Events in likelihood = " << evtsinlik << std::endl;
1888 std::cout <<
"Events out likelihood = " << evtsoutlik << std::endl;
1900 std::vector<TGraphErrors *>
results;
1904 std::vector<double> Ftop;
1905 std::vector<double> Fwidth;
1906 std::vector<double> Fmass;
1907 std::vector<double> Etop;
1908 std::vector<double> Ewidth;
1909 std::vector<double> Emass;
1910 std::vector<double> Fchi2;
1913 std::vector<double> Xcenter;
1914 std::vector<double> Ex;
1919 fitFcn->SetParameters (100, 3, 91);
1920 fitFcn->SetParNames (
"Ftop",
"Fwidth",
"Fmass");
1921 fitFcn->SetLineWidth (2);
1925 double cont_min = 20;
1926 Int_t binx = histo->GetXaxis()->GetNbins();
1929 for (
int i=1;
i<=binx;
i++) {
1930 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
1932 double cont = histoY->GetEntries();
1933 if (cont>cont_min) {
1934 histoY->Fit (
"fitFcn",
"0",
"", 70, 110);
1935 double *par = fitFcn->GetParameters();
1936 double *err = fitFcn->GetParErrors();
1938 Ftop.push_back(par[0]);
1939 Fwidth.push_back(par[1]);
1940 Fmass.push_back(par[2]);
1941 Etop.push_back(err[0]);
1942 Ewidth.push_back(err[1]);
1943 Emass.push_back(err[2]);
1945 double chi2 = fitFcn->GetChisquare();
1946 Fchi2.push_back(chi2);
1948 double xx = histo->GetXaxis()->GetBinCenter(
i);
1949 Xcenter.push_back(xx);
1958 const int nn = Fmass.size();
1959 double *
x =
new double[nn];
1960 double *ym =
new double[nn];
1961 double *
e =
new double[nn];
1962 double *eym =
new double[nn];
1963 double *yw =
new double[nn];
1964 double *eyw =
new double[nn];
1965 double *yc =
new double[nn];
1967 for (
int j=0;
j<nn;
j++) {
1979 TString
name = histo->GetName();
1980 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
1981 grM->SetTitle (name+
"_M");
1982 grM->SetName (name+
"_M");
1983 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
1984 grW->SetTitle (name+
"_W");
1985 grW->SetName (name+
"_W");
1986 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
1987 grC->SetTitle (name+
"_chi2");
1988 grC->SetName (name+
"_chi2");
2001 results.push_back(grM);
2002 results.push_back(grW);
2003 results.push_back(grC);
2010 std::cout <<
"Fitting " << histo->GetName() << std::endl;
2011 std::vector<TGraphErrors *>
results;
2015 std::vector<double> maxs;
2016 std::vector<double> means;
2017 std::vector<double> sigmas;
2018 std::vector<double> chi2s;
2019 std::vector<double> Emaxs;
2020 std::vector<double> Emeans;
2021 std::vector<double> Esigmas;
2025 std::vector<double> Xcenter;
2026 std::vector<double> Ex;
2030 TF1 *fitFcn =
new TF1 (
"fitFunc",
Gaussian, -0.2, 0.2, 3);
2031 fitFcn->SetParameters (100, 0, 0.02);
2032 fitFcn->SetParNames (
"max",
"mean",
"sigma");
2033 fitFcn->SetLineWidth (2);
2037 double cont_min = 20;
2038 Int_t binx = histo->GetXaxis()->GetNbins();
2039 for (
int i=1;
i<=binx;
i++) {
2040 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
2041 double cont = histoY->GetEntries();
2042 if (cont>cont_min) {
2043 histoY->Fit (
"fitFunc",
"0",
"", -0.2, 0.2);
2044 double *par = fitFcn->GetParameters();
2045 double *err = fitFcn->GetParErrors();
2047 maxs.push_back (par[0]);
2048 means.push_back (par[1]);
2049 sigmas.push_back (par[2]);
2050 Emaxs.push_back (err[0]);
2051 Emeans.push_back (err[1]);
2052 Esigmas.push_back (err[2]);
2054 double chi2 = fitFcn->GetChisquare();
2055 chi2s.push_back (chi2);
2057 double xx = histo->GetXaxis()->GetBinCenter(
i);
2058 Xcenter.push_back (xx);
2066 const int nn = means.size();
2067 double *
x =
new double[nn];
2068 double *ym =
new double[nn];
2069 double *
e =
new double[nn];
2070 double *eym =
new double[nn];
2071 double *yw =
new double[nn];
2072 double *eyw =
new double[nn];
2073 double *yc =
new double[nn];
2075 for (
int j=0;
j<nn;
j++) {
2082 eyw[
j] = Esigmas[
j];
2089 TString
name = histo->GetName();
2090 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
2091 grM->SetTitle (name+
"_mean");
2092 grM->SetName (name+
"_mean");
2093 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
2094 grW->SetTitle (name+
"_sigma");
2095 grW->SetName (name+
"_sigma");
2096 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
2097 grC->SetTitle (name+
"_chi2");
2098 grC->SetName (name+
"_chi2");
2111 results.push_back (grM);
2112 results.push_back (grW);
2113 results.push_back (grC);
2129 if (massResol==0.) {
2130 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2132 <<
" : used Lorentz P-value" << std::endl;
2153 double *
x =
new double[
np];
2154 double *
w =
new double[
np];
2156 GL->CalcGaussLegendreSamplingPoints (np, x, w, 0.1
e-15);
2165 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2167 <<
": used epsilon" << std::endl;
2171 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2173 <<
" " << P << std::endl;
2181 std::pair<lorentzVector, lorentzVector> simMuFromRes;
2182 for( edm::SimTrackContainer::const_iterator simTrack=simTracks->begin(); simTrack!=simTracks->end(); ++simTrack ) {
2184 if (fabs((*simTrack).type())==13) {
2186 if ((*simTrack).genpartIndex()>0) {
2187 HepMC::GenParticle* gp = evtMC->GetEvent()->barcode_to_particle ((*simTrack).genpartIndex());
2190 for (HepMC::GenVertex::particle_iterator mother = gp->production_vertex()->particles_begin(HepMC::ancestors);
2191 mother!=gp->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2193 bool fromRes =
false;
2194 unsigned int motherPdgId = (*mother)->pdg_id();
2199 if(gp->pdg_id() == 13)
2200 simMuFromRes.first =
lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
2201 simTrack->momentum().pz(),simTrack->momentum().e());
2203 simMuFromRes.second =
lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
2204 simTrack->momentum().pz(),simTrack->momentum().e());
2212 return simMuFromRes;
2217 const HepMC::GenEvent* Evt = evtMC->
GetEvent();
2218 std::pair<lorentzVector,lorentzVector> muFromRes;
2220 for (HepMC::GenEvent::particle_const_iterator
part=Evt->particles_begin();
2221 part!=Evt->particles_end();
part++) {
2222 if (fabs((*part)->pdg_id())==13 && (*part)->status()==1) {
2223 bool fromRes =
false;
2224 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
2225 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2226 unsigned int motherPdgId = (*mother)->pdg_id();
2231 if( motherPdgId == 13 && (*mother)->status() == 3 ) fromRes =
true;
2240 if((*part)->pdg_id()==13)
2242 muFromRes.first = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2243 (*part)->momentum().pz(),(*part)->momentum().e()));
2245 muFromRes.second = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2246 (*part)->momentum().pz(),(*part)->momentum().e()));
2255 std::pair<lorentzVector,lorentzVector> muFromRes;
2258 if(
debug>0 )
std::cout <<
"Starting loop on " << genParticles->size() <<
" genParticles" << std::endl;
2259 for( reco::GenParticleCollection::const_iterator
part=genParticles->begin();
part!=genParticles->end(); ++
part ) {
2260 if (fabs(
part->pdgId())==13 &&
part->status()==1) {
2261 bool fromRes =
false;
2262 unsigned int motherPdgId =
part->mother()->pdgId();
2264 std::cout <<
"Found a muon with mother: " << motherPdgId << std::endl;
2270 if(
part->pdgId()==13) {
2271 muFromRes.first =
part->p4();
2272 if(
debug>0 )
std::cout <<
"Found a genMuon + : " << muFromRes.first << std::endl;
2277 muFromRes.second =
part->p4();
2278 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)
double sigmaPt(const U &track, const int i=0) const
The second, optional, parameter is the iteration number.
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 double deltaPhiMaxCut_
static unsigned int loopCounter
double sigmaCotgTh(const U &track, const int i=0) const
The second, optional, parameter is the iteration number.
static std::vector< double > parResolMax
static std::pair< lorentzVector, lorentzVector > findSimMuFromRes(const edm::Handle< edm::HepMCProduct > &evtMC, const edm::Handle< edm::SimTrackContainer > &simTracks)
void likelihood(int &npar, double *grad, double &fval, double *xval, int flag)
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]
static bool scaleFitNotDone_
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
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
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 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
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< 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
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 > parScaleMax
double sigmaPhi(const U &track, const int i=0) const
The second, optional, parameter is the iteration number.
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.
static double ResGamma[6]
static double deltaPhiMinCut_
Double_t lorentzianPeak(Double_t *x, Double_t *par)
static bool rapidityBinsForZ_
static bool separateRanges_
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
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
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< double > parResolStep
static std::vector< int > parCrossSectionFix
static resolutionFunctionBase< double * > * resolutionFunction