MaCh3  2.8.0
Reference Guide
Classes | Functions
samples.h File Reference
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>
#include "Samples/SampleHandlerBase.h"
#include "TH1.h"
#include "TH2.h"
#include "histutils.h"
Include dependency graph for samples.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  PySampleHandlerInterface
 EW: As SampleHandlerBase is an abstract base class we have to do some gymnastics to get it to get it into python. More...
 
class  PySampleHandlerBase
 As SampleHandlerBase is an abstract base class we have to do some gymnastics to get it to get it into python. More...
 

Functions

void initSamplesModule (py::module &m_samples)
 

Detailed Description

Author
Ewan Miller

Definition in file samples.h.

Function Documentation

◆ initSamplesModule()

void initSamplesModule ( py::module &  m_samples)

Definition at line 343 of file samples.h.

343  {
344  // Bind the systematic type enum that lets us set different types of systematics
345  py::enum_<TestStatistic>(m_samples, "TestStatistic")
346  .value("Poisson", TestStatistic::kPoisson)
347  .value("Barlow_Beeston", TestStatistic::kBarlowBeeston)
348  .value("Ice_Cube", TestStatistic::kIceCube)
349  .value("Pearson", TestStatistic::kPearson)
350  .value("Dembinski_Abdelmottele", TestStatistic::kDembinskiAbdelmotteleb)
351  .value("N_Test_Statistics", TestStatistic::kNTestStatistics);
352 
353  py::class_<SampleHandlerInterface, PySampleHandlerInterface /* <--- trampoline*/>(m_samples, "SampleHandlerInterface")
354  .def(py::init())
355 
356  .def(
357  "reweight",
359  "reweight the MC events in this sample. You will need to override this.")
360 
361  .def(
362  "get_n_samples",
364  "Get the total number of samples"
365  )
366 
367  .def(
368  "get_n_dim",
370  py::arg("sample"),
371  "Get the dimension of a given sample"
372  )
373 
374  .def(
375  "get_mc_hist",
376  [](SampleHandlerBase &self, const int sample)
377  {
378  auto hist_original = M3::Clone(self.GetMCHist(sample));
379 
380  auto edges = HistToNumpy(hist_original);
381  return edges;
382  },
383 
384  py::return_value_policy::reference_internal,
385  py::arg("sample"),
386  "Get MC histogram as numpy arrays.\n"
387  "For 1D: Returns (contents, edges)\n"
388  "For 2D: Returns (contents, edgesX, edgesY)\n"
389  "where contents is shape (nbinsY, nbinsX) for 2D")
390 
391  .def(
392  "get_likelihood",
394  "Get the sample likelihood at the current point in your model space. You will need to override this.")
395 
396  .def(
397  "set_test_stat",
399  "Set the test statistic that should be used when calculating likelihoods. \n\
400  :param test_stat: The new test statistic to use",
401  py::arg("test_stat"))
402 
403  .def(
404  "get_bin_LLH",
405  py::overload_cast<double, double, double>(&SampleHandlerInterface::GetTestStatLLH, py::const_),
406  "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\
407  :param data: The data content of the bin. \n\
408  :param mc: The mc content of the bin \n\
409  :param w2: The Sum(w_{i}^2) (sum of weights squared) in the bin, which is sigma^2_{MC stats}",
410  py::arg("data"),
411  py::arg("mc"),
412  py::arg("w2"))
413 
414  ; // End of SampleHandlerInterface binding
415 
416  py::class_<SampleHandlerBase, PySampleHandlerBase /* <--- trampoline*/,
417  SampleHandlerInterface>(m_samples, "SampleHandlerBase")
418  .def(
419  py::init<std::string, ParameterHandlerGeneric *>(),
420  "This should never be called directly as SampleHandlerBase is an abstract base class. \n\
421  However when creating a derived class, in the __init__() method, you should call the parent constructor i.e. this one by doing:: \n\
422  \n\
423  \tsuper(<your derived SampleHandler class>, self).__init__(*args) \n\
424  \n ",
425  py::arg("mc_version"), py::arg("xsec_cov"))
426 
427  .def(
428  "add_data",
429  py::overload_cast<const int, const std::vector<double>&>(&SampleHandlerBase::AddData),
430  py::arg("sample"),
431  py::arg("data_array"),
432  "Set the data for your sample handler (assumes the binning is the same as your MC!)"
433  )
434 
435  // ================
436  // Useful getters
437  // ===============
438  .def(
439  "get_sample_title",
441  py::arg("sample"),
442  "Get the title for a given sample"
443  )
444  .def(
445  "get_data_array",
446  py::overload_cast<const int>(&SampleHandlerBase::GetDataArray, py::const_),
447  py::arg("sample"),
448  "Returns the contents of the MC histogram as a flat list"
449  )
450 
451  .def(
452  "get_mc_array",
453  py::overload_cast<const int>(&SampleHandlerBase::GetMCArray, py::const_),
454  py::arg("sample"),
455  "Returns the contents of the MC histogram as a flat list"
456  )
457 
458  .def(
459  "get_w2_array",
460  py::overload_cast<const int>(&SampleHandlerBase::GetW2Array, py::const_),
461  py::arg("sample"),
462  "Returns the contents of the W2 histogram as a flat list"
463  )
464 
465  .def(
466  "get_data_hist",
467  [](SampleHandlerBase &self, const int sample)
468  {
469  auto hist_original = M3::Clone(self.GetDataHist(sample));
470 
471  auto edges = HistToNumpy(hist_original);
472  return edges;
473  },
474  py::arg("Dimension"),
475  "Get Data histogram as numpy arrays.\n"
476  "For 1D: Returns (contents, edges)\n"
477  "For 2D: Returns (contents, edgesX, edgesY)\n"
478  "where contents is shape (nbinsY, nbinsX) for 2D")
479 
480  .def(
481  "get_w2_hist",
482  [](SampleHandlerBase &self, const int sample)
483  {
484  auto hist_original = M3::Clone(self.GetW2Hist(sample));
485 
486  auto edges = HistToNumpy(hist_original);
487  return edges;
488  },
489 
490 
491  py::arg("sample"),
492  "Get W2 histogram as numpy arrays.\n"
493  "For 1D: Returns (contents, edges)\n"
494  "For 2D: Returns (contents, edgesX, edgesY)\n"
495  "where contents is shape (nbinsY, nbinsX) for 2D")
496 
497  .def("get_var_hist",
498  [](SampleHandlerBase &self, const int iSample,
499  const std::string& ProjectionVarX,
500  const std::string& ProjectionVarY="",
501  const std::vector<KinematicCut> &EventSelectionVec = {},
502  int WeightStyle = 0,
503  const std::vector< KinematicCut >& SubEventSelectionVec = {})
504  {
505  py::array_t<M3::float_t> edgesY, edgesX, contents;
506  std::unique_ptr<TH1> hist;
507  int dim;
508  if(ProjectionVarY==""){
509  hist = self.Get1DVarHist(iSample,
510  ProjectionVarX,
511  EventSelectionVec,
512  WeightStyle,
513  SubEventSelectionVec);
514  } else{
515  hist = self.Get2DVarHist(iSample,
516  ProjectionVarX,
517  ProjectionVarY,
518  EventSelectionVec,
519  WeightStyle,
520  SubEventSelectionVec);
521  }
522  return HistToNumpy(hist);
523  }
524  )
525  ; // End of SampleHandler Base
526 
527 
528  py::class_<KinematicCut>(m_samples, "KinematicCut")
529  .def(py::init<>(), "Simple wrapper around Kinematic cuts")
530  .def_readwrite("param_name", &KinematicCut::ParamToCutOnIt, "Parameter to cut on")
531  .def_readwrite("lower_bound", &KinematicCut::LowerBound, "Lower bound")
532  .def_readwrite("upper_bound", &KinematicCut::UpperBound, "Upper Bound");
533 
534 
535  /* Not sure if this will be needed in future versions of MaCh3 so leaving commented for now
536  py::class_<fdmc_base>(m_samples, "MCstruct")
537  .def(py::init())
538 
539  // Because a lot of the variables in fdmc_base use c style arrays,
540  // we need to provide some setter functions to be able to set them using more
541  // "pythony" objects, e.g. lists and numpy arrays
542  .def(
543  "set_event_variable_values",
544  [](fdmc_base &self, int dim, py::array_t<M3::float_t, py::array::c_style> &array)
545  {
546  py::buffer_info bufInfo = array.request();
547 
548  if ( dim > 2 )
549  throw MaCh3Exception(__FILE__, __LINE__, "Currently only dimensions of 1 or 2 are supported sorry :(");
550 
551  if ( bufInfo.ndim != 1 )
552  throw MaCh3Exception(__FILE__, __LINE__, "Number of dimensions in parameter array must be one if setting only one of the event variable arrays!");
553 
554  if( dim ==1 )
555  self.x_var = array.data();
556 
557  else if ( dim == 2)
558  self.y_var = array.data();
559  }
560  )
561  ;
562  */
563 }
@ kNTestStatistics
Number of test statistics.
@ kPearson
Standard Pearson likelihood .
@ kBarlowBeeston
Barlow-Beeston () following Conway approximation ()
@ kIceCube
Based on .
@ 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...
Definition: samples.h:234
EW: As SampleHandlerBase is an abstract base class we have to do some gymnastics to get it to get it ...
Definition: samples.h:20
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
void AddData(const int Sample, TH1 *Data)
DB: Add data for a given sample from a ROOT histogram.
auto GetDataArray() const
Return array storing data entries for every bin.
auto GetMCArray() const
Return array storing MC entries for every bin.
auto GetW2Array() const
Return array storing W2 entries for every bin.
std::string GetSampleTitle(const int iSample) const final
Get fancy title for specified samples.
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
virtual double GetLikelihood() const =0
Return likelihood (-LogL) for all samples.
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 M3::int_t GetNSamples()
returns total number of samples
virtual void Reweight()=0
main routine modifying MC prediction based on proposed parameter values
void SetTestStatistic(TestStatistic testStat)
Set the test statistic to be used when calculating the binned likelihoods.
virtual int GetNDim(const int Sample) const =0
DB Get what dimensionality binning for given sample has.
py::tuple HistToNumpy(std::unique_ptr< TH1 > &hist)
Definition: histutils.h:56
std::unique_ptr< ObjectType > Clone(const ObjectType *obj, const std::string &name="")
KS: Creates a copy of a ROOT-like object and wraps it in a smart pointer.
double UpperBound
Upper bound on which we apply cut.
double LowerBound
Lower bound on which we apply cut.
int ParamToCutOnIt
Index or enum value identifying the kinematic variable to cut on.