MaCh3  2.5.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 *xsec_, 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< std::vector< int > > StripDuplicatedModes (const std::vector< std::vector< int > > &InputVector) const
 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. More...
 
std::vector< std::vector< int > > GetEventSplines (const std::string &SampleTitle, int iOscChan, int EventMode, double Var1Val, double Var2Val, double Var3Val)
 Return the splines which affect a given event. 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...
 
std::vector< TAxis * > FindSplineBinning (const std::string &FileName, const std::string &SampleTitle)
 Grab histograms with spline binning. More...
 
int CountNumberOfLoadedSplines (bool NonFlat=false, int Verbosity=0)
 
std::string getDimLabel (const int BinningOpt, const unsigned int Axis) const
 
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, int iVar1, int iVar2, int iVar3) const
 Ensure we have spline for a given bin. More...
 
void BuildSampleIndexingArray (const std::string &SampleTitle)
 
void PrepForReweight ()
 
void getSplineCoeff_SepMany (int splineindex, M3::float_t *&xArray, M3::float_t *&manyArray)
 
void PrintBinning (TAxis *Axis) const
 
void PrintSampleDetails (const std::string &SampleTitle) const
 Print info like Sample ID of spline params etc. More...
 
void PrintArrayDetails (const std::string &SampleTitle) const
 
const M3::float_tRetPointer (const int sample, const int oscchan, const int syst, const int mode, const int var1bin, const int var2bin, const int var3bin) 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...
 
virtual std::vector< std::string > GetTokensFromSplineName (const std::string &FullSplineName)=0
 
- 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
 
std::vector< std::vector< std::string > > SplineFileParPrefixNames
 
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< std::vector< std::vector< std::vector< std::vector< std::vector< std::vector< int > > > > > > > indexvec
 Variables related to determined which modes have splines and which piggy-back of other modes. More...
 
std::vector< int > coeffindexvec
 
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 136 of file BinnedSplineHandler.h.

Constructor & Destructor Documentation

◆ BinnedSplineHandler()

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

Constructor.

Todo:
ETA - do all of these functions and members actually need to be public?

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.

Todo:
it need some love

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

73 {
74  SampleNames.push_back(SampleName);
75  SampleTitles.push_back(SampleTitle);
76  Dimensions.push_back(static_cast<int>(SplineVarNames.size()));
77  DimensionLabels.push_back(SplineVarNames);
78 
79  int nSplineParam = ParHandler->GetNumParamsFromSampleName(SampleName, SystType::kSpline);
80  nSplineParams.push_back(nSplineParam);
81 
82  //This holds the global index of the spline i.e. 0 -> _fNumPar
83  std::vector<int> GlobalSystIndex_Sample = ParHandler->GetGlobalSystIndexFromSampleName(SampleName, SystType::kSpline);
84  //Keep track of this for all the samples
85  GlobalSystIndex.push_back(GlobalSystIndex_Sample);
86 
87  std::vector<SplineInterpolation> SplineInterpolation_Sample = ParHandler->GetSplineInterpolationFromSampleName(SampleName);
88  // Keep track of this for all samples
89  SplineInterpolationTypes.push_back(SplineInterpolation_Sample);
90 
91  std::vector<std::string> SplineFileParPrefixNames_Sample = ParHandler->GetSplineParsNamesFromSampleName(SampleName);
92  SplineFileParPrefixNames.push_back(SplineFileParPrefixNames_Sample);
93 
94  MACH3LOG_INFO("Create SplineModeVecs_Sample");
95  std::vector<std::vector<int>> SplineModeVecs_Sample = StripDuplicatedModes(ParHandler->GetSplineModeVecFromSampleName(SampleName));
96  MACH3LOG_INFO("SplineModeVecs_Sample is of size {}", SplineModeVecs_Sample.size());
97  SplineModeVecs.push_back(SplineModeVecs_Sample);
98 
99  MACH3LOG_INFO("SplineModeVecs is of size {}", SplineModeVecs.size());
100 
101  int nOscChan = int(OscChanFileNames.size());
102  nOscChans.push_back(nOscChan);
103 
104  PrintSampleDetails(SampleTitle);
105 
106  std::vector<std::vector<TAxis *>> SampleBinning(nOscChan);
107  for (int iOscChan = 0; iOscChan < nOscChan; iOscChan++)
108  {
109  SampleBinning[iOscChan] = FindSplineBinning(OscChanFileNames[iOscChan], SampleTitle);
110  }
111  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
112  SplineBinning.push_back(SampleBinning);
113 
114  BuildSampleIndexingArray(SampleTitle);
115  PrintArrayDetails(SampleTitle);
116  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
117 
118  FillSampleArray(SampleTitle, OscChanFileNames);
119  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
120 }
#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
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)
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
Check if there are any repeated modes. This is used to reduce the number of modes in case many intera...
std::vector< std::vector< std::vector< TAxis * > > > SplineBinning
void PrintArrayDetails(const std::string &SampleTitle) const
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
const std::vector< int > GetGlobalSystIndexFromSampleName(const std::string &SampleName, const SystType Type)
DB Get spline parameters depending on given SampleName.
int GetNumParamsFromSampleName(const std::string &SampleName, const SystType Type)
DB Grab the number of parameters for the relevant SampleName.
const std::vector< std::string > GetSplineParsNamesFromSampleName(const std::string &SampleName)
DB Get spline parameters depending on given SampleName.
const std::vector< SplineInterpolation > GetSplineInterpolationFromSampleName(const std::string &SampleName)
Get the interpolation types for splines affecting a particular SampleName.
const std::vector< std::vector< int > > GetSplineModeVecFromSampleName(const std::string &SampleName)
DB Grab the Spline Modes for the relevant SampleName.

◆ BuildSampleIndexingArray()

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

Definition at line 345 of file BinnedSplineHandler.cpp.

345  {
346 //****************************************
347  int iSample = GetSampleIndex(SampleTitle);
348  int nSplineSysts = nSplineParams[iSample];
349  int nOscChannels = nOscChans[iSample];
350 
351  // Resize the main indexing structure
352  indexvec.emplace_back(nOscChannels);
353 
354  for (int iOscChan = 0; iOscChan < nOscChannels; ++iOscChan)
355  {
356  indexvec.back()[iOscChan].resize(nSplineSysts);
357  for (int iSyst = 0; iSyst < nSplineSysts; ++iSyst)
358  {
359  int nModesInSyst = static_cast<int>(SplineModeVecs[iSample][iSyst].size());
360  indexvec.back()[iOscChan][iSyst].resize(nModesInSyst);
361 
362  for (int iMode = 0; iMode < nModesInSyst; ++iMode)
363  {
364  const int nBins1 = SplineBinning[iSample][iOscChan][0]->GetNbins();
365  const int nBins2 = SplineBinning[iSample][iOscChan][1]->GetNbins();
366  const int nBins3 = SplineBinning[iSample][iOscChan][2]->GetNbins();
367 
368  indexvec.back()[iOscChan][iSyst][iMode]
369  .resize(nBins1,std::vector<std::vector<int>>(nBins2, std::vector<int>(nBins3, 0)));
370  }
371  } // end of iSyst loop
372  } // end of iOscChan loop
373 }
std::vector< std::vector< std::vector< std::vector< std::vector< std::vector< std::vector< int > > > > > > > indexvec
Variables related to determined which modes have splines and which piggy-back of other modes.
int GetSampleIndex(const std::string &SampleTitle) const
Get index of sample based on name.

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

305  {
306 //****************************************
307  #ifdef MULTITHREAD
308  #pragma omp parallel for simd
309  #endif
310  for (size_t iCoeff = 0; iCoeff < uniquecoeffindices.size(); ++iCoeff)
311  {
312  const int iSpline = uniquecoeffindices[iCoeff];
313  const short int uniqueIndex = short(uniquesplinevec_Monolith[iSpline]);
314  const short int currentsegment = short(SplineSegments[uniqueIndex]);
315 
316  const int segCoeff = coeffindexvec[iSpline]+currentsegment;
317  const int coeffOffset = segCoeff * _nCoeff_;
318  // These are what we can extract from the TSpline3
319  const M3::float_t y = manycoeff_arr[coeffOffset+kCoeffY];
320  const M3::float_t b = manycoeff_arr[coeffOffset+kCoeffB];
321  const M3::float_t c = manycoeff_arr[coeffOffset+kCoeffC];
322  const M3::float_t d = manycoeff_arr[coeffOffset+kCoeffD];
323 
324  // Get the variation for this reconfigure for the ith parameter
326  const M3::float_t xvar = (*SplineInfoArray[uniqueIndex].splineParsPointer);
327  // The Delta(x) = xvar - x
328  const M3::float_t dx = xvar - xcoeff_arr[segCoeff];
329 
330  //Speedy 1% time boost https://en.cppreference.com/w/c/numeric/math/fma (see ND code!)
331  M3::float_t weight = M3::fmaf_t(dx, M3::fmaf_t(dx, M3::fmaf_t(dx, d, c), b), y);
332  //This is the speedy version of writing dx^3+b*dx^2+c*dx+d
333 
334  //ETA - do we need this? We check later for negative weights and I wonder if this is even
335  //possible with the fmaf line above?
336  if(weight < 0){weight = 0.;} //Stops is getting negative weights
337 
338  weightvec_Monolith[iSpline] = weight;
339  }
340 }
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
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 43 of file BinnedSplineHandler.cpp.

43  {
44 //****************************************
45  //Call once everything's been allocated in SampleHandlerFDBase, cleans up junk from memory!
46  //Not a huge saving but it's better than leaving everything up to the compiler
47  MACH3LOG_INFO("Cleaning up spline memory");
63  if(isflatarray) delete [] isflatarray;
64 }
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 
)

Definition at line 478 of file BinnedSplineHandler.cpp.

478  {
479 //****************************************
480  int SampleCounter_NonFlat = 0;
481  int SampleCounter_All = 0;
482  int FullCounter_NonFlat = 0;
483  int FullCounter_All = 0;
484 
485  for (unsigned int iSample = 0; iSample < indexvec.size(); iSample++)
486  { // Loop over systematics
487  SampleCounter_NonFlat = 0;
488  SampleCounter_All = 0;
489  std::string SampleTitle = SampleTitles[iSample];
490  for (unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++)
491  { // Loop over oscillation channels
492  for (unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++)
493  { // Loop over systematics
494  for (unsigned int iMode = 0; iMode < indexvec[iSample][iOscChan][iSyst].size(); iMode++)
495  { // Loop over modes
496  for (unsigned int iVar1 = 0; iVar1 < indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
497  { // Loop over first dimension
498  for (unsigned int iVar2 = 0; iVar2 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
499  { // Loop over second dimension
500  for (unsigned int iVar3 = 0; iVar3 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
501  { // Loop over third dimension
502  if (isValidSplineIndex(SampleTitle, iOscChan, iSyst, iMode, iVar1, iVar2, iVar3))
503  {
504  int splineindex = indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
505  if (splinevec_Monolith[splineindex])
506  {
507  SampleCounter_NonFlat += 1;
508  }
509  SampleCounter_All += 1;
510  }
511  }
512  }
513  }
514  }
515  }
516  }
517  MACH3LOG_DEBUG("{:<10} has {:<10} splines, of which {:<10} are not flat", SampleTitles[iSample], SampleCounter_All, SampleCounter_NonFlat);
518 
519  FullCounter_NonFlat += SampleCounter_NonFlat;
520  FullCounter_All += SampleCounter_All;
521  }
522 
523  if (Verbosity > 0)
524  {
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, int iVar1, int iVar2, int iVar3) 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 294 of file BinnedSplineHandler.cpp.

294  {
295 // *****************************************
296  // There's a parameter mapping that goes from spline parameter to a global parameter index
297  // Find the spline segments
299 
300  //KS: Huge MP loop over all valid splines
302 }
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 915 of file BinnedSplineHandler.cpp.

916 {
917  int iSample = GetSampleIndex(SampleTitle);
918  int nOscChannels = nOscChans[iSample];
919 
920  for (int iOscChan = 0; iOscChan < nOscChannels; iOscChan++) {
921  MACH3LOG_INFO("Processing: {}", OscChanFileNames[iOscChan]);
922  TSpline3* mySpline = nullptr;
923  TSpline3_red* Spline = nullptr;
924  TString Syst, Mode;
925  int nKnots, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin = M3::_BAD_INT_;
926  double x,y = M3::_BAD_DOUBLE_;
927  bool isFlat = true;
928 
929  std::set<std::string> SplineFileNames;
930 
931  auto File = std::unique_ptr<TFile>(TFile::Open(OscChanFileNames[iOscChan].c_str()));
932 
933  if (!File || File->IsZombie()) {
934  MACH3LOG_ERROR("File {} not found", OscChanFileNames[iOscChan]);
935  throw MaCh3Exception(__FILE__, __LINE__);
936  }
937 
938  //This is the MC specific part of the code
939  //i.e. we always assume that the splines are just store in single TDirectory and they're all in there as single objects
940  for (auto k : *File->GetListOfKeys()) {
941  auto Key = static_cast<TKey*>(k);
942  TClass *Class = gROOT->GetClass(Key->GetClassName(), false);
943  if(!Class->InheritsFrom("TSpline3")) {
944  continue;
945  }
946 
947  std::string FullSplineName = std::string(Key->GetName());
948 
949  if (SplineFileNames.count(FullSplineName) > 0) {
950  MACH3LOG_CRITICAL("Skipping spline - Found a spline whose name has already been encountered before: {}", FullSplineName);
951  continue;
952  }
953  SplineFileNames.insert(FullSplineName);
954 
955  std::vector<std::string> Tokens = GetTokensFromSplineName(FullSplineName);
956 
957  if (Tokens.size() != kNTokens) {
958  MACH3LOG_ERROR("Invalid tokens from spline name - Expected {} tokens. Check implementation in GetTokensFromSplineName()", static_cast<int>(kNTokens));
959  throw MaCh3Exception(__FILE__, __LINE__);
960  }
961 
962  Syst = Tokens[kSystToken];
963  Mode = Tokens[kModeToken];
964  Var1Bin = std::stoi(Tokens[kVar1BinToken]);
965  Var2Bin = std::stoi(Tokens[kVar2BinToken]);
966  Var3Bin = std::stoi(Tokens[kVar3BinToken]);
967 
968  SystNum = -1;
969  for (unsigned iSyst = 0; iSyst < SplineFileParPrefixNames[iSample].size(); iSyst++) {
970  if (Syst == SplineFileParPrefixNames[iSample][iSyst]) {
971  SystNum = iSyst;
972  break;
973  }
974  }
975 
976  // If the syst doesn't match any of the spline names then skip it
977  if (SystNum == -1){
978  MACH3LOG_DEBUG("Couldn't match!!");
979  MACH3LOG_DEBUG("Couldn't Match any systematic name in ParameterHandler with spline name: {}" , FullSplineName);
980  continue;
981  }
982 
983  ModeNum = -1;
984  for (unsigned int iMode = 0; iMode < SplineModeVecs[iSample][SystNum].size(); iMode++) {
985  if (Mode == Modes->GetSplineSuffixFromMaCh3Mode(SplineModeVecs[iSample][SystNum][iMode])) {
986  ModeNum = iMode;
987  break;
988  }
989  }
990 
991  if (ModeNum == -1) {
992  //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
993  // Therefore include as debug warning and continue instead
994  MACH3LOG_DEBUG("Couldn't find mode for {} in {}. Problem Spline is : {} ", Mode, Syst, FullSplineName);
995  continue;
996  }
997 
998  mySpline = Key->ReadObject<TSpline3>();
999 
1000  if (isValidSplineIndex(SampleTitle, iOscChan, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin)) { // loop over all the spline knots and check their value
1001  MACH3LOG_TRACE("Pushed back monolith for spline {}", FullSplineName);
1002  // if the value is 1 then set the flat bool to false
1003  nKnots = mySpline->GetNp();
1004  isFlat = true;
1005  for (int iKnot = 0; iKnot < nKnots; iKnot++) {
1006  mySpline->GetKnot(iKnot, x, y);
1007  if (y < 0.99999 || y > 1.00001)
1008  {
1009  isFlat = false;
1010  break;
1011  }
1012  }
1013 
1014  //Rather than keeping a mega vector of splines then converting, this should just keep everything nice in memory!
1015  indexvec[iSample][iOscChan][SystNum][ModeNum][Var1Bin][Var2Bin][Var3Bin]=MonolithIndex;
1016  coeffindexvec.push_back(CoeffIndex);
1017  // Should save memory rather saving [x_i_0 ,... x_i_maxknots] for every spline!
1018  if (isFlat) {
1019  splinevec_Monolith.push_back(nullptr);
1020  delete mySpline;
1021  } else {
1022  ApplyKnotWeightCapTSpline3(mySpline, SystNum, ParHandler);
1023  Spline = new TSpline3_red(mySpline, SplineInterpolationTypes[iSample][SystNum]);
1024  if(mySpline) delete mySpline;
1025 
1026  splinevec_Monolith.push_back(Spline);
1027  uniquecoeffindices.push_back(MonolithIndex); //So we can get the unique coefficients and skip flat splines later on!
1028  CoeffIndex+=nKnots;
1029  }
1030  //Incrementing MonolithIndex to keep track of number of valid spline indices
1031  MonolithIndex+=1;
1032  } else {
1033  //Potentially you are not a valid spline index
1034  delete mySpline;
1035  }
1036  }//End of loop over all TKeys in file
1037 
1038  //A bit of clean up
1039  File->Delete("*");
1040  File->Close();
1041  } //End of oscillation channel loop
1042 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33
void ApplyKnotWeightCapTSpline3(TSpline3 *&Spline, const int splineParsIndex, ParameterHandlerGeneric *XsecCov)
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
std::string GetSplineSuffixFromMaCh3Mode(const int Index)
DB: Get binned spline mode suffic 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.
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55

◆ FindSplineBinning()

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

Grab histograms with spline binning.

Definition at line 376 of file BinnedSplineHandler.cpp.

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

◆ getDimLabel()

std::string BinnedSplineHandler::getDimLabel ( const int  BinningOpt,
const unsigned int  Axis 
) const

Definition at line 714 of file BinnedSplineHandler.cpp.

716 {
717  if(Axis > DimensionLabels[iSample].size()){
718  MACH3LOG_ERROR("The spline Axis you are trying to get the label of is larger than the number of dimensions");
719  MACH3LOG_ERROR("You are trying to get axis {} but have only got {}", Axis, Dimensions[iSample]);
720  throw MaCh3Exception(__FILE__ , __LINE__ );
721  }
722  return DimensionLabels.at(iSample).at(Axis);
723 }

◆ GetEventSplines()

std::vector< std::vector< int > > 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 828 of file BinnedSplineHandler.cpp.

828  {
829 //****************************************
830  std::vector<std::vector<int>> ReturnVec;
831  int SampleIndex = GetSampleIndex(SampleTitle);
832  int nSplineSysts = static_cast<int>(indexvec[SampleIndex][iOscChan].size());
833 
834  int Mode = -1;
835  std::string SuffixForEventMode = Modes->GetSplineSuffixFromMaCh3Mode(EventMode);
836  for (int iMode=0;iMode<Modes->GetNModes();iMode++) {
837  if (SuffixForEventMode == Modes->GetSplineSuffixFromMaCh3Mode(iMode)) {
838  Mode = iMode;
839  break;
840  }
841  }
842  if (Mode == -1) {
843  return ReturnVec;
844  }
845 
846  std::vector<int> bins;
847  std::vector<double> vars = {Var1Val, Var2Val, Var3Val};
848  for (size_t i = 0; i < vars.size(); ++i) {
849  int bin = SplineBinning[SampleIndex][iOscChan][i]->FindBin(vars[i]) - 1;
850  if (bin < 0 || bin >= SplineBinning[SampleIndex][iOscChan][i]->GetNbins()) {
851  return ReturnVec;
852  }
853  bins.push_back(bin);
854  }
855  int Var1Bin = bins[0]; int Var2Bin = bins[1]; int Var3Bin = bins[2];
856 
857  for(int iSyst=0; iSyst<nSplineSysts; iSyst++){
858  std::vector<int> spline_modes = SplineModeVecs[SampleIndex][iSyst];
859  int nSampleModes = static_cast<int>(spline_modes.size());
860 
861  //ETA - look here at the length of spline_modes and what you're actually comparing against
862  for(int iMode = 0; iMode<nSampleModes; iMode++){
863  //Only consider if the event mode (Mode) matches ones of the spline modes
864  if (Mode == spline_modes[iMode]) {
865  int splineID=indexvec[SampleIndex][iOscChan][iSyst][iMode][Var1Bin][Var2Bin][Var3Bin];
866  //Also check that the spline isn't flat
867  if(!isflatarray[splineID]){
868  ReturnVec.push_back({SampleIndex, iOscChan, iSyst, iMode, Var1Bin, Var2Bin, Var3Bin});
869  }
870  }
871  }
872  }
873 
874  return ReturnVec;
875 }
int GetNModes() const
KS: Get number of modes, keep in mind actual number is +1 greater due to unknown category.
Definition: MaCh3Modes.h:148

◆ GetSampleIndex()

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

Get index of sample based on name.

Parameters
SampleTitleThe title of the sample to search for.

Definition at line 727 of file BinnedSplineHandler.cpp.

727  {
728 //****************************************
729  for (size_t iSample = 0; iSample < SampleTitles.size(); ++iSample) {
730  if (SampleTitle == SampleTitles[iSample]) {
731  return static_cast<int>(iSample);
732  }
733  }
734  MACH3LOG_ERROR("Sample name not found: {}", SampleTitle);
735  throw MaCh3Exception(__FILE__, __LINE__);
736 }

◆ getSplineCoeff_SepMany()

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

Definition at line 678 of file BinnedSplineHandler.cpp.

678  {
679 //****************************************
680  //No point evaluating a flat spline
681  int nPoints = splinevec_Monolith[splineindex]->GetNp();
682 
683  for (int i = 0; i < nPoints; i++) {
684  xArray[i] = 1.0;
685  for (int j = 0; j < _nCoeff_; j++) {
686  manyArray[i*_nCoeff_+j] = 1.0;
687  }
688  }
689 
690  for(int i=0; i<nPoints; i++) {
691  M3::float_t x = M3::float_t(-999.99);
692  M3::float_t y = M3::float_t(-999.99);
693  M3::float_t b = M3::float_t(-999.99);
694  M3::float_t c = M3::float_t(-999.99);
695  M3::float_t d = M3::float_t(-999.99);
696  splinevec_Monolith[splineindex]->GetCoeff(i, x, y, b, c, d);
697 
698  // Store the coefficients for each knot contiguously in memory
699  // 4 because manyArray stores y,b,c,d
700  xArray[i] = x;
701  manyArray[i * _nCoeff_ + kCoeffY] = y;
702  manyArray[i * _nCoeff_ + kCoeffB] = b;
703  manyArray[i * _nCoeff_ + kCoeffC] = c;
704  manyArray[i * _nCoeff_ + kCoeffD] = d;
705  }
706 
707  //We now clean up the splines!
708  delete splinevec_Monolith[splineindex];
709  splinevec_Monolith[splineindex] = nullptr;
710 }

◆ GetTokensFromSplineName()

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

◆ InvestigateMissingSplines()

void BinnedSplineHandler::InvestigateMissingSplines ( ) const
private

This function will find missing splines in file.

Definition at line 123 of file BinnedSplineHandler.cpp.

123  {
124 //****************************************
125  // Map: iSample → iSyst → modeSuffix → {totalSplines, zeroCount}
126  std::map<unsigned int, std::map<unsigned int, std::map<std::string, std::pair<unsigned int, unsigned int>>>> systZeroCounts;
127 
128  for (unsigned int iSample = 0; iSample < indexvec.size(); iSample++) {
129  std::string SampleName = SampleNames[iSample];
130 
131  // Get list of systematic names for this sample
132  std::vector<std::string> SplineFileParPrefixNames_Sample =
134 
135  for (unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++) {
136  for (unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++) {
137  unsigned int zeroCount = 0;
138  unsigned int totalSplines = 0;
139 
140  for (unsigned int iMode = 0; iMode < indexvec[iSample][iOscChan][iSyst].size(); iMode++) {
141  // Get the mode suffix string
142  std::string modeSuffix =
143  Modes->GetSplineSuffixFromMaCh3Mode(SplineModeVecs[iSample][iSyst][iMode]);
144 
145  for (unsigned int iVar1 = 0; iVar1 < indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++) {
146  for (unsigned int iVar2 = 0; iVar2 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++) {
147  for (unsigned int iVar3 = 0; iVar3 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++) {
148  totalSplines++;
149  if (indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3] == 0) {
150  zeroCount++;
151  if(zeroCount > 1){
152  systZeroCounts[iSample][iSyst][modeSuffix] = {totalSplines, zeroCount};
153  }
155  "Sample '{}' | OscChan {} | Syst '{}' | Mode '{}' | Var1 {} | Var2 {} | Var3 {} => Value: {}",
156  SampleTitles[iSample],
157  iOscChan,
158  SplineFileParPrefixNames_Sample[iSyst],
159  modeSuffix,
160  iVar1,
161  iVar2,
162  iVar3,
163  indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3]
164  );
165  }
166  }
167  }
168  }
169  }
170  }
171  }
172  }
173 
174  // KS: Let's print this atrocious mess...
175  for (const auto& samplePair : systZeroCounts) {
176  unsigned int iSample = samplePair.first;
177  std::vector<std::string> SplineFileParPrefixNames_Sample = ParHandler->GetParsNamesFromSampleName(SampleNames[iSample], kSpline);
178  for (const auto& systPair : samplePair.second) {
179  unsigned int iSyst = systPair.first;
180  const auto& systName = SplineFileParPrefixNames_Sample[iSyst];
181  for (const auto& modePair : systPair.second) {
182  const auto& modeSuffix = modePair.first;
183  const auto& counts = modePair.second;
185  "Sample '{}': Systematic '{}' has missing splines in mode '{}'. Expected Splines: {}, Missing Splines: {}",
186  SampleTitles[iSample],
187  systName,
188  modeSuffix,
189  counts.first,
190  counts.second
191  );
192  }
193  }
194  }
195 }
const std::vector< std::string > GetParsNamesFromSampleName(const std::string &SampleName, const SystType Type)
DB Grab the parameter names for the relevant SampleName.

◆ isValidSplineIndex()

bool BinnedSplineHandler::isValidSplineIndex ( const std::string &  SampleTitle,
int  iSyst,
int  iOscChan,
int  iMode,
int  iVar1,
int  iVar2,
int  iVar3 
) const

Ensure we have spline for a given bin.

Definition at line 777 of file BinnedSplineHandler.cpp.

779 {
780  int iSample = GetSampleIndex(SampleTitle);
781  bool isValid = true;
782 
783  // Lambda to check if an index is valid for a specific dimension
784  auto checkIndex = [&isValid](int index, size_t size, const std::string& name) {
785  if (index < 0 || index >= int(size)) {
786  MACH3LOG_ERROR("{} index is invalid! 0 <= Index < {} ", name, size);
787  isValid = false;
788  }
789  };
790 
791  checkIndex(iSample, indexvec.size(), "Sample");
792  if (isValid) checkIndex(iOscChan, indexvec[iSample].size(), "OscChan");
793  if (isValid) checkIndex(iSyst, indexvec[iSample][iOscChan].size(), "Syst");
794  if (isValid) checkIndex(iMode, indexvec[iSample][iOscChan][iSyst].size(), "Mode");
795  if (isValid) checkIndex(iVar1, indexvec[iSample][iOscChan][iSyst][iMode].size(), "Var1");
796  if (isValid) checkIndex(iVar2, indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(), "Var2");
797  if (isValid) checkIndex(iVar3, indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(), "Var3");
798 
799  if (!isValid)
800  {
801  MACH3LOG_ERROR("Given iSample: {}", iSample);
802  MACH3LOG_ERROR("Given iOscChan: {}", iOscChan);
803  MACH3LOG_ERROR("Given iSyst: {}", iSyst);
804  MACH3LOG_ERROR("Given iMode: {}", iMode);
805  MACH3LOG_ERROR("Given iVar1: {}", iVar1);
806  MACH3LOG_ERROR("Given iVar2: {}", iVar2);
807  MACH3LOG_ERROR("Given iVar3: {}", iVar3);
808  MACH3LOG_ERROR("Come visit me at : {} : {}", __FILE__, __LINE__);
809  throw MaCh3Exception(__FILE__, __LINE__);
810  }
811 
812  return true;
813 }

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

1193  {
1194 // *****************************************
1195  TTree *IndexTree = SplineFile->Get<TTree>("IndexVec");
1196 
1197  std::vector<int> Dim(7);
1198  int value;
1199  for (int d = 0; d < 7; ++d) {
1200  IndexTree->SetBranchAddress(Form("dim%d", d+1), &Dim[d]);
1201  }
1202  IndexTree->SetBranchAddress("value", &value);
1203 
1204  // Fill indexvec with data from IndexTree
1205  for (Long64_t i = 0; i < IndexTree->GetEntries(); ++i) {
1206  IndexTree->GetEntry(i);
1207  indexvec[Dim[0]][Dim[1]][Dim[2]][Dim[3]][Dim[4]][Dim[5]][Dim[6]] = value;
1208  }
1209 
1210  // Load SplineBinning data
1211  TTree *SplineBinningTree = SplineFile->Get<TTree>("SplineBinningTree");
1212  std::vector<int> indices(3);
1213  SplineBinningTree->SetBranchAddress("i", &indices[0]);
1214  SplineBinningTree->SetBranchAddress("j", &indices[1]);
1215  SplineBinningTree->SetBranchAddress("k", &indices[2]);
1216  TAxis* axis = nullptr;
1217  SplineBinningTree->SetBranchAddress("axis", &axis);
1218 
1219  // Reconstruct TAxis objects
1220  for (Long64_t entry = 0; entry < SplineBinningTree->GetEntries(); ++entry) {
1221  SplineBinningTree->GetEntry(entry);
1222  int i = indices[0];
1223  int j = indices[1];
1224  int k = indices[2];
1225  SplineBinning[i][j][k] = static_cast<TAxis*>(axis->Clone());
1226  }
1227 
1228  std::vector<int> indices_mode(3);
1229  int mode_value;
1230  TTree *SplineModeTree = SplineFile->Get<TTree>("SplineModeTree");
1231  SplineModeTree->SetBranchAddress("i", &indices_mode[0]);
1232  SplineModeTree->SetBranchAddress("j", &indices_mode[1]);
1233  SplineModeTree->SetBranchAddress("k", &indices_mode[2]);
1234  SplineModeTree->SetBranchAddress("value", &mode_value);
1235 
1236  // Fill SplineModeVecs with values from the tree
1237  for (Long64_t entry = 0; entry < SplineModeTree->GetEntries(); ++entry) {
1238  SplineModeTree->GetEntry(entry);
1239  int i = indices_mode[0];
1240  int j = indices_mode[1];
1241  int k = indices_mode[2];
1242  SplineModeVecs[i][j][k] = mode_value;
1243  }
1244 }

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

1159  {
1160 // *****************************************
1161  TTree *MonolithTree = SplineFile->Get<TTree>("MonolithTree");
1162 
1164  MonolithTree->SetBranchAddress("manycoeff", manycoeff_arr);
1165  isflatarray = new bool[MonolithSize];
1167  MonolithTree->SetBranchAddress("isflatarray", isflatarray);
1168 
1169  // Load vectors
1170  std::vector<int>* coeffindexvec_temp = nullptr;
1171  MonolithTree->SetBranchAddress("coeffindexvec", &coeffindexvec_temp);
1172  std::vector<int>* uniquecoeffindices_temp = nullptr;
1173  MonolithTree->SetBranchAddress("uniquecoeffindices", &uniquecoeffindices_temp);
1174  std::vector<int>* uniquesplinevec_Monolith_temp = nullptr;
1175  MonolithTree->SetBranchAddress("uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1176  std::vector<int>* UniqueSystIndices_temp = nullptr;
1177  MonolithTree->SetBranchAddress("UniqueSystIndices", &UniqueSystIndices_temp);
1178 
1179  // Allocate and load xcoeff_arr
1181  MonolithTree->SetBranchAddress("xcoeff", xcoeff_arr);
1182 
1183  MonolithTree->GetEntry(0);
1184 
1185  coeffindexvec = *coeffindexvec_temp;
1186  uniquecoeffindices = *uniquecoeffindices_temp;
1187  uniquesplinevec_Monolith = *uniquesplinevec_Monolith_temp;
1188  UniqueSystIndices = *UniqueSystIndices_temp;
1189 }

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

1085  {
1086 // *****************************************
1087  TTree *Settings = SplineFile->Get<TTree>("Settings");
1088  int CoeffIndex_temp, MonolithSize_temp;
1089  short int nParams_temp;
1090  Settings->SetBranchAddress("CoeffIndex", &CoeffIndex_temp);
1091  Settings->SetBranchAddress("MonolithSize", &MonolithSize_temp);
1092  Settings->SetBranchAddress("nParams", &nParams_temp);
1093  int indexvec_sizes[7];
1094  for (int i = 0; i < 7; ++i) {
1095  Settings->SetBranchAddress(("indexvec_size" + std::to_string(i+1)).c_str(), &indexvec_sizes[i]);
1096  }
1097 
1098  int SplineBinning_size1, SplineBinning_size2, SplineBinning_size3;
1099  Settings->SetBranchAddress("SplineBinning_size1", &SplineBinning_size1);
1100  Settings->SetBranchAddress("SplineBinning_size2", &SplineBinning_size2);
1101  Settings->SetBranchAddress("SplineBinning_size3", &SplineBinning_size3);
1102  int SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3;
1103  Settings->SetBranchAddress("SplineModeVecs_size1", &SplineModeVecs_size1);
1104  Settings->SetBranchAddress("SplineModeVecs_size2", &SplineModeVecs_size2);
1105  Settings->SetBranchAddress("SplineModeVecs_size3", &SplineModeVecs_size3);
1106  std::vector<std::string>* SampleNames_temp = nullptr;
1107  Settings->SetBranchAddress("SampleNames", &SampleNames_temp);
1108  std::vector<std::string>* SampleTitles_temp = nullptr;
1109  Settings->SetBranchAddress("SampleTitles", &SampleTitles_temp);
1110  Settings->GetEntry(0);
1111 
1112  CoeffIndex = CoeffIndex_temp;
1113  MonolithSize = MonolithSize_temp;
1114  SampleNames = *SampleNames_temp;
1115  SampleTitles = *SampleTitles_temp;
1116 
1117  nParams = nParams_temp;
1118 
1119  SplineSegments = new short int[nParams]();
1120  ParamValues = new float[nParams]();
1121 
1122  // Resize indexvec according to saved dimensions
1123  indexvec.resize(indexvec_sizes[0]);
1124  for (int i = 0; i < indexvec_sizes[0]; ++i) {
1125  indexvec[i].resize(indexvec_sizes[1]);
1126  for (int j = 0; j < indexvec_sizes[1]; ++j) {
1127  indexvec[i][j].resize(indexvec_sizes[2]);
1128  for (int k = 0; k < indexvec_sizes[2]; ++k) {
1129  indexvec[i][j][k].resize(indexvec_sizes[3]);
1130  for (int l = 0; l < indexvec_sizes[3]; ++l) {
1131  indexvec[i][j][k][l].resize(indexvec_sizes[4]);
1132  for (int m = 0; m < indexvec_sizes[4]; ++m) {
1133  indexvec[i][j][k][l][m].resize(indexvec_sizes[5]);
1134  for (int n = 0; n < indexvec_sizes[5]; ++n) {
1135  indexvec[i][j][k][l][m][n].resize(indexvec_sizes[6]);
1136  }
1137  }
1138  }
1139  }
1140  }
1141  }
1142 
1143  auto Resize3D = [](auto& vec, int d1, int d2, int d3) {
1144  vec.resize(d1);
1145  for (int i = 0; i < d1; ++i) {
1146  vec[i].resize(d2);
1147  for (int j = 0; j < d2; ++j) {
1148  vec[i][j].resize(d3);
1149  }
1150  }
1151  };
1152 
1153  Resize3D(SplineBinning, SplineBinning_size1, SplineBinning_size2, SplineBinning_size3);
1154  Resize3D(SplineModeVecs, SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3);
1155 }
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 1046 of file BinnedSplineHandler.cpp.

1046  {
1047 // *****************************************
1048  M3::AddPath(FileName);
1049 
1050  // Check for spaces in the filename
1051  size_t pos = FileName.find(' ');
1052  if (pos != std::string::npos) {
1053  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1054  while ((pos = FileName.find(' ')) != std::string::npos) {
1055  FileName[pos] = '_';
1056  }
1057  }
1058  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "OPEN");
1059 
1060  TMacro *ConfigCov = SplineFile->Get<TMacro>("ParameterHandler");
1061  // Config which was in MCMC from which we are starting
1062  YAML::Node CovSettings = TMacroToYAML(*ConfigCov);
1063  // Config from currently used cov object
1064  YAML::Node ConfigCurrent = ParHandler->GetConfig();
1065 
1066  if (!compareYAMLNodes(CovSettings, ConfigCurrent))
1067  {
1068  MACH3LOG_ERROR("Loading precomputed spline file, however encountered different YAML config, please regenerate input");
1069  throw MaCh3Exception(__FILE__ , __LINE__ );
1070  }
1071 
1072  LoadSettingsDir(SplineFile);
1073  LoadMonolithDir(SplineFile);
1074  LoadIndexDir(SplineFile);
1075  LoadFastSplineInfoDir(SplineFile);
1076 
1077  for (int iSpline = 0; iSpline < nParams; iSpline++) {
1078  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
1079  }
1080  SplineFile->Close();
1081 }
#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)
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 1351 of file BinnedSplineHandler.cpp.

1351  {
1352 // *****************************************
1353  // Create a TTree to store the data
1354  TTree *IndexTree = new TTree("IndexVec", "IndexVec");
1355 
1356  // Vector holding the 7 dims
1357  std::vector<int> Dim(7);
1358  int value;
1359 
1360  // Create branches for each dimension
1361  for (int d = 0; d < 7; ++d) {
1362  IndexTree->Branch(Form("dim%d", d+1), &Dim[d], Form("dim%d/I", d+1));
1363  }
1364  IndexTree->Branch("value", &value, "value/I");
1365 
1366  // Fill the tree
1367  for (size_t i = 0; i < indexvec.size(); ++i) {
1368  for (size_t j = 0; j < indexvec[i].size(); ++j) {
1369  for (size_t k = 0; k < indexvec[i][j].size(); ++k) {
1370  for (size_t l = 0; l < indexvec[i][j][k].size(); ++l) {
1371  for (size_t m = 0; m < indexvec[i][j][k][l].size(); ++m) {
1372  for (size_t n = 0; n < indexvec[i][j][k][l][m].size(); ++n) {
1373  for (size_t p = 0; p < indexvec[i][j][k][l][m][n].size(); ++p) {
1374  Dim[0] = static_cast<int>(i);
1375  Dim[1] = static_cast<int>(j);
1376  Dim[2] = static_cast<int>(k);
1377  Dim[3] = static_cast<int>(l);
1378  Dim[4] = static_cast<int>(m);
1379  Dim[5] = static_cast<int>(n);
1380  Dim[6] = static_cast<int>(p);
1381  value = static_cast<int>(indexvec[i][j][k][l][m][n][p]);
1382  IndexTree->Fill();
1383  }
1384  }
1385  }
1386  }
1387  }
1388  }
1389  }
1390 
1391  SplineFile->cd();
1392  // Write the tree to the file
1393  IndexTree->Write();
1394  delete IndexTree;
1395 }

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

1328  {
1329 // *****************************************
1330  TTree *MonolithTree = new TTree("MonolithTree", "MonolithTree");
1331  MonolithTree->Branch("manycoeff", manycoeff_arr, Form("manycoeff[%d]/%s", CoeffIndex * _nCoeff_, M3::float_t_str_repr));
1332  MonolithTree->Branch("isflatarray", isflatarray, Form("isflatarray[%d]/O", MonolithSize));
1333 
1334  std::vector<int> coeffindexvec_temp = coeffindexvec;
1335  MonolithTree->Branch("coeffindexvec", &coeffindexvec_temp);
1336  std::vector<int> uniquecoeffindices_temp = uniquecoeffindices;
1337  MonolithTree->Branch("uniquecoeffindices", &uniquecoeffindices_temp);
1338  std::vector<int> uniquesplinevec_Monolith_temp = uniquesplinevec_Monolith;
1339  MonolithTree->Branch("uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1340  std::vector<int> UniqueSystIndices_temp = UniqueSystIndices;
1341  MonolithTree->Branch("UniqueSystIndices", &UniqueSystIndices_temp);
1342  MonolithTree->Branch("xcoeff", xcoeff_arr, Form("xcoeff[%d]/%s", CoeffIndex, M3::float_t_str_repr));
1343 
1344  MonolithTree->Fill();
1345  SplineFile->cd();
1346  MonolithTree->Write();
1347  delete MonolithTree;
1348 }
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 1398 of file BinnedSplineHandler.cpp.

1398  {
1399 // *****************************************
1400  // Create a new tree for SplineBinning data
1401  TTree *SplineBinningTree = new TTree("SplineBinningTree", "SplineBinningTree");
1402  std::vector<int> indices(3); // To store the 3D indices
1403  TAxis* axis = nullptr;
1404  SplineBinningTree->Branch("i", &indices[0], "i/I");
1405  SplineBinningTree->Branch("j", &indices[1], "j/I");
1406  SplineBinningTree->Branch("k", &indices[2], "k/I");
1407  SplineBinningTree->Branch("axis", "TAxis", &axis);
1408 
1409  // Fill the SplineBinningTree
1410  for (size_t i = 0; i < SplineBinning.size(); ++i) {
1411  for (size_t j = 0; j < SplineBinning[i].size(); ++j) {
1412  for (size_t k = 0; k < SplineBinning[i][j].size(); ++k) {
1413  axis = SplineBinning[i][j][k];
1414  indices[0] = static_cast<int>(i);
1415  indices[1] = static_cast<int>(j);
1416  indices[2] = static_cast<int>(k);
1417  SplineBinningTree->Fill();
1418  }
1419  }
1420  }
1421  SplineFile->cd();
1422  SplineBinningTree->Write();
1423  delete SplineBinningTree;
1424 
1425  std::vector<int> indices_mode(3); // to store 3D indices
1426  int mode_value;
1427 
1428  TTree *SplineModeTree = new TTree("SplineModeTree", "SplineModeTree");
1429  // Create branches for indices and value
1430  SplineModeTree->Branch("i", &indices_mode[0], "i/I");
1431  SplineModeTree->Branch("j", &indices_mode[1], "j/I");
1432  SplineModeTree->Branch("k", &indices_mode[2], "k/I");
1433  SplineModeTree->Branch("value", &mode_value, "value/I");
1434 
1435  // Fill the tree
1436  for (size_t i = 0; i < SplineModeVecs.size(); ++i) {
1437  for (size_t j = 0; j < SplineModeVecs[i].size(); ++j) {
1438  for (size_t k = 0; k < SplineModeVecs[i][j].size(); ++k) {
1439  indices_mode[0] = static_cast<int>(i);
1440  indices_mode[1] = static_cast<int>(j);
1441  indices_mode[2] = static_cast<int>(k);
1442  mode_value = SplineModeVecs[i][j][k];
1443  SplineModeTree->Fill();
1444  }
1445  }
1446  }
1447  // Write the tree to the file
1448  SplineFile->cd();
1449  SplineModeTree->Write();
1450  delete SplineModeTree;
1451 }

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

1275  {
1276 // *****************************************
1277  TTree *Settings = new TTree("Settings", "Settings");
1278  int CoeffIndex_temp = CoeffIndex;
1279  int MonolithSize_temp = MonolithSize;
1280  short int nParams_temp = nParams;
1281 
1282  Settings->Branch("CoeffIndex", &CoeffIndex_temp, "CoeffIndex/I");
1283  Settings->Branch("MonolithSize", &MonolithSize_temp, "MonolithSize/I");
1284  Settings->Branch("nParams", &nParams_temp, "nParams/S");
1285 
1286  int indexvec_sizes[7];
1287  indexvec_sizes[0] = static_cast<int>(indexvec.size());
1288  indexvec_sizes[1] = (indexvec_sizes[0] > 0) ? static_cast<int>(indexvec[0].size()) : 0;
1289  indexvec_sizes[2] = (indexvec_sizes[1] > 0) ? static_cast<int>(indexvec[0][0].size()) : 0;
1290  indexvec_sizes[3] = (indexvec_sizes[2] > 0) ? static_cast<int>(indexvec[0][0][0].size()) : 0;
1291  indexvec_sizes[4] = (indexvec_sizes[3] > 0) ? static_cast<int>(indexvec[0][0][0][0].size()) : 0;
1292  indexvec_sizes[5] = (indexvec_sizes[4] > 0) ? static_cast<int>(indexvec[0][0][0][0][0].size()) : 0;
1293  indexvec_sizes[6] = (indexvec_sizes[5] > 0) ? static_cast<int>(indexvec[0][0][0][0][0][0].size()) : 0;
1294 
1295  for (int i = 0; i < 7; ++i) {
1296  Settings->Branch(("indexvec_size" + std::to_string(i+1)).c_str(),
1297  &indexvec_sizes[i], ("indexvec_size" + std::to_string(i+1) + "/I").c_str());
1298  }
1299 
1300  int SplineBinning_size1 = static_cast<int>(SplineBinning.size());
1301  int SplineBinning_size2 = (SplineBinning_size1 > 0) ? static_cast<int>(SplineBinning[0].size()) : 0;
1302  int SplineBinning_size3 = (SplineBinning_size2 > 0) ? static_cast<int>(SplineBinning[0][0].size()) : 0;
1303 
1304  Settings->Branch("SplineBinning_size1", &SplineBinning_size1, "SplineBinning_size1/I");
1305  Settings->Branch("SplineBinning_size2", &SplineBinning_size2, "SplineBinning_size2/I");
1306  Settings->Branch("SplineBinning_size3", &SplineBinning_size3, "SplineBinning_size3/I");
1307 
1308  int SplineModeVecs_size1 = static_cast<int>(SplineModeVecs.size());
1309  int SplineModeVecs_size2 = (SplineModeVecs_size1 > 0) ? static_cast<int>(SplineModeVecs[0].size()) : 0;
1310  int SplineModeVecs_size3 = (SplineModeVecs_size2 > 0) ? static_cast<int>(SplineModeVecs[0][0].size()) : 0;
1311 
1312  Settings->Branch("SplineModeVecs_size1", &SplineModeVecs_size1, "SplineModeVecs_size1/I");
1313  Settings->Branch("SplineModeVecs_size2", &SplineModeVecs_size2, "SplineModeVecs_size2/I");
1314  Settings->Branch("SplineModeVecs_size3", &SplineModeVecs_size3, "SplineModeVecs_size3/I");
1315 
1316  std::vector<std::string> SampleNames_temp = SampleNames;
1317  Settings->Branch("SampleNames", &SampleNames_temp);
1318  std::vector<std::string> SampleTitles_temp = SampleTitles;
1319  Settings->Branch("SampleTitles", &SampleTitles_temp);
1320 
1321  Settings->Fill();
1322  SplineFile->cd();
1323  Settings->Write();
1324  delete Settings;
1325 }

◆ PrepareSplineFile()

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

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

Implements SplineBase.

Definition at line 1248 of file BinnedSplineHandler.cpp.

1248  {
1249 // *****************************************
1250  M3::AddPath(FileName);
1251  // Check for spaces in the filename
1252  size_t pos = FileName.find(' ');
1253  if (pos != std::string::npos) {
1254  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1255  while ((pos = FileName.find(' ')) != std::string::npos) {
1256  FileName[pos] = '_';
1257  }
1258  }
1259  // Save ROOT File
1260  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "recreate");
1261  YAML::Node ConfigCurrent = ParHandler->GetConfig();
1262  TMacro ConfigSave = YAMLtoTMacro(ConfigCurrent, "ParameterHandler");
1263  ConfigSave.Write();
1264 
1265  PrepareSettingsDir(SplineFile);
1266  PrepareMonolithDir(SplineFile);
1267  PrepareIndexDir(SplineFile);
1268  PrepareOtherInfoDir(SplineFile);
1269  PrepareFastSplineInfoDir(SplineFile);
1270 
1271  SplineFile->Close();
1272 }
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 ( )

Definition at line 537 of file BinnedSplineHandler.cpp.

537  {
538 //****************************************
539  std::vector<TSpline3_red*> UniqueSystSplines;
540 
541  // DB Find all the Unique systs across each sample and oscillation channel
542  // This assumes that each occurence of the same systematic spline has the same knot spacing
543  // Which is a reasonable assumption for the current implementation of spline evaluations
544  for (unsigned int iSample = 0; iSample < indexvec.size(); iSample++)
545  { // Loop over systematics
546  for (unsigned int iSyst = 0; iSyst < indexvec[iSample][0].size(); iSyst++)
547  { // Loop over systematics
548  std::string SystName = SplineFileParPrefixNames[iSample][iSyst];
549  bool FoundSyst = false;
550 
551  //ETA - this always seems to be empty to begin with??
552  //so this loop never gets used?
553  for (unsigned int iFoundSyst = 0; iFoundSyst < UniqueSystNames.size(); iFoundSyst++)
554  {
555  if (SystName == UniqueSystNames[iFoundSyst])
556  {
557  FoundSyst = true;
558  }
559  }
560  if (!FoundSyst)
561  {
562  bool FoundNonFlatSpline = false;
563  //This is all basically to check that you have some resposne from a spline
564  //systematic somewhere
565  for (unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++)
566  { // Loop over oscillation channels
567  for (unsigned int iMode = 0; iMode < indexvec[iSample][iOscChan][iSyst].size(); iMode++)
568  { // Loop over modes
569  for (unsigned int iVar1 = 0; iVar1 < indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
570  { // Loop over first dimension
571  for (unsigned int iVar2 = 0; iVar2 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
572  { // Loop over second dimension
573  for (unsigned int iVar3 = 0; iVar3 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
574  { // Loop over third dimension
575  int splineindex=indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
576  if (splinevec_Monolith[splineindex])
577  {
578  UniqueSystSplines.push_back(splinevec_Monolith[splineindex]);
579  UniqueSystIndices.push_back(GlobalSystIndex[iSample][iSyst]);
580  FoundNonFlatSpline = true;
581  }
582  if (FoundNonFlatSpline) { break;}
583  }//3D loop end
584  if (FoundNonFlatSpline) { break;}
585  }//2D loop end
586  if (FoundNonFlatSpline){ break; }
587  }//1D loop end
588  if (FoundNonFlatSpline){ break; }
589  }//mode loop end
590  if (FoundNonFlatSpline) { break; }
591  }//osc loop end
592  //ETA - only push back unique name if a non-flat response has been found
593  if(FoundNonFlatSpline){
594  UniqueSystNames.push_back(SystName);
595  }
596 
597  if (!FoundNonFlatSpline)
598  {
599  MACH3LOG_INFO("{} syst has no response in sample {}", SystName, iSample);
600  MACH3LOG_INFO("Whilst this isn't necessarily a problem, it seems odd");
601  continue;
602  }
603  }
604  }//Syst loop end
605  }
606 
607  nParams = static_cast<short int>(UniqueSystSplines.size());
608 
609  // DB Find the number of splines knots which assumes each instance of the syst has the same number of knots
610  SplineSegments = new short int[nParams]();
611  ParamValues = new float[nParams]();
612  SplineInfoArray.resize(nParams);
613  for (int iSpline = 0; iSpline < nParams; iSpline++)
614  {
615  SplineInfoArray[iSpline].nPts = static_cast<M3::int_t>(UniqueSystSplines[iSpline]->GetNp());
616  SplineInfoArray[iSpline].xPts.resize(SplineInfoArray[iSpline].nPts);
617  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
618  for (int iKnot = 0; iKnot < SplineInfoArray[iSpline].nPts; iKnot++)
619  {
620  M3::float_t xPoint;
621  M3::float_t yPoint;
622  UniqueSystSplines[iSpline]->GetKnot(iKnot, xPoint, yPoint);
623  SplineInfoArray[iSpline].xPts[iKnot] = xPoint;
624  }
625  //ETA - let this just be set as the first segment by default
626  SplineSegments[iSpline] = 0;
627  ParamValues[iSpline] = 0.;
628  }
629 
630  MACH3LOG_INFO("nUniqueSysts: {}", nParams);
631  MACH3LOG_INFO("{:<15} | {:<20} | {:<6}", "Spline Index", "Syst Name", "nKnots");
632  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
633  {
634  MACH3LOG_INFO("{:<15} | {:<20} | {:<6}", iUniqueSyst, UniqueSystNames[iUniqueSyst], SplineInfoArray[iUniqueSyst].nPts);
635  }
636 
637  //ETA
638  //Isn't this just doing what CountNumberOfLoadedSplines() does?
639  int nCombinations_FlatSplines = 0;
640  int nCombinations_All = 0;
641  // DB Now actually loop over splines to determine which are all null i.e. flat
642  for (unsigned int iSample = 0; iSample < indexvec.size(); iSample++)
643  { // Loop over systematics
644  for (unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++)
645  { // Loop over oscillation channels
646  for (unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++)
647  { // Loop over systematics
648  for (unsigned int iMode = 0; iMode < indexvec[iSample][iOscChan][iSyst].size(); iMode++)
649  { // Loop over modes
650  //bool isFlat = false;
651  for (unsigned int iVar1 = 0; iVar1 < indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
652  { // Loop over first dimension
653  for (unsigned int iVar2 = 0; iVar2 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
654  { // Loop over second dimension
655  for (unsigned int iVar3 = 0; iVar3 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
656  { // Loop over third dimension
657  int splineindex=indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
658  if (splinevec_Monolith[splineindex])
659  {
660  nCombinations_All += 1;
661  } else{
662  nCombinations_FlatSplines += 1;
663  nCombinations_All += 1;
664  }
665  }
666  }
667  }
668  }
669  }
670  }
671  }
672  // We need to grab the maximum number of knots
673  MACH3LOG_INFO("Number of combinations of Sample, OscChan, Syst and Mode which have entirely flat response: {} / {}", nCombinations_FlatSplines, nCombinations_All);
674 }
int int_t
Definition: Core.h:38

◆ PrintArrayDetails()

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

Definition at line 751 of file BinnedSplineHandler.cpp.

753 {
754  int iSample = GetSampleIndex(SampleTitle);
755  int nOscChannels = int(indexvec[iSample].size());
756  MACH3LOG_INFO("Sample {} has {} oscillation channels", SampleTitle, nOscChannels);
757 
758  for (int iOscChan = 0; iOscChan < nOscChannels; iOscChan++)
759  {
760  int nSysts = int(indexvec[iSample][iOscChan].size());
761  MACH3LOG_INFO("Oscillation channel {} has {} systematics", iOscChan, nSysts);
762  }
763 
764  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
765  MACH3LOG_INFO("Printing no. of modes affected by each systematic for each oscillation channel");
766  for (unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++) {
767  std::string modes = fmt::format("OscChan: {}\t", iOscChan);
768  for (unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++) {
769  modes += fmt::format("{} ", indexvec[iSample][iOscChan][iSyst].size());
770  }
771  MACH3LOG_INFO("{}", modes);
772  }
773  MACH3LOG_INFO("#----------------------------------------------------------------------------------------------------------------------------------#");
774 }

◆ PrintBinning()

void BinnedSplineHandler::PrintBinning ( TAxis *  Axis) const

Definition at line 816 of file BinnedSplineHandler.cpp.

818 {
819  const int NBins = Axis->GetNbins();
820  std::string text = "";
821  for (int iBin = 0; iBin <= NBins; iBin++) {
822  text += fmt::format("{} ", Axis->GetXbins()->GetAt(iBin));
823  }
824  MACH3LOG_INFO("{}", text);
825 }

◆ PrintSampleDetails()

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

Print info like Sample ID of spline params etc.

Definition at line 739 of file BinnedSplineHandler.cpp.

741 {
742  const int iSample = GetSampleIndex(SampleTitle);
743 
744  MACH3LOG_INFO("Details about sample: {:<20}", SampleTitles[iSample]);
745  MACH3LOG_INFO("\t Dimension: {:<35}", Dimensions[iSample]);
746  MACH3LOG_INFO("\t nSplineParam: {:<35}", nSplineParams[iSample]);
747  MACH3LOG_INFO("\t nOscChan: {:<35}", nOscChans[iSample]);
748 }

◆ RetPointer()

const M3::float_t* BinnedSplineHandler::RetPointer ( const int  sample,
const int  oscchan,
const int  syst,
const int  mode,
const int  var1bin,
const int  var2bin,
const int  var3bin 
) const
inline

get pointer to spline weight based on bin variables

Definition at line 65 of file BinnedSplineHandler.h.

66  {
67  int index = indexvec[sample][oscchan][syst][mode][var1bin][var2bin][var3bin];
68  return &weightvec_Monolith[index];
69  }

◆ StripDuplicatedModes()

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

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

880  {
881 //****************************************
882  //ETA - this is of size nPars from the syst model
883  size_t InputVectorSize = InputVector.size();
884  std::vector< std::vector<int> > ReturnVec(InputVectorSize);
885 
886  //ETA - loop over all systematics
887  for (size_t iSyst=0;iSyst<InputVectorSize;iSyst++) {
888  std::vector<int> TmpVec;
889  std::vector<std::string> TestVec;
890 
891  //Loop over the modes that we've listed in ParHandler
892  for (unsigned int iMode = 0 ; iMode < InputVector[iSyst].size() ; iMode++) {
893  int Mode = InputVector[iSyst][iMode];
894  std::string ModeName = Modes->GetSplineSuffixFromMaCh3Mode(Mode);
895 
896  bool IncludeMode = true;
897  for (auto TestString : TestVec) {
898  if (ModeName == TestString) {
899  IncludeMode = false;
900  break;
901  }
902  }
903 
904  if (IncludeMode) {
905  TmpVec.push_back(Mode);
906  TestVec.push_back(ModeName);
907  }
908  }
909 
910  ReturnVec[iSyst] = TmpVec;
911  }
912  return ReturnVec;
913 }

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

Implements SplineBase.

Definition at line 44 of file BinnedSplineHandler.h.

44 {return;}

◆ TransferToMonolith()

void BinnedSplineHandler::TransferToMonolith ( )

flatten multidimensional spline array into proper monolith

Definition at line 198 of file BinnedSplineHandler.cpp.

198  {
199 //****************************************
200  PrepForReweight();
202 
205  MACH3LOG_ERROR("Something's gone wrong when we tried to get the size of your monolith");
206  MACH3LOG_ERROR("MonolithSize is {}", MonolithSize);
207  MACH3LOG_ERROR("MonolithIndex is {}", MonolithIndex);
208  throw MaCh3Exception(__FILE__ , __LINE__ );
209  }
210 
211  MACH3LOG_INFO("Now transferring splines to a monolith if size {}", MonolithSize);
212 
215  isflatarray = new bool[MonolithSize];
216 
219 
220  for (unsigned int iSample = 0; iSample < indexvec.size(); iSample++)
221  { // Loop over sample
222  for (unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++)
223  { // Loop over oscillation channels
224  for (unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++)
225  { // Loop over systematics
226  for (unsigned int iMode = 0; iMode < indexvec[iSample][iOscChan][iSyst].size(); iMode++)
227  { // Loop over modes
228  for (unsigned int iVar1 = 0; iVar1 < indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
229  { // Loop over first dimension
230  for (unsigned int iVar2 = 0; iVar2 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
231  { // Loop over second dimension
232  for (unsigned int iVar3 = 0; iVar3 < indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
233  {
234  int splineindex=indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
235  weightvec_Monolith[splineindex] = 1.0;
236 
237  bool foundUniqueSpline = false;
238  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
239  {
240  if (SplineFileParPrefixNames[iSample][iSyst] == UniqueSystNames[iUniqueSyst])
241  {
242  uniquesplinevec_Monolith[splineindex] = iUniqueSyst;
243  foundUniqueSpline = true;
244  }
245  }//unique syst loop end
246 
247  if (!foundUniqueSpline)
248  {
249  MACH3LOG_ERROR("Unique spline index not found");
250  MACH3LOG_ERROR("For Spline {}", SplineFileParPrefixNames[iSample][iSyst]);
251  MACH3LOG_ERROR("Couldn't match {} with any of the following {} systs:", SplineFileParPrefixNames[iSample][iSyst], nParams);
252  for (int iUniqueSyst = 0; iUniqueSyst < nParams; iUniqueSyst++)
253  {
254  MACH3LOG_ERROR("{},", UniqueSystNames.at(iUniqueSyst));
255  }//unique syst loop end
256  throw MaCh3Exception(__FILE__ , __LINE__ );
257  }
258 
259  int splineKnots;
260  if(splinevec_Monolith[splineindex]){
261  isflatarray[splineindex]=false;
262  splineKnots=splinevec_Monolith[splineindex]->GetNp();
263 
264  //Now to fill up our coefficient arrayss
265  M3::float_t* tmpXCoeffArr = new M3::float_t[splineKnots];
266  M3::float_t* tmpManyCoeffArr = new M3::float_t[splineKnots*_nCoeff_];
267 
268  int iCoeff=coeffindexvec[splineindex];
269  getSplineCoeff_SepMany(splineindex, tmpXCoeffArr, tmpManyCoeffArr);
270 
271  for(int i = 0; i < splineKnots; i++){
272  xcoeff_arr[iCoeff+i]=tmpXCoeffArr[i];
273 
274  for(int j = 0; j < _nCoeff_; j++){
275  manycoeff_arr[(iCoeff+i)*_nCoeff_+j]=tmpManyCoeffArr[i*_nCoeff_+j];
276  }
277  }
278  delete[] tmpXCoeffArr;
279  delete[] tmpManyCoeffArr;
280  }
281  else {
282  isflatarray[splineindex]=true;
283  }
284  }//3d loop end
285  }//2d loop end
286  }//1d loop end
287  }//mode loop end
288  }//syst2 loop end
289  }//osc loop end
290  }//syst1 loop end
291 }
void getSplineCoeff_SepMany(int splineindex, M3::float_t *&xArray, M3::float_t *&manyArray)
int CountNumberOfLoadedSplines(bool NonFlat=false, int Verbosity=0)
void InvestigateMissingSplines() const
This function will find missing splines in file.

Member Data Documentation

◆ CoeffIndex

int BinnedSplineHandler::CoeffIndex
protected

Definition at line 120 of file BinnedSplineHandler.h.

◆ coeffindexvec

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

Definition at line 111 of file BinnedSplineHandler.h.

◆ DimensionLabels

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

Definition at line 86 of file BinnedSplineHandler.h.

◆ Dimensions

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

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

◆ indexvec

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

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

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

◆ manycoeff_arr

M3::float_t* BinnedSplineHandler::manycoeff_arr
protected

ybcd coefficients for each spline

Definition at line 127 of file BinnedSplineHandler.h.

◆ Modes

MaCh3Modes* BinnedSplineHandler::Modes
protected

pointer to MaCh3 Mode from which we get spline suffix

Definition at line 135 of file BinnedSplineHandler.h.

◆ MonolithIndex

int BinnedSplineHandler::MonolithIndex
protected

Definition at line 119 of file BinnedSplineHandler.h.

◆ MonolithSize

int BinnedSplineHandler::MonolithSize
protected

Definition at line 118 of file BinnedSplineHandler.h.

◆ nOscChans

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

Definition at line 88 of file BinnedSplineHandler.h.

◆ nSplineParams

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

Definition at line 87 of file BinnedSplineHandler.h.

◆ ParHandler

ParameterHandlerGeneric* BinnedSplineHandler::ParHandler
protected

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

Definition at line 80 of file BinnedSplineHandler.h.

◆ SampleNames

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

Definition at line 83 of file BinnedSplineHandler.h.

◆ SampleTitles

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

Definition at line 84 of file BinnedSplineHandler.h.

◆ SplineBinning

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

Definition at line 90 of file BinnedSplineHandler.h.

◆ SplineFileParPrefixNames

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

Definition at line 91 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 102 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 95 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 116 of file BinnedSplineHandler.h.

◆ uniquecoeffindices

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

Unique coefficient indices.

Definition at line 113 of file BinnedSplineHandler.h.

◆ uniquesplinevec_Monolith

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

Maps single spline object with single parameter.

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

◆ UniqueSystNames

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

name of each spline parameter

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

◆ xcoeff_arr

M3::float_t* BinnedSplineHandler::xcoeff_arr
protected

x coefficients for each spline

Definition at line 125 of file BinnedSplineHandler.h.


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