LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
WeightCalc.cxx
Go to the documentation of this file.
2 
3 // art libraries
5 //#include "art/Utilities/Exception.h"
8 
9 // ROOT libraries
10 #include "TMatrixD.h"
11 #include "TDecompChol.h"
12 
13 // CLHEP libraries
14 #include "CLHEP/Random/RandomEngine.h"
15 #include "CLHEP/Random/RandGaussQ.h"
16 
17 namespace evwgh {
18  std::vector<std::vector<double> > WeightCalc::MultiGaussianSmearing(std::vector<double> const& centralValue,std::vector< std::vector<double> > const& inputCovarianceMatrix,int n_multisims,CLHEP::RandGaussQ& GaussRandom)
19  {
20 
21  std::vector<std::vector<double> > setOfSmearedCentralValues;
22 
23  //Check that covarianceMatrix is of compatible dimension with the central values
24  unsigned int covarianceMatrix_dim = centralValue.size();
25 
26  if (inputCovarianceMatrix.size() != covarianceMatrix_dim)
27  {
29  << "inputCovarianceMatrix rows " << inputCovarianceMatrix.size()
30  << " not equal to entries of centralValue[]: " << covarianceMatrix_dim;
31  }
32 
33  for (auto const & row : inputCovarianceMatrix )
34  { // Range-for (C++11).
35  if(row.size() != covarianceMatrix_dim)
36  {
38  << "inputCovarianceMatrix columns " << row.size()
39  << " not equal to entries of centralValue[]: " << covarianceMatrix_dim;
40  }
41  }
42 
43  //change covariance matrix into a TMartixD object
44  int dim = int(inputCovarianceMatrix.size());
45  TMatrixD covarianceMatrix(dim,dim);
46  int i = 0;
47  for (auto const & row : inputCovarianceMatrix)
48  {
49  int j = 0;
50  for (auto const & element : row)
51  {
52  covarianceMatrix[i][j] = element;
53  ++j;
54  }
55  ++i;
56  }
57 
58  //perform Choleskey Decomposition
59  TDecompChol dc = TDecompChol(covarianceMatrix);
60  if(!dc.Decompose())
61  {
63  << "Cannot decompose covariance matrix to begin smearing.";
64  return setOfSmearedCentralValues;
65  }
66 
67  //Get upper triangular matrix. This maintains the relations in the
68  //covariance matrix, but simplifies the structure.
69  TMatrixD U = dc.GetU();
70 
71  //for every multisim
72  for(int n = 0; n < n_multisims; ++n)
73  {
74 
75  //get a gaussian random number for every central value element
76  int dim = centralValue.size();
77 
78  std::vector<double> rands(dim);
79  GaussRandom.fireArray(dim, rands.data());
80 
81  //compute the smeared central values
82  std::vector<double> smearedCentralValues;
83  for(int col = 0; col < dim; ++col)
84  {
85  //find the weight of each col of the upper triangular cov. matrix
86  double weightFromU = 0.;
87  for(int row = 0; row < col+1; ++row)
88  {
89  weightFromU += U(row,col)*rands[row];
90  }
91  //multiply this weight by each col of the central values to obtain
92  //the gaussian smeared and constrained central values
93  // smearedCentralValues.push_back(weightFromU * centralValue[col]);
94  smearedCentralValues.push_back(weightFromU + centralValue[col]);
95  }
96 
97  //collect the smeared central values into a set
98  setOfSmearedCentralValues.push_back(smearedCentralValues);
99  }//loop over multisims
100  return setOfSmearedCentralValues;
101  } // WeightCalc::MultiGaussianSmearing() - gives a vector of sets of smeared parameters
102 
106  std::vector<double> WeightCalc::MultiGaussianSmearing(std::vector<double> const& centralValue, TMatrixD* const& inputCovarianceMatrix, std::vector< double > rand)
107  {
108 
109  //compute the smeared central values
110  std::vector<double> smearedCentralValues;
111 
112  //
113  //perform Choleskey Decomposition
114  //
115  // Best description I have found
116  // is in the PDG (Monte Carlo techniques, Algorithms, Gaussian distribution)
117  //
118  // http://pdg.lbl.gov/2016/reviews/rpp2016-rev-monte-carlo-techniques.pdf (Page 5)
119  //
120  //
121  TDecompChol dc = TDecompChol(*(inputCovarianceMatrix));
122  if(!dc.Decompose())
123  {
125  << "Cannot decompose covariance matrix to begin smearing.";
126  return smearedCentralValues;
127  }
128 
129  //Get upper triangular matrix. This maintains the relations in the
130  //covariance matrix, but simplifies the structure.
131  TMatrixD U = dc.GetU();
132 
133 
134  for(unsigned int col = 0; col < centralValue.size(); ++col)
135  {
136  //find the weight of each col of the upper triangular cov. matrix
137  double weightFromU = 0.;
138 
139  for(unsigned int row = 0; row < col+1; ++row)
140  {
141  weightFromU += U(row,col)*rand[row];
142  }
143 
144  //multiply this weight by each col of the central values to obtain
145  //the gaussian smeared and constrained central values
146  // smearedCentralValues.push_back(weightFromU * centralValue[col]);
147  smearedCentralValues.push_back(weightFromU + centralValue[col]);
148  }
149  return smearedCentralValues;
150  } // WeightCalc::MultiGaussianSmearing() - Gives a single set of smeared parameters
151 
152 
154  //
155  /*
156  static std::vector<double> MultiGaussianSmearing(
157  std::vector<double> const& centralValue,
158  TMatrixD* const& LowerTriangleCovarianceMatrix,
159  bool isDecomposed,
160  std::vector<double> rand);
161  */
163  std::vector<double> WeightCalc::MultiGaussianSmearing(std::vector<double> const& centralValue, TMatrixD* const& LowerTriangleCovarianceMatrix, bool isDecomposed, std::vector< double > rand)
164  {
165 
166  //compute the smeared central values
167  std::vector<double> smearedCentralValues;
168 
169  // This guards against accidentally
170  if(!isDecomposed){
172  << "Must supply the decomposed lower triangular covariance matrix.";
173  return smearedCentralValues;
174  }
175 
176 
177  for(unsigned int col = 0; col < centralValue.size(); ++col)
178  {
179  //find the weight of each col of the upper triangular cov. matrix
180  double weightFromU = 0.;
181 
182  for(unsigned int row = 0; row < col+1; ++row)
183  {
184  weightFromU += LowerTriangleCovarianceMatrix[0][row][col]*rand[row];
185  }
186 
187  //multiply this weight by each col of the central values to obtain
188  //the gaussian smeared and constrained central values
189  // smearedCentralValues.push_back(weightFromU * centralValue[col]);
190  smearedCentralValues.push_back(weightFromU + centralValue[col]);
191  }
192  return smearedCentralValues;
193  } // WeightCalc::MultiGaussianSmearing() - Gives a single set of smeared parameters
194 
195 
196 
197 } // namespace evwgh
198 
static std::vector< std::vector< double > > MultiGaussianSmearing(std::vector< double > const &centralValues, std::vector< std::vector< double >> const &inputCovarianceMatrix, int n_multisims, CLHEP::RandGaussQ &GaussRandom)
Applies Gaussian smearing to a set of data.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Int_t col[ntarg]
Definition: Style.C:29
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
Char_t n[5]