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))",
271 std::pair<SimTrack, SimTrack> simMuFromBestRes;
272 double maxprob = -0.1;
276 for (std::vector<SimTrack>::const_iterator simMu1=simMuons.begin(); simMu1!=simMuons.end(); simMu1++) {
277 for (std::vector<SimTrack>::const_iterator simMu2=simMu1+1; simMu2!=simMuons.end(); simMu2++) {
278 if (((*simMu1).charge()*(*simMu2).charge())>0) {
283 double mcomb = ((*simMu1).momentum()+(*simMu2).momentum()).
mass();
284 double Y = ((*simMu1).momentum()+(*simMu2).momentum()).Rapidity();
289 simMuFromBestRes.first = (*simMu1);
290 simMuFromBestRes.second = (*simMu2);
300 return simMuFromBestRes;
312 std::pair<lorentzVector, lorentzVector> recMuFromBestRes;
316 double maxprob = -0.1;
317 double minDeltaMass = 999999;
318 std::pair<reco::LeafCandidate,reco::LeafCandidate> bestMassMuons;
319 for (std::vector<reco::LeafCandidate>::const_iterator Muon1=muons.begin(); Muon1!=muons.end(); ++Muon1) {
321 if (
debug>0)
std::cout <<
"muon_1_charge:"<<(*Muon1).charge() << std::endl;
322 for (std::vector<reco::LeafCandidate>::const_iterator Muon2=Muon1+1; Muon2!=muons.end(); ++Muon2) {
325 if (((*Muon1).charge()*(*Muon2).charge())>0) {
332 double pt1 = (*Muon1).p4().Pt();
333 double pt2 = (*Muon2).p4().Pt();
334 double eta1 = (*Muon1).p4().Eta();
335 double eta2 = (*Muon2).p4().Eta();
342 double mcomb = ((*Muon1).p4()+(*Muon2).p4()).
mass();
343 double Y = ((*Muon1).p4()+(*Muon2).p4()).Rapidity();
345 std::cout<<
"muon1 "<<(*Muon1).p4().Px()<<
", "<<(*Muon1).p4().Py()<<
", "<<(*Muon1).p4().Pz()<<
", "<<(*Muon1).p4().E()<<std::endl;
346 std::cout<<
"muon2 "<<(*Muon2).p4().Px()<<
", "<<(*Muon2).p4().Py()<<
", "<<(*Muon2).p4().Pz()<<
", "<<(*Muon2).p4().E()<<std::endl;
348 double massResol = 0.;
359 if( (*Muon1).charge()<0 ) {
360 recMuFromBestRes.first = (*Muon1).p4();
361 recMuFromBestRes.second = (*Muon2).p4();
363 recMuFromBestRes.first = (*Muon2).p4();
364 recMuFromBestRes.second = (*Muon1).p4();
374 if( deltaMass<minDeltaMass ){
375 bestMassMuons = std::make_pair((*Muon1),(*Muon2));
376 minDeltaMass = deltaMass;
386 if(bestMassMuons.first.charge()<0){
387 recMuFromBestRes.first = bestMassMuons.first.p4();
388 recMuFromBestRes.second = bestMassMuons.second.p4();
391 recMuFromBestRes.second = bestMassMuons.first.p4();
392 recMuFromBestRes.first = bestMassMuons.second.p4();
395 return recMuFromBestRes;
402 double pt = muon.Pt();
403 double eta = muon.Eta();
404 double phi = muon.Phi();
416 std::cout <<
"Smearing Pt,eta,phi = " << pt <<
" " << eta <<
" "
418 for (
int i=0;
i<SmearType+3;
i++) {
424 double ptEtaPhiE[4] = {pt,
eta,
phi, E};
432 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
451 const std::vector<double> & parval,
const int chg)
453 double *
p =
new double[(int)(parval.size())];
458 for (std::vector<double>::const_iterator it=parval.begin(); it!=parval.end(); ++it, ++
id) {
471 double* parval,
const int chg)
473 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
480 ptEtaPhiE[0] =
scaleFunction->
scale(ptEtaPhiE[0], ptEtaPhiE[1], ptEtaPhiE[2], chg, &(parval[shift]));
491 double px = ptEtaPhiE[0]*
cos(ptEtaPhiE[2]);
492 double py = ptEtaPhiE[0]*
sin(ptEtaPhiE[2]);
493 double tmp = 2*atan(
exp(-ptEtaPhiE[1]));
494 double pz = ptEtaPhiE[0]*
cos(tmp)/
sin(tmp);
509 return (mu1+mu2).mass();
516 const std::vector<double> & parval )
529 double *
p =
new double[(int)(parval.size())];
530 std::vector<double>::const_iterator it = parval.begin();
532 for ( ; it!=parval.end(); ++it, ++
id) {
563 double pt1 = mu1.Pt();
564 double phi1 = mu1.Phi();
565 double eta1 = mu1.Eta();
566 double theta1 = 2*atan(
exp(-eta1));
567 double pt2 = mu2.Pt();
568 double phi2 = mu2.Phi();
569 double eta2 = mu2.Eta();
570 double theta2 = 2*atan(
exp(-eta2));
573 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
575 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
576 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
577 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
578 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
580 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
581 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
583 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
609 2*dmdpt1*dmdpt2*cov_pt1pt2*sigma_pt1*sigma_pt2);
612 std::cout <<
" Pt1=" << pt1 <<
" phi1=" << phi1 <<
" cotgth1=" <<
cos(theta1)/
sin(theta1) <<
" - Pt2=" << pt2
613 <<
" phi2=" << phi2 <<
" cotgth2=" <<
cos(theta2)/
sin(theta2) << std::endl;
615 << parval[0] <<
" P[1]=" << parval[1] <<
"P[2]=" << parval[2] <<
" P[3]=" << parval[3] << std::endl;
616 std::cout <<
" Dmdpt1= " << dmdpt1 <<
" dmdpt2= " << dmdpt2 <<
" sigma_pt1="
617 << sigma_pt1 <<
" sigma_pt2=" << sigma_pt2 << std::endl;
618 std::cout <<
" Dmdphi1= " << dmdphi1 <<
" dmdphi2= " << dmdphi2 <<
" sigma_phi1="
619 << sigma_phi1 <<
" sigma_phi2=" << sigma_phi2 << std::endl;
620 std::cout <<
" Dmdcotgth1= " << dmdcotgth1 <<
" dmdcotgth2= " << dmdcotgth2
622 << sigma_cotgth1 <<
" sigma_cotgth2=" << sigma_cotgth2 << std::endl;
623 std::cout <<
" Mass resolution (pval) for muons of Pt = " << pt1 <<
" " << pt2
624 <<
" : " << mass <<
" +- " << mass_res << std::endl;
634 LogDebug(
"MuScleFitUtils") <<
"RESOLUTION PROBLEM: ires=" << ires << std::endl;
652 double pt1 = mu1.Pt();
653 double phi1 = mu1.Phi();
654 double eta1 = mu1.Eta();
655 double theta1 = 2*atan(
exp(-eta1));
656 double pt2 = mu2.Pt();
657 double phi2 = mu2.Phi();
658 double eta2 = mu2.Eta();
659 double theta2 = 2*atan(
exp(-eta2));
662 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
664 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
665 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
666 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
667 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
669 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
670 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
672 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
676 double sigma_pt1 = resolFunc.
sigmaPt( mu1 );
677 double sigma_pt2 = resolFunc.
sigmaPt( mu2 );
678 double sigma_phi1 = resolFunc.
sigmaPhi( mu1 );
679 double sigma_phi2 = resolFunc.
sigmaPhi( mu2 );
680 double sigma_cotgth1 = resolFunc.
sigmaCotgTh( mu1 );
681 double sigma_cotgth2 = resolFunc.
sigmaCotgTh( mu2 );
695 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 )
698 CALLGRIND_START_INSTRUMENTATION;
701 double *
p =
new double[(int)(parval.size())];
706 std::vector<double>::const_iterator it = parval.begin();
708 for ( ; it!=parval.end(); ++it, ++
id) {
713 double massProbability =
massProb( mass, resEta, rapidity, massResol, p, doUseBkgrWindow, eta1, eta2 );
717 CALLGRIND_STOP_INSTRUMENTATION;
718 CALLGRIND_DUMP_STATS;
721 return massProbability;
730 const double GLvalue[][1001][1001],
const double GLnorm[][1001],
731 const int iRes,
const int iY )
733 if( iRes == 0 && iY > 23 ) {
734 std::cout <<
"WARNING: rapidity bin selected = " << iY <<
" but there are only histograms for the first 24 bins" << std::endl;
738 bool insideProbMassWindow =
true;
746 if (
debug>1)
std::cout << std::setprecision(9)<<
"mass ResMinMass[iRes] ResHalfWidth[iRes] ResHalfWidth[iRes]"
748 int iMassLeft = (int)(fracMass*(
double)
nbins);
749 int iMassRight = iMassLeft+1;
750 double fracMassStep = (double)
nbins*(fracMass - (
double)iMassLeft/(double)
nbins);
751 if (
debug>1)
std::cout<<
"nbins iMassLeft fracMass "<<nbins<<
" "<<iMassLeft<<
" "<<fracMass<<std::endl;
757 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassLeft="
758 << iMassLeft <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
762 insideProbMassWindow =
false;
764 if (iMassRight>nbins) {
765 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassRight="
766 << iMassRight <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
767 <<
":" <<
ResMass[iRes]+2*
ResHalfWidth[iRes] <<
" - iMassRight set to " << nbins-1 << std::endl;
770 insideProbMassWindow =
false;
773 int iSigmaLeft = (int)(fracSigma*(
double)
nbins);
774 int iSigmaRight = iSigmaLeft+1;
775 double fracSigmaStep = (double)nbins * (fracSigma - (
double)iSigmaLeft/(double)nbins);
789 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaLeft="
790 << iSigmaLeft <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = "
791 <<
ResMaxSigma[iRes] <<
" - iSigmaLeft set to 0" << std::endl;
795 if (iSigmaRight>nbins ) {
797 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaRight="
798 << iSigmaRight <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = "
799 <<
ResMaxSigma[iRes] <<
" - iSigmaRight set to " << nbins-1 << std::endl;
800 iSigmaLeft = nbins-1;
807 if( insideProbMassWindow ) {
809 if (GLnorm[iY][iSigmaLeft]>0)
810 f11 = GLvalue[iY][iMassLeft][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
812 if (GLnorm[iY][iSigmaRight]>0)
813 f12 = GLvalue[iY][iMassLeft][iSigmaRight] / GLnorm[iY][iSigmaRight];
815 if (GLnorm[iY][iSigmaLeft]>0)
816 f21 = GLvalue[iY][iMassRight][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
818 if (GLnorm[iY][iSigmaRight]>0)
819 f22 = GLvalue[iY][iMassRight][iSigmaRight] / GLnorm[iY][iSigmaRight];
820 PS = f11 + (f12-f11)*fracSigmaStep + (f21-f11)*fracMassStep +
821 (f22-f21-f12+f11)*fracMassStep*fracSigmaStep;
822 if (PS>0.1 ||
debug>1)
LogDebug(
"MuScleFitUtils") <<
"iRes = " << iRes <<
" PS=" << PS <<
" f11,f12,f21,f22="
823 << f11 <<
" " << f12 <<
" " << f21 <<
" " << f22 <<
" "
824 <<
" fSS=" << fracSigmaStep <<
" fMS=" << fracMassStep <<
" iSL, iSR="
825 << iSigmaLeft <<
" " << iSigmaRight
826 <<
" GLvalue["<<iY<<
"]["<<iMassLeft<<
"] = " << GLvalue[iY][iMassLeft][iSigmaLeft]
827 <<
" GLnorm["<<iY<<
"]["<<iSigmaLeft<<
"] = " << GLnorm[iY][iSigmaLeft] << std::endl;
838 edm::LogInfo(
"probability") <<
"outside mass probability window. Setting PS["<<iRes<<
"] = 0" << std::endl;
860 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 ) {
951 double PStot[6] = {0.};
954 bool resConsidered[6] = {
false};
976 int iY = (int)(fabs(rapidity)*10.);
977 if( iY > 23 ) iY = 23;
984 if( PS[0] != PS[0] ) {
985 std::cout <<
"ERROR: PS[0] = nan, setting it to 0" << std::endl;
997 Bgrp1 = bgrResult.first;
1001 PB = bgrResult.second;
1002 if( PB != PB ) PB = 0;
1003 PStot[0] = (1-Bgrp1)*PS[0] + Bgrp1*PB;
1007 PStot[0] *= relativeCrossSections[0];
1012 std::cout <<
"Mass = " << mass <<
" outside range with rapidity = " << rapidity << std::endl;
1013 std::cout <<
"with resMass = " <<
backgroundHandler->
resMass( useBackgroundWindow, 0 ) <<
" and left border = " << windowBorders.first <<
" right border = " << windowBorders.second << std::endl;
1026 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1036 Bgrp1 = bgrResult.first;
1037 PB = bgrResult.second;
1039 if( PB != PB ) PB = 0;
1040 PStot[
ires] = (1-Bgrp1)*PS[
ires] + Bgrp1*PB;
1043 PStot[
ires] *= relativeCrossSections[
ires];
1048 for(
int i=0;
i<6; ++
i ) {
1053 double PStotTemp = 0.;
1054 for(
int i=0;
i<6; ++
i ) {
1055 PStotTemp += PS[
i]*relativeCrossSections[
i];
1057 if( PStotTemp != PStotTemp ) {
1058 std::cout <<
"ERROR: PStotTemp = nan!!!!!!!!!" << std::endl;
1060 for(
int i=0;
i<6; ++
i ) {
1061 std::cout <<
"PS[i] = " << PS[
i] << std::endl;
1062 if( PS[
i] != PS[
i] ) {
1063 std::cout <<
"mass = " << mass << std::endl;
1064 std::cout <<
"massResol = " << massResol << std::endl;
1065 for(
int j=0;
j<parnumber; ++
j ) {
1066 std::cout <<
"parval["<<
j<<
"] = " << parval[
j] << std::endl;
1071 if( PStotTemp == PStotTemp ) {
1074 if (
debug>0)
std::cout <<
"mass = " << mass <<
", P = " << P <<
", PStot = " << PStotTemp <<
", PB = " << PB <<
", bgrp1 = " << Bgrp1 << std::endl;
1089 return( (mass > leftBorder) && (mass < rightBorder) );
1105 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"using backgrond window for mass = " << mass << std::endl;
1115 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1117 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"setting weight to = " << weight << std::endl;
1131 ofstream FitParametersFile;
1132 FitParametersFile.open (
"FitParameters.txt", std::ios::app);
1133 FitParametersFile <<
"Fitting with resolution, scale, bgr function # "
1150 int parForResonanceWindows = 0;
1163 std::vector<double> *tmpVec = &(
parvalue.back());
1170 std::cout <<
"scaleFitNotDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1174 std::cout <<
"scaleFitDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1177 tmpVec->insert( tmpVec->end(),
parBgr.begin(),
parBgr.end() );
1179 std::vector<double>::const_iterator it = tmpVec->begin();
1180 for( ; it != tmpVec->end(); ++it, ++
i ) {
1181 std::cout <<
"tmpVec["<<i<<
"] = " << *it << std::endl;
1187 std::vector<int> crossSectionParNumSizeVec( MuScleFitUtils::crossSectionHandler->parNum(), 0 );
1191 parfix.insert( parfix.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1196 parorder.insert( parorder.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1200 std::vector<double> parerr(3*parnumberAll,0.);
1203 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters before likelihood " << std::endl;
1204 for (
unsigned int i=0; i<(
unsigned int)parnumberAll; i++) {
1206 << parorder[
i] << std::endl;
1223 TMinuit rmin (parnumber);
1229 rmin.mninit (5, 6, 7);
1236 rmin.mnexcm (
"SET STR", arglis, 1, ierror);
1240 rmin.mnexcm(
"SET RAN", arglis, 1, ierror);
1244 double * Start =
new double[parnumberAll];
1245 double *
Step =
new double[parnumberAll];
1246 double * Mini =
new double[parnumberAll];
1247 double * Maxi =
new double[parnumberAll];
1248 int * ind =
new int[parnumberAll];
1249 TString * parname =
new TString[parnumberAll];
1252 MuScleFitUtils::resolutionFunctionForVec->
setParameters( Start, Step, Mini, Maxi, ind, parname,
parResol,
parResolOrder,
parResolStep,
parResolMin,
parResolMax,
MuonType );
1259 int resParNum = MuScleFitUtils::resolutionFunctionForVec->
parNum();
1262 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]),
1263 &(Mini[resParNum]), &(Maxi[resParNum]),
1264 &(ind[resParNum]), &(parname[resParNum]),
1269 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]),
1270 &(Mini[resParNum]), &(Maxi[resParNum]),
1271 &(ind[resParNum]), &(parname[resParNum]),
1276 int crossSectionParShift = resParNum + MuScleFitUtils::scaleFunctionForVec->
parNum();
1277 MuScleFitUtils::crossSectionHandler->
setParameters( &(Start[crossSectionParShift]), &(Step[crossSectionParShift]), &(Mini[crossSectionParShift]),
1278 &(Maxi[crossSectionParShift]), &(ind[crossSectionParShift]), &(parname[crossSectionParShift]),
1283 MuScleFitUtils::backgroundHandler->
setParameters( &(Start[bgrParShift]), &(Step[bgrParShift]), &(Mini[bgrParShift]), &(Maxi[bgrParShift]),
1286 for(
int ipar=0; ipar<parnumber; ++ipar ) {
1287 std::cout <<
"parname["<<ipar<<
"] = " << parname[ipar] << std::endl;
1288 std::cout <<
"Start["<<ipar<<
"] = " << Start[ipar] << std::endl;
1289 std::cout <<
"Step["<<ipar<<
"] = " << Step[ipar] << std::endl;
1290 std::cout <<
"Mini["<<ipar<<
"] = " << Mini[ipar] << std::endl;
1291 std::cout <<
"Maxi["<<ipar<<
"] = " << Maxi[ipar] << std::endl;
1294 rmin.mnparm( ipar, parname[ipar], Start[ipar], Step[ipar], Mini[ipar], Maxi[ipar], ierror );
1306 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Starting minimization" << std::endl;
1312 rmin.mnexcm (
"CALL FCN", arglis, 1, ierror);
1317 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: First fix all parameters ...";
1318 for (
int ipar=0; ipar<parnumber; ipar++) {
1319 rmin.FixParameter (ipar);
1324 if (
debug>19)
std::cout <<
" Then release them in order..." << std::endl;
1346 std::cout <<
"number of parameters for scaleFunction = " << scaleParNum << std::endl;
1347 std::cout <<
"number of parameters for resolutionFunction = " << resParNum << std::endl;
1349 std::cout <<
"number of parameters for backgroundFunction = " <<
parBgr.size() << std::endl;
1352 for (
int i=0; i<parnumber; i++) {
1354 if (n_times<ind[i]) {
1357 if ( i<resParNum ) {
1360 else if( i<resParNum+scaleParNum ) {
1367 std::cout <<
"Starting minimization " <<
iorder <<
" of " << n_times << std::endl;
1369 bool somethingtodo =
false;
1376 for(
unsigned int ipar=0; ipar<
parResol.size(); ++ipar ) {
1377 if( parfix[ipar]==0 && ind[ipar]==
iorder ) {
1378 rmin.Release( ipar );
1379 somethingtodo =
true;
1387 if( parfix[ipar]==0 && ind[ipar]==
iorder ) {
1388 rmin.Release( ipar );
1389 somethingtodo =
true;
1400 if( doCrossSection ) somethingtodo =
true;
1411 rmin.Release( ipar );
1412 somethingtodo =
true;
1419 if( somethingtodo ) {
1422 std::stringstream fileNum;
1427 sprintf(name,
"likelihoodInLoop_%d_%d", loopCounter,
iorder);
1428 TH1D * tempLikelihoodInLoop =
new TH1D(name,
"likelihood value in minuit loop", 10000, 0, 10000);
1430 char signalProbName[50];
1431 sprintf(signalProbName,
"signalProb_%d_%d", loopCounter,
iorder);
1432 TH1D * tempSignalProb =
new TH1D(signalProbName,
"signal probability", 10000, 0, 10000);
1434 char backgroundProbName[50];
1435 sprintf(backgroundProbName,
"backgroundProb_%d_%d", loopCounter,
iorder);
1436 TH1D * tempBackgroundProb =
new TH1D(backgroundProbName,
"background probability", 10000, 0, 10000);
1447 double protectionFactor = 0.9;
1464 double windowBorderShift = (windowBorder.second - windowBorder.first)*(1-protectionFactor)/2.;
1465 double windowBorderLeft = windowBorder.first + windowBorderShift;
1466 double windowBorderRight = windowBorder.second - windowBorderShift;
1481 std::cout<<
"MINUIT is starting the minimization for the iteration number "<<loopCounter<<std::endl;
1486 std::cout<<
"maxNumberOfIterations (just set) = "<<rmin.GetMaxIterations()<<std::endl;
1497 rmin.mnexcm(
"SIMPLEX", arglis, 0, ierror );
1500 rmin.mnexcm(
"MIGRAD", arglis, 2, ierror );
1509 delete tempLikelihoodInLoop;
1510 delete tempSignalProb;
1511 delete tempBackgroundProb;
1519 rmin.mnexcm(
"HESSE", arglis, 0, ierror );
1524 rmin.mnexcm(
"MINOS", arglis, 0, ierror );
1529 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;
1534 for (
int ipar=0; ipar<parnumber; ipar++) {
1536 rmin.mnpout (ipar, name, pval, erro, pmin, pmax, ivar);
1539 if (ierror!=0 &&
debug>0) {
1540 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: ierror!=0, bogus pars" << std::endl;
1551 rmin.mnerrs (ipar, errh, errl, errp, cglo);
1557 parerr[3*ipar] = errp;
1559 parerr[3*ipar] = (((errh)>(fabs(errl)))?(errh):(fabs(errl)));
1561 parerr[3*ipar+1] = errl;
1562 parerr[3*ipar+2] = errh;
1565 FitParametersFile <<
" Resolution fit parameters:" << std::endl;
1567 if( ipar ==
int(
parResol.size()) ) {
1568 FitParametersFile <<
" Scale fit parameters:" << std::endl;
1571 FitParametersFile <<
" Cross section fit parameters:" << std::endl;
1574 FitParametersFile <<
" Background fit parameters:" << std::endl;
1590 FitParametersFile <<
" Results of the fit: parameter " << ipar <<
" has value "
1591 << pval <<
"+-" << parerr[3*ipar]
1592 <<
" + " << parerr[3*ipar+1] <<
" - " << parerr[3*ipar+2]
1599 rmin.mnstat (fmin, fdem, errdef, npari, nparx, istat);
1600 FitParametersFile << std::endl;
1606 if( somethingtodo ) {
1607 std::stringstream iorderString;
1609 std::stringstream iLoopString;
1612 for (
int ipar=0; ipar<parnumber; ipar++) {
1613 if( parfix[ipar] == 1 )
continue;
1614 std::cout <<
"plotting parameter = " << ipar+1 << std::endl;
1615 std::stringstream iparString;
1616 iparString << ipar+1;
1617 std::stringstream iparStringName;
1618 iparStringName << ipar;
1619 rmin.mncomd( (
"scan "+iparString.str()).c_str(), ierror );
1621 TCanvas *
canvas =
new TCanvas((
"likelihoodCanvas_loop_"+iLoopString.str()+
"_oder_"+iorderString.str()+
"_par_"+iparStringName.str()).c_str(), (
"likelihood_"+iparStringName.str()).c_str(), 1000, 800);
1625 TGraph *
graph = (TGraph*)rmin.GetPlot();
1628 graph->SetTitle(parname[ipar]);
1650 FitParametersFile.close();
1652 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters after likelihood " << std::endl;
1653 for (
unsigned int ipar=0; ipar<(
unsigned int)parnumber; ipar++) {
1655 << parfix[ipar] <<
"; order = " << parorder[ipar] << std::endl;
1660 for(
int i=0; i<(int)(
parResol.size()); ++
i ) {
1663 for(
int i=0; i<(int)(
parScale.size()); ++
i ) {
1672 for(
unsigned int i = 0; i<(
parBgr.size() - parForResonanceWindows); ++
i ) {
1682 if(
MuonType > 2 ) localMuonType = 2;
1698 extern "C" void likelihood(
int& npar,
double* grad,
double& fval,
double* xval,
int flag ) {
1768 double Y = (corrMu1+corrMu2).Rapidity();
1769 double resEta = (corrMu1+corrMu2).
Eta();
1771 std::cout <<
"[MuScleFitUtils-likelihood]: Original/Corrected resonance mass = " << mass
1772 <<
" / " << corrMass << std::endl;
1779 std::cout <<
"[MuScleFitUtils-likelihood]: Resolution is " << massResol << std::endl;
1786 double prob =
MuScleFitUtils::massProb( corrMass, resEta, Y, massResol, xval,
false, corrMu1.eta(), corrMu2.eta() );
1797 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;
1798 std::cout <<
"Original mass was = " << mass << std::endl;
1799 std::cout <<
"WARNING: massResol = " << massResol <<
" outside window" << std::endl;
1804 std::cout <<
"[MuScleFitUtils-likelihood]: Mass probability = " << prob << std::endl;
1827 if( evtsinlik != 0 ) {
1834 double normalizationArg[] = {1/double(evtsinlik)};
1848 fval = -2.*flike/double(evtsinlik);
1859 std::cout <<
"Problem: Events in likelihood = " << evtsinlik << std::endl;
1864 std::cout <<
"[MuScleFitUtils-likelihood]: End tree loop with likelihood value = " << fval << std::endl;
1889 std::cout <<
"Events in likelihood = " << evtsinlik << std::endl;
1890 std::cout <<
"Events out likelihood = " << evtsoutlik << std::endl;
1902 std::vector<TGraphErrors *>
results;
1906 std::vector<double> Ftop;
1907 std::vector<double> Fwidth;
1908 std::vector<double> Fmass;
1909 std::vector<double> Etop;
1910 std::vector<double> Ewidth;
1911 std::vector<double> Emass;
1912 std::vector<double> Fchi2;
1915 std::vector<double> Xcenter;
1916 std::vector<double> Ex;
1921 fitFcn->SetParameters (100, 3, 91);
1922 fitFcn->SetParNames (
"Ftop",
"Fwidth",
"Fmass");
1923 fitFcn->SetLineWidth (2);
1927 double cont_min = 20;
1928 Int_t binx = histo->GetXaxis()->GetNbins();
1931 for (
int i=1;
i<=binx;
i++) {
1932 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
1934 double cont = histoY->GetEntries();
1935 if (cont>cont_min) {
1936 histoY->Fit (
"fitFcn",
"0",
"", 70, 110);
1937 double *par = fitFcn->GetParameters();
1938 double *err = fitFcn->GetParErrors();
1940 Ftop.push_back(par[0]);
1941 Fwidth.push_back(par[1]);
1942 Fmass.push_back(par[2]);
1943 Etop.push_back(err[0]);
1944 Ewidth.push_back(err[1]);
1945 Emass.push_back(err[2]);
1947 double chi2 = fitFcn->GetChisquare();
1948 Fchi2.push_back(chi2);
1950 double xx = histo->GetXaxis()->GetBinCenter(
i);
1951 Xcenter.push_back(xx);
1960 const int nn = Fmass.size();
1961 double *
x =
new double[nn];
1962 double *ym =
new double[nn];
1963 double *
e =
new double[nn];
1964 double *eym =
new double[nn];
1965 double *yw =
new double[nn];
1966 double *eyw =
new double[nn];
1967 double *yc =
new double[nn];
1969 for (
int j=0;
j<nn;
j++) {
1981 TString
name = histo->GetName();
1982 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
1983 grM->SetTitle (name+
"_M");
1984 grM->SetName (name+
"_M");
1985 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
1986 grW->SetTitle (name+
"_W");
1987 grW->SetName (name+
"_W");
1988 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
1989 grC->SetTitle (name+
"_chi2");
1990 grC->SetName (name+
"_chi2");
2003 results.push_back(grM);
2004 results.push_back(grW);
2005 results.push_back(grC);
2012 std::cout <<
"Fitting " << histo->GetName() << std::endl;
2013 std::vector<TGraphErrors *>
results;
2017 std::vector<double> maxs;
2018 std::vector<double> means;
2019 std::vector<double> sigmas;
2020 std::vector<double> chi2s;
2021 std::vector<double> Emaxs;
2022 std::vector<double> Emeans;
2023 std::vector<double> Esigmas;
2027 std::vector<double> Xcenter;
2028 std::vector<double> Ex;
2032 TF1 *fitFcn =
new TF1 (
"fitFunc",
Gaussian, -0.2, 0.2, 3);
2033 fitFcn->SetParameters (100, 0, 0.02);
2034 fitFcn->SetParNames (
"max",
"mean",
"sigma");
2035 fitFcn->SetLineWidth (2);
2039 double cont_min = 20;
2040 Int_t binx = histo->GetXaxis()->GetNbins();
2041 for (
int i=1;
i<=binx;
i++) {
2042 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
2043 double cont = histoY->GetEntries();
2044 if (cont>cont_min) {
2045 histoY->Fit (
"fitFunc",
"0",
"", -0.2, 0.2);
2046 double *par = fitFcn->GetParameters();
2047 double *err = fitFcn->GetParErrors();
2049 maxs.push_back (par[0]);
2050 means.push_back (par[1]);
2051 sigmas.push_back (par[2]);
2052 Emaxs.push_back (err[0]);
2053 Emeans.push_back (err[1]);
2054 Esigmas.push_back (err[2]);
2056 double chi2 = fitFcn->GetChisquare();
2057 chi2s.push_back (chi2);
2059 double xx = histo->GetXaxis()->GetBinCenter(
i);
2060 Xcenter.push_back (xx);
2068 const int nn = means.size();
2069 double *
x =
new double[nn];
2070 double *ym =
new double[nn];
2071 double *
e =
new double[nn];
2072 double *eym =
new double[nn];
2073 double *yw =
new double[nn];
2074 double *eyw =
new double[nn];
2075 double *yc =
new double[nn];
2077 for (
int j=0;
j<nn;
j++) {
2084 eyw[
j] = Esigmas[
j];
2091 TString
name = histo->GetName();
2092 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
2093 grM->SetTitle (name+
"_mean");
2094 grM->SetName (name+
"_mean");
2095 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
2096 grW->SetTitle (name+
"_sigma");
2097 grW->SetName (name+
"_sigma");
2098 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
2099 grC->SetTitle (name+
"_chi2");
2100 grC->SetName (name+
"_chi2");
2113 results.push_back (grM);
2114 results.push_back (grW);
2115 results.push_back (grC);
2131 if (massResol==0.) {
2132 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2134 <<
" : used Lorentz P-value" << std::endl;
2155 double *
x =
new double[
np];
2156 double *
w =
new double[
np];
2158 GL->CalcGaussLegendreSamplingPoints (np, x, w, 0.1
e-15);
2167 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2169 <<
": used epsilon" << std::endl;
2173 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2175 <<
" " << P << std::endl;
2183 std::pair<lorentzVector, lorentzVector> simMuFromRes;
2184 for( edm::SimTrackContainer::const_iterator simTrack=simTracks->begin(); simTrack!=simTracks->end(); ++simTrack ) {
2186 if (fabs((*simTrack).type())==13) {
2188 if ((*simTrack).genpartIndex()>0) {
2189 HepMC::GenParticle* gp = evtMC->GetEvent()->barcode_to_particle ((*simTrack).genpartIndex());
2192 for (HepMC::GenVertex::particle_iterator mother = gp->production_vertex()->particles_begin(HepMC::ancestors);
2193 mother!=gp->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2195 bool fromRes =
false;
2196 unsigned int motherPdgId = (*mother)->pdg_id();
2201 if(gp->pdg_id() == 13)
2202 simMuFromRes.first =
lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
2203 simTrack->momentum().pz(),simTrack->momentum().e());
2205 simMuFromRes.second =
lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
2206 simTrack->momentum().pz(),simTrack->momentum().e());
2214 return simMuFromRes;
2219 const HepMC::GenEvent* Evt = evtMC->
GetEvent();
2220 std::pair<lorentzVector,lorentzVector> muFromRes;
2222 for (HepMC::GenEvent::particle_const_iterator
part=Evt->particles_begin();
2223 part!=Evt->particles_end();
part++) {
2224 if (fabs((*part)->pdg_id())==13 && (*part)->status()==1) {
2225 bool fromRes =
false;
2226 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
2227 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2228 unsigned int motherPdgId = (*mother)->pdg_id();
2233 if( motherPdgId == 13 && (*mother)->status() == 3 ) fromRes =
true;
2242 if((*part)->pdg_id()==13)
2244 muFromRes.first = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2245 (*part)->momentum().pz(),(*part)->momentum().e()));
2247 muFromRes.second = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2248 (*part)->momentum().pz(),(*part)->momentum().e()));
2257 std::pair<lorentzVector,lorentzVector> muFromRes;
2260 if(
debug>0 )
std::cout <<
"Starting loop on " << genParticles->size() <<
" genParticles" << std::endl;
2261 for( reco::GenParticleCollection::const_iterator
part=genParticles->begin();
part!=genParticles->end(); ++
part ) {
2262 if (fabs(
part->pdgId())==13 &&
part->status()==1) {
2263 bool fromRes =
false;
2264 unsigned int motherPdgId =
part->mother()->pdgId();
2266 std::cout <<
"Found a muon with mother: " << motherPdgId << std::endl;
2272 if(
part->pdgId()==13) {
2273 muFromRes.first =
part->p4();
2274 if(
debug>0 )
std::cout <<
"Found a genMuon + : " << muFromRes.first << std::endl;
2279 muFromRes.second =
part->p4();
2280 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