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

Bin-by-bin class calculating response for spline parameters. More...

#include <Splines/BinnedSplineHandler.h>

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

Public Member Functions

 BinnedSplineHandler (ParameterHandlerGeneric *ParamHandler, MaCh3Modes *Modes_, const bool Use_GPU=true)
 Constructor. More...
 
virtual ~BinnedSplineHandler ()
 Destructor. More...
 
void Evaluate () final
 CW: This Eval should be used when using two separate x,{y,a,b,c,d} arrays to store the weights; probably the best one here! Same thing but pass parameter spline segments instead of variations. More...
 
void AddSample (const std::string &SampleName, const std::string &SampleTitle, const std::vector< std::string > &OscChanFileNames, const std::vector< std::string > &SplineVarNames)
 add oscillation channel to spline monolith More...
 
void TransferToMonolith ()
 flatten multidimensional spline array into proper monolith More...
 
void CleanUpMemory ()
 Remove setup variables not needed for spline evaluations. More...
 
virtual void FillSampleArray (const std::string &SampleTitle, const std::vector< std::string > &OscChanFileNames)
 Loads and processes splines from ROOT files for a given sample. More...
 
std::vector< SplineIndex > GetEventSplines (const std::string &SampleTitle, int iOscChan, int EventMode, const std::vector< double > &VarVals)
 Return the splines which affect a given event. More...
 
int CountNumberOfLoadedSplines (bool NonFlat=false, int Verbosity=0) const
 Count how many splines we have. More...
 
const M3::float_t * RetPointer (const SplineIndex &Variables) const
 get pointer to spline weight based on bin variables More...
 
void PrepareSplineFile (std::string FileName) final
 KS: Prepare spline file that can be used for fast loading. More...
 
void LoadSplineFile (std::string FileName) final
 KS: Load preprocessed spline file. More...
 
- Public Member Functions inherited from SplineBase
 SplineBase (const bool Use_GPU=true)
 Constructor. More...
 
virtual ~SplineBase ()
 Destructor. More...
 
virtual std::string GetName () const
 Get class name. More...
 
short int GetNParams () const
 Get number of spline parameters. More...
 
void SynchroniseMemTransfer () const
 KS: After calculations are done on GPU we copy memory to CPU. This operation is asynchronous meaning while memory is being copied some operations are being carried. Memory must be copied before actual reweight. This function make sure all has been copied. More...
 

Protected Types

enum  TokenOrdering { kSystToken , kModeToken , kVarBinToken }
 

Protected Member Functions

void CalcSplineWeights () final
 CPU based code which eval weight for each spline. More...
 
void PrepForReweight ()
 Initialise flat structure. More...
 
void BuildSampleIndexingArray (const std::string &SampleTitle)
 Only need 1 indexing array everything else interfaces with this to get binning properties. More...
 
std::vector< TAxis * > FindSplineBinning (const std::string &FileName, const std::string &SampleTitle)
 Grab histograms with spline binning. More...
 
void PrintBinning (TAxis *Axis) const
 Print spline binning. More...
 
void PrintSampleDetails (const std::string &SampleTitle) const
 Print info like Sample ID of spline params etc. More...
 
void PrintArrayDetails (const std::string &SampleTitle) const
 Print info like Sample ID of spline params etc. More...
 
int GetSampleIndex (const std::string &SampleTitle) const
 Get index of sample based on name. More...
 
bool isValidSplineIndex (const std::string &SampleTitle, int iSyst, int iOscChan, int iMode, const std::vector< int > &iVar) const
 Ensure we have spline for a given bin. More...
 
std::vector< std::vector< int > > StripDuplicatedModes (const std::vector< std::vector< int > > &InputVector) const
 Creates an array to be filled with monolith indexes for each sample (allows for indexing between 7D binning and 1D Vector). More...
 
void GetSplineCoeff_SepMany (int splineindex, M3::float_t *&xArray, M3::float_t *&manyArray)
 Rather work with spline coefficients in the splines, let's copy ND and use coefficient arrays. More...
 
virtual std::vector< std::string > GetTokensFromSplineName (const std::string &FullSplineName)=0
 Extract metadata tokens encoded in a spline name. allows experiment to have different formats of splines. More...
 
- Protected Member Functions inherited from SplineBase
void FindSplineSegment ()
 CW:Code used in step by step reweighting, Find Spline Segment for each param. More...
 
void PrepareFastSplineInfoDir (std::unique_ptr< TFile > &SplineFile) const
 KS: Prepare Fast Spline Info within SplineFile. More...
 
void LoadFastSplineInfoDir (std::unique_ptr< TFile > &SplineFile)
 KS: Load preprocessed FastSplineInfo. More...
 
void GetTF1Coeff (TF1_red *&spl, int &nPoints, float *&coeffs) const
 CW: Gets the polynomial coefficients for TF1. More...
 
void SetupSegments ()
 Since we find segment before actual reweight and sometimes we want to copy it to GPU we have different functionality depending if GPU or CPU. More...
 

Protected Attributes

ParameterHandlerGeneric * ParHandler
 Pointer to covariance from which we get information about spline params. More...
 
std::vector< std::string > SampleNames
 
std::vector< std::string > SampleTitles
 
std::vector< int > Dimensions
 
std::vector< std::vector< std::string > > DimensionLabels
 
std::vector< int > nSplineParams
 
std::vector< int > nOscChans
 
std::vector< std::vector< std::vector< TAxis * > > > SplineBinning
 Holds TAxis for [sample][channel][dimension]. More...
 
std::vector< std::vector< std::string > > SplineFileParPrefixNames
 [Sample][Syst] More...
 
std::vector< std::vector< std::vector< int > > > SplineModeVecs
 
std::vector< std::vector< int > > GlobalSystIndex
 This holds the global spline index and is used to grab the current parameter value to evaluate splines at. Each internal vector will be of size of the number of spline systematics which affect that sample. More...
 
std::vector< std::vector< SplineInterpolation > > SplineInterpolationTypes
 spline interpolation types for each sample. These vectors are from a call to GetSplineInterpolationFromSampleID() More...
 
std::vector< std::string > UniqueSystNames
 name of each spline parameter More...
 
std::vector< int > UniqueSystIndices
 Global index of each spline param, it allows us to match spline ordering with global. More...
 
std::vector< SplineIndex > IndexVect
 Variables related to determined which modes have splines and which piggy-back of other modes. More...
 
std::map< std::tuple< int, int, int, int, std::vector< int > >, int > IndexVectMap
 Map between spline origin/properties (iSample, iOscChan, iSyst, iMode, iVar1, iVar2, iVar3) and the index of the spline in IndexVect. More...
 
std::vector< unsigned int > nKnots_arr
 KS: CPU Number of knots per spline. More...
 
std::vector< TSpline3_red * > splinevec_Monolith
 holds each spline object before stripping into coefficient monolith More...
 
unsigned int MonolithIndex
 
int CoeffIndex
 
std::vector< int > monolith_index
 keep track which splines are flat (-1) otherwise map with flattened splines More...
 
M3::float_t * xcoeff_arr
 x coefficients for each spline More...
 
M3::float_t * manycoeff_arr
 ybcd coefficients for each spline More...
 
std::vector< M3::float_t > cpu_spline_weights
 Stores weight from spline evaluation for each single spline. More...
 
std::vector< short int > paramNo_arr
 CW: CPU array with the number of points per spline (not per spline point!) More...
 
MaCh3Modes * Modes
 pointer to MaCh3 Mode from which we get spline suffix More...
 
- Protected Attributes inherited from SplineBase
std::vector< FastSplineInfo > SplineInfoArray
 
short int * SplineSegments
 
float * ParamValues
 Store parameter values they are not in FastSplineInfo as in case of GPU we need to copy paste it to GPU. More...
 
short int nParams
 Number of parameters that have splines. More...
 
short int _max_knots
 Max knots for production. More...
 
unsigned int NSplines_valid
 Number of valid splines. More...
 
SplineMonolithGPU * gpu_monolith
 KS: Store info about Spline monolith, this allow to obtain better step time. As all necessary information for spline weight calculation are here meaning better cache hits. More...
 
bool useGPU
 Whether to use GPU or not. More...
 

Private Member Functions

void MoveToGPU ()
 CW: The shared initialiser from constructors of TResponseFunction_red. More...
 
void InvestigateMissingSplines () const
 This function will find missing splines in file. More...
 
void LoadSettingsDir (std::unique_ptr< TFile > &SplineFile)
 KS: Load preprocessed Settings. More...
 
void LoadMonolithDir (std::unique_ptr< TFile > &SplineFile)
 KS: Load preprocessed Monolith. More...
 
void LoadIndexDir (std::unique_ptr< TFile > &SplineFile)
 KS: Load preprocessed Index. More...
 
void PrepareSettingsDir (std::unique_ptr< TFile > &SplineFile) const
 KS: Prepare Settings Info within SplineFile. More...
 
void PrepareMonolithDir (std::unique_ptr< TFile > &SplineFile) const
 KS: Prepare Monolith Info within SplineFile. More...
 
void PrepareIndexDir (std::unique_ptr< TFile > &SplineFile) const
 KS: Prepare Index Info within SplineFile. More...
 
void PrepareOtherInfoDir (std::unique_ptr< TFile > &SplineFile) const
 KS: Prepare Other Info within SplineFile. More...
 

Detailed Description

Bin-by-bin class calculating response for spline parameters.

Author
Dan Barrow
Ed Atkin
Henry Wallace

Definition at line 11 of file BinnedSplineHandler.h.

Member Enumeration Documentation

◆ TokenOrdering

Enumerator
kSystToken 
kModeToken 
kVarBinToken 

Definition at line 132 of file BinnedSplineHandler.h.

Constructor & Destructor Documentation

◆ BinnedSplineHandler()

_MaCh3_Safe_Include_Start_ _MaCh3_Safe_Include_End_ BinnedSplineHandler::BinnedSplineHandler ( ParameterHandlerGeneric *  ParamHandler,
MaCh3Modes *  Modes_,
const bool  Use_GPU = true 
)

Constructor.

Definition at line 17 of file BinnedSplineHandler.cpp.

17  : SplineBase(Use_GPU) {
18 //****************************************
19  if (!ParHandler_) {
20  MACH3LOG_ERROR("Trying to create BinnedSplineHandler with uninitialized covariance object");
21  throw MaCh3Exception(__FILE__, __LINE__);
22  }
23  ParHandler = ParHandler_;
24 
25  if (!Modes_) {
26  MACH3LOG_ERROR("Trying to create BinnedSplineHandler with uninitialized MaCh3Modes object");
27  throw MaCh3Exception(__FILE__, __LINE__);
28  }
29  Modes = Modes_;
30 
31  // Keep these in class scope, important for using 1 monolith/sample!
32  MonolithIndex = 0; //Keeps track of the monolith index we're on when filling arrays (declared here so we can have multiple FillSampleArray calls)
33  CoeffIndex = 0; //Keeps track of our indexing the coefficient arrays [x, ybcd]
34 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
ParameterHandlerGeneric * ParHandler
Pointer to covariance from which we get information about spline params.
MaCh3Modes * Modes
pointer to MaCh3 Mode from which we get spline suffix
Custom exception class used throughout MaCh3.
SplineBase(const bool Use_GPU=true)
Constructor.
Definition: SplineBase.cpp:11

◆ ~BinnedSplineHandler()

BinnedSplineHandler::~BinnedSplineHandler ( )
virtual

Destructor.

Definition at line 37 of file BinnedSplineHandler.cpp.

37  {
38 //****************************************
39  if(manycoeff_arr != nullptr) delete[] manycoeff_arr;
40  if(xcoeff_arr != nullptr) delete[] xcoeff_arr;
41  #ifdef MaCh3_CUDA
42  if (useGPU) {
43  //KS: Since we declared them using CUDA alloc we have to free memory using also cuda functions
45  delete gpu_monolith;
46  } else
47  #endif
48  {
49  if(SplineSegments != nullptr) delete[] SplineSegments;
50  if(ParamValues != nullptr) delete[] ParamValues;
51  }
52 }
M3::float_t * xcoeff_arr
x coefficients for each spline
M3::float_t * manycoeff_arr
ybcd coefficients for each spline
SplineMonolithGPU * gpu_monolith
KS: Store info about Spline monolith, this allow to obtain better step time. As all necessary informa...
Definition: SplineBase.h:120
short int * SplineSegments
Definition: SplineBase.h:109
float * ParamValues
Store parameter values they are not in FastSplineInfo as in case of GPU we need to copy paste it to G...
Definition: SplineBase.h:111
bool useGPU
Whether to use GPU or not.
Definition: SplineBase.h:123
__host__ void CleanupPinnedMemory(M3::float_t *cpu_total_weights, short int *segment, float *vals)
Clean up pinned variables at CPU.

Member Function Documentation

◆ AddSample()

void BinnedSplineHandler::AddSample ( const std::string &  SampleName,
const std::string &  SampleTitle,
const std::vector< std::string > &  OscChanFileNames,
const std::vector< std::string > &  SplineVarNames 
)

add oscillation channel to spline monolith

Definition at line 81 of file BinnedSplineHandler.cpp.

84  {
85 //****************************************
86  SampleNames.push_back(SampleName);
87  SampleTitles.push_back(SampleTitle);
88  Dimensions.push_back(static_cast<int>(SplineVarNames.size()));
89  DimensionLabels.push_back(SplineVarNames);
90 
91  int nSplineParam = ParHandler->GetNumParamsFromSampleName(SampleName, SystType::kSpline);
92  nSplineParams.push_back(nSplineParam);
93 
94  //This holds the global index of the spline i.e. 0 -> _fNumPar
95  std::vector<int> GlobalSystIndex_Sample = ParHandler->GetGlobalSystIndexFromSampleName(SampleName, SystType::kSpline);
96  //Keep track of this for all the samples
97  GlobalSystIndex.push_back(GlobalSystIndex_Sample);
98 
99  std::vector<SplineInterpolation> SplineInterpolation_Sample = ParHandler->GetSplineInterpolationFromSampleName(SampleName);
100  // Keep track of this for all samples
101  SplineInterpolationTypes.push_back(SplineInterpolation_Sample);
102 
103  std::vector<std::string> SplineFileParPrefixNames_Sample = ParHandler->GetSplineParsNamesFromSampleName(SampleName);
104  SplineFileParPrefixNames.push_back(SplineFileParPrefixNames_Sample);
105 
106  MACH3LOG_INFO("Create SplineModeVecs_Sample");
107  std::vector<std::vector<int>> SplineModeVecs_Sample = StripDuplicatedModes(ParHandler->GetSplineModeVecFromSampleName(SampleName));
108  MACH3LOG_INFO("SplineModeVecs_Sample is of size {}", SplineModeVecs_Sample.size());
109  SplineModeVecs.push_back(SplineModeVecs_Sample);
110 
111  MACH3LOG_INFO("SplineModeVecs is of size {}", SplineModeVecs.size());
112 
113  int nOscChan = int(OscChanFileNames.size());
114  nOscChans.push_back(nOscChan);
115 
116  PrintSampleDetails(SampleTitle);
117 
118  std::vector<std::vector<TAxis *>> SampleBinning(nOscChan);
119  for (int iOscChan = 0; iOscChan < nOscChan; iOscChan++)
120  {
121  SampleBinning[iOscChan] = FindSplineBinning(OscChanFileNames[iOscChan], SampleTitle);
122  }
123  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
124  SplineBinning.push_back(SampleBinning);
125 
126  BuildSampleIndexingArray(SampleTitle);
127  PrintArrayDetails(SampleTitle);
128  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
129 
130  FillSampleArray(SampleTitle, OscChanFileNames);
131  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
132 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
@ kSpline
For splined parameters (1D)
virtual void FillSampleArray(const std::string &SampleTitle, const std::vector< std::string > &OscChanFileNames)
Loads and processes splines from ROOT files for a given sample.
std::vector< std::vector< std::string > > SplineFileParPrefixNames
[Sample][Syst]
std::vector< int > nSplineParams
std::vector< std::vector< std::vector< int > > > SplineModeVecs
std::vector< int > nOscChans
std::vector< std::string > SampleTitles
void PrintSampleDetails(const std::string &SampleTitle) const
Print info like Sample ID of spline params etc.
std::vector< std::vector< SplineInterpolation > > SplineInterpolationTypes
spline interpolation types for each sample. These vectors are from a call to GetSplineInterpolationFr...
std::vector< int > Dimensions
void BuildSampleIndexingArray(const std::string &SampleTitle)
Only need 1 indexing array everything else interfaces with this to get binning properties.
std::vector< TAxis * > FindSplineBinning(const std::string &FileName, const std::string &SampleTitle)
Grab histograms with spline binning.
std::vector< std::vector< std::string > > DimensionLabels
std::vector< std::vector< int > > StripDuplicatedModes(const std::vector< std::vector< int > > &InputVector) const
Creates an array to be filled with monolith indexes for each sample (allows for indexing between 7D b...
std::vector< std::vector< std::vector< TAxis * > > > SplineBinning
Holds TAxis for [sample][channel][dimension].
void PrintArrayDetails(const std::string &SampleTitle) const
Print info like Sample ID of spline params etc.
std::vector< std::vector< int > > GlobalSystIndex
This holds the global spline index and is used to grab the current parameter value to evaluate spline...
std::vector< std::string > SampleNames
int GetNumParamsFromSampleName(const std::string &SampleName, const SystType Type) const
DB Grab the number of parameters for the relevant SampleName.
const std::vector< std::string > GetSplineParsNamesFromSampleName(const std::string &SampleName) const
DB Get spline parameters depending on given SampleName.
const std::vector< int > GetGlobalSystIndexFromSampleName(const std::string &SampleName, const SystType Type) const
DB Get spline parameters depending on given SampleName.
const std::vector< SplineInterpolation > GetSplineInterpolationFromSampleName(const std::string &SampleName) const
Get the interpolation types for splines affecting a particular SampleName.
const std::vector< std::vector< int > > GetSplineModeVecFromSampleName(const std::string &SampleName) const
DB Grab the Spline Modes for the relevant SampleName.

◆ BuildSampleIndexingArray()

void BinnedSplineHandler::BuildSampleIndexingArray ( const std::string &  SampleTitle)
protected

Only need 1 indexing array everything else interfaces with this to get binning properties.

Definition at line 340 of file BinnedSplineHandler.cpp.

340  {
341 //****************************************
342  int iSample = GetSampleIndex(SampleTitle);
343  for (int iOscChan = 0; iOscChan < nOscChans[iSample]; ++iOscChan)
344  {
345  for (int iSyst = 0; iSyst < nSplineParams[iSample]; ++iSyst)
346  {
347  int nModesInSyst = static_cast<int>(SplineModeVecs[iSample][iSyst].size());
348  for (int iMode = 0; iMode < nModesInSyst; ++iMode)
349  {
350  const int nDims = static_cast<int>(SplineBinning[iSample][iOscChan].size());
351  std::vector<int> nBins(nDims);
352  for (int iDim = 0; iDim < nDims; ++iDim) {
353  nBins[iDim] = SplineBinning[iSample][iOscChan][iDim]->GetNbins();
354  }
355  // Current bin index for each dimension, e.g. {0,0,0} for a 3D spline.
356  std::vector<int> iVar(nDims, 0);
357  // Loop over every possible combination of kinematic bins.
358  while (true)
359  {
360  SplineIndex entry;
361  entry.value = -1;
362  entry.iSample = iSample;
363  entry.iOscChan = iOscChan;
364  entry.iSyst = iSyst;
365  entry.iMode = iMode;
366  entry.iVar = iVar;
367 
368  IndexVect.push_back(entry);
369  IndexVectMap[std::make_tuple(iSample, iOscChan, iSyst, iMode, iVar)] = static_cast<int>(IndexVect.size() - 1);
370 
371  int iDim = nDims - 1;
372  while (iDim >= 0 && ++iVar[iDim] == nBins[iDim]) {
373  iVar[iDim] = 0;
374  --iDim;
375  }
376 
377  if (iDim < 0)
378  break;
379  } // Over kinematic variables
380  } // Over modes
381  } // Over systs
382  } // Over channels
383 }
std::vector< SplineIndex > IndexVect
Variables related to determined which modes have splines and which piggy-back of other modes.
std::map< std::tuple< int, int, int, int, std::vector< int > >, int > IndexVectMap
Map between spline origin/properties (iSample, iOscChan, iSyst, iMode, iVar1, iVar2,...
int GetSampleIndex(const std::string &SampleTitle) const
Get index of sample based on name.
Flat representation of a spline index entry.
Definition: SplineCommon.h:33
std::vector< int > iVar
Kinematic bins index, assumed to be size of 3 for now.
Definition: SplineCommon.h:49
int iSample
Sample index.
Definition: SplineCommon.h:41
int iMode
Mode index within a systematic.
Definition: SplineCommon.h:47
int value
Index into the flattened spline weight vector.
Definition: SplineCommon.h:39
int iOscChan
Oscillation channel index.
Definition: SplineCommon.h:43
int iSyst
Systematic parameter index.
Definition: SplineCommon.h:45

◆ CalcSplineWeights()

void BinnedSplineHandler::CalcSplineWeights ( )
finalprotectedvirtual

CPU based code which eval weight for each spline.

Splines are stored using a flat monolithic structure. The monolith is organised as follows:

Spline 0
Segment 0: [ Y | B | C | D ]
Segment 1: [ Y | B | C | D ]
Segment 2: [ Y | B | C | D ]
Spline 1
Segment 0: [ Y | B | C | D ]
Segment 1: [ Y | B | C | D ]
Segment 2: [ Y | B | C | D ]
Spline 2
Segment 0: [ Y | B | C | D ]
Segment 1: [ Y | B | C | D ]
Segment 2: [ Y | B | C | D ]
...

Once coefficient are grabbed we calculate weight using:

weight = Y + B*dx + C*dx^2 + D*dx^3;
Todo:
KS: Once could use "ParamValues" but this will result in tiny bit different results due to floating point precision

Implements SplineBase.

Definition at line 300 of file BinnedSplineHandler.cpp.

300  {
301 //****************************************
302  #ifdef MULTITHREAD
303  #pragma omp parallel for simd
304  #endif
305  for (unsigned int splineNum = 0; splineNum < NSplines_valid; ++splineNum)
306  {
307  //CW: Which Parameter we are accessing
308  const short int Param = paramNo_arr[splineNum];
309  //CW: Avoids doing costly binary search on GPU
310  const short int segment = short(SplineSegments[Param]);
311 
312  //KS: Segment for coeff_x is simply parameter*max knots + segment as each parameters has the same spacing
313  const short int segment_X = short(Param*_max_knots+segment);
314 
315  //KS: Find knot position in out monolithical structure
316  const unsigned int CurrentKnotPos = (nKnots_arr[splineNum]+segment) * _nCoeff_;
317 
318  // These are what we can extract from the TSpline3
319  const M3::float_t y = manycoeff_arr[CurrentKnotPos+kCoeffY];
320  const M3::float_t b = manycoeff_arr[CurrentKnotPos+kCoeffB];
321  const M3::float_t c = manycoeff_arr[CurrentKnotPos+kCoeffC];
322  const M3::float_t d = manycoeff_arr[CurrentKnotPos+kCoeffD];
323 
324  // Get the variation for this reconfigure for the i-th parameter
326  const M3::float_t xvar = (*SplineInfoArray[Param].splineParsPointer);
327  // The Delta(x) = xvar - x
328  const M3::float_t dx = xvar - xcoeff_arr[segment_X];
329 
330  //CW: Wooow, let's use some fancy intrinsic and pull down the processing time by <1% from normal multiplication! HURRAY
331  cpu_spline_weights[splineNum] = M3::fmaf_t(dx, M3::fmaf_t(dx, M3::fmaf_t(dx, d, c), b), y);
332  // Or for the more "easy to read" version:
333  //cpu_spline_weights[splineNum] = (fY+dx*(fB+dx*(fC+dx*fD)));
334  }
335 }
constexpr int _nCoeff_
KS: We store coefficients {y,b,c,d} in one array one by one, this is only to define it once rather th...
Definition: SplineCommon.h:18
@ kCoeffB
Coefficient B.
Definition: SplineCommon.h:26
@ kCoeffD
Coefficient D.
Definition: SplineCommon.h:28
@ kCoeffY
Coefficient Y.
Definition: SplineCommon.h:25
@ kCoeffC
Coefficient C.
Definition: SplineCommon.h:27
std::vector< short int > paramNo_arr
CW: CPU array with the number of points per spline (not per spline point!)
std::vector< M3::float_t > cpu_spline_weights
Stores weight from spline evaluation for each single spline.
std::vector< unsigned int > nKnots_arr
KS: CPU Number of knots per spline.
unsigned int NSplines_valid
Number of valid splines.
Definition: SplineBase.h:117
short int _max_knots
Max knots for production.
Definition: SplineBase.h:115
std::vector< FastSplineInfo > SplineInfoArray
Definition: SplineBase.h:106
double float_t
Definition: Core.h:37
constexpr T fmaf_t(T x, T y, T z)
Function template for fused multiply-add.
Definition: Core.h:45

◆ CleanUpMemory()

void BinnedSplineHandler::CleanUpMemory ( )

Remove setup variables not needed for spline evaluations.

Definition at line 55 of file BinnedSplineHandler.cpp.

55  {
56 //****************************************
57  //Call once everything's been allocated in SampleHandlerBase, cleans up junk from memory!
58  //Not a huge saving but it's better than leaving everything up to the compiler
59  MACH3LOG_INFO("Cleaning up spline memory");
61  IndexVectMap.clear();
77 }
void CleanContainer(T &)
Base case: do nothing for non-pointer types.
void CleanVector(T &)
Base case: do nothing for non-vector types.
std::vector< std::string > UniqueSystNames
name of each spline parameter
std::vector< int > monolith_index
keep track which splines are flat (-1) otherwise map with flattened splines
std::vector< TSpline3_red * > splinevec_Monolith
holds each spline object before stripping into coefficient monolith
std::vector< int > UniqueSystIndices
Global index of each spline param, it allows us to match spline ordering with global.

◆ CountNumberOfLoadedSplines()

int BinnedSplineHandler::CountNumberOfLoadedSplines ( bool  NonFlat = false,
int  Verbosity = 0 
) const

Count how many splines we have.

Definition at line 485 of file BinnedSplineHandler.cpp.

485  {
486 //****************************************
487  std::vector<int> SampleAll(SampleTitles.size(), 0);
488  std::vector<int> SampleNonFlat(SampleTitles.size(), 0);
489 
490  int FullCounter_All = 0;
491  int FullCounter_NonFlat = 0;
492 
493  for (unsigned int index = 0; index < IndexVect.size(); index++)
494  {
495  const auto& entry = IndexVect[index];
496 
497  int iSample = entry.iSample;
498 
499  std::string SampleTitle = SampleTitles[iSample];
500 
501  if (!isValidSplineIndex(SampleTitle, entry.iOscChan, entry.iSyst,
502  entry.iMode, entry.iVar)) {
503  continue;
504  }
505  SampleAll[iSample]++;
506 
507  if (splinevec_Monolith[entry.value]) {
508  SampleNonFlat[iSample]++;
509  }
510  }
511 
512  // Print per-sample summary
513  for (size_t iSample = 0; iSample < SampleTitles.size(); iSample++)
514  {
515  MACH3LOG_DEBUG("{:<10} has {:<10} splines, of which {:<10} are not flat",
516  SampleTitles[iSample],
517  SampleAll[iSample],
518  SampleNonFlat[iSample]);
519 
520  FullCounter_All += SampleAll[iSample];
521  FullCounter_NonFlat += SampleNonFlat[iSample];
522  }
523 
524  if (Verbosity > 0) {
525  MACH3LOG_INFO("Total number of splines loaded: {}", FullCounter_All);
526  MACH3LOG_INFO("Total number of non-flat splines loaded: {}", FullCounter_NonFlat);
527  }
528 
529  if (NonFlat) {
530  return FullCounter_NonFlat;
531  } else {
532  return FullCounter_All;
533  }
534 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
bool isValidSplineIndex(const std::string &SampleTitle, int iSyst, int iOscChan, int iMode, const std::vector< int > &iVar) const
Ensure we have spline for a given bin.

◆ Evaluate()

void BinnedSplineHandler::Evaluate ( )
finalvirtual

CW: This Eval should be used when using two separate x,{y,a,b,c,d} arrays to store the weights; probably the best one here! Same thing but pass parameter spline segments instead of variations.

Implements SplineBase.

Definition at line 278 of file BinnedSplineHandler.cpp.

278  {
279 // *****************************************
280  // There's a parameter mapping that goes from spline parameter to a global parameter index
281  // Find the spline segments
283 
284  #ifdef MaCh3_CUDA
285  if (useGPU) { // GPU calculations
286  // The main call to the GPU
288  cpu_spline_weights.data(),
289  ParamValues,
291  } else
292  #endif
293  { // CPU-only calculations
294  // KS: Huge MP loop over all valid splines
296  }
297 }
void CalcSplineWeights() final
CPU based code which eval weight for each spline.
void FindSplineSegment()
CW:Code used in step by step reweighting, Find Spline Segment for each param.
Definition: SplineBase.cpp:58
__host__ void RunGPU_SplineMonolith_Binned(M3::float_t *cpu_spline_weights, float *vals, short int *segment)

◆ FillSampleArray()

void BinnedSplineHandler::FillSampleArray ( const std::string &  SampleTitle,
const std::vector< std::string > &  OscChanFileNames 
)
virtual

Loads and processes splines from ROOT files for a given sample.

Note
DB Add virtual so it can be overridden in experiment specific (if needed)

Definition at line 867 of file BinnedSplineHandler.cpp.

868 {
869  int iSample = GetSampleIndex(SampleTitle);
870  int nOscChannels = nOscChans[iSample];
871 
872  for (int iOscChan = 0; iOscChan < nOscChannels; iOscChan++) {
873  MACH3LOG_INFO("Processing: {}", OscChanFileNames[iOscChan]);
874  TSpline3* mySpline = nullptr;
875  TSpline3_red* Spline = nullptr;
876 
877  std::set<std::string> SplineFileNames;
878  auto File = std::unique_ptr<TFile>(TFile::Open(OscChanFileNames[iOscChan].c_str()));
879 
880  if (!File || File->IsZombie()) {
881  MACH3LOG_ERROR("File {} not found", OscChanFileNames[iOscChan]);
882  throw MaCh3Exception(__FILE__, __LINE__);
883  }
884 
885  //This is the MC specific part of the code
886  //i.e. we always assume that the splines are just store in single TDirectory and they're all in there as single objects
887  for (auto k : *File->GetListOfKeys()) {
888  auto Key = static_cast<TKey*>(k);
889  TClass *Class = gROOT->GetClass(Key->GetClassName(), false);
890  if(!Class->InheritsFrom("TSpline3")) {
891  continue;
892  }
893 
894  std::string FullSplineName = std::string(Key->GetName());
895 
896  if (SplineFileNames.count(FullSplineName) > 0) {
897  MACH3LOG_CRITICAL("Skipping spline - Found a spline whose name has already been encountered before: {}", FullSplineName);
898  continue;
899  }
900  SplineFileNames.insert(FullSplineName);
901 
902  std::vector<std::string> Tokens = GetTokensFromSplineName(FullSplineName);
903 
904  TString Syst = Tokens[kSystToken];
905  TString Mode = Tokens[kModeToken];
906  std::vector<int> VarBins;
907  VarBins.reserve(Tokens.size() - kVarBinToken);
908  for (std::size_t i = kVarBinToken; i < Tokens.size(); ++i) {
909  VarBins.push_back(std::stoi(Tokens.at(i)));
910  }
911 
912  int SystNum = -1;
913  for (unsigned iSyst = 0; iSyst < SplineFileParPrefixNames[iSample].size(); iSyst++) {
914  if (Syst == SplineFileParPrefixNames[iSample][iSyst]) {
915  SystNum = iSyst;
916  break;
917  }
918  }
919 
920  // If the syst doesn't match any of the spline names then skip it
921  if (SystNum == -1){
922  MACH3LOG_DEBUG("Couldn't Match any systematic name in ParameterHandler with spline name: {}" , FullSplineName);
923  continue;
924  }
925 
926  int ModeNum = -1;
927  for (unsigned int iMode = 0; iMode < SplineModeVecs[iSample][SystNum].size(); iMode++) {
928  if (Mode == Modes->GetSplineSuffixFromMaCh3Mode(SplineModeVecs[iSample][SystNum][iMode])) {
929  ModeNum = iMode;
930  break;
931  }
932  }
933 
934  if (ModeNum == -1) {
935  //DB - If you have splines in the root file that you don't want to use (e.g. removing a mode from a syst), this will cause a throw
936  // Therefore include as debug warning and continue instead
937  MACH3LOG_DEBUG("Couldn't find mode for {} in {}. Problem Spline is : {} ", Mode, Syst, FullSplineName);
938  continue;
939  }
940 
941  mySpline = Key->ReadObject<TSpline3>();
942  // loop over all the spline knots and check their value
943  if (isValidSplineIndex(SampleTitle, iOscChan, SystNum, ModeNum, VarBins)) {
944  MACH3LOG_TRACE("Pushed back monolith for spline {}", FullSplineName);
945  // if the value is 1 then set the flat bool to false
946  int nKnots = mySpline->GetNp();
947  bool isFlat = true;
948  for (int iKnot = 0; iKnot < nKnots; iKnot++) {
949  double x, y = M3::_BAD_DOUBLE_;
950  mySpline->GetKnot(iKnot, x, y);
951  if (y < 0.99999 || y > 1.00001)
952  {
953  isFlat = false;
954  break;
955  }
956  }
957 
958  //Rather than keeping a mega vector of splines then converting, this should just keep everything nice in memory!
959  int index = IndexVectMap.at(std::make_tuple(iSample, iOscChan, SystNum, ModeNum, VarBins));
960  IndexVect[index].value = MonolithIndex;
961  // Should save memory rather saving [x_i_0 ,... x_i_maxknots] for every spline!
962  if (isFlat) {
963  splinevec_Monolith.push_back(nullptr);
964  delete mySpline;
965  } else {
966  ApplyKnotWeightCapTSpline3(mySpline, SystNum, ParHandler);
967  Spline = new TSpline3_red(mySpline, SplineInterpolationTypes[iSample][SystNum]);
968  if(mySpline) delete mySpline;
969 
970  splinevec_Monolith.push_back(Spline);
971  CoeffIndex+=nKnots;
972  _max_knots = std::max(_max_knots, static_cast<short int>(nKnots));
973  }
974  //Incrementing MonolithIndex to keep track of number of valid spline indices
975  MonolithIndex+=1;
976  } else {
977  //Potentially you are not a valid spline index
978  delete mySpline;
979  }
980  }//End of loop over all TKeys in file
981 
982  //A bit of clean up
983  File->Delete("*");
984  File->Close();
985  } //End of oscillation channel loop
986 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33
void ApplyKnotWeightCapTSpline3(TSpline3 *&Spline, const int splineParsIndex, ParameterHandlerGeneric *ParHandler)
EM: Apply capping to knot weight for specified spline parameter. param graph needs to have been set i...
Definition: SplineStructs.h:99
bool isFlat(TSpline3_red *&spl)
CW: Helper function used in the constructor, tests to see if the spline is flat.
virtual std::vector< std::string > GetTokensFromSplineName(const std::string &FullSplineName)=0
Extract metadata tokens encoded in a spline name. allows experiment to have different formats of spli...
std::string GetSplineSuffixFromMaCh3Mode(const int Index)
DB: Get binned spline mode suffix from MaCh3 Mode.
Definition: MaCh3Modes.cpp:243
CW: Reduced TSpline3 class.
constexpr static const double _BAD_DOUBLE_
Default value used for double initialisation.
Definition: Core.h:53
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.

◆ FindSplineBinning()

std::vector< TAxis * > BinnedSplineHandler::FindSplineBinning ( const std::string &  FileName,
const std::string &  SampleTitle 
)
protected

Grab histograms with spline binning.

Todo:
KS: we should remove this hardcoding in future.

Definition at line 386 of file BinnedSplineHandler.cpp.

387  {
388 //****************************************
389  int iSample = GetSampleIndex(SampleTitle);
390  TH1* Axis_Hist = nullptr;
391 
392  auto File = std::unique_ptr<TFile>(TFile::Open(FileName.c_str(), "READ"));
393  if (!File || File->IsZombie())
394  {
395  MACH3LOG_ERROR("File {} not found", FileName);
396  MACH3LOG_ERROR("This is caused by something here! {} : {}", __FILE__, __LINE__);
397  throw MaCh3Exception(__FILE__ , __LINE__ );
398  }
399 
400  MACH3LOG_INFO("Finding binning for:");
401  MACH3LOG_INFO("{}", FileName);
402 
403  std::string TemplateName = "dev_tmp_0_0";
404  TObject *Obj = File->Get(TemplateName.c_str());
405  //If you can't find dev_tmp_0_0 then this will cause a problem
406  if (!Obj)
407  {
408  TemplateName = "dev_tmp.0.0";
409  Obj = File->Get(TemplateName.c_str());
410  if (!Obj)
411  {
412  MACH3LOG_ERROR("Could not find dev_tmp_0_0 in spline file. Spline binning cannot be set!");
413  MACH3LOG_ERROR("FileName: {}", FileName);
414  throw MaCh3Exception(__FILE__ , __LINE__ );
415  }
416  }
417 
418  //Now check if dev_tmp_0_0 is a TH2 i.e. specifying the dimensions of the splines is 2D
419  bool isHist2D = Obj->IsA() == TH2F::Class();
420  //For T2K annoyingly all objects are TH3Fs
421  bool isHist3D = Obj->IsA() == TH3F::Class();
422  if (!isHist2D && !isHist3D)
423  {
424  MACH3LOG_ERROR("Object doesn't inherit from either TH2D and TH3D - Odd A");
425  throw MaCh3Exception(__FILE__ , __LINE__ );
426  }
427 
428  if (isHist2D)
429  {
430  if (Dimensions[iSample] != 2)
431  {
432  MACH3LOG_ERROR("Trying to load a 2D spline template when nDim={}", Dimensions[iSample]);
433  throw MaCh3Exception(__FILE__, __LINE__);
434  }
435  Axis_Hist = File->Get<TH2F>(TemplateName.c_str());
436  }
437 
438  if (isHist3D)
439  {
440  Axis_Hist = File->Get<TH3F>((TemplateName.c_str()));
441  if (Dimensions[iSample] != 3 && Axis_Hist->GetZaxis()->GetNbins() != 1)
442  {
443  MACH3LOG_ERROR("Trying to load a 3D spline template when nDim={}", Dimensions[iSample]);
444  throw MaCh3Exception(__FILE__ , __LINE__ );
445  }
446  }
448  std::vector<TAxis*> ReturnVec(3);
449  ReturnVec[0] = static_cast<TAxis*>(Axis_Hist->GetXaxis()->Clone());
450  ReturnVec[1] = static_cast<TAxis*>(Axis_Hist->GetYaxis()->Clone());
451 
452  if (Dimensions[iSample] == 3) {
453  ReturnVec[2] = static_cast<TAxis*>(Axis_Hist->GetZaxis()->Clone());
454  } else {
455  // creating dummy binning
456  constexpr double DummyEdges[2] = {-1e15, 1e15};
457  ReturnVec[2] = new TAxis(1, DummyEdges);
458  }
459 
460  for (unsigned int iAxis = 0; iAxis < ReturnVec.size(); ++iAxis) {
461  PrintBinning(ReturnVec[iAxis]);
462  }
463 
464  MACH3LOG_INFO("Left PrintBinning now tidying up");
465  return ReturnVec;
466 }
void PrintBinning(TAxis *Axis) const
Print spline binning.

◆ GetEventSplines()

std::vector< SplineIndex > BinnedSplineHandler::GetEventSplines ( const std::string &  SampleTitle,
int  iOscChan,
int  EventMode,
const std::vector< double > &  VarVals 
)

Return the splines which affect a given event.

Definition at line 740 of file BinnedSplineHandler.cpp.

741  {
742 //****************************************
743  std::vector<SplineIndex> ReturnVec;
744  int SampleIndex = GetSampleIndex(SampleTitle);
745 
746  int Mode = -1;
747  std::string SuffixForEventMode = Modes->GetSplineSuffixFromMaCh3Mode(EventMode);
748  for (int iMode = 0; iMode< Modes->GetNModes(); iMode++) {
749  if (SuffixForEventMode == Modes->GetSplineSuffixFromMaCh3Mode(iMode)) {
750  Mode = iMode;
751  break;
752  }
753  }
754  if (Mode == -1) {
755  return ReturnVec;
756  }
757 
758  std::vector<int> var_bins;
759  for (size_t i = 0; i < VarVals.size(); ++i) {
760  int bin = SplineBinning[SampleIndex][iOscChan][i]->FindBin(VarVals[i]) - 1;
761  if (bin < 0 || bin >= SplineBinning[SampleIndex][iOscChan][i]->GetNbins()) {
762  return ReturnVec;
763  }
764  var_bins.push_back(bin);
765  }
766 
767  for(int iSyst=0; iSyst < nSplineParams[SampleIndex]; iSyst++){
768  std::vector<int> spline_modes = SplineModeVecs[SampleIndex][iSyst];
769  int nSampleModes = static_cast<int>(spline_modes.size());
770 
771  //ETA - look here at the length of spline_modes and what you're actually comparing against
772  for(int iMode = 0; iMode<nSampleModes; iMode++) {
773  //Only consider if the event mode (Mode) matches ones of the spline modes
774  if (Mode == spline_modes[iMode]) {
775  int index = IndexVectMap.at(std::make_tuple(SampleIndex, iOscChan, iSyst, iMode,
776  var_bins));
777  int splineID = IndexVect[index].value;
778  //Also check that the spline isn't flat
779  if(monolith_index[splineID] != M3::_BAD_INT_) {
780  SplineIndex idx;
781  idx.iSample = SampleIndex;
782  idx.iOscChan = iOscChan;
783  idx.iSyst = iSyst;
784  idx.iMode = iMode;
785  idx.iVar = var_bins;
786  ReturnVec.push_back(idx);
787  }
788  }
789  }
790  }
791  return ReturnVec;
792 }
int GetNModes() const
KS: Get number of modes, keep in mind actual number is +1 greater due to unknown category.
Definition: MaCh3Modes.h:155
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55

◆ GetSampleIndex()

int BinnedSplineHandler::GetSampleIndex ( const std::string &  SampleTitle) const
protected

Get index of sample based on name.

Parameters
SampleTitleThe title of the sample to search for.

Definition at line 662 of file BinnedSplineHandler.cpp.

662  {
663 //****************************************
664  for (size_t iSample = 0; iSample < SampleTitles.size(); ++iSample) {
665  if (SampleTitle == SampleTitles[iSample]) {
666  return static_cast<int>(iSample);
667  }
668  }
669  MACH3LOG_ERROR("Sample name not found: {}", SampleTitle);
670  throw MaCh3Exception(__FILE__, __LINE__);
671 }

◆ GetSplineCoeff_SepMany()

void BinnedSplineHandler::GetSplineCoeff_SepMany ( int  splineindex,
M3::float_t *&  xArray,
M3::float_t *&  manyArray 
)
protected

Rather work with spline coefficients in the splines, let's copy ND and use coefficient arrays.

Definition at line 626 of file BinnedSplineHandler.cpp.

626  {
627 //****************************************
628  //No point evaluating a flat spline
629  int nPoints = splinevec_Monolith[splineindex]->GetNp();
630 
631  for (int i = 0; i < nPoints; i++) {
632  xArray[i] = 1.0;
633  for (int j = 0; j < _nCoeff_; j++) {
634  manyArray[i*_nCoeff_+j] = 1.0;
635  }
636  }
637 
638  for(int i=0; i<nPoints; i++) {
639  M3::float_t x = M3::float_t(-999.99);
640  M3::float_t y = M3::float_t(-999.99);
641  M3::float_t b = M3::float_t(-999.99);
642  M3::float_t c = M3::float_t(-999.99);
643  M3::float_t d = M3::float_t(-999.99);
644  splinevec_Monolith[splineindex]->GetCoeff(i, x, y, b, c, d);
645 
646  // Store the coefficients for each knot contiguously in memory
647  // 4 because manyArray stores y,b,c,d
648  xArray[i] = x;
649  manyArray[i * _nCoeff_ + kCoeffY] = y;
650  manyArray[i * _nCoeff_ + kCoeffB] = b;
651  manyArray[i * _nCoeff_ + kCoeffC] = c;
652  manyArray[i * _nCoeff_ + kCoeffD] = d;
653  }
654 
655  //We now clean up the splines!
656  delete splinevec_Monolith[splineindex];
657  splinevec_Monolith[splineindex] = nullptr;
658 }

◆ GetTokensFromSplineName()

virtual std::vector<std::string> BinnedSplineHandler::GetTokensFromSplineName ( const std::string &  FullSplineName)
protectedpure virtual

Extract metadata tokens encoded in a spline name. allows experiment to have different formats of splines.

◆ InvestigateMissingSplines()

void BinnedSplineHandler::InvestigateMissingSplines ( ) const
private

This function will find missing splines in file.

Definition at line 135 of file BinnedSplineHandler.cpp.

135  {
136 //****************************************
137  // Map: iSample → iSyst → modeSuffix → {totalSplines, zeroCount}
138  std::map<unsigned int, std::map<unsigned int, std::map<std::string, std::pair<unsigned int, unsigned int>>>> systZeroCounts;
139  for (const auto& entry : IndexVect) {
140  unsigned int iSample = entry.iSample;
141  unsigned int iSyst = entry.iSyst;
142 
143  std::string SampleName = SampleNames[iSample];
144  // Get the mode suffix string
145  std::string modeSuffix = Modes->GetSplineSuffixFromMaCh3Mode(SplineModeVecs[iSample][entry.iSyst][entry.iMode]);
146  auto& counts = systZeroCounts[iSample][iSyst][modeSuffix];
147 
148  counts.first++; // totalSplines
149  if (entry.value == -1)
150  {
151  counts.second++; // zeroCount
152  if (counts.second > 1)
153  {
155  "Sample '{}' | OscChan {} | Syst '{}' | Mode '{}' | Var {} => Value: {}",
156  SampleTitles[iSample],
157  entry.iOscChan,
158  SplineFileParPrefixNames[iSample][iSyst],
159  modeSuffix,
160  fmt::join(entry.iVar, " "),
161  entry.value
162  );
163  }
164  }
165  }
166 
167  // KS: Let's print this atrocious mess...
168  for (const auto& samplePair : systZeroCounts) {
169  unsigned int iSample = samplePair.first;
170  std::vector<std::string> SplineFileParPrefixNames_Sample = ParHandler->GetParsNamesFromSampleName(SampleNames[iSample], kSpline);
171  for (const auto& systPair : samplePair.second) {
172  unsigned int iSyst = systPair.first;
173  const auto& systName = SplineFileParPrefixNames_Sample[iSyst];
174  for (const auto& modePair : systPair.second) {
175  const auto& modeSuffix = modePair.first;
176  const auto& counts = modePair.second;
178  "Sample '{}': Systematic '{}' has missing splines in mode '{}'. Expected Splines: {}, Missing Splines: {}",
179  SampleTitles[iSample],
180  systName,
181  modeSuffix,
182  counts.first,
183  counts.second
184  );
185  }
186  }
187  }
188 }
const std::vector< std::string > GetParsNamesFromSampleName(const std::string &SampleName, const SystType Type) const
DB Grab the parameter names for the relevant SampleName.
std::string join(const Container &values, std::string_view separator=" ")
Join all values in a container into a single string.
Definition: TablePrinter.h:36

◆ isValidSplineIndex()

bool BinnedSplineHandler::isValidSplineIndex ( const std::string &  SampleTitle,
int  iSyst,
int  iOscChan,
int  iMode,
const std::vector< int > &  iVar 
) const
protected

Ensure we have spline for a given bin.

Definition at line 705 of file BinnedSplineHandler.cpp.

706  {
707 //****************************************
708  int iSample = GetSampleIndex(SampleTitle);
709 
710  bool found = IndexVectMap.find(std::make_tuple(iSample, iOscChan, iSyst, iMode, iVar)) != IndexVectMap.end();
711 
712  if (!found)
713  {
714  MACH3LOG_ERROR("Given iSample: {}", iSample);
715  MACH3LOG_ERROR("Given iOscChan: {}", iOscChan);
716  MACH3LOG_ERROR("Given iSyst: {}", iSyst);
717  MACH3LOG_ERROR("Given iMode: {}", iMode);
718  for (size_t i = 0; i < iVar.size(); ++i) {
719  MACH3LOG_ERROR("Given iVar{}: {}", i, iVar[i]);
720  }
721  MACH3LOG_ERROR("Come visit me at : {} : {}", __FILE__, __LINE__);
722  throw MaCh3Exception(__FILE__, __LINE__);
723  }
724 
725  return true;
726 }

◆ LoadIndexDir()

void BinnedSplineHandler::LoadIndexDir ( std::unique_ptr< TFile > &  SplineFile)
private

KS: Load preprocessed Index.

Parameters
SplineFileFile from which we load new tree

Definition at line 1118 of file BinnedSplineHandler.cpp.

1118  {
1119 // *****************************************
1120  TTree *IndexTree = SplineFile->Get<TTree>("IndexVec");
1121 
1122  SplineIndex* IndexTemp = nullptr;
1123  IndexTree->SetBranchAddress("SplineIndex", &IndexTemp);
1124  IndexVect.resize(IndexTree->GetEntries());
1125  // Fill indexvec with data from IndexTree
1126  for (Long64_t iEntry = 0; iEntry < IndexTree->GetEntries(); ++iEntry) {
1127  IndexTree->GetEntry(iEntry);
1128  IndexVect[iEntry] = *IndexTemp;
1129 
1130  auto key = std::make_tuple(IndexTemp->iSample, IndexTemp->iOscChan, IndexTemp->iSyst,
1131  IndexTemp->iMode, IndexTemp->iVar);
1132  IndexVectMap[key] = static_cast<int>(iEntry);
1133  }
1134 
1135  // Load SplineBinning data
1136  TTree *SplineBinningTree = SplineFile->Get<TTree>("SplineBinningTree");
1137  std::vector<int> indices(3);
1138  SplineBinningTree->SetBranchAddress("i", &indices[0]);
1139  SplineBinningTree->SetBranchAddress("j", &indices[1]);
1140  SplineBinningTree->SetBranchAddress("k", &indices[2]);
1141  TAxis* axis = nullptr;
1142  SplineBinningTree->SetBranchAddress("axis", &axis);
1143 
1144  // Reconstruct TAxis objects
1145  for (Long64_t entry = 0; entry < SplineBinningTree->GetEntries(); ++entry) {
1146  SplineBinningTree->GetEntry(entry);
1147  int i = indices[0];
1148  int j = indices[1];
1149  int k = indices[2];
1150  SplineBinning[i][j][k] = static_cast<TAxis*>(axis->Clone());
1151  }
1152 
1153  std::vector<int> indices_mode(3);
1154  int mode_value;
1155  TTree *SplineModeTree = SplineFile->Get<TTree>("SplineModeTree");
1156  SplineModeTree->SetBranchAddress("i", &indices_mode[0]);
1157  SplineModeTree->SetBranchAddress("j", &indices_mode[1]);
1158  SplineModeTree->SetBranchAddress("k", &indices_mode[2]);
1159  SplineModeTree->SetBranchAddress("value", &mode_value);
1160 
1161  // Fill SplineModeVecs with values from the tree
1162  for (Long64_t entry = 0; entry < SplineModeTree->GetEntries(); ++entry) {
1163  SplineModeTree->GetEntry(entry);
1164  int i = indices_mode[0];
1165  int j = indices_mode[1];
1166  int k = indices_mode[2];
1167  SplineModeVecs[i][j][k] = mode_value;
1168  }
1169 }

◆ LoadMonolithDir()

void BinnedSplineHandler::LoadMonolithDir ( std::unique_ptr< TFile > &  SplineFile)
private

KS: Load preprocessed Monolith.

Parameters
SplineFileFile from which we load new tree

Definition at line 1086 of file BinnedSplineHandler.cpp.

1086  {
1087 // *****************************************
1088  TTree *MonolithTree = SplineFile->Get<TTree>("MonolithTree");
1089 
1091  MonolithTree->SetBranchAddress("manycoeff", manycoeff_arr);
1093  std::vector<int>* monolith_index_temp = nullptr;
1094  MonolithTree->SetBranchAddress("monolith_index", &monolith_index_temp);
1095 
1096  // Load vectors
1097  std::vector<unsigned int>* nKnots_arr_temp = nullptr;
1098  MonolithTree->SetBranchAddress("nKnots_arr", &nKnots_arr_temp);
1099  std::vector<short int>* paramNo_arr_temp = nullptr;
1100  MonolithTree->SetBranchAddress("paramNo_arr", &paramNo_arr_temp);
1101  std::vector<int>* UniqueSystIndices_temp = nullptr;
1102  MonolithTree->SetBranchAddress("UniqueSystIndices", &UniqueSystIndices_temp);
1103 
1104  // Allocate and load xcoeff_arr
1106  MonolithTree->SetBranchAddress("xcoeff", xcoeff_arr);
1107 
1108  MonolithTree->GetEntry(0);
1109 
1110  nKnots_arr = *nKnots_arr_temp;
1111  paramNo_arr = *paramNo_arr_temp;
1112  UniqueSystIndices = *UniqueSystIndices_temp;
1113  monolith_index = *monolith_index_temp;
1114 }
short int nParams
Number of parameters that have splines.
Definition: SplineBase.h:113

◆ LoadSettingsDir()

void BinnedSplineHandler::LoadSettingsDir ( std::unique_ptr< TFile > &  SplineFile)
private

KS: Load preprocessed Settings.

Parameters
SplineFileFile from which we load new tree

Definition at line 1034 of file BinnedSplineHandler.cpp.

1034  {
1035 // *****************************************
1036  TTree *Settings = SplineFile->Get<TTree>("Settings");
1037  int CoeffIndex_temp;
1038  unsigned int NSplines_valid_temp;
1039  short int nParams_temp, max_knots_temp;
1040  Settings->SetBranchAddress("CoeffIndex", &CoeffIndex_temp);
1041  Settings->SetBranchAddress("NSplines_valid", &NSplines_valid_temp);
1042  Settings->SetBranchAddress("nParams", &nParams_temp);
1043  Settings->SetBranchAddress("max_knots", &max_knots_temp);
1044 
1045  int SplineBinning_size1, SplineBinning_size2, SplineBinning_size3;
1046  Settings->SetBranchAddress("SplineBinning_size1", &SplineBinning_size1);
1047  Settings->SetBranchAddress("SplineBinning_size2", &SplineBinning_size2);
1048  Settings->SetBranchAddress("SplineBinning_size3", &SplineBinning_size3);
1049  int SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3;
1050  Settings->SetBranchAddress("SplineModeVecs_size1", &SplineModeVecs_size1);
1051  Settings->SetBranchAddress("SplineModeVecs_size2", &SplineModeVecs_size2);
1052  Settings->SetBranchAddress("SplineModeVecs_size3", &SplineModeVecs_size3);
1053  std::vector<std::string>* SampleNames_temp = nullptr;
1054  Settings->SetBranchAddress("SampleNames", &SampleNames_temp);
1055  std::vector<std::string>* SampleTitles_temp = nullptr;
1056  Settings->SetBranchAddress("SampleTitles", &SampleTitles_temp);
1057  std::vector<int>* nSplineParams_temp = nullptr;
1058  Settings->SetBranchAddress("nSplineParams", &nSplineParams_temp);
1059  Settings->GetEntry(0);
1060 
1061  CoeffIndex = CoeffIndex_temp;
1062  NSplines_valid = NSplines_valid_temp;
1063  SampleNames = *SampleNames_temp;
1064  SampleTitles = *SampleTitles_temp;
1065  nSplineParams = *nSplineParams_temp;
1066 
1067  nParams = nParams_temp;
1068  _max_knots = max_knots_temp;
1069 
1070  auto Resize3D = [](auto& vec, int d1, int d2, int d3) {
1071  vec.resize(d1);
1072  for (int i = 0; i < d1; ++i) {
1073  vec[i].resize(d2);
1074  for (int j = 0; j < d2; ++j) {
1075  vec[i][j].resize(d3);
1076  }
1077  }
1078  };
1079 
1080  Resize3D(SplineBinning, SplineBinning_size1, SplineBinning_size2, SplineBinning_size3);
1081  Resize3D(SplineModeVecs, SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3);
1082 }

◆ LoadSplineFile()

void BinnedSplineHandler::LoadSplineFile ( std::string  FileName)
finalvirtual

KS: Load preprocessed spline file.

Parameters
FileNamePath to ROOT file with predefined reduced Spline Monolith

Implements SplineBase.

Definition at line 990 of file BinnedSplineHandler.cpp.

990  {
991 // *****************************************
992  M3::AddPath(FileName);
993 
994  // Check for spaces in the filename
995  size_t pos = FileName.find(' ');
996  if (pos != std::string::npos) {
997  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
998  while ((pos = FileName.find(' ')) != std::string::npos) {
999  FileName[pos] = '_';
1000  }
1001  }
1002  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "OPEN");
1003 
1004  TMacro *ConfigCov = SplineFile->Get<TMacro>("ParameterHandler");
1005  // Config which was in MCMC from which we are starting
1006  YAML::Node CovSettings = TMacroToYAML(*ConfigCov);
1007  // Config from currently used cov object
1008  YAML::Node ConfigCurrent = ParHandler->GetConfig();
1009 
1010  if (!compareYAMLNodes(CovSettings, ConfigCurrent))
1011  {
1012  MACH3LOG_ERROR("Loading precomputed spline file, however encountered different YAML config, please regenerate input");
1013  throw MaCh3Exception(__FILE__ , __LINE__ );
1014  }
1015 
1016  LoadSettingsDir(SplineFile);
1017  LoadMonolithDir(SplineFile);
1018  LoadIndexDir(SplineFile);
1019  LoadFastSplineInfoDir(SplineFile);
1020 
1021  for (int iSpline = 0; iSpline < nParams; iSpline++) {
1022  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
1023  }
1024  SplineFile->Close();
1025 
1026  MoveToGPU();
1027 
1028  // initialise spline segment structure
1029  SetupSegments();
1030 }
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
YAML::Node TMacroToYAML(const TMacro &macro)
KS: Convert a ROOT TMacro object to a YAML node.
Definition: YamlHelper.h:151
bool compareYAMLNodes(const YAML::Node &node1, const YAML::Node &node2, bool Mute=false)
Compare if yaml nodes are identical.
Definition: YamlHelper.h:185
void LoadIndexDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Index.
void LoadSettingsDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Settings.
void MoveToGPU()
CW: The shared initialiser from constructors of TResponseFunction_red.
void LoadMonolithDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Monolith.
const M3::float_t * RetPointer(const int iParam) const
DB Pointer return to param position.
YAML::Node GetConfig() const
Getter to return a copy of the YAML node.
void LoadFastSplineInfoDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed FastSplineInfo.
Definition: SplineBase.cpp:181
void SetupSegments()
Since we find segment before actual reweight and sometimes we want to copy it to GPU we have differen...
Definition: SplineBase.cpp:208
void AddPath(std::string &FilePath)
Prepends the MACH3 environment path to FilePath if it is not already present.
Definition: Monitor.cpp:382

◆ MoveToGPU()

void BinnedSplineHandler::MoveToGPU ( )
private

CW: The shared initialiser from constructors of TResponseFunction_red.

Definition at line 833 of file BinnedSplineHandler.cpp.

833  {
834 //****************************************
835  #ifdef MaCh3_CUDA
836  if(!useGPU) return;
838  unsigned int event_size_max = _max_knots * nParams;
839 
841  CoeffIndex, // How many entries in coefficient array (*4 for the "many" array)
842  NSplines_valid, // What's the number of splines we have (also number of entries in gpu_nPoints_arr)
843  0,
844  event_size_max //Knots times event number of unique splines
845  );
846 
849  xcoeff_arr,
850  paramNo_arr,
851  nKnots_arr,
852 
853  nParams,
855  _max_knots,
856  CoeffIndex);
857 
858  // Delete all the coefficient arrays from the CPU once they are on the GPU
859  delete[] manycoeff_arr; manycoeff_arr = nullptr;
860  delete[] xcoeff_arr; xcoeff_arr = nullptr;
863  MACH3LOG_INFO("Good GPU loading");
864  #endif
865 }
Class responsible for calculating spline weight on GPU.
__host__ void InitGPU_SplineMonolith(unsigned int total_nknots, unsigned int n_splines, unsigned int n_tf1, int Eve_size)
Allocate memory on gpu for spline monolith.
__host__ void CopyToGPU_SplineMonolith_Binned(M3::float_t *manycoeff_arr, M3::float_t *xcoeff_arr, const std::vector< short int > &uniquesplinevec_Monolith, const std::vector< unsigned int > &coeffindexvec, const int n_params, const unsigned int n_splines, const short int spline_size, const unsigned int total_nknots)
Copies data from CPU to GPU for the spline monolith.

◆ PrepareIndexDir()

void BinnedSplineHandler::PrepareIndexDir ( std::unique_ptr< TFile > &  SplineFile) const
private

KS: Prepare Index Info within SplineFile.

Parameters
SplineFileFile from which we load new tree

Definition at line 1270 of file BinnedSplineHandler.cpp.

1270  {
1271 // *****************************************
1272  // Create a TTree to store the data
1273  TTree *IndexTree = new TTree("IndexVec", "IndexVec");
1274  SplineIndex entry;
1275  IndexTree->Branch("SplineIndex", &entry);
1276  for (const auto& e : IndexVect) {
1277  entry = e;
1278  IndexTree->Fill();
1279  }
1280 
1281  SplineFile->cd();
1282  IndexTree->Write();
1283  delete IndexTree;
1284 }

◆ PrepareMonolithDir()

void BinnedSplineHandler::PrepareMonolithDir ( std::unique_ptr< TFile > &  SplineFile) const
private

KS: Prepare Monolith Info within SplineFile.

Parameters
SplineFileFile from which we load new tree

Definition at line 1243 of file BinnedSplineHandler.cpp.

1243  {
1244 // *****************************************
1245  if(manycoeff_arr == nullptr){
1246  MACH3LOG_ERROR("{} Will not work as manycoeff_arr is nullptr :(", __func__);
1247  MACH3LOG_ERROR("Could be GPU dysfunctionality");
1248  throw MaCh3Exception(__FILE__, __LINE__);
1249  }
1250  TTree *MonolithTree = new TTree("MonolithTree", "MonolithTree");
1251  MonolithTree->Branch("manycoeff", manycoeff_arr, Form("manycoeff[%d]/%s", CoeffIndex * _nCoeff_, M3::float_t_str_repr));
1252 
1253  std::vector<int> monolith_index_temp = monolith_index;
1254  MonolithTree->Branch("monolith_index", &monolith_index_temp);
1255  std::vector<unsigned int> nKnots_arr_temp = nKnots_arr;
1256  MonolithTree->Branch("nKnots_arr", &nKnots_arr_temp);
1257  std::vector<short int> paramNo_arr_temp = paramNo_arr;
1258  MonolithTree->Branch("paramNo_arr", &paramNo_arr_temp);
1259  std::vector<int> UniqueSystIndices_temp = UniqueSystIndices;
1260  MonolithTree->Branch("UniqueSystIndices", &UniqueSystIndices_temp);
1261  MonolithTree->Branch("xcoeff", xcoeff_arr, Form("xcoeff[%d]/%s", _max_knots * nParams, M3::float_t_str_repr));
1262 
1263  MonolithTree->Fill();
1264  SplineFile->cd();
1265  MonolithTree->Write();
1266  delete MonolithTree;
1267 }
constexpr static const char * float_t_str_repr
Definition: Core.h:40

◆ PrepareOtherInfoDir()

void BinnedSplineHandler::PrepareOtherInfoDir ( std::unique_ptr< TFile > &  SplineFile) const
private

KS: Prepare Other Info within SplineFile.

Parameters
SplineFileFile from which we load new tree

Definition at line 1287 of file BinnedSplineHandler.cpp.

1287  {
1288 // *****************************************
1289  // Create a new tree for SplineBinning data
1290  TTree *SplineBinningTree = new TTree("SplineBinningTree", "SplineBinningTree");
1291  std::vector<int> indices(3); // To store the 3D indices
1292  TAxis* axis = nullptr;
1293  SplineBinningTree->Branch("i", &indices[0], "i/I");
1294  SplineBinningTree->Branch("j", &indices[1], "j/I");
1295  SplineBinningTree->Branch("k", &indices[2], "k/I");
1296  SplineBinningTree->Branch("axis", "TAxis", &axis);
1297 
1298  // Fill the SplineBinningTree
1299  for (size_t i = 0; i < SplineBinning.size(); ++i) {
1300  for (size_t j = 0; j < SplineBinning[i].size(); ++j) {
1301  for (size_t k = 0; k < SplineBinning[i][j].size(); ++k) {
1302  axis = SplineBinning[i][j][k];
1303  indices[0] = static_cast<int>(i);
1304  indices[1] = static_cast<int>(j);
1305  indices[2] = static_cast<int>(k);
1306  SplineBinningTree->Fill();
1307  }
1308  }
1309  }
1310  SplineFile->cd();
1311  SplineBinningTree->Write();
1312  delete SplineBinningTree;
1313 
1314  std::vector<int> indices_mode(3); // to store 3D indices
1315  int mode_value;
1316 
1317  TTree *SplineModeTree = new TTree("SplineModeTree", "SplineModeTree");
1318  // Create branches for indices and value
1319  SplineModeTree->Branch("i", &indices_mode[0], "i/I");
1320  SplineModeTree->Branch("j", &indices_mode[1], "j/I");
1321  SplineModeTree->Branch("k", &indices_mode[2], "k/I");
1322  SplineModeTree->Branch("value", &mode_value, "value/I");
1323 
1324  // Fill the tree
1325  for (size_t i = 0; i < SplineModeVecs.size(); ++i) {
1326  for (size_t j = 0; j < SplineModeVecs[i].size(); ++j) {
1327  for (size_t k = 0; k < SplineModeVecs[i][j].size(); ++k) {
1328  indices_mode[0] = static_cast<int>(i);
1329  indices_mode[1] = static_cast<int>(j);
1330  indices_mode[2] = static_cast<int>(k);
1331  mode_value = SplineModeVecs[i][j][k];
1332  SplineModeTree->Fill();
1333  }
1334  }
1335  }
1336  // Write the tree to the file
1337  SplineFile->cd();
1338  SplineModeTree->Write();
1339  delete SplineModeTree;
1340 }

◆ PrepareSettingsDir()

void BinnedSplineHandler::PrepareSettingsDir ( std::unique_ptr< TFile > &  SplineFile) const
private

KS: Prepare Settings Info within SplineFile.

Parameters
SplineFileFile from which we load new tree

Definition at line 1200 of file BinnedSplineHandler.cpp.

1200  {
1201 // *****************************************
1202  TTree *Settings = new TTree("Settings", "Settings");
1203  int CoeffIndex_temp = CoeffIndex;
1204  unsigned int NSplines_valid_temp = NSplines_valid;
1205  short int nParams_temp = nParams;
1206  short int max_knots_temp = _max_knots;
1207 
1208  Settings->Branch("CoeffIndex", &CoeffIndex_temp, "CoeffIndex/I");
1209  Settings->Branch("NSplines_valid", &NSplines_valid_temp, "NSplines_valid/i");
1210  Settings->Branch("nParams", &nParams_temp, "nParams/S");
1211  Settings->Branch("max_knots", &max_knots_temp, "max_knots/S");
1212 
1213  int SplineBinning_size1 = static_cast<int>(SplineBinning.size());
1214  int SplineBinning_size2 = (SplineBinning_size1 > 0) ? static_cast<int>(SplineBinning[0].size()) : 0;
1215  int SplineBinning_size3 = (SplineBinning_size2 > 0) ? static_cast<int>(SplineBinning[0][0].size()) : 0;
1216 
1217  Settings->Branch("SplineBinning_size1", &SplineBinning_size1, "SplineBinning_size1/I");
1218  Settings->Branch("SplineBinning_size2", &SplineBinning_size2, "SplineBinning_size2/I");
1219  Settings->Branch("SplineBinning_size3", &SplineBinning_size3, "SplineBinning_size3/I");
1220 
1221  int SplineModeVecs_size1 = static_cast<int>(SplineModeVecs.size());
1222  int SplineModeVecs_size2 = (SplineModeVecs_size1 > 0) ? static_cast<int>(SplineModeVecs[0].size()) : 0;
1223  int SplineModeVecs_size3 = (SplineModeVecs_size2 > 0) ? static_cast<int>(SplineModeVecs[0][0].size()) : 0;
1224 
1225  Settings->Branch("SplineModeVecs_size1", &SplineModeVecs_size1, "SplineModeVecs_size1/I");
1226  Settings->Branch("SplineModeVecs_size2", &SplineModeVecs_size2, "SplineModeVecs_size2/I");
1227  Settings->Branch("SplineModeVecs_size3", &SplineModeVecs_size3, "SplineModeVecs_size3/I");
1228 
1229  std::vector<std::string> SampleNames_temp = SampleNames;
1230  Settings->Branch("SampleNames", &SampleNames_temp);
1231  std::vector<std::string> SampleTitles_temp = SampleTitles;
1232  Settings->Branch("SampleTitles", &SampleTitles_temp);
1233  std::vector<int> nSplineParams_temp = nSplineParams;
1234  Settings->Branch("nSplineParams", &nSplineParams_temp);
1235 
1236  Settings->Fill();
1237  SplineFile->cd();
1238  Settings->Write();
1239  delete Settings;
1240 }

◆ PrepareSplineFile()

void BinnedSplineHandler::PrepareSplineFile ( std::string  FileName)
finalvirtual

KS: Prepare spline file that can be used for fast loading.

Implements SplineBase.

Definition at line 1173 of file BinnedSplineHandler.cpp.

1173  {
1174 // *****************************************
1175  M3::AddPath(FileName);
1176  // Check for spaces in the filename
1177  size_t pos = FileName.find(' ');
1178  if (pos != std::string::npos) {
1179  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1180  while ((pos = FileName.find(' ')) != std::string::npos) {
1181  FileName[pos] = '_';
1182  }
1183  }
1184  // Save ROOT File
1185  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "recreate");
1186  YAML::Node ConfigCurrent = ParHandler->GetConfig();
1187  TMacro ConfigSave = YAMLtoTMacro(ConfigCurrent, "ParameterHandler");
1188  ConfigSave.Write();
1189 
1190  PrepareSettingsDir(SplineFile);
1191  PrepareMonolithDir(SplineFile);
1192  PrepareIndexDir(SplineFile);
1193  PrepareOtherInfoDir(SplineFile);
1194  PrepareFastSplineInfoDir(SplineFile);
1195 
1196  SplineFile->Close();
1197 }
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
Definition: YamlHelper.h:166
void PrepareIndexDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Index Info within SplineFile.
void PrepareMonolithDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Monolith Info within SplineFile.
void PrepareOtherInfoDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Other Info within SplineFile.
void PrepareSettingsDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Settings Info within SplineFile.
void PrepareFastSplineInfoDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Fast Spline Info within SplineFile.
Definition: SplineBase.cpp:153

◆ PrepForReweight()

void BinnedSplineHandler::PrepForReweight ( )
protected

Initialise flat structure.

Definition at line 537 of file BinnedSplineHandler.cpp.

537  {
538 //****************************************
539  std::vector<TSpline3_red*> UniqueSystSplines;
540  bool FoundNonFlatSpline = false;
541  int SampleCounter = M3::_BAD_INT_;
542  int SystCounter = M3::_BAD_INT_;
543  // DB Find all the Unique systs across each sample and oscillation channel
544  // This assumes that each occurrence of the same systematic spline has the same knot spacing
545  // Which is a reasonable assumption for the current implementation of spline evaluations
546  for (const auto& entry : IndexVect)
547  {
548  int splineindex = entry.value;
549  // KS: reset if we moved to another sample or syst
550  if(SampleCounter != entry.iSample || SystCounter != entry.iSyst) {
551  SampleCounter = entry.iSample;
552  SystCounter = entry.iSyst;
553  FoundNonFlatSpline = false;
554  }
555  std::string SystName = SplineFileParPrefixNames[entry.iSample][entry.iSyst];
556  bool FoundSyst = false;
557  for (unsigned int iFoundSyst = 0; iFoundSyst < UniqueSystNames.size(); iFoundSyst++) {
558  if (SystName == UniqueSystNames[iFoundSyst]) {
559  FoundSyst = true;
560  }
561  }
562  if (FoundSyst) continue;
563 
564  if (splinevec_Monolith[splineindex])
565  {
566  UniqueSystSplines.push_back(splinevec_Monolith[splineindex]);
567  UniqueSystIndices.push_back(GlobalSystIndex[entry.iSample][entry.iSyst]);
568 
569  FoundNonFlatSpline = true;
570  }
571  if (FoundNonFlatSpline) {
572  UniqueSystNames.push_back(SystName);
573  } else {
574  MACH3LOG_DEBUG("{} syst has no response in sample {}", SystName, entry.iSample);
575  MACH3LOG_DEBUG("Whilst this isn't necessarily a problem, it seems odd");
576  }
577  } // end loop over indices
578  nParams = static_cast<short int>(UniqueSystSplines.size());
579 
580  // DB Find the number of splines knots which assumes each instance of the syst has the same number of knots
581  SplineInfoArray.resize(nParams);
582  for (int iSpline = 0; iSpline < nParams; iSpline++)
583  {
584  SplineInfoArray[iSpline].nPts = static_cast<M3::int_t>(UniqueSystSplines[iSpline]->GetNp());
585  SplineInfoArray[iSpline].xPts.resize(SplineInfoArray[iSpline].nPts);
586  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
587  for (int iKnot = 0; iKnot < SplineInfoArray[iSpline].nPts; iKnot++)
588  {
589  M3::float_t xPoint;
590  M3::float_t yPoint;
591  UniqueSystSplines[iSpline]->GetKnot(iKnot, xPoint, yPoint);
592  SplineInfoArray[iSpline].xPts[iKnot] = xPoint;
593  }
594  }
595  M3::Utils::TablePrinter table({{"Spline Index", 10, 15, M3::Utils::Alignment::Left},
596  {"Syst Name", 10, 20, M3::Utils::Alignment::Left},
597  {"nKnots", 10, 6, M3::Utils::Alignment::Right}});
598 
599  MACH3LOG_INFO("nUniqueSysts: {}", nParams);
600  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++) {
601  table.AddRow(iUniqueSyst, UniqueSystNames[iUniqueSyst], SplineInfoArray[iUniqueSyst].nPts);
602  }
603 
604  for (const auto& line : table.Render()) {
605  MACH3LOG_INFO("{}", line);
606  }
607 
608  int nCombinations_FlatSplines = 0;
609  int nCombinations_All = 0;
610  // DB Now actually loop over splines to determine which are all null i.e. flat
611  for (unsigned int index = 0; index < IndexVect.size(); index++)
612  {
613  int splineindex = IndexVect[index].value;;
614  nCombinations_All++;
615  if (!splinevec_Monolith[splineindex]) {
616  nCombinations_FlatSplines++;
617  }
618  }
619 
620  // We need to grab the maximum number of knots
621  MACH3LOG_INFO("Number of combinations of Sample, OscChan, Syst and Mode which have entirely flat response: {} / {}", nCombinations_FlatSplines, nCombinations_All);
622 }
Creates fancy formatted text tables for terminal output.
Definition: TablePrinter.h:50
@ Right
Align text to the right.
@ Left
Align text to the left.
int int_t
Definition: Core.h:38

◆ PrintArrayDetails()

void BinnedSplineHandler::PrintArrayDetails ( const std::string &  SampleTitle) const
protected

Print info like Sample ID of spline params etc.

Definition at line 685 of file BinnedSplineHandler.cpp.

685  {
686 //****************************************
687  int iSample = GetSampleIndex(SampleTitle);
688  // count oscillation channels
689  std::map<int, std::set<int>> OscToSysts;
690 
691  for (const auto& entry : IndexVect) {
692  if (entry.iSample != iSample) continue;
693  OscToSysts[entry.iOscChan].insert(entry.iSyst);
694  }
695  MACH3LOG_INFO("Sample {} has {} oscillation channels", SampleTitle, OscToSysts.size());
696 
697  for (const auto& OscPair : OscToSysts) {
698  int osc = OscPair.first;
699  const std::set<int>& SystSet = OscPair.second;
700  MACH3LOG_INFO("Oscillation channel {} has {} systematics", osc, SystSet.size());
701  }
702 }

◆ PrintBinning()

void BinnedSplineHandler::PrintBinning ( TAxis *  Axis) const
protected

Print spline binning.

Definition at line 729 of file BinnedSplineHandler.cpp.

729  {
730 //****************************************
731  const int NBins = Axis->GetNbins();
732  std::string text = "";
733  for (int iBin = 0; iBin <= NBins; iBin++) {
734  text += fmt::format("{} ", Axis->GetXbins()->GetAt(iBin));
735  }
736  MACH3LOG_INFO("{}", text);
737 }

◆ PrintSampleDetails()

void BinnedSplineHandler::PrintSampleDetails ( const std::string &  SampleTitle) const
protected

Print info like Sample ID of spline params etc.

Definition at line 674 of file BinnedSplineHandler.cpp.

674  {
675 //****************************************
676  const int iSample = GetSampleIndex(SampleTitle);
677 
678  MACH3LOG_INFO("Details about sample: {:<20}", SampleTitles[iSample]);
679  MACH3LOG_INFO("\t Dimension: {:<35}", Dimensions[iSample]);
680  MACH3LOG_INFO("\t nSplineParam: {:<35}", nSplineParams[iSample]);
681  MACH3LOG_INFO("\t nOscChan: {:<35}", nOscChans[iSample]);
682 }

◆ RetPointer()

const M3::float_t * BinnedSplineHandler::RetPointer ( const SplineIndex &  Variables) const

get pointer to spline weight based on bin variables

Definition at line 469 of file BinnedSplineHandler.cpp.

469  {
470 //****************************************
471  // index in global spline space
472  int Index = IndexVectMap.at(std::make_tuple(Variables.iSample, Variables.iOscChan, Variables.iSyst,
473  Variables.iMode, Variables.iVar));
474  // global in space after removing flat splines
475  auto index_flattened = monolith_index[IndexVect[Index].value];
476  // Very unlikely to get response from flat spline. Could perform some optimisation and remove these but leave for now.
477  if(index_flattened == M3::_BAD_INT_) {
478  return &M3::Unity;
479  } else {
480  return &cpu_spline_weights[index_flattened];
481  }
482 }
constexpr static const float_t Unity
Definition: Core.h:64

◆ StripDuplicatedModes()

std::vector< std::vector< int > > BinnedSplineHandler::StripDuplicatedModes ( const std::vector< std::vector< int > > &  InputVector) const
protected

Creates an array to be filled with monolith indexes for each sample (allows for indexing between 7D binning and 1D Vector).

Check if there are any repeated modes. This is used to reduce the number of modes in case many interaction modes get averaged into one spline

Definition at line 797 of file BinnedSplineHandler.cpp.

797  {
798 //****************************************
799  //ETA - this is of size nPars from the syst model
800  size_t InputVectorSize = InputVector.size();
801  std::vector< std::vector<int> > ReturnVec(InputVectorSize);
802 
803  //ETA - loop over all systematics
804  for (size_t iSyst=0;iSyst<InputVectorSize;iSyst++) {
805  std::vector<int> TmpVec;
806  std::vector<std::string> TestVec;
807 
808  //Loop over the modes that we've listed in ParHandler
809  for (unsigned int iMode = 0 ; iMode < InputVector[iSyst].size() ; iMode++) {
810  int Mode = InputVector[iSyst][iMode];
811  std::string ModeName = Modes->GetSplineSuffixFromMaCh3Mode(Mode);
812 
813  bool IncludeMode = true;
814  for (auto TestString : TestVec) {
815  if (ModeName == TestString) {
816  IncludeMode = false;
817  break;
818  }
819  }
820 
821  if (IncludeMode) {
822  TmpVec.push_back(Mode);
823  TestVec.push_back(ModeName);
824  }
825  }
826 
827  ReturnVec[iSyst] = TmpVec;
828  }
829  return ReturnVec;
830 }

◆ TransferToMonolith()

void BinnedSplineHandler::TransferToMonolith ( )

flatten multidimensional spline array into proper monolith

Definition at line 191 of file BinnedSplineHandler.cpp.

191  {
192 //****************************************
193  PrepForReweight();
194  auto NSplines_All = CountNumberOfLoadedSplines(false, 1);
196  if (static_cast<unsigned int>(NSplines_All) != MonolithIndex) {
198  MACH3LOG_ERROR("Something's gone wrong when we tried to get the size of your monolith");
199  MACH3LOG_ERROR("NSplines_valid is {}", NSplines_valid);
200  MACH3LOG_ERROR("MonolithIndex is {}", MonolithIndex);
201  throw MaCh3Exception(__FILE__ , __LINE__ );
202  }
203 
204  MACH3LOG_INFO("Now transferring splines to a monolith if size {}", NSplines_valid);
205  // Maps single spline object with single parameter
206  paramNo_arr.resize(NSplines_valid);
208  nKnots_arr.resize(NSplines_valid);
209  monolith_index.resize(NSplines_All);
210 
213 
214  int ValidSplineCounter = 0;
215  int ValidKnotCounter = 0;
216  for (const auto& entry : IndexVect) {
217  int splineindex = entry.value;
218  if(splinevec_Monolith[splineindex]) {
219  cpu_spline_weights[ValidSplineCounter] = 1.0;
220 
221  bool foundUniqueSpline = false;
222  // We are trying to match Spline Object with single parameter (like MAQE)
223  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
224  {
225  if (SplineFileParPrefixNames[entry.iSample][entry.iSyst] == UniqueSystNames[iUniqueSyst])
226  {
227  paramNo_arr[ValidSplineCounter] = static_cast<short int>(iUniqueSyst);
228  foundUniqueSpline = true;
229  break;
230  }
231  } //unique syst loop end
232 
233  // If current spline object hasn't been matched with actual parameter this means misconfiguration
234  if (!foundUniqueSpline)
235  {
236  MACH3LOG_ERROR("Unique spline index not found");
237  MACH3LOG_ERROR("For Spline {}", SplineFileParPrefixNames[entry.iSample][entry.iSyst]);
238  MACH3LOG_ERROR("Couldn't match {} with any of the following {} systs:", SplineFileParPrefixNames[entry.iSample][entry.iSyst], nParams);
239  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
240  {
241  MACH3LOG_ERROR("{},", UniqueSystNames.at(iUniqueSyst));
242  }//unique syst loop end
243  throw MaCh3Exception(__FILE__ , __LINE__ );
244  }
245 
246  monolith_index[splineindex] = ValidSplineCounter;
247  int splineKnots = splinevec_Monolith[splineindex]->GetNp();
248  //Now to fill up our coefficient arrays
249  M3::float_t* tmpXCoeffArr = new M3::float_t[splineKnots];
250  M3::float_t* tmpManyCoeffArr = new M3::float_t[splineKnots*_nCoeff_];
251 
252  GetSplineCoeff_SepMany(splineindex, tmpXCoeffArr, tmpManyCoeffArr);
253 
254  nKnots_arr[ValidSplineCounter] = ValidKnotCounter;
255  for(int i = 0; i < splineKnots; i++){
256  xcoeff_arr[paramNo_arr[ValidSplineCounter]*_max_knots + i] = tmpXCoeffArr[i];
257 
258  for(int j = 0; j < _nCoeff_; j++){
259  manycoeff_arr[(ValidKnotCounter+i)*_nCoeff_+j]=tmpManyCoeffArr[i*_nCoeff_+j];
260  }
261  }
262  ValidKnotCounter += splineKnots;
263  delete[] tmpXCoeffArr;
264  delete[] tmpManyCoeffArr;
265  ValidSplineCounter++;
266  } else {
267  monolith_index[splineindex] = M3::_BAD_INT_;
268  }
269  }
270 
271  MoveToGPU();
272 
273  // initialise spline segment structure
274  SetupSegments();
275 }
void PrepForReweight()
Initialise flat structure.
void InvestigateMissingSplines() const
This function will find missing splines in file.
void GetSplineCoeff_SepMany(int splineindex, M3::float_t *&xArray, M3::float_t *&manyArray)
Rather work with spline coefficients in the splines, let's copy ND and use coefficient arrays.
int CountNumberOfLoadedSplines(bool NonFlat=false, int Verbosity=0) const
Count how many splines we have.

Member Data Documentation

◆ CoeffIndex

int BinnedSplineHandler::CoeffIndex
protected

Definition at line 116 of file BinnedSplineHandler.h.

◆ cpu_spline_weights

std::vector<M3::float_t> BinnedSplineHandler::cpu_spline_weights
protected

Stores weight from spline evaluation for each single spline.

Definition at line 126 of file BinnedSplineHandler.h.

◆ DimensionLabels

std::vector<std::vector<std::string> > BinnedSplineHandler::DimensionLabels
protected

Definition at line 81 of file BinnedSplineHandler.h.

◆ Dimensions

std::vector<int> BinnedSplineHandler::Dimensions
protected

Definition at line 80 of file BinnedSplineHandler.h.

◆ GlobalSystIndex

std::vector< std::vector<int> > BinnedSplineHandler::GlobalSystIndex
protected

This holds the global spline index and is used to grab the current parameter value to evaluate splines at. Each internal vector will be of size of the number of spline systematics which affect that sample.

Definition at line 95 of file BinnedSplineHandler.h.

◆ IndexVect

std::vector<SplineIndex> BinnedSplineHandler::IndexVect
protected

Variables related to determined which modes have splines and which piggy-back of other modes.

Definition at line 106 of file BinnedSplineHandler.h.

◆ IndexVectMap

std::map<std::tuple<int, int, int, int, std::vector<int> >, int> BinnedSplineHandler::IndexVectMap
protected

Map between spline origin/properties (iSample, iOscChan, iSyst, iMode, iVar1, iVar2, iVar3) and the index of the spline in IndexVect.

Definition at line 108 of file BinnedSplineHandler.h.

◆ manycoeff_arr

M3::float_t* BinnedSplineHandler::manycoeff_arr
protected

ybcd coefficients for each spline

Definition at line 123 of file BinnedSplineHandler.h.

◆ Modes

MaCh3Modes* BinnedSplineHandler::Modes
protected

pointer to MaCh3 Mode from which we get spline suffix

Definition at line 131 of file BinnedSplineHandler.h.

◆ monolith_index

std::vector<int> BinnedSplineHandler::monolith_index
protected

keep track which splines are flat (-1) otherwise map with flattened splines

Definition at line 119 of file BinnedSplineHandler.h.

◆ MonolithIndex

unsigned int BinnedSplineHandler::MonolithIndex
protected

Definition at line 115 of file BinnedSplineHandler.h.

◆ nKnots_arr

std::vector<unsigned int> BinnedSplineHandler::nKnots_arr
protected

KS: CPU Number of knots per spline.

Definition at line 110 of file BinnedSplineHandler.h.

◆ nOscChans

std::vector<int> BinnedSplineHandler::nOscChans
protected

Definition at line 83 of file BinnedSplineHandler.h.

◆ nSplineParams

std::vector<int> BinnedSplineHandler::nSplineParams
protected

Definition at line 82 of file BinnedSplineHandler.h.

◆ paramNo_arr

std::vector<short int> BinnedSplineHandler::paramNo_arr
protected

CW: CPU array with the number of points per spline (not per spline point!)

Definition at line 128 of file BinnedSplineHandler.h.

◆ ParHandler

ParameterHandlerGeneric* BinnedSplineHandler::ParHandler
protected

Pointer to covariance from which we get information about spline params.

Definition at line 75 of file BinnedSplineHandler.h.

◆ SampleNames

std::vector<std::string> BinnedSplineHandler::SampleNames
protected

Definition at line 78 of file BinnedSplineHandler.h.

◆ SampleTitles

std::vector<std::string> BinnedSplineHandler::SampleTitles
protected

Definition at line 79 of file BinnedSplineHandler.h.

◆ SplineBinning

std::vector< std::vector< std::vector<TAxis*> > > BinnedSplineHandler::SplineBinning
protected

Holds TAxis for [sample][channel][dimension].

Definition at line 85 of file BinnedSplineHandler.h.

◆ SplineFileParPrefixNames

std::vector< std::vector<std::string> > BinnedSplineHandler::SplineFileParPrefixNames
protected

[Sample][Syst]

Definition at line 87 of file BinnedSplineHandler.h.

◆ SplineInterpolationTypes

std::vector< std::vector<SplineInterpolation> > BinnedSplineHandler::SplineInterpolationTypes
protected

spline interpolation types for each sample. These vectors are from a call to GetSplineInterpolationFromSampleID()

Definition at line 98 of file BinnedSplineHandler.h.

◆ SplineModeVecs

std::vector< std::vector< std::vector<int> > > BinnedSplineHandler::SplineModeVecs
protected

A vector of vectors of the spline modes that a systematic applies to This gets compared against the event mode to figure out if a syst should apply to an event or not

Definition at line 91 of file BinnedSplineHandler.h.

◆ splinevec_Monolith

std::vector< TSpline3_red* > BinnedSplineHandler::splinevec_Monolith
protected

holds each spline object before stripping into coefficient monolith

Definition at line 113 of file BinnedSplineHandler.h.

◆ UniqueSystIndices

std::vector<int> BinnedSplineHandler::UniqueSystIndices
protected

Global index of each spline param, it allows us to match spline ordering with global.

Definition at line 103 of file BinnedSplineHandler.h.

◆ UniqueSystNames

std::vector<std::string> BinnedSplineHandler::UniqueSystNames
protected

name of each spline parameter

Definition at line 101 of file BinnedSplineHandler.h.

◆ xcoeff_arr

M3::float_t* BinnedSplineHandler::xcoeff_arr
protected

x coefficients for each spline

Definition at line 121 of file BinnedSplineHandler.h.


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