51 #include "valgrind/callgrind.h" 58 TMath::Max(1.
e-10,(x[0]-par[2])*(x[0]-par[2]) + .25*par[1]*par[1]);
64 return par[0]*
exp(-0.5*((x[0]-par[1])/par[2])*((x[0]-par[1])/par[2]));
83 TF1 *
GL =
new TF1 (
"GL",
84 "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))",
87 TF2 *
GL2=
new TF2 (
"GL2",
88 "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))",
273 std::pair<SimTrack, SimTrack> simMuFromBestRes;
274 double maxprob = -0.1;
278 for (std::vector<SimTrack>::const_iterator simMu1=simMuons.begin(); simMu1!=simMuons.end(); simMu1++) {
279 for (std::vector<SimTrack>::const_iterator simMu2=simMu1+1; simMu2!=simMuons.end(); simMu2++) {
280 if (((*simMu1).charge()*(*simMu2).charge())>0) {
285 double mcomb = ((*simMu1).momentum()+(*simMu2).momentum()).
mass();
286 double Y = ((*simMu1).momentum()+(*simMu2).momentum()).Rapidity();
291 simMuFromBestRes.first = (*simMu1);
292 simMuFromBestRes.second = (*simMu2);
302 return simMuFromBestRes;
314 std::pair<MuScleFitMuon, MuScleFitMuon> recMuFromBestRes;
318 double maxprob = -0.1;
319 double minDeltaMass = 999999;
320 std::pair<MuScleFitMuon, MuScleFitMuon> bestMassMuons;
321 for (std::vector<MuScleFitMuon>::const_iterator Muon1=muons.begin(); Muon1!=muons.end(); ++Muon1) {
323 if (
debug>0)
std::cout <<
"muon_1_charge:"<<(*Muon1).charge() << std::endl;
324 for (std::vector<MuScleFitMuon>::const_iterator Muon2=Muon1+1; Muon2!=muons.end(); ++Muon2) {
327 if ((((*Muon1).charge())*((*Muon2).charge()))>0) {
332 double ch1 = (*Muon1).charge();
333 double ch2 = (*Muon2).charge();
334 double pt1 = (*Muon1).Pt();
335 double pt2 = (*Muon2).Pt();
336 double eta1 = (*Muon1).Eta();
337 double eta2 = (*Muon2).Eta();
349 double mcomb = ((*Muon1).p4()+(*Muon2).p4()).
mass();
350 double Y = ((*Muon1).p4()+(*Muon2).p4()).Rapidity();
352 std::cout<<
"muon1 "<<(*Muon1).p4().Px()<<
", "<<(*Muon1).p4().Py()<<
", "<<(*Muon1).p4().Pz()<<
", "<<(*Muon1).p4().E()<<
", "<<(*Muon1).charge()<<std::endl;
353 std::cout<<
"muon2 "<<(*Muon2).p4().Px()<<
", "<<(*Muon2).p4().Py()<<
", "<<(*Muon2).p4().Pz()<<
", "<<(*Muon2).p4().E()<<
", "<<(*Muon2).charge()<<std::endl;
356 double massResol = 0.;
368 recMuFromBestRes.first = (*Muon1);
369 recMuFromBestRes.second = (*Muon2);
372 recMuFromBestRes.first = (*Muon2);
373 recMuFromBestRes.second = (*Muon1);
375 if (
debug>0)
std::cout <<
"muon_1_charge (after swapping):"<<recMuFromBestRes.first.charge() << std::endl;
384 if (deltaMass<minDeltaMass){
385 bestMassMuons = std::make_pair((*Muon1), (*Muon2));
386 minDeltaMass = deltaMass;
396 if (bestMassMuons.first.charge()<0){
397 recMuFromBestRes.first = bestMassMuons.first;
398 recMuFromBestRes.second = bestMassMuons.second;
401 recMuFromBestRes.second = bestMassMuons.first;
402 recMuFromBestRes.first = bestMassMuons.second;
405 return recMuFromBestRes;
412 double pt = muon.Pt();
413 double eta = muon.Eta();
414 double phi = muon.Phi();
426 std::cout <<
"Smearing Pt,eta,phi = " << pt <<
" " << eta <<
" " 428 for (
int i=0;
i<SmearType+3;
i++) {
434 double ptEtaPhiE[4] = {
pt,
eta,
phi, E};
442 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
461 const std::vector<double> & parval,
const int chg)
463 double *
p =
new double[(
int)(parval.size())];
468 for (std::vector<double>::const_iterator it=parval.begin(); it!=parval.end(); ++it, ++
id) {
481 double* parval,
const int chg)
483 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
490 ptEtaPhiE[0] =
scaleFunction->
scale(ptEtaPhiE[0], ptEtaPhiE[1], ptEtaPhiE[2], chg, &(parval[shift]));
501 double px = ptEtaPhiE[0]*
cos(ptEtaPhiE[2]);
502 double py = ptEtaPhiE[0]*
sin(ptEtaPhiE[2]);
503 double tmp = 2*atan(
exp(-ptEtaPhiE[1]));
504 double pz = ptEtaPhiE[0]*
cos(tmp)/
sin(tmp);
519 return (mu1+mu2).mass();
526 const std::vector<double> & parval )
539 double *
p =
new double[(
int)(parval.size())];
540 std::vector<double>::const_iterator it = parval.begin();
542 for ( ; it!=parval.end(); ++it, ++
id) {
573 double pt1 = mu1.Pt();
574 double phi1 = mu1.Phi();
575 double eta1 = mu1.Eta();
576 double theta1 = 2*atan(
exp(-eta1));
577 double pt2 = mu2.Pt();
578 double phi2 = mu2.Phi();
579 double eta2 = mu2.Eta();
580 double theta2 = 2*atan(
exp(-eta2));
583 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
585 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
586 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
587 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
588 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
590 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
591 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
593 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
619 2*dmdpt1*dmdpt2*cov_pt1pt2*sigma_pt1*sigma_pt2);
622 std::cout <<
" Pt1=" << pt1 <<
" phi1=" << phi1 <<
" cotgth1=" <<
cos(theta1)/
sin(theta1) <<
" - Pt2=" << pt2
623 <<
" phi2=" << phi2 <<
" cotgth2=" <<
cos(theta2)/
sin(theta2) << std::endl;
625 << parval[0] <<
" P[1]=" << parval[1] <<
"P[2]=" << parval[2] <<
" P[3]=" << parval[3] << std::endl;
626 std::cout <<
" Dmdpt1= " << dmdpt1 <<
" dmdpt2= " << dmdpt2 <<
" sigma_pt1=" 627 << sigma_pt1 <<
" sigma_pt2=" << sigma_pt2 << std::endl;
628 std::cout <<
" Dmdphi1= " << dmdphi1 <<
" dmdphi2= " << dmdphi2 <<
" sigma_phi1=" 629 << sigma_phi1 <<
" sigma_phi2=" << sigma_phi2 << std::endl;
630 std::cout <<
" Dmdcotgth1= " << dmdcotgth1 <<
" dmdcotgth2= " << dmdcotgth2
632 << sigma_cotgth1 <<
" sigma_cotgth2=" << sigma_cotgth2 << std::endl;
633 std::cout <<
" Mass resolution (pval) for muons of Pt = " << pt1 <<
" " << pt2
634 <<
" : " << mass <<
" +- " << mass_res << std::endl;
644 LogDebug(
"MuScleFitUtils") <<
"RESOLUTION PROBLEM: ires=" << ires << std::endl;
662 double pt1 = mu1.Pt();
663 double phi1 = mu1.Phi();
664 double eta1 = mu1.Eta();
665 double theta1 = 2*atan(
exp(-eta1));
666 double pt2 = mu2.Pt();
667 double phi2 = mu2.Phi();
668 double eta2 = mu2.Eta();
669 double theta2 = 2*atan(
exp(-eta2));
672 pt2*(
cos(phi1-phi2)+
cos(theta1)*
cos(theta2)/(
sin(theta1)*
sin(theta2))))/mass;
674 pt1*(
cos(phi2-phi1)+
cos(theta2)*
cos(theta1)/(
sin(theta2)*
sin(theta1))))/mass;
675 double dmdphi1 = pt1*pt2/mass*
sin(phi1-phi2);
676 double dmdphi2 = pt2*pt1/mass*
sin(phi2-phi1);
677 double dmdcotgth1 = (pt1*pt1*
cos(theta1)/
sin(theta1)*
679 pt1*pt2*
cos(theta2)/
sin(theta2))/mass;
680 double dmdcotgth2 = (pt2*pt2*
cos(theta2)/
sin(theta2)*
682 pt2*pt1*
cos(theta1)/
sin(theta1))/mass;
686 double sigma_pt1 = resolFunc.
sigmaPt( mu1 );
687 double sigma_pt2 = resolFunc.
sigmaPt( mu2 );
688 double sigma_phi1 = resolFunc.
sigmaPhi( mu1 );
689 double sigma_phi2 = resolFunc.
sigmaPhi( mu2 );
690 double sigma_cotgth1 = resolFunc.
sigmaCotgTh( mu1 );
691 double sigma_cotgth2 = resolFunc.
sigmaCotgTh( mu2 );
705 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 )
708 CALLGRIND_START_INSTRUMENTATION;
711 double *
p =
new double[(
int)(parval.size())];
716 std::vector<double>::const_iterator it = parval.begin();
718 for ( ; it!=parval.end(); ++it, ++
id) {
723 double massProbability =
massProb( mass, resEta, rapidity, massResol, p, doUseBkgrWindow, eta1, eta2 );
727 CALLGRIND_STOP_INSTRUMENTATION;
728 CALLGRIND_DUMP_STATS;
731 return massProbability;
740 const double GLvalue[][1001][1001],
const double GLnorm[][1001],
741 const int iRes,
const int iY )
743 if( iRes == 0 && iY > 23 ) {
744 std::cout <<
"WARNING: rapidity bin selected = " << iY <<
" but there are only histograms for the first 24 bins" << std::endl;
748 bool insideProbMassWindow =
true;
756 if (
debug>1)
std::cout << std::setprecision(9)<<
"mass ResMinMass[iRes] ResHalfWidth[iRes] ResHalfWidth[iRes]" 758 int iMassLeft = (
int)(fracMass*(
double)
nbins);
759 int iMassRight = iMassLeft+1;
760 double fracMassStep = (double)
nbins*(fracMass - (
double)iMassLeft/(double)
nbins);
761 if (
debug>1)
std::cout<<
"nbins iMassLeft fracMass "<<nbins<<
" "<<iMassLeft<<
" "<<fracMass<<std::endl;
767 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassLeft=" 768 << iMassLeft <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
772 insideProbMassWindow =
false;
774 if (iMassRight>nbins) {
775 edm::LogInfo(
"probability") <<
"WARNING: fracMass=" << fracMass <<
", iMassRight=" 776 << iMassRight <<
"; mass = " << mass <<
" and bounds are " <<
ResMinMass[iRes]
777 <<
":" <<
ResMass[iRes]+2*
ResHalfWidth[iRes] <<
" - iMassRight set to " << nbins-1 << std::endl;
780 insideProbMassWindow =
false;
783 int iSigmaLeft = (
int)(fracSigma*(
double)
nbins);
784 int iSigmaRight = iSigmaLeft+1;
785 double fracSigmaStep = (double)nbins * (fracSigma - (
double)iSigmaLeft/(double)nbins);
799 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaLeft=" 800 << iSigmaLeft <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = " 801 <<
ResMaxSigma[iRes] <<
" - iSigmaLeft set to 0" << std::endl;
805 if (iSigmaRight>nbins ) {
807 edm::LogInfo(
"probability") <<
"WARNING: fracSigma = " << fracSigma <<
", iSigmaRight=" 808 << iSigmaRight <<
", with massResol = " << massResol <<
" and ResMaxSigma[iRes] = " 809 <<
ResMaxSigma[iRes] <<
" - iSigmaRight set to " << nbins-1 << std::endl;
810 iSigmaLeft = nbins-1;
817 if( insideProbMassWindow ) {
819 if (GLnorm[iY][iSigmaLeft]>0)
820 f11 = GLvalue[iY][iMassLeft][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
822 if (GLnorm[iY][iSigmaRight]>0)
823 f12 = GLvalue[iY][iMassLeft][iSigmaRight] / GLnorm[iY][iSigmaRight];
825 if (GLnorm[iY][iSigmaLeft]>0)
826 f21 = GLvalue[iY][iMassRight][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
828 if (GLnorm[iY][iSigmaRight]>0)
829 f22 = GLvalue[iY][iMassRight][iSigmaRight] / GLnorm[iY][iSigmaRight];
830 PS = f11 + (f12-f11)*fracSigmaStep + (f21-f11)*fracMassStep +
831 (f22-f21-f12+f11)*fracMassStep*fracSigmaStep;
832 if (PS>0.1 ||
debug>1)
LogDebug(
"MuScleFitUtils") <<
"iRes = " << iRes <<
" PS=" << PS <<
" f11,f12,f21,f22=" 833 << f11 <<
" " << f12 <<
" " << f21 <<
" " << f22 <<
" " 834 <<
" fSS=" << fracSigmaStep <<
" fMS=" << fracMassStep <<
" iSL, iSR=" 835 << iSigmaLeft <<
" " << iSigmaRight
836 <<
" GLvalue["<<iY<<
"]["<<iMassLeft<<
"] = " << GLvalue[iY][iMassLeft][iSigmaLeft]
837 <<
" GLnorm["<<iY<<
"]["<<iSigmaLeft<<
"] = " << GLnorm[iY][iSigmaLeft] << std::endl;
848 edm::LogInfo(
"probability") <<
"outside mass probability window. Setting PS["<<iRes<<
"] = 0" << std::endl;
870 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 ) {
961 double PStot[6] = {0.};
964 bool resConsidered[6] = {
false};
987 if( iY > 23 ) iY = 23;
994 if( PS[0] != PS[0] ) {
995 std::cout <<
"ERROR: PS[0] = nan, setting it to 0" << std::endl;
1007 Bgrp1 = bgrResult.first;
1011 PB = bgrResult.second;
1012 if( PB != PB ) PB = 0;
1013 PStot[0] = (1-Bgrp1)*PS[0] + Bgrp1*PB;
1018 PStot[0] *= relativeCrossSections[0];
1019 if (
MuScleFitUtils::debug > 0 )
std::cout <<
"PStot["<<0<<
"] = " <<
"(1-"<<Bgrp1<<
")*"<<PS[0]<<
" + "<<Bgrp1<<
"*"<<PB<<
" = " << PStot[0] <<
" (reletiveXS = )" << relativeCrossSections[0] << std::endl;
1023 std::cout <<
"Mass = " << mass <<
" outside range with rapidity = " << rapidity << std::endl;
1024 std::cout <<
"with resMass = " <<
backgroundHandler->
resMass( useBackgroundWindow, 0 ) <<
" and left border = " << windowBorders.first <<
" right border = " << windowBorders.second << std::endl;
1037 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1047 Bgrp1 = bgrResult.first;
1048 PB = bgrResult.second;
1050 if( PB != PB ) PB = 0;
1051 PStot[
ires] = (1-Bgrp1)*PS[
ires] + Bgrp1*PB;
1054 PStot[
ires] *= relativeCrossSections[
ires];
1059 for(
int i=0;
i<6; ++
i ) {
1064 double PStotTemp = 0.;
1065 for(
int i=0;
i<6; ++
i ) {
1066 PStotTemp += PS[
i]*relativeCrossSections[
i];
1068 if( PStotTemp != PStotTemp ) {
1069 std::cout <<
"ERROR: PStotTemp = nan!!!!!!!!!" << std::endl;
1071 for(
int i=0;
i<6; ++
i ) {
1072 std::cout <<
"PS[i] = " << PS[
i] << std::endl;
1073 if( PS[
i] != PS[
i] ) {
1074 std::cout <<
"mass = " << mass << std::endl;
1075 std::cout <<
"massResol = " << massResol << std::endl;
1076 for(
int j=0; j<parnumber; ++j ) {
1077 std::cout <<
"parval["<<j<<
"] = " << parval[j] << std::endl;
1082 if( PStotTemp == PStotTemp ) {
1085 if (
debug>0)
std::cout <<
"mass = " << mass <<
", P = " << P <<
", PStot = " << PStotTemp <<
", PB = " << PB <<
", bgrp1 = " << Bgrp1 << std::endl;
1100 return( (mass > leftBorder) && (mass < rightBorder) );
1116 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"using backgrond window for mass = " << mass << std::endl;
1126 if(
checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
1128 if( doUseBkgrWindow && (
debug > 0) )
std::cout <<
"setting weight to = " << weight << std::endl;
1142 std::ofstream FitParametersFile;
1143 FitParametersFile.open (
"FitParameters.txt", std::ios::app);
1144 FitParametersFile <<
"Fitting with resolution, scale, bgr function # " 1161 int parForResonanceWindows = 0;
1174 std::vector<double> *tmpVec = &(
parvalue.back());
1181 std::cout <<
"scaleFitNotDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1185 std::cout <<
"scaleFitDone: tmpVec->size() = " << tmpVec->size() << std::endl;
1188 tmpVec->insert( tmpVec->end(),
parBgr.begin(),
parBgr.end() );
1190 std::vector<double>::const_iterator it = tmpVec->begin();
1191 for( ; it != tmpVec->end(); ++it, ++
i ) {
1192 std::cout <<
"tmpVec["<<i<<
"] = " << *it << std::endl;
1198 std::vector<int> crossSectionParNumSizeVec( MuScleFitUtils::crossSectionHandler->parNum(), 0 );
1202 parfix.insert( parfix.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1207 parorder.insert( parorder.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
1211 std::vector<double> parerr(3*parnumberAll,0.);
1214 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters before likelihood " << std::endl;
1215 for (
unsigned int i=0; i<(
unsigned int)parnumberAll; i++) {
1217 << parorder[
i] << std::endl;
1234 TMinuit rmin (parnumber);
1240 rmin.mninit (5, 6, 7);
1247 rmin.mnexcm (
"SET STR", arglis, 1, ierror);
1251 rmin.mnexcm(
"SET RAN", arglis, 1, ierror);
1255 double * Start =
new double[parnumberAll];
1256 double *
Step =
new double[parnumberAll];
1257 double * Mini =
new double[parnumberAll];
1258 double * Maxi =
new double[parnumberAll];
1259 int * ind =
new int[parnumberAll];
1260 TString * parname =
new TString[parnumberAll];
1263 MuScleFitUtils::resolutionFunctionForVec->
setParameters( Start, Step, Mini, Maxi, ind, parname,
parResol,
parResolOrder,
parResolStep,
parResolMin,
parResolMax,
MuonType );
1270 int resParNum = MuScleFitUtils::resolutionFunctionForVec->
parNum();
1273 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]),
1274 &(Mini[resParNum]), &(Maxi[resParNum]),
1275 &(ind[resParNum]), &(parname[resParNum]),
1280 MuScleFitUtils::scaleFunctionForVec->
setParameters( &(Start[resParNum]), &(Step[resParNum]),
1281 &(Mini[resParNum]), &(Maxi[resParNum]),
1282 &(ind[resParNum]), &(parname[resParNum]),
1287 int crossSectionParShift = resParNum + MuScleFitUtils::scaleFunctionForVec->
parNum();
1288 MuScleFitUtils::crossSectionHandler->
setParameters( &(Start[crossSectionParShift]), &(Step[crossSectionParShift]), &(Mini[crossSectionParShift]),
1289 &(Maxi[crossSectionParShift]), &(ind[crossSectionParShift]), &(parname[crossSectionParShift]),
1294 MuScleFitUtils::backgroundHandler->
setParameters( &(Start[bgrParShift]), &(Step[bgrParShift]), &(Mini[bgrParShift]), &(Maxi[bgrParShift]),
1297 for(
int ipar=0; ipar<parnumber; ++ipar ) {
1298 std::cout <<
"parname["<<ipar<<
"] = " << parname[ipar] << std::endl;
1299 std::cout <<
"Start["<<ipar<<
"] = " << Start[ipar] << std::endl;
1300 std::cout <<
"Step["<<ipar<<
"] = " << Step[ipar] << std::endl;
1301 std::cout <<
"Mini["<<ipar<<
"] = " << Mini[ipar] << std::endl;
1302 std::cout <<
"Maxi["<<ipar<<
"] = " << Maxi[ipar] << std::endl;
1305 rmin.mnparm( ipar, parname[ipar], Start[ipar], Step[ipar], Mini[ipar], Maxi[ipar], ierror );
1317 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Starting minimization" << std::endl;
1323 rmin.mnexcm (
"CALL FCN", arglis, 1, ierror);
1328 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: First fix all parameters ...";
1329 for (
int ipar=0; ipar<parnumber; ipar++) {
1330 rmin.FixParameter (ipar);
1335 if (
debug>19)
std::cout <<
" Then release them in order..." << std::endl;
1357 std::cout <<
"number of parameters for scaleFunction = " << scaleParNum << std::endl;
1358 std::cout <<
"number of parameters for resolutionFunction = " << resParNum << std::endl;
1360 std::cout <<
"number of parameters for backgroundFunction = " <<
parBgr.size() << std::endl;
1363 for (
int i=0; i<parnumber; i++) {
1365 if (n_times<ind[i]) {
1368 if ( i<resParNum ) {
1371 else if( i<resParNum+scaleParNum ) {
1378 std::cout <<
"Starting minimization " <<
iorder <<
" of " << n_times << std::endl;
1380 bool somethingtodo =
false;
1387 for(
unsigned int ipar=0; ipar<
parResol.size(); ++ipar ) {
1388 if( parfix[ipar]==0 && ind[ipar]==
iorder ) {
1389 rmin.Release( ipar );
1390 somethingtodo =
true;
1398 if( parfix[ipar]==0 && ind[ipar]==
iorder ) {
1399 rmin.Release( ipar );
1400 somethingtodo =
true;
1411 if( doCrossSection ) somethingtodo =
true;
1422 rmin.Release( ipar );
1423 somethingtodo =
true;
1430 if( somethingtodo ) {
1433 std::stringstream fileNum;
1438 sprintf(name,
"likelihoodInLoop_%d_%d", loopCounter,
iorder);
1439 TH1D * tempLikelihoodInLoop =
new TH1D(name,
"likelihood value in minuit loop", 10000, 0, 10000);
1441 char signalProbName[50];
1442 sprintf(signalProbName,
"signalProb_%d_%d", loopCounter,
iorder);
1443 TH1D * tempSignalProb =
new TH1D(signalProbName,
"signal probability", 10000, 0, 10000);
1445 char backgroundProbName[50];
1446 sprintf(backgroundProbName,
"backgroundProb_%d_%d", loopCounter,
iorder);
1447 TH1D * tempBackgroundProb =
new TH1D(backgroundProbName,
"background probability", 10000, 0, 10000);
1458 double protectionFactor = 0.9;
1475 double windowBorderShift = (windowBorder.second - windowBorder.first)*(1-protectionFactor)/2.;
1476 double windowBorderLeft = windowBorder.first + windowBorderShift;
1477 double windowBorderRight = windowBorder.second - windowBorderShift;
1492 std::cout<<
"MINUIT is starting the minimization for the iteration number "<<loopCounter<<std::endl;
1497 std::cout<<
"maxNumberOfIterations (just set) = "<<rmin.GetMaxIterations()<<std::endl;
1508 rmin.mnexcm(
"SIMPLEX", arglis, 0, ierror );
1511 rmin.mnexcm(
"MIGRAD", arglis, 2, ierror );
1520 delete tempLikelihoodInLoop;
1521 delete tempSignalProb;
1522 delete tempBackgroundProb;
1530 rmin.mnexcm(
"HESSE", arglis, 0, ierror );
1535 rmin.mnexcm(
"MINOS", arglis, 0, ierror );
1540 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;
1545 for (
int ipar=0; ipar<parnumber; ipar++) {
1547 rmin.mnpout (ipar, name, pval, erro, pmin, pmax, ivar);
1550 if (ierror!=0 &&
debug>0) {
1551 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: ierror!=0, bogus pars" << std::endl;
1562 rmin.mnerrs (ipar, errh, errl, errp, cglo);
1568 parerr[3*ipar] = errp;
1572 parerr[3*ipar+1] = errl;
1573 parerr[3*ipar+2] = errh;
1576 FitParametersFile <<
" Resolution fit parameters:" << std::endl;
1578 if( ipar ==
int(
parResol.size()) ) {
1579 FitParametersFile <<
" Scale fit parameters:" << std::endl;
1582 FitParametersFile <<
" Cross section fit parameters:" << std::endl;
1585 FitParametersFile <<
" Background fit parameters:" << std::endl;
1601 FitParametersFile <<
" Results of the fit: parameter " << ipar <<
" has value " 1602 << pval <<
"+-" << parerr[3*ipar]
1603 <<
" + " << parerr[3*ipar+1] <<
" - " << parerr[3*ipar+2]
1610 rmin.mnstat (fmin, fdem, errdef, npari, nparx, istat);
1611 FitParametersFile << std::endl;
1617 if( somethingtodo ) {
1618 std::stringstream iorderString;
1620 std::stringstream iLoopString;
1623 for (
int ipar=0; ipar<parnumber; ipar++) {
1624 if( parfix[ipar] == 1 )
continue;
1625 std::cout <<
"plotting parameter = " << ipar+1 << std::endl;
1626 std::stringstream iparString;
1627 iparString << ipar+1;
1628 std::stringstream iparStringName;
1629 iparStringName << ipar;
1630 rmin.mncomd( (
"scan "+iparString.str()).c_str(), ierror );
1632 TCanvas *
canvas =
new TCanvas((
"likelihoodCanvas_loop_"+iLoopString.str()+
"_oder_"+iorderString.str()+
"_par_"+iparStringName.str()).c_str(), (
"likelihood_"+iparStringName.str()).c_str(), 1000, 800);
1636 TGraph * graph = (TGraph*)rmin.GetPlot();
1639 graph->SetTitle(parname[ipar]);
1661 FitParametersFile.close();
1663 std::cout <<
"[MuScleFitUtils-minimizeLikelihood]: Parameters after likelihood " << std::endl;
1664 for (
unsigned int ipar=0; ipar<(
unsigned int)parnumber; ipar++) {
1666 << parfix[ipar] <<
"; order = " << parorder[ipar] << std::endl;
1683 for(
unsigned int i = 0; i<(
parBgr.size() - parForResonanceWindows); ++
i ) {
1693 if(
MuonType > 2 ) localMuonType = 2;
1709 extern "C" void likelihood(
int& npar,
double* grad,
double& fval,
double* xval,
int flag ) {
1779 double Y = (corrMu1+corrMu2).Rapidity();
1780 double resEta = (corrMu1+corrMu2).
Eta();
1782 std::cout <<
"[MuScleFitUtils-likelihood]: Original/Corrected resonance mass = " << mass
1783 <<
" / " << corrMass << std::endl;
1790 std::cout <<
"[MuScleFitUtils-likelihood]: Resolution is " << massResol << std::endl;
1808 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;
1809 std::cout <<
"Original mass was = " << mass << std::endl;
1810 std::cout <<
"WARNING: massResol = " << massResol <<
" outside window" << std::endl;
1815 std::cout <<
"[MuScleFitUtils-likelihood]: Mass probability = " << prob << std::endl;
1838 if( evtsinlik != 0 ) {
1845 double normalizationArg[] = {1/double(evtsinlik)};
1859 fval = -2.*flike/double(evtsinlik);
1870 std::cout <<
"Problem: Events in likelihood = " << evtsinlik << std::endl;
1875 std::cout <<
"[MuScleFitUtils-likelihood]: End tree loop with likelihood value = " << fval << std::endl;
1900 std::cout <<
"Events in likelihood = " << evtsinlik << std::endl;
1901 std::cout <<
"Events out likelihood = " << evtsoutlik << std::endl;
1913 std::vector<TGraphErrors *>
results;
1917 std::vector<double> Ftop;
1918 std::vector<double> Fwidth;
1919 std::vector<double> Fmass;
1920 std::vector<double> Etop;
1921 std::vector<double> Ewidth;
1922 std::vector<double> Emass;
1923 std::vector<double> Fchi2;
1926 std::vector<double> Xcenter;
1927 std::vector<double> Ex;
1932 fitFcn->SetParameters (100, 3, 91);
1933 fitFcn->SetParNames (
"Ftop",
"Fwidth",
"Fmass");
1934 fitFcn->SetLineWidth (2);
1938 double cont_min = 20;
1939 Int_t binx = histo->GetXaxis()->GetNbins();
1942 for (
int i=1;
i<=binx;
i++) {
1943 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
1945 double cont = histoY->GetEntries();
1946 if (cont>cont_min) {
1947 histoY->Fit (
"fitFcn",
"0",
"", 70, 110);
1948 double *par = fitFcn->GetParameters();
1949 const double *err = fitFcn->GetParErrors();
1951 Ftop.push_back(par[0]);
1952 Fwidth.push_back(par[1]);
1953 Fmass.push_back(par[2]);
1954 Etop.push_back(err[0]);
1955 Ewidth.push_back(err[1]);
1956 Emass.push_back(err[2]);
1958 double chi2 = fitFcn->GetChisquare();
1959 Fchi2.push_back(chi2);
1961 double xx = histo->GetXaxis()->GetBinCenter(
i);
1962 Xcenter.push_back(xx);
1971 const int nn = Fmass.size();
1972 double *
x =
new double[
nn];
1973 double *ym =
new double[
nn];
1974 double *
e =
new double[
nn];
1975 double *eym =
new double[
nn];
1976 double *yw =
new double[
nn];
1977 double *eyw =
new double[
nn];
1978 double *yc =
new double[
nn];
1980 for (
int j=0; j<
nn; j++) {
1992 TString
name = histo->GetName();
1993 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
1994 grM->SetTitle (name+
"_M");
1995 grM->SetName (name+
"_M");
1996 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
1997 grW->SetTitle (name+
"_W");
1998 grW->SetName (name+
"_W");
1999 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
2000 grC->SetTitle (name+
"_chi2");
2001 grC->SetName (name+
"_chi2");
2014 results.push_back(grM);
2015 results.push_back(grW);
2016 results.push_back(grC);
2023 std::cout <<
"Fitting " << histo->GetName() << std::endl;
2024 std::vector<TGraphErrors *>
results;
2028 std::vector<double> maxs;
2029 std::vector<double> means;
2030 std::vector<double> sigmas;
2031 std::vector<double> chi2s;
2032 std::vector<double> Emaxs;
2033 std::vector<double> Emeans;
2034 std::vector<double> Esigmas;
2038 std::vector<double> Xcenter;
2039 std::vector<double> Ex;
2043 TF1 *fitFcn =
new TF1 (
"fitFunc",
Gaussian, -0.2, 0.2, 3);
2044 fitFcn->SetParameters (100, 0, 0.02);
2045 fitFcn->SetParNames (
"max",
"mean",
"sigma");
2046 fitFcn->SetLineWidth (2);
2050 double cont_min = 20;
2051 Int_t binx = histo->GetXaxis()->GetNbins();
2052 for (
int i=1;
i<=binx;
i++) {
2053 TH1 * histoY = histo->ProjectionY (
"",
i,
i);
2054 double cont = histoY->GetEntries();
2055 if (cont>cont_min) {
2056 histoY->Fit (
"fitFunc",
"0",
"", -0.2, 0.2);
2057 double *par = fitFcn->GetParameters();
2058 const double *err = fitFcn->GetParErrors();
2060 maxs.push_back (par[0]);
2061 means.push_back (par[1]);
2062 sigmas.push_back (par[2]);
2063 Emaxs.push_back (err[0]);
2064 Emeans.push_back (err[1]);
2065 Esigmas.push_back (err[2]);
2067 double chi2 = fitFcn->GetChisquare();
2068 chi2s.push_back (chi2);
2070 double xx = histo->GetXaxis()->GetBinCenter(
i);
2071 Xcenter.push_back (xx);
2079 const int nn = means.size();
2080 double *
x =
new double[
nn];
2081 double *ym =
new double[
nn];
2082 double *
e =
new double[
nn];
2083 double *eym =
new double[
nn];
2084 double *yw =
new double[
nn];
2085 double *eyw =
new double[
nn];
2086 double *yc =
new double[
nn];
2088 for (
int j=0; j<
nn; j++) {
2095 eyw[j] = Esigmas[j];
2102 TString
name = histo->GetName();
2103 TGraphErrors *grM =
new TGraphErrors (nn, x, ym, e, eym);
2104 grM->SetTitle (name+
"_mean");
2105 grM->SetName (name+
"_mean");
2106 TGraphErrors *grW =
new TGraphErrors (nn, x, yw, e, eyw);
2107 grW->SetTitle (name+
"_sigma");
2108 grW->SetName (name+
"_sigma");
2109 TGraphErrors *grC =
new TGraphErrors (nn, x, yc, e, e);
2110 grC->SetTitle (name+
"_chi2");
2111 grC->SetName (name+
"_chi2");
2124 results.push_back (grM);
2125 results.push_back (grW);
2126 results.push_back (grC);
2142 if (massResol==0.) {
2143 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2145 <<
" : used Lorentz P-value" << std::endl;
2166 double *
x =
new double[
np];
2167 double *
w =
new double[
np];
2169 GL->CalcGaussLegendreSamplingPoints (np, x, w, 0.1
e-15);
2178 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2180 <<
": used epsilon" << std::endl;
2184 if (
debug>9)
std::cout <<
"Mass, gamma , mref, width, P: " << mass
2186 <<
" " << P << std::endl;
2194 std::pair<lorentzVector, lorentzVector> simMuFromRes;
2195 for( edm::SimTrackContainer::const_iterator
simTrack=simTracks->begin();
simTrack!=simTracks->end(); ++
simTrack ) {
2197 if (
std::abs((*simTrack).type())==13) {
2199 if ((*simTrack).genpartIndex()>0) {
2201 if( gp !=
nullptr ) {
2203 for (HepMC::GenVertex::particle_iterator mother = gp->production_vertex()->particles_begin(HepMC::ancestors);
2204 mother!=gp->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2206 bool fromRes =
false;
2207 unsigned int motherPdgId = (*mother)->pdg_id();
2212 if(gp->pdg_id() == 13)
2225 return simMuFromRes;
2231 std::pair<lorentzVector,lorentzVector> muFromRes;
2233 for (HepMC::GenEvent::particle_const_iterator
part=Evt->particles_begin();
2234 part!=Evt->particles_end();
part++) {
2235 if (
std::abs((*part)->pdg_id())==13 && (*part)->status()==1) {
2236 bool fromRes =
false;
2237 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
2238 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
2239 unsigned int motherPdgId = (*mother)->pdg_id();
2244 if( motherPdgId == 13 && (*mother)->status() == 3 ) fromRes =
true;
2253 if((*part)->pdg_id()==13)
2255 muFromRes.first = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2256 (*part)->momentum().pz(),(*part)->momentum().e()));
2258 muFromRes.second = (
lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
2259 (*part)->momentum().pz(),(*part)->momentum().e()));
2268 std::pair<lorentzVector,lorentzVector> muFromRes;
2271 if(
debug>0 )
std::cout <<
"Starting loop on " << genParticles->size() <<
" genParticles" << std::endl;
2272 for( reco::GenParticleCollection::const_iterator
part=genParticles->begin();
part!=genParticles->end(); ++
part ) {
2274 bool fromRes =
false;
2275 unsigned int motherPdgId =
part->mother()->pdgId();
2277 std::cout <<
"Found a muon with mother: " << motherPdgId << std::endl;
2283 if(
part->pdgId()==13) {
2284 muFromRes.first =
part->p4();
2285 if(
debug>0 )
std::cout <<
"Found a genMuon + : " << muFromRes.first << std::endl;
2290 muFromRes.second =
part->p4();
2291 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)
static std::vector< std::pair< MuScleFitMuon, MuScleFitMuon > > SavedPairMuScleFitMuons
void likelihood(int &npar, double *grad, double &fval, double *xval, int flag)
static std::vector< std::pair< MuScleFitMuon, MuScleFitMuon > > genMuscleFitPair
virtual double scale(const double &pt, const double &eta, const double &phi, const int chg, const T &parScale) const =0
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
static std::vector< int > parScaleFix
static bool computeMinosErrors_
reco::Particle::LorentzVector lorentzVector
static scaleFunctionBase< std::vector< double > > * scaleFunctionForVec
static std::pair< SimTrack, SimTrack > findBestSimuRes(const std::vector< SimTrack > &simMuons)
static std::vector< std::vector< double > > parvalue
virtual double sigmaPt(const double &pt, const double &eta, const T &parval)=0
static std::pair< MuScleFitMuon, MuScleFitMuon > findBestRecoRes(const std::vector< MuScleFitMuon > &muons)
static std::vector< std::pair< lorentzVector, lorentzVector > > genPair
static std::vector< std::pair< lorentzVector, lorentzVector > > ReducedSavedPair
static const int totalResNum
static const double muMass
static double massResolution(const lorentzVector &mu1, const lorentzVector &mu2)
static const unsigned int motherPdgIdArray[6]
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
virtual void setParameters(double *Start, double *Step, double *Mini, double *Maxi, int *ind, TString *parname, const T &parScale, const std::vector< int > &parScaleOrder, const int muonType)=0
This method is used to differentiate parameters among the different functions.
static lorentzVector fromPtEtaPhiToPxPyPz(const double *ptEtaPhiE)
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
virtual double covPt1Pt2(const double &pt1, const double &eta1, const double &pt2, const double &eta2, const T &parval)
bool releaseParameters(TMinuit &rmin, const std::vector< int > &resfind, const std::vector< int > &parfix, const int *ind, const int iorder, const unsigned int shift)
Use the information in resfind, parorder and parfix to release the N-1 variables. ...
static double ResMaxSigma[6]
static double computeWeight(const double &mass, const int iev, const bool doUseBkgrWindow=false)
static std::vector< double > parScaleStep
static std::vector< std::pair< lorentzVector, lorentzVector > > SavedPair
static double invDimuonMass(const lorentzVector &mu1, const lorentzVector &mu2)
static lorentzVector applyScale(const lorentzVector &muon, const std::vector< double > &parval, const int charge)
static TH1D * signalProb_
static std::vector< int > parResolFix
static double GLZValue[40][1001][1001]
static TMinuit * rminPtr_
static std::vector< double > parSmear
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)
std::pair< OmniClusterRef, TrackingParticleRef > P
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_
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