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
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
00033 RooArgList eigvVarsPlusOne(eigenVars_);
00034 if (w->var("_one_") == 0) w->factory("_one_[1]");
00035 eigvVarsPlusOne.add(*w->var("_one_"));
00036
00037
00038
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
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 }