00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "MuonAnalysis/MomentumScaleCalibration/interface/MuScleFitUtils.h"
00029 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00030 #include "SimDataFormats/Track/interface/SimTrack.h"
00031 #include "DataFormats/Candidate/interface/LeafCandidate.h"
00032 #include "DataFormats/Math/interface/LorentzVector.h"
00033 #include "TString.h"
00034 #include "TFile.h"
00035 #include "TTree.h"
00036 #include "TCanvas.h"
00037 #include "TH2F.h"
00038 #include "TF1.h"
00039 #include "TF2.h"
00040 #include <iostream>
00041 #include <fstream>
00042 #include <memory>
00043
00044
00045
00046
00047 #include "MuonAnalysis/MomentumScaleCalibration/interface/Functions.h"
00048
00049
00050
00051 #ifdef USE_CALLGRIND
00052 #include "valgrind/callgrind.h"
00053 #endif
00054
00055
00056
00057 Double_t lorentzianPeak (Double_t *x, Double_t *par) {
00058 return (0.5*par[0]*par[1]/TMath::Pi()) /
00059 TMath::Max(1.e-10,(x[0]-par[2])*(x[0]-par[2]) + .25*par[1]*par[1]);
00060 }
00061
00062
00063
00064 Double_t Gaussian (Double_t *x, Double_t *par) {
00065 return par[0]*exp(-0.5*((x[0]-par[1])/par[2])*((x[0]-par[1])/par[2]));
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 double mzsum;
00078 double isum;
00079 double f[11][100];
00080 double g[11][100];
00081
00082
00083
00084 TF1 * GL = new TF1 ("GL",
00085 "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))",
00086 0, 1000);
00087
00088 TF2 * GL2= new TF2 ("GL2",
00089 "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))",
00090 0, 200, 0, 200);
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 std::vector<int> MuScleFitUtils::doResolFit;
00105 std::vector<int> MuScleFitUtils::doScaleFit;
00106 std::vector<int> MuScleFitUtils::doCrossSectionFit;
00107 std::vector<int> MuScleFitUtils::doBackgroundFit;
00108
00109 int MuScleFitUtils::minuitLoop_ = 0;
00110 TH1D* MuScleFitUtils::likelihoodInLoop_ = 0;
00111 TH1D* MuScleFitUtils::signalProb_ = 0;
00112 TH1D* MuScleFitUtils::backgroundProb_ = 0;
00113
00114 bool MuScleFitUtils::duringMinos_ = false;
00115
00116 const int MuScleFitUtils::totalResNum = 6;
00117
00118 int MuScleFitUtils::SmearType = 0;
00119 smearFunctionBase * MuScleFitUtils::smearFunction = 0;
00120 int MuScleFitUtils::BiasType = 0;
00121
00122 scaleFunctionBase<std::vector<double> > * MuScleFitUtils::biasFunction = 0;
00123 int MuScleFitUtils::ResolFitType = 0;
00124 resolutionFunctionBase<double *> * MuScleFitUtils::resolutionFunction = 0;
00125 resolutionFunctionBase<std::vector<double> > * MuScleFitUtils::resolutionFunctionForVec = 0;
00126 int MuScleFitUtils::ScaleFitType = 0;
00127 scaleFunctionBase<double*> * MuScleFitUtils::scaleFunction = 0;
00128 scaleFunctionBase<std::vector<double> > * MuScleFitUtils::scaleFunctionForVec = 0;
00129 int MuScleFitUtils::BgrFitType = 0;
00130
00131 CrossSectionHandler * MuScleFitUtils::crossSectionHandler;
00132
00133
00134
00135 BackgroundHandler * MuScleFitUtils::backgroundHandler;
00136 std::vector<double> MuScleFitUtils::parBias;
00137 std::vector<double> MuScleFitUtils::parSmear;
00138 std::vector<double> MuScleFitUtils::parResol;
00139 std::vector<double> MuScleFitUtils::parScale;
00140 std::vector<double> MuScleFitUtils::parCrossSection;
00141 std::vector<double> MuScleFitUtils::parBgr;
00142 std::vector<int> MuScleFitUtils::parResolFix;
00143 std::vector<int> MuScleFitUtils::parScaleFix;
00144 std::vector<int> MuScleFitUtils::parCrossSectionFix;
00145 std::vector<int> MuScleFitUtils::parBgrFix;
00146 std::vector<int> MuScleFitUtils::parResolOrder;
00147 std::vector<int> MuScleFitUtils::parScaleOrder;
00148 std::vector<int> MuScleFitUtils::parCrossSectionOrder;
00149 std::vector<int> MuScleFitUtils::parBgrOrder;
00150
00151 std::vector<int> MuScleFitUtils::resfind;
00152 int MuScleFitUtils::debug = 0;
00153
00154 bool MuScleFitUtils::ResFound = false;
00155 int MuScleFitUtils::goodmuon = 0;
00156 int MuScleFitUtils::counter_resprob = 0;
00157
00158 std::vector<std::vector<double> > MuScleFitUtils::parvalue;
00159
00160 int MuScleFitUtils::FitStrategy = 1;
00161 bool MuScleFitUtils::speedup = false;
00162
00163 std::vector<std::pair<lorentzVector,lorentzVector> > MuScleFitUtils::SavedPair;
00164 std::vector<std::pair<lorentzVector,lorentzVector> > MuScleFitUtils::ReducedSavedPair;
00165 std::vector<std::pair<lorentzVector,lorentzVector> > MuScleFitUtils::genPair;
00166 std::vector<std::pair<lorentzVector,lorentzVector> > MuScleFitUtils::simPair;
00167
00168
00169
00170 double MuScleFitUtils::x[][10000];
00171
00172
00173
00174 int MuScleFitUtils::nbins = 1000;
00175 double MuScleFitUtils::GLZValue[][1001][1001];
00176 double MuScleFitUtils::GLZNorm[][1001];
00177 double MuScleFitUtils::GLValue[][1001][1001];
00178 double MuScleFitUtils::GLNorm[][1001];
00179 double MuScleFitUtils::ResMaxSigma[];
00180
00181
00182
00183
00184 const double MuScleFitUtils::mMu2 = 0.011163612;
00185 const double MuScleFitUtils::muMass = 0.105658;
00186 double MuScleFitUtils::ResHalfWidth[];
00187 double MuScleFitUtils::massWindowHalfWidth[][6];
00188 int MuScleFitUtils::MuonType;
00189 int MuScleFitUtils::MuonTypeForCheckMassWindow;
00190
00191 double MuScleFitUtils::ResGamma[] = {2.4952, 0.000020, 0.000032, 0.000054, 0.000317, 0.0000932 };
00192
00193
00194
00195
00196
00197
00198 double MuScleFitUtils::ResMinMass[] = {-99, -99, -99, -99, -99, -99};
00199 double MuScleFitUtils::ResMass[] = {91.1876, 10.3552, 10.0233, 9.4603, 3.68609, 3.0969};
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 unsigned int MuScleFitUtils::loopCounter = 5;
00211
00212
00213
00214 const unsigned int MuScleFitUtils::motherPdgIdArray[] = {23, 100553, 100553, 553, 100443, 443};
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 bool MuScleFitUtils::scaleFitNotDone_ = true;
00228
00229 bool MuScleFitUtils::sherpa_ = false;
00230
00231 bool MuScleFitUtils::useProbsFile_ = true;
00232
00233 bool MuScleFitUtils::rapidityBinsForZ_ = true;
00234
00235 double MuScleFitUtils::minMuonPt_ = 0.;
00236 double MuScleFitUtils::maxMuonPt_ = 100000000.;
00237 double MuScleFitUtils::minMuonEtaFirstRange_ = -6.;
00238 double MuScleFitUtils::maxMuonEtaFirstRange_ = 6.;
00239 double MuScleFitUtils::minMuonEtaSecondRange_ = -100.;
00240 double MuScleFitUtils::maxMuonEtaSecondRange_ = 100.;
00241
00242 bool MuScleFitUtils::debugMassResol_;
00243 MuScleFitUtils::massResolComponentsStruct MuScleFitUtils::massResolComponents;
00244
00245 bool MuScleFitUtils::normalizeLikelihoodByEventNumber_ = true;
00246 TMinuit * MuScleFitUtils::rminPtr_ = 0;
00247 double MuScleFitUtils::oldNormalization_ = 0.;
00248 unsigned int MuScleFitUtils::normalizationChanged_ = 0;
00249
00250 bool MuScleFitUtils::startWithSimplex_;
00251 bool MuScleFitUtils::computeMinosErrors_;
00252 bool MuScleFitUtils::minimumShapePlots_;
00253
00254 int MuScleFitUtils::iev_ = 0;
00256
00257
00258
00259
00260 std::pair<SimTrack,SimTrack> MuScleFitUtils::findBestSimuRes (const std::vector<SimTrack>& simMuons) {
00261
00262 std::pair<SimTrack, SimTrack> simMuFromBestRes;
00263 double maxprob = -0.1;
00264
00265
00266
00267 for (std::vector<SimTrack>::const_iterator simMu1=simMuons.begin(); simMu1!=simMuons.end(); simMu1++) {
00268 for (std::vector<SimTrack>::const_iterator simMu2=simMu1+1; simMu2!=simMuons.end(); simMu2++) {
00269 if (((*simMu1).charge()*(*simMu2).charge())>0) {
00270 continue;
00271 }
00272
00273
00274 double mcomb = ((*simMu1).momentum()+(*simMu2).momentum()).mass();
00275 double Y = ((*simMu1).momentum()+(*simMu2).momentum()).Rapidity();
00276 for (int ires=0; ires<6; ires++) {
00277 if (resfind[ires]>0) {
00278 double prob = massProb( mcomb, Y, ires, 0. );
00279 if (prob>maxprob) {
00280 simMuFromBestRes.first = (*simMu1);
00281 simMuFromBestRes.second = (*simMu2);
00282 maxprob = prob;
00283 }
00284 }
00285 }
00286 }
00287 }
00288
00289
00290
00291 return simMuFromBestRes;
00292 }
00293
00294
00295
00296
00297 std::pair<lorentzVector,lorentzVector> MuScleFitUtils::findBestRecoRes( const std::vector<reco::LeafCandidate>& muons ){
00298
00299
00300
00301 if (debug>0) std::cout << "In findBestRecoRes" << std::endl;
00302 ResFound = false;
00303 std::pair<lorentzVector, lorentzVector> recMuFromBestRes;
00304
00305
00306
00307 double maxprob = -0.1;
00308 double minDeltaMass = 999999;
00309 std::pair<reco::LeafCandidate,reco::LeafCandidate> bestMassMuons;
00310 for (std::vector<reco::LeafCandidate>::const_iterator Muon1=muons.begin(); Muon1!=muons.end(); ++Muon1) {
00311 for (std::vector<reco::LeafCandidate>::const_iterator Muon2=Muon1+1; Muon2!=muons.end(); ++Muon2) {
00312 if (((*Muon1).charge()*(*Muon2).charge())>0) {
00313 continue;
00314 }
00315
00316
00317
00318
00319 double pt1 = (*Muon1).p4().Pt();
00320 double pt2 = (*Muon2).p4().Pt();
00321 double eta1 = (*Muon1).p4().Eta();
00322 double eta2 = (*Muon2).p4().Eta();
00323 if( pt1 > minMuonPt_ && pt1 < maxMuonPt_ &&
00324 pt2 > minMuonPt_ && pt2 < maxMuonPt_ &&
00325 eta1 > minMuonEtaFirstRange_ && eta1 < maxMuonEtaFirstRange_ &&
00326 eta2 > minMuonEtaFirstRange_ && eta2 < maxMuonEtaFirstRange_ &&
00327 eta1 > minMuonEtaSecondRange_ && eta1 < maxMuonEtaSecondRange_ &&
00328 eta2 > minMuonEtaSecondRange_ && eta2 < maxMuonEtaSecondRange_ ) {
00329 double mcomb = ((*Muon1).p4()+(*Muon2).p4()).mass();
00330 double Y = ((*Muon1).p4()+(*Muon2).p4()).Rapidity();
00331 if (debug>1) {
00332 std::cout<<"muon1 "<<(*Muon1).p4().Px()<<", "<<(*Muon1).p4().Py()<<", "<<(*Muon1).p4().Pz()<<", "<<(*Muon1).p4().E()<<std::endl;
00333 std::cout<<"muon2 "<<(*Muon2).p4().Px()<<", "<<(*Muon2).p4().Py()<<", "<<(*Muon2).p4().Pz()<<", "<<(*Muon2).p4().E()<<std::endl;
00334 std::cout<<"mcomb "<<mcomb<<std::endl;}
00335 double massResol = 0.;
00336 if( useProbsFile_ ) {
00337 massResol = massResolution ((*Muon1).p4(), (*Muon2).p4(), parResol);
00338 }
00339 double prob = 0;
00340 for( int ires=0; ires<6; ires++ ) {
00341 if( resfind[ires]>0 ) {
00342 if( useProbsFile_ ) {
00343 prob = massProb( mcomb, Y, ires, massResol );
00344 }
00345 if( prob>maxprob ) {
00346 if( (*Muon1).charge()<0 ) {
00347 recMuFromBestRes.first = (*Muon1).p4();
00348 recMuFromBestRes.second = (*Muon2).p4();
00349 } else {
00350 recMuFromBestRes.first = (*Muon2).p4();
00351 recMuFromBestRes.second = (*Muon1).p4();
00352 }
00353 ResFound = true;
00354 maxprob = prob;
00355 }
00356
00357
00358
00359
00360 double deltaMass = fabs(mcomb-ResMass[ires])/ResMass[ires];
00361 if( deltaMass<minDeltaMass ){
00362 bestMassMuons = std::make_pair((*Muon1),(*Muon2));
00363 minDeltaMass = deltaMass;
00364 }
00365 }
00366 }
00367 }
00368 }
00369 }
00370
00371
00372 if(!maxprob){
00373 if(bestMassMuons.first.charge()<0){
00374 recMuFromBestRes.first = bestMassMuons.first.p4();
00375 recMuFromBestRes.second = bestMassMuons.second.p4();
00376 }
00377 else{
00378 recMuFromBestRes.second = bestMassMuons.first.p4();
00379 recMuFromBestRes.first = bestMassMuons.second.p4();
00380 }
00381 }
00382 return recMuFromBestRes;
00383 }
00384
00385
00386
00387 lorentzVector MuScleFitUtils::applySmearing (const lorentzVector& muon)
00388 {
00389 double pt = muon.Pt();
00390 double eta = muon.Eta();
00391 double phi = muon.Phi();
00392 double E = muon.E();
00393
00394 double y[7];
00395 for (int i=0; i<SmearType+3; i++) {
00396 y[i] = x[i][goodmuon%10000];
00397 }
00398
00399
00400 smearFunction->smear( pt, eta, phi, y, parSmear );
00401
00402 if (debug>9) {
00403 std::cout << "Smearing Pt,eta,phi = " << pt << " " << eta << " "
00404 << phi << "; x = ";
00405 for (int i=0; i<SmearType+3; i++) {
00406 std::cout << y[i];
00407 }
00408 std::cout << std::endl;
00409 }
00410
00411 double ptEtaPhiE[4] = {pt, eta, phi, E};
00412 return( fromPtEtaPhiToPxPyPz(ptEtaPhiE) );
00413 }
00414
00415
00416
00417 lorentzVector MuScleFitUtils::applyBias( const lorentzVector& muon, const int chg )
00418 {
00419 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
00420
00421 if (MuScleFitUtils::debug>1) std::cout << "pt before bias = " << ptEtaPhiE[0] << std::endl;
00422
00423
00424
00425
00426
00427
00428 ptEtaPhiE[0] = biasFunction->scale(ptEtaPhiE[0], ptEtaPhiE[1], ptEtaPhiE[2], chg, MuScleFitUtils::parBias);
00429
00430 if (MuScleFitUtils::debug>1) std::cout << "pt after bias = " << ptEtaPhiE[0] << std::endl;
00431
00432 return( fromPtEtaPhiToPxPyPz(ptEtaPhiE) );
00433 }
00434
00435
00436
00437 lorentzVector MuScleFitUtils::applyScale (const lorentzVector& muon,
00438 const std::vector<double> & parval, const int chg)
00439 {
00440 double * p = new double[(int)(parval.size())];
00441
00442
00443
00444 int id = 0;
00445 for (std::vector<double>::const_iterator it=parval.begin(); it!=parval.end(); ++it, ++id) {
00446
00447
00448 p[id] = *it;
00449 }
00450 lorentzVector tempScaleVec( applyScale (muon, p, chg) );
00451 delete[] p;
00452 return tempScaleVec;
00453 }
00454
00455
00456
00457 lorentzVector MuScleFitUtils::applyScale (const lorentzVector& muon,
00458 double* parval, const int chg)
00459 {
00460 double ptEtaPhiE[4] = {muon.Pt(),muon.Eta(),muon.Phi(),muon.E()};
00461 int shift = parResol.size();
00462
00463 if (MuScleFitUtils::debug>1) std::cout << "pt before scale = " << ptEtaPhiE[0] << std::endl;
00464
00465
00466
00467 ptEtaPhiE[0] = scaleFunction->scale(ptEtaPhiE[0], ptEtaPhiE[1], ptEtaPhiE[2], chg, &(parval[shift]));
00468
00469 if (MuScleFitUtils::debug>1) std::cout << "pt after scale = " << ptEtaPhiE[0] << std::endl;
00470
00471 return( fromPtEtaPhiToPxPyPz(ptEtaPhiE) );
00472 }
00473
00474
00475
00476 lorentzVector MuScleFitUtils::fromPtEtaPhiToPxPyPz( const double* ptEtaPhiE )
00477 {
00478 double px = ptEtaPhiE[0]*cos(ptEtaPhiE[2]);
00479 double py = ptEtaPhiE[0]*sin(ptEtaPhiE[2]);
00480 double tmp = 2*atan(exp(-ptEtaPhiE[1]));
00481 double pz = ptEtaPhiE[0]*cos(tmp)/sin(tmp);
00482 double E = sqrt(px*px+py*py+pz*pz+muMass*muMass);
00483
00484
00485
00486
00487
00488 return lorentzVector(px,py,pz,E);
00489 }
00490
00491
00492
00493 inline double MuScleFitUtils::invDimuonMass( const lorentzVector& mu1,
00494 const lorentzVector& mu2 )
00495 {
00496 return (mu1+mu2).mass();
00497 }
00498
00499
00500
00501 double MuScleFitUtils::massResolution( const lorentzVector& mu1,
00502 const lorentzVector& mu2,
00503 const std::vector<double> & parval )
00504 {
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 double * p = new double[(int)(parval.size())];
00517 std::vector<double>::const_iterator it = parval.begin();
00518 int id = 0;
00519 for ( ; it!=parval.end(); ++it, ++id) {
00520
00521 p[id] = *it;
00522 }
00523 double massRes = massResolution (mu1, mu2, p);
00524 delete[] p;
00525 return massRes;
00526 }
00527
00528 double MuScleFitUtils::massResolution( const lorentzVector& mu1,
00529 const lorentzVector& mu2,
00530 double* parval )
00531 {
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 double mass = (mu1+mu2).mass();
00549 double pt1 = mu1.Pt();
00550 double phi1 = mu1.Phi();
00551 double eta1 = mu1.Eta();
00552 double theta1 = 2*atan(exp(-eta1));
00553
00554 double pt2 = mu2.Pt();
00555 double phi2 = mu2.Phi();
00556 double eta2 = mu2.Eta();
00557 double theta2 = 2*atan(exp(-eta2));
00558
00559
00560
00561
00562
00563
00564
00565 double dmdpt1 = (pt1/std::pow(sin(theta1),2)*sqrt((std::pow(pt2/sin(theta2),2)+mMu2)/(std::pow(pt1/sin(theta1),2)+mMu2))-
00566 pt2*(cos(phi1-phi2)+cos(theta1)*cos(theta2)/(sin(theta1)*sin(theta2))))/mass;
00567 double dmdpt2 = (pt2/std::pow(sin(theta2),2)*sqrt((std::pow(pt1/sin(theta1),2)+mMu2)/(std::pow(pt2/sin(theta2),2)+mMu2))-
00568 pt1*(cos(phi2-phi1)+cos(theta2)*cos(theta1)/(sin(theta2)*sin(theta1))))/mass;
00569 double dmdphi1 = pt1*pt2/mass*sin(phi1-phi2);
00570 double dmdphi2 = pt2*pt1/mass*sin(phi2-phi1);
00571
00572
00573
00574
00575
00576
00577 double dmdcotgth1 = (pt1*pt1*cos(theta1)/sin(theta1)*
00578 sqrt((std::pow(pt2/sin(theta2),2)+mMu2)/(std::pow(pt1/sin(theta1),2)+mMu2)) -
00579 pt1*pt2*cos(theta2)/sin(theta2))/mass;
00580 double dmdcotgth2 = (pt2*pt2*cos(theta2)/sin(theta2)*
00581 sqrt((std::pow(pt1/sin(theta1),2)+mMu2)/(std::pow(pt2/sin(theta2),2)+mMu2)) -
00582 pt2*pt1*cos(theta1)/sin(theta1))/mass;
00583
00584 if( debugMassResol_ ) {
00585 massResolComponents.dmdpt1 = dmdpt1;
00586 massResolComponents.dmdpt2 = dmdpt2;
00587 massResolComponents.dmdphi1 = dmdphi1;
00588 massResolComponents.dmdphi2 = dmdphi2;
00589 massResolComponents.dmdcotgth1 = dmdcotgth1;
00590 massResolComponents.dmdcotgth2 = dmdcotgth2;
00591 }
00592
00593
00594
00595 double sigma_pt1 = resolutionFunction->sigmaPt( pt1,eta1,parval );
00596 double sigma_pt2 = resolutionFunction->sigmaPt( pt2,eta2,parval );
00597 double sigma_phi1 = resolutionFunction->sigmaPhi( pt1,eta1,parval );
00598 double sigma_phi2 = resolutionFunction->sigmaPhi( pt2,eta2,parval );
00599 double sigma_cotgth1 = resolutionFunction->sigmaCotgTh( pt1,eta1,parval );
00600 double sigma_cotgth2 = resolutionFunction->sigmaCotgTh( pt2,eta2,parval );
00601 double cov_pt1pt2 = resolutionFunction->covPt1Pt2( pt1, eta1, pt2, eta2, parval );
00602
00603
00604
00605 double mass_res = sqrt(std::pow(dmdpt1*sigma_pt1*pt1,2)+std::pow(dmdpt2*sigma_pt2*pt2,2)+
00606 std::pow(dmdphi1*sigma_phi1,2)+std::pow(dmdphi2*sigma_phi2,2)+
00607 std::pow(dmdcotgth1*sigma_cotgth1,2)+std::pow(dmdcotgth2*sigma_cotgth2,2)+
00608 2*dmdpt1*dmdpt2*cov_pt1pt2);
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 if (debug>19) {
00619 std::cout << " Pt1=" << pt1 << " phi1=" << phi1 << " cotgth1=" << cos(theta1)/sin(theta1) << " - Pt2=" << pt2
00620 << " phi2=" << phi2 << " cotgth2=" << cos(theta2)/sin(theta2) << std::endl;
00621 std::cout << " P[0]="
00622 << parval[0] << " P[1]=" << parval[1] << "P[2]=" << parval[2] << " P[3]=" << parval[3] << std::endl;
00623 std::cout << " Dmdpt1= " << dmdpt1 << " dmdpt2= " << dmdpt2 << " sigma_pt1="
00624 << sigma_pt1 << " sigma_pt2=" << sigma_pt2 << std::endl;
00625 std::cout << " Dmdphi1= " << dmdphi1 << " dmdphi2= " << dmdphi2 << " sigma_phi1="
00626 << sigma_phi1 << " sigma_phi2=" << sigma_phi2 << std::endl;
00627 std::cout << " Dmdcotgth1= " << dmdcotgth1 << " dmdcotgth2= " << dmdcotgth2
00628 << " sigma_cotgth1="
00629 << sigma_cotgth1 << " sigma_cotgth2=" << sigma_cotgth2 << std::endl;
00630 std::cout << " Mass resolution (pval) for muons of Pt = " << pt1 << " " << pt2
00631 << " : " << mass << " +- " << mass_res << std::endl;
00632 }
00633
00634
00635
00636 bool didit = false;
00637 for (int ires=0; ires<6; ires++) {
00638 if (!didit && resfind[ires]>0 && fabs(mass-ResMass[ires])<ResHalfWidth[ires]) {
00639 if (mass_res>ResMaxSigma[ires] && counter_resprob<100) {
00640 counter_resprob++;
00641 LogDebug("MuScleFitUtils") << "RESOLUTION PROBLEM: ires=" << ires << std::endl;
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 didit = true;
00664 }
00665 }
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 return mass_res;
00682 }
00683
00684
00685
00686 double MuScleFitUtils::massProb( const double & mass, const double & resEta, const double & rapidity, const double & massResol, const std::vector<double> & parval, const bool doUseBkgrWindow )
00687 {
00688 #ifdef USE_CALLGRIND
00689 CALLGRIND_START_INSTRUMENTATION;
00690 #endif
00691
00692 double * p = new double[(int)(parval.size())];
00693
00694
00695
00696
00697 std::vector<double>::const_iterator it = parval.begin();
00698 int id = 0;
00699 for ( ; it!=parval.end(); ++it, ++id) {
00700
00701 p[id] = *it;
00702 }
00703
00704 double massProbability = massProb( mass, resEta, rapidity, massResol, p, doUseBkgrWindow );
00705 delete[] p;
00706
00707 #ifdef USE_CALLGRIND
00708 CALLGRIND_STOP_INSTRUMENTATION;
00709 CALLGRIND_DUMP_STATS;
00710 #endif
00711
00712 return massProbability;
00713 }
00714
00720 double MuScleFitUtils::probability( const double & mass, const double & massResol,
00721 const double GLvalue[][1001][1001], const double GLnorm[][1001],
00722 const int iRes, const int iY )
00723 {
00724 if( iRes == 0 && iY > 23 ) {
00725 std::cout << "WARNING: rapidity bin selected = " << iY << " but there are only histograms for the first 24 bins" << std::endl;
00726 }
00727
00728 double PS = 0.;
00729 bool insideProbMassWindow = true;
00730
00731
00732
00733
00734
00735
00736 double fracMass = (mass - ResMinMass[iRes])/(2*ResHalfWidth[iRes]);
00737 if (debug>1) std::cout << std::setprecision(9)<<"mass ResMinMass[iRes] ResHalfWidth[iRes] ResHalfWidth[iRes]"
00738 << mass << " "<<ResMinMass[iRes]<<" "<<ResHalfWidth[iRes]<<" "<<ResHalfWidth[iRes]<<std::endl;
00739 int iMassLeft = (int)(fracMass*(double)nbins);
00740 int iMassRight = iMassLeft+1;
00741 double fracMassStep = (double)nbins*(fracMass - (double)iMassLeft/(double)nbins);
00742 if (debug>1) std::cout<<"nbins iMassLeft fracMass "<<nbins<<" "<<iMassLeft<<" "<<fracMass<<std::endl;
00743
00744
00745
00746
00747 if (iMassLeft<0) {
00748 edm::LogInfo("probability") << "WARNING: fracMass=" << fracMass << ", iMassLeft="
00749 << iMassLeft << "; mass = " << mass << " and bounds are " << ResMinMass[iRes]
00750 << ":" << ResMinMass[iRes]+2*ResHalfWidth[iRes] << " - iMassLeft set to 0" << std::endl;
00751 iMassLeft = 0;
00752 iMassRight = 1;
00753 insideProbMassWindow = false;
00754 }
00755 if (iMassRight>nbins) {
00756 edm::LogInfo("probability") << "WARNING: fracMass=" << fracMass << ", iMassRight="
00757 << iMassRight << "; mass = " << mass << " and bounds are " << ResMinMass[iRes]
00758 << ":" << ResMass[iRes]+2*ResHalfWidth[iRes] << " - iMassRight set to " << nbins-1 << std::endl;
00759 iMassLeft = nbins-1;
00760 iMassRight = nbins;
00761 insideProbMassWindow = false;
00762 }
00763 double fracSigma = (massResol/ResMaxSigma[iRes]);
00764 int iSigmaLeft = (int)(fracSigma*(double)nbins);
00765 int iSigmaRight = iSigmaLeft+1;
00766 double fracSigmaStep = (double)nbins * (fracSigma - (double)iSigmaLeft/(double)nbins);
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 if (iSigmaLeft<0) {
00780 edm::LogInfo("probability") << "WARNING: fracSigma = " << fracSigma << ", iSigmaLeft="
00781 << iSigmaLeft << ", with massResol = " << massResol << " and ResMaxSigma[iRes] = "
00782 << ResMaxSigma[iRes] << " - iSigmaLeft set to 0" << std::endl;
00783 iSigmaLeft = 0;
00784 iSigmaRight = 1;
00785 }
00786 if (iSigmaRight>nbins ) {
00787 if (counter_resprob<100)
00788 edm::LogInfo("probability") << "WARNING: fracSigma = " << fracSigma << ", iSigmaRight="
00789 << iSigmaRight << ", with massResol = " << massResol << " and ResMaxSigma[iRes] = "
00790 << ResMaxSigma[iRes] << " - iSigmaRight set to " << nbins-1 << std::endl;
00791 iSigmaLeft = nbins-1;
00792 iSigmaRight = nbins;
00793 }
00794
00795
00796
00797
00798 if( insideProbMassWindow ) {
00799 double f11 = 0.;
00800 if (GLnorm[iY][iSigmaLeft]>0)
00801 f11 = GLvalue[iY][iMassLeft][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
00802 double f12 = 0.;
00803 if (GLnorm[iY][iSigmaRight]>0)
00804 f12 = GLvalue[iY][iMassLeft][iSigmaRight] / GLnorm[iY][iSigmaRight];
00805 double f21 = 0.;
00806 if (GLnorm[iY][iSigmaLeft]>0)
00807 f21 = GLvalue[iY][iMassRight][iSigmaLeft] / GLnorm[iY][iSigmaLeft];
00808 double f22 = 0.;
00809 if (GLnorm[iY][iSigmaRight]>0)
00810 f22 = GLvalue[iY][iMassRight][iSigmaRight] / GLnorm[iY][iSigmaRight];
00811 PS = f11 + (f12-f11)*fracSigmaStep + (f21-f11)*fracMassStep +
00812 (f22-f21-f12+f11)*fracMassStep*fracSigmaStep;
00813 if (PS>0.1 || debug>1) LogDebug("MuScleFitUtils") << "iRes = " << iRes << " PS=" << PS << " f11,f12,f21,f22="
00814 << f11 << " " << f12 << " " << f21 << " " << f22 << " "
00815 << " fSS=" << fracSigmaStep << " fMS=" << fracMassStep << " iSL, iSR="
00816 << iSigmaLeft << " " << iSigmaRight
00817 << " GLvalue["<<iY<<"]["<<iMassLeft<<"] = " << GLvalue[iY][iMassLeft][iSigmaLeft]
00818 << " GLnorm["<<iY<<"]["<<iSigmaLeft<<"] = " << GLnorm[iY][iSigmaLeft] << std::endl;
00819
00820
00821
00822
00823
00824
00825
00826
00827 }
00828 else {
00829 edm::LogInfo("probability") << "outside mass probability window. Setting PS["<<iRes<<"] = 0" << std::endl;
00830 }
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 return PS;
00847 }
00848
00849
00850
00851 double MuScleFitUtils::massProb( const double & mass, const double & resEta, const double & rapidity, const double & massResol, double * parval, const bool doUseBkgrWindow ) {
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 double P = 0.;
00913 int crossSectionParShift = parResol.size() + parScale.size();
00914
00915 std::vector<double> relativeCrossSections = crossSectionHandler->relativeCrossSections(&(parval[crossSectionParShift]), resfind);
00916
00917
00918
00919
00920
00921
00922 int bgrParShift = crossSectionParShift + crossSectionHandler->parNum();
00923 double Bgrp1 = 0.;
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 double PS[6] = {0.};
00941 double PB = 0.;
00942 double PStot[6] = {0.};
00943
00944
00945 bool resConsidered[6] = {false};
00946
00947 bool useBackgroundWindow = (doBackgroundFit[loopCounter] || doUseBkgrWindow);
00948
00949
00950
00951
00952
00953
00954
00955 if( MuScleFitUtils::rapidityBinsForZ_ ) {
00956
00957
00958 std::pair<double, double> windowBorders = backgroundHandler->windowBorders( useBackgroundWindow, 0 );
00959 if( resfind[0]>0
00960
00961
00962
00963 && checkMassWindow( mass, windowBorders.first, windowBorders.second )
00964
00965 ) {
00966
00967 int iY = (int)(fabs(rapidity)*10.);
00968 if( iY > 23 ) iY = 23;
00969
00970 if (MuScleFitUtils::debug>1) std::cout << "massProb:resFound = 0, rapidity bin =" << iY << std::endl;
00971
00972
00973 PS[0] = probability(mass, massResol, GLZValue, GLZNorm, 0, iY);
00974
00975 if( PS[0] != PS[0] ) {
00976 std::cout << "ERROR: PS[0] = nan, setting it to 0" << std::endl;
00977 PS[0] = 0;
00978 }
00979
00980 std::pair<double, double> bgrResult = backgroundHandler->backgroundFunction( doBackgroundFit[loopCounter],
00981 &(parval[bgrParShift]), MuScleFitUtils::totalResNum, 0,
00982 resConsidered, ResMass, ResHalfWidth, MuonType, mass, resEta );
00983 Bgrp1 = bgrResult.first;
00984
00985
00986
00987 PB = bgrResult.second;
00988 if( PB != PB ) PB = 0;
00989 PStot[0] = (1-Bgrp1)*PS[0] + Bgrp1*PB;
00990
00991
00992
00993 PStot[0] *= relativeCrossSections[0];
00994
00995 }
00996 else {
00997 if( debug > 0 ) {
00998 std::cout << "Mass = " << mass << " outside range with rapidity = " << rapidity << std::endl;
00999 std::cout << "with resMass = " << backgroundHandler->resMass( useBackgroundWindow, 0 ) << " and left border = " << windowBorders.first << " right border = " << windowBorders.second << std::endl;
01000 }
01001 }
01002 }
01003
01004
01005 int firstRes = 1;
01006 if( !MuScleFitUtils::rapidityBinsForZ_ ) firstRes = 0;
01007 for( int ires=firstRes; ires<6; ++ires ) {
01008 if( resfind[ires] > 0 ) {
01009
01010
01011 std::pair<double, double> windowBorder = backgroundHandler->windowBorders( useBackgroundWindow, ires );
01012 if( checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
01013 if (MuScleFitUtils::debug>1) std::cout << "massProb:resFound = " << ires << std::endl;
01014
01015
01016 PS[ires] = probability(mass, massResol, GLValue, GLNorm, ires, ires);
01017
01018 std::pair<double, double> bgrResult = backgroundHandler->backgroundFunction( doBackgroundFit[loopCounter],
01019 &(parval[bgrParShift]), MuScleFitUtils::totalResNum, ires,
01020 resConsidered, ResMass, ResHalfWidth, MuonType, mass, resEta );
01021 Bgrp1 = bgrResult.first;
01022 PB = bgrResult.second;
01023
01024 if( PB != PB ) PB = 0;
01025 PStot[ires] = (1-Bgrp1)*PS[ires] + Bgrp1*PB;
01026 if( MuScleFitUtils::debug>0 ) std::cout << "PStot["<<ires<<"] = " << "(1-"<<Bgrp1<<")*"<<PS[ires]<<" + "<<Bgrp1<<"*"<<PB<<" = " << PStot[ires] << std::endl;
01027
01028 PStot[ires] *= relativeCrossSections[ires];
01029 }
01030 }
01031 }
01032
01033 for( int i=0; i<6; ++i ) {
01034 P += PStot[i];
01035 }
01036
01037 if( MuScleFitUtils::signalProb_ != 0 && MuScleFitUtils::backgroundProb_ != 0 ) {
01038 double PStotTemp = 0.;
01039 for( int i=0; i<6; ++i ) {
01040 PStotTemp += PS[i]*relativeCrossSections[i];
01041 }
01042 if( PStotTemp != PStotTemp ) {
01043 std::cout << "ERROR: PStotTemp = nan!!!!!!!!!" << std::endl;
01044 int parnumber = (int)(parResol.size()+parScale.size()+crossSectionHandler->parNum()+parBgr.size());
01045 for( int i=0; i<6; ++i ) {
01046 std::cout << "PS[i] = " << PS[i] << std::endl;
01047 if( PS[i] != PS[i] ) {
01048 std::cout << "mass = " << mass << std::endl;
01049 std::cout << "massResol = " << massResol << std::endl;
01050 for( int j=0; j<parnumber; ++j ) {
01051 std::cout << "parval["<<j<<"] = " << parval[j] << std::endl;
01052 }
01053 }
01054 }
01055 }
01056 if( PStotTemp == PStotTemp ) {
01057 MuScleFitUtils::signalProb_->SetBinContent(MuScleFitUtils::minuitLoop_, MuScleFitUtils::signalProb_->GetBinContent(MuScleFitUtils::minuitLoop_) + PStotTemp);
01058 }
01059 if (debug>0) std::cout << "mass = " << mass << ", P = " << P << ", PStot = " << PStotTemp << ", PB = " << PB << ", bgrp1 = " << Bgrp1 << std::endl;
01060
01061 MuScleFitUtils::backgroundProb_->SetBinContent(MuScleFitUtils::minuitLoop_, MuScleFitUtils::backgroundProb_->GetBinContent(MuScleFitUtils::minuitLoop_) + PB);
01062 }
01063 return P;
01064 }
01065
01066
01067
01068
01069
01070
01071
01072 inline bool MuScleFitUtils::checkMassWindow( const double & mass, const double & leftBorder, const double & rightBorder )
01073 {
01074 return( (mass > leftBorder) && (mass < rightBorder) );
01075 }
01076
01077
01078
01079 double MuScleFitUtils::computeWeight( const double & mass, const int iev, const bool doUseBkgrWindow )
01080 {
01081
01082
01083 double weight = 0.;
01084
01085
01086
01087
01088
01089
01090 if( doUseBkgrWindow && (debug > 0) ) std::cout << "using backgrond window for mass = " << mass << std::endl;
01091
01092 bool useBackgroundWindow = (doBackgroundFit[loopCounter]);
01093
01094 for (int ires=0; ires<6; ires++) {
01095 if (resfind[ires]>0 && weight==0.) {
01096
01097 std::pair<double, double> windowBorder = backgroundHandler->windowBorders( useBackgroundWindow, ires );
01098
01099
01100 if( checkMassWindow(mass, windowBorder.first, windowBorder.second) ) {
01101 weight = 1.0;
01102 if( doUseBkgrWindow && (debug > 0) ) std::cout << "setting weight to = " << weight << std::endl;
01103 }
01104 }
01105 }
01106
01107 return weight;
01108 }
01109
01110
01111
01112 void MuScleFitUtils::minimizeLikelihood()
01113 {
01114
01115
01116 ofstream FitParametersFile;
01117 FitParametersFile.open ("FitParameters.txt", std::ios::app);
01118 FitParametersFile << "Fitting with resolution, scale, bgr function # "
01119 << ResolFitType << " " << ScaleFitType << " " << BgrFitType
01120 << " - Iteration " << loopCounter << std::endl;
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 int parForResonanceWindows = 0;
01136
01137 int parnumber = (int)(parResol.size()+parScale.size()+crossSectionHandler->parNum()+parBgr.size() - parForResonanceWindows);
01138
01139
01140
01141
01142
01143
01144 int parnumberAll = (int)(parResol.size()+parScale.size()+crossSectionHandler->parNum()+parBgr.size());
01145
01146
01147 parvalue.push_back(parResol);
01148 std::vector<double> *tmpVec = &(parvalue.back());
01149
01150
01151
01152
01153 if( scaleFitNotDone_ ) {
01154 tmpVec->insert( tmpVec->end(), parScale.begin(), parScale.end() );
01155 std::cout << "scaleFitNotDone: tmpVec->size() = " << tmpVec->size() << std::endl;
01156 }
01157 else {
01158 scaleFunction->resetParameters(tmpVec);
01159 std::cout << "scaleFitDone: tmpVec->size() = " << tmpVec->size() << std::endl;
01160 }
01161 tmpVec->insert( tmpVec->end(), parCrossSection.begin(), parCrossSection.end() );
01162 tmpVec->insert( tmpVec->end(), parBgr.begin(), parBgr.end() );
01163 int i = 0;
01164 std::vector<double>::const_iterator it = tmpVec->begin();
01165 for( ; it != tmpVec->end(); ++it, ++i ) {
01166 std::cout << "tmpVec["<<i<<"] = " << *it << std::endl;
01167 }
01168
01169
01170
01171
01172 std::vector<int> crossSectionParNumSizeVec( MuScleFitUtils::crossSectionHandler->parNum(), 0 );
01173
01174 std::vector<int> parfix(parResolFix);
01175 parfix.insert( parfix.end(), parScaleFix.begin(), parScaleFix.end() );
01176 parfix.insert( parfix.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
01177 parfix.insert( parfix.end(), parBgrFix.begin(), parBgrFix.end() );
01178
01179 std::vector<int> parorder(parResolOrder);
01180 parorder.insert( parorder.end(), parScaleOrder.begin(), parScaleOrder.end() );
01181 parorder.insert( parorder.end(), crossSectionParNumSizeVec.begin(), crossSectionParNumSizeVec.end() );
01182 parorder.insert( parorder.end(), parBgrOrder.begin(), parBgrOrder.end() );
01183
01184
01185 std::vector<double> parerr(3*parnumberAll,0.);
01186
01187 if (debug>19) {
01188 std::cout << "[MuScleFitUtils-minimizeLikelihood]: Parameters before likelihood " << std::endl;
01189 for (unsigned int i=0; i<(unsigned int)parnumberAll; i++) {
01190 std::cout << " Par # " << i << " = " << parvalue[loopCounter][i] << " : free = " << parfix[i] << "; order = "
01191 << parorder[i] << std::endl;
01192 }
01193 }
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 TMinuit rmin (parnumber);
01209 rminPtr_ = &rmin;
01210 rmin.SetFCN (likelihood);
01211
01212
01213
01214 rmin.mninit (5, 6, 7);
01215 int ierror = 0;
01216 int istat;
01217 double arglis[4];
01218 arglis[0] = FitStrategy;
01219
01220
01221 rmin.mnexcm ("SET STR", arglis, 1, ierror);
01222
01223 arglis[0] = 10001;
01224
01225 rmin.mnexcm("SET RAN", arglis, 1, ierror);
01226
01227
01228
01229 double * Start = new double[parnumberAll];
01230 double * Step = new double[parnumberAll];
01231 double * Mini = new double[parnumberAll];
01232 double * Maxi = new double[parnumberAll];
01233 int * ind = new int[parnumberAll];
01234 TString * parname = new TString[parnumberAll];
01235
01236 MuScleFitUtils::resolutionFunctionForVec->setParameters( Start, Step, Mini, Maxi, ind, parname, parResol, parResolOrder, MuonType );
01237
01238
01239 int resParNum = MuScleFitUtils::resolutionFunctionForVec->parNum();
01240
01241 MuScleFitUtils::scaleFunctionForVec->setParameters( &(Start[resParNum]), &(Step[resParNum]), &(Mini[resParNum]), &(Maxi[resParNum]),
01242 &(ind[resParNum]), &(parname[resParNum]), parScale, parScaleOrder, MuonType );
01243
01244
01245 int crossSectionParShift = resParNum + MuScleFitUtils::scaleFunctionForVec->parNum();
01246 MuScleFitUtils::crossSectionHandler->setParameters( &(Start[crossSectionParShift]), &(Step[crossSectionParShift]), &(Mini[crossSectionParShift]),
01247 &(Maxi[crossSectionParShift]), &(ind[crossSectionParShift]), &(parname[crossSectionParShift]),
01248 parCrossSection, parCrossSectionOrder, resfind );
01249
01250
01251 int bgrParShift = crossSectionParShift + crossSectionHandler->parNum();
01252 MuScleFitUtils::backgroundHandler->setParameters( &(Start[bgrParShift]), &(Step[bgrParShift]), &(Mini[bgrParShift]), &(Maxi[bgrParShift]),
01253 &(ind[bgrParShift]), &(parname[bgrParShift]), parBgr, parBgrOrder, MuonType );
01254
01255 for( int ipar=0; ipar<parnumber; ++ipar ) {
01256 std::cout << "parname["<<ipar<<"] = " << parname[ipar] << std::endl;
01257 std::cout << "Start["<<ipar<<"] = " << Start[ipar] << std::endl;
01258 std::cout << "Step["<<ipar<<"] = " << Step[ipar] << std::endl;
01259 std::cout << "Mini["<<ipar<<"] = " << Mini[ipar] << std::endl;
01260 std::cout << "Maxi["<<ipar<<"] = " << Maxi[ipar] << std::endl;
01261
01262
01263 rmin.mnparm( ipar, parname[ipar], Start[ipar], Step[ipar], Mini[ipar], Maxi[ipar], ierror );
01264
01265
01266
01267
01268
01269
01270 }
01271
01272
01273
01274 if (debug>19)
01275 std::cout << "[MuScleFitUtils-minimizeLikelihood]: Starting minimization" << std::endl;
01276 double fmin;
01277 double fdem;
01278 double errdef;
01279 int npari;
01280 int nparx;
01281 rmin.mnexcm ("call fcn", arglis, 1, ierror);
01282
01283
01284
01285 if (debug>19)
01286 std::cout << "[MuScleFitUtils-minimizeLikelihood]: First fix all parameters ...";
01287 for (int ipar=0; ipar<parnumber; ipar++) {
01288 rmin.FixParameter (ipar);
01289 }
01290
01291
01292
01293 if (debug>19) std::cout << " Then release them in order..." << std::endl;
01294
01295 TString name;
01296 double pval;
01297 double pmin;
01298 double pmax;
01299 double errp;
01300 double errl;
01301 double errh;
01302 int ivar;
01303 double erro;
01304 double cglo;
01305 int n_times = 0;
01306
01307
01308 if (debug>19) std::cout << "Before scale parNum" << std::endl;
01309 int scaleParNum = scaleFunction->parNum();
01310 if (debug>19) std::cout << "After scale parNum" << std::endl;
01311
01312
01313
01314
01315 std::cout << "number of parameters for scaleFunction = " << scaleParNum << std::endl;
01316 std::cout << "number of parameters for resolutionFunction = " << resParNum << std::endl;
01317 std::cout << "number of parameters for cross section = " << crossSectionHandler->parNum() << std::endl;
01318 std::cout << "number of parameters for backgroundFunction = " << parBgr.size() << std::endl;
01319
01320
01321 for (int i=0; i<parnumber; i++) {
01322
01323 if (n_times<ind[i]) {
01324 edm::LogInfo("minimizeLikelihood") << "n_times = " << n_times << ", ind["<<i<<"] = " << ind[i] << ", scaleParNum = " << scaleParNum << ", doScaleFit["<<loopCounter<<"] = " << doScaleFit[loopCounter] << std::endl;
01325
01326 if ( i<resParNum ) {
01327 if( doResolFit[loopCounter] ) n_times = ind[i];
01328 }
01329 else if( i<resParNum+scaleParNum ) {
01330 if( doScaleFit[loopCounter] ) n_times = ind[i];
01331 }
01332 else if( doBackgroundFit[loopCounter] ) n_times = ind[i];
01333 }
01334 }
01335 for (int iorder=0; iorder<n_times+1; iorder++) {
01336 std::cout << "Starting minimization " << iorder << " of " << n_times << std::endl;
01337
01338 bool somethingtodo = false;
01339
01340
01341
01342 if( doResolFit[loopCounter] ) {
01343
01344
01345 for( unsigned int ipar=0; ipar<parResol.size(); ++ipar ) {
01346 if( parfix[ipar]==0 && ind[ipar]==iorder ) {
01347 rmin.Release( ipar );
01348 somethingtodo = true;
01349 }
01350 }
01351 }
01352 if( doScaleFit[loopCounter] ) {
01353
01354
01355 for( unsigned int ipar=parResol.size(); ipar<parResol.size()+parScale.size(); ++ipar ) {
01356 if( parfix[ipar]==0 && ind[ipar]==iorder ) {
01357 rmin.Release( ipar );
01358 somethingtodo = true;
01359 }
01360 }
01361 scaleFitNotDone_ = false;
01362 }
01363 unsigned int crossSectionParShift = parResol.size()+parScale.size();
01364 if( doCrossSectionFit[loopCounter] ) {
01365
01366
01367
01368 bool doCrossSection = crossSectionHandler->releaseParameters( rmin, resfind, parfix, ind, iorder, crossSectionParShift );
01369 if( doCrossSection ) somethingtodo = true;
01370 }
01371 if( doBackgroundFit[loopCounter] ) {
01372
01373
01374
01375
01376 unsigned int bgrParShift = crossSectionParShift+crossSectionHandler->parNum();
01377 for( unsigned int ipar = bgrParShift; ipar < bgrParShift+backgroundHandler->regionsParNum(); ++ipar ) {
01378
01379 if( parfix[ipar]==0 && ind[ipar]==iorder && backgroundHandler->unlockParameter(resfind, ipar - bgrParShift) ) {
01380 rmin.Release( ipar );
01381 somethingtodo = true;
01382 }
01383 }
01384 }
01385
01386
01387
01388 if( somethingtodo ) {
01389
01390
01391 std::stringstream fileNum;
01392 fileNum << loopCounter;
01393
01394 minuitLoop_ = 0;
01395 char name[50];
01396 sprintf(name, "likelihoodInLoop_%d_%d", loopCounter, iorder);
01397 TH1D * tempLikelihoodInLoop = new TH1D(name, "likelihood value in minuit loop", 10000, 0, 10000);
01398 likelihoodInLoop_ = tempLikelihoodInLoop;
01399 char signalProbName[50];
01400 sprintf(signalProbName, "signalProb_%d_%d", loopCounter, iorder);
01401 TH1D * tempSignalProb = new TH1D(signalProbName, "signal probability", 10000, 0, 10000);
01402 signalProb_ = tempSignalProb;
01403 char backgroundProbName[50];
01404 sprintf(backgroundProbName, "backgroundProb_%d_%d", loopCounter, iorder);
01405 TH1D * tempBackgroundProb = new TH1D(backgroundProbName, "background probability", 10000, 0, 10000);
01406 backgroundProb_ = tempBackgroundProb;
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416 double protectionFactor = 0.9;
01417
01418 MuScleFitUtils::ReducedSavedPair.clear();
01419 for( unsigned int nev=0; nev<MuScleFitUtils::SavedPair.size(); ++nev ) {
01420 const lorentzVector * recMu1 = &(MuScleFitUtils::SavedPair[nev].first);
01421 const lorentzVector * recMu2 = &(MuScleFitUtils::SavedPair[nev].second);
01422 double mass = MuScleFitUtils::invDimuonMass( *recMu1, *recMu2 );
01423
01424 bool check = false;
01425 for( int ires = 0; ires < 6; ++ires ) {
01426
01427 std::pair<double, double> windowBorder = backgroundHandler->windowBorders( doBackgroundFit[loopCounter], ires );
01428
01429
01430 double resMassValue = backgroundHandler->resMass( doBackgroundFit[loopCounter], ires );
01431 double windowBorderLeft = resMassValue - protectionFactor*(resMassValue - windowBorder.first);
01432 double windowBorderRight = resMassValue + protectionFactor*(windowBorder.second - resMassValue);
01433 if( resfind[ires] && checkMassWindow( mass, windowBorderLeft, windowBorderRight ) ) {
01434 check = true;
01435 }
01436 }
01437 if( check ) {
01438 MuScleFitUtils::ReducedSavedPair.push_back(std::make_pair(*recMu1, *recMu2));
01439 }
01440 }
01441 std::cout << "Fitting with " << MuScleFitUtils::ReducedSavedPair.size() << " events" << std::endl;
01442
01443
01444
01445
01446 MuScleFitUtils::normalizationChanged_ = 0;
01447
01448
01449 arglis[0] = 5000;
01450
01451
01452 if( startWithSimplex_ ) {
01453 rmin.mnexcm( "simplex", arglis, 0, ierror );
01454 }
01455
01456 rmin.mnexcm( "mini", arglis, 0, ierror );
01457
01458
01459
01460 likelihoodInLoop_->Write();
01461 signalProb_->Write();
01462 backgroundProb_->Write();
01463 delete tempLikelihoodInLoop;
01464 delete tempSignalProb;
01465 delete tempBackgroundProb;
01466 likelihoodInLoop_ = 0;
01467 signalProb_ = 0;
01468 backgroundProb_ = 0;
01469
01470
01471
01472
01473 rmin.mnexcm( "hesse", arglis, 0, ierror );
01474
01475
01476 if( computeMinosErrors_ ) {
01477 duringMinos_ = true;
01478 rmin.mnexcm( "minos", arglis, 0, ierror );
01479 duringMinos_ = false;
01480 }
01481
01482 if( normalizationChanged_ > 1 ) {
01483 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;
01484 }
01485 }
01486
01487
01488 for (int ipar=0; ipar<parnumber; ipar++) {
01489
01490 rmin.mnpout (ipar, name, pval, erro, pmin, pmax, ivar);
01491
01492
01493 if (ierror!=0 && debug>0) {
01494 std::cout << "[MuScleFitUtils-minimizeLikelihood]: ierror!=0, bogus pars" << std::endl;
01495 }
01496
01497
01498 parvalue[loopCounter][ipar] = pval;
01499
01500
01501
01502
01503
01504
01505 rmin.mnerrs (ipar, errh, errl, errp, cglo);
01506
01507
01508
01509
01510 if (errp!=0) {
01511 parerr[3*ipar] = errp;
01512 } else {
01513 parerr[3*ipar] = (((errh)>(fabs(errl)))?(errh):(fabs(errl)));
01514 }
01515 parerr[3*ipar+1] = errl;
01516 parerr[3*ipar+2] = errh;
01517
01518 if( ipar == 0 ) {
01519 FitParametersFile << " Resolution fit parameters:" << std::endl;
01520 }
01521 if( ipar == int(parResol.size()) ) {
01522 FitParametersFile << " Scale fit parameters:" << std::endl;
01523 }
01524 if( ipar == int(parResol.size()+parScale.size()) ) {
01525 FitParametersFile << " Cross section fit parameters:" << std::endl;
01526 }
01527 if( ipar == int(parResol.size()+parScale.size()+crossSectionHandler->parNum()) ) {
01528 FitParametersFile << " Background fit parameters:" << std::endl;
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544 FitParametersFile << " Results of the fit: parameter " << ipar << " has value "
01545 << pval << "+-" << parerr[3*ipar]
01546 << " + " << parerr[3*ipar+1] << " - " << parerr[3*ipar+2]
01547
01548 << std::endl;
01549
01550 }
01551 rmin.mnstat (fmin, fdem, errdef, npari, nparx, istat);
01552 FitParametersFile << std::endl;
01553
01554 if( minimumShapePlots_ ) {
01555
01556
01557
01558 if( somethingtodo ) {
01559 std::stringstream iorderString;
01560 iorderString << iorder;
01561 std::stringstream iLoopString;
01562 iLoopString << loopCounter;
01563
01564 for (int ipar=0; ipar<parnumber; ipar++) {
01565 if( parfix[ipar] == 1 ) continue;
01566 std::cout << "plotting parameter = " << ipar+1 << std::endl;
01567 std::stringstream iparString;
01568 iparString << ipar+1;
01569 rmin.mncomd( ("scan "+iparString.str()).c_str(), ierror );
01570 if( ierror == 0 ) {
01571 TCanvas * canvas = new TCanvas(("likelihoodCanvas_loop_"+iLoopString.str()+"_oder_"+iorderString.str()+"_par_"+iparString.str()).c_str(), ("likelihood_"+iparString.str()).c_str(), 1000, 800);
01572 canvas->cd();
01573
01574
01575 TGraph * graph = (TGraph*)rmin.GetPlot();
01576 graph->Draw("AP");
01577
01578 graph->SetTitle(parname[ipar]);
01579
01580
01581 canvas->Write();
01582 }
01583 }
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596 }
01597 }
01598
01599 }
01600 FitParametersFile.close();
01601
01602 std::cout << "[MuScleFitUtils-minimizeLikelihood]: Parameters after likelihood " << std::endl;
01603 for (unsigned int ipar=0; ipar<(unsigned int)parnumber; ipar++) {
01604 std::cout << ipar << " " << parvalue[loopCounter][ipar] << " : free = "
01605 << parfix[ipar] << "; order = " << parorder[ipar] << std::endl;
01606 }
01607
01608
01609
01610 for( int i=0; i<(int)(parResol.size()); ++i ) {
01611 parResol[i] = parvalue[loopCounter][i];
01612 }
01613 for( int i=0; i<(int)(parScale.size()); ++i ) {
01614 parScale[i] = parvalue[loopCounter][i+parResol.size()];
01615 }
01616 parCrossSection = crossSectionHandler->relativeCrossSections(&(parvalue[loopCounter][parResol.size()+parScale.size()]), resfind);
01617 for( unsigned int i=0; i<parCrossSection.size(); ++i ) {
01618
01619 std::cout << "relative cross section["<<i<<"] = " << parCrossSection[i] << std::endl;
01620 }
01621
01622 for( unsigned int i = 0; i<(parBgr.size() - parForResonanceWindows); ++i ) {
01623 parBgr[i] = parvalue[loopCounter][i+parResol.size()+parScale.size()+crossSectionHandler->parNum()];
01624 }
01625
01626
01627
01628
01629 if( doBackgroundFit[loopCounter] ) {
01630
01631 int localMuonType = MuonType;
01632 if( MuonType > 2 ) localMuonType = 2;
01633 backgroundHandler->rescale( parBgr, ResMass, massWindowHalfWidth[localMuonType],
01634 MuScleFitUtils::ReducedSavedPair );
01635 }
01636
01637
01638 delete[] Start;
01639 delete[] Step;
01640 delete[] Mini;
01641 delete[] Maxi;
01642 delete[] ind;
01643 delete[] parname;
01644 }
01645
01646
01647
01648 extern "C" void likelihood( int& npar, double* grad, double& fval, double* xval, int flag ) {
01649
01650 if (MuScleFitUtils::debug>19) std::cout << "[MuScleFitUtils-likelihood]: In likelihood function" << std::endl;
01651
01652 const lorentzVector * recMu1;
01653 const lorentzVector * recMu2;
01654 lorentzVector corrMu1;
01655 lorentzVector corrMu2;
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669 double flike = 0;
01670 int evtsinlik = 0;
01671 int evtsoutlik = 0;
01672
01673 if( MuScleFitUtils::debug>0 ) {
01674 std::cout << "SavedPair.size() = " << MuScleFitUtils::SavedPair.size() << std::endl;
01675 std::cout << "ReducedSavedPair.size() = " << MuScleFitUtils::ReducedSavedPair.size() << std::endl;
01676 }
01677
01678 for( unsigned int nev=0; nev<MuScleFitUtils::ReducedSavedPair.size(); ++nev ) {
01679
01680
01681
01682 recMu1 = &(MuScleFitUtils::ReducedSavedPair[nev].first);
01683 recMu2 = &(MuScleFitUtils::ReducedSavedPair[nev].second);
01684
01685
01686
01687 double mass = MuScleFitUtils::invDimuonMass( *recMu1, *recMu2 );
01688
01689
01690
01691 double weight = MuScleFitUtils::computeWeight(mass, MuScleFitUtils::iev_);
01692 if( weight!=0. ) {
01693
01694
01695 if( MuScleFitUtils::doScaleFit[MuScleFitUtils::loopCounter] ) {
01696
01697
01698 corrMu1 = MuScleFitUtils::applyScale(*recMu1, xval, -1);
01699 corrMu2 = MuScleFitUtils::applyScale(*recMu2, xval, 1);
01700
01701
01702
01703
01704
01705
01706
01707 }
01708 else {
01709 corrMu1 = *recMu1;
01710 corrMu2 = *recMu2;
01711
01712
01713
01714
01715
01716 }
01717 double corrMass = MuScleFitUtils::invDimuonMass(corrMu1, corrMu2);
01718 double Y = (corrMu1+corrMu2).Rapidity();
01719 double resEta = (corrMu1+corrMu2).Eta();
01720 if( MuScleFitUtils::debug>19 ) {
01721 std::cout << "[MuScleFitUtils-likelihood]: Original/Corrected resonance mass = " << mass
01722 << " / " << corrMass << std::endl;
01723 }
01724
01725
01726
01727 double massResol = MuScleFitUtils::massResolution(corrMu1, corrMu2, xval);
01728 if (MuScleFitUtils::debug>19)
01729 std::cout << "[MuScleFitUtils-likelihood]: Resolution is " << massResol << std::endl;
01730
01731
01732
01733 if (MuScleFitUtils::debug>1) std::cout << "calling massProb inside likelihood function" << std::endl;
01734
01735 double prob = MuScleFitUtils::massProb( corrMass, resEta, Y, massResol, xval );
01736 if (MuScleFitUtils::debug>1) std::cout << "likelihood:massProb = " << prob << std::endl;
01737
01738
01739
01740 if( prob>0 ) {
01741
01742 flike += log(prob)*weight;
01743 evtsinlik += 1;
01744 } else {
01745 if( MuScleFitUtils::debug > 0 ) {
01746 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;
01747 std::cout << "Original mass was = " << mass << std::endl;
01748 std::cout << "WARNING: massResol = " << massResol << " outside window" << std::endl;
01749 }
01750 evtsoutlik += 1;
01751 }
01752 if (MuScleFitUtils::debug>19)
01753 std::cout << "[MuScleFitUtils-likelihood]: Mass probability = " << prob << std::endl;
01754 }
01755
01756 }
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776 if( evtsinlik != 0 ) {
01777
01778 if( MuScleFitUtils::normalizeLikelihoodByEventNumber_ ) {
01779
01780 if( MuScleFitUtils::rminPtr_ == 0 ) {
01781 std::cout << "ERROR: rminPtr_ = " << MuScleFitUtils::rminPtr_ << ", code will crash" << std::endl;
01782 }
01783 double normalizationArg[] = {1/double(evtsinlik)};
01784
01785 if( MuScleFitUtils::oldNormalization_ != normalizationArg[0] ) {
01786 int ierror = 0;
01787
01788
01789
01790
01791
01792 MuScleFitUtils::rminPtr_->mnexcm("SET ERR", normalizationArg, 1, ierror);
01793 std::cout << "oldNormalization = " << MuScleFitUtils::oldNormalization_ << " new = " << normalizationArg[0] << std::endl;
01794 MuScleFitUtils::oldNormalization_ = normalizationArg[0];
01795 MuScleFitUtils::normalizationChanged_ += 1;
01796 }
01797 fval = -2.*flike/double(evtsinlik);
01798
01799
01800
01801
01802 }
01803 else {
01804 fval = -2.*flike;
01805 }
01806 }
01807 else {
01808 std::cout << "Problem: Events in likelihood = " << evtsinlik << std::endl;
01809 fval = 999999999.;
01810 }
01811
01812 if (MuScleFitUtils::debug>19)
01813 std::cout << "[MuScleFitUtils-likelihood]: End tree loop with likelihood value = " << fval << std::endl;
01814
01815
01816
01817 if( MuScleFitUtils::minuitLoop_ < 10000 ) {
01818 if( MuScleFitUtils::likelihoodInLoop_ != 0 ) {
01819 ++MuScleFitUtils::minuitLoop_;
01820 MuScleFitUtils::likelihoodInLoop_->SetBinContent(MuScleFitUtils::minuitLoop_, fval);
01821 }
01822 }
01823
01824
01825 if( MuScleFitUtils::debug > 0 ) {
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836 std::cout << "Events in likelihood = " << evtsinlik << std::endl;
01837 std::cout << "Events out likelihood = " << evtsoutlik << std::endl;
01838 }
01839
01840
01841 }
01842
01843
01844
01845 std::vector<TGraphErrors*> MuScleFitUtils::fitMass (TH2F* histo) {
01846
01847 if (MuScleFitUtils::debug>0) std::cout << "Fitting " << histo->GetName() << std::endl;
01848
01849 std::vector<TGraphErrors *> results;
01850
01851
01852
01853 std::vector<double> Ftop;
01854 std::vector<double> Fwidth;
01855 std::vector<double> Fmass;
01856 std::vector<double> Etop;
01857 std::vector<double> Ewidth;
01858 std::vector<double> Emass;
01859 std::vector<double> Fchi2;
01860
01861
01862 std::vector<double> Xcenter;
01863 std::vector<double> Ex;
01864
01865
01866
01867 TF1 *fitFcn = new TF1 ("fitFcn", lorentzianPeak, 70, 110, 3);
01868 fitFcn->SetParameters (100, 3, 91);
01869 fitFcn->SetParNames ("Ftop", "Fwidth", "Fmass");
01870 fitFcn->SetLineWidth (2);
01871
01872
01873
01874 double cont_min = 20;
01875 Int_t binx = histo->GetXaxis()->GetNbins();
01876
01877
01878 for (int i=1; i<=binx; i++) {
01879 TH1 * histoY = histo->ProjectionY ("", i, i);
01880
01881 double cont = histoY->GetEntries();
01882 if (cont>cont_min) {
01883 histoY->Fit ("fitFcn", "0", "", 70, 110);
01884 double *par = fitFcn->GetParameters();
01885 double *err = fitFcn->GetParErrors();
01886
01887 Ftop.push_back(par[0]);
01888 Fwidth.push_back(par[1]);
01889 Fmass.push_back(par[2]);
01890 Etop.push_back(err[0]);
01891 Ewidth.push_back(err[1]);
01892 Emass.push_back(err[2]);
01893
01894 double chi2 = fitFcn->GetChisquare();
01895 Fchi2.push_back(chi2);
01896
01897 double xx = histo->GetXaxis()->GetBinCenter(i);
01898 Xcenter.push_back(xx);
01899 double ex = 0;
01900 Ex.push_back(ex);
01901 }
01902 }
01903
01904
01905
01906
01907 const int nn = Fmass.size();
01908 double *x = new double[nn];
01909 double *ym = new double[nn];
01910 double *e = new double[nn];
01911 double *eym = new double[nn];
01912 double *yw = new double[nn];
01913 double *eyw = new double[nn];
01914 double *yc = new double[nn];
01915
01916 for (int j=0; j<nn; j++) {
01917 x[j] = Xcenter[j];
01918 ym[j] = Fmass[j];
01919 eym[j] = Emass[j];
01920 yw[j] = Fwidth[j];
01921 eyw[j] = Ewidth[j];
01922 yc[j] = Fchi2[j];
01923 e[j] = Ex[j];
01924 }
01925
01926
01927
01928 TString name = histo->GetName();
01929 TGraphErrors *grM = new TGraphErrors (nn, x, ym, e, eym);
01930 grM->SetTitle (name+"_M");
01931 grM->SetName (name+"_M");
01932 TGraphErrors *grW = new TGraphErrors (nn, x, yw, e, eyw);
01933 grW->SetTitle (name+"_W");
01934 grW->SetName (name+"_W");
01935 TGraphErrors *grC = new TGraphErrors (nn, x, yc, e, e);
01936 grC->SetTitle (name+"_chi2");
01937 grC->SetName (name+"_chi2");
01938
01939
01940
01941 delete x;
01942 delete ym;
01943 delete eym;
01944 delete yw;
01945 delete eyw;
01946 delete yc;
01947 delete e;
01948 delete fitFcn;
01949
01950 results.push_back(grM);
01951 results.push_back(grW);
01952 results.push_back(grC);
01953 return results;
01954 }
01955
01956
01957
01958 std::vector<TGraphErrors*> MuScleFitUtils::fitReso (TH2F* histo) {
01959 std::cout << "Fitting " << histo->GetName() << std::endl;
01960 std::vector<TGraphErrors *> results;
01961
01962
01963
01964 std::vector<double> maxs;
01965 std::vector<double> means;
01966 std::vector<double> sigmas;
01967 std::vector<double> chi2s;
01968 std::vector<double> Emaxs;
01969 std::vector<double> Emeans;
01970 std::vector<double> Esigmas;
01971
01972
01973
01974 std::vector<double> Xcenter;
01975 std::vector<double> Ex;
01976
01977
01978
01979 TF1 *fitFcn = new TF1 ("fitFunc", Gaussian, -0.2, 0.2, 3);
01980 fitFcn->SetParameters (100, 0, 0.02);
01981 fitFcn->SetParNames ("max", "mean", "sigma");
01982 fitFcn->SetLineWidth (2);
01983
01984
01985
01986 double cont_min = 20;
01987 Int_t binx = histo->GetXaxis()->GetNbins();
01988 for (int i=1; i<=binx; i++) {
01989 TH1 * histoY = histo->ProjectionY ("", i, i);
01990 double cont = histoY->GetEntries();
01991 if (cont>cont_min) {
01992 histoY->Fit ("fitFunc", "0", "", -0.2, 0.2);
01993 double *par = fitFcn->GetParameters();
01994 double *err = fitFcn->GetParErrors();
01995
01996 maxs.push_back (par[0]);
01997 means.push_back (par[1]);
01998 sigmas.push_back (par[2]);
01999 Emaxs.push_back (err[0]);
02000 Emeans.push_back (err[1]);
02001 Esigmas.push_back (err[2]);
02002
02003 double chi2 = fitFcn->GetChisquare();
02004 chi2s.push_back (chi2);
02005
02006 double xx = histo->GetXaxis()->GetBinCenter(i);
02007 Xcenter.push_back (xx);
02008 double ex = 0;
02009 Ex.push_back (ex);
02010 }
02011 }
02012
02013
02014
02015 const int nn = means.size();
02016 double *x = new double[nn];
02017 double *ym = new double[nn];
02018 double *e = new double[nn];
02019 double *eym = new double[nn];
02020 double *yw = new double[nn];
02021 double *eyw = new double[nn];
02022 double *yc = new double[nn];
02023
02024 for (int j=0; j<nn; j++) {
02025 x[j] = Xcenter[j];
02026 ym[j] = means[j];
02027 eym[j] = Emeans[j];
02028
02029
02030 yw[j] = sigmas[j];
02031 eyw[j] = Esigmas[j];
02032 yc[j] = chi2s[j];
02033 e[j] = Ex[j];
02034 }
02035
02036
02037
02038 TString name = histo->GetName();
02039 TGraphErrors *grM = new TGraphErrors (nn, x, ym, e, eym);
02040 grM->SetTitle (name+"_mean");
02041 grM->SetName (name+"_mean");
02042 TGraphErrors *grW = new TGraphErrors (nn, x, yw, e, eyw);
02043 grW->SetTitle (name+"_sigma");
02044 grW->SetName (name+"_sigma");
02045 TGraphErrors *grC = new TGraphErrors (nn, x, yc, e, e);
02046 grC->SetTitle (name+"_chi2");
02047 grC->SetName (name+"_chi2");
02048
02049
02050
02051 delete x;
02052 delete ym;
02053 delete eym;
02054 delete yw;
02055 delete eyw;
02056 delete yc;
02057 delete e;
02058 delete fitFcn;
02059
02060 results.push_back (grM);
02061 results.push_back (grW);
02062 results.push_back (grC);
02063 return results;
02064 }
02065
02066
02067
02068 double MuScleFitUtils::massProb( const double & mass, const double & rapidity, const int ires, const double & massResol )
02069 {
02070
02071
02072
02073
02074 double P = 0.;
02075
02076
02077
02078 if (massResol==0.) {
02079 if (debug>9) std::cout << "Mass, gamma , mref, width, P: " << mass
02080 << " " << ResGamma[ires] << " " << ResMass[ires]<< " " << massResol
02081 << " : used Lorentz P-value" << std::endl;
02082 return (0.5*ResGamma[ires]/TMath::Pi())/((mass-ResMass[ires])*(mass-ResMass[ires])+
02083 .25*ResGamma[ires]*ResGamma[ires]);
02084 }
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101 Int_t np = 100;
02102 double * x = new double[np];
02103 double * w = new double[np];
02104 GL->SetParameters (ResGamma[ires], ResMass[ires], mass, massResol);
02105 GL->CalcGaussLegendreSamplingPoints (np, x, w, 0.1e-15);
02106 P = GL->IntegralFast (np, x, w, ResMass[ires]-10*ResGamma[ires], ResMass[ires]+10*ResGamma[ires]);
02107 delete[] x;
02108 delete[] w;
02109
02110
02111
02112 if (P<1.0e-12) {
02113 P = 1.0e-12;
02114 if (debug>9) std::cout << "Mass, gamma , mref, width, P: " << mass
02115 << " " << ResGamma[ires] << " " << ResMass[ires] << " " << massResol
02116 << ": used epsilon" << std::endl;
02117 return P;
02118 }
02119
02120 if (debug>9) std::cout << "Mass, gamma , mref, width, P: " << mass
02121 << " " << ResGamma[ires] << " " << ResMass[ires] << " " << massResol
02122 << " " << P << std::endl;
02123 return P;
02124 }
02125
02126 std::pair<lorentzVector, lorentzVector> MuScleFitUtils::findSimMuFromRes( const edm::Handle<edm::HepMCProduct> & evtMC,
02127 const edm::Handle<edm::SimTrackContainer> & simTracks )
02128 {
02129
02130 std::pair<lorentzVector, lorentzVector> simMuFromRes;
02131 for( edm::SimTrackContainer::const_iterator simTrack=simTracks->begin(); simTrack!=simTracks->end(); ++simTrack ) {
02132
02133 if (fabs((*simTrack).type())==13) {
02134
02135 if ((*simTrack).genpartIndex()>0) {
02136 HepMC::GenParticle* gp = evtMC->GetEvent()->barcode_to_particle ((*simTrack).genpartIndex());
02137 if( gp != 0 ) {
02138
02139 for (HepMC::GenVertex::particle_iterator mother = gp->production_vertex()->particles_begin(HepMC::ancestors);
02140 mother!=gp->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
02141
02142 bool fromRes = false;
02143 unsigned int motherPdgId = (*mother)->pdg_id();
02144 for( int ires = 0; ires < 6; ++ires ) {
02145 if( motherPdgId == motherPdgIdArray[ires] && resfind[ires] ) fromRes = true;
02146 }
02147 if( fromRes ) {
02148 if(gp->pdg_id() == 13)
02149 simMuFromRes.first = lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
02150 simTrack->momentum().pz(),simTrack->momentum().e());
02151 else
02152 simMuFromRes.second = lorentzVector(simTrack->momentum().px(),simTrack->momentum().py(),
02153 simTrack->momentum().pz(),simTrack->momentum().e());
02154 }
02155 }
02156 }
02157
02158 }
02159 }
02160 }
02161 return simMuFromRes;
02162 }
02163
02164 std::pair<lorentzVector, lorentzVector> MuScleFitUtils::findGenMuFromRes( const edm::HepMCProduct* evtMC )
02165 {
02166 const HepMC::GenEvent* Evt = evtMC->GetEvent();
02167 std::pair<lorentzVector,lorentzVector> muFromRes;
02168
02169 for (HepMC::GenEvent::particle_const_iterator part=Evt->particles_begin();
02170 part!=Evt->particles_end(); part++) {
02171 if (fabs((*part)->pdg_id())==13 && (*part)->status()==1) {
02172 bool fromRes = false;
02173 for (HepMC::GenVertex::particle_iterator mother = (*part)->production_vertex()->particles_begin(HepMC::ancestors);
02174 mother != (*part)->production_vertex()->particles_end(HepMC::ancestors); ++mother) {
02175 unsigned int motherPdgId = (*mother)->pdg_id();
02176
02177
02178
02179 if( sherpa_ ) {
02180 if( motherPdgId == 13 && (*mother)->status() == 3 ) fromRes = true;
02181 }
02182 else {
02183 for( int ires = 0; ires < 6; ++ires ) {
02184 if( motherPdgId == motherPdgIdArray[ires] && resfind[ires] ) fromRes = true;
02185 }
02186 }
02187 }
02188 if(fromRes){
02189 if((*part)->pdg_id()==13)
02190
02191 muFromRes.first = (lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
02192 (*part)->momentum().pz(),(*part)->momentum().e()));
02193 else
02194 muFromRes.second = (lorentzVector((*part)->momentum().px(),(*part)->momentum().py(),
02195 (*part)->momentum().pz(),(*part)->momentum().e()));
02196 }
02197 }
02198 }
02199 return muFromRes;
02200 }
02201
02202 std::pair<lorentzVector, lorentzVector> MuScleFitUtils::findGenMuFromRes( const reco::GenParticleCollection* genParticles)
02203 {
02204 std::pair<lorentzVector,lorentzVector> muFromRes;
02205
02206
02207 if( debug>0 ) std::cout << "Starting loop on " << genParticles->size() << " genParticles" << std::endl;
02208 for( reco::GenParticleCollection::const_iterator part=genParticles->begin(); part!=genParticles->end(); ++part ) {
02209 if (fabs(part->pdgId())==13 && part->status()==1) {
02210 bool fromRes = false;
02211 unsigned int motherPdgId = part->mother()->pdgId();
02212 if( debug>0 ) {
02213 std::cout << "Found a muon with mother: " << motherPdgId << std::endl;
02214 }
02215 for( int ires = 0; ires < 6; ++ires ) {
02216 if( motherPdgId == motherPdgIdArray[ires] && resfind[ires] ) fromRes = true;
02217 }
02218 if(fromRes){
02219 if(part->pdgId()==13) {
02220 muFromRes.first = part->p4();
02221 if( debug>0 ) std::cout << "Found a genMuon + : " << muFromRes.first << std::endl;
02222
02223
02224 }
02225 else {
02226 muFromRes.second = part->p4();
02227 if( debug>0 ) std::cout << "Found a genMuon - : " << muFromRes.second << std::endl;
02228
02229
02230 }
02231 }
02232 }
02233 }
02234 return muFromRes;
02235 }