426 py::enum_<TestStatistic>(m_samples,
"TestStatistic")
440 "reweight the MC events in this sample. You will need to override this."
446 "Get the sample likelihood at the current point in your model space. You will need to override this."
452 "Set the test statistic that should be used when calculating likelihoods. \n\
453 :param test_stat: The new test statistic to use",
460 "Get the LLH for a bin by comparing the data and MC. The result depends on having previously set the test statistic using :py:meth:`pyMaCh3.samples.SampleHandlerInterface.set_test_stat` \n\
461 :param data: The data content of the bin. \n\
462 :param mc: The mc content of the bin \n\
463 :param w2: The Sum(w_{i}^2) (sum of weights squared) in the bin, which is sigma^2_{MC stats}",
473 py::init<std::string, ParameterHandlerGeneric*>(),
474 "This should never be called directly as SampleHandlerBase is an abstract base class. \n\
475 However when creating a derived class, in the __init__() method, you should call the parent constructor i.e. this one by doing:: \n\
477 \tsuper(<your derived SampleHandler class>, self).__init__(*args) \n\
479 py::arg(
"mc_version"), py::arg(
"xsec_cov"))
485 int Dimension =
self.GetNDim(sample);
490 const TH1 *hist_original =
self.GetMCHist(sample);
493 if (!hist_original) {
494 throw std::runtime_error(
"GetMCHist returned null pointer");
498 TH1D *hist =
static_cast<TH1D*
>(hist_original->Clone(
"cloned_hist"));
500 if (Dimension == 1) {
503 auto edgesY = py::array_t<M3::float_t>();
504 return py::make_tuple(contents, edgesX, edgesY);
505 }
else if (Dimension == 2) {
507 TH2Poly *hist2poly =
dynamic_cast<TH2Poly *
>(hist);
510 throw std::runtime_error(
"pyMaCh3 can't do non-uniform binning for now :(");
514 TH2 *hist2d =
dynamic_cast<TH2 *
>(hist);
516 throw std::runtime_error(
"Failed to cast to TH2");
518 auto [contents, edgesX, edgesY] =
TH2ToNumpy(hist2d);
519 return py::make_tuple(contents, edgesX, edgesY);
524 throw std::invalid_argument(
"Dimension must be 1 or 2");
527 py::return_value_policy::reference_internal,
529 "Get MC histogram as numpy arrays.\n"
530 "For 1D: Returns (contents, edges)\n"
531 "For 2D: Returns (contents, edgesX, edgesY)\n"
532 "where contents is shape (nbinsY, nbinsX) for 2D")
537 const TH1 *hist =
self.GetDataHist(sample);
539 int Dimension =
self.GetNDim(sample);
541 if (Dimension == 1) {
543 const auto [contents, edgesX] =
TH1ToNumpy(hist);
544 const auto edgesY = py::array_t<M3::float_t>();
545 return py::make_tuple(contents, edgesX, edgesY);
546 }
else if (Dimension == 2) {
548 const TH2Poly *hist2poly =
dynamic_cast<const TH2Poly *
>(hist);
551 throw std::runtime_error(
"pyMaCh3 can't do non-uniform binning for now :(");
555 throw std::runtime_error(
"pyMaCh3 can't do non-uniform binning for now :(");
558 const TH2 *hist2d =
dynamic_cast<const TH2 *
>(hist);
560 throw std::runtime_error(
"Failed to cast to TH2");
562 const auto [contents, edgesX, edgesY] =
TH2ToNumpy(hist2d);
563 return py::make_tuple(contents, edgesX, edgesY);
568 throw std::invalid_argument(
"Dimension must be 1 or 2");
571 py::arg(
"Dimension"),
572 "Get Data histogram as numpy arrays.\n"
573 "For 1D: Returns (contents, edges)\n"
574 "For 2D: Returns (contents, edgesX, edgesY)\n"
575 "where contents is shape (nbinsY, nbinsX) for 2D")
580 const TH1 *hist =
self.GetW2Hist(sample);
582 int Dimension =
self.GetNDim(sample);
584 if (Dimension == 1) {
586 const auto [contents, edgesX] =
TH1ToNumpy(hist);
587 const auto edgesY = py::array_t<M3::float_t>();
588 return py::make_tuple(contents, edgesX, edgesY);
589 }
else if (Dimension == 2) {
591 const TH2Poly *hist2poly =
dynamic_cast<const TH2Poly *
>(hist);
594 throw std::runtime_error(
"pyMaCh3 can't do non-uniform binning for now :(");
598 const TH2 *hist2d =
dynamic_cast<const TH2 *
>(hist);
600 throw std::runtime_error(
"Failed to cast to TH2");
602 const auto [contents, edgesX, edgesY] =
TH2ToNumpy(hist2d);
603 return py::make_tuple(contents, edgesX, edgesY);
608 throw std::invalid_argument(
"Dimension must be 1 or 2");
612 "Get W2 histogram as numpy arrays.\n"
613 "For 1D: Returns (contents, edges)\n"
614 "For 2D: Returns (contents, edgesX, edgesY)\n"
615 "where contents is shape (nbinsY, nbinsX) for 2D");
@ kNTestStatistics
Number of test statistics.
@ kPearson
Standard Pearson likelihood .
@ kBarlowBeeston
Barlow-Beeston () following Conway approximation ()
@ kDembinskiAbdelmotteleb
Based on .
@ kPoisson
Standard Poisson likelihood .
As SampleHandlerBase is an abstract base class we have to do some gymnastics to get it to get it into...
EW: As SampleHandlerBase is an abstract base class we have to do some gymnastics to get it to get it ...
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
virtual double GetLikelihood() const =0
double GetTestStatLLH(const double data, const double mc, const double w2) const
Calculate test statistic for a single bin. Calculation depends on setting of fTestStatistic....
virtual void Reweight()=0
void SetTestStatistic(TestStatistic testStat)
Set the test statistic to be used when calculating the binned likelihoods.
std::tuple< py::array_t< M3::float_t >, py::array_t< M3::float_t > > TH1ToNumpy(const TH1 *hist)
std::tuple< py::array_t< M3::float_t >, py::array_t< M3::float_t >, py::array_t< M3::float_t > > TH2ToNumpy(const TH2 *hist)