16 #define SIMPLEFITS_TEST_DEBUG
36 #define BOOST_TEST_MODULE ( SimpleFits_test )
37 #include "boost/test/unit_test.hpp"
54 template <
typename Array>
56 (std::ostream& out, Array
const&
m, std::string
name =
"Matrix")
58 const size_t Dim = size_t(std::sqrt(m.size()));
60 out <<
name <<
" " << Dim <<
"x" << Dim <<
":";
61 for (
size_t r = 0;
r < Dim; ++
r) {
63 for (
size_t c = 0; c < Dim; ++c)
64 out <<
" " << m[
r * Dim + c];
71 template <
typename Array>
73 (std::ostream& out, Array
const& v, std::string
name =
"Vector")
75 using Data_t =
typename Array::value_type;
76 const size_t Dim = v.size();
78 out <<
name <<
" [" << Dim <<
"]: { ";
80 out <<
"}" << std::endl;
84 template <
typename Fitter>
86 #ifdef SIMPLEFITS_TEST_DEBUG
87 typename Fitter::FitParameters_t params;
88 typename Fitter::FitMatrix_t Xmat, Smat;
89 typename Fitter::Data_t det;
91 bool res = fitter.FillResults(params, Xmat, det, Smat);
94 std::cout <<
"det(X) = " << det << std::endl;
97 if (!res)
std::cout <<
"The fit results are marked as invalid!" << std::endl;
98 #else // !SIMPLEFITS_TEST_DEBUG
100 #endif // SIMPLEFITS_TEST_DEBUG
104 template <
typename T>
112 T intercept_slope_covariance,
117 BOOST_TEST(fitter.
N() ==
n);
120 BOOST_CHECK_THROW(fitter.
Slope(), std::range_error);
121 BOOST_CHECK_THROW(fitter.
Intercept(), std::range_error);
122 BOOST_CHECK_THROW(fitter.
SlopeError(), std::range_error);
125 BOOST_CHECK_THROW(fitter.
ChiSquare(), std::range_error);
126 BOOST_TEST(fitter.
NDF() == -2);
134 BOOST_TEST(
double(fitter.
Slope()) ==
double(slope), 0.1%
tolerance());
139 double(intercept_slope_covariance), 0.1%
tolerance());
140 if (
double(chisq) == 0.)
144 BOOST_TEST(fitter.
NDF() == NDF);
150 template <
typename T>
154 std::array<T, 3>
const& solution,
155 std::array<T, 3>
const& error2,
160 BOOST_TEST(fitter.
N() ==
n);
163 BOOST_CHECK_THROW(fitter.
FitParameter(0), std::range_error);
164 BOOST_CHECK_THROW(fitter.
FitParameter(1), std::range_error);
165 BOOST_CHECK_THROW(fitter.
FitParameter(2), std::range_error);
169 BOOST_CHECK_THROW(fitter.
ChiSquare(), std::range_error);
170 BOOST_TEST(fitter.
NDF() == -3);
187 if (
double(chisq) == 0.)
191 BOOST_TEST(fitter.
NDF() == NDF);
197 template <
typename T>
201 std::array<T, 3>
const& solution,
202 std::array<T, 3>
const& error2,
207 BOOST_TEST(fitter.
N() ==
n);
210 BOOST_CHECK_THROW(fitter.
FitParameters(), std::runtime_error);
212 BOOST_CHECK_THROW(fitter.
ChiSquare(), std::runtime_error);
213 BOOST_TEST(fitter.
NDF() == -3);
229 BOOST_TEST(
double(params[0]) ==
double(solution[0]), 0.1%
tolerance());
230 BOOST_TEST(
double(params[1]) ==
double(solution[1]), 0.1%
tolerance());
231 BOOST_TEST(
double(params[2]) ==
double(solution[2]), 0.1%
tolerance());
235 if (
double(chisq) == 0.)
239 BOOST_TEST(fitter.
NDF() == NDF);
249 template <
typename T>
254 using PerfectItem_t = std::pair<Data_t, Data_t>;
255 using UncertainItem_t = std::tuple<Data_t, Data_t, Data_t>;
257 using PerfectData_t = std::vector<PerfectItem_t>;
258 using UncertainData_t = std::vector<UncertainItem_t>;
261 PerfectData_t perfect_data{
262 { Data_t(-4), Data_t( 8) },
263 { Data_t( 0), Data_t( 0) },
264 { Data_t( 4), Data_t(-8) }
268 const Data_t intercept = Data_t( 0);
269 const Data_t slope = Data_t(-2);
270 const Data_t perf_chisq = Data_t( 0);
271 const Data_t perf_intercept_error = std::sqrt(Data_t(32)/Data_t(96));
272 const Data_t perf_slope_error = std::sqrt(Data_t( 3)/Data_t(96));
273 const Data_t perf_intercept_slope_cov = - Data_t(0)/Data_t(96);
274 const int perf_DoF = 1;
276 UncertainData_t uncertain_data({
277 UncertainItem_t{ Data_t(-4), Data_t( 8), Data_t(1) },
278 UncertainItem_t{ Data_t( 0), Data_t( 0), Data_t(2) },
279 UncertainItem_t{ Data_t( 4), Data_t(-8), Data_t(2) }
282 const Data_t unc_chisq = Data_t( 0);
283 const Data_t unc_intercept_error = std::sqrt(Data_t(20)/Data_t(21));
284 const Data_t unc_slope_error = std::sqrt(Data_t(1.5)/Data_t(21));
285 const Data_t unc_intercept_slope_cov = - Data_t(-3)/Data_t(21);
286 const int unc_DoF = 1;
294 CheckLinearFit<Data_t>(fitter, 0, 0., 0., 0., 0., 0., 0., 0);
302 for (
auto const& data: uncertain_data) {
303 if (std::get<2>(data) == Data_t(1))
304 fitter.
add(std::get<0>(data), std::get<1>(data));
306 fitter.add(std::get<0>(data), std::get<1>(data), std::get<2>(data));
310 CheckLinearFit<Data_t>(fitter,
n,
312 unc_intercept_error, unc_slope_error, unc_intercept_slope_cov,
323 CheckLinearFit<Data_t>(fitter, 0, 0., 0., 0., 0., 0., 0., 0);
326 fitter.add_without_uncertainty
328 CheckLinearFit<Data_t>(fitter,
n,
330 perf_intercept_error, perf_slope_error, perf_intercept_slope_cov,
336 fitter.add_without_uncertainty(perfect_data);
337 CheckLinearFit<Data_t>(fitter,
n,
339 perf_intercept_error, perf_slope_error, perf_intercept_slope_cov,
345 fitter.add_without_uncertainty(
346 uncertain_data.begin(), uncertain_data.end(),
347 [](UncertainItem_t
const& d)
348 {
return PerfectItem_t{ std::get<0>(d), std::get<1>(d) }; }
350 CheckLinearFit<Data_t>(fitter,
n,
352 perf_intercept_error, perf_slope_error, perf_intercept_slope_cov,
358 fitter.add_without_uncertainty(uncertain_data,
359 [](UncertainItem_t
const& d)
360 {
return PerfectItem_t{ std::get<0>(d), std::get<1>(d) }; }
362 CheckLinearFit<Data_t>(fitter,
n,
364 perf_intercept_error, perf_slope_error, perf_intercept_slope_cov,
375 fitter.add_with_uncertainty(uncertain_data.begin(), uncertain_data.end());
376 CheckLinearFit<Data_t>(fitter,
n,
378 unc_intercept_error, unc_slope_error, unc_intercept_slope_cov,
384 fitter.add_with_uncertainty(uncertain_data);
385 CheckLinearFit<Data_t>(fitter,
n,
387 unc_intercept_error, unc_slope_error, unc_intercept_slope_cov,
397 template <
typename T>
402 using PerfectItem_t = std::pair<Data_t, Data_t>;
403 using UncertainItem_t = std::tuple<Data_t, Data_t, Data_t>;
405 using PerfectData_t = std::vector<PerfectItem_t>;
406 using UncertainData_t = std::vector<UncertainItem_t>;
409 PerfectData_t perfect_data{
410 { Data_t(-4), Data_t( 9) },
411 { Data_t( 0), Data_t(-1) },
412 { Data_t( 4), Data_t( 5) },
413 { Data_t( 6), Data_t(14) }
419 const std::array<Data_t, 3> solution = {{ -1.0, -0.5, 0.5 }};
420 const std::array<Data_t, 3> perf_errors2 = {{ 149./199., 163./6368., 59./25472. }};
421 const Data_t perf_chisq = Data_t( 0);
422 const int perf_DoF = 1;
424 UncertainData_t uncertain_data({
425 UncertainItem_t{ Data_t(-4), Data_t( 9), Data_t(2) },
426 UncertainItem_t{ Data_t( 0), Data_t(-1), Data_t(1) },
427 UncertainItem_t{ Data_t( 4), Data_t( 5), Data_t(1) },
428 UncertainItem_t{ Data_t( 6), Data_t(14), Data_t(2) }
431 const Data_t unc_chisq = Data_t( 0);
434 const std::array<Data_t, 3> unc_errors2 = {{ 517./617., 769./9872., 209./39488. }};
435 const int unc_DoF = 1;
442 std::array<Data_t, 3> empty_params;
443 empty_params.fill(0);
446 CheckQuadraticFit<Data_t>(fitter, 0, empty_params, empty_params, 0., 0);
454 for (
auto const& data: uncertain_data) {
455 if (std::get<2>(data) == Data_t(1))
456 fitter.add(std::get<0>(data), std::get<1>(data));
458 fitter.add(std::get<0>(data), std::get<1>(data), std::get<2>(data));
462 CheckQuadraticFit<Data_t>
463 (fitter,
n, solution, unc_errors2, unc_chisq, unc_DoF);
472 CheckQuadraticFit<Data_t>(fitter, 0, empty_params, empty_params, 0., 0);
475 fitter.add_without_uncertainty
477 CheckQuadraticFit<Data_t>
478 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
482 fitter.add_without_uncertainty(perfect_data);
483 CheckQuadraticFit<Data_t>
484 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
488 fitter.add_without_uncertainty(
489 uncertain_data.begin(), uncertain_data.end(),
490 [](UncertainItem_t
const& d)
491 {
return PerfectItem_t{ std::get<0>(d), std::get<1>(d) }; }
493 CheckQuadraticFit<Data_t>
494 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
498 fitter.add_without_uncertainty(uncertain_data,
499 [](UncertainItem_t
const& d)
500 {
return PerfectItem_t{ std::get<0>(d), std::get<1>(d) }; }
502 CheckQuadraticFit<Data_t>
503 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
512 fitter.add_with_uncertainty(uncertain_data.begin(), uncertain_data.end());
513 CheckQuadraticFit<Data_t>
514 (fitter,
n, solution, unc_errors2, unc_chisq, unc_DoF);
518 fitter.add_with_uncertainty(uncertain_data);
519 CheckQuadraticFit<Data_t>
520 (fitter,
n, solution, unc_errors2, unc_chisq, unc_DoF);
529 template <
typename T>
531 const T
z = (x -
mean) / sigma;
532 return amplitude *
std::exp(-0.5*z*z);
536 template <
typename T>
541 using PerfectItem_t = std::pair<Data_t, Data_t>;
542 using UncertainItem_t = std::tuple<Data_t, Data_t, Data_t>;
544 using PerfectData_t = std::vector<PerfectItem_t>;
545 using UncertainData_t = std::vector<UncertainItem_t>;
549 const std::array<Data_t, 3> solution = {{ 5.0, 1.0, 2.0 }};
552 PerfectData_t perfect_data{
553 { Data_t(-1),
gaus(Data_t(-1), solution[0], solution[1], solution[2]) },
554 { Data_t( 0),
gaus(Data_t( 0), solution[0], solution[1], solution[2]) },
555 { Data_t(+1),
gaus(Data_t(+1), solution[0], solution[1], solution[2]) },
556 { Data_t(+3),
gaus(Data_t(+3), solution[0], solution[1], solution[2]) }
562 const std::array<Data_t, 3> perf_errors2 = {{ 0., 0., 0. }};
563 const Data_t perf_chisq = Data_t( 0);
564 const int perf_DoF = 1;
566 UncertainData_t uncertain_data({
567 UncertainItem_t{ Data_t(-1),
gaus(Data_t(-1), solution[0], solution[1], solution[2]), Data_t(2) },
568 UncertainItem_t{ Data_t( 0),
gaus(Data_t( 0), solution[0], solution[1], solution[2]), Data_t(1) },
569 UncertainItem_t{ Data_t(+1),
gaus(Data_t(+1), solution[0], solution[1], solution[2]), Data_t(1) },
570 UncertainItem_t{ Data_t(+3),
gaus(Data_t(+3), solution[0], solution[1], solution[2]), Data_t(2) }
573 const Data_t unc_chisq = Data_t( 0);
576 const std::array<Data_t, 3> unc_errors2 = {{ 0., 0., 0. }};
577 const int unc_DoF = 1;
584 std::array<Data_t, 3> empty_params;
585 empty_params.fill(0);
588 CheckGaussianFit<Data_t>(fitter, 0, empty_params, empty_params, 0., 0);
596 for (
auto const& data: uncertain_data) {
597 if (std::get<2>(data) == Data_t(1))
598 fitter.add(std::get<0>(data), std::get<1>(data));
600 fitter.add(std::get<0>(data), std::get<1>(data), std::get<2>(data));
604 CheckGaussianFit<Data_t>
605 (fitter,
n, solution, unc_errors2, unc_chisq, unc_DoF);
614 CheckGaussianFit<Data_t>(fitter, 0, empty_params, empty_params, 0., 0);
617 fitter.add_without_uncertainty
619 CheckGaussianFit<Data_t>
620 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
624 fitter.add_without_uncertainty(perfect_data);
625 CheckGaussianFit<Data_t>
626 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
630 fitter.add_without_uncertainty(
631 uncertain_data.begin(), uncertain_data.end(),
632 [](UncertainItem_t
const& d)
633 {
return PerfectItem_t{ std::get<0>(d), std::get<1>(d) }; }
635 CheckGaussianFit<Data_t>
636 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
640 fitter.add_without_uncertainty(uncertain_data,
641 [](UncertainItem_t
const& d)
642 {
return PerfectItem_t{ std::get<0>(d), std::get<1>(d) }; }
644 CheckGaussianFit<Data_t>
645 (fitter,
n, solution, perf_errors2, perf_chisq, perf_DoF);
654 fitter.add_with_uncertainty(uncertain_data.begin(), uncertain_data.end());
655 CheckGaussianFit<Data_t>
656 (fitter,
n, solution, unc_errors2, unc_chisq, unc_DoF);
660 fitter.add_with_uncertainty(uncertain_data);
661 CheckGaussianFit<Data_t>
662 (fitter,
n, solution, unc_errors2, unc_chisq, unc_DoF);
680 LinearFitTest<double>();
687 QuadraticFitTest<double>();
694 GaussianFitTest<double>();
process_name opflash particleana ie ie ie z
void LinearFitTest()
Tests LinearFit object with a known input.
Data_t InterceptError() const
Returns the error on intercept of the fit.
virtual Data_t FitParameterError(unsigned int n) const override
Returns the error on parameter n of the fit result.
process_name opflash particleana ie x
virtual Data_t ChiSquare() const override
Returns the of the original fit.
virtual Data_t FitParameter(unsigned int n) const override
Returns the parameter n of the fit result.
void QuadraticFitTest()
Tests QuadraticFit object with a known input.
virtual FitParameters_t FitParameterErrors() const override
Computes and returns all the parameter errors of the fit result.
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
int N() const
Returns the number of (valid) points added.
Classes performing simple fits.
Performs a linear regression of data.
void CheckGaussianFit(lar::util::GaussianFit< T > const &fitter, int n, std::array< T, 3 > const &solution, std::array< T, 3 > const &error2, T chisq, int NDF)
Data_t Slope() const
Returns the slope of the fit.
Data_t InterceptSlopeCovariance() const
Returns the covariance between intercept and slope of the fit.
T gaus(T x, T amplitude, T mean, T sigma)
Tests GausssianFit object with a known input.
Data_t Intercept() const
Returns the intercept of the fit.
auto end(FixedBins< T, C > const &) noexcept
"Fast" Gaussian fit
Data_t SlopeError() const
Returns the error in slope of the fit.
void PrintMatrix(std::ostream &out, Array const &m, std::string name="Matrix")
Performs a second-degree fit of data.
auto begin(FixedBins< T, C > const &) noexcept
virtual bool isValid() const override
Returns if the fit has valid results.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
virtual Fitter_t const & Fitter() const
Returns the internal fitter (mostly for debugging)
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
void CheckLinearFit(lar::util::LinearFit< T > const &fitter, int n, T intercept, T slope, T intercept_error, T slope_error, T intercept_slope_covariance, T chisq, int NDF)
void CheckQuadraticFit(lar::util::QuadraticFit< T > const &fitter, int n, std::array< T, 3 > const &solution, std::array< T, 3 > const &error2, T chisq, int NDF)
virtual Data_t ChiSquare() const override
Returns the of the fit.
virtual bool isValid() const override
Returns if the fit has valid results.
typename Fitter_t::FitParameters_t FitParameters_t
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
void PrintVector(std::ostream &out, Array const &v, std::string name="Vector")
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
BEGIN_PROLOG could also be cout
void PrintFitterInfo(Fitter const &fitter)
virtual FitParameters_t FitParameters() const override
Computes and returns all the parameters of the fit result.
virtual Data_t ChiSquare() const override
Returns the of the fit.