DAS  3.0
Das Analysis System
Teddy

Description

class Teddy

Use MC techniques to apply a function \(f\) to a distribution $x$ with (non-diagonal) covariance matrix \(\mathbf{V}\).

Procedure:

  1. Diagonalise the covariance matrix
  2. Generate a multi-dimensional Gaussian event \(\delta\) distributed according to the (sqrt of the) eigenvalues \(\epsilon_i\)

    \[ \delta_i \sim \mathcal{N}(0,\sqrt{\epsilon_i}) \]

  3. Transform back to the original base (where the cov matrix is non-diagonal)
  4. Add rotated vector to the input distribution an apply the function \(f\):

    \[ \mathbf{y}_k = \]

  5. Go back to 2. until a satisfying statistics is reached, with Teddy::play() (the criterion of satisfaction and the loop are to be defined outside of the Teddy instance)
  6. Get output histogram and covariance matrix with Teddy::buy()

#include <Teddy.h>

Public Member Functions

 Teddy (const Eigen::VectorXd &, const Eigen::MatrixXd &, std::function< Eigen::VectorXd(const Eigen::VectorXd &)>=identity, int=42)
 
 Teddy (const std::unique_ptr< TH1D > &, const std::unique_ptr< TH2D > &, std::function< Eigen::VectorXd(const Eigen::VectorXd &)>=identity, int=42)
 
void play ()
 
std::pair< Eigen::VectorXd, Eigen::MatrixXd > buy () const
 
template<typename... Args>
std::pair< std::unique_ptr< TH1D >, std::unique_ptr< TH2D > > buy (TString name, Args... args) const
 

Static Public Attributes

static bool verbose = true
 

Static Private Member Functions

static Eigen::VectorXd H2V (const std::unique_ptr< TH1D > &)
 
static Eigen::MatrixXd H2M (const std::unique_ptr< TH2D > &)
 
static int GuessOutDim (int, std::function< Eigen::VectorXd(const Eigen::VectorXd &)>)
 
static void SanityCheck (const Eigen::VectorXd &, Eigen::VectorXd &, double=0)
 

Private Attributes

const Eigen::VectorXd vec
 
const Eigen::MatrixXd cov
 
const int nOldBins
 
const int nNewBins
 
long long N
 
Eigen::VectorXd eigVals
 
Eigen::MatrixXd rotation
 
Eigen::VectorXd sigma
 
Eigen::VectorXd sum
 
Eigen::MatrixXd sum2
 
std::function< Eigen::VectorXd(const Eigen::VectorXd &)> func
 
TRandom3 random
 

Constructor & Destructor Documentation

◆ Teddy() [1/2]

Teddy ( const Eigen::VectorXd &  ,
const Eigen::MatrixXd &  ,
std::function< Eigen::VectorXd(const Eigen::VectorXd &)>  = identity,
int  = 42 
)

The rotation and the eigenvalues are determined from the input covariance matrix. Default function is the identity (useful for testing).

◆ Teddy() [2/2]

Teddy ( const std::unique_ptr< TH1D > &  ,
const std::unique_ptr< TH2D > &  ,
std::function< Eigen::VectorXd(const Eigen::VectorXd &)>  = identity,
int  = 42 
)

The rotation and the eigenvalues are determined from the input covariance matrix. Default function is the identity (useful for testing).

Member Function Documentation

◆ buy() [1/2]

pair< VectorXd, MatrixXd > buy ( ) const

Get output distributions, can be called several times.

154 {
155  VectorXd outputDist = sum*(1./N);
156 
157  MatrixXd avSq = sum2*(1./N);
158  MatrixXd outputCov = avSq - outputDist * outputDist.transpose();
159 
160  return {outputDist, outputCov};
161 }

◆ buy() [2/2]

std::pair<std::unique_ptr<TH1D>,std::unique_ptr<TH2D> > buy ( TString  name,
Args...  args 
) const
inline

Get output distributions, can be called several times. Input histrogams are defined from scratch and filled. The statistical uncertainty of the 1D histogram correspondings to the square-root of the diagonal elements of the covariance matrix

106  {
107  using namespace std;
108  using namespace Eigen;
109 
110  TAxis * axis = new TAxis(args...);
111  int ndiv = axis->GetNbins();
112  double * edges = new double[ndiv];
113  axis->GetLowEdge(edges);
114  edges[ndiv-1] = axis->GetBinUpEdge(ndiv);
115  auto h = make_unique<TH1D>(name , name, ndiv-1, edges);
116  auto cov = make_unique<TH2D>(name + "_cov", name, ndiv-1, edges, ndiv-1, edges);
117 
118  VectorXd x(nNewBins);
119  MatrixXd err(nNewBins, nNewBins);
120  tie(x,err) = buy();
121 
122  for (int i=0; i<nNewBins; ++i) {
123  double content = x(i),
124  error = sqrt(err(i,i));
125 
126  h->SetBinContent(i+1, content);
127  h->SetBinError (i+1, error );
128 
129  for (int j=0; j<nNewBins; ++j)
130  cov->SetBinContent(i+1,j+1, err(i,j));
131  }
132 
133  return make_pair<unique_ptr<TH1D>,unique_ptr<TH2D>>(move(h),move(cov));
134  }

◆ GuessOutDim()

int GuessOutDim ( int  ,
std::function< Eigen::VectorXd(const Eigen::VectorXd &)>   
)
staticprivate

Guess size of the output distribution by calling once the function with dummy input.

47 {
48  if (verbose) cout << __FILE__ << ':' << __LINE__ << '\t' << __func__ << endl;
49  VectorXd In(nOldBins);
50  VectorXd Out = f(In); // guessing the size from the output of the function
51  return Out.size();
52 }

◆ H2M()

MatrixXd H2M ( const std::unique_ptr< TH2D > &  h)
staticprivate

conversion from (2D) histogram to matrix

35 {
36  if (verbose) cout << __FILE__ << ':' << __LINE__ << '\t' << __func__ << endl;
37  int sizx = h->GetNbinsX(),
38  sizy = h->GetNbinsY();
39  MatrixXd mat(sizx,sizy);
40  for(int j = 1; j <= sizx; ++j)
41  for(int i = 1; i <= sizy; ++i)
42  mat(i-1,j-1) = h->GetBinContent(j,i);
43  return mat;
44 }

◆ H2V()

VectorXd H2V ( const std::unique_ptr< TH1D > &  h)
staticprivate

conversion from (1D) histogram to vector

26 {
27  if (verbose) cout << __FILE__ << ':' << __LINE__ << '\t' << __func__ << endl;
28  VectorXd v(h->GetNbinsX());
29  for(int i = 1; i <= h->GetNbinsX(); ++i)
30  v(i-1) = h->GetBinContent(i);
31  return v;
32 }

◆ play()

void play ( )

Needs to be called from a loop, but requires no argument.

131 {
132  // 1) get vector in rotated basis
133  VectorXd deltaP(nOldBins); // P for prime
134  for (int k = 0; k < nOldBins; ++k)
135  deltaP(k) = random.Gaus(0, sigma(k));
136 
137  // 2) rotate the shift back
138  VectorXd delta = rotation*deltaP;
139  VectorXd x = vec + delta;
140 
141  // 3) compute whatever transformation you like on x
142  VectorXd y = func(x); // dimension may change here!
143  sum+= y;
144 
145  // 4) get its uncertainty
146  MatrixXd square = y * y.transpose(); // tensor product
147  sum2 += square;
148 
149  // 5) increment count for normalisation in Teddy::buy()
150  ++N;
151 }

◆ SanityCheck()

void SanityCheck ( const Eigen::VectorXd &  ,
Eigen::VectorXd &  ,
double  = 0 
)
staticprivate

Check the number of negative eigenvalues and fail if any is found.

55 {
56  int nEigv = 0, nNegEigVals = 0, nEmptyBins = 0;
57  for (long k = 0; k < eigVals.size(); ++k) {
58  if (eigVals(k) > -tolerance) {
59  eigVals(k) = max(eigVals(k), 0.);
60  ++nEigv;
61  }
62  else {
63  ++nNegEigVals;
64  cout << __FILE__ << ':' << __LINE__ << '\t' << k << ' ' << eigVals(k) << '\n';
65  }
66 
67  if (x(k) == 0)
68  ++nEmptyBins;
69  }
70  cout << flush;
71 
72  if (nNegEigVals > 0)
73  BOOST_THROW_EXCEPTION( invalid_argument(Form("%d negative eigenvalues (%d empty bins in input dist)",
74  nNegEigVals, nEmptyBins)) );
75 }

Member Data Documentation

◆ cov

const Eigen::MatrixXd cov
private

covariance matrix

◆ eigVals

Eigen::VectorXd eigVals
private

eigenvalues of input covariance matrix

◆ func

std::function<Eigen::VectorXd(const Eigen::VectorXd &)> func
private

transformation defining output as a function of the input

◆ N

long long N
private

number of calls

◆ nNewBins

const int nNewBins
private

number of bins of output distributions

◆ nOldBins

const int nOldBins
private

number of bins of input distributions

◆ random

TRandom3 random
private

random generator

◆ rotation

Eigen::MatrixXd rotation
private

rotation from diagonal basis to original basis

◆ sigma

Eigen::VectorXd sigma
private

Gaussian widths in diagonal base.

◆ sum

Eigen::VectorXd sum
private

sum of events, increased at each call and from which output distribution is estimated

◆ sum2

Eigen::MatrixXd sum2
private

sum of tensor products of each event, increased at each call and from which output covariance is estimated

◆ vec

const Eigen::VectorXd vec
private

distribution

◆ verbose

bool verbose = true
static

The documentation for this class was generated from the following files:
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.name
name
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:48
DAS::Teddy::verbose
static bool verbose
Definition: Teddy.h:74
DAS::Teddy::cov
const Eigen::MatrixXd cov
covariance matrix
Definition: Teddy.h:54
DAS::Teddy::func
std::function< Eigen::VectorXd(const Eigen::VectorXd &)> func
transformation defining output as a function of the input
Definition: Teddy.h:68
Ntupliser_cfg.args
args
Definition: Ntupliser_cfg.py:11
Ntupliser_cfg.f
f
Definition: Ntupliser_cfg.py:255
DAS::Teddy::random
TRandom3 random
random generator
Definition: Teddy.h:70
DAS::Teddy::vec
const Eigen::VectorXd vec
distribution
Definition: Teddy.h:53
DAS::Teddy::sum
Eigen::VectorXd sum
sum of events, increased at each call and from which output distribution is estimated
Definition: Teddy.h:65
DAS::Teddy::N
long long N
number of calls
Definition: Teddy.h:58
DAS::Teddy::nNewBins
const int nNewBins
number of bins of output distributions
Definition: Teddy.h:57
DAS::Teddy::buy
std::pair< Eigen::VectorXd, Eigen::MatrixXd > buy() const
Get output distributions, can be called several times.
Definition: Teddy.cc:153
DAS::Teddy::sum2
Eigen::MatrixXd sum2
sum of tensor products of each event, increased at each call and from which output covariance is esti...
Definition: Teddy.h:66
DAS::Teddy::sigma
Eigen::VectorXd sigma
Gaussian widths in diagonal base.
Definition: Teddy.h:63
DAS::Teddy::nOldBins
const int nOldBins
number of bins of input distributions
Definition: Teddy.h:56
DAS::Teddy::eigVals
Eigen::VectorXd eigVals
eigenvalues of input covariance matrix
Definition: Teddy.h:60
DAS::Teddy::rotation
Eigen::MatrixXd rotation
rotation from diagonal basis to original basis
Definition: Teddy.h:61