CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/HiggsAnalysis/CombinedLimit/src/PdfDiagonalizer.cc

Go to the documentation of this file.
00001 #include "../interface/PdfDiagonalizer.h"
00002 
00003 #include <cstdio>
00004 #include <TMatrixDSym.h>
00005 #include <TMatrixDSymEigen.h>
00006 #include <RooAbsPdf.h>
00007 #include <RooAddition.h>
00008 #include <RooCustomizer.h>
00009 #include <RooFitResult.h>
00010 #include <RooRealVar.h>
00011 #include <RooWorkspace.h>
00012 
00013 PdfDiagonalizer::PdfDiagonalizer(const char *name, RooWorkspace *w, RooFitResult &result) :
00014     name_(name),
00015     parameters_(result.floatParsFinal())
00016 {
00017     int n = parameters_.getSize();
00018 
00019     TMatrixDSym cov(result.covarianceMatrix()); 
00020     TMatrixDSymEigen eigen(cov);
00021 
00022     const TMatrixD& vectors = eigen.GetEigenVectors();
00023     const TVectorD& values  = eigen.GetEigenValues();
00024 
00025     char buff[10240];
00026 
00027     // create unit gaussians per eigen-vector
00028     for (int i = 0; i < n; ++i) {
00029         snprintf(buff,sizeof(buff),"%s_eig%d[-5,5]", name, i);
00030         eigenVars_.add(*w->factory(buff));
00031     }
00032     // put them in a list, with a one at the end to set the mean
00033     RooArgList eigvVarsPlusOne(eigenVars_);
00034     if (w->var("_one_") == 0) w->factory("_one_[1]");
00035     eigvVarsPlusOne.add(*w->var("_one_"));
00036 
00037     // then go create the linear combinations
00038     // each is equal to the transpose matrx times the square root of the eigenvalue (so that we get unit gaussians)
00039     for (int i = 0; i < n; ++i) {   
00040         RooArgList coeffs;
00041         for (int j = 0; j < n; ++j) {
00042             snprintf(buff,sizeof(buff),"%s_eigCoeff_%d_%d[%g]", name, i, j, vectors(i,j)*sqrt(values(j)));
00043             coeffs.add(*w->factory(buff)); 
00044         }
00045         snprintf(buff,sizeof(buff),"%s_eigBase_%d[%g]", name, i, (dynamic_cast<RooAbsReal*>(parameters_.at(i)))->getVal());
00046         coeffs.add(*w->factory(buff)); 
00047         snprintf(buff,sizeof(buff),"%s_eigLin_%d", name, i);
00048         RooAddition *add = new RooAddition(buff,buff,coeffs,eigvVarsPlusOne);
00049         w->import(*add);
00050         replacements_.add(*add);
00051     }
00052 }
00053 
00054 RooAbsPdf *PdfDiagonalizer::diagonalize(RooAbsPdf &pdf)
00055 {
00056     if (!pdf.dependsOn(parameters_)) return 0;
00057 
00058     // now do the customization
00059     RooCustomizer custom(pdf, name_.c_str());
00060     for (int i = 0, n = parameters_.getSize(); i < n; ++i) { 
00061         if (pdf.dependsOn(*parameters_.at(i))) {
00062             custom.replaceArg(*parameters_.at(i), *replacements_.at(i));
00063         }
00064     }
00065 
00066     RooAbsPdf *ret = dynamic_cast<RooAbsPdf *>(custom.build());
00067     ret->SetName((std::string(pdf.GetName()) + "_" + name_).c_str());
00068     return ret;
00069 }