MaCh3  2.6.1
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, std::vector< int > >, int > IndexVectMap
 Map between spline origin/properties (iSample, iOscChan, iSyst, iMode, iVar1, iVar2, iVar3) and the index of the spline in IndexVect. More...
 
std::vector< 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 13 of file BinnedSplineHandler.cpp.

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

34  {
35 //****************************************
36  if(manycoeff_arr != nullptr) delete[] manycoeff_arr;
37  if(xcoeff_arr != nullptr) delete[] xcoeff_arr;
38  if(SplineSegments != nullptr) delete[] SplineSegments;
39  if(ParamValues != nullptr) delete[] ParamValues;
40 }
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 69 of file BinnedSplineHandler.cpp.

72  {
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
[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 309 of file BinnedSplineHandler.cpp.

309  {
310 //****************************************
311  int iSample = GetSampleIndex(SampleTitle);
312  for (int iOscChan = 0; iOscChan < nOscChans[iSample]; ++iOscChan)
313  {
314  for (int iSyst = 0; iSyst < nSplineParams[iSample]; ++iSyst)
315  {
316  int nModesInSyst = static_cast<int>(SplineModeVecs[iSample][iSyst].size());
317  for (int iMode = 0; iMode < nModesInSyst; ++iMode)
318  {
319  const int nBins1 = SplineBinning[iSample][iOscChan][0]->GetNbins();
320  const int nBins2 = SplineBinning[iSample][iOscChan][1]->GetNbins();
321  const int nBins3 = SplineBinning[iSample][iOscChan][2]->GetNbins();
322  for (int iVar1 = 0; iVar1 < nBins1; ++iVar1) {
323  for (int iVar2 = 0; iVar2 < nBins2; ++iVar2) {
324  for (int iVar3 = 0; iVar3 < nBins3; ++iVar3) {
325  SplineIndex entry;
326  entry.value = -1;
327  entry.iSample = iSample;
328  entry.iOscChan = iOscChan;
329  entry.iSyst = iSyst;
330  entry.iMode = iMode;
331  entry.iVar = {iVar1, iVar2, iVar3};
332  IndexVect.push_back(entry);
333  IndexVectMap[std::make_tuple(iSample, iOscChan, iSyst, iMode, std::vector<int>{iVar1, iVar2, iVar3})] = static_cast<int>(IndexVect.size() - 1);
334  }
335  }
336  }
337  }
338  }
339  }
340 }
std::vector< SplineIndex > IndexVect
Variables related to determined which modes have splines and which piggy-back of other modes.
std::map< std::tuple< int, int, int, int, std::vector< int > >, int > IndexVectMap
Map between spline origin/properties (iSample, iOscChan, iSyst, iMode, iVar1, iVar2,...
int GetSampleIndex(const std::string &SampleTitle) const
Get index of sample based on name.
Flat representation of a spline index entry.
Definition: SplineCommon.h:33
std::vector< int > iVar
Kinematic bins index, assumed to be size of 3 for now.
Definition: SplineCommon.h:49
int iSample
Sample index.
Definition: SplineCommon.h:41
int iMode
Mode index within a systematic.
Definition: SplineCommon.h:47
int value
Index into the flattened spline weight vector.
Definition: SplineCommon.h:39
int iOscChan
Oscillation channel index.
Definition: SplineCommon.h:43
int iSyst
Systematic parameter index.
Definition: SplineCommon.h:45

◆ CalcSplineWeights()

void BinnedSplineHandler::CalcSplineWeights ( )
finalprotectedvirtual

CPU based code which eval weight for each spline.

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

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

43  {
44 //****************************************
45  //Call once everything's been allocated in SampleHandlerBase, 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");
49  IndexVectMap.clear();
64  if(isflatarray) delete [] isflatarray;
65 }
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 451 of file BinnedSplineHandler.cpp.

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

258  {
259 // *****************************************
260  // There's a parameter mapping that goes from spline parameter to a global parameter index
261  // Find the spline segments
263 
264  //KS: Huge MP loop over all valid splines
266 }
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 801 of file BinnedSplineHandler.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

928  {
929 // *****************************************
930  M3::AddPath(FileName);
931 
932  // Check for spaces in the filename
933  size_t pos = FileName.find(' ');
934  if (pos != std::string::npos) {
935  MACH3LOG_WARN("Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
936  while ((pos = FileName.find(' ')) != std::string::npos) {
937  FileName[pos] = '_';
938  }
939  }
940  auto SplineFile = std::make_unique<TFile>(FileName.c_str(), "OPEN");
941 
942  TMacro *ConfigCov = SplineFile->Get<TMacro>("ParameterHandler");
943  // Config which was in MCMC from which we are starting
944  YAML::Node CovSettings = TMacroToYAML(*ConfigCov);
945  // Config from currently used cov object
946  YAML::Node ConfigCurrent = ParHandler->GetConfig();
947 
948  if (!compareYAMLNodes(CovSettings, ConfigCurrent))
949  {
950  MACH3LOG_ERROR("Loading precomputed spline file, however encountered different YAML config, please regenerate input");
951  throw MaCh3Exception(__FILE__ , __LINE__ );
952  }
953 
954  LoadSettingsDir(SplineFile);
955  LoadMonolithDir(SplineFile);
956  LoadIndexDir(SplineFile);
957  LoadFastSplineInfoDir(SplineFile);
958 
959  for (int iSpline = 0; iSpline < nParams; iSpline++) {
960  SplineInfoArray[iSpline].splineParsPointer = ParHandler->RetPointer(UniqueSystIndices[iSpline]);
961  }
962  SplineFile->Close();
963 }
#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 1199 of file BinnedSplineHandler.cpp.

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

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

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

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

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

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

◆ PrepareSplineFile()

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

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

Implements SplineBase.

Definition at line 1108 of file BinnedSplineHandler.cpp.

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

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

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

◆ PrintBinning()

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

Print spline binning.

Definition at line 696 of file BinnedSplineHandler.cpp.

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

◆ PrintSampleDetails()

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

Print info like Sample ID of spline params etc.

Definition at line 641 of file BinnedSplineHandler.cpp.

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

◆ RetPointer()

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

get pointer to spline weight based on bin variables

Definition at line 443 of file BinnedSplineHandler.cpp.

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

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

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

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

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

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

Definition at line 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: