Classes | Macros | Typedefs | Functions
GausFitCache_test.cc File Reference

Test for classes in GausFitCache,h. More...

#include <cassert>
#include <cmath>
#include <array>
#include <limits>
#include "boost/test/unit_test.hpp"
#include "cetlib/pow.h"
#include "TH1D.h"
#include "TFitResultPtr.h"
#include "TFitResult.h"
#include "larreco/RecoAlg/GausFitCache.h"

Go to the source code of this file.

Classes

struct  RootGausFuncWrapper
 

Macros

#define BOOST_TEST_MODULE   ( HitAnaAlg_test )
 

Typedefs

using tolerance_t = decltype(0.001%tolerance())
 

Functions

 BOOST_AUTO_TEST_CASE (TestGaussianTest)
 
 BOOST_AUTO_TEST_CASE (GaussianTest)
 
 BOOST_AUTO_TEST_CASE (GaussianTrunc5Test)
 
 BOOST_AUTO_TEST_CASE (GaussianTrunc4Test)
 
Double_t multi_gaus (Double_t x, const unsigned int nGaus, Double_t const *params)
 Expect for each Gaussian ROOT-like parameters: amplitude, mean, sigma. More...
 
std::vector< Double_t > SortGaussianResults (TF1 const *pFunc, Double_t const *Params)
 
void ThreeGaussianFitTest (hit::GausFitCache &GausCache, tolerance_t tol)
 
 BOOST_AUTO_TEST_CASE (ThreeGaussianTest)
 
 BOOST_AUTO_TEST_CASE (RunTimeThreeGaussianFitTest)
 
 BOOST_AUTO_TEST_CASE (CompiledThreeGaussianFitTest)
 
 BOOST_AUTO_TEST_CASE (CompiledTruncated5ThreeGaussianFitTest)
 
 BOOST_AUTO_TEST_CASE (CompiledTruncated4ThreeGaussianFitTest)
 
 BOOST_AUTO_TEST_CASE (CompiledTruncated3ThreeGaussianFitTest)
 

Detailed Description

Test for classes in GausFitCache,h.

Author
Gianluca Petrillo (petri.nosp@m.llo@.nosp@m.fnal..nosp@m.gov)
Date
March 27th, 2015
See also
GausFitCache,h

Definition in file GausFitCache_test.cc.

Macro Definition Documentation

#define BOOST_TEST_MODULE   ( HitAnaAlg_test )

Definition at line 19 of file GausFitCache_test.cc.

Typedef Documentation

using tolerance_t = decltype(0.001% tolerance())

Definition at line 36 of file GausFitCache_test.cc.

Function Documentation

BOOST_AUTO_TEST_CASE ( TestGaussianTest  )

Definition at line 52 of file GausFitCache_test.cc.

53 {
54  // static function to be tested:
55  const auto gaus_func = ::gaus;
56 
57  const double exp1sigma = std::exp(-0.5*square(1.));
58  const double exp2sigma = std::exp(-0.5*square(2.));
59 
60  // here there should be some more believable test...
61  const double amplitude = 16.;
62  for (double sigma = 0.5; sigma < 2.25; ++sigma) {
63  for (double mean = -5; mean < 5.5; ++mean) {
64 
65  BOOST_TEST(gaus_func(-6.5 * sigma + mean, mean, sigma, amplitude) > 0.);
66  BOOST_TEST(gaus_func(-5.5 * sigma + mean, mean, sigma, amplitude) > 0.);
67  BOOST_TEST(gaus_func(-4.5 * sigma + mean, mean, sigma, amplitude) > 0.);
68 
69  auto const tol = 0.001% tolerance();
70  BOOST_TEST(gaus_func(-2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
71  BOOST_TEST(gaus_func(-1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
72  BOOST_TEST(gaus_func( 0.0 * sigma + mean, mean, sigma, amplitude) == amplitude, tol);
73  BOOST_TEST(gaus_func( 1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
74  BOOST_TEST(gaus_func( 2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
75 
76  BOOST_TEST(gaus_func( 4.5 * sigma + mean, mean, sigma, amplitude) > 0.);
77  BOOST_TEST(gaus_func( 5.5 * sigma + mean, mean, sigma, amplitude) > 0.);
78  BOOST_TEST(gaus_func( 6.5 * sigma + mean, mean, sigma, amplitude) > 0.);
79 
80  } // for mean
81  } // for sigma
82 
83 } // BOOST_AUTO_TEST_CASE(TestGaussianTest)
auto const tol
Definition: SurfXYZTest.cc:16
auto const tolerance
constexpr T square(T x)
Definition: pow.h:21
T gaus(T x, T amplitude, T mean, T sigma)
Tests GausssianFit object with a known input.
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
BOOST_AUTO_TEST_CASE ( GaussianTest  )

Definition at line 107 of file GausFitCache_test.cc.

108 {
109  // static function to be tested:
110  const auto gaus_func = RootGausFuncWrapper
112 
113  const double exp1sigma = std::exp(-0.5*square(1.));
114  const double exp2sigma = std::exp(-0.5*square(2.));
115 
116  const double amplitude = 16.;
117  for (double sigma = 0.5; sigma < 2.25; ++sigma) {
118  for (double mean = -5; mean < 5.5; ++mean) {
119 
120  BOOST_TEST(gaus_func(-6.5 * sigma + mean, mean, sigma, amplitude) > 0.);
121  BOOST_TEST(gaus_func(-5.5 * sigma + mean, mean, sigma, amplitude) > 0.);
122  BOOST_TEST(gaus_func(-4.5 * sigma + mean, mean, sigma, amplitude) > 0.);
123 
124  auto const tol = 0.001% tolerance();
125  BOOST_TEST(gaus_func(-2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
126  BOOST_TEST(gaus_func(-1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
127  BOOST_TEST(gaus_func( 0.0 * sigma + mean, mean, sigma, amplitude) == amplitude, tol);
128  BOOST_TEST(gaus_func(+1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
129  BOOST_TEST(gaus_func(+2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
130 
131  BOOST_TEST(gaus_func(+4.5 * sigma + mean, mean, sigma, amplitude) > 0.);
132  BOOST_TEST(gaus_func(+5.5 * sigma + mean, mean, sigma, amplitude) > 0.);
133  BOOST_TEST(gaus_func(+6.5 * sigma + mean, mean, sigma, amplitude) > 0.);
134 
135  } // for mean
136  } // for sigma
137 
138 } // BOOST_AUTO_TEST_CASE(GaussianTest)
static Double_t gaus(Double_t const *x, Double_t const *params)
Single Gaussian function.
auto const tol
Definition: SurfXYZTest.cc:16
auto const tolerance
constexpr T square(T x)
Definition: pow.h:21
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
BOOST_AUTO_TEST_CASE ( GaussianTrunc5Test  )

Definition at line 141 of file GausFitCache_test.cc.

142 {
143  // static function to be tested:
144  const auto gaus_func = RootGausFuncWrapper
145  (hit::details::CompiledGausFitCacheBaseStruct::gaus_trunc<5>);
146 
147  const double exp1sigma = std::exp(-0.5*square(1.));
148  const double exp2sigma = std::exp(-0.5*square(2.));
149 
150  const double amplitude = 16.;
151  for (double sigma = 0.5; sigma < 2.25; ++sigma) {
152  for (double mean = -5; mean < 5.5; ++mean) {
153 
154  BOOST_TEST(gaus_func(-6.5 * sigma + mean, mean, sigma, amplitude) == 0.);
155  BOOST_TEST(gaus_func(-5.5 * sigma + mean, mean, sigma, amplitude) == 0.);
156  BOOST_TEST(gaus_func(-4.5 * sigma + mean, mean, sigma, amplitude) > 0.);
157 
158  auto const tol = 0.001% tolerance();
159  BOOST_TEST(gaus_func(-2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
160  BOOST_TEST(gaus_func(-1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
161  BOOST_TEST(gaus_func( 0.0 * sigma + mean, mean, sigma, amplitude) == amplitude, tol);
162  BOOST_TEST(gaus_func( 1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
163  BOOST_TEST(gaus_func( 2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
164 
165  BOOST_TEST(gaus_func( 4.5 * sigma + mean, mean, sigma, amplitude) > 0.);
166  BOOST_TEST(gaus_func( 5.5 * sigma + mean, mean, sigma, amplitude) == 0.);
167  BOOST_TEST(gaus_func( 6.5 * sigma + mean, mean, sigma, amplitude) == 0.);
168 
169  } // for mean
170  } // for sigma
171 
172 } // BOOST_AUTO_TEST_CASE(GaussianTrunc5Test)
auto const tol
Definition: SurfXYZTest.cc:16
auto const tolerance
constexpr T square(T x)
Definition: pow.h:21
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
BOOST_AUTO_TEST_CASE ( GaussianTrunc4Test  )

Definition at line 175 of file GausFitCache_test.cc.

176 {
177  // static function to be tested:
178  const auto gaus_func = RootGausFuncWrapper
179  (hit::details::CompiledGausFitCacheBaseStruct::gaus_trunc<4>);
180 
181  const double exp1sigma = std::exp(-0.5*square(1.));
182  const double exp2sigma = std::exp(-0.5*square(2.));
183 
184  const double amplitude = 16.;
185  for (double sigma = 0.5; sigma < 2.25; ++sigma) {
186  for (double mean = -5; mean < 5.5; ++mean) {
187 
188  BOOST_TEST(gaus_func(-6.5 * sigma + mean, mean, sigma, amplitude) == 0.);
189  BOOST_TEST(gaus_func(-5.5 * sigma + mean, mean, sigma, amplitude) == 0.);
190  BOOST_TEST(gaus_func(-4.5 * sigma + mean, mean, sigma, amplitude) == 0.);
191 
192  auto const tol = 0.001% tolerance();
193  BOOST_TEST(gaus_func(-2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
194  BOOST_TEST(gaus_func(-1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
195  BOOST_TEST(gaus_func( 0.0 * sigma + mean, mean, sigma, amplitude) == amplitude, tol);
196  BOOST_TEST(gaus_func( 1.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp1sigma, tol);
197  BOOST_TEST(gaus_func( 2.0 * sigma + mean, mean, sigma, amplitude) == amplitude * exp2sigma, tol);
198 
199  BOOST_TEST(gaus_func( 4.5 * sigma + mean, mean, sigma, amplitude) == 0.);
200  BOOST_TEST(gaus_func( 5.5 * sigma + mean, mean, sigma, amplitude) == 0.);
201  BOOST_TEST(gaus_func( 6.5 * sigma + mean, mean, sigma, amplitude) == 0.);
202 
203  } // for mean
204  } // for sigma
205 
206 } // BOOST_AUTO_TEST_CASE(GaussianTrunc4Test)
auto const tol
Definition: SurfXYZTest.cc:16
auto const tolerance
constexpr T square(T x)
Definition: pow.h:21
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
BOOST_AUTO_TEST_CASE ( ThreeGaussianTest  )

Definition at line 364 of file GausFitCache_test.cc.

365 {
366 
367  const Double_t Params[] = {
368  4.0, -2.0, 1.5,
369  5.0, 0.1, 0.3,
370  2.0, 1.0, 0.5
371  }; // Params[]
372 
373  // rounding errors on x on the look do not really matter
374  for (double x = -10.; x <= +10.; x += 0.1) {
375  const Double_t expected = multi_gaus(x, 3, Params);
376 
377  const Double_t tested
378  = hit::details::CompiledGausFitCacheBaseStruct::ngaus<3>(&x, Params);
379 
380  BOOST_TEST(tested == expected, 0.001% tolerance());
381  } // for x
382 
383 } // BOOST_AUTO_TEST_CASE(ThreeGaussianTest)
const char expected[]
Definition: Exception_t.cc:22
auto const tolerance
Double_t multi_gaus(Double_t x, const unsigned int nGaus, Double_t const *params)
Expect for each Gaussian ROOT-like parameters: amplitude, mean, sigma.
list x
Definition: train.py:276
BOOST_AUTO_TEST_CASE ( RunTimeThreeGaussianFitTest  )

Definition at line 387 of file GausFitCache_test.cc.

388 {
389  // max 20 Gaussians
390  hit::GausFitCache GausCache("RunTimeGaussians");
391  ThreeGaussianFitTest(GausCache, 0.02% tolerance());
392 } // BOOST_AUTO_TEST_CASE(RunTimeThreeGaussianFitTest)
auto const tolerance
void ThreeGaussianFitTest(hit::GausFitCache &GausCache, tolerance_t tol)
A set of TF1 linear sum of base functions (Gaussians)
Definition: GausFitCache.h:46
BOOST_AUTO_TEST_CASE ( CompiledThreeGaussianFitTest  )

Definition at line 396 of file GausFitCache_test.cc.

397 {
398  // max 20 Gaussians
399  hit::CompiledGausFitCache<20> GausCache("CompiledGaussians");
400  ThreeGaussianFitTest(GausCache, 0.02% tolerance());
401 } // BOOST_AUTO_TEST_CASE(CompiledThreeGaussianFitTest)
auto const tolerance
void ThreeGaussianFitTest(hit::GausFitCache &GausCache, tolerance_t tol)
A set of TF1 linear sum of Gaussians.
Definition: GausFitCache.h:277
BOOST_AUTO_TEST_CASE ( CompiledTruncated5ThreeGaussianFitTest  )

Definition at line 406 of file GausFitCache_test.cc.

407 {
408  // max 20 Gaussians; truncate at 5 sigma
410  ("CompiledTruncated5Gaussians");
411  ThreeGaussianFitTest(GausCache, 0.1% tolerance()); // 0.1% tolerance
412 } // BOOST_AUTO_TEST_CASE(CompiledTruncated5ThreeGaussianFitTest)
auto const tolerance
void ThreeGaussianFitTest(hit::GausFitCache &GausCache, tolerance_t tol)
A set of TF1 linear sum of truncated Gaussians.
Definition: GausFitCache.h:310
BOOST_AUTO_TEST_CASE ( CompiledTruncated4ThreeGaussianFitTest  )

Definition at line 417 of file GausFitCache_test.cc.

418 {
419  // max 20 Gaussians; truncate at 4 sigma
421  ("CompiledTruncated4Gaussians");
422  ThreeGaussianFitTest(GausCache, 0.1% tolerance());
423 } // BOOST_AUTO_TEST_CASE(CompiledTruncated4ThreeGaussianFitTest)
auto const tolerance
void ThreeGaussianFitTest(hit::GausFitCache &GausCache, tolerance_t tol)
A set of TF1 linear sum of truncated Gaussians.
Definition: GausFitCache.h:310
BOOST_AUTO_TEST_CASE ( CompiledTruncated3ThreeGaussianFitTest  )

Definition at line 427 of file GausFitCache_test.cc.

428 {
429  // max 20 Gaussians; truncate at 3 sigma
431  ("CompiledTruncated3Gaussians");
432  ThreeGaussianFitTest(GausCache, 10.% tolerance()); // (seriously, it's that bad)
433 } // BOOST_AUTO_TEST_CASE(CompiledTruncated3ThreeGaussianFitTest)
auto const tolerance
void ThreeGaussianFitTest(hit::GausFitCache &GausCache, tolerance_t tol)
A set of TF1 linear sum of truncated Gaussians.
Definition: GausFitCache.h:310
Double_t multi_gaus ( Double_t  x,
const unsigned int  nGaus,
Double_t const *  params 
)

Expect for each Gaussian ROOT-like parameters: amplitude, mean, sigma.

Definition at line 214 of file GausFitCache_test.cc.

215 {
216 
217  Double_t res = 0.;
218  for (unsigned int iGaus = 0; iGaus < nGaus; ++iGaus) {
219  // our gaus() takes the parameters as: mean, sigma, amplitude
220  res += gaus(x, params[1], params[2], params[0]);
221  params += 3;
222  } // for
223  return res;
224 } // multi_gaus()
T gaus(T x, T amplitude, T mean, T sigma)
Tests GausssianFit object with a known input.
list x
Definition: train.py:276
std::vector<Double_t> SortGaussianResults ( TF1 const *  pFunc,
Double_t const *  Params 
)

Definition at line 229 of file GausFitCache_test.cc.

230 {
231  assert(pFunc->GetNpar() % 3 == 0); // Sorting non-Gaussian function!
232 
233  const size_t nGaus = pFunc->GetNpar() / 3;
234 
235  std::vector<size_t> BestMatch(nGaus, nGaus); // initialize with invalid number
236  for (size_t iGaus = 0; iGaus < nGaus; ++iGaus) {
237  double best_match_quality = std::numeric_limits<double>::max();
238  for (size_t iFitGaus = 0; iFitGaus < nGaus; ++iFitGaus) {
239  // so far, we compare all the parameters with the same weight
240  const double match_quality
241  = square(Params[iGaus*3 + 0] - pFunc->GetParameter(iFitGaus*3 + 0))
242  + square(Params[iGaus*3 + 1] - pFunc->GetParameter(iFitGaus*3 + 1))
243  + square(Params[iGaus*3 + 2] - pFunc->GetParameter(iFitGaus*3 + 2))
244  ;
245  if (match_quality < best_match_quality) {
246  best_match_quality = match_quality;
247  BestMatch[iGaus] = iFitGaus;
248  } // if this is the best so far
249  } // for fit
250 
251  assert(BestMatch[iGaus] < nGaus); // No reasonable solution matched!
252 
253  for (size_t i = 0; i < iGaus; ++i) {
254  // Same fit Gaussian solution matches multiple solutions
255  assert(BestMatch[i] != BestMatch[iGaus]);
256  } // for i
257 
258  } // for solution
259 
260  std::vector<Double_t> sorted_params(nGaus * 3);
261  for (size_t iGaus = 0; iGaus < nGaus; ++iGaus) {
262  const size_t iBestFit = BestMatch[iGaus];
263  for (size_t i = 0; i < 3; ++i)
264  sorted_params[iGaus*3 + i] = pFunc->GetParameter(iBestFit*3 + i);
265  }
266  return sorted_params;
267 } // SortGaussianResults()
constexpr T square(T x)
Definition: pow.h:21
static int max(int a, int b)
void ThreeGaussianFitTest ( hit::GausFitCache GausCache,
tolerance_t  tol 
)

Definition at line 271 of file GausFitCache_test.cc.

272  {
273  std::string name = GausCache.GetName();
274 
275  constexpr size_t nGaus = 3; // we test three gaussians
276 
277  // sorted by increasing mean
278  const Double_t Params[nGaus * 3] = { // amplitude, mean, sigma
279  4.0, -2.0, 1.5,
280  5.0, 0.1, 0.3,
281  2.0, 1.0, 0.5
282  }; // Params[]
283 
284  // fit test
285  // - fill the input histogram
286  TH1D Hist
287  ("H3Gaus", ("Three-Gaussian test - " + name).c_str(), 200, -10., 10.);
288  for (Int_t iBin = 1; iBin <= Hist.GetNbinsX(); ++iBin)
289  Hist.SetBinContent(iBin, multi_gaus(Hist.GetBinCenter(iBin), nGaus, Params));
290 
291 #ifdef GAUSFITCACHE_TEST_DEBUG
292  Hist.Draw();
293 #endif // GAUSFITCACHE_TEST_DEBUG
294 
295  // - get the 3-Gaussian fitting function
296  TF1* pFunc = GausCache.Get(nGaus);
297 
298  // - prepare the function with reasonable initial values
299  const double MeanOffset = -((double(nGaus) - 1.) / 2.);
300  const double MeanStep = 1.;
301  for (size_t iGaus = 0; iGaus < nGaus; ++iGaus) {
302  size_t BaseIndex = iGaus * 3;
303  pFunc->SetParameter(BaseIndex + 0, 1.); // amplitude
304  pFunc->SetParameter(BaseIndex + 1, MeanOffset + iGaus * MeanStep); // mean
305  pFunc->SetParameter(BaseIndex + 2, 1.); // sigma
306  } // for
307 
308  // function range is ignored in the fit, but used when drawing
309  pFunc->SetRange(Hist.GetBinCenter(1), Hist.GetBinCenter(Hist.GetNbinsX()));
310 
311 #ifdef GAUSFITCACHE_TEST_DEBUG
312  TF1* pFCopy = pFunc->DrawCopy("L SAME");
313  pFCopy->SetLineStyle(kDashed);
314  pFCopy->SetLineColor(kCyan);
315 #endif // GAUSFITCACHE_TEST_DEBUG
316 
317  // - fit
318  TFitResultPtr fit_res = Hist.Fit(pFunc, "WQ0NS");
319  BOOST_TEST(int(fit_res) == 0);
320 
321 #ifdef GAUSFITCACHE_TEST_DEBUG
322  pFCopy = pFunc->DrawCopy("L SAME");
323  pFCopy->SetLineWidth(1);
324  pFCopy->SetLineColor(kRed);
325 
326  gPad->SaveAs(("3GausTest_" + name + ".eps").c_str());
327 #endif // GAUSFITCACHE_TEST_DEBUG
328 
329  // - sort the results according to the expected ones
330  std::vector<Double_t> results = SortGaussianResults(pFunc, Params);
331 
332 
333  // - check them
334  for (size_t iGaus = 0; iGaus < nGaus; ++iGaus) {
335  const size_t iParam = iGaus * 3;
336 
337  // - check amplitude
338  BOOST_TEST(results[iParam + 0] == Params[iParam + 0], tol);
339  // - check mean
340  BOOST_TEST(results[iParam + 1] == Params[iParam + 1], tol);
341  // - check sigma
342  BOOST_TEST(results[iParam + 2] == Params[iParam + 2], tol);
343 
344  } // for iGaus
345 
346  BOOST_WARN(pFunc->GetChisquare() < pFunc->GetNDF() / 2.);
347 
348 #ifdef GAUSFITCACHE_TEST_DEBUG
349  pFunc->Print();
350  // always print the fit result
351 #else // !GAUSFITCACHE_TEST_DEBUG
352  // in case of trouble, print the fit result
353  if ((int(fit_res) != 0) || (pFunc->GetChisquare() >= pFunc->GetNDF() / 2.))
354 #endif // GAUSFITCACHE_TEST_DEBUG
355  {
356  fit_res->Print();
357  }
358 
359 } // ThreeGaussianFitTest()
static QCString name
Definition: declinfo.cpp:673
std::string string
Definition: nybbler.cc:12
auto const tol
Definition: SurfXYZTest.cc:16
std::vector< Double_t > SortGaussianResults(TF1 const *pFunc, Double_t const *Params)
virtual TF1 * Get(size_t nFunc)
Returns a function sum of nFunc base functions.
Double_t multi_gaus(Double_t x, const unsigned int nGaus, Double_t const *params)
Expect for each Gaussian ROOT-like parameters: amplitude, mean, sigma.
std::string GetName() const
Return the name of this cache.
Definition: GausFitCache.h:55