CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PdfDiagonalizer.cc
Go to the documentation of this file.
1 #include "../interface/PdfDiagonalizer.h"
2 
3 #include <cstdio>
4 #include <TMatrixDSym.h>
5 #include <TMatrixDSymEigen.h>
6 #include <RooAbsPdf.h>
7 #include <RooAddition.h>
8 #include <RooCustomizer.h>
9 #include <RooFitResult.h>
10 #include <RooRealVar.h>
11 #include <RooWorkspace.h>
12 
13 PdfDiagonalizer::PdfDiagonalizer(const char *name, RooWorkspace *w, RooFitResult &result) :
14  name_(name),
15  parameters_(result.floatParsFinal())
16 {
17  int n = parameters_.getSize();
18 
19  TMatrixDSym cov(result.covarianceMatrix());
20  TMatrixDSymEigen eigen(cov);
21 
22  const TMatrixD& vectors = eigen.GetEigenVectors();
23  const TVectorD& values = eigen.GetEigenValues();
24 
25  char buff[10240];
26 
27  // create unit gaussians per eigen-vector
28  for (int i = 0; i < n; ++i) {
29  snprintf(buff,sizeof(buff),"%s_eig%d[-5,5]", name, i);
30  eigenVars_.add(*w->factory(buff));
31  }
32  // put them in a list, with a one at the end to set the mean
33  RooArgList eigvVarsPlusOne(eigenVars_);
34  if (w->var("_one_") == 0) w->factory("_one_[1]");
35  eigvVarsPlusOne.add(*w->var("_one_"));
36 
37  // then go create the linear combinations
38  // each is equal to the transpose matrx times the square root of the eigenvalue (so that we get unit gaussians)
39  for (int i = 0; i < n; ++i) {
40  RooArgList coeffs;
41  for (int j = 0; j < n; ++j) {
42  snprintf(buff,sizeof(buff),"%s_eigCoeff_%d_%d[%g]", name, i, j, vectors(i,j)*sqrt(values(j)));
43  coeffs.add(*w->factory(buff));
44  }
45  snprintf(buff,sizeof(buff),"%s_eigBase_%d[%g]", name, i, (dynamic_cast<RooAbsReal*>(parameters_.at(i)))->getVal());
46  coeffs.add(*w->factory(buff));
47  snprintf(buff,sizeof(buff),"%s_eigLin_%d", name, i);
48  RooAddition *add = new RooAddition(buff,buff,coeffs,eigvVarsPlusOne);
49  w->import(*add);
50  replacements_.add(*add);
51  }
52 }
53 
54 RooAbsPdf *PdfDiagonalizer::diagonalize(RooAbsPdf &pdf)
55 {
56  if (!pdf.dependsOn(parameters_)) return 0;
57 
58  // now do the customization
59  RooCustomizer custom(pdf, name_.c_str());
60  for (int i = 0, n = parameters_.getSize(); i < n; ++i) {
61  if (pdf.dependsOn(*parameters_.at(i))) {
62  custom.replaceArg(*parameters_.at(i), *replacements_.at(i));
63  }
64  }
65 
66  RooAbsPdf *ret = dynamic_cast<RooAbsPdf *>(custom.build());
67  ret->SetName((std::string(pdf.GetName()) + "_" + name_).c_str());
68  return ret;
69 }
int i
Definition: DBlmapReader.cc:9
RooArgList parameters_
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
RooArgList eigenVars_
T sqrt(T t)
Definition: SSEVec.h:46
std::string name_
tuple result
Definition: query.py:137
RooArgList replacements_
int j
Definition: DBlmapReader.cc:9
RooAbsPdf * diagonalize(RooAbsPdf &pdf)
PdfDiagonalizer(const char *name, RooWorkspace *w, RooFitResult &result)
T w() const