MaCh3  2.4.2
Reference Guide
Public Member Functions | Protected Member Functions | Protected Attributes | Private Types | Private Attributes | List of all members
SampleHandlerFD Class Referenceabstract

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

#include <Samples/SampleHandlerFD.h>

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

Public Member Functions

 SampleHandlerFD (std::string ConfigFileName, ParameterHandlerGeneric *xsec_cov, const std::shared_ptr< OscillationHandler > &OscillatorObj_=nullptr)
 Constructor. More...
 
virtual ~SampleHandlerFD ()
 destructor More...
 
int GetNDim (const int Sample) const override
 DB Function to differentiate 1D or 2D binning. More...
 
std::string GetName () const override
 
std::string GetSampleTitle (const int Sample) const override
 
std::string GetKinVarName (const int iSample, const int Dimension) const override
 Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino_Energy". More...
 
std::string GetXBinVarName (const int Sample) const
 
std::string GetYBinVarName (const int Sample) const
 
const BinningHandlerGetBinningHandler () const
 Get pointer to binning handler. More...
 
void PrintIntegral (const int iSample, const TString &OutputName="/dev/null", const int WeightStyle=0, const TString &OutputCSVName="/dev/null")
 
void AddData (const int Sample, TH1 *Data)
 
void AddData (const int Sample, const std::vector< double > &Data_Array)
 
void PrintRates (const bool DataOnly=false) override
 Helper function to print rates for the samples with LLH. More...
 
double GetLikelihood () const override
 DB Multi-threaded GetLikelihood. More...
 
double GetSampleLikelihood (const int isample) const override
 Get likelihood for single sample. More...
 
int GetSampleIndex (const std::string &SampleTitle) const
 Get index of sample based on name. More...
 
TH1 * GetDataHist (const int Sample) override
 Get Data histogram. More...
 
TH1 * GetDataHist (const std::string &Sample)
 
TH1 * GetMCHist (const int Sample) override
 Get MC histogram. More...
 
TH1 * GetMCHist (const std::string &Sample)
 
TH1 * GetW2Hist (const int Sample) override
 Get W2 histogram. More...
 
TH1 * GetW2Hist (const std::string &Sample)
 
void Reweight () override
 
M3::float_t GetEventWeight (const int iEntry)
 
void InitialiseNuOscillatorObjects ()
 including Dan's magic NuOscillator More...
 
void SetupNuOscillatorPointers ()
 
const M3::float_tGetNuOscillatorPointers (const int iEvent) const
 
void ReadConfig ()
 
void LoadSingleSample (const int iSample, const YAML::Node &Settings)
 
int GetNOscChannels (const int iSample) const override
 
std::string GetFlavourName (const int iSample, const int iChannel) const override
 
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...
 
TH1 * Get1DVarHist (const int iSample, const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, TAxis *Axis=nullptr, const std::vector< KinematicCut > &SubEventSelectionVec={}) override
 
TH2 * Get2DVarHist (const int iSample, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, TAxis *AxisX=nullptr, TAxis *AxisY=nullptr, const std::vector< KinematicCut > &SubEventSelectionVec={}) override
 
std::vector< KinematicCutBuildModeChannelSelection (const int iSample, const int kModeToFill, const int kChannelToFill) const
 
void Fill1DSubEventHist (const int iSample, TH1D *_h1DVar, const std::string &ProjectionVar, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)
 
void Fill2DSubEventHist (const int iSample, TH2D *_h2DVar, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)
 
TH1 * Get1DVarHistByModeAndChannel (const int iSample, const std::string &ProjectionVar_Str, int kModeToFill=-1, int kChannelToFill=-1, int WeightStyle=0, TAxis *Axis=nullptr) override
 
TH2 * Get2DVarHistByModeAndChannel (const int iSample, const std::string &ProjectionVar_StrX, const std::string &ProjectionVar_StrY, int kModeToFill=-1, int kChannelToFill=-1, int WeightStyle=0, TAxis *AxisX=nullptr, TAxis *AxisY=nullptr) override
 
TH1 * GetModeHist1D (const int iSample, int s, int m, int style=0)
 
TH2 * GetModeHist2D (const int iSample, int s, int m, int style=0)
 
std::vector< TH1 * > ReturnHistsBySelection1D (const int iSample, const std::string &KinematicProjection, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *Axis=nullptr)
 
std::vector< TH2 * > ReturnHistsBySelection2D (const int iSample, const std::string &KinematicProjectionX, const std::string &KinematicProjectionY, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *XAxis=nullptr, TAxis *YAxis=nullptr)
 
THStack * ReturnStackedHistBySelection1D (const int iSample, const std::string &KinematicProjection, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *Axis=nullptr)
 
TLegend * ReturnStackHistLegend ()
 
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) override
 Store additional info in a chan. More...
 
int ReturnKinematicVectorFromString (const std::string &KinematicStr) const
 
std::string ReturnStringFromKinematicVector (const int KinematicVariable) const
 
bool IsSubEventVarString (const std::string &VarStr)
 JM Check if a kinematic parameter string corresponds to a subevent-level variable. More...
 
std::vector< double > GetDataArray () const
 Return array storing data entries for every bin. More...
 
std::vector< double > GetMCArray () const
 Return array storing MC entries for every bin. More...
 
std::vector< double > GetW2Array () const
 Return array storing W2 entries for every bin. More...
 
std::vector< double > GetArrayForSample (const int Sample, const double *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...
 
- Public Member Functions inherited from SampleHandlerBase
 SampleHandlerBase ()
 The main constructor. More...
 
virtual ~SampleHandlerBase ()
 destructor More...
 
virtual M3::int_t GetNsamples ()
 
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
 
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

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 SetupFDMC ()=0
 Function which translates experiment struct into core struct. 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...
 
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, where Selection double looks like {{ND280KinematicTypes Var1, douuble LowBound}. 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...
 
void CalcNormsBins (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
 Calculate the total weight weight for a given event. More...
 
virtual void CalcWeightFunc (int iEvent)
 Calculate weights for function parameters. More...
 
virtual double ReturnKinematicParameter (std::string KinematicParamter, int iEvent)=0
 Return the value of an associated kinematic parameter for an event. More...
 
virtual double ReturnKinematicParameter (int KinematicVariable, int iEvent)=0
 
virtual std::vector< double > ReturnKinematicVector (std::string KinematicParameter, int iEvent)
 
virtual std::vector< double > ReturnKinematicVector (int KinematicVariable, int iEvent)
 
std::vector< double > ReturnKinematicParameterBinning (const int Sample, const std::string &KinematicParameter) const override
 Return the binning used to draw a kinematic parameter. More...
 
virtual const double * GetPointerToKinematicParameter (std::string KinematicParamter, int iEvent)=0
 
virtual const double * GetPointerToKinematicParameter (double KinematicVariable, int iEvent)=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 FillHist (const int Sample, TH1 *Hist, double *Array)
 Fill a histogram with the event-level information used in the fit. More...
 
void FillArray ()
 DB Nice new multi-threaded function which calculates the event weights and fills the relevant bins of an array. More...
 
void ResetHistograms ()
 Helper function to reset histograms. More...
 
void InitialiseSplineObject ()
 
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 SampleHandlerBase
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< FunctionalParameterfuncParsVec
 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...
 
double * SampleHandlerFD_array
 DB Array to be filled after reweighting. More...
 
double * SampleHandlerFD_array_w2
 KS Array used for MC stat. More...
 
double * SampleHandlerFD_data
 DB Array to be filled in AddData. More...
 
std::vector< EventInfoMCSamples
 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 Miscellaneous Variables. 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 SampleHandlerBase
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 Types

enum  FDPlotType { kModePlot = 0 , kOscChannelPlot = 1 }
 

Private Attributes

std::unordered_map< std::string, NuPDGFileToInitPDGMap
 
std::unordered_map< std::string, NuPDGFileToFinalPDGMap
 

Detailed Description

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

Author
Dan Barrow
Ed Atkin

Definition at line 21 of file SampleHandlerFD.h.

Member Enumeration Documentation

◆ FDPlotType

Enumerator
kModePlot 
kOscChannelPlot 

Definition at line 403 of file SampleHandlerFD.h.

403  {
404  kModePlot = 0,
405  kOscChannelPlot = 1
406  };

Constructor & Destructor Documentation

◆ SampleHandlerFD()

SampleHandlerFD::SampleHandlerFD ( 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 SampleHandlerFD.cpp.

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

◆ ~SampleHandlerFD()

SampleHandlerFD::~SampleHandlerFD ( )
virtual

destructor

Definition at line 48 of file SampleHandlerFD.cpp.

48  {
49  MACH3LOG_DEBUG("I'm deleting SampleHandlerFD");
50 
51  if (SampleHandlerFD_array != nullptr) delete[] SampleHandlerFD_array;
52  if (SampleHandlerFD_array_w2 != nullptr) delete[] SampleHandlerFD_array_w2;
53  //ETA - there is a chance that you haven't added any data...
54  if (SampleHandlerFD_data != nullptr) delete[] SampleHandlerFD_data;
55 
56  if(THStackLeg != nullptr) delete THStackLeg;
57 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
TLegend * THStackLeg
DB Miscellaneous Variables.

Member Function Documentation

◆ AddAdditionalWeightPointers()

virtual void SampleHandlerFD::AddAdditionalWeightPointers ( )
protectedpure virtual

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

Implemented in PySampleHandlerFD.

◆ AddData() [1/2]

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

Definition at line 998 of file SampleHandlerFD.cpp.

998  {
999 // ************************************************
1000  const int Start = Binning->GetSampleStartBin(Sample);
1001  const int End = Binning->GetSampleEndBin(Sample);
1002  const int ExpectedSize = End - Start;
1003 
1004  if (static_cast<int>(Data_Array.size()) != ExpectedSize) {
1005  MACH3LOG_ERROR("Data_Array size mismatch for sample '{}'.", GetSampleTitle(Sample));
1006  MACH3LOG_ERROR("Expected size: {}, received size: {}.", ExpectedSize, Data_Array.size());
1007  MACH3LOG_ERROR("Start bin: {}, End bin: {}.", Start, End);
1008  MACH3LOG_ERROR("This likely indicates a binning or sample slicing bug.");
1009  throw MaCh3Exception(__FILE__, __LINE__);
1010  }
1011 
1012  for (int idx = Start; idx < End; ++idx) {
1013  SampleHandlerFD_data[idx] = Data_Array[idx - Start];
1014  }
1015 
1016  FillHist(Sample, SampleDetails[Sample].DataHist, SampleHandlerFD_data);
1017 }
std::vector< SampleInfo > SampleDetails
Stores info about currently initialised sample.
void FillHist(const int Sample, TH1 *Hist, double *Array)
Fill a histogram with the event-level information used in the fit.
std::string GetSampleTitle(const int Sample) const override

◆ AddData() [2/2]

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

Definition at line 935 of file SampleHandlerFD.cpp.

935  {
936  int Dim = GetNDim(Sample);
937  MACH3LOG_INFO("Adding {}D data histogram: {} with {:.2f} events", Dim, Data->GetTitle(), Data->Integral());
938  // delete old histogram
939  delete SampleDetails[Sample].DataHist;
940  SampleDetails[Sample].DataHist = static_cast<TH1*>(Data->Clone());
941 
942  if(SampleHandlerFD_data == nullptr) {
943  MACH3LOG_ERROR("SampleHandlerFD_data haven't been initialised yet");
944  throw MaCh3Exception(__FILE__, __LINE__);
945  }
946 
947  auto ChecHistType = [&](const std::string& Type, const int Dimen, const TH1* Hist,
948  const std::string& file, const int line) {
949  if (std::string(Hist->ClassName()) != Type) {
950  MACH3LOG_ERROR("Expected {} for {}D sample, got {}", Type, Dimen, Hist->ClassName());
951  throw MaCh3Exception(file, line);
952  }
953  };
954 
955  if (Dim == 1) {
956  // Ensure we really have a TH1D
957  ChecHistType("TH1D", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
958  for (int xBin = 0; xBin < Binning->GetNAxisBins(Sample, 0); ++xBin) {
959  const int idx = Binning->GetGlobalBinSafe(Sample, {xBin});
960  // ROOT histograms are 1-based, so bin index + 1
961  SampleHandlerFD_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(xBin + 1);
962  }
963  SampleDetails[Sample].DataHist->GetXaxis()->SetTitle(GetXBinVarName(Sample).c_str());
964  SampleDetails[Sample].DataHist->GetYaxis()->SetTitle("Number of Events");
965  } else if (Dim == 2) {
966  if(Binning->IsUniform(Sample)) {
967  ChecHistType("TH2D", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
968  for (int yBin = 0; yBin < Binning->GetNAxisBins(Sample, 1); ++yBin) {
969  for (int xBin = 0; xBin < Binning->GetNAxisBins(Sample, 0); ++xBin) {
970  const int idx = Binning->GetGlobalBinSafe(Sample, {xBin, yBin});
971  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
972  SampleHandlerFD_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(xBin + 1, yBin + 1);
973  }
974  }
975  } else{
976  ChecHistType("TH2Poly", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
977  for (int iBin = 0; iBin < Binning->GetNBins(Sample); ++iBin) {
978  const int idx = iBin + Binning->GetSampleStartBin(Sample);
979  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
980  SampleHandlerFD_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(iBin + 1);
981  }
982  }
983 
984  SampleDetails[Sample].DataHist->GetXaxis()->SetTitle(GetXBinVarName(Sample).c_str());
985  SampleDetails[Sample].DataHist->GetYaxis()->SetTitle(GetYBinVarName(Sample).c_str());
986  SampleDetails[Sample].DataHist->GetZaxis()->SetTitle("Number of Events");
987  } else {
988  ChecHistType("TH1D", Dim, SampleDetails[Sample].DataHist, __FILE__, __LINE__);
989  for (int iBin = 0; iBin < Binning->GetNBins(Sample); ++iBin) {
990  const int idx = iBin + Binning->GetSampleStartBin(Sample);
991  //Need to do +1 for the bin, this is to be consistent with ROOTs binning scheme
992  SampleHandlerFD_data[idx] = SampleDetails[Sample].DataHist->GetBinContent(iBin + 1);
993  }
994  }
995 }
std::string GetYBinVarName(const int Sample) const
int GetNDim(const int Sample) const override
DB Function to differentiate 1D or 2D binning.
std::string GetXBinVarName(const int Sample) const

◆ ApplyShifts()

void SampleHandlerFD::ApplyShifts ( const int  iEvent)
protectedvirtual

ETA - generic function applying shifts.

Definition at line 562 of file SampleHandlerFD.cpp.

562  {
563 // ***************************************************************************
564  const auto& shifts = funcParsGrid[iEvent];
565  const auto nShifts = shifts.size();
566  // KS: If there are no shifts then there is no point in resetting which can be costly.
567  if(nShifts == 0) {
568  return;
569  }
570 
571  // Given a sample and event, apply the shifts to the event based on the vector of functional parameter enums
572  // First reset shifted array back to nominal values
573  ResetShifts(iEvent);
574 
575  for (std::size_t iShift = 0; iShift < nShifts; ++iShift) {
576  const auto* _restrict_ fp = shifts[iShift];
577  (*fp->funcPtr)(fp->valuePtr, iEvent);
578  }
579 }
#define _restrict_
KS: Using restrict limits the effects of pointer aliasing, aiding optimizations. While reading I foun...
Definition: Core.h:108
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 > > SampleHandlerFD::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.

Definition at line 1362 of file SampleHandlerFD.cpp.

1363  {
1364 // ************************************************
1365  // Backup current selection
1366  auto originalSelection = Selection;
1367 
1368  //DB Add all the predefined selections to the selection vector which will be applied
1369  auto selectionToApply = Selection;
1370 
1371  //DB Add all requested cuts from the argument to the selection vector which will be applied
1372  for (const auto& cut : ExtraCuts) {
1373  selectionToApply[iSample].emplace_back(cut);
1374  }
1375 
1376  //DB Set the member variable to be the cuts to apply
1377  Selection = std::move(selectionToApply);
1378 
1379  return originalSelection;
1380 }
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 > SampleHandlerFD::BuildModeChannelSelection ( const int  iSample,
const int  kModeToFill,
const int  kChannelToFill 
) const

Definition at line 1691 of file SampleHandlerFD.cpp.

1691  {
1692 // ************************************************
1693  bool fChannel;
1694  bool fMode;
1695 
1696  if (kChannelToFill != -1) {
1697  if (kChannelToFill > GetNOscChannels(iSample)) {
1698  MACH3LOG_ERROR("Required channel is not available. kChannelToFill should be between 0 and {}", GetNOscChannels(iSample));
1699  MACH3LOG_ERROR("kChannelToFill given:{}", kChannelToFill);
1700  MACH3LOG_ERROR("Exiting.");
1701  throw MaCh3Exception(__FILE__, __LINE__);
1702  }
1703  fChannel = true;
1704  } else {
1705  fChannel = false;
1706  }
1707 
1708  if (kModeToFill != -1) {
1709  if (!(kModeToFill >= 0) && (kModeToFill < Modes->GetNModes())) {
1710  MACH3LOG_ERROR("Required mode is not available. kModeToFill should be between 0 and {}", Modes->GetNModes());
1711  MACH3LOG_ERROR("kModeToFill given:{}", kModeToFill);
1712  MACH3LOG_ERROR("Exiting..");
1713  throw MaCh3Exception(__FILE__, __LINE__);
1714  }
1715  fMode = true;
1716  } else {
1717  fMode = false;
1718  }
1719 
1720  std::vector< KinematicCut > SelectionVec;
1721 
1722  if (fMode) {
1723  KinematicCut SelecMode;
1725  SelecMode.LowerBound = kModeToFill;
1726  SelecMode.UpperBound = kModeToFill+1;
1727  SelectionVec.push_back(SelecMode);
1728  }
1729 
1730  if (fChannel) {
1731  KinematicCut SelecChannel;
1732  SelecChannel.ParamToCutOnIt = ReturnKinematicParameterFromString("OscillationChannel");
1733  SelecChannel.LowerBound = kChannelToFill;
1734  SelecChannel.UpperBound = kChannelToFill+1;
1735  SelectionVec.push_back(SelecChannel);
1736  }
1737 
1738  return SelectionVec;
1739 }
std::unique_ptr< MaCh3Modes > Modes
Holds information about used Generator and MaCh3 modes.
int GetNOscChannels(const int iSample) const override
int ReturnKinematicParameterFromString(const std::string &KinematicStr) const
ETA function to generically convert a string from xsec cov to a kinematic type.
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 SampleHandlerFD::CalcNormsBins ( std::vector< NormParameter > &  norm_parameters,
std::vector< std::vector< int > > &  norms_bins 
)
protected

Check whether a normalisation systematic affects an event or not.

Definition at line 642 of file SampleHandlerFD.cpp.

642  {
643 // ************************************************
644  #ifdef DEBUG
645  std::vector<int> VerboseCounter(norm_parameters.size(), 0);
646  #endif
647  for(unsigned int iEvent = 0; iEvent < GetNEvents(); ++iEvent){
648  std::vector< int > NormBins = {};
649  if (ParHandler) {
650  // Skip oscillated NC events
651  // Not strictly needed, but these events don't get included in oscillated predictions, so
652  // no need to waste our time calculating and storing information about xsec parameters
653  // that will never be used.
654  if (MCSamples[iEvent].isNC && (*MCSamples[iEvent].nupdg != *MCSamples[iEvent].nupdgUnosc) ) {
655  MACH3LOG_TRACE("Event {}, missed NC/signal check", iEvent);
656  continue;
657  } //DB Abstract check on MaCh3Modes to determine which apply to neutral current
658  for (std::vector<NormParameter>::iterator it = norm_parameters.begin(); it != norm_parameters.end(); ++it) {
659  //Now check that the target of an interaction matches with the normalisation parameters
660  bool TargetMatch = MatchCondition((*it).targets, *(MCSamples[iEvent].Target));
661  if (!TargetMatch) {
662  MACH3LOG_TRACE("Event {}, missed target check ({}) for dial {}", iEvent, *(MCSamples[iEvent].Target), (*it).name);
663  continue;
664  }
665 
666  //Now check that the neutrino flavour in an interaction matches with the normalisation parameters
667  bool FlavourMatch = MatchCondition((*it).pdgs, *(MCSamples[iEvent].nupdg));
668  if (!FlavourMatch) {
669  MACH3LOG_TRACE("Event {}, missed PDG check ({}) for dial {}", iEvent,(*MCSamples[iEvent].nupdg), (*it).name);
670  continue;
671  }
672 
673  //Now check that the unoscillated neutrino flavour in an interaction matches with the normalisation parameters
674  bool FlavourUnoscMatch = MatchCondition((*it).preoscpdgs, *(MCSamples[iEvent].nupdgUnosc));
675  if (!FlavourUnoscMatch){
676  MACH3LOG_TRACE("Event {}, missed FlavourUnosc check ({}) for dial {}", iEvent,(*MCSamples[iEvent].nupdgUnosc), (*it).name);
677  continue;
678  }
679 
680  //Now check that the mode of an interaction matches with the normalisation parameters
681  bool ModeMatch = MatchCondition((*it).modes, static_cast<int>(std::round(*(MCSamples[iEvent].mode))));
682  if (!ModeMatch) {
683  MACH3LOG_TRACE("Event {}, missed Mode check ({}) for dial {}", iEvent, *(MCSamples[iEvent].mode), (*it).name);
684  continue;
685  }
686 
687  //Now check whether the norm has kinematic bounds
688  //i.e. does it only apply to events in a particular kinematic region?
689  // Now check whether within kinematic bounds
690  bool IsSelected = PassesSelection((*it), iEvent);
691  // Need to then break the event loop
692  if(!IsSelected){
693  MACH3LOG_TRACE("Event {}, missed Kinematic var check for dial {}", iEvent, (*it).name);
694  continue;
695  }
696  // Now set 'index bin' for each normalisation parameter
697  // All normalisations are just 1 bin for 2015, so bin = index (where index is just the bin for that normalisation)
698  int bin = (*it).index;
699 
700  NormBins.push_back(bin);
701  MACH3LOG_TRACE("Event {}, will be affected by dial {}", iEvent, (*it).name);
702  #ifdef DEBUG
703  VerboseCounter[std::distance(norm_parameters.begin(), it)]++;
704  #endif
705  //}
706  } // end iteration over norm_parameters
707  } // end if (ParHandler)
708  norms_bins[iEvent] = NormBins;
709  }//end loop over events
710  #ifdef DEBUG
711  MACH3LOG_DEBUG("┌──────────────────────────────────────────────────────────┐");
712  for (std::size_t i = 0; i < norm_parameters.size(); ++i) {
713  const auto& norm = norm_parameters[i];
714  double eventRatio = static_cast<double>(VerboseCounter[i]) / static_cast<double>(GetNEvents());
715 
716  MACH3LOG_DEBUG("│ Param {:<15}, affects {:<8} events ({:>6.2f}%) │",
717  ParHandler->GetParFancyName(norm.index), VerboseCounter[i], eventRatio);
718  }
719  MACH3LOG_DEBUG("└──────────────────────────────────────────────────────────┘");
720  #endif
721 }
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33
std::string GetParFancyName(const int i) const
Get fancy name of the Parameter.
unsigned int GetNEvents() const
bool MatchCondition(const std::vector< T > &allowedValues, const T &value)
check if event is affected by following conditions, for example pdg, or modes etc
bool PassesSelection(const ParT &Par, std::size_t iEvent)
std::vector< EventInfo > MCSamples
Stores information about every MC event.

◆ CalcWeightFunc()

virtual void SampleHandlerFD::CalcWeightFunc ( 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 284 of file SampleHandlerFD.h.

284 {return; (void)iEvent;};

◆ CalcWeightTotal()

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

Calculate the total weight weight for a given event.

Definition at line 583 of file SampleHandlerFD.cpp.

583  {
584 // ***************************************************************************
585  M3::float_t TotalWeight = 1.0;
586  const int nNorms = static_cast<int>(MCEvent->norm_pointers.size());
587  //Loop over stored normalisation and function pointers
588  #ifdef MULTITHREAD
589  #pragma omp simd reduction(*:TotalWeight)
590  #endif
591  for (int iParam = 0; iParam < nNorms; ++iParam)
592  {
593  #pragma GCC diagnostic push
594  #pragma GCC diagnostic ignored "-Wuseless-cast"
595  TotalWeight *= static_cast<M3::float_t>(*(MCEvent->norm_pointers[iParam]));
596  #pragma GCC diagnostic pop
597  }
598 
599  const int TotalWeights = static_cast<int>(MCEvent->total_weight_pointers.size());
600  //DB Loop over stored pointers
601  #ifdef MULTITHREAD
602  #pragma omp simd reduction(*:TotalWeight)
603  #endif
604  for (int iWeight = 0; iWeight < TotalWeights; ++iWeight) {
605  TotalWeight *= *(MCEvent->total_weight_pointers[iWeight]);
606  }
607 
608  return TotalWeight;
609 }
double float_t
Definition: Core.h:37
std::vector< const double * > norm_pointers
Pointers to normalisation weights which are being taken from Parameter Handler.
std::vector< const M3::float_t * > total_weight_pointers
Pointers to weights like oscillation spline etc.

◆ Fill1DSubEventHist()

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

Definition at line 1428 of file SampleHandlerFD.cpp.

1429  {
1430 // ************************************************
1431  int ProjectionVar_Int = ReturnKinematicVectorFromString(ProjectionVar_Str);
1432 
1433  //JM Loop over all events
1434  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1435  const int EventSample = MCSamples[iEvent].NominalSample;
1436  if(EventSample != iSample) continue;
1437  if (IsEventSelected(EventSample, iEvent)) {
1438  double Weight = GetEventWeight(iEvent);
1439  if (WeightStyle == 1) {
1440  Weight = 1.;
1441  }
1442  std::vector<double> Vec = ReturnKinematicVector(ProjectionVar_Int,iEvent);
1443  size_t nsubevents = Vec.size();
1444  //JM Loop over all subevents in event
1445  for (unsigned int iSubEvent = 0; iSubEvent < nsubevents; iSubEvent++) {
1446  if (IsSubEventSelected(SubEventSelectionVec, iEvent, iSubEvent, nsubevents)) {
1447  double Var = Vec[iSubEvent];
1448  _h1DVar->Fill(Var,Weight);
1449  }
1450  }
1451  }
1452  }
1453 }
M3::float_t GetEventWeight(const int iEntry)
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
virtual std::vector< double > ReturnKinematicVector(std::string KinematicParameter, int iEvent)
bool IsEventSelected(const int iSample, const int iEvent) _noexcept_
DB Function which determines if an event is selected, where Selection double looks like {{ND280Kinema...

◆ Fill2DSubEventHist()

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

Definition at line 1508 of file SampleHandlerFD.cpp.

1512  {
1513 // ************************************************
1514 
1515  bool IsSubEventVarX = IsSubEventVarString(ProjectionVar_StrX);
1516  bool IsSubEventVarY = IsSubEventVarString(ProjectionVar_StrY);
1517 
1518  int ProjectionVar_IntX, ProjectionVar_IntY;
1519  if (IsSubEventVarX) ProjectionVar_IntX = ReturnKinematicVectorFromString(ProjectionVar_StrX);
1520  else ProjectionVar_IntX = ReturnKinematicParameterFromString(ProjectionVar_StrX);
1521  if (IsSubEventVarY) ProjectionVar_IntY = ReturnKinematicVectorFromString(ProjectionVar_StrY);
1522  else ProjectionVar_IntY = ReturnKinematicParameterFromString(ProjectionVar_StrY);
1523 
1524  //JM Loop over all events
1525  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1526  const int EventSample = MCSamples[iEvent].NominalSample;
1527  if(EventSample != iSample) continue;
1528  if (IsEventSelected(EventSample, iEvent)) {
1529  double Weight = GetEventWeight(iEvent);
1530  if (WeightStyle == 1) {
1531  Weight = 1.;
1532  }
1533  std::vector<double> VecX = {}, VecY = {};
1534  double VarX = M3::_BAD_DOUBLE_, VarY = M3::_BAD_DOUBLE_;
1535  size_t nsubevents = 0;
1536  // JM Three cases: subeventX vs eventY || eventX vs subeventY || subeventX vs subeventY
1537  if (IsSubEventVarX && !IsSubEventVarY) {
1538  VecX = ReturnKinematicVector(ProjectionVar_IntX, iEvent);
1539  VarY = ReturnKinematicParameter(ProjectionVar_IntY, iEvent);
1540  nsubevents = VecX.size();
1541  }
1542  else if (!IsSubEventVarX && IsSubEventVarY) {
1543  VecY = ReturnKinematicVector(ProjectionVar_IntY, iEvent);
1544  VarX = ReturnKinematicParameter(ProjectionVar_IntX, iEvent);
1545  nsubevents = VecY.size();
1546  }
1547  else {
1548  VecX = ReturnKinematicVector(ProjectionVar_IntX, iEvent);
1549  VecY = ReturnKinematicVector(ProjectionVar_IntY, iEvent);
1550  if (VecX.size() != VecY.size()) {
1551  MACH3LOG_ERROR("Cannot plot {} of size {} against {} of size {}", ProjectionVar_StrX, VecX.size(), ProjectionVar_StrY, VecY.size());
1552  throw MaCh3Exception(__FILE__, __LINE__);
1553  }
1554  nsubevents = VecX.size();
1555  }
1556  //JM Loop over all subevents in event
1557  for (unsigned int iSubEvent = 0; iSubEvent < nsubevents; iSubEvent++) {
1558  if (IsSubEventSelected(SubEventSelectionVec, iEvent, iSubEvent, nsubevents)) {
1559  if (IsSubEventVarX) VarX = VecX[iSubEvent];
1560  if (IsSubEventVarY) VarY = VecY[iSubEvent];
1561  _h2DVar->Fill(VarX,VarY,Weight);
1562  }
1563  }
1564  }
1565  }
1566 }
virtual double ReturnKinematicParameter(std::string KinematicParamter, int iEvent)=0
Return the value of an associated kinematic parameter for an event.
bool IsSubEventVarString(const std::string &VarStr)
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 SampleHandlerFD::FillArray ( )
protected

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

Function which does the core reweighting, fills the SampleHandlerFD::SampleHandlerFD_array vector with the weight calculated from reweighting

Definition at line 374 of file SampleHandlerFD.cpp.

374  {
375 //************************************************
376  //DB Reset which cuts to apply
378 
379  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
380  ApplyShifts(iEvent);
381  const EventInfo* _restrict_ MCEvent = &MCSamples[iEvent];
382 
383  if (!IsEventSelected(MCEvent->NominalSample, iEvent)) {
384  continue;
385  }
386 
387  // Virtual by default does nothing, has to happen before CalcWeightTotal
388  CalcWeightFunc(iEvent);
389 
390  const M3::float_t totalweight = CalcWeightTotal(MCEvent);
391  //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
392  if (totalweight <= 0.){
393  continue;
394  }
395 
396  //DB Find the relevant bin in the PDF for each event
397  const int GlobalBin = Binning->FindGlobalBin(MCEvent->NominalSample, MCEvent->KinVar, MCEvent->NomBin);
398 
399  //DB Fill relevant part of thread array
400  if (GlobalBin > M3::UnderOverFlowBin) {
401  SampleHandlerFD_array[GlobalBin] += totalweight;
402  if (FirstTimeW2) SampleHandlerFD_array_w2[GlobalBin] += totalweight*totalweight;
403  }
404  }
405 }
virtual void CalcWeightFunc(int iEvent)
Calculate weights for function parameters.
M3::float_t CalcWeightTotal(const EventInfo *_restrict_ MCEvent) const
Calculate the total weight weight for a given event.
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.
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.

◆ FillHist()

void SampleHandlerFD::FillHist ( const int  Sample,
TH1 *  Hist,
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 SampleHandlerFD_array

Definition at line 264 of file SampleHandlerFD.cpp.

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

◆ FindNominalBinAndEdges()

void SampleHandlerFD::FindNominalBinAndEdges ( )
protected

Definition at line 839 of file SampleHandlerFD.cpp.

839  {
840 // ************************************************
841  for (unsigned int event_i = 0; event_i < GetNEvents(); event_i++) {
842  int Sample = MCSamples[event_i].NominalSample;
843  const int dim = GetNDim(Sample);
844  MCSamples[event_i].KinVar.resize(dim);
845  MCSamples[event_i].NomBin.resize(dim);
846 
847  auto SetNominalBin = [&](int bin, int max_bins, int& out_bin) {
848  if (bin >= 0 && bin < max_bins) {
849  out_bin = bin;
850  } else {
851  out_bin = M3::UnderOverFlowBin; // Out of bounds
852  }
853  };
854 
855  // Find nominal bin for each dimension
856  for(int iDim = 0; iDim < dim; iDim++) {
857  MCSamples[event_i].KinVar[iDim] = GetPointerToKinematicParameter(GetKinVarName(Sample, iDim), event_i);
858  if (std::isnan(*MCSamples[event_i].KinVar[iDim]) || std::isinf(*MCSamples[event_i].KinVar[iDim])) {
859  MACH3LOG_ERROR("Variable {} for sample {} and dimension {} is ill-defined and equal to {}",
860  GetKinVarName(Sample, iDim), GetSampleTitle(Sample), dim, *MCSamples[event_i].KinVar[iDim]);
861  throw MaCh3Exception(__FILE__, __LINE__);
862  }
863  const int bin = Binning->FindNominalBin(Sample, iDim, *MCSamples[event_i].KinVar[iDim]);
864  int NBins_i = static_cast<int>(Binning->GetBinEdges(Sample, iDim).size() - 1);
865  SetNominalBin(bin, NBins_i, MCSamples[event_i].NomBin[iDim]);
866  }
867  }
868 }
std::string GetKinVarName(const int iSample, const int Dimension) const override
Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino...
virtual const double * GetPointerToKinematicParameter(std::string KinematicParamter, int iEvent)=0

◆ Get1DVarHist()

TH1 * SampleHandlerFD::Get1DVarHist ( const int  iSample,
const std::string &  ProjectionVar,
const std::vector< KinematicCut > &  EventSelectionVec = {},
int  WeightStyle = 0,
TAxis *  Axis = nullptr,
const std::vector< KinematicCut > &  SubEventSelectionVec = {} 
)
overridevirtual

Implements SampleHandlerBase.

Definition at line 1384 of file SampleHandlerFD.cpp.

1385  {
1386 // ************************************************
1387  //DB Need to overwrite the Selection member variable so that IsEventSelected function operates correctly.
1388  // Consequently, store the selection cuts already saved in the sample, overwrite the Selection variable, then reset
1389  auto tmp_Selection = ApplyTemporarySelection(iSample, EventSelectionVec);
1390 
1391  //DB Define the histogram which will be returned
1392  TH1D* _h1DVar = nullptr;;
1393  if (Axis) {
1394  _h1DVar = new TH1D("","",Axis->GetNbins(),Axis->GetXbins()->GetArray());
1395  } else {
1396  std::vector<double> xBinEdges = ReturnKinematicParameterBinning(iSample, ProjectionVar_Str);
1397  _h1DVar = new TH1D("", "", int(xBinEdges.size())-1, xBinEdges.data());
1398  }
1399  _h1DVar->GetXaxis()->SetTitle(ProjectionVar_Str.c_str());
1400 
1401  if (IsSubEventVarString(ProjectionVar_Str)) {
1402  Fill1DSubEventHist(iSample, _h1DVar, ProjectionVar_Str, SubEventSelectionVec, WeightStyle);
1403  } else {
1404  //DB Grab the associated enum with the argument string
1405  int ProjectionVar_Int = ReturnKinematicParameterFromString(ProjectionVar_Str);
1406 
1407  //DB Loop over all events
1408  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1409  const int EventSample = MCSamples[iEvent].NominalSample;
1410  if(EventSample != iSample) continue;
1411  if (IsEventSelected(EventSample, iEvent)) {
1412  double Weight = GetEventWeight(iEvent);
1413  if (WeightStyle == 1) {
1414  Weight = 1.;
1415  }
1416  double Var = ReturnKinematicParameter(ProjectionVar_Int, iEvent);
1417  _h1DVar->Fill(Var, Weight);
1418  }
1419  }
1420  }
1421  //DB Reset the saved selection
1422  Selection = tmp_Selection;
1423 
1424  return _h1DVar;
1425 }
std::vector< double > ReturnKinematicParameterBinning(const int Sample, const std::string &KinematicParameter) const override
Return the binning used to draw a kinematic parameter.
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 ...
void Fill1DSubEventHist(const int iSample, TH1D *_h1DVar, const std::string &ProjectionVar, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)

◆ Get1DVarHistByModeAndChannel()

TH1 * SampleHandlerFD::Get1DVarHistByModeAndChannel ( const int  iSample,
const std::string &  ProjectionVar_Str,
int  kModeToFill = -1,
int  kChannelToFill = -1,
int  WeightStyle = 0,
TAxis *  Axis = nullptr 
)
overridevirtual

Implements SampleHandlerBase.

Definition at line 1742 of file SampleHandlerFD.cpp.

1743  {
1744 // ************************************************
1745  auto SelectionVec = BuildModeChannelSelection(iSample, kModeToFill, kChannelToFill);
1746  return Get1DVarHist(iSample, ProjectionVar_Str, SelectionVec, WeightStyle, Axis);
1747 }
std::vector< KinematicCut > BuildModeChannelSelection(const int iSample, const int kModeToFill, const int kChannelToFill) const
TH1 * Get1DVarHist(const int iSample, const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, TAxis *Axis=nullptr, const std::vector< KinematicCut > &SubEventSelectionVec={}) override

◆ Get2DVarHist()

TH2 * SampleHandlerFD::Get2DVarHist ( const int  iSample,
const std::string &  ProjectionVarX,
const std::string &  ProjectionVarY,
const std::vector< KinematicCut > &  EventSelectionVec = {},
int  WeightStyle = 0,
TAxis *  AxisX = nullptr,
TAxis *  AxisY = nullptr,
const std::vector< KinematicCut > &  SubEventSelectionVec = {} 
)
overridevirtual

Implements SampleHandlerBase.

Definition at line 1456 of file SampleHandlerFD.cpp.

1461  {
1462 // ************************************************
1463  //DB Need to overwrite the Selection member variable so that IsEventSelected function operates correctly.
1464  // Consequently, store the selection cuts already saved in the sample, overwrite the Selection variable, then reset
1465  auto tmp_Selection = ApplyTemporarySelection(iSample, EventSelectionVec);
1466 
1467  //DB Define the histogram which will be returned
1468  TH2D* _h2DVar = nullptr;
1469  if (AxisX && AxisY) {
1470  _h2DVar = new TH2D("","",AxisX->GetNbins(),AxisX->GetXbins()->GetArray(),AxisY->GetNbins(),AxisY->GetXbins()->GetArray());
1471  } else {
1472  std::vector<double> xBinEdges = ReturnKinematicParameterBinning(iSample, ProjectionVar_StrX);
1473  std::vector<double> yBinEdges = ReturnKinematicParameterBinning(iSample, ProjectionVar_StrY);
1474  _h2DVar = new TH2D("", "", int(xBinEdges.size())-1, xBinEdges.data(), int(yBinEdges.size())-1, yBinEdges.data());
1475  }
1476  _h2DVar->GetXaxis()->SetTitle(ProjectionVar_StrX.c_str());
1477  _h2DVar->GetYaxis()->SetTitle(ProjectionVar_StrY.c_str());
1478 
1479  bool IsSubEventHist = IsSubEventVarString(ProjectionVar_StrX) || IsSubEventVarString(ProjectionVar_StrY);
1480  if (IsSubEventHist) Fill2DSubEventHist(iSample, _h2DVar, ProjectionVar_StrX, ProjectionVar_StrY, SubEventSelectionVec, WeightStyle);
1481  else {
1482  //DB Grab the associated enum with the argument string
1483  int ProjectionVar_IntX = ReturnKinematicParameterFromString(ProjectionVar_StrX);
1484  int ProjectionVar_IntY = ReturnKinematicParameterFromString(ProjectionVar_StrY);
1485 
1486  //DB Loop over all events
1487  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1488  const int EventSample = MCSamples[iEvent].NominalSample;
1489  if(EventSample != iSample) continue;
1490  if (IsEventSelected(EventSample, iEvent)) {
1491  double Weight = GetEventWeight(iEvent);
1492  if (WeightStyle == 1) {
1493  Weight = 1.;
1494  }
1495  double VarX = ReturnKinematicParameter(ProjectionVar_IntX, iEvent);
1496  double VarY = ReturnKinematicParameter(ProjectionVar_IntY, iEvent);
1497  _h2DVar->Fill(VarX,VarY,Weight);
1498  }
1499  }
1500  }
1501  //DB Reset the saved selection
1502  Selection = tmp_Selection;
1503 
1504  return _h2DVar;
1505 }
void Fill2DSubEventHist(const int iSample, TH2D *_h2DVar, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &SubEventSelectionVec={}, int WeightStyle=0)

◆ Get2DVarHistByModeAndChannel()

TH2 * SampleHandlerFD::Get2DVarHistByModeAndChannel ( const int  iSample,
const std::string &  ProjectionVar_StrX,
const std::string &  ProjectionVar_StrY,
int  kModeToFill = -1,
int  kChannelToFill = -1,
int  WeightStyle = 0,
TAxis *  AxisX = nullptr,
TAxis *  AxisY = nullptr 
)
overridevirtual

Implements SampleHandlerBase.

Definition at line 1750 of file SampleHandlerFD.cpp.

1751  {
1752 // ************************************************
1753  auto SelectionVec = BuildModeChannelSelection(iSample, kModeToFill, kChannelToFill);
1754  return Get2DVarHist(iSample, ProjectionVar_StrX, ProjectionVar_StrY, SelectionVec, WeightStyle, AxisX,AxisY);
1755 }
TH2 * Get2DVarHist(const int iSample, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, TAxis *AxisX=nullptr, TAxis *AxisY=nullptr, const std::vector< KinematicCut > &SubEventSelectionVec={}) override

◆ GetArrayForSample()

std::vector< double > SampleHandlerFD::GetArrayForSample ( const int  Sample,
const double *  array 
) const

Return a sub-array for a given sample.

Definition at line 2055 of file SampleHandlerFD.cpp.

2055  {
2056 // ***************************************************************************
2057  const int Start = Binning->GetSampleStartBin(Sample);
2058  const int End = Binning->GetSampleEndBin(Sample);
2059 
2060  return std::vector<double>(array + Start, array + End);
2061 }

◆ GetBinningHandler()

const BinningHandler* SampleHandlerFD::GetBinningHandler ( ) const
inline

Get pointer to binning handler.

Definition at line 45 of file SampleHandlerFD.h.

45 {return Binning.get();}

◆ GetDataArray() [1/2]

std::vector<double> SampleHandlerFD::GetDataArray ( ) const
inline

Return array storing data entries for every bin.

Definition at line 162 of file SampleHandlerFD.h.

162  {
163  return std::vector<double>(SampleHandlerFD_data, SampleHandlerFD_data + Binning->GetNBins());
164  }

◆ GetDataArray() [2/2]

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

Return array storing data entries for every bin.

Definition at line 177 of file SampleHandlerFD.h.

177  {
178  return GetArrayForSample(Sample, SampleHandlerFD_data);
179  }
std::vector< double > GetArrayForSample(const int Sample, const double *array) const
Return a sub-array for a given sample.

◆ GetDataHist() [1/2]

TH1 * SampleHandlerFD::GetDataHist ( const int  Sample)
overridevirtual

Get Data histogram.

Implements SampleHandlerBase.

Definition at line 919 of file SampleHandlerFD.cpp.

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

◆ GetDataHist() [2/2]

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

Definition at line 929 of file SampleHandlerFD.cpp.

929  {
930 // ************************************************
931  int Index = GetSampleIndex(Sample);
932  return GetDataHist(Index);
933 }
TH1 * GetDataHist(const int Sample) override
Get Data histogram.
int GetSampleIndex(const std::string &SampleTitle) const
Get index of sample based on name.

◆ GetEventWeight()

M3::float_t SampleHandlerFD::GetEventWeight ( const int  iEntry)

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 1151 of file SampleHandlerFD.cpp.

1151  {
1152 // ************************************************
1154 
1155  // Virtual by default does nothing, has to happen before CalcWeightTotal
1156  CalcWeightFunc(iEntry);
1157 
1158  const EventInfo* _restrict_ MCEvent = &MCSamples[iEntry];
1159  M3::float_t totalweight = CalcWeightTotal(MCEvent);
1160 
1161  //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
1162  if (totalweight <= 0.){
1163  totalweight = 0.;
1164  }
1165  return totalweight;
1166 }

◆ GetFinalPDGFromFileName()

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

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

Definition at line 397 of file SampleHandlerFD.h.

397 {return FileToFinalPDGMap.at(FileName);}
std::unordered_map< std::string, NuPDG > FileToFinalPDGMap

◆ GetFlavourName()

std::string SampleHandlerFD::GetFlavourName ( const int  iSample,
const int  iChannel 
) const
inlineoverridevirtual

Implements SampleHandlerBase.

Definition at line 95 of file SampleHandlerFD.h.

95  {
96  if (iChannel < 0 || iChannel > GetNOscChannels(iSample)) {
97  MACH3LOG_ERROR("Invalid Channel Requested: {}", iChannel);
98  throw MaCh3Exception(__FILE__ , __LINE__);
99  }
100  return SampleDetails[iSample].OscChannels[iChannel].flavourName;
101  }

◆ GetInitPDGFromFileName()

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

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

Definition at line 395 of file SampleHandlerFD.h.

395 {return FileToInitPDGMap.at(FileName);}
std::unordered_map< std::string, NuPDG > FileToInitPDGMap

◆ GetKinVarName()

std::string SampleHandlerFD::GetKinVarName ( const int  iSample,
const int  Dimension 
) const
overridevirtual

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

Parameters
iSampleSample index
DimensionDimension index

Implements SampleHandlerBase.

Definition at line 2045 of file SampleHandlerFD.cpp.

2045  {
2046 // ***************************************************************************
2047  if(Dimension > GetNDim(iSample)) {
2048  MACH3LOG_ERROR("Asking for dimension {}, while sample: {} only has {}", Dimension, GetSampleTitle(iSample), GetNDim(iSample));
2049  throw MaCh3Exception(__FILE__, __LINE__);
2050  }
2051  return SampleDetails[iSample].VarStr[Dimension];
2052 }

◆ GetLikelihood()

double SampleHandlerFD::GetLikelihood ( ) const
overridevirtual

DB Multi-threaded GetLikelihood.

Implements SampleHandlerBase.

Definition at line 1250 of file SampleHandlerFD.cpp.

1250  {
1251 // ************************************************
1252  double negLogL = 0.;
1253  #ifdef MULTITHREAD
1254  #pragma omp parallel for reduction(+:negLogL)
1255  #endif
1256  for (int idx = 0; idx < Binning->GetNBins(); ++idx)
1257  {
1258  const double DataVal = SampleHandlerFD_data[idx];
1259  const double MCPred = SampleHandlerFD_array[idx];
1260  const double w2 = SampleHandlerFD_array_w2[idx];
1261 
1262  //KS: Calculate likelihood using Barlow-Beeston Poisson or even IceCube
1263  negLogL += GetTestStatLLH(DataVal, MCPred, w2);
1264  }
1265  return negLogL;
1266 }
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]

std::vector<double> SampleHandlerFD::GetMCArray ( ) const
inline

Return array storing MC entries for every bin.

Definition at line 166 of file SampleHandlerFD.h.

166  {
167  return std::vector<double>(SampleHandlerFD_array, SampleHandlerFD_array + Binning->GetNBins());
168  }

◆ GetMCArray() [2/2]

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

Return array storing MC entries for every bin.

Definition at line 181 of file SampleHandlerFD.h.

181  {
183  }

◆ GetMCHist() [1/2]

TH1 * SampleHandlerFD::GetMCHist ( const int  Sample)
overridevirtual

Get MC histogram.

Implements SampleHandlerBase.

Definition at line 901 of file SampleHandlerFD.cpp.

901  {
902 // ************************************************
903  FillHist(Sample, SampleDetails[Sample].MCHist, SampleHandlerFD_array);
904  if(SampleDetails[Sample].MCHist == nullptr) {
905  MACH3LOG_ERROR("Can't access {} for {}Dimensions", __func__, GetNDim(Sample));
906  throw MaCh3Exception(__FILE__, __LINE__);
907  }
908  return SampleDetails[Sample].MCHist;
909 }

◆ GetMCHist() [2/2]

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

Definition at line 912 of file SampleHandlerFD.cpp.

912  {
913 // ************************************************
914  const int Index = GetSampleIndex(Sample);
915  return GetMCHist(Index);
916 }
TH1 * GetMCHist(const int Sample) override
Get MC histogram.

◆ GetModeHist1D()

TH1* SampleHandlerFD::GetModeHist1D ( const int  iSample,
int  s,
int  m,
int  style = 0 
)
inline

Definition at line 128 of file SampleHandlerFD.h.

128  {
129  return Get1DVarHistByModeAndChannel(iSample, GetXBinVarName(iSample), m, s, style);
130  }
TH1 * Get1DVarHistByModeAndChannel(const int iSample, const std::string &ProjectionVar_Str, int kModeToFill=-1, int kChannelToFill=-1, int WeightStyle=0, TAxis *Axis=nullptr) override

◆ GetModeHist2D()

TH2* SampleHandlerFD::GetModeHist2D ( const int  iSample,
int  s,
int  m,
int  style = 0 
)
inline

Definition at line 131 of file SampleHandlerFD.h.

131  {
132  return Get2DVarHistByModeAndChannel(iSample, GetXBinVarName(iSample),GetYBinVarName(iSample), m, s, style);
133  }
TH2 * Get2DVarHistByModeAndChannel(const int iSample, const std::string &ProjectionVar_StrX, const std::string &ProjectionVar_StrY, int kModeToFill=-1, int kChannelToFill=-1, int WeightStyle=0, TAxis *AxisX=nullptr, TAxis *AxisY=nullptr) override

◆ GetName()

std::string SampleHandlerFD::GetName ( ) const
overridevirtual

Implements SampleHandlerBase.

Definition at line 1138 of file SampleHandlerFD.cpp.

1138  {
1139 // ************************************************
1140  //ETA - extra safety to make sure SampleHandlerName is actually set
1141  // probably unnecessary due to the requirement for it to be in the yaml config
1142  if(SampleHandlerName.length() == 0) {
1143  MACH3LOG_ERROR("No sample name provided");
1144  MACH3LOG_ERROR("Please provide a SampleHandlerName in your configuration file: {}", SampleManager->GetFileName());
1145  throw MaCh3Exception(__FILE__, __LINE__);
1146  }
1147  return SampleHandlerName;
1148 }

◆ GetNDim()

int SampleHandlerFD::GetNDim ( const int  Sample) const
inlineoverridevirtual

DB Function to differentiate 1D or 2D binning.

Implements SampleHandlerBase.

Definition at line 33 of file SampleHandlerFD.h.

33 { return SampleDetails[Sample].nDimensions; }

◆ GetNOscChannels()

int SampleHandlerFD::GetNOscChannels ( const int  iSample) const
inlineoverridevirtual

Implements SampleHandlerBase.

Definition at line 93 of file SampleHandlerFD.h.

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

◆ GetNuOscillatorPointers()

const M3::float_t * SampleHandlerFD::GetNuOscillatorPointers ( const int  iEvent) const

Definition at line 1098 of file SampleHandlerFD.cpp.

1098  {
1099 // ************************************************
1100  const M3::float_t* osc_w_pointer = &M3::Unity;
1101  if (MCSamples[iEvent].isNC) {
1102  if (*MCSamples[iEvent].nupdg != *MCSamples[iEvent].nupdgUnosc) {
1103  osc_w_pointer = &M3::Zero;
1104  } else {
1105  osc_w_pointer = &M3::Unity;
1106  }
1107  } else {
1108  int InitFlav = M3::_BAD_INT_;
1109  int FinalFlav = M3::_BAD_INT_;
1110 
1111  InitFlav = MaCh3Utils::PDGToNuOscillatorFlavour((*MCSamples[iEvent].nupdgUnosc));
1112  FinalFlav = MaCh3Utils::PDGToNuOscillatorFlavour((*MCSamples[iEvent].nupdg));
1113 
1114  if (InitFlav == M3::_BAD_INT_ || FinalFlav == M3::_BAD_INT_) {
1115  MACH3LOG_ERROR("Something has gone wrong in the mapping between MCSamples.nutype and the enum used within NuOscillator");
1116  MACH3LOG_ERROR("MCSamples.nupdgUnosc: {}", (*MCSamples[iEvent].nupdgUnosc));
1117  MACH3LOG_ERROR("InitFlav: {}", InitFlav);
1118  MACH3LOG_ERROR("MCSamples.nupdg: {}", (*MCSamples[iEvent].nupdg));
1119  MACH3LOG_ERROR("FinalFlav: {}", FinalFlav);
1120  throw MaCh3Exception(__FILE__, __LINE__);
1121  }
1122  const int Sample = MCSamples[iEvent].NominalSample;
1123 
1124  const int OscIndex = GetOscChannel(SampleDetails[Sample].OscChannels, (*MCSamples[iEvent].nupdgUnosc), (*MCSamples[iEvent].nupdg));
1125  //Can only happen if truecz has been initialised within the experiment specific code
1126  if (*(MCSamples[iEvent].rw_truecz) != M3::_BAD_DOUBLE_) {
1127  //Atmospherics
1128  osc_w_pointer = Oscillator->GetNuOscillatorPointers(Sample, OscIndex, InitFlav, FinalFlav, FLOAT_T(*(MCSamples[iEvent].rw_etru)), FLOAT_T(*(MCSamples[iEvent].rw_truecz)));
1129  } else {
1130  //Beam
1131  osc_w_pointer = Oscillator->GetNuOscillatorPointers(Sample, OscIndex, InitFlav, FinalFlav, FLOAT_T(*(MCSamples[iEvent].rw_etru)));
1132  }
1133  } // end if NC
1134  return osc_w_pointer;
1135 }
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.
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
int PDGToNuOscillatorFlavour(const int NuPdg)
Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscilla...

◆ GetPointerToKinematicParameter() [1/2]

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

Implemented in PySampleHandlerFD.

◆ GetPointerToKinematicParameter() [2/2]

virtual const double* SampleHandlerFD::GetPointerToKinematicParameter ( std::string  KinematicParamter,
int  iEvent 
)
protectedpure virtual

Implemented in PySampleHandlerFD.

◆ GetPointerToOscChannel()

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

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

Definition at line 1983 of file SampleHandlerFD.cpp.

1983  {
1984 // ************************************************
1985  auto& OscillationChannels = SampleDetails[MCSamples[iEvent].NominalSample].OscChannels;
1986  const int Channel = GetOscChannel(OscillationChannels, (*MCSamples[iEvent].nupdgUnosc), (*MCSamples[iEvent].nupdg));
1987 
1988  return &(OscillationChannels[Channel].ChannelIndex);
1989 }

◆ GetSampleIndex()

int SampleHandlerFD::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 871 of file SampleHandlerFD.cpp.

871  {
872 // ************************************************
873  for (M3::int_t iSample = 0; iSample < nSamples; ++iSample) {
874  if (SampleTitle == GetSampleTitle(iSample)) {
875  return iSample;
876  }
877  }
878  MACH3LOG_ERROR("Sample name not found: {}", SampleTitle);
879  throw MaCh3Exception(__FILE__, __LINE__);
880 }
int int_t
Definition: Core.h:38

◆ GetSampleLikelihood()

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

Get likelihood for single sample.

Implements SampleHandlerBase.

Definition at line 1228 of file SampleHandlerFD.cpp.

1228  {
1229 // ************************************************
1230  const int Start = Binning->GetSampleStartBin(isample);
1231  const int End = Binning->GetSampleEndBin(isample);
1232 
1233  double negLogL = 0.;
1234  #ifdef MULTITHREAD
1235  #pragma omp parallel for reduction(+:negLogL)
1236  #endif
1237  for (int idx = Start; idx < End; ++idx)
1238  {
1239  const double DataVal = SampleHandlerFD_data[idx];
1240  const double MCPred = SampleHandlerFD_array[idx];
1241  const double w2 = SampleHandlerFD_array_w2[idx];
1242 
1243  //KS: Calculate likelihood using Barlow-Beeston Poisson or even IceCube
1244  negLogL += GetTestStatLLH(DataVal, MCPred, w2);
1245  }
1246  return negLogL;
1247 }

◆ GetSampleTitle()

std::string SampleHandlerFD::GetSampleTitle ( const int  Sample) const
inlineoverridevirtual

Implements SampleHandlerBase.

Definition at line 35 of file SampleHandlerFD.h.

35 {return SampleDetails[Sample].SampleTitle;}

◆ GetW2Array() [1/2]

std::vector<double> SampleHandlerFD::GetW2Array ( ) const
inline

Return array storing W2 entries for every bin.

Definition at line 170 of file SampleHandlerFD.h.

170  {
171  return std::vector<double>(SampleHandlerFD_array_w2, SampleHandlerFD_array_w2 + Binning->GetNBins());
172  }

◆ GetW2Array() [2/2]

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

Return array storing W2 entries for single sample.

Definition at line 185 of file SampleHandlerFD.h.

185  {
187  }

◆ GetW2Hist() [1/2]

TH1 * SampleHandlerFD::GetW2Hist ( const int  Sample)
overridevirtual

Get W2 histogram.

Implements SampleHandlerBase.

Definition at line 883 of file SampleHandlerFD.cpp.

883  {
884 // ************************************************
885  FillHist(Sample, SampleDetails[Sample].W2Hist, SampleHandlerFD_array_w2);
886  if(SampleDetails[Sample].W2Hist == nullptr) {
887  MACH3LOG_ERROR("Can't access {} for {}Dimensions", __func__, GetNDim(Sample));
888  throw MaCh3Exception(__FILE__, __LINE__);
889  }
890  return SampleDetails[Sample].W2Hist;
891 }

◆ GetW2Hist() [2/2]

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

Definition at line 894 of file SampleHandlerFD.cpp.

894  {
895 // ************************************************
896  const int Index = GetSampleIndex(Sample);
897  return GetW2Hist(Index);
898 }
TH1 * GetW2Hist(const int Sample) override
Get W2 histogram.

◆ GetXBinVarName()

std::string SampleHandlerFD::GetXBinVarName ( const int  Sample) const
inline

Definition at line 42 of file SampleHandlerFD.h.

42 {return GetKinVarName(Sample, 0);}

◆ GetYBinVarName()

std::string SampleHandlerFD::GetYBinVarName ( const int  Sample) const
inline

Definition at line 43 of file SampleHandlerFD.h.

43 {return GetKinVarName(Sample, 1);}

◆ Init()

virtual void SampleHandlerFD::Init ( )
protectedpure virtual

Initialise any variables that your experiment specific SampleHandler needs.

Implemented in PySampleHandlerFD.

◆ Initialise()

void SampleHandlerFD::Initialise ( )
protected

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

Definition at line 163 of file SampleHandlerFD.cpp.

163  {
164  TStopwatch clock;
165  clock.Start();
166 
167  //First grab all the information from your sample config via your manager
168  ReadConfig();
169 
170  //Now initialise all the variables you will need
171  Init();
172 
174  MCSamples.resize(nEvents);
175  SetupFDMC();
176 
177  MACH3LOG_INFO("=============================================");
178  MACH3LOG_INFO("Total number of events is: {}", GetNEvents());
179 
181  if (OscParams.size() > 0) {
182  MACH3LOG_INFO("Setting up NuOscillator..");
183  if (Oscillator != nullptr) {
184  MACH3LOG_INFO("You have passed an OscillatorBase object through the constructor of a SampleHandlerFD object - this will be used for all oscillation channels");
185  if(Oscillator->isEqualBinningPerOscChannel() != true) {
186  MACH3LOG_ERROR("Trying to run shared NuOscillator without EqualBinningPerOscChannel, this will not work");
187  throw MaCh3Exception(__FILE__, __LINE__);
188  }
189 
190  if(OscParams.size() != Oscillator->GetOscParamsSize()){
191  MACH3LOG_ERROR("SampleHandler {} has {} osc params, while shared NuOsc has {} osc params", GetName(),
192  OscParams.size(), Oscillator->GetOscParamsSize());
193  MACH3LOG_ERROR("This indicate misconfiguration in your Osc yaml");
194  throw MaCh3Exception(__FILE__, __LINE__);
195  }
196  } else {
198  }
200  } else{
201  MACH3LOG_WARN("Didn't find any oscillation params, thus will not enable oscillations");
202  if(CheckNodeExists(SampleManager->raw(), "NuOsc")){
203  MACH3LOG_ERROR("However config for SampleHandler {} has 'NuOsc' field", GetName());
204  MACH3LOG_ERROR("This may indicate misconfiguration");
205  MACH3LOG_ERROR("Either remove 'NuOsc' field from SampleHandler config or check your model.yaml and include oscillation for sample");
206  throw MaCh3Exception(__FILE__, __LINE__);
207  }
208  }
209  MACH3LOG_INFO("Setting up Sample Binning..");
210  SetBinning();
211  MACH3LOG_INFO("Setting up Splines..");
212  SetupSplines();
213  MACH3LOG_INFO("Setting up Normalisation Pointers..");
215  MACH3LOG_INFO("Setting up Functional Pointers..");
217  MACH3LOG_INFO("Setting up Additional Weight Pointers..");
219  MACH3LOG_INFO("Setting up Kinematic Map..");
221  clock.Stop();
222  MACH3LOG_INFO("Finished loading MC for {}, it took {:.2f}s to finish", GetName(), clock.RealTime());
223  MACH3LOG_INFO("=======================================================");
224 }
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
Definition: YamlHelper.h:60
std::vector< const double * > GetOscParsFromSampleName(const std::string &SampleName)
Get pointers to Osc params from Sample name.
unsigned int nEvents
Number of MC events are there.
virtual void Init()=0
Initialise any variables that your experiment specific SampleHandler needs.
virtual void SetupSplines()=0
initialise your splineXX object and then use InitialiseSplineObject to conviently setup everything up
virtual int SetupExperimentMC()=0
Experiment specific setup, returns the number of events which were loaded.
void SetupNormParameters()
Setup the norm parameters by assigning each event with bin.
std::string GetName() const override
void SetupKinematicMap()
Ensure Kinematic Map is setup and make sure it is initialised correctly.
virtual void SetupFDMC()=0
Function which translates experiment struct into core struct.
void InitialiseNuOscillatorObjects()
including Dan's magic NuOscillator
void SetBinning()
set the binning for 2D sample used for the likelihood calculation
void SetupNuOscillatorPointers()
virtual void SetupFunctionalParameters()
ETA - a function to setup and pass values to functional parameters where you need to pass a value to ...
virtual void AddAdditionalWeightPointers()=0
DB Function to determine which weights apply to which types of samples.

◆ InitialiseNuOscillatorObjects()

void SampleHandlerFD::InitialiseNuOscillatorObjects ( )

including Dan's magic NuOscillator

Definition at line 1020 of file SampleHandlerFD.cpp.

1020  {
1021 // ************************************************
1022  auto NuOscillatorConfigFile = Get<std::string>(SampleManager->raw()["NuOsc"]["NuOscConfigFile"], __FILE__ , __LINE__);
1023  auto EqualBinningPerOscChannel = Get<bool>(SampleManager->raw()["NuOsc"]["EqualBinningPerOscChannel"], __FILE__ , __LINE__);
1024 
1025  // TN override the sample setting if not using binned oscillation
1026  if (EqualBinningPerOscChannel) {
1027  if (YAML::LoadFile(NuOscillatorConfigFile)["General"]["CalculationType"].as<std::string>() == "Unbinned") {
1028  MACH3LOG_WARN("Tried using EqualBinningPerOscChannel while using Unbinned oscillation calculation, changing EqualBinningPerOscChannel to false");
1029  EqualBinningPerOscChannel = false;
1030  }
1031  }
1032  std::vector<const double*> OscParams = ParHandler->GetOscParsFromSampleName(SampleHandlerName);
1033  if (OscParams.empty()) {
1034  MACH3LOG_ERROR("OscParams is empty for sample '{}'.", GetName());
1035  MACH3LOG_ERROR("This likely indicates an error in your oscillation YAML configuration.");
1036  throw MaCh3Exception(__FILE__, __LINE__);
1037  }
1038  Oscillator = std::make_shared<OscillationHandler>(NuOscillatorConfigFile, EqualBinningPerOscChannel, OscParams, GetNOscChannels(0));
1039  // Add samples only if we don't use same binning
1040  if(!EqualBinningPerOscChannel) {
1041  // KS: Start from 1 because sample 0 already added
1042  for(int iSample = 1; iSample < GetNsamples(); iSample++) {
1043  Oscillator->AddSample(NuOscillatorConfigFile, GetNOscChannels(iSample));
1044  }
1045  for(int iSample = 0; iSample < GetNsamples(); iSample++) {
1046  for(int iChannel = 0; iChannel < GetNOscChannels(iSample); iChannel++) {
1047  std::vector<M3::float_t> EnergyArray;
1048  std::vector<M3::float_t> CosineZArray;
1049 
1050  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1051  if(MCSamples[iEvent].NominalSample != iSample) continue;
1052  // 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
1053  const int Channel = GetOscChannel(SampleDetails[MCSamples[iEvent].NominalSample].OscChannels, (*MCSamples[iEvent].nupdgUnosc), (*MCSamples[iEvent].nupdg));
1054  //DB Remove NC events from the arrays which are handed to the NuOscillator objects
1055  if (!MCSamples[iEvent].isNC && Channel == iChannel) {
1056  EnergyArray.push_back(M3::float_t(*(MCSamples[iEvent].rw_etru)));
1057  }
1058  }
1059  std::sort(EnergyArray.begin(),EnergyArray.end());
1060 
1061  //============================================================================
1062  //DB Atmospheric only part, can only happen if truecz has been initialised within the experiment specific code
1063  if (*(MCSamples[0].rw_truecz) != M3::_BAD_DOUBLE_) {
1064  for (unsigned int iEvent = 0; iEvent < GetNEvents(); iEvent++) {
1065  if(MCSamples[iEvent].NominalSample != iSample) continue;
1066  // 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
1067  const int Channel = GetOscChannel(SampleDetails[MCSamples[iEvent].NominalSample].OscChannels, (*MCSamples[iEvent].nupdgUnosc), (*MCSamples[iEvent].nupdg));
1068  //DB Remove NC events from the arrays which are handed to the NuOscillator objects
1069  if (!MCSamples[iEvent].isNC && Channel == iChannel) {
1070  CosineZArray.push_back(M3::float_t(*(MCSamples[iEvent].rw_truecz)));
1071  }
1072  }
1073  std::sort(CosineZArray.begin(),CosineZArray.end());
1074  }
1075  Oscillator->SetOscillatorBinning(iSample, iChannel, EnergyArray, CosineZArray);
1076  } // end loop over channels
1077  } // end loop over samples
1078  }
1079 }
virtual M3::int_t GetNsamples()

◆ InitialiseSplineObject()

void SampleHandlerFD::InitialiseSplineObject ( )
protected

Definition at line 1314 of file SampleHandlerFD.cpp.

1314  {
1315  if(auto BinnedSplines = dynamic_cast<BinnedSplineHandler*>(SplineHandler.get())) {
1316  bool LoadSplineFile = GetFromManager<bool>(SampleManager->raw()["InputFiles"]["LoadSplineFile"], false, __FILE__, __LINE__);
1317  bool PrepSplineFile = GetFromManager<bool>(SampleManager->raw()["InputFiles"]["PrepSplineFile"], false, __FILE__, __LINE__);
1318  auto SplineFileName = GetFromManager<std::string>(SampleManager->raw()["InputFiles"]["SplineFileName"],
1319  (SampleHandlerName + "_SplineFile.root"), __FILE__, __LINE__);
1320  if(!LoadSplineFile) {
1321  for(int iSample = 0; iSample < GetNsamples(); iSample++) {
1322  std::vector<std::string> spline_filepaths = SampleDetails[iSample].spline_files;
1323 
1324  //Keep a track of the spline variables
1325  std::vector<std::string> SplineVarNames = {"TrueNeutrinoEnergy"};
1326  if (GetNDim(iSample) == 1) {
1327  SplineVarNames.push_back(GetKinVarName(iSample, 0));
1328  } else if (GetNDim(iSample) == 2) {
1329  SplineVarNames.push_back(GetKinVarName(iSample, 0));
1330  SplineVarNames.push_back(GetKinVarName(iSample, 1));
1331  } else {
1332  MACH3LOG_CRITICAL("{} Not implemented for dimension {}, will use 2D", __func__, GetNDim(iSample));
1333  SplineVarNames.push_back(GetKinVarName(iSample, 0));
1334  SplineVarNames.push_back(GetKinVarName(iSample, 1));
1335  }
1336  BinnedSplines->AddSample(SampleHandlerName, GetSampleTitle(iSample), spline_filepaths, SplineVarNames);
1337  }
1338  BinnedSplines->CountNumberOfLoadedSplines(false, 1);
1339  BinnedSplines->TransferToMonolith();
1340  if(PrepSplineFile) BinnedSplines->PrepareSplineFile(SplineFileName);
1341  } else {
1342  // KS: Skip default spline loading and use flattened spline format allowing to read stuff much faster
1343  BinnedSplines->LoadSplineFile(SplineFileName);
1344  }
1345  MACH3LOG_INFO("--------------------------------");
1346  MACH3LOG_INFO("Setup Far Detector splines");
1347 
1349 
1350  BinnedSplines->cleanUpMemory();
1351  } else if (auto UnbinnedSpline = dynamic_cast<SMonolith*>(SplineHandler.get())) {
1352  (void) UnbinnedSpline;
1354  } else {
1355  MACH3LOG_ERROR("Unsupported spline type encountered.");
1356  throw MaCh3Exception(__FILE__, __LINE__);
1357  }
1358 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
Bin-by-bin class calculating response for spline parameters.
Even-by-event class calculating response for spline parameters. It is possible to use GPU acceleratio...
std::unique_ptr< SplineBase > SplineHandler
Contains all your splines (binned or unbinned) and handles the setup and the returning of weights fro...
void SetSplinePointers()
Set pointers for each event to appropriate weights, for unbinned based on event number while for binn...

◆ IsEventSelected()

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

DB Function which determines if an event is selected, where Selection double looks like {{ND280KinematicTypes Var1, douuble LowBound}.

Definition at line 303 of file SampleHandlerFD.cpp.

303  {
304 // ************************************************
305  const auto& SampleSelection = Selection[iSample];
306  const int SelectionSize = static_cast<int>(SampleSelection.size());
307  for (int iSelection = 0; iSelection < SelectionSize; ++iSelection) {
308  const auto& Cut = SampleSelection[iSelection];
309  const double Val = ReturnKinematicParameter(Cut.ParamToCutOnIt, iEvent);
310  if ((Val < Cut.LowerBound) || (Val >= Cut.UpperBound)) {
311  return false;
312  }
313  }
314  //DB To avoid unnecessary checks, now return false rather than setting bool to true and continuing to check
315  return true;
316 }

◆ IsSubEventSelected()

bool SampleHandlerFD::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 319 of file SampleHandlerFD.cpp.

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

◆ IsSubEventVarString()

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

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

Definition at line 1676 of file SampleHandlerFD.cpp.

1676  {
1677  if (KinematicVectors == nullptr) return false;
1678 
1679  if (KinematicVectors->count(VarStr)) {
1680  if (!KinematicParameters->count(VarStr)) return true;
1681  else {
1682  MACH3LOG_ERROR("Attempted to plot kinematic variable {}, but it appears in both KinematicVectors and KinematicParameters", VarStr);
1683  throw MaCh3Exception(__FILE__,__LINE__);
1684  }
1685  }
1686  return false;
1687 }

◆ LoadSingleSample()

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

Add new sample

Definition at line 113 of file SampleHandlerFD.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 
119  Binning->SetupSampleBinning(SampleSettings["Binning"], SingleSample);
120 
121  auto mtupleprefix = Get<std::string>(SampleSettings["InputFiles"]["mtupleprefix"], __FILE__, __LINE__);
122  auto mtuplesuffix = Get<std::string>(SampleSettings["InputFiles"]["mtuplesuffix"], __FILE__, __LINE__);
123  auto splineprefix = Get<std::string>(SampleSettings["InputFiles"]["splineprefix"], __FILE__, __LINE__);
124  auto splinesuffix = Get<std::string>(SampleSettings["InputFiles"]["splinesuffix"], __FILE__, __LINE__);
125 
126  int NChannels = static_cast<M3::int_t>(SampleSettings["SubSamples"].size());
127  SingleSample.OscChannels.reserve(NChannels);
128 
129  int OscChannelCounter = 0;
130  for (auto const &osc_channel : SampleSettings["SubSamples"]) {
131  std::string MTupleFileName = mtupleprefix+osc_channel["mtuplefile"].as<std::string>()+mtuplesuffix;
132 
133  OscChannelInfo OscInfo;
134  OscInfo.flavourName = osc_channel["Name"].as<std::string>();
135  OscInfo.flavourName_Latex = osc_channel["LatexName"].as<std::string>();
136  OscInfo.InitPDG = static_cast<NuPDG>(osc_channel["nutype"].as<int>());
137  OscInfo.FinalPDG = static_cast<NuPDG>(osc_channel["oscnutype"].as<int>());
138  OscInfo.ChannelIndex = OscChannelCounter;
139 
140  SingleSample.OscChannels.push_back(std::move(OscInfo));
141 
142  FileToInitPDGMap[MTupleFileName] = static_cast<NuPDG>(osc_channel["nutype"].as<int>());
143  FileToFinalPDGMap[MTupleFileName] = static_cast<NuPDG>(osc_channel["oscnutype"].as<int>());
144 
145  SingleSample.mc_files.push_back(MTupleFileName);
146  SingleSample.spline_files.push_back(splineprefix+osc_channel["splinefile"].as<std::string>()+splinesuffix);
147  OscChannelCounter++;
148  }
149  //Now grab the selection cuts from the manager
150  for ( auto const &SelectionCuts : SampleSettings["SelectionCuts"]) {
151  auto TempBoundsVec = GetBounds(SelectionCuts["Bounds"]);
152  KinematicCut CutObj;
153  CutObj.LowerBound = TempBoundsVec[0];
154  CutObj.UpperBound = TempBoundsVec[1];
155  CutObj.ParamToCutOnIt = ReturnKinematicParameterFromString(SelectionCuts["KinematicStr"].as<std::string>());
156  MACH3LOG_INFO("Adding cut on {} with bounds {} to {}", SelectionCuts["KinematicStr"].as<std::string>(), TempBoundsVec[0], TempBoundsVec[1]);
157  StoredSelection[iSample].emplace_back(CutObj);
158  }
160  SampleDetails[iSample] = std::move(SingleSample);
161 }
NuPDG
Enum to track the incoming neutrino species.
Definition: SampleStructs.h:94
#define GetBounds(filename)
Definition: YamlHelper.h:590
KS: Store info about used osc channels.
std::string flavourName
Name of osc channel.
KS: Store info about MC sample.
std::vector< OscChannelInfo > OscChannels
Stores info about oscillation channel for a single sample.
std::vector< std::string > mc_files
names of mc files associated associated with this object
std::string SampleTitle
the name of this sample e.g."muon-like"
std::vector< std::string > spline_files
names of spline files associated associated with this object

◆ PassesSelection()

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

Definition at line 2065 of file SampleHandlerFD.cpp.

2065  {
2066 // ***************************************************************************
2067  bool IsSelected = true;
2068  if (Par.hasKinBounds) {
2069  const auto& kinVars = Par.KinematicVarStr;
2070  const auto& selection = Par.Selection;
2071 
2072  for (std::size_t iKinPar = 0; iKinPar < kinVars.size(); ++iKinPar) {
2073  const double kinVal = ReturnKinematicParameter(kinVars[iKinPar], static_cast<int>(iEvent));
2074 
2075  bool passedAnyBound = false;
2076  const auto& boundsList = selection[iKinPar];
2077 
2078  for (const auto& bounds : boundsList) {
2079  if (kinVal > bounds[0] && kinVal <= bounds[1]) {
2080  passedAnyBound = true;
2081  break;
2082  }
2083  }
2084 
2085  if (!passedAnyBound) {
2086  MACH3LOG_TRACE("Event {}, missed kinematic check ({}) for dial {}",
2087  iEvent, kinVars[iKinPar], Par.name);
2088  IsSelected = false;
2089  break;
2090  }
2091  }
2092  }
2093  return IsSelected;
2094 }

◆ PrepFunctionalParameters()

virtual void SampleHandlerFD::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 241 of file SampleHandlerFD.h.

241 {};

◆ PrintIntegral()

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

Definition at line 1757 of file SampleHandlerFD.cpp.

1757  {
1758  constexpr int space = 14;
1759 
1760  bool printToFile=false;
1761  if (OutputFileName.CompareTo("/dev/null")) {printToFile = true;}
1762 
1763  bool printToCSV=false;
1764  if(OutputCSVFileName.CompareTo("/dev/null")) printToCSV=true;
1765 
1766  std::ofstream outfile;
1767  if (printToFile) {
1768  outfile.open(OutputFileName.Data(), std::ios_base::app);
1769  outfile.precision(7);
1770  }
1771 
1772  std::ofstream outcsv;
1773  if(printToCSV){
1774  outcsv.open(OutputCSVFileName, std::ios_base::app); // Appened to CSV
1775  outcsv.precision(7);
1776  }
1777 
1778  double PDFIntegral = 0.;
1779 
1780  std::vector< std::vector< TH1* > > IntegralList;
1781  IntegralList.resize(Modes->GetNModes());
1782 
1783  std::vector<double> ChannelIntegral;
1784  ChannelIntegral.resize(GetNOscChannels(iSample));
1785  for (unsigned int i=0;i<ChannelIntegral.size();i++) {ChannelIntegral[i] = 0.;}
1786 
1787  for (int i=0;i<Modes->GetNModes();i++) {
1788  if (GetNDim(iSample) == 1) {
1789  IntegralList[i] = ReturnHistsBySelection1D(iSample, GetXBinVarName(iSample),1,i,WeightStyle);
1790  } else {
1791  IntegralList[i] = CastVector<TH2, TH1>(ReturnHistsBySelection2D(iSample, GetXBinVarName(iSample), GetYBinVarName(iSample),1,i,WeightStyle));
1792  }
1793  }
1794 
1795  MACH3LOG_INFO("-------------------------------------------------");
1796 
1797  if (printToFile) {
1798  outfile << "\\begin{table}[ht]" << std::endl;
1799  outfile << "\\begin{center}" << std::endl;
1800  outfile << "\\caption{Integral breakdown for sample: " << GetSampleTitle(iSample) << "}" << std::endl;
1801  outfile << "\\label{" << GetSampleTitle(iSample) << "-EventRate}" << std::endl;
1802 
1803  TString nColumns;
1804  for (int i=0;i<GetNOscChannels(iSample);i++) {nColumns+="|c";}
1805  nColumns += "|c|";
1806  outfile << "\\begin{tabular}{|l" << nColumns.Data() << "}" << std::endl;
1807  outfile << "\\hline" << std::endl;
1808  }
1809 
1810  if(printToCSV){
1811  // HW Probably a better way but oh well, here I go making MaCh3 messy again
1812  outcsv<<"Integral Breakdown for sample :"<<GetSampleTitle(iSample)<<"\n";
1813  }
1814 
1815  MACH3LOG_INFO("Integral breakdown for sample: {}", GetSampleTitle(iSample));
1816  MACH3LOG_INFO("");
1817 
1818  if (printToFile) {outfile << std::setw(space) << "Mode:";}
1819  if(printToCSV) {outcsv<<"Mode,";}
1820 
1821  std::string table_headings = fmt::format("| {:<8} |", "Mode");
1822  std::string table_footline = "------------"; //Scalable table horizontal line
1823  for (int i = 0;i < GetNOscChannels(iSample); i++) {
1824  table_headings += fmt::format(" {:<17} |", GetFlavourName(iSample, i));
1825  table_footline += "--------------------";
1826  if (printToFile) {outfile << "&" << std::setw(space) << SampleDetails[iSample].OscChannels[i].flavourName_Latex << " ";}
1827  if (printToCSV) {outcsv << GetFlavourName(iSample, i) << ",";}
1828  }
1829  if (printToFile) {outfile << "&" << std::setw(space) << "Total:" << "\\\\ \\hline" << std::endl;}
1830  if (printToCSV) {outcsv <<"Total\n";}
1831  table_headings += fmt::format(" {:<10} |", "Total");
1832  table_footline += "-------------";
1833 
1834  MACH3LOG_INFO("{}", table_headings);
1835  MACH3LOG_INFO("{}", table_footline);
1836 
1837  for (unsigned int i=0;i<IntegralList.size();i++) {
1838  double ModeIntegral = 0;
1839  if (printToFile) {outfile << std::setw(space) << Modes->GetMaCh3ModeName(i);}
1840  if(printToCSV) {outcsv << Modes->GetMaCh3ModeName(i) << ",";}
1841 
1842  table_headings = fmt::format("| {:<8} |", Modes->GetMaCh3ModeName(i)); //Start string with mode name
1843 
1844  for (unsigned int j=0;j<IntegralList[i].size();j++) {
1845  double Integral = IntegralList[i][j]->Integral();
1846 
1847  if (Integral < 1e-100) {Integral=0;}
1848 
1849  ModeIntegral += Integral;
1850  ChannelIntegral[j] += Integral;
1851  PDFIntegral += Integral;
1852 
1853  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",Integral) << " ";}
1854  if (printToCSV) {outcsv << Form("%4.5f", Integral) << ",";}
1855 
1856  table_headings += fmt::format(" {:<17.4f} |", Integral);
1857  }
1858  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",ModeIntegral) << " \\\\ \\hline" << std::endl;}
1859  if (printToCSV) {outcsv << Form("%4.5f", ModeIntegral) << "\n";}
1860 
1861  table_headings += fmt::format(" {:<10.4f} |", ModeIntegral);
1862 
1863  MACH3LOG_INFO("{}", table_headings);
1864  }
1865 
1866  if (printToFile) {outfile << std::setw(space) << "Total:";}
1867  if (printToCSV) {outcsv << "Total,";}
1868 
1869  //Clear the table_headings to print last row of totals
1870  table_headings = fmt::format("| {:<8} |", "Total");
1871  for (unsigned int i=0;i<ChannelIntegral.size();i++) {
1872  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",ChannelIntegral[i]) << " ";}
1873  if (printToCSV) {outcsv << Form("%4.5f", ChannelIntegral[i]) << ",";}
1874  table_headings += fmt::format(" {:<17.4f} |", ChannelIntegral[i]);
1875  }
1876  if (printToFile) {outfile << "&" << std::setw(space) << Form("%4.5f",PDFIntegral) << " \\\\ \\hline" << std::endl;}
1877  if (printToCSV) {outcsv << Form("%4.5f", PDFIntegral) << "\n\n\n\n";} // Let's have a few new lines!
1878 
1879  table_headings += fmt::format(" {:<10.4f} |", PDFIntegral);
1880  MACH3LOG_INFO("{}", table_headings);
1881  MACH3LOG_INFO("{}", table_footline);
1882 
1883  if (printToFile) {
1884  outfile << "\\end{tabular}" << std::endl;
1885  outfile << "\\end{center}" << std::endl;
1886  outfile << "\\end{table}" << std::endl;
1887  }
1888 
1889  MACH3LOG_INFO("");
1890 
1891  if (printToFile) {
1892  outfile << std::endl;
1893  outfile.close();
1894  }
1895  // KS: Clean memory we could use smart pointers in future
1896  CleanContainer(IntegralList);
1897 }
void CleanContainer(T &)
Base case: do nothing for non-pointer types.
std::vector< TH2 * > ReturnHistsBySelection2D(const int iSample, const std::string &KinematicProjectionX, const std::string &KinematicProjectionY, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *XAxis=nullptr, TAxis *YAxis=nullptr)
std::string GetFlavourName(const int iSample, const int iChannel) const override
std::vector< TH1 * > ReturnHistsBySelection1D(const int iSample, const std::string &KinematicProjection, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *Axis=nullptr)

◆ PrintRates()

void SampleHandlerFD::PrintRates ( const bool  DataOnly = false)
overridevirtual

Helper function to print rates for the samples with LLH.

Parameters
DataOnlywhether to print data only rates

Implements SampleHandlerBase.

Definition at line 1993 of file SampleHandlerFD.cpp.

1993  {
1994 // ***************************************************************************
1995  if (SampleHandlerFD_data == nullptr) {
1996  MACH3LOG_ERROR("Data sample is empty!");
1997  throw MaCh3Exception(__FILE__, __LINE__);
1998  }
1999  MACH3LOG_INFO("Printing for {}", GetName());
2000 
2001  if (!DataOnly) {
2002  const std::string sep_full(71, '-');
2003  MACH3LOG_INFO("{}", sep_full);
2004  MACH3LOG_INFO("{:<40}{:<10}{:<10}{:<10}|", "Sample", "Data", "MC", "-LLH");
2005  } else {
2006  const std::string sep_data(51, '-');
2007  MACH3LOG_INFO("{}", sep_data);
2008  MACH3LOG_INFO("{:<40}{:<10}|", "Sample", "Data");
2009  }
2010 
2011  double sumData = 0.0;
2012  double sumMC = 0.0;
2013  double likelihood = 0.0;
2014 
2015  for (int iSample = 0; iSample < GetNsamples(); ++iSample) {
2016  std::string name = GetSampleTitle(iSample);
2017  std::vector<double> DataArray = GetDataArray(iSample);
2018  double dataIntegral = std::accumulate(DataArray.begin(), DataArray.end(), 0.0);
2019  sumData += dataIntegral;
2020  if (!DataOnly) {
2021  std::vector<double> MCArray = GetMCArray(iSample);
2022  double mcIntegral = std::accumulate(MCArray.begin(), MCArray.end(), 0.0);
2023  sumMC += mcIntegral;
2024  likelihood = GetSampleLikelihood(iSample);
2025 
2026  MACH3LOG_INFO("{:<40}{:<10.2f}{:<10.2f}{:<10.2f}|", name, dataIntegral, mcIntegral, likelihood);
2027  } else {
2028  MACH3LOG_INFO("{:<40}{:<10.2f}|", name, dataIntegral);
2029  }
2030  }
2031  if (!DataOnly) {
2032  likelihood = GetLikelihood();
2033  MACH3LOG_INFO("{:<40}{:<10.2f}{:<10.2f}{:<10.2f}|", "Total", sumData, sumMC, likelihood);
2034  const std::string sep_full(71, '-');
2035  MACH3LOG_INFO("{}", sep_full);
2036  } else {
2037  MACH3LOG_INFO("{:<40}{:<10.2f}|", "Total", sumData);
2038  const std::string sep_data(51, '-');
2039  MACH3LOG_INFO("{}", sep_data);
2040  }
2041 }
double GetLikelihood() const override
DB Multi-threaded GetLikelihood.
std::vector< double > GetDataArray() const
Return array storing data entries for every bin.
std::vector< double > GetMCArray() const
Return array storing MC entries for every bin.
double GetSampleLikelihood(const int isample) const override
Get likelihood for single sample.

◆ ReadConfig()

void SampleHandlerFD::ReadConfig ( )

Definition at line 59 of file SampleHandlerFD.cpp.

60 {
61  auto ModeName = Get<std::string>(SampleManager->raw()["MaCh3ModeConfig"], __FILE__ , __LINE__);
62  Modes = std::make_unique<MaCh3Modes>(ModeName);
63  //SampleName has to be provided in the sample yaml otherwise this will throw an exception
64  SampleHandlerName = Get<std::string>(SampleManager->raw()["SampleHandlerName"], __FILE__ , __LINE__);
65 
66  fTestStatistic = static_cast<TestStatistic>(SampleManager->GetMCStatLLH());
67  if (CheckNodeExists(SampleManager->raw(), "LikelihoodOptions")) {
68  UpdateW2 = GetFromManager<bool>(SampleManager->raw()["LikelihoodOptions"]["UpdateW2"], false);
69  }
70 
71  if (!CheckNodeExists(SampleManager->raw(), "BinningFile")){
72  MACH3LOG_ERROR("BinningFile not given in for sample handler {}, ReturnKinematicParameterBinning will not work", SampleHandlerName);
73  throw MaCh3Exception(__FILE__, __LINE__);
74  }
75 
76  auto EnabledSasmples = Get<std::vector<std::string>>(SampleManager->raw()["Samples"], __FILE__ , __LINE__);
77  // Get number of samples and resize relevant objects
78  nSamples = static_cast<M3::int_t>(EnabledSasmples.size());
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.
TestStatistic fTestStatistic
Test statistic tells what kind of likelihood sample is using.
void LoadSingleSample(const int iSample, const YAML::Node &Settings)
std::unordered_map< std::string, double > _modeNomWeightMap

◆ RegisterFunctionalParameters()

virtual void SampleHandlerFD::RegisterFunctionalParameters ( )
protectedpure virtual

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

Implemented in PySampleHandlerFD.

◆ RegisterIndividualFunctionalParameter()

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

HH - a helper function for RegisterFunctionalParameter.

Definition at line 483 of file SampleHandlerFD.cpp.

483  {
484  // Add protections to not add the same functional parameter twice
485  if (funcParsNamesMap.find(fpName) != funcParsNamesMap.end()) {
486  MACH3LOG_ERROR("Functional parameter {} already registered in funcParsNamesMap with enum {}", fpName, funcParsNamesMap[fpName]);
487  throw MaCh3Exception(__FILE__, __LINE__);
488  }
489  if (std::find(funcParsNamesVec.begin(), funcParsNamesVec.end(), fpName) != funcParsNamesVec.end()) {
490  MACH3LOG_ERROR("Functional parameter {} already in funcParsNamesVec", fpName);
491  throw MaCh3Exception(__FILE__, __LINE__);
492  }
493  if (funcParsFuncMap.find(fpEnum) != funcParsFuncMap.end()) {
494  MACH3LOG_ERROR("Functional parameter enum {} already registered in funcParsFuncMap", fpEnum);
495  throw MaCh3Exception(__FILE__, __LINE__);
496  }
497  funcParsNamesMap[fpName] = fpEnum;
498  funcParsNamesVec.push_back(fpName);
499  funcParsFuncMap[fpEnum] = fpFunc;
500 }
std::unordered_map< int, FuncParFuncType > funcParsFuncMap
HH - a map that relates the funcpar enum to pointer of the actual function.
std::vector< std::string > funcParsNamesVec
HH - a vector of string names for each functional parameter.
std::unordered_map< std::string, int > funcParsNamesMap
HH - a map that relates the name of the functional parameter to funcpar enum.

◆ ResetHistograms()

void SampleHandlerFD::ResetHistograms ( )
protected

Helper function to reset histograms.

Definition at line 472 of file SampleHandlerFD.cpp.

472  {
473 // **************************************************
474  // DB Reset values stored in PDF array to 0.
475  // Don't openMP this; no significant gain
476  const int nBins = Binning->GetNBins();
478  if (FirstTimeW2) {
480  }
481 } // end function

◆ ResetShifts()

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

HH - reset the shifted values to the original values.

Definition at line 250 of file SampleHandlerFD.h.

250 {(void)iEvent;};

◆ ReturnHistsBySelection1D()

std::vector< TH1 * > SampleHandlerFD::ReturnHistsBySelection1D ( const int  iSample,
const std::string &  KinematicProjection,
int  Selection1,
int  Selection2 = -1,
int  WeightStyle = 0,
TAxis *  Axis = nullptr 
)

Definition at line 1900 of file SampleHandlerFD.cpp.

1901  {
1902 // ************************************************
1903  std::vector<TH1*> hHistList;
1904  std::string legendEntry;
1905 
1906  if (THStackLeg != nullptr) {delete THStackLeg;}
1907  THStackLeg = new TLegend(0.1,0.1,0.9,0.9);
1908 
1909  int iMax = -1;
1910  if (Selection1 == FDPlotType::kModePlot) {
1911  iMax = Modes->GetNModes();
1912  }
1913  if (Selection1 == FDPlotType::kOscChannelPlot) {
1914  iMax = GetNOscChannels(iSample);
1915  }
1916  if (iMax == -1) {
1917  MACH3LOG_ERROR("You've passed me a Selection1 which was not implemented in ReturnHistsBySelection1D. Selection1 and Selection2 are counters for different indexable quantities");
1918  throw MaCh3Exception(__FILE__, __LINE__);
1919  }
1920 
1921  for (int i=0;i<iMax;i++) {
1922  if (Selection1 == FDPlotType::kModePlot) {
1923  hHistList.push_back(Get1DVarHistByModeAndChannel(iSample, KinematicProjection,i,Selection2,WeightStyle,XAxis));
1924  THStackLeg->AddEntry(hHistList[i],(Modes->GetMaCh3ModeName(i)+Form(" : (%4.2f)",hHistList[i]->Integral())).c_str(),"f");
1925 
1926  hHistList[i]->SetFillColor(static_cast<Color_t>(Modes->GetMaCh3ModePlotColor(i)));
1927  hHistList[i]->SetLineColor(static_cast<Color_t>(Modes->GetMaCh3ModePlotColor(i)));
1928  }
1929  if (Selection1 == FDPlotType::kOscChannelPlot) {
1930  hHistList.push_back(Get1DVarHistByModeAndChannel(iSample, KinematicProjection,Selection2,i,WeightStyle,XAxis));
1931  THStackLeg->AddEntry(hHistList[i],(GetFlavourName(iSample, i)+Form(" | %4.2f",hHistList[i]->Integral())).c_str(),"f");
1932  }
1933  }
1934 
1935  return hHistList;
1936 }

◆ ReturnHistsBySelection2D()

std::vector< TH2 * > SampleHandlerFD::ReturnHistsBySelection2D ( const int  iSample,
const std::string &  KinematicProjectionX,
const std::string &  KinematicProjectionY,
int  Selection1,
int  Selection2 = -1,
int  WeightStyle = 0,
TAxis *  XAxis = nullptr,
TAxis *  YAxis = nullptr 
)

Definition at line 1938 of file SampleHandlerFD.cpp.

1941  {
1942 // ************************************************
1943  std::vector<TH2*> hHistList;
1944 
1945  int iMax = -1;
1946  if (Selection1 == FDPlotType::kModePlot) {
1947  iMax = Modes->GetNModes();
1948  }
1949  if (Selection1 == FDPlotType::kOscChannelPlot) {
1950  iMax = GetNOscChannels(iSample);
1951  }
1952  if (iMax == -1) {
1953  MACH3LOG_ERROR("You've passed me a Selection1 which was not implemented in ReturnHistsBySelection1D. Selection1 and Selection2 are counters for different indexable quantities");
1954  throw MaCh3Exception(__FILE__, __LINE__);
1955  }
1956 
1957  for (int i=0;i<iMax;i++) {
1958  if (Selection1 == FDPlotType::kModePlot) {
1959  hHistList.push_back(Get2DVarHistByModeAndChannel(iSample, KinematicProjectionX,KinematicProjectionY,i,Selection2,WeightStyle,XAxis,YAxis));
1960  }
1961  if (Selection1 == FDPlotType::kOscChannelPlot) {
1962  hHistList.push_back(Get2DVarHistByModeAndChannel(iSample, KinematicProjectionX,KinematicProjectionY,Selection2,i,WeightStyle,XAxis,YAxis));
1963  }
1964  }
1965 
1966  return hHistList;
1967 }

◆ ReturnKinematicParameter() [1/2]

virtual double SampleHandlerFD::ReturnKinematicParameter ( int  KinematicVariable,
int  iEvent 
)
protectedpure virtual

Implemented in PySampleHandlerFD.

◆ ReturnKinematicParameter() [2/2]

virtual double SampleHandlerFD::ReturnKinematicParameter ( std::string  KinematicParamter,
int  iEvent 
)
protectedpure virtual

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

Implemented in PySampleHandlerFD.

◆ ReturnKinematicParameterBinning()

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

Return the binning used to draw a kinematic parameter.

Todo:
might be useful to allow overwriting this

Implements SampleHandlerBase.

Definition at line 1622 of file SampleHandlerFD.cpp.

1622  {
1623 // ************************************************
1624  // If any of fit based variables return them
1626  if(Binning->IsUniform(Sample)) {
1627  for(int iDim = 0; iDim < GetNDim(Sample); iDim++) {
1628  if(KinematicParameter == GetKinVarName(Sample, iDim)) {
1629  return Binning->GetBinEdges(Sample, iDim);
1630  }
1631  } // end loop over Dimension
1632  } // end loop over IsUniform
1633 
1634  auto MakeBins = [](int nBins) {
1635  std::vector<double> bins(nBins + 1);
1636  for (int i = 0; i <= nBins; ++i)
1637  bins[i] = static_cast<double>(i) - 0.5;
1638  return bins;
1639  };
1640 
1641  if (KinematicParameter == "OscillationChannel") {
1642  return MakeBins(GetNOscChannels(Sample));
1643  } else if (KinematicParameter == "Mode") {
1644  return MakeBins(Modes->GetNModes());
1645  }
1646 
1647 
1648  std::vector<double> BinningVect;
1649  // We first check if binning for a sample has been specified
1650  auto BinningConfig = M3OpenConfig(SampleManager->raw()["BinningFile"].as<std::string>());
1651  if(BinningConfig[GetSampleTitle(Sample)] && BinningConfig[GetSampleTitle(Sample)][KinematicParameter]){
1652  BinningVect = Get<std::vector<double>>(BinningConfig[GetSampleTitle(Sample)][KinematicParameter], __FILE__, __LINE__);
1653  } else {
1654  BinningVect = Get<std::vector<double>>(BinningConfig[KinematicParameter], __FILE__, __LINE__);
1655  }
1656 
1657  // Ensure binning is increasing
1658  auto IsIncreasing = [](const std::vector<double>& vec) {
1659  for (size_t i = 1; i < vec.size(); ++i) {
1660  if (vec[i] <= vec[i-1]) {
1661  return false;
1662  }
1663  }
1664  return true;
1665  };
1666 
1667  if (!IsIncreasing(BinningVect)) {
1668  MACH3LOG_ERROR("Binning for {} is not increasing [{}]", KinematicParameter, fmt::join(BinningVect, ", "));
1669  throw MaCh3Exception(__FILE__,__LINE__);
1670  }
1671 
1672  return BinningVect;
1673 }
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589

◆ ReturnKinematicParameterFromString()

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

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

Definition at line 1569 of file SampleHandlerFD.cpp.

1569  {
1570 // ************************************************
1571  auto it = KinematicParameters->find(KinematicParameterStr);
1572  if (it != KinematicParameters->end()) return it->second;
1573 
1574  MACH3LOG_ERROR("Did not recognise Kinematic Parameter type: {}", KinematicParameterStr);
1575  throw MaCh3Exception(__FILE__, __LINE__);
1576 
1577  return M3::_BAD_INT_;
1578 }

◆ ReturnKinematicVector() [1/2]

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

Definition at line 292 of file SampleHandlerFD.h.

292 {return {}; (void)KinematicVariable; (void)iEvent;};

◆ ReturnKinematicVector() [2/2]

virtual std::vector<double> SampleHandlerFD::ReturnKinematicVector ( std::string  KinematicParameter,
int  iEvent 
)
inlineprotectedvirtual

Definition at line 291 of file SampleHandlerFD.h.

291 {return {}; (void)KinematicParameter; (void)iEvent;};

◆ ReturnKinematicVectorFromString()

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

Definition at line 1596 of file SampleHandlerFD.cpp.

1596  {
1597 // ************************************************
1598  auto it = KinematicVectors->find(KinematicVectorStr);
1599  if (it != KinematicVectors->end()) return it->second;
1600 
1601  MACH3LOG_ERROR("Did not recognise Kinematic Vector: {}", KinematicVectorStr);
1602  throw MaCh3Exception(__FILE__, __LINE__);
1603 
1604  return M3::_BAD_INT_;
1605 }

◆ ReturnStackedHistBySelection1D()

THStack * SampleHandlerFD::ReturnStackedHistBySelection1D ( const int  iSample,
const std::string &  KinematicProjection,
int  Selection1,
int  Selection2 = -1,
int  WeightStyle = 0,
TAxis *  Axis = nullptr 
)

Definition at line 1970 of file SampleHandlerFD.cpp.

1971  {
1972 // ************************************************
1973  std::vector<TH1*> HistList = ReturnHistsBySelection1D(iSample, KinematicProjection, Selection1, Selection2, WeightStyle, XAxis);
1974  THStack* StackHist = new THStack((GetSampleTitle(iSample)+"_"+KinematicProjection+"_Stack").c_str(),"");
1975  for (unsigned int i=0;i<HistList.size();i++) {
1976  StackHist->Add(HistList[i]);
1977  }
1978  return StackHist;
1979 }

◆ ReturnStackHistLegend()

TLegend* SampleHandlerFD::ReturnStackHistLegend ( )
inline

Definition at line 144 of file SampleHandlerFD.h.

144 {return THStackLeg;}

◆ ReturnStringFromKinematicParameter()

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

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

Definition at line 1581 of file SampleHandlerFD.cpp.

1581  {
1582 // ************************************************
1583  auto it = ReversedKinematicParameters->find(KinematicParameter);
1584  if (it != ReversedKinematicParameters->end()) {
1585  return it->second;
1586  }
1587 
1588  MACH3LOG_ERROR("Did not recognise Kinematic Parameter type: {}", KinematicParameter);
1589  throw MaCh3Exception(__FILE__, __LINE__);
1590 
1591  return "";
1592 }

◆ ReturnStringFromKinematicVector()

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

Definition at line 1608 of file SampleHandlerFD.cpp.

1608  {
1609 // ************************************************
1610  auto it = ReversedKinematicVectors->find(KinematicVector);
1611  if (it != ReversedKinematicVectors->end()) {
1612  return it->second;
1613  }
1614 
1615  MACH3LOG_ERROR("Did not recognise Kinematic Vector: {}", KinematicVector);
1616  throw MaCh3Exception(__FILE__, __LINE__);
1617 
1618  return "";
1619 }

◆ Reweight()

void SampleHandlerFD::Reweight ( )
overridevirtual

Implements SampleHandlerBase.

Definition at line 338 of file SampleHandlerFD.cpp.

338  {
339 //************************************************
340  //KS: Reset the histograms before reweight
341  ResetHistograms();
342 
343  //You only need to do these things if Oscillator has been initialised
344  //if not then you're not considering oscillations
345  if (Oscillator) Oscillator->Evaluate();
346 
347  // Calculate weight coming from all splines if we initialised handler
348  if(SplineHandler) SplineHandler->Evaluate();
349 
350  // Update the functional parameter values to the latest proposed values
352 
353  //KS: If using CPU this does nothing, if on GPU need to make sure we finished copying memory from
354  if(SplineHandler) SplineHandler->SynchroniseMemTransfer();
355 
356  #ifdef MULTITHREAD
357  // Call entirely different routine if we're running with openMP
358  FillArray_MP();
359  #else
360  FillArray();
361  #endif
362 
363  //KS: If you want to not update W2 wights then uncomment this line
364  if(!UpdateW2) FirstTimeW2 = false;
365 }
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()
DB Nice new multi-threaded function which calculates the event weights and fills the relevant bins of...

◆ SaveAdditionalInfo()

void SampleHandlerFD::SaveAdditionalInfo ( TDirectory *  Dir)
overridevirtual

Store additional info in a chan.

Reimplemented from SampleHandlerBase.

Definition at line 1269 of file SampleHandlerFD.cpp.

1269  {
1270 // ************************************************
1271  Dir->cd();
1272 
1273  YAML::Node Config = SampleManager->raw();
1274  TMacro ConfigSave = YAMLtoTMacro(Config, (std::string("Config_") + GetName()));
1275  ConfigSave.Write();
1276 
1277  for(int iSample = 0; iSample < GetNsamples(); iSample++)
1278  {
1279  std::unique_ptr<TH1> data_hist;
1280 
1281  if (GetNDim(iSample) == 1) {
1282  data_hist = M3::Clone<TH1D>(dynamic_cast<TH1D*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1283  data_hist->GetXaxis()->SetTitle(GetXBinVarName(iSample).c_str());
1284  data_hist->GetYaxis()->SetTitle("Number of Events");
1285  } else if (GetNDim(iSample) == 2) {
1286  if(Binning->IsUniform(iSample)) {
1287  data_hist = M3::Clone<TH2D>(dynamic_cast<TH2D*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1288  } else {
1289  data_hist = M3::Clone<TH2Poly>(dynamic_cast<TH2Poly*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1290  }
1291  data_hist->GetXaxis()->SetTitle(GetXBinVarName(iSample).c_str());
1292  data_hist->GetYaxis()->SetTitle(GetYBinVarName(iSample).c_str());
1293  data_hist->GetZaxis()->SetTitle("Number of Events");
1294  } else {
1295  data_hist = M3::Clone<TH1D>(dynamic_cast<TH1D*>(GetDataHist(iSample)), "data_" + GetSampleTitle(iSample));
1296  int nbins = Binning->GetNBins(iSample);
1297  for(int iBin = 0; iBin < nbins; iBin++) {
1298  auto BinName = Binning->GetBinName(iSample, iBin);
1299  data_hist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
1300  }
1301  data_hist->GetYaxis()->SetTitle("Number of Events");
1302  }
1303 
1304  if (!data_hist) {
1305  MACH3LOG_ERROR("nullptr data hist :(");
1306  throw MaCh3Exception(__FILE__, __LINE__);
1307  }
1308 
1309  data_hist->SetTitle(("data_" + GetSampleTitle(iSample)).c_str());
1310  data_hist->Write();
1311  }
1312 }
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 SampleHandlerFD::SetBinning ( )
protected

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

Definition at line 738 of file SampleHandlerFD.cpp.

738  {
739 // ************************************************
740  for(int iSample = 0; iSample < GetNsamples(); iSample++)
741  {
742  int Dimension = GetNDim(iSample);
743  std::string HistTitle = GetSampleTitle(iSample);
744 
745  auto* SamDet = &SampleDetails[iSample];
746  if(Dimension == 1) {
747  auto XVec = Binning->GetBinEdges(iSample, 0);
748  SamDet->DataHist = new TH1D(("d" + HistTitle).c_str(), HistTitle.c_str(), static_cast<int>(XVec.size()-1), XVec.data());
749  SamDet->MCHist = new TH1D(("h" + HistTitle).c_str(), HistTitle.c_str(), static_cast<int>(XVec.size()-1), XVec.data());
750  SamDet->W2Hist = new TH1D(("w" + HistTitle).c_str(), HistTitle.c_str(), static_cast<int>(XVec.size()-1), XVec.data());
751 
752  // Set all titles so most of projections don't have empty titles...
753  SamDet->DataHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
754  SamDet->DataHist->GetYaxis()->SetTitle("Events");
755  SamDet->MCHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
756  SamDet->MCHist->GetYaxis()->SetTitle("Events");
757  SamDet->W2Hist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
758  SamDet->W2Hist->GetYaxis()->SetTitle("Events");
759  } else if (Dimension == 2){
760  if(Binning->IsUniform(iSample)) {
761  auto XVec = Binning->GetBinEdges(iSample, 0);
762  auto YVec = Binning->GetBinEdges(iSample, 1);
763  int nX = static_cast<int>(XVec.size() - 1);
764  int nY = static_cast<int>(YVec.size() - 1);
765 
766  SamDet->DataHist = new TH2D(("d" + HistTitle).c_str(), HistTitle.c_str(), nX, XVec.data(), nY, YVec.data());
767  SamDet->MCHist = new TH2D(("h" + HistTitle).c_str(), HistTitle.c_str(), nX, XVec.data(), nY, YVec.data());
768  SamDet->W2Hist = new TH2D(("w" + HistTitle).c_str(), HistTitle.c_str(), nX, XVec.data(), nY, YVec.data());
769  } else {
770  auto AddBinsToTH2Poly = [](TH2Poly* hist, const std::vector<BinInfo>& bins) {
771  for (const auto& bin : bins) {
772  double xLow = bin.Extent[0][0];
773  double xHigh = bin.Extent[0][1];
774  double yLow = bin.Extent[1][0];
775  double yHigh = bin.Extent[1][1];
776 
777  double x[4] = {xLow, xHigh, xHigh, xLow};
778  double y[4] = {yLow, yLow, yHigh, yHigh};
779 
780  hist->AddBin(4, x, y);
781  }
782  };
783  // Create all three histograms
784  SamDet->DataHist = new TH2Poly();
785  SamDet->DataHist->SetName(("d" + HistTitle).c_str());
786  SamDet->DataHist->SetTitle(HistTitle.c_str());
787 
788  SamDet->MCHist = new TH2Poly();
789  SamDet->MCHist->SetName(("h" + HistTitle).c_str());
790  SamDet->MCHist->SetTitle(HistTitle.c_str());
791 
792  SamDet->W2Hist = new TH2Poly();
793  SamDet->W2Hist->SetName(("w" + HistTitle).c_str());
794  SamDet->W2Hist->SetTitle(HistTitle.c_str());
795 
796  // Add bins to each
797  AddBinsToTH2Poly(static_cast<TH2Poly*>(SamDet->DataHist), Binning->GetNonUniformBins(iSample));
798  AddBinsToTH2Poly(static_cast<TH2Poly*>(SamDet->MCHist), Binning->GetNonUniformBins(iSample));
799  AddBinsToTH2Poly(static_cast<TH2Poly*>(SamDet->W2Hist), Binning->GetNonUniformBins(iSample));
800  }
801 
802  // Set all titles so most of projections don't have empty titles...
803  SamDet->DataHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
804  SamDet->DataHist->GetYaxis()->SetTitle(SamDet->VarStr[1].c_str());
805  SamDet->MCHist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
806  SamDet->MCHist->GetYaxis()->SetTitle(SamDet->VarStr[1].c_str());
807  SamDet->W2Hist->GetXaxis()->SetTitle(SamDet->VarStr[0].c_str());
808  SamDet->W2Hist->GetYaxis()->SetTitle(SamDet->VarStr[1].c_str());
809  } else {
810  int nbins = Binning->GetNBins(iSample);
811  SamDet->DataHist = new TH1D(("d" + HistTitle).c_str(), HistTitle.c_str(), nbins, 0, nbins);
812  SamDet->MCHist = new TH1D(("h" + HistTitle).c_str(), HistTitle.c_str(), nbins, 0, nbins);
813  SamDet->W2Hist = new TH1D(("w" + HistTitle).c_str(), HistTitle.c_str(), nbins, 0, nbins);
814 
815  for(int iBin = 0; iBin < nbins; iBin++) {
816  auto BinName = Binning->GetBinName(iSample, iBin);
817  SamDet->DataHist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
818  SamDet->MCHist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
819  SamDet->W2Hist->GetXaxis()->SetBinLabel(iBin+1, BinName.c_str());
820  }
821 
822  // Set all titles so most of projections don't have empty titles...
823  SamDet->DataHist->GetYaxis()->SetTitle("Events");
824  SamDet->MCHist->GetYaxis()->SetTitle("Events");
825  SamDet->W2Hist->GetYaxis()->SetTitle("Events");
826  }
827 
828  SamDet->DataHist->SetDirectory(nullptr);
829  SamDet->MCHist->SetDirectory(nullptr);
830  SamDet->W2Hist->SetDirectory(nullptr);
831  }
832 
833  //Set the number of X and Y bins now
836 }
void SetupReweightArrays()
Initialise data, MC and W2 histograms.

◆ SetSplinePointers()

void SampleHandlerFD::SetSplinePointers ( )
protected

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

Todo:
Fix this mess :(

Definition at line 1169 of file SampleHandlerFD.cpp.

1169  {
1170 // ************************************************
1171  //Now loop over events and get the spline bin for each event
1172  if (auto BinnedSpline = dynamic_cast<BinnedSplineHandler*>(SplineHandler.get())) {
1173  bool ThrowCrititcal = true;
1174  for (unsigned int j = 0; j < GetNEvents(); ++j) {
1175  const int SampleIndex = MCSamples[j].NominalSample;
1176  const auto SampleTitle = GetSampleTitle(SampleIndex);
1177  const int OscIndex = GetOscChannel(SampleDetails[SampleIndex].OscChannels, (*MCSamples[j].nupdgUnosc), (*MCSamples[j].nupdg));
1178  const int Mode = int(*(MCSamples[j].mode));
1179  const double Etrue = *(MCSamples[j].rw_etru);
1180  std::vector< std::vector<int> > EventSplines;
1181  switch(GetNDim(SampleIndex)) {
1182  case 1:
1183  EventSplines = BinnedSpline->GetEventSplines(SampleTitle, OscIndex, Mode, Etrue, *(MCSamples[j].KinVar[0]), 0.);
1184  break;
1185  case 2:
1186  EventSplines = BinnedSpline->GetEventSplines(SampleTitle, OscIndex, Mode, Etrue, *(MCSamples[j].KinVar[0]), *(MCSamples[j].KinVar[1]));
1187  break;
1188  default:
1189  if(ThrowCrititcal) {
1190  MACH3LOG_CRITICAL("MaCh3 doesn't support binned splines for more than 2D while you use {}", GetNDim(SampleIndex));
1191  MACH3LOG_CRITICAL("Will use 2D like approach");
1192  ThrowCrititcal = false;
1193  }
1194  EventSplines = BinnedSpline->GetEventSplines(SampleTitle, OscIndex, Mode, Etrue, *(MCSamples[j].KinVar[0]), *(MCSamples[j].KinVar[1]));
1195  break;
1196  }
1197  const int NSplines = static_cast<int>(EventSplines.size());
1198  if(NSplines == 0) continue;
1199  const int PointersBefore = static_cast<int>(MCSamples[j].total_weight_pointers.size());
1200  MCSamples[j].total_weight_pointers.resize(PointersBefore + NSplines);
1201 
1202  for(int spline = 0; spline < NSplines; spline++) {
1203  //Event Splines indexed as: sample name, oscillation channel, syst, mode, etrue, var1, var2 (var2 is a dummy 0 for 1D splines)
1204  MCSamples[j].total_weight_pointers[PointersBefore+spline] = BinnedSpline->retPointer(EventSplines[spline][0], EventSplines[spline][1],
1205  EventSplines[spline][2], EventSplines[spline][3],
1206  EventSplines[spline][4], EventSplines[spline][5],
1207  EventSplines[spline][6]);
1208  } // end loop over splines
1209  } // end loop over events
1210  } else if (auto UnbinnedSpline = dynamic_cast<SMonolith*>(SplineHandler.get())) {
1212  #ifdef _LOW_MEMORY_STRUCTS_
1213  for (unsigned int iEvent = 0; iEvent < GetNEvents(); ++iEvent) {
1214  MCSamples[iEvent].total_weight_pointers.push_back(UnbinnedSpline->retPointer(iEvent));
1215  }
1216  #else
1217  (void) UnbinnedSpline;
1218  MACH3LOG_ERROR("Unbinned splines only for float :(");
1219  throw MaCh3Exception(__FILE__, __LINE__);
1220  #endif
1221  } else {
1222  MACH3LOG_ERROR("Not supported splines");
1223  throw MaCh3Exception(__FILE__, __LINE__);
1224  }
1225 }

◆ SetupExperimentMC()

virtual int SampleHandlerFD::SetupExperimentMC ( )
protectedpure virtual

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

Implemented in PySampleHandlerFD.

◆ SetupFDMC()

virtual void SampleHandlerFD::SetupFDMC ( )
protectedpure virtual

Function which translates experiment struct into core struct.

Implemented in PySampleHandlerFD.

◆ SetupFunctionalParameters()

void SampleHandlerFD::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 503 of file SampleHandlerFD.cpp.

503  {
504 // **************************************************
506  // RegisterFunctionalParameters is implemented in experiment-specific code,
507  // which calls RegisterIndividualFuncPar to populate funcParsNamesMap, funcParsNamesVec, and funcParsFuncMap
509  funcParsMap.resize(funcParsNamesMap.size());
510  funcParsGrid.resize(GetNEvents());
511 
512  // For every functional parameter in XsecCov that matches the name in funcParsNames, add it to the map
513  for (FunctionalParameter& fp : funcParsVec) {
514  auto it = funcParsNamesMap.find(fp.name);
515  // If we don't find a match, we need to throw an error
516  if (it == funcParsNamesMap.end()) {
517  MACH3LOG_ERROR("Functional parameter {} not found, did you define it in RegisterFunctionalParameters()?", fp.name);
518  throw MaCh3Exception(__FILE__, __LINE__);
519  }
520  const std::size_t key = static_cast<std::size_t>(it->second);
521  MACH3LOG_INFO("Adding functional parameter: {} to funcParsMap with key: {}",fp.name, key);
522 
523  const int ikey = it->second;
524  fp.funcPtr = &funcParsFuncMap[ikey];
525 
526  funcParsMap[key].valuePtr = fp.valuePtr;
527  funcParsMap[key].funcPtr = fp.funcPtr;
528  }
529 
530  // Mostly the same as CalcNormsBins
531  // For each event, make a vector of pointers to the functional parameters
532  for (std::size_t iEvent = 0; iEvent < static_cast<std::size_t>(GetNEvents()); ++iEvent) {
533  // Now loop over the functional parameters and get a vector of enums corresponding to the functional parameters
534  for (std::vector<FunctionalParameter>::iterator it = funcParsVec.begin(); it != funcParsVec.end(); ++it) {
535  // Check whether the interaction modes match
536  bool ModeMatch = MatchCondition((*it).modes, static_cast<int>(std::round(*(MCSamples[iEvent].mode))));
537  if (!ModeMatch) {
538  MACH3LOG_TRACE("Event {}, missed Mode check ({}) for dial {}", iEvent, *(MCSamples[iEvent].mode), (*it).name);
539  continue;
540  }
541  // Now check whether within kinematic bounds
542  bool IsSelected = PassesSelection((*it), iEvent);
543  // Need to then break the event loop
544  if(!IsSelected){
545  MACH3LOG_TRACE("Event {}, missed Kinematic var check for dial {}", iEvent, (*it).name);
546  continue;
547  }
548  const std::size_t key = static_cast<std::size_t>(funcParsNamesMap[it->name]);
549  funcParsGrid[iEvent].push_back(&funcParsMap[key]);
550  }
551  }
552  MACH3LOG_INFO("Finished setting up functional parameters");
553 
556 
557  funcParsNamesMap.clear();
558  funcParsNamesMap.rehash(0);
559 }
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< FunctionalParameter > funcParsVec
HH - a vector that stores all the FuncPars struct.
std::vector< FunctionalShifter > funcParsMap
HH - a map that relates the funcpar enum to pointer of FuncPars struct HH - Changed to a vector of po...
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 SampleHandlerFD::SetupKinematicMap ( )
protected

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

Definition at line 227 of file SampleHandlerFD.cpp.

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

◆ SetupNormParameters()

void SampleHandlerFD::SetupNormParameters ( )
protected

Setup the norm parameters by assigning each event with bin.

Definition at line 613 of file SampleHandlerFD.cpp.

613  {
614 // ***************************************************************************
615  std::vector< std::vector< int > > norms_bins(GetNEvents());
616 
617  std::vector<NormParameter> norm_parameters = ParHandler->GetNormParsFromSampleName(GetName());
618 
619  if(!ParHandler){
620  MACH3LOG_ERROR("ParHandler is not setup!");
621  throw MaCh3Exception(__FILE__ , __LINE__ );
622  }
623 
624  // Assign norm bins in MCSamples tree
625  CalcNormsBins(norm_parameters, norms_bins);
626 
627  //DB Attempt at reducing impact of SystematicHandlerGeneric::calcReweight()
628  int counter;
629  for (unsigned int iEvent = 0; iEvent < GetNEvents(); ++iEvent) {
630  counter = 0;
631 
632  MCSamples[iEvent].norm_pointers.resize(norms_bins[iEvent].size());
633  for(auto const & norm_bin: norms_bins[iEvent]) {
634  MCSamples[iEvent].norm_pointers[counter] = ParHandler->RetPointer(norm_bin);
635  counter += 1;
636  }
637  }
638 }
const double * RetPointer(const int iParam)
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< NormParameter > &norm_parameters, std::vector< std::vector< int > > &norms_bins)
Check whether a normalisation systematic affects an event or not.

◆ SetupNuOscillatorPointers()

void SampleHandlerFD::SetupNuOscillatorPointers ( )

Definition at line 1081 of file SampleHandlerFD.cpp.

1081  {
1082  auto AddOscPointer = GetFromManager<bool>(SampleManager->raw()["NuOsc"]["AddOscPointer"], true, __FILE__ , __LINE__);
1083  // 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
1084  if(!AddOscPointer) {
1085  return;
1086  }
1087  for (unsigned int iEvent=0;iEvent<GetNEvents();iEvent++) {
1088  const M3::float_t* osc_w_pointer = GetNuOscillatorPointers(iEvent);
1089 
1090  // KS: Do not add unity
1091  if (osc_w_pointer != &M3::Unity) {
1092  MCSamples[iEvent].total_weight_pointers.push_back(osc_w_pointer);
1093  }
1094  }
1095 }
const M3::float_t * GetNuOscillatorPointers(const int iEvent) const

◆ SetupReweightArrays()

void SampleHandlerFD::SetupReweightArrays ( )
protected

Initialise data, MC and W2 histograms.

Definition at line 724 of file SampleHandlerFD.cpp.

724  {
725 // ************************************************
726  SampleHandlerFD_array = new double[Binning->GetNBins()];
727  SampleHandlerFD_array_w2 = new double[Binning->GetNBins()];
728  SampleHandlerFD_data = new double[Binning->GetNBins()];
729 
730  for (int i = 0; i < Binning->GetNBins(); ++i) {
731  SampleHandlerFD_array[i] = 0.0;
732  SampleHandlerFD_array_w2[i] = 0.0;
733  SampleHandlerFD_data[i] = 0.0;
734  }
735 }

◆ SetupSplines()

virtual void SampleHandlerFD::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 PySampleHandlerFD.

Member Data Documentation

◆ _modeNomWeightMap

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

Definition at line 382 of file SampleHandlerFD.h.

◆ Binning

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

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

Definition at line 329 of file SampleHandlerFD.h.

◆ FileToFinalPDGMap

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

Definition at line 401 of file SampleHandlerFD.h.

◆ FileToInitPDGMap

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

Definition at line 400 of file SampleHandlerFD.h.

◆ FirstTimeW2

bool SampleHandlerFD::FirstTimeW2
protected

KS:Super hacky to update W2 or not.

Definition at line 390 of file SampleHandlerFD.h.

◆ funcParsFuncMap

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

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

Definition at line 269 of file SampleHandlerFD.h.

◆ funcParsGrid

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

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

Definition at line 252 of file SampleHandlerFD.h.

◆ funcParsMap

std::vector<FunctionalShifter> SampleHandlerFD::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 257 of file SampleHandlerFD.h.

◆ funcParsNamesMap

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

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

Definition at line 266 of file SampleHandlerFD.h.

◆ funcParsNamesVec

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

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

Definition at line 271 of file SampleHandlerFD.h.

◆ funcParsVec

std::vector<FunctionalParameter> SampleHandlerFD::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 263 of file SampleHandlerFD.h.

◆ KinematicParameters

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

Mapping between string and kinematic enum.

Definition at line 369 of file SampleHandlerFD.h.

◆ KinematicVectors

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

Definition at line 374 of file SampleHandlerFD.h.

◆ MCSamples

std::vector<EventInfo> SampleHandlerFD::MCSamples
protected

Stores information about every MC event.

Definition at line 340 of file SampleHandlerFD.h.

◆ Oscillator

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

Contains oscillator handling calculating oscillation probabilities.

Definition at line 217 of file SampleHandlerFD.h.

◆ ParHandler

ParameterHandlerGeneric* SampleHandlerFD::ParHandler = nullptr
protected

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

Definition at line 348 of file SampleHandlerFD.h.

◆ ReversedKinematicParameters

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

Mapping between kinematic enum and string.

Definition at line 371 of file SampleHandlerFD.h.

◆ ReversedKinematicVectors

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

Definition at line 375 of file SampleHandlerFD.h.

◆ SampleDetails

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

Stores info about currently initialised sample.

Definition at line 342 of file SampleHandlerFD.h.

◆ SampleHandlerFD_array

double* SampleHandlerFD::SampleHandlerFD_array
protected

DB Array to be filled after reweighting.

Definition at line 331 of file SampleHandlerFD.h.

◆ SampleHandlerFD_array_w2

double* SampleHandlerFD::SampleHandlerFD_array_w2
protected

KS Array used for MC stat.

Definition at line 333 of file SampleHandlerFD.h.

◆ SampleHandlerFD_data

double* SampleHandlerFD::SampleHandlerFD_data
protected

DB Array to be filled in AddData.

Definition at line 335 of file SampleHandlerFD.h.

◆ SampleHandlerName

std::string SampleHandlerFD::SampleHandlerName
protected

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

Definition at line 352 of file SampleHandlerFD.h.

◆ SampleManager

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

The manager object used to read the sample yaml file.

Definition at line 379 of file SampleHandlerFD.h.

◆ Selection

std::vector< std::vector< KinematicCut > > SampleHandlerFD::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 365 of file SampleHandlerFD.h.

◆ SplineHandler

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

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

Definition at line 214 of file SampleHandlerFD.h.

◆ StoredSelection

std::vector< std::vector< KinematicCut > > SampleHandlerFD::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 362 of file SampleHandlerFD.h.

◆ THStackLeg

TLegend* SampleHandlerFD::THStackLeg = nullptr
protected

DB Miscellaneous Variables.

Definition at line 386 of file SampleHandlerFD.h.

◆ UpdateW2

bool SampleHandlerFD::UpdateW2
protected

KS:Super hacky to update W2 or not.

Definition at line 392 of file SampleHandlerFD.h.


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