MaCh3  2.6.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_)
 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< SplineIndexGetEventSplines (const std::string &SampleTitle, int iOscChan, int EventMode, double Var1Val, double Var2Val, double Var3Val)
 Return the splines which affect a given event. More...
 
void SynchroniseMemTransfer () const final
 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...
 
int CountNumberOfLoadedSplines (bool NonFlat=false, int Verbosity=0) const
 Count how many splines we have. More...
 
const M3::float_tRetPointer (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 ()
 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...
 

Protected Types

enum  TokenOrdering {
  kSystToken , kModeToken , kVar1BinToken , kVar2BinToken ,
  kVar3BinToken , kNTokens
}
 

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...
 

Protected Attributes

ParameterHandlerGenericParHandler
 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< SplineIndexIndexVect
 Variables related to determined which modes have splines and which piggy-back of other modes. More...
 
std::map< std::tuple< int, int, int, int, int, int, 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< int > coeffindexvec
 Number of coefficients for a single flat (after flattening) More...
 
std::vector< int > uniquecoeffindices
 Unique coefficient indices. More...
 
std::vector< TSpline3_red * > splinevec_Monolith
 holds each spline object before stripping into coefficient monolith More...
 
int MonolithSize
 
int MonolithIndex
 
int CoeffIndex
 
bool * isflatarray
 Need to keep track of which splines are flat and which aren't. More...
 
M3::float_txcoeff_arr
 x coefficients for each spline More...
 
M3::float_tmanycoeff_arr
 ybcd coefficients for each spline More...
 
std::vector< M3::float_tweightvec_Monolith
 Stores weight from spline evaluation for each single spline. More...
 
std::vector< int > uniquesplinevec_Monolith
 Maps single spline object with single parameter. More...
 
MaCh3ModesModes
 pointer to MaCh3 Mode from which we get spline suffix More...
 
- Protected Attributes inherited from SplineBase
std::vector< FastSplineInfoSplineInfoArray
 
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...
 

Private Member Functions

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 
kVar1BinToken 
kVar2BinToken 
kVar3BinToken 
kNTokens 

Definition at line 141 of file BinnedSplineHandler.h.

Constructor & Destructor Documentation

◆ BinnedSplineHandler()

_MaCh3_Safe_Include_Start_ _MaCh3_Safe_Include_End_ BinnedSplineHandler::BinnedSplineHandler ( ParameterHandlerGeneric ParamHandler,
MaCh3Modes Modes_ 
)

Constructor.

Definition at line 14 of file BinnedSplineHandler.cpp.

14  : SplineBase() {
15 //****************************************
16  if (!ParHandler_) {
17  MACH3LOG_ERROR("Trying to create BinnedSplineHandler with uninitialized covariance object");
18  throw MaCh3Exception(__FILE__, __LINE__);
19  }
20  ParHandler = ParHandler_;
21 
22  if (!Modes_) {
23  MACH3LOG_ERROR("Trying to create BinnedSplineHandler with uninitialized MaCh3Modes object");
24  throw MaCh3Exception(__FILE__, __LINE__);
25  }
26  Modes = Modes_;
27 
28  // Keep these in class scope, important for using 1 monolith/sample!
29  MonolithIndex = 0; //Keeps track of the monolith index we're on when filling arrays (declared here so we can have multiple FillSampleArray calls)
30  CoeffIndex = 0; //Keeps track of our indexing the coefficient arrays [x, ybcd]
31  isflatarray = nullptr;
32 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
bool * isflatarray
Need to keep track of which splines are flat and which aren't.
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()
Constructor.
Definition: SplineBase.cpp:7

◆ ~BinnedSplineHandler()

BinnedSplineHandler::~BinnedSplineHandler ( )
virtual

Destructor.

Definition at line 35 of file BinnedSplineHandler.cpp.

35  {
36 //****************************************
37  if(manycoeff_arr != nullptr) delete[] manycoeff_arr;
38  if(xcoeff_arr != nullptr) delete[] xcoeff_arr;
39  if(SplineSegments != nullptr) delete[] SplineSegments;
40  if(ParamValues != nullptr) delete[] ParamValues;
41 }
M3::float_t * xcoeff_arr
x coefficients for each spline
M3::float_t * manycoeff_arr
ybcd coefficients for each spline
short int * SplineSegments
Definition: SplineBase.h:77
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:79

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 70 of file BinnedSplineHandler.cpp.

73  {
74 //****************************************
75  SampleNames.push_back(SampleName);
76  SampleTitles.push_back(SampleTitle);
77  Dimensions.push_back(static_cast<int>(SplineVarNames.size()));
78  DimensionLabels.push_back(SplineVarNames);
79 
80  int nSplineParam = ParHandler->GetNumParamsFromSampleName(SampleName, SystType::kSpline);
81  nSplineParams.push_back(nSplineParam);
82 
83  //This holds the global index of the spline i.e. 0 -> _fNumPar
84  std::vector<int> GlobalSystIndex_Sample = ParHandler->GetGlobalSystIndexFromSampleName(SampleName, SystType::kSpline);
85  //Keep track of this for all the samples
86  GlobalSystIndex.push_back(GlobalSystIndex_Sample);
87 
88  std::vector<SplineInterpolation> SplineInterpolation_Sample = ParHandler->GetSplineInterpolationFromSampleName(SampleName);
89  // Keep track of this for all samples
90  SplineInterpolationTypes.push_back(SplineInterpolation_Sample);
91 
92  std::vector<std::string> SplineFileParPrefixNames_Sample = ParHandler->GetSplineParsNamesFromSampleName(SampleName);
93  SplineFileParPrefixNames.push_back(SplineFileParPrefixNames_Sample);
94 
95  MACH3LOG_INFO("Create SplineModeVecs_Sample");
96  std::vector<std::vector<int>> SplineModeVecs_Sample = StripDuplicatedModes(ParHandler->GetSplineModeVecFromSampleName(SampleName));
97  MACH3LOG_INFO("SplineModeVecs_Sample is of size {}", SplineModeVecs_Sample.size());
98  SplineModeVecs.push_back(SplineModeVecs_Sample);
99 
100  MACH3LOG_INFO("SplineModeVecs is of size {}", SplineModeVecs.size());
101 
102  int nOscChan = int(OscChanFileNames.size());
103  nOscChans.push_back(nOscChan);
104 
105  PrintSampleDetails(SampleTitle);
106 
107  std::vector<std::vector<TAxis *>> SampleBinning(nOscChan);
108  for (int iOscChan = 0; iOscChan < nOscChan; iOscChan++)
109  {
110  SampleBinning[iOscChan] = FindSplineBinning(OscChanFileNames[iOscChan], SampleTitle);
111  }
112  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
113  SplineBinning.push_back(SampleBinning);
114 
115  BuildSampleIndexingArray(SampleTitle);
116  PrintArrayDetails(SampleTitle);
117  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
118 
119  FillSampleArray(SampleTitle, OscChanFileNames);
120  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
121 }
#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 310 of file BinnedSplineHandler.cpp.

310  {
311 //****************************************
312  int iSample = GetSampleIndex(SampleTitle);
313  for (int iOscChan = 0; iOscChan < nOscChans[iSample]; ++iOscChan)
314  {
315  for (int iSyst = 0; iSyst < nSplineParams[iSample]; ++iSyst)
316  {
317  int nModesInSyst = static_cast<int>(SplineModeVecs[iSample][iSyst].size());
318  for (int iMode = 0; iMode < nModesInSyst; ++iMode)
319  {
320  const int nBins1 = SplineBinning[iSample][iOscChan][0]->GetNbins();
321  const int nBins2 = SplineBinning[iSample][iOscChan][1]->GetNbins();
322  const int nBins3 = SplineBinning[iSample][iOscChan][2]->GetNbins();
323  for (int iVar1 = 0; iVar1 < nBins1; ++iVar1) {
324  for (int iVar2 = 0; iVar2 < nBins2; ++iVar2) {
325  for (int iVar3 = 0; iVar3 < nBins3; ++iVar3) {
326  SplineIndex entry;
327  entry.value = -1;
328  entry.iSample = iSample;
329  entry.iOscChan = iOscChan;
330  entry.iSyst = iSyst;
331  entry.iMode = iMode;
332  entry.iVar = {iVar1, iVar2, iVar3};
333  IndexVect.push_back(entry);
334  IndexVectMap[std::make_tuple(iSample, iOscChan, iSyst, iMode, iVar1, iVar2, iVar3)] = static_cast<int>(IndexVect.size() - 1);
335  }
336  }
337  }
338  }
339  }
340  }
341 }
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, int, int, 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.

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 270 of file BinnedSplineHandler.cpp.

270  {
271 //****************************************
272  #ifdef MULTITHREAD
273  #pragma omp parallel for simd
274  #endif
275  for (size_t iCoeff = 0; iCoeff < uniquecoeffindices.size(); ++iCoeff)
276  {
277  const int iSpline = uniquecoeffindices[iCoeff];
278  const short int uniqueIndex = short(uniquesplinevec_Monolith[iSpline]);
279  const short int currentsegment = short(SplineSegments[uniqueIndex]);
280 
281  const int segCoeff = coeffindexvec[iSpline]+currentsegment;
282  const int coeffOffset = segCoeff * _nCoeff_;
283  // These are what we can extract from the TSpline3
284  const M3::float_t y = manycoeff_arr[coeffOffset+kCoeffY];
285  const M3::float_t b = manycoeff_arr[coeffOffset+kCoeffB];
286  const M3::float_t c = manycoeff_arr[coeffOffset+kCoeffC];
287  const M3::float_t d = manycoeff_arr[coeffOffset+kCoeffD];
288 
289  // Get the variation for this reconfigure for the i-th parameter
291  const M3::float_t xvar = (*SplineInfoArray[uniqueIndex].splineParsPointer);
292  // The Delta(x) = xvar - x
293  const M3::float_t dx = xvar - xcoeff_arr[segCoeff];
294 
295  //Speedy 1% time boost https://en.cppreference.com/w/c/numeric/math/fma (see ND code!)
296  M3::float_t weight = M3::fmaf_t(dx, M3::fmaf_t(dx, M3::fmaf_t(dx, d, c), b), y);
297  //This is the speedy version of writing dx^3+b*dx^2+c*dx+d
298 
299  //ETA - do we need this? We check later for negative weights and I wonder if this is even
300  //possible with the fmaf line above?
301  if(weight < 0){weight = 0.;} //Stops is getting negative weights
302 
303  weightvec_Monolith[iSpline] = weight;
304  }
305 }
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< int > coeffindexvec
Number of coefficients for a single flat (after flattening)
std::vector< int > uniquesplinevec_Monolith
Maps single spline object with single parameter.
std::vector< M3::float_t > weightvec_Monolith
Stores weight from spline evaluation for each single spline.
std::vector< int > uniquecoeffindices
Unique coefficient indices.
std::vector< FastSplineInfo > SplineInfoArray
Definition: SplineBase.h:74
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 44 of file BinnedSplineHandler.cpp.

44  {
45 //****************************************
46  //Call once everything's been allocated in SampleHandlerBase, cleans up junk from memory!
47  //Not a huge saving but it's better than leaving everything up to the compiler
48  MACH3LOG_INFO("Cleaning up spline memory");
50  IndexVectMap.clear();
65  if(isflatarray) delete [] isflatarray;
66 }
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< 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 452 of file BinnedSplineHandler.cpp.

452  {
453 //****************************************
454  std::vector<int> SampleAll(SampleTitles.size(), 0);
455  std::vector<int> SampleNonFlat(SampleTitles.size(), 0);
456 
457  int FullCounter_All = 0;
458  int FullCounter_NonFlat = 0;
459 
460  for (unsigned int index = 0; index < IndexVect.size(); index++)
461  {
462  const auto& entry = IndexVect[index];
463 
464  int iSample = entry.iSample;
465 
466  std::string SampleTitle = SampleTitles[iSample];
467 
468  if (!isValidSplineIndex(SampleTitle, entry.iOscChan, entry.iSyst,
469  entry.iMode, entry.iVar)) {
470  continue;
471  }
472  SampleAll[iSample]++;
473 
474  if (splinevec_Monolith[entry.value]) {
475  SampleNonFlat[iSample]++;
476  }
477  }
478 
479  // Print per-sample summary
480  for (size_t iSample = 0; iSample < SampleTitles.size(); iSample++)
481  {
482  MACH3LOG_DEBUG("{:<10} has {:<10} splines, of which {:<10} are not flat",
483  SampleTitles[iSample],
484  SampleAll[iSample],
485  SampleNonFlat[iSample]);
486 
487  FullCounter_All += SampleAll[iSample];
488  FullCounter_NonFlat += SampleNonFlat[iSample];
489  }
490 
491  if (Verbosity > 0) {
492  MACH3LOG_INFO("Total number of splines loaded: {}", FullCounter_All);
493  MACH3LOG_INFO("Total number of non-flat splines loaded: {}", FullCounter_NonFlat);
494  }
495 
496  if (NonFlat) {
497  return FullCounter_NonFlat;
498  } else {
499  return FullCounter_All;
500  }
501 }
#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 259 of file BinnedSplineHandler.cpp.

259  {
260 // *****************************************
261  // There's a parameter mapping that goes from spline parameter to a global parameter index
262  // Find the spline segments
264 
265  //KS: Huge MP loop over all valid splines
267 }
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:44

◆ 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 802 of file BinnedSplineHandler.cpp.

803 {
804  int iSample = GetSampleIndex(SampleTitle);
805  int nOscChannels = nOscChans[iSample];
806 
807  for (int iOscChan = 0; iOscChan < nOscChannels; iOscChan++) {
808  MACH3LOG_INFO("Processing: {}", OscChanFileNames[iOscChan]);
809  TSpline3* mySpline = nullptr;
810  TSpline3_red* Spline = nullptr;
811 
812  std::set<std::string> SplineFileNames;
813  auto File = std::unique_ptr<TFile>(TFile::Open(OscChanFileNames[iOscChan].c_str()));
814 
815  if (!File || File->IsZombie()) {
816  MACH3LOG_ERROR("File {} not found", OscChanFileNames[iOscChan]);
817  throw MaCh3Exception(__FILE__, __LINE__);
818  }
819 
820  //This is the MC specific part of the code
821  //i.e. we always assume that the splines are just store in single TDirectory and they're all in there as single objects
822  for (auto k : *File->GetListOfKeys()) {
823  auto Key = static_cast<TKey*>(k);
824  TClass *Class = gROOT->GetClass(Key->GetClassName(), false);
825  if(!Class->InheritsFrom("TSpline3")) {
826  continue;
827  }
828 
829  std::string FullSplineName = std::string(Key->GetName());
830 
831  if (SplineFileNames.count(FullSplineName) > 0) {
832  MACH3LOG_CRITICAL("Skipping spline - Found a spline whose name has already been encountered before: {}", FullSplineName);
833  continue;
834  }
835  SplineFileNames.insert(FullSplineName);
836 
837  std::vector<std::string> Tokens = GetTokensFromSplineName(FullSplineName);
838 
839  if (Tokens.size() != kNTokens) {
840  MACH3LOG_ERROR("Invalid tokens from spline name - Expected {} tokens. Check implementation in GetTokensFromSplineName()", static_cast<int>(kNTokens));
841  throw MaCh3Exception(__FILE__, __LINE__);
842  }
843 
844  TString Syst = Tokens[kSystToken];
845  TString Mode = Tokens[kModeToken];
846  int Var1Bin = std::stoi(Tokens[kVar1BinToken]);
847  int Var2Bin = std::stoi(Tokens[kVar2BinToken]);
848  int Var3Bin = std::stoi(Tokens[kVar3BinToken]);
849 
850  int SystNum = -1;
851  for (unsigned iSyst = 0; iSyst < SplineFileParPrefixNames[iSample].size(); iSyst++) {
852  if (Syst == SplineFileParPrefixNames[iSample][iSyst]) {
853  SystNum = iSyst;
854  break;
855  }
856  }
857 
858  // If the syst doesn't match any of the spline names then skip it
859  if (SystNum == -1){
860  MACH3LOG_DEBUG("Couldn't Match any systematic name in ParameterHandler with spline name: {}" , FullSplineName);
861  continue;
862  }
863 
864  int ModeNum = -1;
865  for (unsigned int iMode = 0; iMode < SplineModeVecs[iSample][SystNum].size(); iMode++) {
866  if (Mode == Modes->GetSplineSuffixFromMaCh3Mode(SplineModeVecs[iSample][SystNum][iMode])) {
867  ModeNum = iMode;
868  break;
869  }
870  }
871 
872  if (ModeNum == -1) {
873  //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
874  // Therefore include as debug warning and continue instead
875  MACH3LOG_DEBUG("Couldn't find mode for {} in {}. Problem Spline is : {} ", Mode, Syst, FullSplineName);
876  continue;
877  }
878 
879  mySpline = Key->ReadObject<TSpline3>();
880  // loop over all the spline knots and check their value
881  if (isValidSplineIndex(SampleTitle, iOscChan, SystNum, ModeNum, {Var1Bin, Var2Bin, Var3Bin})) {
882  MACH3LOG_TRACE("Pushed back monolith for spline {}", FullSplineName);
883  // if the value is 1 then set the flat bool to false
884  int nKnots = mySpline->GetNp();
885  bool isFlat = true;
886  for (int iKnot = 0; iKnot < nKnots; iKnot++) {
887  double x, y = M3::_BAD_DOUBLE_;
888  mySpline->GetKnot(iKnot, x, y);
889  if (y < 0.99999 || y > 1.00001)
890  {
891  isFlat = false;
892  break;
893  }
894  }
895 
896  //Rather than keeping a mega vector of splines then converting, this should just keep everything nice in memory!
897  int index = IndexVectMap.at(std::make_tuple(iSample, iOscChan, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin));
898  IndexVect[index].value = MonolithIndex;
899  coeffindexvec.push_back(CoeffIndex);
900  // Should save memory rather saving [x_i_0 ,... x_i_maxknots] for every spline!
901  if (isFlat) {
902  splinevec_Monolith.push_back(nullptr);
903  delete mySpline;
904  } else {
905  ApplyKnotWeightCapTSpline3(mySpline, SystNum, ParHandler);
906  Spline = new TSpline3_red(mySpline, SplineInterpolationTypes[iSample][SystNum]);
907  if(mySpline) delete mySpline;
908 
909  splinevec_Monolith.push_back(Spline);
910  uniquecoeffindices.push_back(MonolithIndex); //So we can get the unique coefficients and skip flat splines later on!
911  CoeffIndex+=nKnots;
912  }
913  //Incrementing MonolithIndex to keep track of number of valid spline indices
914  MonolithIndex+=1;
915  } else {
916  //Potentially you are not a valid spline index
917  delete mySpline;
918  }
919  }//End of loop over all TKeys in file
920 
921  //A bit of clean up
922  File->Delete("*");
923  File->Close();
924  } //End of oscillation channel loop
925 }
#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.

Definition at line 344 of file BinnedSplineHandler.cpp.

344  {
345 //****************************************
346  int iSample = GetSampleIndex(SampleTitle);
347 
348  //Try declaring these outside of TFile so they aren't owned by File
349  constexpr int nDummyBins = 1;
350  constexpr double DummyEdges[2] = {-1e15, 1e15};
351  TAxis* DummyAxis = new TAxis(nDummyBins, DummyEdges);
352  TH2F* Hist2D = nullptr;
353  TH3F* Hist3D = nullptr;
354 
355  auto File = std::unique_ptr<TFile>(TFile::Open(FileName.c_str(), "READ"));
356  if (!File || File->IsZombie())
357  {
358  MACH3LOG_ERROR("File {} not found", FileName);
359  MACH3LOG_ERROR("This is caused by something here! {} : {}", __FILE__, __LINE__);
360  throw MaCh3Exception(__FILE__ , __LINE__ );
361  }
362 
363  MACH3LOG_INFO("Finding binning for:");
364  MACH3LOG_INFO("{}", FileName);
365 
366  std::string TemplateName = "dev_tmp_0_0";
367  TObject *Obj = File->Get(TemplateName.c_str());
368  //If you can't find dev_tmp_0_0 then this will cause a problem
369  if (!Obj)
370  {
371  TemplateName = "dev_tmp.0.0";
372  Obj = File->Get(TemplateName.c_str());
373  if (!Obj)
374  {
375  MACH3LOG_ERROR("Could not find dev_tmp_0_0 in spline file. Spline binning cannot be set!");
376  MACH3LOG_ERROR("FileName: {}", FileName);
377  throw MaCh3Exception(__FILE__ , __LINE__ );
378  }
379  }
380 
381  //Now check if dev_tmp_0_0 is a TH2 i.e. specifying the dimensions of the splines is 2D
382  bool isHist2D = Obj->IsA() == TH2F::Class();
383  //For T2K annoyingly all objects are TH3Fs
384  bool isHist3D = Obj->IsA() == TH3F::Class();
385  if (!isHist2D && !isHist3D)
386  {
387  MACH3LOG_ERROR("Object doesn't inherit from either TH2D and TH3D - Odd A");
388  throw MaCh3Exception(__FILE__ , __LINE__ );
389  }
390 
391  if (isHist2D)
392  {
393  if (Dimensions[iSample] != 2)
394  {
395  MACH3LOG_ERROR("Trying to load a 2D spline template when nDim={}", Dimensions[iSample]);
396  throw MaCh3Exception(__FILE__, __LINE__);
397  }
398  Hist2D = File->Get<TH2F>(TemplateName.c_str());
399  }
400 
401  if (isHist3D)
402  {
403  Hist3D = File->Get<TH3F>((TemplateName.c_str()));
404  if (Dimensions[iSample] != 3 && Hist3D->GetZaxis()->GetNbins() != 1)
405  {
406  MACH3LOG_ERROR("Trying to load a 3D spline template when nDim={}", Dimensions[iSample]);
407  throw MaCh3Exception(__FILE__ , __LINE__ );
408  }
409  }
410 
411  std::vector<TAxis*> ReturnVec;
412  // KS: Resize to reduce impact of push back and memory fragmentation
413  ReturnVec.resize(3);
414  if (Dimensions[iSample] == 2) {
415  if (isHist2D) {
416  ReturnVec[0] = static_cast<TAxis*>(Hist2D->GetXaxis()->Clone());
417  ReturnVec[1] = static_cast<TAxis*>(Hist2D->GetYaxis()->Clone());
418  ReturnVec[2] = static_cast<TAxis*>(DummyAxis->Clone());
419  } else if (isHist3D) {
420  ReturnVec[0] = static_cast<TAxis*>(Hist3D->GetXaxis()->Clone());
421  ReturnVec[1] = static_cast<TAxis*>(Hist3D->GetYaxis()->Clone());
422  ReturnVec[2] = static_cast<TAxis*>(DummyAxis->Clone());
423  }
424  } else if (Dimensions[iSample] == 3) {
425  ReturnVec[0] = static_cast<TAxis*>(Hist3D->GetXaxis()->Clone());
426  ReturnVec[1] = static_cast<TAxis*>(Hist3D->GetYaxis()->Clone());
427  ReturnVec[2] = static_cast<TAxis*>(Hist3D->GetZaxis()->Clone());
428  } else {
429  MACH3LOG_ERROR("Number of dimensions not valid! Given: {}", Dimensions[iSample]);
430  throw MaCh3Exception(__FILE__, __LINE__);
431  }
432 
433  for (unsigned int iAxis = 0; iAxis < ReturnVec.size(); ++iAxis) {
434  PrintBinning(ReturnVec[iAxis]);
435  }
436 
437  MACH3LOG_INFO("Left PrintBinning now tidying up");
438  delete DummyAxis;
439 
440  return ReturnVec;
441 }
void PrintBinning(TAxis *Axis) const
Print spline binning.

◆ GetEventSplines()

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

Return the splines which affect a given event.

Definition at line 708 of file BinnedSplineHandler.cpp.

710  {
711 //****************************************
712  std::vector<SplineIndex> ReturnVec;
713  int SampleIndex = GetSampleIndex(SampleTitle);
714 
715  int Mode = -1;
716  std::string SuffixForEventMode = Modes->GetSplineSuffixFromMaCh3Mode(EventMode);
717  for (int iMode = 0; iMode< Modes->GetNModes(); iMode++) {
718  if (SuffixForEventMode == Modes->GetSplineSuffixFromMaCh3Mode(iMode)) {
719  Mode = iMode;
720  break;
721  }
722  }
723  if (Mode == -1) {
724  return ReturnVec;
725  }
726 
727  std::vector<int> var_bins;
728  std::vector<double> vars = {Var1Val, Var2Val, Var3Val};
729  for (size_t i = 0; i < vars.size(); ++i) {
730  int bin = SplineBinning[SampleIndex][iOscChan][i]->FindBin(vars[i]) - 1;
731  if (bin < 0 || bin >= SplineBinning[SampleIndex][iOscChan][i]->GetNbins()) {
732  return ReturnVec;
733  }
734  var_bins.push_back(bin);
735  }
736 
737  for(int iSyst=0; iSyst < nSplineParams[SampleIndex]; iSyst++){
738  std::vector<int> spline_modes = SplineModeVecs[SampleIndex][iSyst];
739  int nSampleModes = static_cast<int>(spline_modes.size());
740 
741  //ETA - look here at the length of spline_modes and what you're actually comparing against
742  for(int iMode = 0; iMode<nSampleModes; iMode++) {
743  //Only consider if the event mode (Mode) matches ones of the spline modes
744  if (Mode == spline_modes[iMode]) {
745  int index = IndexVectMap.at(std::make_tuple(SampleIndex, iOscChan, iSyst, iMode,
746  var_bins[0], var_bins[1], var_bins[2]));
747  int splineID = IndexVect[index].value;
748  //Also check that the spline isn't flat
749  if(!isflatarray[splineID]) {
750  SplineIndex idx;
751  idx.iSample = SampleIndex;
752  idx.iOscChan = iOscChan;
753  idx.iSyst = iSyst;
754  idx.iMode = iMode;
755  idx.iVar = var_bins;
756  ReturnVec.push_back(idx);
757  }
758  }
759  }
760  }
761  return ReturnVec;
762 }
int GetNModes() const
KS: Get number of modes, keep in mind actual number is +1 greater due to unknown category.
Definition: MaCh3Modes.h:155

◆ 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 630 of file BinnedSplineHandler.cpp.

630  {
631 //****************************************
632  for (size_t iSample = 0; iSample < SampleTitles.size(); ++iSample) {
633  if (SampleTitle == SampleTitles[iSample]) {
634  return static_cast<int>(iSample);
635  }
636  }
637  MACH3LOG_ERROR("Sample name not found: {}", SampleTitle);
638  throw MaCh3Exception(__FILE__, __LINE__);
639 }

◆ 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 593 of file BinnedSplineHandler.cpp.

593  {
594 //****************************************
595  //No point evaluating a flat spline
596  int nPoints = splinevec_Monolith[splineindex]->GetNp();
597 
598  for (int i = 0; i < nPoints; i++) {
599  xArray[i] = 1.0;
600  for (int j = 0; j < _nCoeff_; j++) {
601  manyArray[i*_nCoeff_+j] = 1.0;
602  }
603  }
604 
605  for(int i=0; i<nPoints; i++) {
606  M3::float_t x = M3::float_t(-999.99);
607  M3::float_t y = M3::float_t(-999.99);
608  M3::float_t b = M3::float_t(-999.99);
609  M3::float_t c = M3::float_t(-999.99);
610  M3::float_t d = M3::float_t(-999.99);
611  splinevec_Monolith[splineindex]->GetCoeff(i, x, y, b, c, d);
612 
613  // Store the coefficients for each knot contiguously in memory
614  // 4 because manyArray stores y,b,c,d
615  xArray[i] = x;
616  manyArray[i * _nCoeff_ + kCoeffY] = y;
617  manyArray[i * _nCoeff_ + kCoeffB] = b;
618  manyArray[i * _nCoeff_ + kCoeffC] = c;
619  manyArray[i * _nCoeff_ + kCoeffD] = d;
620  }
621 
622  //We now clean up the splines!
623  delete splinevec_Monolith[splineindex];
624  splinevec_Monolith[splineindex] = nullptr;
625 }

◆ 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 124 of file BinnedSplineHandler.cpp.

124  {
125 //****************************************
126  // Map: iSample → iSyst → modeSuffix → {totalSplines, zeroCount}
127  std::map<unsigned int, std::map<unsigned int, std::map<std::string, std::pair<unsigned int, unsigned int>>>> systZeroCounts;
128  for (const auto& entry : IndexVect) {
129  unsigned int iSample = entry.iSample;
130  unsigned int iSyst = entry.iSyst;
131 
132  std::string SampleName = SampleNames[iSample];
133  // Get the mode suffix string
134  std::string modeSuffix = Modes->GetSplineSuffixFromMaCh3Mode(SplineModeVecs[iSample][entry.iSyst][entry.iMode]);
135  auto& counts = systZeroCounts[iSample][iSyst][modeSuffix];
136 
137  counts.first++; // totalSplines
138  if (entry.value == -1)
139  {
140  counts.second++; // zeroCount
141  if (counts.second > 1)
142  {
144  "Sample '{}' | OscChan {} | Syst '{}' | Mode '{}' | Var {} => Value: {}",
145  SampleTitles[iSample],
146  entry.iOscChan,
147  SplineFileParPrefixNames[iSample][iSyst],
148  modeSuffix,
149  fmt::join(entry.iVar, " "),
150  entry.value
151  );
152  }
153  }
154  }
155 
156  // KS: Let's print this atrocious mess...
157  for (const auto& samplePair : systZeroCounts) {
158  unsigned int iSample = samplePair.first;
159  std::vector<std::string> SplineFileParPrefixNames_Sample = ParHandler->GetParsNamesFromSampleName(SampleNames[iSample], kSpline);
160  for (const auto& systPair : samplePair.second) {
161  unsigned int iSyst = systPair.first;
162  const auto& systName = SplineFileParPrefixNames_Sample[iSyst];
163  for (const auto& modePair : systPair.second) {
164  const auto& modeSuffix = modePair.first;
165  const auto& counts = modePair.second;
167  "Sample '{}': Systematic '{}' has missing splines in mode '{}'. Expected Splines: {}, Missing Splines: {}",
168  SampleTitles[iSample],
169  systName,
170  modeSuffix,
171  counts.first,
172  counts.second
173  );
174  }
175  }
176  }
177 }
const std::vector< std::string > GetParsNamesFromSampleName(const std::string &SampleName, const SystType Type) const
DB Grab the parameter names for the relevant SampleName.

◆ 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 673 of file BinnedSplineHandler.cpp.

674  {
675 //****************************************
676  int iSample = GetSampleIndex(SampleTitle);
677 
678  bool found = IndexVectMap.find(std::make_tuple(iSample, iOscChan, iSyst, iMode, iVar[0], iVar[1], iVar[2])) != IndexVectMap.end();
679 
680  if (!found)
681  {
682  MACH3LOG_ERROR("Given iSample: {}", iSample);
683  MACH3LOG_ERROR("Given iOscChan: {}", iOscChan);
684  MACH3LOG_ERROR("Given iSyst: {}", iSyst);
685  MACH3LOG_ERROR("Given iMode: {}", iMode);
686  for (size_t i = 0; i < iVar.size(); ++i) {
687  MACH3LOG_ERROR("Given iVar{}: {}", i, iVar[i]);
688  }
689  MACH3LOG_ERROR("Come visit me at : {} : {}", __FILE__, __LINE__);
690  throw MaCh3Exception(__FILE__, __LINE__);
691  }
692 
693  return true;
694 }

◆ 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 1054 of file BinnedSplineHandler.cpp.

1054  {
1055 // *****************************************
1056  TTree *IndexTree = SplineFile->Get<TTree>("IndexVec");
1057 
1058  SplineIndex* IndexTemp = nullptr;
1059  IndexTree->SetBranchAddress("SplineIndex", &IndexTemp);
1060  IndexVect.resize(IndexTree->GetEntries());
1061  // Fill indexvec with data from IndexTree
1062  for (Long64_t iEntry = 0; iEntry < IndexTree->GetEntries(); ++iEntry) {
1063  IndexTree->GetEntry(iEntry);
1064  IndexVect[iEntry] = *IndexTemp;
1065 
1066  auto key = std::make_tuple(IndexTemp->iSample, IndexTemp->iOscChan, IndexTemp->iSyst,
1067  IndexTemp->iMode, IndexTemp->iVar[0], IndexTemp->iVar[1],
1068  IndexTemp->iVar[2]);
1069  IndexVectMap[key] = static_cast<int>(iEntry);
1070  }
1071 
1072  // Load SplineBinning data
1073  TTree *SplineBinningTree = SplineFile->Get<TTree>("SplineBinningTree");
1074  std::vector<int> indices(3);
1075  SplineBinningTree->SetBranchAddress("i", &indices[0]);
1076  SplineBinningTree->SetBranchAddress("j", &indices[1]);
1077  SplineBinningTree->SetBranchAddress("k", &indices[2]);
1078  TAxis* axis = nullptr;
1079  SplineBinningTree->SetBranchAddress("axis", &axis);
1080 
1081  // Reconstruct TAxis objects
1082  for (Long64_t entry = 0; entry < SplineBinningTree->GetEntries(); ++entry) {
1083  SplineBinningTree->GetEntry(entry);
1084  int i = indices[0];
1085  int j = indices[1];
1086  int k = indices[2];
1087  SplineBinning[i][j][k] = static_cast<TAxis*>(axis->Clone());
1088  }
1089 
1090  std::vector<int> indices_mode(3);
1091  int mode_value;
1092  TTree *SplineModeTree = SplineFile->Get<TTree>("SplineModeTree");
1093  SplineModeTree->SetBranchAddress("i", &indices_mode[0]);
1094  SplineModeTree->SetBranchAddress("j", &indices_mode[1]);
1095  SplineModeTree->SetBranchAddress("k", &indices_mode[2]);
1096  SplineModeTree->SetBranchAddress("value", &mode_value);
1097 
1098  // Fill SplineModeVecs with values from the tree
1099  for (Long64_t entry = 0; entry < SplineModeTree->GetEntries(); ++entry) {
1100  SplineModeTree->GetEntry(entry);
1101  int i = indices_mode[0];
1102  int j = indices_mode[1];
1103  int k = indices_mode[2];
1104  SplineModeVecs[i][j][k] = mode_value;
1105  }
1106 }

◆ 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 1020 of file BinnedSplineHandler.cpp.

1020  {
1021 // *****************************************
1022  TTree *MonolithTree = SplineFile->Get<TTree>("MonolithTree");
1023 
1025  MonolithTree->SetBranchAddress("manycoeff", manycoeff_arr);
1026  isflatarray = new bool[MonolithSize];
1028  MonolithTree->SetBranchAddress("isflatarray", isflatarray);
1029 
1030  // Load vectors
1031  std::vector<int>* coeffindexvec_temp = nullptr;
1032  MonolithTree->SetBranchAddress("coeffindexvec", &coeffindexvec_temp);
1033  std::vector<int>* uniquecoeffindices_temp = nullptr;
1034  MonolithTree->SetBranchAddress("uniquecoeffindices", &uniquecoeffindices_temp);
1035  std::vector<int>* uniquesplinevec_Monolith_temp = nullptr;
1036  MonolithTree->SetBranchAddress("uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1037  std::vector<int>* UniqueSystIndices_temp = nullptr;
1038  MonolithTree->SetBranchAddress("UniqueSystIndices", &UniqueSystIndices_temp);
1039 
1040  // Allocate and load xcoeff_arr
1042  MonolithTree->SetBranchAddress("xcoeff", xcoeff_arr);
1043 
1044  MonolithTree->GetEntry(0);
1045 
1046  coeffindexvec = *coeffindexvec_temp;
1047  uniquecoeffindices = *uniquecoeffindices_temp;
1048  uniquesplinevec_Monolith = *uniquesplinevec_Monolith_temp;
1049  UniqueSystIndices = *UniqueSystIndices_temp;
1050 }

◆ 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 968 of file BinnedSplineHandler.cpp.

968  {
969 // *****************************************
970  TTree *Settings = SplineFile->Get<TTree>("Settings");
971  int CoeffIndex_temp, MonolithSize_temp;
972  short int nParams_temp;
973  Settings->SetBranchAddress("CoeffIndex", &CoeffIndex_temp);
974  Settings->SetBranchAddress("MonolithSize", &MonolithSize_temp);
975  Settings->SetBranchAddress("nParams", &nParams_temp);
976 
977  int SplineBinning_size1, SplineBinning_size2, SplineBinning_size3;
978  Settings->SetBranchAddress("SplineBinning_size1", &SplineBinning_size1);
979  Settings->SetBranchAddress("SplineBinning_size2", &SplineBinning_size2);
980  Settings->SetBranchAddress("SplineBinning_size3", &SplineBinning_size3);
981  int SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3;
982  Settings->SetBranchAddress("SplineModeVecs_size1", &SplineModeVecs_size1);
983  Settings->SetBranchAddress("SplineModeVecs_size2", &SplineModeVecs_size2);
984  Settings->SetBranchAddress("SplineModeVecs_size3", &SplineModeVecs_size3);
985  std::vector<std::string>* SampleNames_temp = nullptr;
986  Settings->SetBranchAddress("SampleNames", &SampleNames_temp);
987  std::vector<std::string>* SampleTitles_temp = nullptr;
988  Settings->SetBranchAddress("SampleTitles", &SampleTitles_temp);
989  std::vector<int>* nSplineParams_temp = nullptr;
990  Settings->SetBranchAddress("nSplineParams", &nSplineParams_temp);
991  Settings->GetEntry(0);
992 
993  CoeffIndex = CoeffIndex_temp;
994  MonolithSize = MonolithSize_temp;
995  SampleNames = *SampleNames_temp;
996  SampleTitles = *SampleTitles_temp;
997  nSplineParams = *nSplineParams_temp;
998 
999  nParams = nParams_temp;
1000 
1001  SplineSegments = new short int[nParams]();
1002  ParamValues = new float[nParams]();
1003 
1004  auto Resize3D = [](auto& vec, int d1, int d2, int d3) {
1005  vec.resize(d1);
1006  for (int i = 0; i < d1; ++i) {
1007  vec[i].resize(d2);
1008  for (int j = 0; j < d2; ++j) {
1009  vec[i][j].resize(d3);
1010  }
1011  }
1012  };
1013 
1014  Resize3D(SplineBinning, SplineBinning_size1, SplineBinning_size2, SplineBinning_size3);
1015  Resize3D(SplineModeVecs, SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3);
1016 }
short int nParams
Number of parameters that have splines.
Definition: SplineBase.h:81

◆ 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 929 of file BinnedSplineHandler.cpp.

929  {
930 // *****************************************
931  M3::AddPath(FileName);
932 
933  // Check for spaces in the filename
934  size_t pos = FileName.find(' ');
935  if (pos != std::string::npos) {
936  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
937  while ((pos = FileName.find(' ')) != std::string::npos) {
938  FileName[pos] = '_';
939  }
940  }
941  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "OPEN");
942 
943  TMacro *ConfigCov = SplineFile->Get<TMacro>("ParameterHandler");
944  // Config which was in MCMC from which we are starting
945  YAML::Node CovSettings = TMacroToYAML(*ConfigCov);
946  // Config from currently used cov object
947  YAML::Node ConfigCurrent = ParHandler->GetConfig();
948 
949  if (!compareYAMLNodes(CovSettings, ConfigCurrent))
950  {
951  MACH3LOG_ERROR("Loading precomputed spline file, however encountered different YAML config, please regenerate input");
952  throw MaCh3Exception(__FILE__ , __LINE__ );
953  }
954 
955  LoadSettingsDir(SplineFile);
956  LoadMonolithDir(SplineFile);
957  LoadIndexDir(SplineFile);
958  LoadFastSplineInfoDir(SplineFile);
959 
960  for (int iSpline = 0; iSpline < nParams; iSpline++) {
961  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
962  }
963  SplineFile->Close();
964 }
#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:152
bool compareYAMLNodes(const YAML::Node &node1, const YAML::Node &node2, bool Mute=false)
Compare if yaml nodes are identical.
Definition: YamlHelper.h:186
void LoadIndexDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Index.
void LoadSettingsDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Settings.
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:167
void AddPath(std::string &FilePath)
Prepends the MACH3 environment path to FilePath if it is not already present.
Definition: Monitor.cpp:382

◆ 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 1201 of file BinnedSplineHandler.cpp.

1201  {
1202 // *****************************************
1203  // Create a TTree to store the data
1204  TTree *IndexTree = new TTree("IndexVec", "IndexVec");
1205  SplineIndex entry;
1206  IndexTree->Branch("SplineIndex", &entry);
1207  for (const auto& e : IndexVect) {
1208  entry = e;
1209  IndexTree->Fill();
1210  }
1211 
1212  SplineFile->cd();
1213  IndexTree->Write();
1214  delete IndexTree;
1215 }

◆ 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 1178 of file BinnedSplineHandler.cpp.

1178  {
1179 // *****************************************
1180  TTree *MonolithTree = new TTree("MonolithTree", "MonolithTree");
1181  MonolithTree->Branch("manycoeff", manycoeff_arr, Form("manycoeff[%d]/%s", CoeffIndex * _nCoeff_, M3::float_t_str_repr));
1182  MonolithTree->Branch("isflatarray", isflatarray, Form("isflatarray[%d]/O", MonolithSize));
1183 
1184  std::vector<int> coeffindexvec_temp = coeffindexvec;
1185  MonolithTree->Branch("coeffindexvec", &coeffindexvec_temp);
1186  std::vector<int> uniquecoeffindices_temp = uniquecoeffindices;
1187  MonolithTree->Branch("uniquecoeffindices", &uniquecoeffindices_temp);
1188  std::vector<int> uniquesplinevec_Monolith_temp = uniquesplinevec_Monolith;
1189  MonolithTree->Branch("uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1190  std::vector<int> UniqueSystIndices_temp = UniqueSystIndices;
1191  MonolithTree->Branch("UniqueSystIndices", &UniqueSystIndices_temp);
1192  MonolithTree->Branch("xcoeff", xcoeff_arr, Form("xcoeff[%d]/%s", CoeffIndex, M3::float_t_str_repr));
1193 
1194  MonolithTree->Fill();
1195  SplineFile->cd();
1196  MonolithTree->Write();
1197  delete MonolithTree;
1198 }
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 1218 of file BinnedSplineHandler.cpp.

1218  {
1219 // *****************************************
1220  // Create a new tree for SplineBinning data
1221  TTree *SplineBinningTree = new TTree("SplineBinningTree", "SplineBinningTree");
1222  std::vector<int> indices(3); // To store the 3D indices
1223  TAxis* axis = nullptr;
1224  SplineBinningTree->Branch("i", &indices[0], "i/I");
1225  SplineBinningTree->Branch("j", &indices[1], "j/I");
1226  SplineBinningTree->Branch("k", &indices[2], "k/I");
1227  SplineBinningTree->Branch("axis", "TAxis", &axis);
1228 
1229  // Fill the SplineBinningTree
1230  for (size_t i = 0; i < SplineBinning.size(); ++i) {
1231  for (size_t j = 0; j < SplineBinning[i].size(); ++j) {
1232  for (size_t k = 0; k < SplineBinning[i][j].size(); ++k) {
1233  axis = SplineBinning[i][j][k];
1234  indices[0] = static_cast<int>(i);
1235  indices[1] = static_cast<int>(j);
1236  indices[2] = static_cast<int>(k);
1237  SplineBinningTree->Fill();
1238  }
1239  }
1240  }
1241  SplineFile->cd();
1242  SplineBinningTree->Write();
1243  delete SplineBinningTree;
1244 
1245  std::vector<int> indices_mode(3); // to store 3D indices
1246  int mode_value;
1247 
1248  TTree *SplineModeTree = new TTree("SplineModeTree", "SplineModeTree");
1249  // Create branches for indices and value
1250  SplineModeTree->Branch("i", &indices_mode[0], "i/I");
1251  SplineModeTree->Branch("j", &indices_mode[1], "j/I");
1252  SplineModeTree->Branch("k", &indices_mode[2], "k/I");
1253  SplineModeTree->Branch("value", &mode_value, "value/I");
1254 
1255  // Fill the tree
1256  for (size_t i = 0; i < SplineModeVecs.size(); ++i) {
1257  for (size_t j = 0; j < SplineModeVecs[i].size(); ++j) {
1258  for (size_t k = 0; k < SplineModeVecs[i][j].size(); ++k) {
1259  indices_mode[0] = static_cast<int>(i);
1260  indices_mode[1] = static_cast<int>(j);
1261  indices_mode[2] = static_cast<int>(k);
1262  mode_value = SplineModeVecs[i][j][k];
1263  SplineModeTree->Fill();
1264  }
1265  }
1266  }
1267  // Write the tree to the file
1268  SplineFile->cd();
1269  SplineModeTree->Write();
1270  delete SplineModeTree;
1271 }

◆ 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 1137 of file BinnedSplineHandler.cpp.

1137  {
1138 // *****************************************
1139  TTree *Settings = new TTree("Settings", "Settings");
1140  int CoeffIndex_temp = CoeffIndex;
1141  int MonolithSize_temp = MonolithSize;
1142  short int nParams_temp = nParams;
1143 
1144  Settings->Branch("CoeffIndex", &CoeffIndex_temp, "CoeffIndex/I");
1145  Settings->Branch("MonolithSize", &MonolithSize_temp, "MonolithSize/I");
1146  Settings->Branch("nParams", &nParams_temp, "nParams/S");
1147 
1148  int SplineBinning_size1 = static_cast<int>(SplineBinning.size());
1149  int SplineBinning_size2 = (SplineBinning_size1 > 0) ? static_cast<int>(SplineBinning[0].size()) : 0;
1150  int SplineBinning_size3 = (SplineBinning_size2 > 0) ? static_cast<int>(SplineBinning[0][0].size()) : 0;
1151 
1152  Settings->Branch("SplineBinning_size1", &SplineBinning_size1, "SplineBinning_size1/I");
1153  Settings->Branch("SplineBinning_size2", &SplineBinning_size2, "SplineBinning_size2/I");
1154  Settings->Branch("SplineBinning_size3", &SplineBinning_size3, "SplineBinning_size3/I");
1155 
1156  int SplineModeVecs_size1 = static_cast<int>(SplineModeVecs.size());
1157  int SplineModeVecs_size2 = (SplineModeVecs_size1 > 0) ? static_cast<int>(SplineModeVecs[0].size()) : 0;
1158  int SplineModeVecs_size3 = (SplineModeVecs_size2 > 0) ? static_cast<int>(SplineModeVecs[0][0].size()) : 0;
1159 
1160  Settings->Branch("SplineModeVecs_size1", &SplineModeVecs_size1, "SplineModeVecs_size1/I");
1161  Settings->Branch("SplineModeVecs_size2", &SplineModeVecs_size2, "SplineModeVecs_size2/I");
1162  Settings->Branch("SplineModeVecs_size3", &SplineModeVecs_size3, "SplineModeVecs_size3/I");
1163 
1164  std::vector<std::string> SampleNames_temp = SampleNames;
1165  Settings->Branch("SampleNames", &SampleNames_temp);
1166  std::vector<std::string> SampleTitles_temp = SampleTitles;
1167  Settings->Branch("SampleTitles", &SampleTitles_temp);
1168  std::vector<int> nSplineParams_temp = nSplineParams;
1169  Settings->Branch("nSplineParams", &nSplineParams_temp);
1170 
1171  Settings->Fill();
1172  SplineFile->cd();
1173  Settings->Write();
1174  delete Settings;
1175 }

◆ PrepareSplineFile()

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

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

Implements SplineBase.

Definition at line 1110 of file BinnedSplineHandler.cpp.

1110  {
1111 // *****************************************
1112  M3::AddPath(FileName);
1113  // Check for spaces in the filename
1114  size_t pos = FileName.find(' ');
1115  if (pos != std::string::npos) {
1116  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1117  while ((pos = FileName.find(' ')) != std::string::npos) {
1118  FileName[pos] = '_';
1119  }
1120  }
1121  // Save ROOT File
1122  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "recreate");
1123  YAML::Node ConfigCurrent = ParHandler->GetConfig();
1124  TMacro ConfigSave = YAMLtoTMacro(ConfigCurrent, "ParameterHandler");
1125  ConfigSave.Write();
1126 
1127  PrepareSettingsDir(SplineFile);
1128  PrepareMonolithDir(SplineFile);
1129  PrepareIndexDir(SplineFile);
1130  PrepareOtherInfoDir(SplineFile);
1131  PrepareFastSplineInfoDir(SplineFile);
1132 
1133  SplineFile->Close();
1134 }
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
Definition: YamlHelper.h:167
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:139

◆ PrepForReweight()

void BinnedSplineHandler::PrepForReweight ( )
protected

Initialise flat structure.

Definition at line 504 of file BinnedSplineHandler.cpp.

504  {
505 //****************************************
506  std::vector<TSpline3_red*> UniqueSystSplines;
507  bool FoundNonFlatSpline = false;
508  int SampleCounter = M3::_BAD_INT_;
509  int SystCounter = M3::_BAD_INT_;
510  // DB Find all the Unique systs across each sample and oscillation channel
511  // This assumes that each occurrence of the same systematic spline has the same knot spacing
512  // Which is a reasonable assumption for the current implementation of spline evaluations
513  for (const auto& entry : IndexVect)
514  {
515  int splineindex = entry.value;
516  // KS: reset if we moved to another sample or syst
517  if(SampleCounter != entry.iSample || SystCounter != entry.iSyst) {
518  SampleCounter = entry.iSample;
519  SystCounter = entry.iSyst;
520  FoundNonFlatSpline = false;
521  }
522  std::string SystName = SplineFileParPrefixNames[entry.iSample][entry.iSyst];
523  bool FoundSyst = false;
524  for (unsigned int iFoundSyst = 0; iFoundSyst < UniqueSystNames.size(); iFoundSyst++) {
525  if (SystName == UniqueSystNames[iFoundSyst]) {
526  FoundSyst = true;
527  }
528  }
529  if (FoundSyst) continue;
530 
531  if (splinevec_Monolith[splineindex])
532  {
533  UniqueSystSplines.push_back(splinevec_Monolith[splineindex]);
534  UniqueSystIndices.push_back(GlobalSystIndex[entry.iSample][entry.iSyst]);
535 
536  FoundNonFlatSpline = true;
537  }
538  if (FoundNonFlatSpline) {
539  UniqueSystNames.push_back(SystName);
540  } else {
541  MACH3LOG_INFO("{} syst has no response in sample {}", SystName, entry.iSample);
542  MACH3LOG_INFO("Whilst this isn't necessarily a problem, it seems odd");
543  }
544  } // end loop over indices
545  nParams = static_cast<short int>(UniqueSystSplines.size());
546 
547  // DB Find the number of splines knots which assumes each instance of the syst has the same number of knots
548  SplineSegments = new short int[nParams]();
549  ParamValues = new float[nParams]();
550  SplineInfoArray.resize(nParams);
551  for (int iSpline = 0; iSpline < nParams; iSpline++)
552  {
553  SplineInfoArray[iSpline].nPts = static_cast<M3::int_t>(UniqueSystSplines[iSpline]->GetNp());
554  SplineInfoArray[iSpline].xPts.resize(SplineInfoArray[iSpline].nPts);
555  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
556  for (int iKnot = 0; iKnot < SplineInfoArray[iSpline].nPts; iKnot++)
557  {
558  M3::float_t xPoint;
559  M3::float_t yPoint;
560  UniqueSystSplines[iSpline]->GetKnot(iKnot, xPoint, yPoint);
561  SplineInfoArray[iSpline].xPts[iKnot] = xPoint;
562  }
563  //ETA - let this just be set as the first segment by default
564  SplineSegments[iSpline] = 0;
565  ParamValues[iSpline] = 0.;
566  }
567 
568  MACH3LOG_INFO("nUniqueSysts: {}", nParams);
569  MACH3LOG_INFO("{:<15} | {:<20} | {:<6}", "Spline Index", "Syst Name", "nKnots");
570  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
571  {
572  MACH3LOG_INFO("{:<15} | {:<20} | {:<6}", iUniqueSyst, UniqueSystNames[iUniqueSyst], SplineInfoArray[iUniqueSyst].nPts);
573  }
574 
575  int nCombinations_FlatSplines = 0;
576  int nCombinations_All = 0;
577  // DB Now actually loop over splines to determine which are all null i.e. flat
578  for (unsigned int index = 0; index < IndexVect.size(); index++)
579  {
580  int splineindex = IndexVect[index].value;;
581  nCombinations_All++;
582  if (!splinevec_Monolith[splineindex]) {
583  nCombinations_FlatSplines++;
584  }
585  }
586 
587  // We need to grab the maximum number of knots
588  MACH3LOG_INFO("Number of combinations of Sample, OscChan, Syst and Mode which have entirely flat response: {} / {}", nCombinations_FlatSplines, nCombinations_All);
589 }
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55
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 653 of file BinnedSplineHandler.cpp.

653  {
654 //****************************************
655  int iSample = GetSampleIndex(SampleTitle);
656  // count oscillation channels
657  std::map<int, std::set<int>> OscToSysts;
658 
659  for (const auto& entry : IndexVect) {
660  if (entry.iSample != iSample) continue;
661  OscToSysts[entry.iOscChan].insert(entry.iSyst);
662  }
663  MACH3LOG_INFO("Sample {} has {} oscillation channels", SampleTitle, OscToSysts.size());
664 
665  for (const auto& OscPair : OscToSysts) {
666  int osc = OscPair.first;
667  const std::set<int>& SystSet = OscPair.second;
668  MACH3LOG_INFO("Oscillation channel {} has {} systematics", osc, SystSet.size());
669  }
670 }

◆ PrintBinning()

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

Print spline binning.

Definition at line 697 of file BinnedSplineHandler.cpp.

697  {
698 //****************************************
699  const int NBins = Axis->GetNbins();
700  std::string text = "";
701  for (int iBin = 0; iBin <= NBins; iBin++) {
702  text += fmt::format("{} ", Axis->GetXbins()->GetAt(iBin));
703  }
704  MACH3LOG_INFO("{}", text);
705 }

◆ PrintSampleDetails()

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

Print info like Sample ID of spline params etc.

Definition at line 642 of file BinnedSplineHandler.cpp.

642  {
643 //****************************************
644  const int iSample = GetSampleIndex(SampleTitle);
645 
646  MACH3LOG_INFO("Details about sample: {:<20}", SampleTitles[iSample]);
647  MACH3LOG_INFO("\t Dimension: {:<35}", Dimensions[iSample]);
648  MACH3LOG_INFO("\t nSplineParam: {:<35}", nSplineParams[iSample]);
649  MACH3LOG_INFO("\t nOscChan: {:<35}", nOscChans[iSample]);
650 }

◆ RetPointer()

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

get pointer to spline weight based on bin variables

Definition at line 444 of file BinnedSplineHandler.cpp.

444  {
445 //****************************************
446  int Index = IndexVectMap.at(std::make_tuple(Variables.iSample, Variables.iOscChan, Variables.iSyst,
447  Variables.iMode, Variables.iVar[0], Variables.iVar[1], Variables.iVar[2]));
448  return &weightvec_Monolith[IndexVect[Index].value];
449 }

◆ 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 767 of file BinnedSplineHandler.cpp.

767  {
768 //****************************************
769  //ETA - this is of size nPars from the syst model
770  size_t InputVectorSize = InputVector.size();
771  std::vector< std::vector<int> > ReturnVec(InputVectorSize);
772 
773  //ETA - loop over all systematics
774  for (size_t iSyst=0;iSyst<InputVectorSize;iSyst++) {
775  std::vector<int> TmpVec;
776  std::vector<std::string> TestVec;
777 
778  //Loop over the modes that we've listed in ParHandler
779  for (unsigned int iMode = 0 ; iMode < InputVector[iSyst].size() ; iMode++) {
780  int Mode = InputVector[iSyst][iMode];
781  std::string ModeName = Modes->GetSplineSuffixFromMaCh3Mode(Mode);
782 
783  bool IncludeMode = true;
784  for (auto TestString : TestVec) {
785  if (ModeName == TestString) {
786  IncludeMode = false;
787  break;
788  }
789  }
790 
791  if (IncludeMode) {
792  TmpVec.push_back(Mode);
793  TestVec.push_back(ModeName);
794  }
795  }
796 
797  ReturnVec[iSyst] = TmpVec;
798  }
799  return ReturnVec;
800 }

◆ SynchroniseMemTransfer()

void BinnedSplineHandler::SynchroniseMemTransfer ( ) const
inlinefinalvirtual

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.

Note
now is empty but once we add GPU support it will actually do something

Implements SplineBase.

Definition at line 40 of file BinnedSplineHandler.h.

40 {return;}

◆ TransferToMonolith()

void BinnedSplineHandler::TransferToMonolith ( )

flatten multidimensional spline array into proper monolith

Definition at line 180 of file BinnedSplineHandler.cpp.

180  {
181 //****************************************
182  PrepForReweight();
184 
187  MACH3LOG_ERROR("Something's gone wrong when we tried to get the size of your monolith");
188  MACH3LOG_ERROR("MonolithSize is {}", MonolithSize);
189  MACH3LOG_ERROR("MonolithIndex is {}", MonolithIndex);
190  throw MaCh3Exception(__FILE__ , __LINE__ );
191  }
192 
193  MACH3LOG_INFO("Now transferring splines to a monolith if size {}", MonolithSize);
194  // Maps single spline object with single parameter
197  isflatarray = new bool[MonolithSize];
198 
201 
202  for (const auto& entry : IndexVect) {
203  int splineindex = entry.value;
204  weightvec_Monolith[splineindex] = 1.0;
205 
206  bool foundUniqueSpline = false;
207  // We are trying to match Spline Object with single parameter (like MAQE)
208  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
209  {
210  if (SplineFileParPrefixNames[entry.iSample][entry.iSyst] == UniqueSystNames[iUniqueSyst])
211  {
212  uniquesplinevec_Monolith[splineindex] = iUniqueSyst;
213  foundUniqueSpline = true;
214  break;
215  }
216  } //unique syst loop end
217 
218  // If current spline object hasn't been matched with actual parameter this means misconfiguration
219  if (!foundUniqueSpline)
220  {
221  MACH3LOG_ERROR("Unique spline index not found");
222  MACH3LOG_ERROR("For Spline {}", SplineFileParPrefixNames[entry.iSample][entry.iSyst]);
223  MACH3LOG_ERROR("Couldn't match {} with any of the following {} systs:", SplineFileParPrefixNames[entry.iSample][entry.iSyst], nParams);
224  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
225  {
226  MACH3LOG_ERROR("{},", UniqueSystNames.at(iUniqueSyst));
227  }//unique syst loop end
228  throw MaCh3Exception(__FILE__ , __LINE__ );
229  }
230 
231  int splineKnots;
232  if(splinevec_Monolith[splineindex]){
233  isflatarray[splineindex] = false;
234  splineKnots=splinevec_Monolith[splineindex]->GetNp();
235 
236  //Now to fill up our coefficient arrayss
237  M3::float_t* tmpXCoeffArr = new M3::float_t[splineKnots];
238  M3::float_t* tmpManyCoeffArr = new M3::float_t[splineKnots*_nCoeff_];
239 
240  int iCoeff=coeffindexvec[splineindex];
241  GetSplineCoeff_SepMany(splineindex, tmpXCoeffArr, tmpManyCoeffArr);
242 
243  for(int i = 0; i < splineKnots; i++){
244  xcoeff_arr[iCoeff+i] = tmpXCoeffArr[i];
245 
246  for(int j = 0; j < _nCoeff_; j++){
247  manycoeff_arr[(iCoeff+i)*_nCoeff_+j]=tmpManyCoeffArr[i*_nCoeff_+j];
248  }
249  }
250  delete[] tmpXCoeffArr;
251  delete[] tmpManyCoeffArr;
252  } else {
253  isflatarray[splineindex]=true;
254  }
255  }
256 }
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 125 of file BinnedSplineHandler.h.

◆ coeffindexvec

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

Number of coefficients for a single flat (after flattening)

Definition at line 116 of file BinnedSplineHandler.h.

◆ DimensionLabels

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

Definition at line 87 of file BinnedSplineHandler.h.

◆ Dimensions

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

Definition at line 86 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 101 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 112 of file BinnedSplineHandler.h.

◆ IndexVectMap

std::map<std::tuple<int, int, int, int, int, int, 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 114 of file BinnedSplineHandler.h.

◆ isflatarray

bool* BinnedSplineHandler::isflatarray
protected

Need to keep track of which splines are flat and which aren't.

Definition at line 128 of file BinnedSplineHandler.h.

◆ manycoeff_arr

M3::float_t* BinnedSplineHandler::manycoeff_arr
protected

ybcd coefficients for each spline

Definition at line 132 of file BinnedSplineHandler.h.

◆ Modes

MaCh3Modes* BinnedSplineHandler::Modes
protected

pointer to MaCh3 Mode from which we get spline suffix

Definition at line 140 of file BinnedSplineHandler.h.

◆ MonolithIndex

int BinnedSplineHandler::MonolithIndex
protected

Definition at line 124 of file BinnedSplineHandler.h.

◆ MonolithSize

int BinnedSplineHandler::MonolithSize
protected

Definition at line 123 of file BinnedSplineHandler.h.

◆ nOscChans

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

Definition at line 89 of file BinnedSplineHandler.h.

◆ nSplineParams

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

Definition at line 88 of file BinnedSplineHandler.h.

◆ ParHandler

ParameterHandlerGeneric* BinnedSplineHandler::ParHandler
protected

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

Definition at line 81 of file BinnedSplineHandler.h.

◆ SampleNames

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

Definition at line 84 of file BinnedSplineHandler.h.

◆ SampleTitles

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

Definition at line 85 of file BinnedSplineHandler.h.

◆ SplineBinning

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

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

Definition at line 91 of file BinnedSplineHandler.h.

◆ SplineFileParPrefixNames

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

[Sample][Syst]

Definition at line 93 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 104 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 97 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 121 of file BinnedSplineHandler.h.

◆ uniquecoeffindices

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

Unique coefficient indices.

Definition at line 118 of file BinnedSplineHandler.h.

◆ uniquesplinevec_Monolith

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

Maps single spline object with single parameter.

Definition at line 137 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 109 of file BinnedSplineHandler.h.

◆ UniqueSystNames

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

name of each spline parameter

Definition at line 107 of file BinnedSplineHandler.h.

◆ weightvec_Monolith

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

Stores weight from spline evaluation for each single spline.

Definition at line 135 of file BinnedSplineHandler.h.

◆ xcoeff_arr

M3::float_t* BinnedSplineHandler::xcoeff_arr
protected

x coefficients for each spline

Definition at line 130 of file BinnedSplineHandler.h.


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