MaCh3  2.5.1
Reference Guide
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
SampleHandlerBase Class Referenceabstract

Class responsible for handling implementation of samples used in analysis, reweighting and returning LLH. More...

#include <Samples/SampleHandlerBase.h>

Inheritance diagram for SampleHandlerBase:
[legend]
Collaboration diagram for SampleHandlerBase:
[legend]

Public Member Functions

 SampleHandlerBase (std::string ConfigFileName, ParameterHandlerGeneric *xsec_cov, const std::shared_ptr< OscillationHandler > &OscillatorObj_=nullptr)
 Constructor. More...
 
virtual ~SampleHandlerBase ()
 destructor More...
 
int GetNDim (const int Sample) const final
 DB Get what dimensionality binning for given sample has. More...
 
std::string GetName () const final
 Get name for Sample Handler. More...
 
std::string GetSampleTitle (const int Sample) const final
 Get fancy title for specified samples. More...
 
std::string GetSampleName (const int Sample) const
 Sample name tag used only for getting relevant uncertainties. More...
 
std::string GetKinVarName (const int iSample, const int Dimension) const final
 Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino_Energy". More...
 
void PrintIntegral (const int iSample, const TString &OutputName="/dev/null", const int WeightStyle=0, const TString &OutputCSVName="/dev/null")
 Computes and prints the integral breakdown of all modes and oscillation channels for a given sample. More...
 
void AddData (const int Sample, TH1 *Data)
 DB: Add data for a given sample from a ROOT histogram. More...
 
void AddData (const int Sample, const std::vector< double > &Data_Array)
 ETA: Add data for a given sample from a raw array. More...
 
void PrintRates (const bool DataOnly=false) final
 Helper function to print rates for the samples with LLH. More...
 
double GetLikelihood () const override
 Return likelihood (-logL) for all samples. More...
 
double GetSampleLikelihood (const int isample) const override
 Get likelihood (-logL) for a single sample. More...
 
int GetSampleIndex (const std::string &SampleTitle) const
 Get index of sample based on name. More...
 
const TH1 * GetDataHist (const int Sample) final
 Get Data histogram. More...
 
const TH1 * GetDataHist (const std::string &Sample)
 Get Data histogram by sample name. More...
 
const TH1 * GetMCHist (const int Sample) final
 Get MC histogram. More...
 
const TH1 * GetMCHist (const std::string &Sample)
 Get MC histogram by sample title. More...
 
const TH1 * GetW2Hist (const int Sample) final
 Get W2 histogram. More...
 
const TH1 * GetW2Hist (const std::string &Sample)
 Get W2 histogram by sample name. More...
 
void Reweight () override
 main routine modifying MC prediction based on proposed parameter values More...
 
M3::float_t GetEventWeight (const int iEvent)
 Computes the total event weight for a given entry. More...
 
int GetNOscChannels (const int iSample) const final
 Get number of oscillation channels for a single sample. More...
 
std::string GetFlavourName (const int iSample, const int iChannel) const final
 Get the flavour name for a given sample and oscillation channel. More...
 
std::unique_ptr< TH1 > Get1DVarHist (const int iSample, const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={}) final
 Return 1D projection of MC into given 1D variable (doesn't have to be variable used in the fit) More...
 
std::unique_ptr< TH2 > Get2DVarHist (const int iSample, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={}) final
 Build a 2D projection of MC events into specified variables. More...
 
std::vector< KinematicCutBuildModeChannelSelection (const int iSample, const int kModeToFill, const int kChannelToFill) const
 Construct vector of kinematic cuts that will be applied, on top of default cuts include stuff like cut on mode etc. More...
 
void Fill1DSubEventHist (const int iSample, TH1D *_h1DVar, const std::string &ProjectionVar, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)
 Fill projection histogram by looping over all events, and skipping one which doesn't pass specified condition. More...
 
void Fill2DSubEventHist (const int iSample, TH2 *_h2DVar, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)
 Fill projection histogram by looping over all events, and skipping one which doesn't pass specified condition. More...
 
std::unique_ptr< TH1 > Get1DVarHistByModeAndChannel (const int iSample, const std::string &ProjectionVar_Str, const int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0) final
 Build a 1D histogram for a given variable, optionally filtered by mode and channel. More...
 
std::unique_ptr< TH2 > Get2DVarHistByModeAndChannel (const int iSample, const std::string &ProjectionVar_StrX, const std::string &ProjectionVar_StrY, const int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0) final
 Build a 2D histogram for given variables, optionally filtered by mode and channel. More...
 
std::unique_ptr< TH1 > GetModeHist1D (const int iSample, int s, int m, int style=0)
 Produce 1D projection into X-variable, for a single MaCh3 mode. More...
 
std::unique_ptr< TH2 > GetModeHist2D (const int iSample, int s, int m, int style=0)
 Produce 2D projection into X-variable, and Y-variable for a single MaCh3 mode. More...
 
int GetRangeForPlotType (const SamplePlotType TypeEnum, const int iSample) const
 KS: Return range for plot type, for example number of modes, osc channels etc. More...
 
std::vector< std::unique_ptr< TH1 > > ReturnHistsBySelection1D (const int iSample, const std::string &KinematicProjection, const int Selection1, const int Selection2=-1, const int WeightStyle=0)
 
std::vector< std::unique_ptr< TH2 > > ReturnHistsBySelection2D (const int iSample, const std::string &KinematicProjectionX, const std::string &KinematicProjectionY, const int Selection1, const int Selection2=-1, const int WeightStyle=0)
 
std::unique_ptr< THStack > ReturnStackedHistBySelection1D (const int iSample, const std::string &KinematicProjection, const int Selection1, const int Selection2=-1, const int WeightStyle=0)
 
const TLegend * ReturnStackHistLegend () const
 Return the legend used for stacked histograms with sample info. More...
 
int ReturnKinematicParameterFromString (const std::string &KinematicStr) const
 ETA function to generically convert a string from xsec cov to a kinematic type. More...
 
std::string ReturnStringFromKinematicParameter (const int KinematicVariable) const
 ETA function to generically convert a kinematic type from xsec cov to a string. More...
 
void SaveAdditionalInfo (TDirectory *Dir) final
 Store additional info in a chain. More...
 
int ReturnKinematicVectorFromString (const std::string &KinematicStr) const
 JM: Convert a kinematic vector name to its corresponding integer ID. More...
 
std::string ReturnStringFromKinematicVector (const int KinematicVariable) const
 JM: Convert a kinematic vector integer ID to its corresponding name as a string. More...
 
bool IsSubEventVarString (const std::string &VarStr) const
 JM: Check if a kinematic parameter string corresponds to a subevent-level variable. More...
 
auto GetDataArray () const
 Return array storing data entries for every bin. More...
 
auto GetMCArray () const
 Return array storing MC entries for every bin. More...
 
auto GetW2Array () const
 Return array storing W2 entries for every bin. More...
 
std::vector< double > GetArrayForSample (const int Sample, std::vector< double > const &array) const
 Return a sub-array for a given sample. More...
 
std::vector< double > GetDataArray (const int Sample) const
 Return array storing data entries for every bin. More...
 
std::vector< double > GetMCArray (const int Sample) const
 Return array storing MC entries for every bin. More...
 
std::vector< double > GetW2Array (const int Sample) const
 Return array storing W2 entries for single sample. More...
 
void CheckEmptyBins () const
 Loop over bins and checks if there are any which have 0 entries. More...
 
- Public Member Functions inherited from SampleHandlerInterface
 SampleHandlerInterface ()
 The main constructor. More...
 
virtual ~SampleHandlerInterface ()
 destructor More...
 
virtual M3::int_t GetNSamples ()
 returns total number of samples More...
 
virtual void CleanMemoryBeforeFit ()=0
 Allow to clean not used memory before fit starts. More...
 
MaCh3ModesGetMaCh3Modes () const
 Return pointer to MaCh3 modes. More...
 
unsigned int GetNEvents () const
 Return total number of events. More...
 
double GetPoissonLLH (const double data, const double mc) const
 Calculate test statistic for a single bin using Poisson. More...
 
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. Data and mc -> 0 cut-offs are defined in M3::LOW_MC_BOUND. More...
 
void SetTestStatistic (TestStatistic testStat)
 Set the test statistic to be used when calculating the binned likelihoods. More...
 
TestStatistic GetTestStatistic () const
 Get the test statistic used when calculating the binned likelihoods. More...
 

Protected Member Functions

void InitialiseNuOscillatorObjects ()
 including Dan's magic NuOscillator More...
 
const M3::float_tGetNuOscillatorPointers (const int iEvent) const
 Get pointer to NuOscillator weight for a given event. More...
 
void SetupNuOscillatorPointers ()
 Initialise pointer to oscillation weight to NuOscillator object. More...
 
void ReadConfig ()
 Load information about sample handler and corresponding samples from config file. More...
 
void LoadSingleSample (const int iSample, const YAML::Node &Settings)
 Initialise single sample from config file. More...
 
virtual void AddAdditionalWeightPointers ()=0
 DB Function to determine which weights apply to which types of samples. More...
 
void SetupKinematicMap ()
 Ensure Kinematic Map is setup and make sure it is initialised correctly. More...
 
virtual void SetupSplines ()=0
 initialise your splineXX object and then use InitialiseSplineObject to conviently setup everything up More...
 
virtual void Init ()=0
 Initialise any variables that your experiment specific SampleHandler needs. More...
 
virtual int SetupExperimentMC ()=0
 Experiment specific setup, returns the number of events which were loaded. More...
 
virtual void SetupMC ()=0
 Function which translates experiment struct into core struct. More...
 
virtual void InititialiseData ()=0
 Function responsible for loading data from file or loading from file. More...
 
void Initialise ()
 Function which does a lot of the lifting regarding the workflow in creating different MC objects. More...
 
void SetSplinePointers ()
 Set pointers for each event to appropriate weights, for unbinned based on event number while for binned based on other kinematical properties. More...
 
std::vector< std::vector< int > > GetSplineBins (int Event, BinnedSplineHandler *BinnedSpline, bool &ThrowCrititcal) const
 Retrieve the spline bin indices associated with a given event. More...
 
void FindNominalBinAndEdges ()
 
void SetBinning ()
 set the binning for 2D sample used for the likelihood calculation More...
 
void SetupReweightArrays ()
 Initialise data, MC and W2 histograms. More...
 
virtual void SetupFunctionalParameters ()
 ETA - a function to setup and pass values to functional parameters where you need to pass a value to some custom reweight calc or engine. More...
 
void RegisterIndividualFunctionalParameter (const std::string &fpName, int fpEnum, FuncParFuncType fpFunc)
 HH - a helper function for RegisterFunctionalParameter. More...
 
virtual void RegisterFunctionalParameters ()=0
 HH - a experiment-specific function where the maps to actual functions are set up. More...
 
virtual void PrepFunctionalParameters ()
 Update the functional parameter values to the latest proposed values. Needs to be called before every new reweight so is called in fillArray. More...
 
virtual void ApplyShifts (const int iEvent)
 ETA - generic function applying shifts. More...
 
bool IsEventSelected (const int iSample, const int iEvent) _noexcept_
 DB Function which determines if an event is selected based on KinematicCut. More...
 
bool IsSubEventSelected (const std::vector< KinematicCut > &SubEventCuts, const int iEvent, unsigned const int iSubEvent, size_t nsubevents)
 JM Function which determines if a subevent is selected. More...
 
virtual void ResetShifts (const int iEvent)
 HH - reset the shifted values to the original values. More...
 
virtual void FinaliseShifts (const int iEvent)
 LP - Optionally calculate derived observables after all shifts have been applied. More...
 
void CalcNormsBins (std::vector< std::vector< NormParameter >> &norm_parameters, std::vector< std::vector< int > > &norms_bins)
 Check whether a normalisation systematic affects an event or not. More...
 
template<typename ParT >
bool PassesSelection (const ParT &Par, std::size_t iEvent)
 
M3::float_t CalcWeightTotal (const EventInfo *_restrict_ MCEvent) const _noexcept_
 Calculate the total weight weight for a given event. More...
 
virtual void CalcWeightFunc (const int iEvent)
 Calculate weights for function parameters. More...
 
double ReturnKinematicParameter (const std::string &KinematicParameter, int iEvent) const
 Return the value of an associated kinematic parameter for an event. More...
 
virtual double ReturnKinematicParameter (const int KinematicVariable, const int iEvent) const =0
 
std::vector< double > ReturnKinematicVector (const std::string &KinematicParameter, const int iEvent) const
 
virtual std::vector< double > ReturnKinematicVector (const int KinematicVariable, const int iEvent) const
 
std::vector< double > ReturnKinematicParameterBinning (const int Sample, const std::string &KinematicParameter) const final
 Return the binning used to draw a kinematic parameter. More...
 
const double * GetPointerToKinematicParameter (const std::string &KinematicParameter, int iEvent) const
 
virtual const double * GetPointerToKinematicParameter (const int KinematicVariable, const int iEvent) const =0
 
const double * GetPointerToOscChannel (const int iEvent) const
 Get pointer to oscillation channel associated with given event. Osc channel is const. More...
 
void SetupNormParameters ()
 Setup the norm parameters by assigning each event with bin. More...
 
void SetupOscParameters ()
 Setup the osc parameters. More...
 
void FillHist (const int Sample, TH1 *Hist, std::vector< double > &Array)
 Fill a histogram with the event-level information used in the fit. More...
 
void FillArray_MP ()
 DB Nice new multi-threaded function which calculates the event weights and fills the relevant bins of an array. More...
 
void FillArray ()
 Function which does the core reweighting, fills the SampleHandlerBase::SampleHandler_array vector with the weight calculated from reweighting. More...
 
void ResetHistograms ()
 Helper function to reset histograms. More...
 
void InitialiseSplineObject ()
 Setup spline handler (both binned or unbinned) More...
 
NuPDG GetInitPDGFromFileName (const std::string &FileName) const
 Retrieve the initial neutrino PDG code associated with a given input file name. More...
 
NuPDG GetFinalPDGFromFileName (const std::string &FileName) const
 Retrieve the final neutrino PDG code associated with a given input file name. More...
 
- Protected Member Functions inherited from SampleHandlerInterface
void QuietPlease ()
 CW: Redirect std::cout to silence some experiment specific libraries. More...
 
void NowTalk ()
 CW: Redirect std::cout to silence some experiment specific libraries. More...
 
template<typename T >
bool MatchCondition (const std::vector< T > &allowedValues, const T &value)
 check if event is affected by following conditions, for example pdg, or modes etc More...
 

Protected Attributes

std::unique_ptr< SplineBaseSplineHandler
 Contains all your splines (binned or unbinned) and handles the setup and the returning of weights from spline evaluations. More...
 
std::shared_ptr< OscillationHandlerOscillator
 Contains oscillator handling calculating oscillation probabilities. More...
 
std::vector< std::vector< FunctionalShifter * > > funcParsGrid
 HH - a grid of vectors of enums for each sample and event. More...
 
std::vector< FunctionalShifterfuncParsMap
 HH - a map that relates the funcpar enum to pointer of FuncPars struct HH - Changed to a vector of pointers since it's faster than unordered_map and we are using ints as keys. More...
 
std::vector< std::vector< FunctionalParameter > > funcParsVec
 HH - a vector that stores all the FuncPars struct. More...
 
std::unordered_map< std::string, int > funcParsNamesMap
 HH - a map that relates the name of the functional parameter to funcpar enum. More...
 
std::unordered_map< int, FuncParFuncTypefuncParsFuncMap
 HH - a map that relates the funcpar enum to pointer of the actual function. More...
 
std::vector< std::string > funcParsNamesVec = {}
 HH - a vector of string names for each functional parameter. More...
 
std::unique_ptr< BinningHandlerBinning
 KS: This stores binning information, in future could be come vector to store binning for every used sample. More...
 
std::vector< double > SampleHandler_array
 DB Array to be filled after reweighting. More...
 
std::vector< double > SampleHandler_array_w2
 KS Array used for MC stat. More...
 
std::vector< double > SampleHandler_data
 DB Array to be filled in AddData. More...
 
std::vector< EventInfoMCEvents
 Stores information about every MC event. More...
 
std::vector< SampleInfoSampleDetails
 Stores info about currently initialised sample. More...
 
ParameterHandlerGenericParHandler = nullptr
 ETA - All experiments will need an xsec, det and osc cov. More...
 
std::string SampleHandlerName
 A unique ID for each sample based on which we can define what systematic should be applied. More...
 
std::vector< std::vector< KinematicCut > > StoredSelection
 What gets pulled from config options, these are constant after loading in this is of length 3: 0th index is the value, 1st is lower bound, 2nd is upper bound. More...
 
std::vector< std::vector< KinematicCut > > Selection
 a way to store selection cuts which you may push back in the get1DVar functions most of the time this is just the same as StoredSelection More...
 
const std::unordered_map< std::string, int > * KinematicParameters
 Mapping between string and kinematic enum. More...
 
const std::unordered_map< int, std::string > * ReversedKinematicParameters
 Mapping between kinematic enum and string. More...
 
const std::unordered_map< std::string, int > * KinematicVectors
 
const std::unordered_map< int, std::string > * ReversedKinematicVectors
 
std::unique_ptr< ManagerSampleManager
 The manager object used to read the sample yaml file. More...
 
std::unordered_map< std::string, double > _modeNomWeightMap
 
TLegend * THStackLeg = nullptr
 DB: Legend associated with stacked histograms produced by this class. More...
 
bool FirstTimeW2
 KS:Super hacky to update W2 or not. More...
 
bool UpdateW2
 KS:Super hacky to update W2 or not. More...
 
- Protected Attributes inherited from SampleHandlerInterface
TestStatistic fTestStatistic
 Test statistic tells what kind of likelihood sample is using. More...
 
std::streambuf * buf
 Keep the cout buffer. More...
 
std::streambuf * errbuf
 Keep the cerr buffer. More...
 
M3::int_t nSamples
 Contains how many samples we've got. More...
 
unsigned int nEvents
 Number of MC events are there. More...
 
std::unique_ptr< MaCh3ModesModes
 Holds information about used Generator and MaCh3 modes. More...
 

Private Member Functions

std::vector< std::vector< KinematicCut > > ApplyTemporarySelection (const int iSample, const std::vector< KinematicCut > &ExtraCuts)
 Temporarily extend Selection for a given sample with additional cuts. Returns the original Selection so the caller can restore it later. More...
 

Private Attributes

std::unordered_map< std::string, NuPDGFileToInitPDGMap
 Mapping from input file names to initial neutrino PDG codes. More...
 
std::unordered_map< std::string, NuPDGFileToFinalPDGMap
 Mapping from input file names to final neutrino PDG codes. More...
 

Detailed Description

Class responsible for handling implementation of samples used in analysis, reweighting and returning LLH.

Author
Dan Barrow
Ed Atkin

Definition at line 28 of file SampleHandlerBase.h.

Constructor & Destructor Documentation

◆ SampleHandlerBase()

SampleHandlerBase::SampleHandlerBase ( std::string  ConfigFileName,
ParameterHandlerGeneric xsec_cov,
const std::shared_ptr< OscillationHandler > &  OscillatorObj_ = nullptr 
)

Constructor.

Parameters
ConfigFileNameName of config to initialise the sample object

Definition at line 12 of file SampleHandlerBase.cpp.

14 // ************************************************
15  MACH3LOG_INFO("-------------------------------------------------------------------");
16  MACH3LOG_INFO("Creating SampleHandlerBase object");
17 
18  //ETA - safety feature so you can't pass a NULL xsec_cov
19  if(!xsec_cov) {
20  MACH3LOG_WARN("You've passed me a nullptr ParameterHandler so I will not use any xsec parameters");
21  }
22  ParHandler = xsec_cov;
23 
24  nSamples = 1;
25 
26  if (OscillatorObj_ != nullptr) {
27  MACH3LOG_WARN("You have passed an Oscillator object through the constructor of a SampleHandlerBase object - this will be used for all oscillation channels");
28  Oscillator = OscillatorObj_;
29  if(!ParHandler) {
30  MACH3LOG_CRITICAL("You've passed me a nullptr to ParamHandler while non null to Oscillator");
31  MACH3LOG_CRITICAL("Make up you mind");
32  throw MaCh3Exception(__FILE__, __LINE__);
33  }
34  }
35 
36  KinematicParameters = nullptr;
38  KinematicVectors = nullptr;
39  ReversedKinematicVectors = nullptr;
40 
41  SampleHandlerName = "";
42  SampleManager = std::make_unique<Manager>(ConfigFileName.c_str());
43  Binning = std::make_unique<BinningHandler>();
44  // Variables related to MC stat
45  FirstTimeW2 = true;
46  UpdateW2 = false;
47 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
Custom exception class used throughout MaCh3.
std::string SampleHandlerName
A unique ID for each sample based on which we can define what systematic should be applied.
const std::unordered_map< int, std::string > * ReversedKinematicParameters
Mapping between kinematic enum and string.
std::shared_ptr< OscillationHandler > Oscillator
Contains oscillator handling calculating oscillation probabilities.
std::unique_ptr< Manager > SampleManager
The manager object used to read the sample yaml file.
const std::unordered_map< std::string, int > * KinematicParameters
Mapping between string and kinematic enum.
std::unique_ptr< BinningHandler > Binning
KS: This stores binning information, in future could be come vector to store binning for every used s...
ParameterHandlerGeneric * ParHandler
ETA - All experiments will need an xsec, det and osc cov.
bool UpdateW2
KS:Super hacky to update W2 or not.
const std::unordered_map< int, std::string > * ReversedKinematicVectors
const std::unordered_map< std::string, int > * KinematicVectors
bool FirstTimeW2
KS:Super hacky to update W2 or not.
M3::int_t nSamples
Contains how many samples we've got.
SampleHandlerInterface()
The main constructor.

◆ ~SampleHandlerBase()

SampleHandlerBase::~SampleHandlerBase ( )
virtual

destructor

Definition at line 49 of file SampleHandlerBase.cpp.

49  {
50  MACH3LOG_DEBUG("I'm deleting SampleHandlerBase");
51  if(THStackLeg != nullptr) delete THStackLeg;
52 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
TLegend * THStackLeg
DB: Legend associated with stacked histograms produced by this class.

Member Function Documentation

◆ AddAdditionalWeightPointers()

virtual void SampleHandlerBase::AddAdditionalWeightPointers ( )
protectedpure virtual

DB Function to determine which weights apply to which types of samples.

Implemented in PySampleHandlerBase.

◆ AddData() [1/2]

void SampleHandlerBase::AddData ( const int  Sample,
const std::vector< double > &  Data_Array 
)

ETA: Add data for a given sample from a raw array.

Parameters
SampleIndex of the sample.
Data_ArrayVector containing the data values.

Definition at line 1042 of file SampleHandlerBase.cpp.

1042  {
1043 // ************************************************
1044  const int Start = Binning->GetSampleStartBin(Sample);
1045  const int End = Binning->GetSampleEndBin(Sample);
1046  const int ExpectedSize = End - Start;
1047 
1048  if (static_cast<int>(Data_Array.size()) != ExpectedSize) {
1049  MACH3LOG_ERROR("Data_Array size mismatch for sample '{}'.", GetSampleTitle(Sample));
1050  MACH3LOG_ERROR("Expected size: {}, received size: {}.", ExpectedSize, Data_Array.size());
1051  MACH3LOG_ERROR("Start bin: {}, End bin: {}.", Start, End);
1052  MACH3LOG_ERROR("This likely indicates a binning or sample slicing bug.");
1053  throw MaCh3Exception(__FILE__, __LINE__);
1054  }
1055 
1056  std::copy_n(Data_Array.begin(), End-Start, SampleHandler_data.begin() + Start);
1057 
1058  FillHist(Sample, SampleDetails[Sample].DataHist, SampleHandler_data);
1059 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
void FillHist(const int Sample, TH1 *Hist, std::vector< double > &Array)
Fill a histogram with the event-level information used in the fit.
std::vector< SampleInfo > SampleDetails
Stores info about currently initialised sample.
std::string GetSampleTitle(const int Sample) const final
Get fancy title for specified samples.
std::vector< double > SampleHandler_data
DB Array to be filled in AddData.

◆ AddData() [2/2]

void SampleHandlerBase::AddData ( const int  Sample,
TH1 *  Data 
)

DB: Add data for a given sample from a ROOT histogram.

Parameters
SampleIndex of the sample.
DataPointer to a TH1 containing the data to be stored.

Definition at line 970 of file SampleHandlerBase.cpp.

970  {
971 // ************************************************
972  int Dim = GetNDim(Sample);
973  MACH3LOG_INFO("Adding {}D data histogram: {} with {:.2f} events", Dim, Data->GetTitle(), Data->Integral());
974  // delete old histogram
975  delete SampleDetails[Sample].DataHist;
976  SampleDetails[Sample].DataHist = static_cast<TH1*>(Data->Clone());
977 
978  if(!SampleHandler_data.size()) {
979  MACH3LOG_ERROR("SampleHandler_data haven't been initialised yet");
980  throw MaCh3Exception(__FILE__, __LINE__);
981  }
982 
983  auto ChecHistType = [&](const std::string& Type, const int Dimen, const TH1* Hist,
984  const std::string& file, const int line) {
985  if (std::string(Hist->ClassName()) != Type) {
986  MACH3LOG_ERROR("Expected {} for {}D sample, got {}", Type, Dimen, Hist->ClassName());
987  throw MaCh3Exception(file, line);
988  }
989  };
990 
991  if (Dim == 1) {
992  // Ensure we really have a TH1D
993  ChecHistType("TH1D", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
994  M3::CheckBinningMatch(static_cast<TH1D*>(SampleDetails[Sample].DataHist),
995  static_cast<TH1D*>(SampleDetails[Sample].MCHist), __FILE__, __LINE__);
996  for (int xBin = 0; xBin < Binning->GetNAxisBins(Sample, 0); ++xBin) {
997  const int idx = Binning->GetGlobalBinSafe(Sample, {xBin});
998  // ROOT histograms are 1-based, so bin index + 1
999  SampleHandler_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(xBin + 1);
1000  }
1001  SampleDetails[Sample].DataHist->GetXaxis()->SetTitle(GetKinVarName(Sample, 0).c_str());
1002  SampleDetails[Sample].DataHist->GetYaxis()->SetTitle("Number of Events");
1003  } else if (Dim == 2) {
1004  if(Binning->IsUniform(Sample)) {
1005  ChecHistType("TH2D", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
1006  M3::CheckBinningMatch(static_cast<TH2D*>(SampleDetails[Sample].DataHist),
1007  static_cast<TH2D*>(SampleDetails[Sample].MCHist), __FILE__, __LINE__);
1008  for (int yBin = 0; yBin < Binning->GetNAxisBins(Sample, 1); ++yBin) {
1009  for (int xBin = 0; xBin < Binning->GetNAxisBins(Sample, 0); ++xBin) {
1010  const int idx = Binning->GetGlobalBinSafe(Sample, {xBin, yBin});
1011  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
1012  SampleHandler_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(xBin + 1, yBin + 1);
1013  }
1014  }
1015  } else{
1016  ChecHistType("TH2Poly", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
1017  M3::CheckBinningMatch(static_cast<TH2Poly*>(SampleDetails[Sample].DataHist),
1018  static_cast<TH2Poly*>(SampleDetails[Sample].MCHist), __FILE__, __LINE__);
1019  for (int iBin = 0; iBin < Binning->GetNBins(Sample); ++iBin) {
1020  const int idx = iBin + Binning->GetSampleStartBin(Sample);
1021  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
1022  SampleHandler_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(iBin + 1);
1023  }
1024  }
1025 
1026  SampleDetails[Sample].DataHist->GetXaxis()->SetTitle(GetKinVarName(Sample, 0).c_str());
1027  SampleDetails[Sample].DataHist->GetYaxis()->SetTitle(GetKinVarName(Sample, 1).c_str());
1028  SampleDetails[Sample].DataHist->GetZaxis()->SetTitle("Number of Events");
1029  } else {
1030  ChecHistType("TH1D", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
1031  M3::CheckBinningMatch(static_cast<TH1D*>(SampleDetails[Sample].DataHist),
1032  static_cast<TH1D*>(SampleDetails[Sample].MCHist), __FILE__, __LINE__);
1033  for (int iBin = 0; iBin < Binning->GetNBins(Sample); ++iBin) {
1034  const int idx = iBin + Binning->GetSampleStartBin(Sample);
1035  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
1036  SampleHandler_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(iBin + 1);
1037  }
1038  }
1039 }
int GetNDim(const int Sample) const final
DB Get what dimensionality binning for given sample has.
std::string GetKinVarName(const int iSample, const int Dimension) const final
Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino...
void CheckBinningMatch(const TH1D *Hist1, const TH1D *Hist2, const std::string &File, const int Line)
KS: Helper function check if data and MC binning matches.

◆ ApplyShifts()

void SampleHandlerBase::ApplyShifts ( const int  iEvent)
protectedvirtual

ETA - generic function applying shifts.

Definition at line 584 of file SampleHandlerBase.cpp.

584  {
585 // ***************************************************************************
586  const auto& shifts = funcParsGrid[iEvent];
587  const auto nShifts = shifts.size();
588  // KS: If there are no shifts then there is no point in resetting which can be costly.
589  if(nShifts == 0) {
590  return;
591  }
592 
593  // Given a sample and event, apply the shifts to the event based on the vector of functional parameter enums
594  // First reset shifted array back to nominal values
595  ResetShifts(iEvent);
596 
597  for (std::size_t iShift = 0; iShift < nShifts; ++iShift) {
598  const auto* _restrict_ fp = shifts[iShift];
599  (*fp->funcPtr)(fp->valuePtr, iEvent);
600  }
601 
602  FinaliseShifts(iEvent);
603 }
#define _restrict_
KS: Using restrict limits the effects of pointer aliasing, aiding optimizations. While reading I foun...
Definition: Core.h:108
virtual void FinaliseShifts(const int iEvent)
LP - Optionally calculate derived observables after all shifts have been applied.
virtual void ResetShifts(const int iEvent)
HH - reset the shifted values to the original values.
std::vector< std::vector< FunctionalShifter * > > funcParsGrid
HH - a grid of vectors of enums for each sample and event.

◆ ApplyTemporarySelection()

std::vector< std::vector< KinematicCut > > SampleHandlerBase::ApplyTemporarySelection ( const int  iSample,
const std::vector< KinematicCut > &  ExtraCuts 
)
private

Temporarily extend Selection for a given sample with additional cuts. Returns the original Selection so the caller can restore it later.

Definition at line 1440 of file SampleHandlerBase.cpp.

1441  {
1442 // ************************************************
1443  // Backup current selection
1444  auto originalSelection = Selection;
1445 
1446  //DB Add all the predefined selections to the selection vector which will be applied
1447  auto selectionToApply = Selection;
1448 
1449  //DB Add all requested cuts from the argument to the selection vector which will be applied
1450  for (const auto& cut : ExtraCuts) {
1451  selectionToApply[iSample].emplace_back(cut);
1452  }
1453 
1454  //DB Set the member variable to be the cuts to apply
1455  Selection = std::move(selectionToApply);
1456 
1457  return originalSelection;
1458 }
std::vector< std::vector< KinematicCut > > Selection
a way to store selection cuts which you may push back in the get1DVar functions most of the time this...

◆ BuildModeChannelSelection()

std::vector< KinematicCut > SampleHandlerBase::BuildModeChannelSelection ( const int  iSample,
const int  kModeToFill,
const int  kChannelToFill 
) const

Construct vector of kinematic cuts that will be applied, on top of default cuts include stuff like cut on mode etc.

Parameters
SampleIndex of the sample.

Definition at line 1773 of file SampleHandlerBase.cpp.

1773  {
1774 // ************************************************
1775  bool fChannel;
1776  bool fMode;
1777 
1778  if (kChannelToFill != -1) {
1779  if (kChannelToFill > GetNOscChannels(iSample)) {
1780  MACH3LOG_ERROR("Required channel is not available. kChannelToFill should be between 0 and {}", GetNOscChannels(iSample));
1781  MACH3LOG_ERROR("kChannelToFill given:{}", kChannelToFill);
1782  MACH3LOG_ERROR("Exiting.");
1783  throw MaCh3Exception(__FILE__, __LINE__);
1784  }
1785  fChannel = true;
1786  } else {
1787  fChannel = false;
1788  }
1789 
1790  if (kModeToFill != -1) {
1791  if (!(kModeToFill >= 0) && (kModeToFill < Modes->GetNModes())) {
1792  MACH3LOG_ERROR("Required mode is not available. kModeToFill should be between 0 and {}", Modes->GetNModes());
1793  MACH3LOG_ERROR("kModeToFill given:{}", kModeToFill);
1794  MACH3LOG_ERROR("Exiting..");
1795  throw MaCh3Exception(__FILE__, __LINE__);
1796  }
1797  fMode = true;
1798  } else {
1799  fMode = false;
1800  }
1801 
1802  std::vector< KinematicCut > SelectionVec;
1803 
1804  if (fMode) {
1805  KinematicCut SelecMode;
1807  SelecMode.LowerBound = kModeToFill;
1808  SelecMode.UpperBound = kModeToFill+1;
1809  SelectionVec.push_back(SelecMode);
1810  }
1811 
1812  if (fChannel) {
1813  KinematicCut SelecChannel;
1814  SelecChannel.ParamToCutOnIt = ReturnKinematicParameterFromString("OscillationChannel");
1815  SelecChannel.LowerBound = kChannelToFill;
1816  SelecChannel.UpperBound = kChannelToFill+1;
1817  SelectionVec.push_back(SelecChannel);
1818  }
1819 
1820  return SelectionVec;
1821 }
int GetNOscChannels(const int iSample) const final
Get number of oscillation channels for a single sample.
int ReturnKinematicParameterFromString(const std::string &KinematicStr) const
ETA function to generically convert a string from xsec cov to a kinematic type.
std::unique_ptr< MaCh3Modes > Modes
Holds information about used Generator and MaCh3 modes.
KS: Small struct used for applying kinematic cuts.
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.

◆ CalcNormsBins()

void SampleHandlerBase::CalcNormsBins ( std::vector< std::vector< NormParameter >> &  norm_parameters,
std::vector< std::vector< int > > &  norms_bins 
)
protected

Check whether a normalisation systematic affects an event or not.

Parameters
norm_parametersindexed [sample][param] describe norm params and associated kinematic cuts etc.

Definition at line 696 of file SampleHandlerBase.cpp.

696  {
697 // ************************************************
698  for(unsigned int iEvent = 0; iEvent < GetNEvents(); ++iEvent){
699  std::vector< int > NormBins = {};
700  if (ParHandler) {
701  const auto SampleId = MCEvents[iEvent].NominalSample;
702  auto& NormParam = norm_parameters[SampleId];
703  // Skip oscillated NC events
704  // Not strictly needed, but these events don't get included in oscillated predictions, so
705  // no need to waste our time calculating and storing information about xsec parameters
706  // that will never be used.
707  if (MCEvents[iEvent].isNC && (MCEvents[iEvent].nupdg != MCEvents[iEvent].nupdgUnosc) ) {
708  MACH3LOG_TRACE("Event {}, missed NC/signal check", iEvent);
709  continue;
710  } //DB Abstract check on MaCh3Modes to determine which apply to neutral current
711  for (std::vector<NormParameter>::iterator it = NormParam.begin(); it != NormParam.end(); ++it) {
712  //Now check that the target of an interaction matches with the normalisation parameters
713  const int Target = static_cast<int>(std::round(ReturnKinematicParameter("TargetNucleus", iEvent)));
714  bool TargetMatch = MatchCondition(it->targets, Target);
715  if (!TargetMatch) {
716  MACH3LOG_TRACE("Event {}, missed target check ({}) for dial {}", iEvent, Target, it->name);
717  continue;
718  }
719 
720  //Now check that the neutrino flavour in an interaction matches with the normalisation parameters
721  bool FlavourMatch = MatchCondition(it->pdgs, MCEvents[iEvent].nupdg);
722  if (!FlavourMatch) {
723  MACH3LOG_TRACE("Event {}, missed PDG check ({}) for dial {}", iEvent,MCEvents[iEvent].nupdg, it->name);
724  continue;
725  }
726 
727  //Now check that the unoscillated neutrino flavour in an interaction matches with the normalisation parameters
728  bool FlavourUnoscMatch = MatchCondition(it->preoscpdgs, MCEvents[iEvent].nupdgUnosc);
729  if (!FlavourUnoscMatch){
730  MACH3LOG_TRACE("Event {}, missed FlavourUnosc check ({}) for dial {}", iEvent,MCEvents[iEvent].nupdgUnosc, it->name);
731  continue;
732  }
733 
734  //Now check that the mode of an interaction matches with the normalisation parameters
735  const int Mode = static_cast<int>(std::round(ReturnKinematicParameter("Mode", iEvent)));
736  bool ModeMatch = MatchCondition(it->modes, Mode);
737  if (!ModeMatch) {
738  MACH3LOG_TRACE("Event {}, missed Mode check ({}) for dial {}", iEvent, Mode, it->name);
739  continue;
740  }
741 
742  //Now check whether the norm has kinematic bounds
743  //i.e. does it only apply to events in a particular kinematic region?
744  // Now check whether within kinematic bounds
745  bool IsSelected = PassesSelection((*it), iEvent);
746  // Need to then break the event loop
747  if(!IsSelected){
748  MACH3LOG_TRACE("Event {}, missed Kinematic var check for dial {}", iEvent, it->name);
749  continue;
750  }
751  // Now set 'index bin' for each normalisation parameter
752  // All normalisations are just 1 bin for 2015, so bin = index (where index is just the bin for that normalisation)
753  int bin = it->index;
754 
755  NormBins.push_back(bin);
756  MACH3LOG_TRACE("Event {}, will be affected by dial {}", iEvent, it->name);
757  } // end iteration over norm_parameters
758  } // end if (ParHandler)
759  norms_bins[iEvent] = NormBins;
760  }//end loop over events
761 }
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33
bool PassesSelection(const ParT &Par, std::size_t iEvent)
double ReturnKinematicParameter(const std::string &KinematicParameter, int iEvent) const
Return the value of an associated kinematic parameter for an event.
std::vector< EventInfo > MCEvents
Stores information about every MC event.
bool MatchCondition(const std::vector< T > &allowedValues, const T &value)
check if event is affected by following conditions, for example pdg, or modes etc
unsigned int GetNEvents() const
Return total number of events.

◆ CalcWeightFunc()

virtual void SampleHandlerBase::CalcWeightFunc ( const int  iEvent)
inlineprotectedvirtual

Calculate weights for function parameters.

First you need to setup additional pointers in you experiment code in SetupWeightPointers Then in this function you can calculate whatever fancy function you want by filling weight to which you have pointer This way func weight shall be used in GetEventWeight

Definition at line 326 of file SampleHandlerBase.h.

326 {return; (void)iEvent;};

◆ CalcWeightTotal()

M3::float_t SampleHandlerBase::CalcWeightTotal ( const EventInfo *_restrict_  MCEvent) const
protected

Calculate the total weight weight for a given event.

Definition at line 607 of file SampleHandlerBase.cpp.

607  {
608 // ***************************************************************************
609  M3::float_t TotalWeight = 1.0;
610  const int TotalWeights = static_cast<int>(MCEvent->total_weight_pointers.size());
611  //DB Loop over stored pointers
612  #ifdef MULTITHREAD
613  #pragma omp simd reduction(*:TotalWeight)
614  #endif
615  for (int iWeight = 0; iWeight < TotalWeights; ++iWeight) {
616  TotalWeight *= *(MCEvent->total_weight_pointers[iWeight]);
617  }
618 
619  return TotalWeight;
620 }
double float_t
Definition: Core.h:37
std::vector< const M3::float_t * > total_weight_pointers
Pointers to weights like oscillation spline, normalisation etc.
Definition: EventInfo.h:28

◆ CheckEmptyBins()

void SampleHandlerBase::CheckEmptyBins ( ) const

Loop over bins and checks if there are any which have 0 entries.

Definition at line 2069 of file SampleHandlerBase.cpp.

2069  {
2070 // ***************************************************************************
2071  const auto TotalBins = Binning->GetNBins();
2072  int iCounter = 0;
2073  for(int iBin = 0; iBin < TotalBins; iBin++) {
2074  if(SampleHandler_array[iBin] == 0) {
2075  iCounter++;
2076  MACH3LOG_DEBUG("Bin {}, for sample {}, has 0 entries",
2077  Binning->GetBinName(iBin), GetSampleTitle(Binning->GetSampleIndex(iBin)));
2078  }
2079  }
2080 
2081  if(iCounter > 0){
2082  MACH3LOG_WARN("Found in total {} ({:.2f}%) empty bins for SampleHandler: {}",
2083  iCounter, 100.0 * static_cast<double>(iCounter) / TotalBins, GetName());
2084  }
2085 }
std::string GetName() const final
Get name for Sample Handler.
std::vector< double > SampleHandler_array
DB Array to be filled after reweighting.

◆ Fill1DSubEventHist()

void SampleHandlerBase::Fill1DSubEventHist ( const int  iSample,
TH1D *  _h1DVar,
const std::string &  ProjectionVar,
const std::vector< KinematicCut > &  SubEventSelectionVec = {},
int  WeightStyle = 0 
)

Fill projection histogram by looping over all events, and skipping one which doesn't pass specified condition.

Definition at line 1505 of file SampleHandlerBase.cpp.

1506  {
1507 // ************************************************
1508  int ProjectionVar_Int = ReturnKinematicVectorFromString(ProjectionVar_Str);
1509 
1510  //JM Loop over all events
1511  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1512  const int EventSample = MCEvents[iEvent].NominalSample;
1513  if(EventSample != iSample) continue;
1514  if (IsEventSelected(EventSample, iEvent)) {
1515  double Weight = GetEventWeight(iEvent);
1516  if (WeightStyle == 1) {
1517  Weight = 1.;
1518  }
1519  std::vector<double> Vec = ReturnKinematicVector(ProjectionVar_Int,iEvent);
1520  size_t nsubevents = Vec.size();
1521  //JM Loop over all subevents in event
1522  for (unsigned int iSubEvent = 0; iSubEvent < nsubevents; iSubEvent++) {
1523  if (IsSubEventSelected(SubEventSelectionVec, iEvent, iSubEvent, nsubevents)) {
1524  double Var = Vec[iSubEvent];
1525  _h1DVar->Fill(Var,Weight);
1526  }
1527  }
1528  }
1529  }
1530 }
M3::float_t GetEventWeight(const int iEvent)
Computes the total event weight for a given entry.
std::vector< double > ReturnKinematicVector(const std::string &KinematicParameter, const int iEvent) const
bool IsEventSelected(const int iSample, const int iEvent) _noexcept_
DB Function which determines if an event is selected based on KinematicCut.
bool IsSubEventSelected(const std::vector< KinematicCut > &SubEventCuts, const int iEvent, unsigned const int iSubEvent, size_t nsubevents)
JM Function which determines if a subevent is selected.
int ReturnKinematicVectorFromString(const std::string &KinematicStr) const
JM: Convert a kinematic vector name to its corresponding integer ID.

◆ Fill2DSubEventHist()

void SampleHandlerBase::Fill2DSubEventHist ( const int  iSample,
TH2 *  _h2DVar,
const std::string &  ProjectionVarX,
const std::string &  ProjectionVarY,
const std::vector< KinematicCut > &  SubEventSelectionVec = {},
int  WeightStyle = 0 
)

Fill projection histogram by looping over all events, and skipping one which doesn't pass specified condition.

Definition at line 1589 of file SampleHandlerBase.cpp.

1593  {
1594 // ************************************************
1595  bool IsSubEventVarX = IsSubEventVarString(ProjectionVar_StrX);
1596  bool IsSubEventVarY = IsSubEventVarString(ProjectionVar_StrY);
1597 
1598  int ProjectionVar_IntX, ProjectionVar_IntY;
1599  if (IsSubEventVarX) ProjectionVar_IntX = ReturnKinematicVectorFromString(ProjectionVar_StrX);
1600  else ProjectionVar_IntX = ReturnKinematicParameterFromString(ProjectionVar_StrX);
1601  if (IsSubEventVarY) ProjectionVar_IntY = ReturnKinematicVectorFromString(ProjectionVar_StrY);
1602  else ProjectionVar_IntY = ReturnKinematicParameterFromString(ProjectionVar_StrY);
1603 
1604  //JM Loop over all events
1605  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1606  const int EventSample = MCEvents[iEvent].NominalSample;
1607  if(EventSample != iSample) continue;
1608  if (IsEventSelected(EventSample, iEvent)) {
1609  double Weight = GetEventWeight(iEvent);
1610  if (WeightStyle == 1) {
1611  Weight = 1.;
1612  }
1613  std::vector<double> VecX = {}, VecY = {};
1614  double VarX = M3::_BAD_DOUBLE_, VarY = M3::_BAD_DOUBLE_;
1615  size_t nsubevents = 0;
1616  // JM Three cases: subeventX vs eventY || eventX vs subeventY || subeventX vs subeventY
1617  if (IsSubEventVarX && !IsSubEventVarY) {
1618  VecX = ReturnKinematicVector(ProjectionVar_IntX, iEvent);
1619  VarY = ReturnKinematicParameter(ProjectionVar_IntY, iEvent);
1620  nsubevents = VecX.size();
1621  }
1622  else if (!IsSubEventVarX && IsSubEventVarY) {
1623  VecY = ReturnKinematicVector(ProjectionVar_IntY, iEvent);
1624  VarX = ReturnKinematicParameter(ProjectionVar_IntX, iEvent);
1625  nsubevents = VecY.size();
1626  }
1627  else {
1628  VecX = ReturnKinematicVector(ProjectionVar_IntX, iEvent);
1629  VecY = ReturnKinematicVector(ProjectionVar_IntY, iEvent);
1630  if (VecX.size() != VecY.size()) {
1631  MACH3LOG_ERROR("Cannot plot {} of size {} against {} of size {}", ProjectionVar_StrX, VecX.size(), ProjectionVar_StrY, VecY.size());
1632  throw MaCh3Exception(__FILE__, __LINE__);
1633  }
1634  nsubevents = VecX.size();
1635  }
1636  //JM Loop over all subevents in event
1637  for (unsigned int iSubEvent = 0; iSubEvent < nsubevents; iSubEvent++) {
1638  if (IsSubEventSelected(SubEventSelectionVec, iEvent, iSubEvent, nsubevents)) {
1639  if (IsSubEventVarX) VarX = VecX[iSubEvent];
1640  if (IsSubEventVarY) VarY = VecY[iSubEvent];
1641  _h2DVar->Fill(VarX,VarY,Weight);
1642  }
1643  }
1644  }
1645  }
1646 }
bool IsSubEventVarString(const std::string &VarStr) const
JM: Check if a kinematic parameter string corresponds to a subevent-level variable.
constexpr static const double _BAD_DOUBLE_
Default value used for double initialisation.
Definition: Core.h:53

◆ FillArray()

void SampleHandlerBase::FillArray ( )
protected

Function which does the core reweighting, fills the SampleHandlerBase::SampleHandler_array vector with the weight calculated from reweighting.

Definition at line 383 of file SampleHandlerBase.cpp.

383  {
384 //************************************************
385  //DB Reset which cuts to apply
387 
388  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
389  ApplyShifts(iEvent);
390  const EventInfo* _restrict_ MCEvent = &MCEvents[iEvent];
391 
392  if (!IsEventSelected(MCEvent->NominalSample, iEvent)) {
393  continue;
394  }
395 
396  // Virtual by default does nothing, has to happen before CalcWeightTotal
397  CalcWeightFunc(iEvent);
398 
399  const M3::float_t totalweight = CalcWeightTotal(MCEvent);
400  //DB Catch negative total weights and skip any event with a negative weight. Previously we would set weight to zero and continue but that is inefficient
401  if (totalweight <= 0.){
402  continue;
403  }
404 
405  //DB Find the relevant bin in the PDF for each event
406  const int GlobalBin = Binning->FindGlobalBin(MCEvent->NominalSample, MCEvent->KinVar, MCEvent->NomBin);
407 
408  //DB Fill relevant part of thread array
409  if (GlobalBin > M3::UnderOverFlowBin) {
410  SampleHandler_array[GlobalBin] += totalweight;
411  if (FirstTimeW2) SampleHandler_array_w2[GlobalBin] += totalweight*totalweight;
412  }
413  }
414 }
std::vector< std::vector< KinematicCut > > StoredSelection
What gets pulled from config options, these are constant after loading in this is of length 3: 0th in...
virtual void ApplyShifts(const int iEvent)
ETA - generic function applying shifts.
M3::float_t CalcWeightTotal(const EventInfo *_restrict_ MCEvent) const _noexcept_
Calculate the total weight weight for a given event.
std::vector< double > SampleHandler_array_w2
KS Array used for MC stat.
virtual void CalcWeightFunc(const int iEvent)
Calculate weights for function parameters.
constexpr static const int UnderOverFlowBin
Mark bin which is overflow or underflow in MaCh3 binning.
Definition: Core.h:91
Stores info about each MC event used during reweighting routine.
Definition: EventInfo.h:13

◆ FillArray_MP()

void SampleHandlerBase::FillArray_MP ( )
protected

DB Nice new multi-threaded function which calculates the event weights and fills the relevant bins of an array.

Multithreaded version of fillArray.

Function which does the core reweighting, fills the SampleHandlerBase::SampleHandler_array vector with the weight calculated from reweighting but multithreaded

See also
fillArray()

Definition at line 421 of file SampleHandlerBase.cpp.

421  {
422 // ************************************************
423  //DB Reset which cuts to apply
425 
426  // NOTE comment below is left for historical reasons
427  //DB - Brain dump of speedup ideas
428  //
429  //Those relevant to reweighting
430  // 1. Don't bother storing and calculating NC signal events - Implemented and saves marginal s/step
431  // 2. Loop over spline event weight calculation in the following event loop - Currently done in splineSKBase->calcWeight() where multi-threading won't be optimised - Implemented and saves 0.3s/step
432  // 3. Inline getDiscVar or somehow include that calculation inside the multi-threading - Implemented and saves about 0.01s/step
433  // 4. Include isCC inside SKMCStruct so don't have to have several 'if' statements determine if oscillation weight needs to be set to 1.0 for NC events - Implemented and saves marginal s/step
434  // 5. Do explicit check on adjacent bins when finding event XBin instead of looping over all BinEdge indices - Implemented but doesn't significantly affect s/step
435  //
436  //Other aspects
437  // 1. Order minituples in Y-axis variable as this will *hopefully* reduce cache misses inside SampleHandler_array_class[yBin][xBin]
438  //
439  // We will hit <0.1 s/step eventually! :D
440  const auto TotalBins = Binning->GetNBins();
441  const unsigned int NumberOfEvents = GetNEvents();
442 
443  double* _restrict_ MC_Array_for_reduction = SampleHandler_array.data();
444  double* _restrict_ W2_array_for_reduction = SampleHandler_array_w2.data();
445 
446  #pragma omp parallel for reduction(+:MC_Array_for_reduction[:TotalBins], W2_array_for_reduction[:TotalBins])
447  for (unsigned int iEvent = 0; iEvent < NumberOfEvents; ++iEvent) {
448  //ETA - generic functions to apply shifts to kinematic variables
449  // Apply this before IsEventSelected is called.
450  ApplyShifts(iEvent);
451 
452  const EventInfo* _restrict_ MCEvent = &MCEvents[iEvent];
453  //ETA - generic functions to apply shifts to kinematic variable
454  if(!IsEventSelected(MCEvent->NominalSample, iEvent)){
455  continue;
456  }
457 
458  // Virtual by default does nothing, has to happen before CalcWeightTotal
459  CalcWeightFunc(iEvent);
460 
461  const M3::float_t totalweight = CalcWeightTotal(MCEvent);
462  //DB Catch negative total weights and skip any event with a negative weight. Previously we would set weight to zero and continue but that is inefficient
463  if (totalweight <= 0.){
464  continue;
465  }
466 
467  //DB Find the relevant bin in the PDF for each event
468  const int GlobalBin = Binning->FindGlobalBin(MCEvent->NominalSample, MCEvent->KinVar, MCEvent->NomBin);
469 
470  //ETA - we can probably remove this final if check on the -1?
471  //Maybe we can add an overflow bin to the array and assign any events to this bin?
472  //Might save us an extra if call?
473  //DB Fill relevant part of thread array
474  if (GlobalBin > M3::UnderOverFlowBin) {
475  MC_Array_for_reduction[GlobalBin] += totalweight;
476  if (FirstTimeW2) W2_array_for_reduction[GlobalBin] += totalweight*totalweight;
477  }
478  }
479 }

◆ FillHist()

void SampleHandlerBase::FillHist ( const int  Sample,
TH1 *  Hist,
std::vector< double > &  Array 
)
protected

Fill a histogram with the event-level information used in the fit.

DB Functions required for reweighting functions DB Replace previous implementation with reading bin contents from SampleHandler_array

Definition at line 273 of file SampleHandlerBase.cpp.

273  {
274 // ************************************************
275  int Dimension = GetNDim(Sample);
276  // DB Commented out by default - Code heading towards GetLikelihood using arrays instead of root objects
277  // Wouldn't actually need this for GetLikelihood as TH objects wouldn't be filled
278  if(Dimension == 1) {
279  Hist->Reset();
280  for (int xBin = 0; xBin < Binning->GetNAxisBins(Sample, 0); ++xBin) {
281  const int idx = Binning->GetGlobalBinSafe(Sample, {xBin});
282  Hist->SetBinContent(xBin + 1, Array[idx]);
283  }
284  } else if (Dimension == 2) {
285  Hist->Reset();
286  if(Binning->IsUniform(Sample)) {
287  for (int yBin = 0; yBin < Binning->GetNAxisBins(Sample, 1); ++yBin) {
288  for (int xBin = 0; xBin < Binning->GetNAxisBins(Sample, 0); ++xBin) {
289  const int idx = Binning->GetGlobalBinSafe(Sample, {xBin, yBin});
290  Hist->SetBinContent(xBin + 1, yBin + 1, Array[idx]);
291  }
292  }
293  } else {
294  for (int iBin = 0; iBin < Binning->GetNBins(Sample); ++iBin) {
295  const int idx = iBin + Binning->GetSampleStartBin(Sample);
296  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
297  Hist->SetBinContent(iBin + 1, Array[idx]);
298  }
299  }
300  } else {
301  for (int iBin = 0; iBin < Binning->GetNBins(Sample); ++iBin) {
302  const int idx = iBin + Binning->GetSampleStartBin(Sample);
303  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
304  Hist->SetBinContent(iBin + 1, Array[idx]);
305  }
306  }
307 }

◆ FinaliseShifts()

virtual void SampleHandlerBase::FinaliseShifts ( const int  iEvent)
inlineprotectedvirtual

LP - Optionally calculate derived observables after all shifts have been applied.

LP - For example, have shifts that varied lepton energy and hadron energy separately in a subclass implementation of this method you may add the shifted quantities together to build a shifted neutrino energy estimator

Definition at line 291 of file SampleHandlerBase.h.

291 {(void)iEvent;};

◆ FindNominalBinAndEdges()

void SampleHandlerBase::FindNominalBinAndEdges ( )
protected

Definition at line 873 of file SampleHandlerBase.cpp.

873  {
874 // ************************************************
875  for (unsigned int event_i = 0; event_i < GetNEvents(); event_i++) {
876  int Sample = MCEvents[event_i].NominalSample;
877  const int dim = GetNDim(Sample);
878  MCEvents[event_i].KinVar.resize(dim);
879  MCEvents[event_i].NomBin.resize(dim);
880 
881  auto SetNominalBin = [&](int bin, int max_bins, int& out_bin) {
882  if (bin >= 0 && bin < max_bins) {
883  out_bin = bin;
884  } else {
885  out_bin = M3::UnderOverFlowBin; // Out of bounds
886  }
887  };
888 
889  // Find nominal bin for each dimension
890  for(int iDim = 0; iDim < dim; iDim++) {
891  MCEvents[event_i].KinVar[iDim] = GetPointerToKinematicParameter(GetKinVarName(Sample, iDim), event_i);
892  if (std::isnan(*MCEvents[event_i].KinVar[iDim]) || std::isinf(*MCEvents[event_i].KinVar[iDim])) {
893  MACH3LOG_ERROR("Variable {} for sample {} and dimension {} is ill-defined and equal to {}",
894  GetKinVarName(Sample, iDim), GetSampleTitle(Sample), dim, *MCEvents[event_i].KinVar[iDim]);
895  throw MaCh3Exception(__FILE__, __LINE__);
896  }
897  const int bin = Binning->FindNominalBin(Sample, iDim, *MCEvents[event_i].KinVar[iDim]);
898  int NBins_i = static_cast<int>(Binning->GetBinEdges(Sample, iDim).size() - 1);
899  SetNominalBin(bin, NBins_i, MCEvents[event_i].NomBin[iDim]);
900  }
901  }
902 }
const double * GetPointerToKinematicParameter(const std::string &KinematicParameter, int iEvent) const

◆ Get1DVarHist()

std::unique_ptr< TH1 > SampleHandlerBase::Get1DVarHist ( const int  iSample,
const std::string &  ProjectionVar,
const std::vector< KinematicCut > &  EventSelectionVec = {},
int  WeightStyle = 0,
const std::vector< KinematicCut > &  SubEventSelectionVec = {} 
)
finalvirtual

Return 1D projection of MC into given 1D variable (doesn't have to be variable used in the fit)

Parameters
iSampleIndex of the sample.
ProjectionVarname of variable
EventSelectionVecVector of additional cuts like cut on interaction mode
WeightStyleAlow to modify weight for example if equal to 1 all weights are set to 1
SubEventSelectionVecVector of additional cuts for sub event (particle, ring etc.)

Implements SampleHandlerInterface.

Definition at line 1462 of file SampleHandlerBase.cpp.

1465  {
1466 // ************************************************
1467  //DB Need to overwrite the Selection member variable so that IsEventSelected function operates correctly.
1468  // Consequently, store the selection cuts already saved in the sample, overwrite the Selection variable, then reset
1469  auto tmp_Selection = ApplyTemporarySelection(iSample, EventSelectionVec);
1470 
1471  //DB Define the histogram which will be returned
1472  std::vector<double> xBinEdges = ReturnKinematicParameterBinning(iSample, ProjectionVar_Str);
1473  auto _h1DVar = std::make_unique<TH1D>("", "", int(xBinEdges.size())-1, xBinEdges.data());
1474  _h1DVar->SetDirectory(nullptr);
1475  _h1DVar->GetXaxis()->SetTitle(ProjectionVar_Str.c_str());
1476  _h1DVar->GetYaxis()->SetTitle("Events");
1477 
1478  if (IsSubEventVarString(ProjectionVar_Str)) {
1479  Fill1DSubEventHist(iSample, _h1DVar.get(), ProjectionVar_Str, SubEventSelectionVec, WeightStyle);
1480  } else {
1481  //DB Grab the associated enum with the argument string
1482  int ProjectionVar_Int = ReturnKinematicParameterFromString(ProjectionVar_Str);
1483 
1484  //DB Loop over all events
1485  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1486  const int EventSample = MCEvents[iEvent].NominalSample;
1487  if(EventSample != iSample) continue;
1488  if (IsEventSelected(EventSample, iEvent)) {
1489  double Weight = GetEventWeight(iEvent);
1490  if (WeightStyle == 1) {
1491  Weight = 1.;
1492  }
1493  double Var = ReturnKinematicParameter(ProjectionVar_Int, iEvent);
1494  _h1DVar->Fill(Var, Weight);
1495  }
1496  }
1497  }
1498  //DB Reset the saved selection
1499  Selection = tmp_Selection;
1500 
1501  return _h1DVar;
1502 }
std::vector< double > ReturnKinematicParameterBinning(const int Sample, const std::string &KinematicParameter) const final
Return the binning used to draw a kinematic parameter.
void Fill1DSubEventHist(const int iSample, TH1D *_h1DVar, const std::string &ProjectionVar, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)
Fill projection histogram by looping over all events, and skipping one which doesn't pass specified c...
std::vector< std::vector< KinematicCut > > ApplyTemporarySelection(const int iSample, const std::vector< KinematicCut > &ExtraCuts)
Temporarily extend Selection for a given sample with additional cuts. Returns the original Selection ...

◆ Get1DVarHistByModeAndChannel()

std::unique_ptr< TH1 > SampleHandlerBase::Get1DVarHistByModeAndChannel ( const int  iSample,
const std::string &  ProjectionVar_Str,
const int  kModeToFill = -1,
const int  kChannelToFill = -1,
const int  WeightStyle = 0 
)
finalvirtual

Build a 1D histogram for a given variable, optionally filtered by mode and channel.

Parameters
iSampleIndex of the sample.
ProjectionVar_StrName of the variable to project onto.
kModeToFillInteraction mode to select (-1 means all modes).
kChannelToFillOscillation channel to select (-1 means all channels).
WeightStyleWeighting scheme (e.g. 0 = nominal weights, 1 = unit weights).

Implements SampleHandlerInterface.

Definition at line 1824 of file SampleHandlerBase.cpp.

1825  {
1826 // ************************************************
1827  auto SelectionVec = BuildModeChannelSelection(iSample, kModeToFill, kChannelToFill);
1828  return Get1DVarHist(iSample, ProjectionVar_Str, SelectionVec, WeightStyle);
1829 }
std::vector< KinematicCut > BuildModeChannelSelection(const int iSample, const int kModeToFill, const int kChannelToFill) const
Construct vector of kinematic cuts that will be applied, on top of default cuts include stuff like cu...
std::unique_ptr< TH1 > Get1DVarHist(const int iSample, const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={}) final
Return 1D projection of MC into given 1D variable (doesn't have to be variable used in the fit)

◆ Get2DVarHist()

std::unique_ptr< TH2 > SampleHandlerBase::Get2DVarHist ( const int  iSample,
const std::string &  ProjectionVarX,
const std::string &  ProjectionVarY,
const std::vector< KinematicCut > &  EventSelectionVec = {},
int  WeightStyle = 0,
const std::vector< KinematicCut > &  SubEventSelectionVec = {} 
)
finalvirtual

Build a 2D projection of MC events into specified variables.

Parameters
iSampleIndex of the sample.
ProjectionVarXName of the variable for the X axis.
ProjectionVarYName of the variable for the Y axis.
EventSelectionVecVector of event-level selection cuts.
WeightStyleWeighting scheme (e.g. 0 = nominal weights, 1 = unit weights).
SubEventSelectionVecVector of sub-event selection cuts.

Implements SampleHandlerInterface.

Definition at line 1533 of file SampleHandlerBase.cpp.

1538  {
1539 // ************************************************
1540  //DB Need to overwrite the Selection member variable so that IsEventSelected function operates correctly.
1541  // Consequently, store the selection cuts already saved in the sample, overwrite the Selection variable, then reset
1542  auto tmp_Selection = ApplyTemporarySelection(iSample, EventSelectionVec);
1543 
1544  //DB Define the histogram which will be returned
1545  //KS: If we use 2D non uniform binning and wanting to plot fit variables use TH2Poly everything else uses TH2D with binning from config
1546  std::unique_ptr<TH2> _h2DVar;
1547  if(GetNDim(iSample) == 2 && !Binning->IsUniform(iSample) &&
1548  ProjectionVar_StrX == GetKinVarName(iSample, 0) && ProjectionVar_StrY == GetKinVarName(iSample, 1) ) {
1549  _h2DVar = std::unique_ptr<TH2>(static_cast<TH2*>(M3::Clone(GetMCHist(iSample)).release()));
1550  } else {
1551  std::vector<double> xBinEdges = ReturnKinematicParameterBinning(iSample, ProjectionVar_StrX);
1552  std::vector<double> yBinEdges = ReturnKinematicParameterBinning(iSample, ProjectionVar_StrY);
1553  _h2DVar = std::make_unique<TH2D>("", "", int(xBinEdges.size())-1, xBinEdges.data(), int(yBinEdges.size())-1, yBinEdges.data());
1554  }
1555  _h2DVar->SetDirectory(nullptr);
1556  _h2DVar->GetXaxis()->SetTitle(ProjectionVar_StrX.c_str());
1557  _h2DVar->GetYaxis()->SetTitle(ProjectionVar_StrY.c_str());
1558  _h2DVar->GetZaxis()->SetTitle("Events");
1559 
1560  bool IsSubEventHist = IsSubEventVarString(ProjectionVar_StrX) || IsSubEventVarString(ProjectionVar_StrY);
1561  if (IsSubEventHist) Fill2DSubEventHist(iSample, _h2DVar.get(), ProjectionVar_StrX, ProjectionVar_StrY, SubEventSelectionVec, WeightStyle);
1562  else {
1563  //DB Grab the associated enum with the argument string
1564  int ProjectionVar_IntX = ReturnKinematicParameterFromString(ProjectionVar_StrX);
1565  int ProjectionVar_IntY = ReturnKinematicParameterFromString(ProjectionVar_StrY);
1566 
1567  //DB Loop over all events
1568  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1569  const int EventSample = MCEvents[iEvent].NominalSample;
1570  if(EventSample != iSample) continue;
1571  if (IsEventSelected(EventSample, iEvent)) {
1572  double Weight = GetEventWeight(iEvent);
1573  if (WeightStyle == 1) {
1574  Weight = 1.;
1575  }
1576  double VarX = ReturnKinematicParameter(ProjectionVar_IntX, iEvent);
1577  double VarY = ReturnKinematicParameter(ProjectionVar_IntY, iEvent);
1578  _h2DVar->Fill(VarX,VarY,Weight);
1579  }
1580  }
1581  }
1582  //DB Reset the saved selection
1583  Selection = tmp_Selection;
1584 
1585  return _h2DVar;
1586 }
void Fill2DSubEventHist(const int iSample, TH2 *_h2DVar, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)
Fill projection histogram by looping over all events, and skipping one which doesn't pass specified c...
const TH1 * GetMCHist(const int Sample) final
Get MC histogram.
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.

◆ Get2DVarHistByModeAndChannel()

std::unique_ptr< TH2 > SampleHandlerBase::Get2DVarHistByModeAndChannel ( const int  iSample,
const std::string &  ProjectionVar_StrX,
const std::string &  ProjectionVar_StrY,
const int  kModeToFill = -1,
const int  kChannelToFill = -1,
const int  WeightStyle = 0 
)
finalvirtual

Build a 2D histogram for given variables, optionally filtered by mode and channel.

Parameters
iSampleIndex of the sample.
ProjectionVar_StrXName of the variable for the X axis.
ProjectionVar_StrYName of the variable for the Y axis.
kModeToFillInteraction mode to select (-1 means all modes).
kChannelToFillOscillation channel to select (-1 means all channels).
WeightStyleWeighting scheme (e.g. 0 = nominal weights, 1 = unit weights).

Implements SampleHandlerInterface.

Definition at line 1832 of file SampleHandlerBase.cpp.

1834  {
1835 // ************************************************
1836  auto SelectionVec = BuildModeChannelSelection(iSample, kModeToFill, kChannelToFill);
1837  return Get2DVarHist(iSample, ProjectionVar_StrX, ProjectionVar_StrY, SelectionVec, WeightStyle);
1838 }
std::unique_ptr< TH2 > Get2DVarHist(const int iSample, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={}) final
Build a 2D projection of MC events into specified variables.

◆ GetArrayForSample()

std::vector< double > SampleHandlerBase::GetArrayForSample ( const int  Sample,
std::vector< double > const &  array 
) const

Return a sub-array for a given sample.

Definition at line 2151 of file SampleHandlerBase.cpp.

2151  {
2152 // ***************************************************************************
2153  const int Start = Binning->GetSampleStartBin(Sample);
2154  const int End = Binning->GetSampleEndBin(Sample);
2155 
2156  return std::vector<double>(array.begin() + Start, array.begin() + End);
2157 }

◆ GetDataArray() [1/2]

auto SampleHandlerBase::GetDataArray ( ) const
inline

Return array storing data entries for every bin.

Definition at line 176 of file SampleHandlerBase.h.

176  {
177  return SampleHandler_data;
178  }

◆ GetDataArray() [2/2]

std::vector<double> SampleHandlerBase::GetDataArray ( const int  Sample) const
inline

Return array storing data entries for every bin.

Parameters
SampleSample index

Definition at line 192 of file SampleHandlerBase.h.

192  {
193  return GetArrayForSample(Sample, SampleHandler_data);
194  }
std::vector< double > GetArrayForSample(const int Sample, std::vector< double > const &array) const
Return a sub-array for a given sample.

◆ GetDataHist() [1/2]

const TH1 * SampleHandlerBase::GetDataHist ( const int  Sample)
finalvirtual

Get Data histogram.

Parameters
SampleSample enumerator

Implements SampleHandlerInterface.

Definition at line 953 of file SampleHandlerBase.cpp.

953  {
954 // ************************************************
955  if(SampleDetails[Sample].DataHist == nullptr) {
956  MACH3LOG_ERROR("Can't access {} for {}Dimensions", __func__, GetNDim(Sample));
957  throw MaCh3Exception(__FILE__, __LINE__);
958  }
959  return SampleDetails[Sample].DataHist;
960 }

◆ GetDataHist() [2/2]

const TH1 * SampleHandlerBase::GetDataHist ( const std::string &  Sample)

Get Data histogram by sample name.

Parameters
SampleSample title

Definition at line 963 of file SampleHandlerBase.cpp.

963  {
964 // ************************************************
965  int Index = GetSampleIndex(Sample);
966  return GetDataHist(Index);
967 }
const TH1 * GetDataHist(const int Sample) final
Get Data histogram.
int GetSampleIndex(const std::string &SampleTitle) const
Get index of sample based on name.

◆ GetEventWeight()

M3::float_t SampleHandlerBase::GetEventWeight ( const int  iEvent)

Computes the total event weight for a given entry.

Parameters
iEventEvent enumerator

KS:

Warning
we have to here recalculate weight and cap because there is possibility weight wasn't calculated during FillArray because it didn't fulfil IsEventSelected

Definition at line 1208 of file SampleHandlerBase.cpp.

1208  {
1209 // ************************************************
1211 
1212  // Virtual by default does nothing, has to happen before CalcWeightTotal
1213  CalcWeightFunc(iEntry);
1214 
1215  const EventInfo* _restrict_ MCEvent = &MCEvents[iEntry];
1216  M3::float_t totalweight = CalcWeightTotal(MCEvent);
1217 
1218  //DB Catch negative total weights and skip any event with a negative weight. Previously we would set weight to zero and continue but that is inefficient
1219  if (totalweight <= 0.){
1220  totalweight = 0.;
1221  }
1222  return totalweight;
1223 }

◆ GetFinalPDGFromFileName()

NuPDG SampleHandlerBase::GetFinalPDGFromFileName ( const std::string &  FileName) const
inlineprotected

Retrieve the final neutrino PDG code associated with a given input file name.

Definition at line 447 of file SampleHandlerBase.h.

447 {return FileToFinalPDGMap.at(FileName);}
std::unordered_map< std::string, NuPDG > FileToFinalPDGMap
Mapping from input file names to final neutrino PDG codes.

◆ GetFlavourName()

std::string SampleHandlerBase::GetFlavourName ( const int  iSample,
const int  iChannel 
) const
inlinefinalvirtual

Get the flavour name for a given sample and oscillation channel.

Parameters
iSampleIndex of the sample.
iChannelIndex of the oscillation channel within the sample.

Implements SampleHandlerInterface.

Definition at line 102 of file SampleHandlerBase.h.

102  {
103  if (iChannel < 0 || iChannel > GetNOscChannels(iSample)) {
104  MACH3LOG_ERROR("Invalid Channel Requested: {}", iChannel);
105  throw MaCh3Exception(__FILE__ , __LINE__);
106  }
107  return SampleDetails[iSample].OscChannels[iChannel].flavourName;
108  }

◆ GetInitPDGFromFileName()

NuPDG SampleHandlerBase::GetInitPDGFromFileName ( const std::string &  FileName) const
inlineprotected

Retrieve the initial neutrino PDG code associated with a given input file name.

Definition at line 445 of file SampleHandlerBase.h.

445 {return FileToInitPDGMap.at(FileName);}
std::unordered_map< std::string, NuPDG > FileToInitPDGMap
Mapping from input file names to initial neutrino PDG codes.

◆ GetKinVarName()

std::string SampleHandlerBase::GetKinVarName ( const int  iSample,
const int  Dimension 
) const
finalvirtual

Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino_Energy".

Parameters
iSampleSample index
DimensionDimension index

Implements SampleHandlerInterface.

Definition at line 2141 of file SampleHandlerBase.cpp.

2141  {
2142 // ***************************************************************************
2143  if(Dimension > GetNDim(iSample)) {
2144  MACH3LOG_ERROR("Asking for dimension {}, while sample: {} only has {}", Dimension, GetSampleTitle(iSample), GetNDim(iSample));
2145  throw MaCh3Exception(__FILE__, __LINE__);
2146  }
2147  return SampleDetails[iSample].VarStr[Dimension];
2148 }

◆ GetLikelihood()

double SampleHandlerBase::GetLikelihood ( ) const
overridevirtual

Return likelihood (-logL) for all samples.

Implements SampleHandlerInterface.

Definition at line 1327 of file SampleHandlerBase.cpp.

1327  {
1328 // ************************************************
1329  double negLogL = 0.;
1330  #ifdef MULTITHREAD
1331  #pragma omp parallel for reduction(+:negLogL)
1332  #endif
1333  for (int idx = 0; idx < Binning->GetNBins(); ++idx)
1334  {
1335  double const &DataVal = SampleHandler_data[idx];
1336  double const &MCPred = SampleHandler_array[idx];
1337  double const &w2 = SampleHandler_array_w2[idx];
1338 
1339  //KS: Calculate likelihood using Barlow-Beeston Poisson or even IceCube
1340  negLogL += GetTestStatLLH(DataVal, MCPred, w2);
1341  }
1342  return negLogL;
1343 }
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....

◆ GetMCArray() [1/2]

auto SampleHandlerBase::GetMCArray ( ) const
inline

Return array storing MC entries for every bin.

Definition at line 180 of file SampleHandlerBase.h.

180  {
181  return SampleHandler_array;
182  }

◆ GetMCArray() [2/2]

std::vector<double> SampleHandlerBase::GetMCArray ( const int  Sample) const
inline

Return array storing MC entries for every bin.

Parameters
SampleSample index

Definition at line 197 of file SampleHandlerBase.h.

197  {
198  return GetArrayForSample(Sample, SampleHandler_array);
199  }

◆ GetMCHist() [1/2]

const TH1 * SampleHandlerBase::GetMCHist ( const int  Sample)
finalvirtual

Get MC histogram.

Parameters
SampleSample enumerator

Implements SampleHandlerInterface.

Definition at line 935 of file SampleHandlerBase.cpp.

935  {
936 // ************************************************
937  FillHist(Sample, SampleDetails[Sample].MCHist, SampleHandler_array);
938  if(SampleDetails[Sample].MCHist == nullptr) {
939  MACH3LOG_ERROR("Can't access {} for {}Dimensions", __func__, GetNDim(Sample));
940  throw MaCh3Exception(__FILE__, __LINE__);
941  }
942  return SampleDetails[Sample].MCHist;
943 }

◆ GetMCHist() [2/2]

const TH1 * SampleHandlerBase::GetMCHist ( const std::string &  Sample)

Get MC histogram by sample title.

Parameters
SampleSample name

Definition at line 946 of file SampleHandlerBase.cpp.

946  {
947 // ************************************************
948  const int Index = GetSampleIndex(Sample);
949  return GetMCHist(Index);
950 }

◆ GetModeHist1D()

std::unique_ptr<TH1> SampleHandlerBase::GetModeHist1D ( const int  iSample,
int  s,
int  m,
int  style = 0 
)
inline

Produce 1D projection into X-variable, for a single MaCh3 mode.

Definition at line 136 of file SampleHandlerBase.h.

136  {
137  return Get1DVarHistByModeAndChannel(iSample, GetKinVarName(iSample, 0), m, s, style);
138  }
std::unique_ptr< TH1 > Get1DVarHistByModeAndChannel(const int iSample, const std::string &ProjectionVar_Str, const int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0) final
Build a 1D histogram for a given variable, optionally filtered by mode and channel.

◆ GetModeHist2D()

std::unique_ptr<TH2> SampleHandlerBase::GetModeHist2D ( const int  iSample,
int  s,
int  m,
int  style = 0 
)
inline

Produce 2D projection into X-variable, and Y-variable for a single MaCh3 mode.

Definition at line 140 of file SampleHandlerBase.h.

140  {
141  return Get2DVarHistByModeAndChannel(iSample, GetKinVarName(iSample, 0), GetKinVarName(iSample, 1), m, s, style);
142  }
std::unique_ptr< TH2 > Get2DVarHistByModeAndChannel(const int iSample, const std::string &ProjectionVar_StrX, const std::string &ProjectionVar_StrY, const int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0) final
Build a 2D histogram for given variables, optionally filtered by mode and channel.

◆ GetName()

std::string SampleHandlerBase::GetName ( ) const
finalvirtual

Get name for Sample Handler.

Implements SampleHandlerInterface.

Definition at line 1195 of file SampleHandlerBase.cpp.

1195  {
1196 // ************************************************
1197  //ETA - extra safety to make sure SampleHandlerName is actually set
1198  // probably unnecessary due to the requirement for it to be in the yaml config
1199  if(SampleHandlerName.length() == 0) {
1200  MACH3LOG_ERROR("No sample name provided");
1201  MACH3LOG_ERROR("Please provide a SampleHandlerName in your configuration file: {}", SampleManager->GetFileName());
1202  throw MaCh3Exception(__FILE__, __LINE__);
1203  }
1204  return SampleHandlerName;
1205 }

◆ GetNDim()

int SampleHandlerBase::GetNDim ( const int  Sample) const
inlinefinalvirtual

DB Get what dimensionality binning for given sample has.

Parameters
SampleNumber of sample

Implements SampleHandlerInterface.

Definition at line 40 of file SampleHandlerBase.h.

40 { return SampleDetails[Sample].nDimensions; }

◆ GetNOscChannels()

int SampleHandlerBase::GetNOscChannels ( const int  iSample) const
inlinefinalvirtual

Get number of oscillation channels for a single sample.

Parameters
iSampleSample enumerator

Implements SampleHandlerInterface.

Definition at line 100 of file SampleHandlerBase.h.

100 {return static_cast<int>(SampleDetails[iSample].OscChannels.size());};

◆ GetNuOscillatorPointers()

const M3::float_t * SampleHandlerBase::GetNuOscillatorPointers ( const int  iEvent) const
protected

Get pointer to NuOscillator weight for a given event.

Parameters
iEventEvent enumerator

Definition at line 1155 of file SampleHandlerBase.cpp.

1155  {
1156 // ************************************************
1157  const M3::float_t* osc_w_pointer = &M3::Unity;
1158  if (MCEvents[iEvent].isNC) {
1159  if (MCEvents[iEvent].nupdg != MCEvents[iEvent].nupdgUnosc) {
1160  osc_w_pointer = &M3::Zero;
1161  } else {
1162  osc_w_pointer = &M3::Unity;
1163  }
1164  } else {
1165  int InitFlav = M3::_BAD_INT_;
1166  int FinalFlav = M3::_BAD_INT_;
1167 
1168  InitFlav = M3::Utils::PDGToNuOscillatorFlavour(MCEvents[iEvent].nupdgUnosc);
1169  FinalFlav = M3::Utils::PDGToNuOscillatorFlavour(MCEvents[iEvent].nupdg);
1170 
1171  if (InitFlav == M3::_BAD_INT_ || FinalFlav == M3::_BAD_INT_) {
1172  MACH3LOG_ERROR("Something has gone wrong in the mapping between MCEvents.nutype and the enum used within NuOscillator");
1173  MACH3LOG_ERROR("MCEvents.nupdgUnosc: {}", MCEvents[iEvent].nupdgUnosc);
1174  MACH3LOG_ERROR("InitFlav: {}", InitFlav);
1175  MACH3LOG_ERROR("MCEvents.nupdg: {}", MCEvents[iEvent].nupdg);
1176  MACH3LOG_ERROR("FinalFlav: {}", FinalFlav);
1177  throw MaCh3Exception(__FILE__, __LINE__);
1178  }
1179  const int Sample = MCEvents[iEvent].NominalSample;
1180 
1181  const int OscIndex = GetOscChannel(SampleDetails[Sample].OscChannels, MCEvents[iEvent].nupdgUnosc, MCEvents[iEvent].nupdg);
1182  //Can only happen if truecz has been initialised within the experiment specific code
1183  if (MCEvents[iEvent].coszenith_true != M3::_BAD_DOUBLE_) {
1184  //Atmospherics
1185  osc_w_pointer = Oscillator->GetNuOscillatorPointers(Sample, OscIndex, InitFlav, FinalFlav, FLOAT_T(MCEvents[iEvent].enu_true), FLOAT_T(MCEvents[iEvent].coszenith_true));
1186  } else {
1187  //Beam
1188  osc_w_pointer = Oscillator->GetNuOscillatorPointers(Sample, OscIndex, InitFlav, FinalFlav, FLOAT_T(MCEvents[iEvent].enu_true));
1189  }
1190  } // end if NC
1191  return osc_w_pointer;
1192 }
int GetOscChannel(const std::vector< OscChannelInfo > &OscChannel, const int InitFlav, const int FinalFlav)
KS: Get Osc Channel Index based on initial and final PDG codes.
Definition: SampleInfo.h:28
int PDGToNuOscillatorFlavour(const int NuPdg)
Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscilla...
constexpr static const float_t Unity
Definition: Core.h:64
constexpr static const float_t Zero
Definition: Core.h:71
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55

◆ GetPointerToKinematicParameter() [1/2]

virtual const double* SampleHandlerBase::GetPointerToKinematicParameter ( const int  KinematicVariable,
const int  iEvent 
) const
protectedpure virtual

Implemented in PySampleHandlerBase.

◆ GetPointerToKinematicParameter() [2/2]

const double* SampleHandlerBase::GetPointerToKinematicParameter ( const std::string &  KinematicParameter,
int  iEvent 
) const
inlineprotected

Definition at line 345 of file SampleHandlerBase.h.

345  {
346  return GetPointerToKinematicParameter(ReturnKinematicParameterFromString(KinematicParameter), iEvent);
347  }

◆ GetPointerToOscChannel()

const double * SampleHandlerBase::GetPointerToOscChannel ( const int  iEvent) const
protected

Get pointer to oscillation channel associated with given event. Osc channel is const.

Definition at line 2061 of file SampleHandlerBase.cpp.

2061  {
2062 // ************************************************
2063  auto& OscillationChannels = SampleDetails[MCEvents[iEvent].NominalSample].OscChannels;
2064  const int Channel = GetOscChannel(OscillationChannels, MCEvents[iEvent].nupdgUnosc, MCEvents[iEvent].nupdg);
2065  return &(OscillationChannels[Channel].ChannelIndex);
2066 }

◆ GetRangeForPlotType()

int SampleHandlerBase::GetRangeForPlotType ( const SamplePlotType  TypeEnum,
const int  iSample 
) const

KS: Return range for plot type, for example number of modes, osc channels etc.

Parameters
TypeEnumPlot type enumerator see SamplePlotType
iSampleSample enumerator

Definition at line 1984 of file SampleHandlerBase.cpp.

1984  {
1985 // ************************************************
1986  switch (TypeEnum) {
1988  return Modes->GetNModes();
1989  break;
1991  return GetNOscChannels(iSample);
1992  break;
1993  default:
1994  MACH3LOG_ERROR("You've passed me a SamplePlotType with value {} which was not implemented.", static_cast<int>(TypeEnum));
1995  throw MaCh3Exception(__FILE__, __LINE__);
1996  }
1997 }
@ kOscChannelPlot
@ kModePlot

◆ GetSampleIndex()

int SampleHandlerBase::GetSampleIndex ( const std::string &  SampleTitle) const

Get index of sample based on name.

Parameters
SampleTitleThe title of the sample to search for.

Definition at line 905 of file SampleHandlerBase.cpp.

905  {
906 // ************************************************
907  for (M3::int_t iSample = 0; iSample < nSamples; ++iSample) {
908  if (SampleTitle == GetSampleTitle(iSample)) {
909  return iSample;
910  }
911  }
912  MACH3LOG_ERROR("Sample name not found: {}", SampleTitle);
913  throw MaCh3Exception(__FILE__, __LINE__);
914 }
int int_t
Definition: Core.h:38

◆ GetSampleLikelihood()

double SampleHandlerBase::GetSampleLikelihood ( const int  isample) const
overridevirtual

Get likelihood (-logL) for a single sample.

Parameters
iSampleSample enumerator

Implements SampleHandlerInterface.

Definition at line 1305 of file SampleHandlerBase.cpp.

1305  {
1306 // ************************************************
1307  const int Start = Binning->GetSampleStartBin(isample);
1308  const int End = Binning->GetSampleEndBin(isample);
1309 
1310  double negLogL = 0.;
1311  #ifdef MULTITHREAD
1312  #pragma omp parallel for reduction(+:negLogL)
1313  #endif
1314  for (int idx = Start; idx < End; ++idx)
1315  {
1316  double const &DataVal = SampleHandler_data[idx];
1317  double const &MCPred = SampleHandler_array[idx];
1318  double const &w2 = SampleHandler_array_w2[idx];
1319 
1320  //KS: Calculate likelihood using Barlow-Beeston Poisson or even IceCube
1321  negLogL += GetTestStatLLH(DataVal, MCPred, w2);
1322  }
1323  return negLogL;
1324 }

◆ GetSampleName()

std::string SampleHandlerBase::GetSampleName ( const int  Sample) const
inline

Sample name tag used only for getting relevant uncertainties.

Parameters
SampleIndex of the sample.

Definition at line 47 of file SampleHandlerBase.h.

47 {return SampleDetails[Sample].SampleName;}

◆ GetSampleTitle()

std::string SampleHandlerBase::GetSampleTitle ( const int  Sample) const
inlinefinalvirtual

Get fancy title for specified samples.

Parameters
iSampleSample enumerator

Implements SampleHandlerInterface.

Definition at line 44 of file SampleHandlerBase.h.

44 {return SampleDetails[Sample].SampleTitle;}

◆ GetSplineBins()

std::vector< std::vector< int > > SampleHandlerBase::GetSplineBins ( int  Event,
BinnedSplineHandler BinnedSpline,
bool &  ThrowCrititcal 
) const
protected

Retrieve the spline bin indices associated with a given event.

Warning
ThrowCrititcal argument will be eventually removed

Definition at line 1226 of file SampleHandlerBase.cpp.

1226  {
1227 // ************************************************
1228  const int SampleIndex = MCEvents[Event].NominalSample;
1229  const auto SampleTitle = GetSampleTitle(SampleIndex);
1230  bool NoOscChannels = false;
1231  if(Oscillator == nullptr && GetNOscChannels(SampleIndex) == 1) {
1232  MACH3LOG_DEBUG("Assuming there are no osc channels in {}", __func__);
1233  NoOscChannels = true;
1234  }
1235  const int OscIndex = NoOscChannels ? 0 : GetOscChannel(SampleDetails[SampleIndex].OscChannels,
1236  MCEvents[Event].nupdgUnosc, MCEvents[Event].nupdg);
1237  const int Mode = static_cast<int>(std::round(ReturnKinematicParameter("Mode", Event)));
1238  const double Etrue = MCEvents[Event].enu_true;
1239  std::vector< std::vector<int> > EventSplines;
1240  switch(GetNDim(SampleIndex)) {
1241  case 1:
1242  EventSplines = BinnedSpline->GetEventSplines(SampleTitle, OscIndex, Mode, Etrue, *(MCEvents[Event].KinVar[0]), 0.);
1243  break;
1244  case 2:
1245  EventSplines = BinnedSpline->GetEventSplines(SampleTitle, OscIndex, Mode, Etrue, *(MCEvents[Event].KinVar[0]), *(MCEvents[Event].KinVar[1]));
1246  break;
1247  default:
1248  if(ThrowCrititcal) {
1249  MACH3LOG_CRITICAL("MaCh3 doesn't support binned splines for more than 2D while you use {}", GetNDim(SampleIndex));
1250  MACH3LOG_CRITICAL("Will use 2D like approach");
1251  ThrowCrititcal = false;
1252  }
1253  EventSplines = BinnedSpline->GetEventSplines(SampleTitle, OscIndex, Mode, Etrue, *(MCEvents[Event].KinVar[0]), *(MCEvents[Event].KinVar[1]));
1254  break;
1255  }
1256  return EventSplines;
1257 }
std::vector< std::vector< int > > GetEventSplines(const std::string &SampleTitle, int iOscChan, int EventMode, double Var1Val, double Var2Val, double Var3Val)
Return the splines which affect a given event.

◆ GetW2Array() [1/2]

auto SampleHandlerBase::GetW2Array ( ) const
inline

Return array storing W2 entries for every bin.

Definition at line 184 of file SampleHandlerBase.h.

184  {
185  return SampleHandler_array_w2;
186  }

◆ GetW2Array() [2/2]

std::vector<double> SampleHandlerBase::GetW2Array ( const int  Sample) const
inline

Return array storing W2 entries for single sample.

Parameters
SampleSample index

Definition at line 202 of file SampleHandlerBase.h.

202  {
204  }

◆ GetW2Hist() [1/2]

const TH1 * SampleHandlerBase::GetW2Hist ( const int  Sample)
finalvirtual

Get W2 histogram.

Parameters
SampleSample enumerator

Implements SampleHandlerInterface.

Definition at line 917 of file SampleHandlerBase.cpp.

917  {
918 // ************************************************
919  FillHist(Sample, SampleDetails[Sample].W2Hist, SampleHandler_array_w2);
920  if(SampleDetails[Sample].W2Hist == nullptr) {
921  MACH3LOG_ERROR("Can't access {} for {}Dimensions", __func__, GetNDim(Sample));
922  throw MaCh3Exception(__FILE__, __LINE__);
923  }
924  return SampleDetails[Sample].W2Hist;
925 }

◆ GetW2Hist() [2/2]

const TH1 * SampleHandlerBase::GetW2Hist ( const std::string &  Sample)

Get W2 histogram by sample name.

Parameters
SampleSample title

Definition at line 928 of file SampleHandlerBase.cpp.

928  {
929 // ************************************************
930  const int Index = GetSampleIndex(Sample);
931  return GetW2Hist(Index);
932 }
const TH1 * GetW2Hist(const int Sample) final
Get W2 histogram.

◆ Init()

virtual void SampleHandlerBase::Init ( )
protectedpure virtual

Initialise any variables that your experiment specific SampleHandler needs.

Implemented in PySampleHandlerBase.

◆ Initialise()

void SampleHandlerBase::Initialise ( )
protected

Function which does a lot of the lifting regarding the workflow in creating different MC objects.

Definition at line 197 of file SampleHandlerBase.cpp.

197  {
198 // ************************************************
199  TStopwatch clock;
200  clock.Start();
201 
202  //First grab all the information from your sample config via your manager
203  ReadConfig();
204 
205  //Now initialise all the variables you will need
206  Init();
207 
209  MCEvents.resize(nEvents);
210  SetupMC();
211 
212  MACH3LOG_INFO("=============================================");
213  MACH3LOG_INFO("Total number of events is: {}", GetNEvents());
215  MACH3LOG_INFO("Setting up Sample Binning..");
216  SetBinning();
217  MACH3LOG_INFO("Setting up Splines..");
218  SetupSplines();
219  MACH3LOG_INFO("Setting up Normalisation Pointers..");
221  MACH3LOG_INFO("Setting up Functional Pointers..");
223  MACH3LOG_INFO("Setting up Additional Weight Pointers..");
225  MACH3LOG_INFO("Setting up Kinematic Map..");
227  clock.Stop();
228  MACH3LOG_INFO("Finished loading MC for {}, it took {:.2f}s to finish", GetName(), clock.RealTime());
229  MACH3LOG_INFO("Initialising Data");
231  MACH3LOG_INFO("=======================================================");
232  CheckEmptyBins();
233 }
void SetBinning()
set the binning for 2D sample used for the likelihood calculation
void SetupNormParameters()
Setup the norm parameters by assigning each event with bin.
void ReadConfig()
Load information about sample handler and corresponding samples from config file.
void SetupKinematicMap()
Ensure Kinematic Map is setup and make sure it is initialised correctly.
virtual void Init()=0
Initialise any variables that your experiment specific SampleHandler needs.
void CheckEmptyBins() const
Loop over bins and checks if there are any which have 0 entries.
virtual void SetupMC()=0
Function which translates experiment struct into core struct.
virtual void InititialiseData()=0
Function responsible for loading data from file or loading from file.
virtual void SetupSplines()=0
initialise your splineXX object and then use InitialiseSplineObject to conviently setup everything up
virtual void AddAdditionalWeightPointers()=0
DB Function to determine which weights apply to which types of samples.
virtual int SetupExperimentMC()=0
Experiment specific setup, returns the number of events which were loaded.
virtual void SetupFunctionalParameters()
ETA - a function to setup and pass values to functional parameters where you need to pass a value to ...
void SetupOscParameters()
Setup the osc parameters.
unsigned int nEvents
Number of MC events are there.

◆ InitialiseNuOscillatorObjects()

void SampleHandlerBase::InitialiseNuOscillatorObjects ( )
protected

including Dan's magic NuOscillator

Definition at line 1062 of file SampleHandlerBase.cpp.

1062  {
1063 // ************************************************
1064  auto NuOscillatorConfigFile = Get<std::string>(SampleManager->raw()["NuOsc"]["NuOscConfigFile"], __FILE__ , __LINE__);
1065  auto EqualBinningPerOscChannel = Get<bool>(SampleManager->raw()["NuOsc"]["EqualBinningPerOscChannel"], __FILE__ , __LINE__);
1066 
1067  // TN override the sample setting if not using binned oscillation
1068  if (EqualBinningPerOscChannel) {
1069  if (YAML::LoadFile(NuOscillatorConfigFile)["General"]["CalculationType"].as<std::string>() == "Unbinned") {
1070  MACH3LOG_WARN("Tried using EqualBinningPerOscChannel while using Unbinned oscillation calculation, changing EqualBinningPerOscChannel to false");
1071  EqualBinningPerOscChannel = false;
1072  }
1073  }
1074  // get osc params for sample 0, later we check all have same number
1075  std::vector<const M3::float_t*> OscParams = ParHandler->GetOscParsFromSampleName(GetSampleName(0));
1076  if (OscParams.empty()) {
1077  MACH3LOG_ERROR("OscParams is empty for sample '{}'.", GetName());
1078  MACH3LOG_ERROR("This likely indicates an error in your oscillation YAML configuration.");
1079  throw MaCh3Exception(__FILE__, __LINE__);
1080  }
1081 
1082  for(int iSample = 1; iSample < GetNSamples(); iSample++) {
1083  auto OscParamsCrossCheck = ParHandler->GetOscParsFromSampleName(GetSampleName(iSample));
1084  if (OscParamsCrossCheck.size() != OscParams.size()) {
1085  MACH3LOG_ERROR("Sample {} has {} osc params while sample {} has {}",
1086  GetSampleTitle(iSample), OscParamsCrossCheck.size(), 0, GetSampleTitle(0));
1087  throw MaCh3Exception(__FILE__, __LINE__);
1088  }
1089  }
1090  Oscillator = std::make_shared<OscillationHandler>(NuOscillatorConfigFile, EqualBinningPerOscChannel, OscParams, GetNOscChannels(0));
1091  // Add samples only if we don't use same binning
1092  if(!EqualBinningPerOscChannel) {
1093  // KS: Start from 1 because sample 0 already added
1094  for(int iSample = 1; iSample < GetNSamples(); iSample++) {
1095  Oscillator->AddSample(NuOscillatorConfigFile, GetNOscChannels(iSample));
1096  }
1097  for(int iSample = 0; iSample < GetNSamples(); iSample++) {
1098  for(int iChannel = 0; iChannel < GetNOscChannels(iSample); iChannel++) {
1099  std::vector<M3::float_t> EnergyArray;
1100  std::vector<M3::float_t> CosineZArray;
1101 
1102 #pragma GCC diagnostic push
1103 #pragma GCC diagnostic ignored "-Wuseless-cast"
1104  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1105  if(MCEvents[iEvent].NominalSample != iSample) continue;
1106  // KS: This is bit weird but we basically loop over all events and push to vector only these which are part of a given OscChannel
1107  const int Channel = GetOscChannel(SampleDetails[MCEvents[iEvent].NominalSample].OscChannels, MCEvents[iEvent].nupdgUnosc, MCEvents[iEvent].nupdg);
1108  //DB Remove NC events from the arrays which are handed to the NuOscillator objects
1109  if (!MCEvents[iEvent].isNC && Channel == iChannel) {
1110  EnergyArray.push_back(M3::float_t(MCEvents[iEvent].enu_true));
1111  }
1112  }
1113  std::sort(EnergyArray.begin(),EnergyArray.end());
1114 
1115  //============================================================================
1116  //DB Atmospheric only part, can only happen if truecz has been initialised within the experiment specific code
1117  if (MCEvents[0].coszenith_true != M3::_BAD_DOUBLE_) {
1118  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1119  if(MCEvents[iEvent].NominalSample != iSample) continue;
1120  // KS: This is bit weird but we basically loop over all events and push to vector only these which are part of a given OscChannel
1121  const int Channel = GetOscChannel(SampleDetails[MCEvents[iEvent].NominalSample].OscChannels, MCEvents[iEvent].nupdgUnosc, MCEvents[iEvent].nupdg);
1122  //DB Remove NC events from the arrays which are handed to the NuOscillator objects
1123  if (!MCEvents[iEvent].isNC && Channel == iChannel) {
1124  CosineZArray.push_back(M3::float_t(MCEvents[iEvent].coszenith_true));
1125  }
1126  }
1127  std::sort(CosineZArray.begin(),CosineZArray.end());
1128  }
1129 #pragma GCC diagnostic pop
1130  Oscillator->SetOscillatorBinning(iSample, iChannel, EnergyArray, CosineZArray);
1131  } // end loop over channels
1132  } // end loop over samples
1133  }
1134 }
std::vector< const M3::float_t * > GetOscParsFromSampleName(const std::string &SampleName) const
Get pointers to Osc params from Sample name.
std::string GetSampleName(const int Sample) const
Sample name tag used only for getting relevant uncertainties.
virtual M3::int_t GetNSamples()
returns total number of samples

◆ InitialiseSplineObject()

void SampleHandlerBase::InitialiseSplineObject ( )
protected

Setup spline handler (both binned or unbinned)

Definition at line 1392 of file SampleHandlerBase.cpp.

1392  {
1393 // ************************************************
1394  if(auto BinnedSplines = dynamic_cast<BinnedSplineHandler*>(SplineHandler.get())) {
1395  bool LoadSplineFile = GetFromManager<bool>(SampleManager->raw()["InputFiles"]["LoadSplineFile"], false, __FILE__, __LINE__);
1396  bool PrepSplineFile = GetFromManager<bool>(SampleManager->raw()["InputFiles"]["PrepSplineFile"], false, __FILE__, __LINE__);
1397  auto SplineFileName = GetFromManager<std::string>(SampleManager->raw()["InputFiles"]["SplineFileName"],
1398  (SampleHandlerName + "_SplineFile.root"), __FILE__, __LINE__);
1399  if(!LoadSplineFile) {
1400  for(int iSample = 0; iSample < GetNSamples(); iSample++) {
1401  std::vector<std::string> spline_filepaths = SampleDetails[iSample].spline_files;
1402 
1403  //Keep a track of the spline variables
1404  std::vector<std::string> SplineVarNames = {"TrueNeutrinoEnergy"};
1405  if (GetNDim(iSample) == 1) {
1406  SplineVarNames.push_back(GetKinVarName(iSample, 0));
1407  } else if (GetNDim(iSample) == 2) {
1408  SplineVarNames.push_back(GetKinVarName(iSample, 0));
1409  SplineVarNames.push_back(GetKinVarName(iSample, 1));
1410  } else {
1411  MACH3LOG_CRITICAL("{} Not implemented for dimension {}, will use 2D", __func__, GetNDim(iSample));
1412  SplineVarNames.push_back(GetKinVarName(iSample, 0));
1413  SplineVarNames.push_back(GetKinVarName(iSample, 1));
1414  }
1415  BinnedSplines->AddSample(GetSampleName(iSample), GetSampleTitle(iSample), spline_filepaths, SplineVarNames);
1416  }
1417  BinnedSplines->CountNumberOfLoadedSplines(false, 1);
1418  BinnedSplines->TransferToMonolith();
1419  if(PrepSplineFile) BinnedSplines->PrepareSplineFile(SplineFileName);
1420  } else {
1421  // KS: Skip default spline loading and use flattened spline format allowing to read stuff much faster
1422  BinnedSplines->LoadSplineFile(SplineFileName);
1423  }
1424  MACH3LOG_INFO("--------------------------------");
1425  MACH3LOG_INFO("Setup Far Detector splines");
1426 
1428 
1429  BinnedSplines->cleanUpMemory();
1430  } else if (auto UnbinnedSpline = dynamic_cast<UnbinnedSplineHandler*>(SplineHandler.get())) {
1431  (void) UnbinnedSpline;
1433  } else {
1434  MACH3LOG_ERROR("Unsupported spline type encountered.");
1435  throw MaCh3Exception(__FILE__, __LINE__);
1436  }
1437 }
Bin-by-bin class calculating response for spline parameters.
void SetSplinePointers()
Set pointers for each event to appropriate weights, for unbinned based on event number while for binn...
std::unique_ptr< SplineBase > SplineHandler
Contains all your splines (binned or unbinned) and handles the setup and the returning of weights fro...
Even-by-event class calculating response for spline parameters. It is possible to use GPU acceleratio...

◆ InititialiseData()

virtual void SampleHandlerBase::InititialiseData ( )
protectedpure virtual

Function responsible for loading data from file or loading from file.

Implemented in PySampleHandlerBase.

◆ IsEventSelected()

bool SampleHandlerBase::IsEventSelected ( const int  iSample,
const int  iEvent 
)
protected

DB Function which determines if an event is selected based on KinematicCut.

Definition at line 312 of file SampleHandlerBase.cpp.

312  {
313 // ************************************************
314  const auto& SampleSelection = Selection[iSample];
315  const int SelectionSize = static_cast<int>(SampleSelection.size());
316  for (int iSelection = 0; iSelection < SelectionSize; ++iSelection) {
317  const auto& Cut = SampleSelection[iSelection];
318  const double Val = ReturnKinematicParameter(Cut.ParamToCutOnIt, iEvent);
319  if ((Val < Cut.LowerBound) || (Val >= Cut.UpperBound)) {
320  return false;
321  }
322  }
323  //DB To avoid unnecessary checks, now return false rather than setting bool to true and continuing to check
324  return true;
325 }

◆ IsSubEventSelected()

bool SampleHandlerBase::IsSubEventSelected ( const std::vector< KinematicCut > &  SubEventCuts,
const int  iEvent,
unsigned const int  iSubEvent,
size_t  nsubevents 
)
protected

JM Function which determines if a subevent is selected.

Definition at line 328 of file SampleHandlerBase.cpp.

328  {
329  for (unsigned int iSelection=0;iSelection < SubEventCuts.size() ;iSelection++) {
330  std::vector<double> Vec = ReturnKinematicVector(SubEventCuts[iSelection].ParamToCutOnIt, iEvent);
331  if (nsubevents != Vec.size()) {
332  MACH3LOG_ERROR("Cannot apply kinematic cut on {} as it is of different size to plotting variable");
333  throw MaCh3Exception(__FILE__, __LINE__);
334  }
335  const double Val = Vec[iSubEvent];
336  if ((Val < SubEventCuts[iSelection].LowerBound) || (Val >= SubEventCuts[iSelection].UpperBound)) {
337  return false;
338  }
339  }
340  //DB To avoid unnecessary checks, now return false rather than setting bool to true and continuing to check
341  return true;
342 }

◆ IsSubEventVarString()

bool SampleHandlerBase::IsSubEventVarString ( const std::string &  VarStr) const

JM: Check if a kinematic parameter string corresponds to a subevent-level variable.

Definition at line 1758 of file SampleHandlerBase.cpp.

1758  {
1759 // ************************************************
1760  if (KinematicVectors == nullptr) return false;
1761 
1762  if (KinematicVectors->count(VarStr)) {
1763  if (!KinematicParameters->count(VarStr)) return true;
1764  else {
1765  MACH3LOG_ERROR("Attempted to plot kinematic variable {}, but it appears in both KinematicVectors and KinematicParameters", VarStr);
1766  throw MaCh3Exception(__FILE__,__LINE__);
1767  }
1768  }
1769  return false;
1770 }

◆ LoadSingleSample()

void SampleHandlerBase::LoadSingleSample ( const int  iSample,
const YAML::Node &  Settings 
)
protected

Initialise single sample from config file.

Add new sample

Definition at line 113 of file SampleHandlerBase.cpp.

113  {
114 // ************************************************
115  SampleInfo SingleSample;
116  //SampleTitle has to be provided in the sample yaml otherwise this will throw an exception
117  SingleSample.SampleTitle = Get<std::string>(SampleSettings["SampleTitle"], __FILE__ , __LINE__);
118  // Sample name used for defying syst uncertainties, if not specified use SampleHandler name
119  SingleSample.SampleName = GetFromManager<std::string>(SampleSettings["SampleName"], GetName(), __FILE__ , __LINE__);
120 
121  Binning->SetupSampleBinning(SampleSettings["Binning"], SingleSample);
122 
123  auto MCFilePrefix = Get<std::string>(SampleSettings["InputFiles"]["mtupleprefix"], __FILE__, __LINE__);
124  auto MCFileSuffix = Get<std::string>(SampleSettings["InputFiles"]["mtuplesuffix"], __FILE__, __LINE__);
125  auto SplinePrefix = Get<std::string>(SampleSettings["InputFiles"]["splineprefix"], __FILE__, __LINE__);
126  auto SplineSuffix = Get<std::string>(SampleSettings["InputFiles"]["splinesuffix"], __FILE__, __LINE__);
127 
128  int NChannels = static_cast<M3::int_t>(SampleSettings["OscChannels"].size());
129  SingleSample.OscChannels.reserve(NChannels);
130 
131  YAML::Node OscChannelsConfig;
132  // KS: We first check whether OscChannel are defined individually for this sample or taken from list
133  if(SampleSettings["OscChannels"].IsScalar()) {
134  auto PredeterminedChannelsName = Get<std::string>(SampleSettings["OscChannels"], __FILE__, __LINE__);
135  if(!SampleManager->raw()["OscChannels"]) {
136  MACH3LOG_ERROR("Trying to use Predetermined OscChannels however such field doesn't exist in config for SampleHandler: {}", GetName());
137  throw MaCh3Exception(__FILE__, __LINE__);
138  }
139  if(!SampleManager->raw()["OscChannels"][PredeterminedChannelsName]) {
140  MACH3LOG_ERROR("I didn't find PredeterminedChannelsName called: {}", PredeterminedChannelsName);
141  MACH3LOG_ERROR("However I have PredeterminedChannelsName known as:");
142  for (const auto& item : SampleManager->raw()["OscChannels"]) {
143  MACH3LOG_ERROR("{}", item.first.as<std::string>());
144  }
145  throw MaCh3Exception(__FILE__, __LINE__);
146  }
147  OscChannelsConfig = SampleManager->raw()["OscChannels"][PredeterminedChannelsName];
148  } else {
149  OscChannelsConfig = SampleSettings["OscChannels"];
150  }
151  int OscChannelCounter = 0;
152  for (auto const &osc_channel : OscChannelsConfig) {
153  OscChannelInfo OscInfo;
154  OscInfo.flavourName = Get<std::string>(osc_channel["Name"], __FILE__ , __LINE__);
155  OscInfo.flavourName_Latex = Get<std::string>(osc_channel["LatexName"], __FILE__ , __LINE__);
156  OscInfo.InitPDG = GetFromManager(osc_channel["nutype"], 0, __FILE__,__LINE__);
157  OscInfo.FinalPDG = GetFromManager(osc_channel["oscnutype"], 0, __FILE__,__LINE__);
158  OscInfo.ChannelIndex = OscChannelCounter;
159 
160  for (const auto& Existing : SingleSample.OscChannels) {
161  if (Existing.InitPDG == OscInfo.InitPDG && Existing.FinalPDG == OscInfo.FinalPDG) {
162  MACH3LOG_ERROR("Duplicate oscillation channel detected! InitPDG = {}, FinalPDG = {}"
163  "already defined in channel {} for sample {}",
164  OscInfo.InitPDG, OscInfo.FinalPDG, Existing.ChannelIndex, SingleSample.SampleTitle);
165  throw MaCh3Exception(__FILE__, __LINE__);
166  }
167  }
168  auto MCFileNames = Get<std::vector<std::string>>(osc_channel["mtuplefile"], __FILE__ , __LINE__);
169  for(size_t iFile = 0; iFile < MCFileNames.size(); iFile++){
170  std::string FileName = MCFilePrefix + MCFileNames[iFile] + MCFileSuffix;
171  MCFileNames[iFile] = FileName;
172  FileToInitPDGMap[FileName] = NuPDG(OscInfo.InitPDG);
173  FileToFinalPDGMap[FileName] = NuPDG(OscInfo.FinalPDG);
174  }
175 
176  SingleSample.OscChannels.push_back(std::move(OscInfo));
177  SingleSample.mc_files.push_back(MCFileNames);
178  SingleSample.spline_files.push_back(SplinePrefix+osc_channel["splinefile"].as<std::string>()+SplineSuffix);
179  OscChannelCounter++;
180  }
181  //Now grab the selection cuts from the manager
182  for ( auto const &SelectionCuts : SampleSettings["SelectionCuts"]) {
183  auto TempBoundsVec = GetBounds(SelectionCuts["Bounds"]);
184  KinematicCut CutObj;
185  CutObj.LowerBound = TempBoundsVec[0];
186  CutObj.UpperBound = TempBoundsVec[1];
187  CutObj.ParamToCutOnIt = ReturnKinematicParameterFromString(SelectionCuts["KinematicStr"].as<std::string>());
188  MACH3LOG_INFO("Adding cut on {} with bounds {} to {}", SelectionCuts["KinematicStr"].as<std::string>(), TempBoundsVec[0], TempBoundsVec[1]);
189  StoredSelection[iSample].emplace_back(CutObj);
190  }
193  SampleDetails[iSample] = std::move(SingleSample);
194 }
NuPDG
Enum to track the incoming neutrino species.
Definition: SampleStructs.h:94
Type GetFromManager(const YAML::Node &node, const Type defval, const std::string File="", const int Line=1)
Get content of config file if node is not found take default value specified.
Definition: YamlHelper.h:329
#define GetBounds(filename)
Definition: YamlHelper.h:590
KS: Store info about used osc channels.
Definition: SampleInfo.h:8
int InitPDG
PDG of initial flavour.
Definition: SampleInfo.h:15
double ChannelIndex
In case experiment specific would like to have pointer to channel after using GetOscChannel,...
Definition: SampleInfo.h:20
int FinalPDG
PDG of oscillated/final flavour.
Definition: SampleInfo.h:17
std::string flavourName
Name of osc channel.
Definition: SampleInfo.h:10
std::string flavourName_Latex
Fancy channel name (e.g., LaTeX formatted)
Definition: SampleInfo.h:12
KS: Store info about MC sample.
Definition: SampleInfo.h:40
std::string SampleName
tag for sample used to easily set by which uncertainties should be affected
Definition: SampleInfo.h:57
std::vector< OscChannelInfo > OscChannels
Stores info about oscillation channel for a single sample.
Definition: SampleInfo.h:68
std::string SampleTitle
the name of this sample e.g."muon-like" used for printing
Definition: SampleInfo.h:55
std::vector< std::string > spline_files
names of spline files associated associated with this object
Definition: SampleInfo.h:65
std::vector< std::vector< std::string > > mc_files
names of mc files associated associated with this object
Definition: SampleInfo.h:63

◆ PassesSelection()

template<typename ParT >
bool SampleHandlerBase::PassesSelection ( const ParT &  Par,
std::size_t  iEvent 
)
protected

Definition at line 2161 of file SampleHandlerBase.cpp.

2161  {
2162 // ***************************************************************************
2163  bool IsSelected = true;
2164  if (Par.hasKinBounds) {
2165  const auto& kinVars = Par.KinematicVarStr;
2166  const auto& selection = Par.Selection;
2167 
2168  for (std::size_t iKinPar = 0; iKinPar < kinVars.size(); ++iKinPar) {
2169  const double kinVal = ReturnKinematicParameter(kinVars[iKinPar], static_cast<int>(iEvent));
2170 
2171  bool passedAnyBound = false;
2172  const auto& boundsList = selection[iKinPar];
2173 
2174  for (const auto& bounds : boundsList) {
2175  if (kinVal > bounds[0] && kinVal <= bounds[1]) {
2176  passedAnyBound = true;
2177  break;
2178  }
2179  }
2180 
2181  if (!passedAnyBound) {
2182  MACH3LOG_TRACE("Event {}, missed kinematic check ({}) for dial {}",
2183  iEvent, kinVars[iKinPar], Par.name);
2184  IsSelected = false;
2185  break;
2186  }
2187  }
2188  }
2189  return IsSelected;
2190 }

◆ PrepFunctionalParameters()

virtual void SampleHandlerBase::PrepFunctionalParameters ( )
inlineprotectedvirtual

Update the functional parameter values to the latest proposed values. Needs to be called before every new reweight so is called in fillArray.

Definition at line 277 of file SampleHandlerBase.h.

277 {};

◆ PrintIntegral()

void SampleHandlerBase::PrintIntegral ( const int  iSample,
const TString &  OutputName = "/dev/null",
const int  WeightStyle = 0,
const TString &  OutputCSVName = "/dev/null" 
)

Computes and prints the integral breakdown of all modes and oscillation channels for a given sample.

Definition at line 1841 of file SampleHandlerBase.cpp.

1841  {
1842 // ************************************************
1843  constexpr int space = 14;
1844 
1845  bool printToFile=false;
1846  if (OutputFileName.CompareTo("/dev/null")) {printToFile = true;}
1847 
1848  bool printToCSV=false;
1849  if(OutputCSVFileName.CompareTo("/dev/null")) printToCSV=true;
1850 
1851  std::ofstream outfile;
1852  if (printToFile) {
1853  outfile.open(OutputFileName.Data(), std::ios_base::app);
1854  outfile.precision(7);
1855  }
1856 
1857  std::ofstream outcsv;
1858  if(printToCSV){
1859  outcsv.open(OutputCSVFileName, std::ios_base::app); // Appened to CSV
1860  outcsv.precision(7);
1861  }
1862 
1863  double PDFIntegral = 0.;
1864 
1865  std::vector< std::vector< std::unique_ptr<TH1> > > IntegralList;
1866  IntegralList.resize(Modes->GetNModes());
1867 
1868  std::vector<double> ChannelIntegral;
1869  ChannelIntegral.resize(GetNOscChannels(iSample));
1870  for (unsigned int i=0;i<ChannelIntegral.size();i++) {ChannelIntegral[i] = 0.;}
1871 
1872  for (int i=0;i<Modes->GetNModes();i++) {
1873  if (GetNDim(iSample) == 1) {
1874  IntegralList[i] = ReturnHistsBySelection1D(iSample, GetKinVarName(iSample, 0), SamplePlotType::kOscChannelPlot, i, WeightStyle);
1875  } else {
1876  IntegralList[i] = CastVector<TH2, TH1>(ReturnHistsBySelection2D(iSample, GetKinVarName(iSample, 0), GetKinVarName(iSample, 1),
1877  SamplePlotType::kOscChannelPlot, i, WeightStyle));
1878  }
1879  }
1880 
1881  MACH3LOG_INFO("-------------------------------------------------");
1882 
1883  if (printToFile) {
1884  outfile << "\\begin{table}[ht]" << std::endl;
1885  outfile << "\\begin{center}" << std::endl;
1886  outfile << "\\caption{Integral breakdown for sample: " << GetSampleTitle(iSample) << "}" << std::endl;
1887  outfile << "\\label{" << GetSampleTitle(iSample) << "-EventRate}" << std::endl;
1888 
1889  TString nColumns;
1890  for (int i=0;i<GetNOscChannels(iSample);i++) {nColumns+="|c";}
1891  nColumns += "|c|";
1892  outfile << "\\begin{tabular}{|l" << nColumns.Data() << "}" << std::endl;
1893  outfile << "\\hline" << std::endl;
1894  }
1895 
1896  if(printToCSV){
1897  // HW Probably a better way but oh well, here I go making MaCh3 messy again
1898  outcsv<<"Integral Breakdown for sample :"<<GetSampleTitle(iSample)<<"\n";
1899  }
1900 
1901  MACH3LOG_INFO("Integral breakdown for sample: {}", GetSampleTitle(iSample));
1902  MACH3LOG_INFO("");
1903 
1904  if (printToFile) {outfile << std::setw(space) << "Mode:";}
1905  if(printToCSV) {outcsv<<"Mode,";}
1906 
1907  std::string table_headings = fmt::format("| {:<8} |", "Mode");
1908  std::string table_footline = "------------"; //Scalable table horizontal line
1909  for (int i = 0;i < GetNOscChannels(iSample); i++) {
1910  table_headings += fmt::format(" {:<17} |", GetFlavourName(iSample, i));
1911  table_footline += "--------------------";
1912  if (printToFile) {outfile << "&" << std::setw(space) << SampleDetails[iSample].OscChannels[i].flavourName_Latex << " ";}
1913  if (printToCSV) {outcsv << GetFlavourName(iSample, i) << ",";}
1914  }
1915  if (printToFile) {outfile << "&" << std::setw(space) << "Total:" << "\\\\ \\hline" << std::endl;}
1916  if (printToCSV) {outcsv <<"Total\n";}
1917  table_headings += fmt::format(" {:<10} |", "Total");
1918  table_footline += "-------------";
1919 
1920  MACH3LOG_INFO("{}", table_headings);
1921  MACH3LOG_INFO("{}", table_footline);
1922 
1923  for (unsigned int i=0;i<IntegralList.size();i++) {
1924  double ModeIntegral = 0;
1925  if (printToFile) {outfile << std::setw(space) << Modes->GetMaCh3ModeName(i);}
1926  if(printToCSV) {outcsv << Modes->GetMaCh3ModeName(i) << ",";}
1927 
1928  table_headings = fmt::format("| {:<8} |", Modes->GetMaCh3ModeName(i)); //Start string with mode name
1929 
1930  for (unsigned int j=0;j<IntegralList[i].size();j++) {
1931  double Integral = IntegralList[i][j]->Integral();
1932 
1933  if (Integral < 1e-100) {Integral=0;}
1934 
1935  ModeIntegral += Integral;
1936  ChannelIntegral[j] += Integral;
1937  PDFIntegral += Integral;
1938 
1939  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",Integral) << " ";}
1940  if (printToCSV) {outcsv << Form("%4.5f", Integral) << ",";}
1941 
1942  table_headings += fmt::format(" {:<17.4f} |", Integral);
1943  }
1944  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",ModeIntegral) << " \\\\ \\hline" << std::endl;}
1945  if (printToCSV) {outcsv << Form("%4.5f", ModeIntegral) << "\n";}
1946 
1947  table_headings += fmt::format(" {:<10.4f} |", ModeIntegral);
1948 
1949  MACH3LOG_INFO("{}", table_headings);
1950  }
1951 
1952  if (printToFile) {outfile << std::setw(space) << "Total:";}
1953  if (printToCSV) {outcsv << "Total,";}
1954 
1955  //Clear the table_headings to print last row of totals
1956  table_headings = fmt::format("| {:<8} |", "Total");
1957  for (unsigned int i=0;i<ChannelIntegral.size();i++) {
1958  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",ChannelIntegral[i]) << " ";}
1959  if (printToCSV) {outcsv << Form("%4.5f", ChannelIntegral[i]) << ",";}
1960  table_headings += fmt::format(" {:<17.4f} |", ChannelIntegral[i]);
1961  }
1962  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",PDFIntegral) << " \\\\ \\hline" << std::endl;}
1963  if (printToCSV) {outcsv << Form("%4.5f", PDFIntegral) << "\n\n\n\n";} // Let's have a few new lines!
1964 
1965  table_headings += fmt::format(" {:<10.4f} |", PDFIntegral);
1966  MACH3LOG_INFO("{}", table_headings);
1967  MACH3LOG_INFO("{}", table_footline);
1968 
1969  if (printToFile) {
1970  outfile << "\\end{tabular}" << std::endl;
1971  outfile << "\\end{center}" << std::endl;
1972  outfile << "\\end{table}" << std::endl;
1973  }
1974 
1975  MACH3LOG_INFO("");
1976 
1977  if (printToFile) {
1978  outfile << std::endl;
1979  outfile.close();
1980  }
1981 }
std::string GetFlavourName(const int iSample, const int iChannel) const final
Get the flavour name for a given sample and oscillation channel.
std::vector< std::unique_ptr< TH1 > > ReturnHistsBySelection1D(const int iSample, const std::string &KinematicProjection, const int Selection1, const int Selection2=-1, const int WeightStyle=0)
std::vector< std::unique_ptr< TH2 > > ReturnHistsBySelection2D(const int iSample, const std::string &KinematicProjectionX, const std::string &KinematicProjectionY, const int Selection1, const int Selection2=-1, const int WeightStyle=0)

◆ PrintRates()

void SampleHandlerBase::PrintRates ( const bool  DataOnly = false)
finalvirtual

Helper function to print rates for the samples with LLH.

Parameters
DataOnlywhether to print data only rates

Implements SampleHandlerInterface.

Definition at line 2089 of file SampleHandlerBase.cpp.

2089  {
2090 // ***************************************************************************
2091  if (!SampleHandler_data.size()) {
2092  MACH3LOG_ERROR("Data sample is empty!");
2093  throw MaCh3Exception(__FILE__, __LINE__);
2094  }
2095  MACH3LOG_INFO("Printing for {}", GetName());
2096 
2097  if (!DataOnly) {
2098  const std::string sep_full(71, '-');
2099  MACH3LOG_INFO("{}", sep_full);
2100  MACH3LOG_INFO("{:<40}{:<10}{:<10}{:<10}|", "Sample", "Data", "MC", "-LLH");
2101  } else {
2102  const std::string sep_data(51, '-');
2103  MACH3LOG_INFO("{}", sep_data);
2104  MACH3LOG_INFO("{:<40}{:<10}|", "Sample", "Data");
2105  }
2106 
2107  double sumData = 0.0;
2108  double sumMC = 0.0;
2109  double likelihood = 0.0;
2110 
2111  for (int iSample = 0; iSample < GetNSamples(); ++iSample) {
2112  std::string name = GetSampleTitle(iSample);
2113  std::vector<double> DataArray = GetDataArray(iSample);
2114  double dataIntegral = std::accumulate(DataArray.begin(), DataArray.end(), 0.0);
2115  sumData += dataIntegral;
2116  if (!DataOnly) {
2117  std::vector<double> MCArray = GetMCArray(iSample);
2118  double mcIntegral = std::accumulate(MCArray.begin(), MCArray.end(), 0.0);
2119  sumMC += mcIntegral;
2120  likelihood = GetSampleLikelihood(iSample);
2121 
2122  MACH3LOG_INFO("{:<40}{:<10.2f}{:<10.2f}{:<10.2f}|", name, dataIntegral, mcIntegral, likelihood);
2123  } else {
2124  MACH3LOG_INFO("{:<40}{:<10.2f}|", name, dataIntegral);
2125  }
2126  }
2127  if (!DataOnly) {
2128  likelihood = GetLikelihood();
2129  MACH3LOG_INFO("{:<40}{:<10.2f}{:<10.2f}{:<10.2f}|", "Total", sumData, sumMC, likelihood);
2130  const std::string sep_full(71, '-');
2131  MACH3LOG_INFO("{}", sep_full);
2132  } else {
2133  MACH3LOG_INFO("{:<40}{:<10.2f}|", "Total", sumData);
2134  const std::string sep_data(51, '-');
2135  MACH3LOG_INFO("{}", sep_data);
2136  }
2137 }
double GetSampleLikelihood(const int isample) const override
Get likelihood (-logL) for a single sample.
double GetLikelihood() const override
Return likelihood (-logL) for all samples.
auto GetDataArray() const
Return array storing data entries for every bin.
auto GetMCArray() const
Return array storing MC entries for every bin.

◆ ReadConfig()

void SampleHandlerBase::ReadConfig ( )
protected

Load information about sample handler and corresponding samples from config file.

Definition at line 54 of file SampleHandlerBase.cpp.

55 {
56  auto ModeName = Get<std::string>(SampleManager->raw()["MaCh3ModeConfig"], __FILE__ , __LINE__);
57  Modes = std::make_unique<MaCh3Modes>(getenv("MACH3")+std::string("/") + ModeName);
58  //SampleName has to be provided in the sample yaml otherwise this will throw an exception
59  SampleHandlerName = Get<std::string>(SampleManager->raw()["SampleHandlerName"], __FILE__ , __LINE__);
60 
61  fTestStatistic = static_cast<TestStatistic>(SampleManager->GetMCStatLLH());
62  if (CheckNodeExists(SampleManager->raw(), "LikelihoodOptions")) {
63  UpdateW2 = GetFromManager<bool>(SampleManager->raw()["LikelihoodOptions"]["UpdateW2"], false);
64  }
65 
66  if (!CheckNodeExists(SampleManager->raw(), "BinningFile")){
67  MACH3LOG_ERROR("BinningFile not given in for sample handler {}, ReturnKinematicParameterBinning will not work", SampleHandlerName);
68  throw MaCh3Exception(__FILE__, __LINE__);
69  }
70 
71  auto EnabledSasmples = Get<std::vector<std::string>>(SampleManager->raw()["Samples"], __FILE__ , __LINE__);
72  // Get number of samples and resize relevant objects
73  nSamples = static_cast<M3::int_t>(EnabledSasmples.size());
74  if (nSamples == 0){
75  MACH3LOG_ERROR("No samples for Sample Handler {}, please double check sample config", GetName());
76  throw MaCh3Exception(__FILE__, __LINE__);
77  }
78 
79  SampleDetails.resize(nSamples);
80  StoredSelection.resize(nSamples);
81  for (int iSample = 0; iSample < nSamples; iSample++)
82  {
83  auto SampleSettings = SampleManager->raw()[EnabledSasmples[iSample]];
84  LoadSingleSample(iSample, SampleSettings);
85  } // end loop over enabling samples
86 
87  // EM: initialise the mode weight map
88  for( int iMode=0; iMode < Modes->GetNModes(); iMode++ ) {
89  _modeNomWeightMap[Modes->GetMaCh3ModeName(iMode)] = 1.0;
90  }
91 
92  // EM: multiply by the nominal weight specified in the sample config file
93  if ( SampleManager->raw()["NominalWeights"] ) {
94  for( int iMode=0; iMode<Modes->GetNModes(); iMode++ ) {
95  std::string modeStr = Modes->GetMaCh3ModeName(iMode);
96  if( SampleManager->raw()["NominalWeights"][modeStr] ) {
97  double modeWeight = SampleManager->raw()["NominalWeights"][modeStr].as<double>();
98  _modeNomWeightMap[Modes->GetMaCh3ModeName(iMode)] *= modeWeight;
99  }
100  }
101  }
102 
103  // EM: print em out
104  MACH3LOG_INFO(" Nominal mode weights to apply: ");
105  for(int iMode=0; iMode<Modes->GetNModes(); iMode++ ) {
106  std::string modeStr = Modes->GetMaCh3ModeName(iMode);
107  MACH3LOG_INFO(" - {}: {}", modeStr, _modeNomWeightMap.at(modeStr));
108  }
109 }
TestStatistic
Make an enum of the test statistic that we're using.
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
Definition: YamlHelper.h:60
std::unordered_map< std::string, double > _modeNomWeightMap
void LoadSingleSample(const int iSample, const YAML::Node &Settings)
Initialise single sample from config file.
TestStatistic fTestStatistic
Test statistic tells what kind of likelihood sample is using.

◆ RegisterFunctionalParameters()

virtual void SampleHandlerBase::RegisterFunctionalParameters ( )
protectedpure virtual

HH - a experiment-specific function where the maps to actual functions are set up.

Implemented in PySampleHandlerBase.

◆ RegisterIndividualFunctionalParameter()

void SampleHandlerBase::RegisterIndividualFunctionalParameter ( const std::string &  fpName,
int  fpEnum,
FuncParFuncType  fpFunc 
)
protected

HH - a helper function for RegisterFunctionalParameter.

Definition at line 496 of file SampleHandlerBase.cpp.

496  {
497  // Add protections to not add the same functional parameter twice
498  if (funcParsNamesMap.find(fpName) != funcParsNamesMap.end()) {
499  MACH3LOG_ERROR("Functional parameter {} already registered in funcParsNamesMap with enum {}", fpName, funcParsNamesMap[fpName]);
500  throw MaCh3Exception(__FILE__, __LINE__);
501  }
502  if (std::find(funcParsNamesVec.begin(), funcParsNamesVec.end(), fpName) != funcParsNamesVec.end()) {
503  MACH3LOG_ERROR("Functional parameter {} already in funcParsNamesVec", fpName);
504  throw MaCh3Exception(__FILE__, __LINE__);
505  }
506  if (funcParsFuncMap.find(fpEnum) != funcParsFuncMap.end()) {
507  MACH3LOG_ERROR("Functional parameter enum {} already registered in funcParsFuncMap", fpEnum);
508  throw MaCh3Exception(__FILE__, __LINE__);
509  }
510  funcParsNamesMap[fpName] = fpEnum;
511  funcParsNamesVec.push_back(fpName);
512  funcParsFuncMap[fpEnum] = fpFunc;
513 }
std::unordered_map< std::string, int > funcParsNamesMap
HH - a map that relates the name of the functional parameter to funcpar enum.
std::vector< std::string > funcParsNamesVec
HH - a vector of string names for each functional parameter.
std::unordered_map< int, FuncParFuncType > funcParsFuncMap
HH - a map that relates the funcpar enum to pointer of the actual function.

◆ ResetHistograms()

void SampleHandlerBase::ResetHistograms ( )
protected

Helper function to reset histograms.

Definition at line 485 of file SampleHandlerBase.cpp.

485  {
486 // **************************************************
487  // DB Reset values stored in PDF array to 0.
488  // Don't openMP this; no significant gain
489  const int nBins = Binning->GetNBins();
490  std::fill_n(SampleHandler_array.begin(), nBins, 0.0);
491  if (FirstTimeW2) {
492  std::fill_n(SampleHandler_array_w2.begin(), nBins, 0.0);
493  }
494 } // end function

◆ ResetShifts()

virtual void SampleHandlerBase::ResetShifts ( const int  iEvent)
inlineprotectedvirtual

HH - reset the shifted values to the original values.

Definition at line 286 of file SampleHandlerBase.h.

286 {(void)iEvent;};

◆ ReturnHistsBySelection1D()

std::vector< std::unique_ptr< TH1 > > SampleHandlerBase::ReturnHistsBySelection1D ( const int  iSample,
const std::string &  KinematicProjection,
const int  Selection1,
const int  Selection2 = -1,
const int  WeightStyle = 0 
)

Definition at line 2000 of file SampleHandlerBase.cpp.

2001  {
2002 // ************************************************
2003  std::vector<std::unique_ptr<TH1>> hHistList;
2004  std::string legendEntry;
2005 
2006  if (THStackLeg != nullptr) {delete THStackLeg;}
2007  THStackLeg = new TLegend(0.1,0.1,0.9,0.9);
2008 
2009  const int iMax = GetRangeForPlotType(static_cast<SamplePlotType>(Selection1), iSample);
2010  for (int i=0;i<iMax;i++) {
2011  if (Selection1 == SamplePlotType::kModePlot) {
2012  hHistList.push_back(Get1DVarHistByModeAndChannel(iSample, KinematicProjection,i,Selection2,WeightStyle));
2013  THStackLeg->AddEntry(hHistList[i].get(), (Modes->GetMaCh3ModeName(i)+Form(" : (%4.2f)",hHistList[i]->Integral())).c_str(),"f");
2014 
2015  hHistList[i]->SetFillColor(static_cast<Color_t>(Modes->GetMaCh3ModePlotColor(i)));
2016  hHistList[i]->SetLineColor(static_cast<Color_t>(Modes->GetMaCh3ModePlotColor(i)));
2017  }
2018  if (Selection1 == SamplePlotType::kOscChannelPlot) {
2019  hHistList.push_back(Get1DVarHistByModeAndChannel(iSample, KinematicProjection,Selection2,i,WeightStyle));
2020  THStackLeg->AddEntry(hHistList[i].get(),(GetFlavourName(iSample, i)+Form(" | %4.2f",hHistList[i]->Integral())).c_str(),"f");
2021  }
2022  }
2023 
2024  return hHistList;
2025 }
SamplePlotType
int GetRangeForPlotType(const SamplePlotType TypeEnum, const int iSample) const
KS: Return range for plot type, for example number of modes, osc channels etc.

◆ ReturnHistsBySelection2D()

std::vector< std::unique_ptr< TH2 > > SampleHandlerBase::ReturnHistsBySelection2D ( const int  iSample,
const std::string &  KinematicProjectionX,
const std::string &  KinematicProjectionY,
const int  Selection1,
const int  Selection2 = -1,
const int  WeightStyle = 0 
)

Definition at line 2028 of file SampleHandlerBase.cpp.

2030  {
2031 // ************************************************
2032  std::vector<std::unique_ptr<TH2>> hHistList;
2033 
2034  const int iMax = GetRangeForPlotType(static_cast<SamplePlotType>(Selection1), iSample);
2035  for (int i=0;i<iMax;i++) {
2036  if (Selection1 == SamplePlotType::kModePlot) {
2037  hHistList.push_back(Get2DVarHistByModeAndChannel(iSample, KinematicProjectionX,KinematicProjectionY,i,Selection2,WeightStyle));
2038  }
2039  if (Selection1 == SamplePlotType::kOscChannelPlot) {
2040  hHistList.push_back(Get2DVarHistByModeAndChannel(iSample, KinematicProjectionX,KinematicProjectionY,Selection2,i,WeightStyle));
2041  }
2042  }
2043 
2044  return hHistList;
2045 }

◆ ReturnKinematicParameter() [1/2]

virtual double SampleHandlerBase::ReturnKinematicParameter ( const int  KinematicVariable,
const int  iEvent 
) const
protectedpure virtual

Implemented in PySampleHandlerBase.

◆ ReturnKinematicParameter() [2/2]

double SampleHandlerBase::ReturnKinematicParameter ( const std::string &  KinematicParameter,
int  iEvent 
) const
inlineprotected

Return the value of an associated kinematic parameter for an event.

Definition at line 329 of file SampleHandlerBase.h.

329  {
330  return ReturnKinematicParameter(ReturnKinematicParameterFromString(KinematicParameter), iEvent);
331  }

◆ ReturnKinematicParameterBinning()

std::vector< double > SampleHandlerBase::ReturnKinematicParameterBinning ( const int  Sample,
const std::string &  KinematicParameter 
) const
finalprotectedvirtual

Return the binning used to draw a kinematic parameter.

Parameters
iSampleIndex of the sample.
KinematicParametername of variable
Todo:
might be useful to allow overwriting this

Implements SampleHandlerInterface.

Definition at line 1702 of file SampleHandlerBase.cpp.

1702  {
1703 // ************************************************
1704  // If any of fit based variables return them
1706  if(Binning->IsUniform(Sample)) {
1707  for(int iDim = 0; iDim < GetNDim(Sample); iDim++) {
1708  if(KinematicParameter == GetKinVarName(Sample, iDim)) {
1709  return Binning->GetBinEdges(Sample, iDim);
1710  }
1711  } // end loop over Dimension
1712  } // end loop over IsUniform
1713 
1714  auto MakeBins = [](int nBins) {
1715  std::vector<double> bins(nBins + 1);
1716  for (int i = 0; i <= nBins; ++i)
1717  bins[i] = static_cast<double>(i) - 0.5;
1718  return bins;
1719  };
1720 
1721  if (KinematicParameter == "OscillationChannel") {
1722  return MakeBins(GetNOscChannels(Sample));
1723  } else if (KinematicParameter == "Mode") {
1724  return MakeBins(Modes->GetNModes());
1725  }
1726 
1727  std::vector<double> BinningVect;
1728  // We first check if binning for a sample has been specified
1729  auto BinningConfig = M3OpenConfig(SampleManager->raw()["BinningFile"].as<std::string>());
1730  bool found_range_specifier = false;
1731  if(BinningConfig[GetSampleTitle(Sample)] && BinningConfig[GetSampleTitle(Sample)][KinematicParameter]){
1732  BinningVect = BuildBinEdgesFromNode(BinningConfig[GetSampleTitle(Sample)][KinematicParameter], found_range_specifier);
1733  } else {
1734  BinningVect = BuildBinEdgesFromNode(BinningConfig[KinematicParameter], found_range_specifier);
1735  }
1736 
1737  // Ensure binning is increasing
1738  auto IsIncreasing = [](const std::vector<double>& vec) {
1739  for (size_t i = 1; i < vec.size(); ++i) {
1740  if (vec[i] <= vec[i-1]) {
1741  return false;
1742  }
1743  }
1744  return true;
1745  };
1746 
1747  if (!IsIncreasing(BinningVect)) {
1748  MACH3LOG_ERROR("Binning for {} is not increasing [{}]", KinematicParameter, fmt::join(BinningVect, ", "));
1749  if(found_range_specifier){
1750  MACH3LOG_ERROR("A bin range specifier was found. Please carefully check the number of square brackets used.");
1751  }
1752  throw MaCh3Exception(__FILE__, __LINE__);
1753  }
1754  return BinningVect;
1755 }
std::vector< double > BuildBinEdgesFromNode(YAML::Node const &bin_edges_node, bool &found_range_specifier)
Builds a single dimension's bin edges from YAML::Node.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589

◆ ReturnKinematicParameterFromString()

int SampleHandlerBase::ReturnKinematicParameterFromString ( const std::string &  KinematicStr) const

ETA function to generically convert a string from xsec cov to a kinematic type.

Definition at line 1649 of file SampleHandlerBase.cpp.

1649  {
1650 // ************************************************
1651  auto it = KinematicParameters->find(KinematicParameterStr);
1652  if (it != KinematicParameters->end()) return it->second;
1653 
1654  MACH3LOG_ERROR("Did not recognise Kinematic Parameter type: {}", KinematicParameterStr);
1655  throw MaCh3Exception(__FILE__, __LINE__);
1656 
1657  return M3::_BAD_INT_;
1658 }

◆ ReturnKinematicVector() [1/2]

virtual std::vector<double> SampleHandlerBase::ReturnKinematicVector ( const int  KinematicVariable,
const int  iEvent 
) const
inlineprotectedvirtual

Definition at line 338 of file SampleHandlerBase.h.

338  {
339  return {}; (void)KinematicVariable; (void)iEvent;};

◆ ReturnKinematicVector() [2/2]

std::vector<double> SampleHandlerBase::ReturnKinematicVector ( const std::string &  KinematicParameter,
const int  iEvent 
) const
inlineprotected

Definition at line 335 of file SampleHandlerBase.h.

335  {
336  return ReturnKinematicVector(ReturnKinematicVectorFromString(KinematicParameter), iEvent);
337  }

◆ ReturnKinematicVectorFromString()

int SampleHandlerBase::ReturnKinematicVectorFromString ( const std::string &  KinematicStr) const

JM: Convert a kinematic vector name to its corresponding integer ID.

Definition at line 1676 of file SampleHandlerBase.cpp.

1676  {
1677 // ************************************************
1678  auto it = KinematicVectors->find(KinematicVectorStr);
1679  if (it != KinematicVectors->end()) return it->second;
1680 
1681  MACH3LOG_ERROR("Did not recognise Kinematic Vector: {}", KinematicVectorStr);
1682  throw MaCh3Exception(__FILE__, __LINE__);
1683 
1684  return M3::_BAD_INT_;
1685 }

◆ ReturnStackedHistBySelection1D()

std::unique_ptr< THStack > SampleHandlerBase::ReturnStackedHistBySelection1D ( const int  iSample,
const std::string &  KinematicProjection,
const int  Selection1,
const int  Selection2 = -1,
const int  WeightStyle = 0 
)

Definition at line 2048 of file SampleHandlerBase.cpp.

2049  {
2050 // ************************************************
2051  auto HistList = ReturnHistsBySelection1D(iSample, KinematicProjection, Selection1, Selection2, WeightStyle);
2052  auto StackHist = std::make_unique<THStack>((GetSampleTitle(iSample)+"_"+KinematicProjection+"_Stack").c_str(),"");
2053  // Note: we use .release() to transfer ownership of each TH1 to THStack.
2054  for (unsigned int i=0;i<HistList.size();i++) {
2055  StackHist->Add(HistList[i].release());
2056  }
2057  return StackHist;
2058 }

◆ ReturnStackHistLegend()

const TLegend* SampleHandlerBase::ReturnStackHistLegend ( ) const
inline

Return the legend used for stacked histograms with sample info.

Definition at line 158 of file SampleHandlerBase.h.

158 {return THStackLeg;}

◆ ReturnStringFromKinematicParameter()

std::string SampleHandlerBase::ReturnStringFromKinematicParameter ( const int  KinematicVariable) const

ETA function to generically convert a kinematic type from xsec cov to a string.

Definition at line 1661 of file SampleHandlerBase.cpp.

1661  {
1662 // ************************************************
1663  auto it = ReversedKinematicParameters->find(KinematicParameter);
1664  if (it != ReversedKinematicParameters->end()) {
1665  return it->second;
1666  }
1667 
1668  MACH3LOG_ERROR("Did not recognise Kinematic Parameter type: {}", KinematicParameter);
1669  throw MaCh3Exception(__FILE__, __LINE__);
1670 
1671  return "";
1672 }

◆ ReturnStringFromKinematicVector()

std::string SampleHandlerBase::ReturnStringFromKinematicVector ( const int  KinematicVariable) const

JM: Convert a kinematic vector integer ID to its corresponding name as a string.

Definition at line 1688 of file SampleHandlerBase.cpp.

1688  {
1689 // ************************************************
1690  auto it = ReversedKinematicVectors->find(KinematicVector);
1691  if (it != ReversedKinematicVectors->end()) {
1692  return it->second;
1693  }
1694 
1695  MACH3LOG_ERROR("Did not recognise Kinematic Vector: {}", KinematicVector);
1696  throw MaCh3Exception(__FILE__, __LINE__);
1697 
1698  return "";
1699 }

◆ Reweight()

void SampleHandlerBase::Reweight ( )
overridevirtual

main routine modifying MC prediction based on proposed parameter values

Implements SampleHandlerInterface.

Definition at line 347 of file SampleHandlerBase.cpp.

347  {
348 //************************************************
349  //KS: Reset the histograms before reweight
350  ResetHistograms();
351 
352  //You only need to do these things if Oscillator has been initialised
353  //if not then you're not considering oscillations
354  if (Oscillator) Oscillator->Evaluate();
355 
356  // Calculate weight coming from all splines if we initialised handler
357  if(SplineHandler) SplineHandler->Evaluate();
358 
359  // Update the functional parameter values to the latest proposed values
361 
362  //KS: If using CPU this does nothing, if on GPU need to make sure we finished copying memory from
363  if(SplineHandler) SplineHandler->SynchroniseMemTransfer();
364 
365  #ifdef MULTITHREAD
366  // Call entirely different routine if we're running with openMP
367  FillArray_MP();
368  #else
369  FillArray();
370  #endif
371 
372  //KS: If you want to not update W2 wights then uncomment this line
373  if(!UpdateW2) FirstTimeW2 = false;
374 }
void FillArray_MP()
DB Nice new multi-threaded function which calculates the event weights and fills the relevant bins of...
virtual void PrepFunctionalParameters()
Update the functional parameter values to the latest proposed values. Needs to be called before every...
void ResetHistograms()
Helper function to reset histograms.
void FillArray()
Function which does the core reweighting, fills the SampleHandlerBase::SampleHandler_array vector wit...

◆ SaveAdditionalInfo()

void SampleHandlerBase::SaveAdditionalInfo ( TDirectory *  Dir)
finalvirtual

Store additional info in a chain.

Parameters
Dirdirectory to which we save additional info

Reimplemented from SampleHandlerInterface.

Definition at line 1346 of file SampleHandlerBase.cpp.

1346  {
1347 // ************************************************
1348  Dir->cd();
1349 
1350  YAML::Node Config = SampleManager->raw();
1351  TMacro ConfigSave = YAMLtoTMacro(Config, (std::string("Config_") + GetName()));
1352  ConfigSave.Write();
1353 
1354  for(int iSample = 0; iSample < GetNSamples(); iSample++)
1355  {
1356  std::unique_ptr<TH1> data_hist;
1357 
1358  if (GetNDim(iSample) == 1) {
1359  data_hist = M3::Clone<TH1D>(dynamic_cast<const TH1D*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1360  data_hist->GetXaxis()->SetTitle(GetKinVarName(iSample, 0).c_str());
1361  data_hist->GetYaxis()->SetTitle("Number of Events");
1362  } else if (GetNDim(iSample) == 2) {
1363  if(Binning->IsUniform(iSample)) {
1364  data_hist = M3::Clone<TH2D>(dynamic_cast<const TH2D*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1365  } else {
1366  data_hist = M3::Clone<TH2Poly>(dynamic_cast<const TH2Poly*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1367  }
1368  data_hist->GetXaxis()->SetTitle(GetKinVarName(iSample, 0).c_str());
1369  data_hist->GetYaxis()->SetTitle(GetKinVarName(iSample, 1).c_str());
1370  data_hist->GetZaxis()->SetTitle("Number of Events");
1371  } else {
1372  data_hist = M3::Clone<TH1D>(dynamic_cast<const TH1D*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1373  int nbins = Binning->GetNBins(iSample);
1374  for(int iBin = 0; iBin < nbins; iBin++) {
1375  auto BinName = Binning->GetBinName(iSample, iBin);
1376  data_hist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
1377  }
1378  data_hist->GetYaxis()->SetTitle("Number of Events");
1379  }
1380 
1381  if (!data_hist) {
1382  MACH3LOG_ERROR("nullptr data hist :(");
1383  throw MaCh3Exception(__FILE__, __LINE__);
1384  }
1385 
1386  data_hist->SetTitle(("data_" + GetSampleTitle(iSample)).c_str());
1387  data_hist->Write();
1388  }
1389 }
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
Definition: YamlHelper.h:167

◆ SetBinning()

void SampleHandlerBase::SetBinning ( )
protected

set the binning for 2D sample used for the likelihood calculation

Definition at line 772 of file SampleHandlerBase.cpp.

772  {
773 // ************************************************
774  for(int iSample = 0; iSample < GetNSamples(); iSample++)
775  {
776  int Dimension = GetNDim(iSample);
777  std::string HistTitle = GetSampleTitle(iSample);
778 
779  auto* SamDet = &SampleDetails[iSample];
780  if(Dimension == 1) {
781  auto XVec = Binning->GetBinEdges(iSample, 0);
782  SamDet->DataHist = new TH1D(("d" + HistTitle).c_str(), HistTitle.c_str(), static_cast<int>(XVec.size()-1), XVec.data());
783  SamDet->MCHist = new TH1D(("h" + HistTitle).c_str(), HistTitle.c_str(), static_cast<int>(XVec.size()-1), XVec.data());
784  SamDet->W2Hist = new TH1D(("w" + HistTitle).c_str(), HistTitle.c_str(), static_cast<int>(XVec.size()-1), XVec.data());
785 
786  // Set all titles so most of projections don't have empty titles...
787  SamDet->DataHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
788  SamDet->DataHist->GetYaxis()->SetTitle("Events");
789  SamDet->MCHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
790  SamDet->MCHist->GetYaxis()->SetTitle("Events");
791  SamDet->W2Hist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
792  SamDet->W2Hist->GetYaxis()->SetTitle("Events");
793  } else if (Dimension == 2){
794  if(Binning->IsUniform(iSample)) {
795  auto XVec = Binning->GetBinEdges(iSample, 0);
796  auto YVec = Binning->GetBinEdges(iSample, 1);
797  int nX = static_cast<int>(XVec.size() - 1);
798  int nY = static_cast<int>(YVec.size() - 1);
799 
800  SamDet->DataHist = new TH2D(("d" + HistTitle).c_str(), HistTitle.c_str(), nX, XVec.data(), nY, YVec.data());
801  SamDet->MCHist = new TH2D(("h" + HistTitle).c_str(), HistTitle.c_str(), nX, XVec.data(), nY, YVec.data());
802  SamDet->W2Hist = new TH2D(("w" + HistTitle).c_str(), HistTitle.c_str(), nX, XVec.data(), nY, YVec.data());
803  } else {
804  auto AddBinsToTH2Poly = [](TH2Poly* hist, const std::vector<BinInfo>& bins) {
805  for (const auto& bin : bins) {
806  double xLow = bin.Extent[0][0];
807  double xHigh = bin.Extent[0][1];
808  double yLow = bin.Extent[1][0];
809  double yHigh = bin.Extent[1][1];
810 
811  double x[4] = {xLow, xHigh, xHigh, xLow};
812  double y[4] = {yLow, yLow, yHigh, yHigh};
813 
814  hist->AddBin(4, x, y);
815  }
816  };
817  // Create all three histograms
818  SamDet->DataHist = new TH2Poly();
819  SamDet->DataHist->SetName(("d" + HistTitle).c_str());
820  SamDet->DataHist->SetTitle(HistTitle.c_str());
821 
822  SamDet->MCHist = new TH2Poly();
823  SamDet->MCHist->SetName(("h" + HistTitle).c_str());
824  SamDet->MCHist->SetTitle(HistTitle.c_str());
825 
826  SamDet->W2Hist = new TH2Poly();
827  SamDet->W2Hist->SetName(("w" + HistTitle).c_str());
828  SamDet->W2Hist->SetTitle(HistTitle.c_str());
829 
830  // Add bins to each
831  AddBinsToTH2Poly(static_cast<TH2Poly*>(SamDet->DataHist), Binning->GetNonUniformBins(iSample));
832  AddBinsToTH2Poly(static_cast<TH2Poly*>(SamDet->MCHist), Binning->GetNonUniformBins(iSample));
833  AddBinsToTH2Poly(static_cast<TH2Poly*>(SamDet->W2Hist), Binning->GetNonUniformBins(iSample));
834  }
835 
836  // Set all titles so most of projections don't have empty titles...
837  SamDet->DataHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
838  SamDet->DataHist->GetYaxis()->SetTitle(SamDet->VarStr[1].c_str());
839  SamDet->MCHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
840  SamDet->MCHist->GetYaxis()->SetTitle(SamDet->VarStr[1].c_str());
841  SamDet->W2Hist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
842  SamDet->W2Hist->GetYaxis()->SetTitle(SamDet->VarStr[1].c_str());
843  } else {
844  int nbins = Binning->GetNBins(iSample);
845  SamDet->DataHist = new TH1D(("d" + HistTitle).c_str(), HistTitle.c_str(), nbins, 0, nbins);
846  SamDet->MCHist = new TH1D(("h" + HistTitle).c_str(), HistTitle.c_str(), nbins, 0, nbins);
847  SamDet->W2Hist = new TH1D(("w" + HistTitle).c_str(), HistTitle.c_str(), nbins, 0, nbins);
848 
849  for(int iBin = 0; iBin < nbins; iBin++) {
850  auto BinName = Binning->GetBinName(iSample, iBin);
851  SamDet->DataHist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
852  SamDet->MCHist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
853  SamDet->W2Hist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
854  }
855 
856  // Set all titles so most of projections don't have empty titles...
857  SamDet->DataHist->GetYaxis()->SetTitle("Events");
858  SamDet->MCHist->GetYaxis()->SetTitle("Events");
859  SamDet->W2Hist->GetYaxis()->SetTitle("Events");
860  }
861 
862  SamDet->DataHist->SetDirectory(nullptr);
863  SamDet->MCHist->SetDirectory(nullptr);
864  SamDet->W2Hist->SetDirectory(nullptr);
865  }
866 
867  //Set the number of X and Y bins now
870 }
void SetupReweightArrays()
Initialise data, MC and W2 histograms.

◆ SetSplinePointers()

void SampleHandlerBase::SetSplinePointers ( )
protected

Set pointers for each event to appropriate weights, for unbinned based on event number while for binned based on other kinematical properties.

Definition at line 1260 of file SampleHandlerBase.cpp.

1260  {
1261 // ************************************************
1262  //Now loop over events and get the spline bin for each event
1263  if (auto BinnedSpline = dynamic_cast<BinnedSplineHandler*>(SplineHandler.get())) {
1264  bool ThrowCrititcal = true;
1265 
1266  std::vector< std::vector<SplineParameter> > SplineParsVec(GetNSamples());
1267  for (int iSample = 0; iSample < GetNSamples(); ++iSample) {
1268  SplineParsVec[iSample] = ParHandler->GetSplineParsFromSampleName(GetSampleName(iSample));
1269  }
1270  for (unsigned int j = 0; j < GetNEvents(); ++j) {
1271  auto EventSplines = GetSplineBins(j, BinnedSpline, ThrowCrititcal);
1272  const int NSplines = static_cast<int>(EventSplines.size());
1273  if(NSplines == 0) continue;
1274  auto& w_pointers = MCEvents[j].total_weight_pointers;
1275  w_pointers.reserve(w_pointers.size() + NSplines);
1276  const auto SampleId = MCEvents[j].NominalSample;
1277  for(int spline = 0; spline < NSplines; spline++) {
1278  int SystIndex = EventSplines[spline][2];
1279 
1280  bool IsSelected = PassesSelection(SplineParsVec[SampleId][SystIndex], j);
1281  // Need to then break the event loop
1282  if(!IsSelected){
1283  MACH3LOG_TRACE("Event {}, missed Kinematic var check for dial {}", j, SplineParsVec[SampleId][SystIndex].name);
1284  continue;
1285  }
1286  //Event Splines indexed as: sample name, oscillation channel, syst, mode, etrue, var1, var2 (var2 is a dummy 0 for 1D splines)
1287  w_pointers.push_back(BinnedSpline->RetPointer(EventSplines[spline][0], EventSplines[spline][1],
1288  EventSplines[spline][2], EventSplines[spline][3],
1289  EventSplines[spline][4], EventSplines[spline][5],
1290  EventSplines[spline][6]));
1291  } // end loop over splines
1292  w_pointers.shrink_to_fit();
1293  } // end loop over events
1294  } else if (auto UnbinnedSpline = dynamic_cast<UnbinnedSplineHandler*>(SplineHandler.get())) {
1295  for (unsigned int iEvent = 0; iEvent < GetNEvents(); ++iEvent) {
1296  MCEvents[iEvent].total_weight_pointers.push_back(UnbinnedSpline->RetPointer(iEvent));
1297  }
1298  } else {
1299  MACH3LOG_ERROR("Not supported splines");
1300  throw MaCh3Exception(__FILE__, __LINE__);
1301  }
1302 }
const std::vector< SplineParameter > GetSplineParsFromSampleName(const std::string &SampleName) const
KS: Grab the Spline parameters for the relevant SampleName.
std::vector< std::vector< int > > GetSplineBins(int Event, BinnedSplineHandler *BinnedSpline, bool &ThrowCrititcal) const
Retrieve the spline bin indices associated with a given event.

◆ SetupExperimentMC()

virtual int SampleHandlerBase::SetupExperimentMC ( )
protectedpure virtual

Experiment specific setup, returns the number of events which were loaded.

Implemented in PySampleHandlerBase.

◆ SetupFunctionalParameters()

void SampleHandlerBase::SetupFunctionalParameters ( )
protectedvirtual

ETA - a function to setup and pass values to functional parameters where you need to pass a value to some custom reweight calc or engine.

Todo:
KS: Instead of clearing it they should not be class members, so we must fix it in future

Definition at line 516 of file SampleHandlerBase.cpp.

516  {
517 // **************************************************
518  funcParsGrid.resize(GetNEvents());
519  if(ParHandler == nullptr) return;
520  funcParsVec.resize(GetNSamples());
521  for(int iSample = 0; iSample < GetNSamples(); iSample++){
523  }
524  // RegisterFunctionalParameters is implemented in experiment-specific code,
525  // which calls RegisterIndividualFuncPar to populate funcParsNamesMap, funcParsNamesVec, and funcParsFuncMap
527  funcParsMap.resize(funcParsNamesMap.size());
528 
529  // For every functional parameter in XsecCov that matches the name in funcParsNames, add it to the map
530  for (auto& funcParsSubVec : funcParsVec) {
531  // For every FunctionalParameter in the sub-vector
532  for (FunctionalParameter& fp : funcParsSubVec) {
533  auto it = funcParsNamesMap.find(fp.name);
534  // If we don't find a match, we need to throw an error
535  if (it == funcParsNamesMap.end()) {
536  MACH3LOG_ERROR("Functional parameter {} not found, did you define it in RegisterFunctionalParameters()?", fp.name);
537  throw MaCh3Exception(__FILE__, __LINE__);
538  }
539  const std::size_t key = static_cast<std::size_t>(it->second);
540  MACH3LOG_INFO("Adding functional parameter: {} to funcParsMap with key: {}",fp.name, key);
541 
542  const int ikey = it->second;
543  fp.funcPtr = &funcParsFuncMap[ikey];
544 
545  funcParsMap[key].valuePtr = fp.valuePtr;
546  funcParsMap[key].funcPtr = fp.funcPtr;
547  }
548  }
549 
550  // Mostly the same as CalcNormsBins
551  // For each event, make a vector of pointers to the functional parameters
552  for (std::size_t iEvent = 0; iEvent < static_cast<std::size_t>(GetNEvents()); ++iEvent) {
553  const auto SampleId = MCEvents[iEvent].NominalSample;
554  // Now loop over the functional parameters and get a vector of enums corresponding to the functional parameters
555  for (std::vector<FunctionalParameter>::iterator it = funcParsVec[SampleId].begin(); it != funcParsVec[SampleId].end(); ++it) {
556  // Check whether the interaction modes match
557  const int Mode = static_cast<int>(std::round(ReturnKinematicParameter("Mode", static_cast<int>(iEvent))));
558  bool ModeMatch = MatchCondition(it->modes, Mode);
559  if (!ModeMatch) {
560  MACH3LOG_TRACE("Event {}, missed Mode check ({}) for dial {}", iEvent, Mode, it->name);
561  continue;
562  }
563  // Now check whether within kinematic bounds
564  bool IsSelected = PassesSelection((*it), iEvent);
565  // Need to then break the event loop
566  if(!IsSelected){
567  MACH3LOG_TRACE("Event {}, missed Kinematic var check for dial {}", iEvent, it->name);
568  continue;
569  }
570  const std::size_t key = static_cast<std::size_t>(funcParsNamesMap[it->name]);
571  funcParsGrid[iEvent].push_back(&funcParsMap[key]);
572  }
573  }
574  MACH3LOG_INFO("Finished setting up functional parameters");
575 
578 
579  funcParsNamesMap.clear();
580  funcParsNamesMap.rehash(0);
581 }
void CleanVector(T &)
Base case: do nothing for non-vector types.
const std::vector< FunctionalParameter > GetFunctionalParametersFromSampleName(const std::string &SampleName) const
HH Get functional parameters for the relevant SampleName.
std::vector< FunctionalShifter > funcParsMap
HH - a map that relates the funcpar enum to pointer of FuncPars struct HH - Changed to a vector of po...
std::vector< std::vector< FunctionalParameter > > funcParsVec
HH - a vector that stores all the FuncPars struct.
virtual void RegisterFunctionalParameters()=0
HH - a experiment-specific function where the maps to actual functions are set up.
HH - Functional parameters Carrier for whether you want to apply a systematic to an event or not.

◆ SetupKinematicMap()

void SampleHandlerBase::SetupKinematicMap ( )
protected

Ensure Kinematic Map is setup and make sure it is initialised correctly.

Definition at line 236 of file SampleHandlerBase.cpp.

236  {
237 // ************************************************
238  if(KinematicParameters == nullptr || ReversedKinematicParameters == nullptr) {
239  MACH3LOG_ERROR("Map KinematicParameters or ReversedKinematicParameters hasn't been initialised");
240  throw MaCh3Exception(__FILE__, __LINE__);
241  }
242  // KS: Ensure maps exist correctly
243  for (const auto& pair : *KinematicParameters) {
244  const auto& key = pair.first;
245  const auto& value = pair.second;
246 
247  auto it = ReversedKinematicParameters->find(value);
248  if (it == ReversedKinematicParameters->end() || it->second != key) {
249  MACH3LOG_ERROR("Mismatch found: {} -> {} but {} -> {}",
250  key, value, value, (it != ReversedKinematicParameters->end() ? it->second : "NOT FOUND"));
251  throw MaCh3Exception(__FILE__, __LINE__);
252  }
253  }
254  // KS: Ensure some MaCh3 specific variables are defined
255  std::vector<std::string> Vars = {"Mode", "OscillationChannel", "TargetNucleus"};
256  for(size_t iVar = 0; iVar < Vars.size(); iVar++) {
257  try {
259  } catch (const MaCh3Exception&) {
260  MACH3LOG_ERROR("MaCh3 expected variable: {} not found in KinematicParameters.", Vars[iVar]);
261  MACH3LOG_ERROR("All keys in KinematicParameters:");
262  for (const auto& pair : *KinematicParameters) {
263  MACH3LOG_ERROR("Key: {}", pair.first);
264  }
265  throw MaCh3Exception(__FILE__, __LINE__);
266  }
267  }
268 }

◆ SetupMC()

virtual void SampleHandlerBase::SetupMC ( )
protectedpure virtual

Function which translates experiment struct into core struct.

Implemented in PySampleHandlerBase.

◆ SetupNormParameters()

void SampleHandlerBase::SetupNormParameters ( )
protected

Setup the norm parameters by assigning each event with bin.

Definition at line 663 of file SampleHandlerBase.cpp.

663  {
664 // ***************************************************************************
665  if(ParHandler == nullptr) return;
666  std::vector< std::vector< int > > norms_bins(GetNEvents());
667 
668  std::vector< std::vector<NormParameter>> norm_parameters(GetNSamples());
669 
670  for (int iSample = 0; iSample < GetNSamples(); ++iSample) {
671  norm_parameters[iSample] = ParHandler->GetNormParsFromSampleName(GetSampleName(iSample));
672  }
673  if(!ParHandler) {
674  MACH3LOG_ERROR("ParHandler is not setup!");
675  throw MaCh3Exception(__FILE__ , __LINE__ );
676  }
677 
678  // Assign norm bins in MCEvents tree
679  CalcNormsBins(norm_parameters, norms_bins);
680 
681  //DB Attempt at reducing impact of SystematicHandlerGeneric::calcReweight()
682  for (unsigned int iEvent = 0; iEvent < GetNEvents(); ++iEvent) {
683  int counter = 0;
684  const size_t offset = MCEvents[iEvent].total_weight_pointers.size();
685  const size_t addSize = norms_bins[iEvent].size();
686  MCEvents[iEvent].total_weight_pointers.resize(offset + addSize);
687  for(auto const & norm_bin: norms_bins[iEvent]) {
688  MCEvents[iEvent].total_weight_pointers[offset + counter] = ParHandler->RetPointer(norm_bin);
689  counter += 1;
690  }
691  }
692 }
const M3::float_t * RetPointer(const int iParam) const
DB Pointer return to param position.
const std::vector< NormParameter > GetNormParsFromSampleName(const std::string &SampleName) const
DB Get norm/func parameters depending on given SampleName.
void CalcNormsBins(std::vector< std::vector< NormParameter >> &norm_parameters, std::vector< std::vector< int > > &norms_bins)
Check whether a normalisation systematic affects an event or not.

◆ SetupNuOscillatorPointers()

void SampleHandlerBase::SetupNuOscillatorPointers ( )
protected

Initialise pointer to oscillation weight to NuOscillator object.

Definition at line 1137 of file SampleHandlerBase.cpp.

1137  {
1138 // ************************************************
1139  auto AddOscPointer = GetFromManager<bool>(SampleManager->raw()["NuOsc"]["AddOscPointer"], true, __FILE__ , __LINE__);
1140  // Sometimes we don't want to add osc pointer to allow for some experiment specific handling of osc weight, like for example being able to shift osc weigh
1141  if(!AddOscPointer) {
1142  return;
1143  }
1144  for (unsigned int iEvent=0;iEvent<GetNEvents();iEvent++) {
1145  const M3::float_t* osc_w_pointer = GetNuOscillatorPointers(iEvent);
1146 
1147  // KS: Do not add unity
1148  if (osc_w_pointer != &M3::Unity) {
1149  MCEvents[iEvent].total_weight_pointers.push_back(osc_w_pointer);
1150  }
1151  }
1152 }
const M3::float_t * GetNuOscillatorPointers(const int iEvent) const
Get pointer to NuOscillator weight for a given event.

◆ SetupOscParameters()

void SampleHandlerBase::SetupOscParameters ( )
protected

Setup the osc parameters.

Definition at line 624 of file SampleHandlerBase.cpp.

624  {
625 // ***************************************************************************
626  // KS: Only make sense to setup osc if you have ParHandler
627  if(ParHandler == nullptr ) return;
628 
629  auto OscParams = ParHandler->GetOscParsFromSampleName(GetSampleName(0));
630  if (OscParams.size() > 0) {
631  MACH3LOG_INFO("Setting up NuOscillator..");
632  if (Oscillator != nullptr) {
633  MACH3LOG_INFO("You have passed an OscillatorBase object through the constructor of a SampleHandlerFD object - this will be used for all oscillation channels");
634  if(Oscillator->isEqualBinningPerOscChannel() != true) {
635  MACH3LOG_ERROR("Trying to run shared NuOscillator without EqualBinningPerOscChannel, this will not work");
636  throw MaCh3Exception(__FILE__, __LINE__);
637  }
638 
639  if(OscParams.size() != Oscillator->GetOscParamsSize()){
640  MACH3LOG_ERROR("SampleHandler {} has {} osc params, while shared NuOsc has {} osc params", GetName(),
641  OscParams.size(), Oscillator->GetOscParamsSize());
642  MACH3LOG_ERROR("This indicate misconfiguration in your Osc yaml");
643  throw MaCh3Exception(__FILE__, __LINE__);
644  }
645  } else {
647  }
649  } else{
650  MACH3LOG_WARN("Didn't find any oscillation params, thus will not enable oscillations");
651  if(CheckNodeExists(SampleManager->raw(), "NuOsc")){
652  MACH3LOG_ERROR("However config for SampleHandler {} has 'NuOsc' field", GetName());
653  MACH3LOG_ERROR("This may indicate misconfiguration");
654  MACH3LOG_ERROR("Either remove 'NuOsc' field from SampleHandler config or check your model.yaml and include oscillation for sample");
655  throw MaCh3Exception(__FILE__, __LINE__);
656  }
657  }
658 }
void InitialiseNuOscillatorObjects()
including Dan's magic NuOscillator
void SetupNuOscillatorPointers()
Initialise pointer to oscillation weight to NuOscillator object.

◆ SetupReweightArrays()

void SampleHandlerBase::SetupReweightArrays ( )
protected

Initialise data, MC and W2 histograms.

Definition at line 764 of file SampleHandlerBase.cpp.

764  {
765 // ************************************************
766  SampleHandler_array = std::vector<double>(Binning->GetNBins(),0);
767  SampleHandler_array_w2 = std::vector<double>(Binning->GetNBins(),0);
768  SampleHandler_data = std::vector<double>(Binning->GetNBins(),0);
769 }

◆ SetupSplines()

virtual void SampleHandlerBase::SetupSplines ( )
protectedpure virtual

initialise your splineXX object and then use InitialiseSplineObject to conviently setup everything up

Todo:
abstract the spline initialisation completely to core

Implemented in PySampleHandlerBase.

Member Data Documentation

◆ _modeNomWeightMap

std::unordered_map<std::string, double> SampleHandlerBase::_modeNomWeightMap
protected

Definition at line 433 of file SampleHandlerBase.h.

◆ Binning

std::unique_ptr<BinningHandler> SampleHandlerBase::Binning
protected

KS: This stores binning information, in future could be come vector to store binning for every used sample.

Definition at line 381 of file SampleHandlerBase.h.

◆ FileToFinalPDGMap

std::unordered_map<std::string, NuPDG> SampleHandlerBase::FileToFinalPDGMap
private

Mapping from input file names to final neutrino PDG codes.

Definition at line 457 of file SampleHandlerBase.h.

◆ FileToInitPDGMap

std::unordered_map<std::string, NuPDG> SampleHandlerBase::FileToInitPDGMap
private

Mapping from input file names to initial neutrino PDG codes.

Definition at line 455 of file SampleHandlerBase.h.

◆ FirstTimeW2

bool SampleHandlerBase::FirstTimeW2
protected

KS:Super hacky to update W2 or not.

Definition at line 440 of file SampleHandlerBase.h.

◆ funcParsFuncMap

std::unordered_map<int, FuncParFuncType> SampleHandlerBase::funcParsFuncMap
protected

HH - a map that relates the funcpar enum to pointer of the actual function.

Definition at line 310 of file SampleHandlerBase.h.

◆ funcParsGrid

std::vector<std::vector<FunctionalShifter*> > SampleHandlerBase::funcParsGrid
protected

HH - a grid of vectors of enums for each sample and event.

Definition at line 293 of file SampleHandlerBase.h.

◆ funcParsMap

std::vector<FunctionalShifter> SampleHandlerBase::funcParsMap
protected

HH - a map that relates the funcpar enum to pointer of FuncPars struct HH - Changed to a vector of pointers since it's faster than unordered_map and we are using ints as keys.

Definition at line 298 of file SampleHandlerBase.h.

◆ funcParsNamesMap

std::unordered_map<std::string, int> SampleHandlerBase::funcParsNamesMap
protected

HH - a map that relates the name of the functional parameter to funcpar enum.

Definition at line 307 of file SampleHandlerBase.h.

◆ funcParsNamesVec

std::vector<std::string> SampleHandlerBase::funcParsNamesVec = {}
protected

HH - a vector of string names for each functional parameter.

Definition at line 312 of file SampleHandlerBase.h.

◆ funcParsVec

std::vector<std::vector<FunctionalParameter> > SampleHandlerBase::funcParsVec
protected

HH - a vector that stores all the FuncPars struct.

Todo:
KS: Below functional variables are used only on setup, thus we should refactor them in such a way that they are removed as class members but this would be breaking change thus keep it for the time being.

Definition at line 304 of file SampleHandlerBase.h.

◆ KinematicParameters

const std::unordered_map<std::string, int>* SampleHandlerBase::KinematicParameters
protected

Mapping between string and kinematic enum.

Definition at line 421 of file SampleHandlerBase.h.

◆ KinematicVectors

const std::unordered_map<std::string, int>* SampleHandlerBase::KinematicVectors
protected

Definition at line 426 of file SampleHandlerBase.h.

◆ MCEvents

std::vector<EventInfo> SampleHandlerBase::MCEvents
protected

Stores information about every MC event.

Definition at line 392 of file SampleHandlerBase.h.

◆ Oscillator

std::shared_ptr<OscillationHandler> SampleHandlerBase::Oscillator
protected

Contains oscillator handling calculating oscillation probabilities.

Definition at line 250 of file SampleHandlerBase.h.

◆ ParHandler

ParameterHandlerGeneric* SampleHandlerBase::ParHandler = nullptr
protected

ETA - All experiments will need an xsec, det and osc cov.

Definition at line 400 of file SampleHandlerBase.h.

◆ ReversedKinematicParameters

const std::unordered_map<int, std::string>* SampleHandlerBase::ReversedKinematicParameters
protected

Mapping between kinematic enum and string.

Definition at line 423 of file SampleHandlerBase.h.

◆ ReversedKinematicVectors

const std::unordered_map<int, std::string>* SampleHandlerBase::ReversedKinematicVectors
protected

Definition at line 427 of file SampleHandlerBase.h.

◆ SampleDetails

std::vector<SampleInfo> SampleHandlerBase::SampleDetails
protected

Stores info about currently initialised sample.

Definition at line 394 of file SampleHandlerBase.h.

◆ SampleHandler_array

std::vector<double> SampleHandlerBase::SampleHandler_array
protected

DB Array to be filled after reweighting.

Definition at line 383 of file SampleHandlerBase.h.

◆ SampleHandler_array_w2

std::vector<double> SampleHandlerBase::SampleHandler_array_w2
protected

KS Array used for MC stat.

Definition at line 385 of file SampleHandlerBase.h.

◆ SampleHandler_data

std::vector<double> SampleHandlerBase::SampleHandler_data
protected

DB Array to be filled in AddData.

Definition at line 387 of file SampleHandlerBase.h.

◆ SampleHandlerName

std::string SampleHandlerBase::SampleHandlerName
protected

A unique ID for each sample based on which we can define what systematic should be applied.

Definition at line 404 of file SampleHandlerBase.h.

◆ SampleManager

std::unique_ptr<Manager> SampleHandlerBase::SampleManager
protected

The manager object used to read the sample yaml file.

Definition at line 431 of file SampleHandlerBase.h.

◆ Selection

std::vector< std::vector< KinematicCut > > SampleHandlerBase::Selection
protected

a way to store selection cuts which you may push back in the get1DVar functions most of the time this is just the same as StoredSelection

Definition at line 417 of file SampleHandlerBase.h.

◆ SplineHandler

std::unique_ptr<SplineBase> SampleHandlerBase::SplineHandler
protected

Contains all your splines (binned or unbinned) and handles the setup and the returning of weights from spline evaluations.

Definition at line 247 of file SampleHandlerBase.h.

◆ StoredSelection

std::vector< std::vector< KinematicCut > > SampleHandlerBase::StoredSelection
protected

What gets pulled from config options, these are constant after loading in this is of length 3: 0th index is the value, 1st is lower bound, 2nd is upper bound.

Definition at line 414 of file SampleHandlerBase.h.

◆ THStackLeg

TLegend* SampleHandlerBase::THStackLeg = nullptr
protected

DB: Legend associated with stacked histograms produced by this class.

Definition at line 437 of file SampleHandlerBase.h.

◆ UpdateW2

bool SampleHandlerBase::UpdateW2
protected

KS:Super hacky to update W2 or not.

Definition at line 442 of file SampleHandlerBase.h.


The documentation for this class was generated from the following files: