MaCh3  2.6.0
Reference Guide
Classes | Functions
SplineStructs.h File Reference

Contains structures and helper functions for handling spline representations of systematic parameters in the MaCh3. More...

#include "Parameters/ParameterHandlerGeneric.h"
#include "Parameters/ParameterStructs.h"
#include <cmath>
Include dependency graph for SplineStructs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  FastSplineInfo
 CW: Add a struct to hold info about the splinified parameters and help with FindSplineSegment. More...
 
class  TResponseFunction_red
 KS: A reduced ResponseFunction Generic function used for evaluating weight. More...
 
class  TF1_red
 CW: A reduced TF1 class only. Only saves parameters for each TF1 and how many parameters each parameter set has. More...
 
class  TSpline3_red
 CW: Reduced TSpline3 class. More...
 

Functions

void ApplyKnotWeightCap (TGraph *SplineGraph, const int splineParsIndex, ParameterHandlerGeneric *ParHandler)
 EM: Apply capping to knot weight for specified spline parameter. SplineGraph needs to have been set in graph array first. More...
 
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 in Spline array first. More...
 
bool isFlat (TSpline3_red *&spl)
 CW: Helper function used in the constructor, tests to see if the spline is flat. More...
 
std::vector< std::vector< TSpline3_red * > > ReduceTSpline3 (std::vector< std::vector< TSpline3 * > > &MasterSpline)
 CW: Reduced the TSpline3 to TSpline3_red. More...
 
std::vector< std::vector< TF1_red * > > ReduceTF1 (std::vector< std::vector< TF1 * > > &MasterSpline)
 CW: Reduced the TF1 to TF1_red. More...
 
TResponseFunction_redCreateResponseFunction (TGraph *&graph, const RespFuncType SplineRespFuncType, const SplineInterpolation SplineInterpolationType, const std::string &Title)
 KS: Create Response Function using TGraph. More...
 

Detailed Description

Contains structures and helper functions for handling spline representations of systematic parameters in the MaCh3.

Author
Clarence Wret
Kamil Skwarczynski
Ewan Miller

Definition in file SplineStructs.h.

Function Documentation

◆ ApplyKnotWeightCap()

void ApplyKnotWeightCap ( TGraph *  SplineGraph,
const int  splineParsIndex,
ParameterHandlerGeneric ParHandler 
)
inline

EM: Apply capping to knot weight for specified spline parameter. SplineGraph needs to have been set in graph array first.

Definition at line 49 of file SplineStructs.h.

49  {
50 // ***************************************************************************
51  if(SplineGraph == nullptr){
52  MACH3LOG_ERROR("hmmm looks like you're trying to apply capping for spline parameter {} but it hasn't been set in SplineGraph yet",
53  ParHandler->GetParFancyName(splineParsIndex));
54  throw MaCh3Exception(__FILE__ , __LINE__ );
55  }
56 
57  // EM: cap the weights of the knots if specified in the config
58  if(
59  (ParHandler->GetParSplineKnotUpperBound(splineParsIndex) != M3::DefSplineKnotUpBound)
60  || (ParHandler->GetParSplineKnotLowerBound(splineParsIndex) != M3::DefSplineKnotLowBound))
61  {
62  for(int knotId = 0; knotId < SplineGraph->GetN(); knotId++){
63  double x,y;
64 
65  // EM: get the x and y of the point. Also double check that the requested point was valid just to be super safe
66  if(SplineGraph->GetPoint(knotId, x, y) == -1) {
67  MACH3LOG_ERROR("Invalid knot requested: {}", knotId);
68  throw MaCh3Exception(__FILE__ , __LINE__ );
69  }
70 
71  y = std::min(y, ParHandler->GetParSplineKnotUpperBound(splineParsIndex));
72  y = std::max(y, ParHandler->GetParSplineKnotLowerBound(splineParsIndex));
73 
74  SplineGraph->SetPoint(knotId, x, y);
75  }
76 
77  // EM: check if our cap made the spline flat, if so we set to 1 knot to avoid problems later on
78  bool isFlat = true;
79  for(int knotId = 0; knotId < SplineGraph->GetN(); knotId++){
80  double x,y;
81 
82  // EM: get the x and y of the point. Also double check that the requested point was valid just to be super safe
83  if(SplineGraph->GetPoint(knotId, x, y) == -1) {
84  MACH3LOG_ERROR("Invalid knot requested: {}", knotId);
85  throw MaCh3Exception(__FILE__ , __LINE__ );
86  }
87  if(std::abs(y - 1.0) > 1e-5) isFlat = false;
88  }
89 
90  if(isFlat){
91  SplineGraph->Set(1);
92  SplineGraph->SetPoint(0, 0.0, 1.0);
93  }
94  }
95 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
bool isFlat(TSpline3_red *&spl)
CW: Helper function used in the constructor, tests to see if the spline is flat.
Custom exception class used throughout MaCh3.
std::string GetParFancyName(const int i) const
Get fancy name of the Parameter.
double GetParSplineKnotUpperBound(const int i) const
EM: value at which we cap spline knot weight.
double GetParSplineKnotLowerBound(const int i) const
EM: value at which we cap spline knot weight.
constexpr static const double DefSplineKnotUpBound
Default value for spline knot capping, default mean not capping is being applied.
Definition: Core.h:86
constexpr static const double DefSplineKnotLowBound
Default value for spline knot capping, default mean not capping is being applied.
Definition: Core.h:88

◆ ApplyKnotWeightCapTSpline3()

void ApplyKnotWeightCapTSpline3 ( TSpline3 *&  Spline,
const int  splineParsIndex,
ParameterHandlerGeneric ParHandler 
)
inline

EM: Apply capping to knot weight for specified spline parameter. param graph needs to have been set in Spline array first.

Definition at line 99 of file SplineStructs.h.

99  {
100 // ***************************************************************************
101  if(Spline == nullptr) {
102  MACH3LOG_ERROR("hmmm looks like you're trying to apply capping for spline parameter {} but it hasn't been set in Spline yet",
103  ParHandler->GetParFancyName(splineParsIndex));
104  throw MaCh3Exception(__FILE__ , __LINE__ );
105  }
106 
107  std::string oldName = Spline->GetName();
108  // EM: cap the weights of the knots if specified in the config
109  if((ParHandler->GetParSplineKnotUpperBound(splineParsIndex) != M3::DefSplineKnotUpBound)
110  || (ParHandler->GetParSplineKnotLowerBound(splineParsIndex) != M3::DefSplineKnotLowBound))
111  {
112  const int NValues = Spline->GetNp();
113  std::vector<double> XVals(NValues);
114  std::vector<double> YVals(NValues);
115  for(int knotId = 0; knotId < NValues; knotId++){
116  double x,y;
117  // Extract X and Y
118  Spline->GetKnot(knotId, x, y);
119 
120  y = std::min(y, ParHandler->GetParSplineKnotUpperBound(splineParsIndex));
121  y = std::max(y, ParHandler->GetParSplineKnotLowerBound(splineParsIndex));
122 
123  XVals[knotId] = x;
124  YVals[knotId] = y;
125  }
126  delete Spline;
127  // If we capped we have to make new TSpline3 to recalculate coefficients
128  Spline = new TSpline3(oldName.c_str(), XVals.data(), YVals.data(), NValues);
129  }
130 }

◆ CreateResponseFunction()

TResponseFunction_red* CreateResponseFunction ( TGraph *&  graph,
const RespFuncType  SplineRespFuncType,
const SplineInterpolation  SplineInterpolationType,
const std::string &  Title 
)
inline

KS: Create Response Function using TGraph.

Parameters
graphThis holds weights for each "spline" knot
SplineRespFuncTypeType of response function, whether we use Spline or TF1
SplineInterpolationTypeInterpolation type for example Monotonic Akima etc.
Titletitle you want for ROOT object, isn't very useful as in MaCh3 we usually convert later to something light weight to not waste RAM.

Definition at line 878 of file SplineStructs.h.

881  {
882 // *********************************
883  TResponseFunction_red* RespFunc = nullptr;
884 
885  if (graph && graph->GetN() > 1)
886  {
887  if(SplineRespFuncType == kTSpline3_red)
888  {
889  // Here's the TSpline3
890  TSpline3* spline = nullptr;
891  TSpline3_red *spline_red = nullptr;
892 
893  // Create the TSpline3* from the TGraph* and build the coefficients
894  spline = new TSpline3(Title.c_str(), graph);
895  spline->SetNameTitle(Title.c_str(), Title.c_str());
896 
897  // Make the reduced TSpline3 format and delete the old spline
898  spline_red = new TSpline3_red(spline, SplineInterpolationType);
899 
900  RespFunc = spline_red;
901  }
902  else if(SplineRespFuncType == kTF1_red)
903  {
904  // The TF1 object we build from fitting the TGraph
905  TF1 *Fitter = nullptr;
906  TF1_red *tf1_red = nullptr;
907 
908  if(graph->GetN() != 2) {
909  MACH3LOG_ERROR("Trying to make TF1 from more than 2 knots. Knots = {}", graph->GetN());
910  MACH3LOG_ERROR("Currently support only linear with 2 knots :(");
911  throw MaCh3Exception(__FILE__ , __LINE__ );
912  }
913 
914  // Try simple linear function
915  Fitter = new TF1(Title.c_str(), "([1]+[0]*x)", graph->GetX()[0], graph->GetX()[graph->GetN()-1]);
916  //CW: For 2p2h shape C and O we can't fit a polynomial: try a linear combination of two linear functions around 0
917  //Fitter = new TF1(Title.c_str(), "(x<=0)*(1+[0]*x)+(x>0)*([1]*x+1)", graph->GetX()[0], graph->GetX()[graph->GetN()-1]);
918  // Fit 5hd order polynomial for all other parameters
919  //Fitter = new TF1(Title.c_str(), "1+[0]*x+[1]*x*x+[2]*x*x*x+[3]*x*x*x*x+[4]*x*x*x*x*x", graph->GetX()[0], graph->GetX()[graph->GetN()-1]);
920  //Pseudo Heaviside for Pauli Blocking
921  //Fitter = new TF1(Title.c_str(), "(x <= 0)*(1+[0]*x) + (1 >= x)*(x > 0)*(1+[1]*x) + (x > 1)*([3]+[2]*x)", graph->GetX()[0], graph->GetX()[graph->GetN()-1]);
922 
923  // Fit the TF1 to the graph
924  graph->Fit(Fitter, "Q0");
925  // Make the reduced TF1 if we want
926  tf1_red = new TF1_red(Fitter);
927 
928  RespFunc = tf1_red;
929  }
930  else
931  {
932  MACH3LOG_ERROR("Unsupported response function type");
933  throw MaCh3Exception(__FILE__ , __LINE__ );
934  }
935  }
936  else
937  {
938  RespFunc = nullptr;
939  }
940  return RespFunc;
941 }
@ kTF1_red
Uses TF1_red for interpolation.
@ kTSpline3_red
Uses TSpline3_red for interpolation.
CW: A reduced TF1 class only. Only saves parameters for each TF1 and how many parameters each paramet...
KS: A reduced ResponseFunction Generic function used for evaluating weight.
CW: Reduced TSpline3 class.

◆ isFlat()

bool isFlat ( TSpline3_red *&  spl)
inline

CW: Helper function used in the constructor, tests to see if the spline is flat.

Parameters
splpointer to TSpline3_red that will be checked

Definition at line 784 of file SplineStructs.h.

784  {
785 // *****************************************
786  int Np = spl->GetNp();
787  M3::float_t x, y, b, c, d;
788  // Go through spline segment parameters,
789  // Get y values for each spline knot,
790  // Every knot must evaluate to 1.0 to create a flat spline
791  for(int i = 0; i < Np; i++) {
792  spl->GetCoeff(i, x, y, b, c, d);
793  if (y != 1) {
794  return false;
795  }
796  }
797  return true;
798 }
void GetCoeff(int segment, M3::float_t &x, M3::float_t &y, M3::float_t &b, M3::float_t &c, M3::float_t &d) const
CW: Get the coefficient of a given segment.
M3::int_t GetNp() const override
CW: Get the number of points.
double float_t
Definition: Core.h:37

◆ ReduceTF1()

std::vector<std::vector<TF1_red*> > ReduceTF1 ( std::vector< std::vector< TF1 * > > &  MasterSpline)
inline

CW: Reduced the TF1 to TF1_red.

Parameters
MasterSplineVector of TF1_red pointers which we strip back

Definition at line 839 of file SplineStructs.h.

839  {
840 // *********************************
841  std::vector<std::vector<TF1*> >::iterator OuterIt;
842  std::vector<TF1*>::iterator InnerIt;
843 
844  // The return vector
845  std::vector<std::vector<TF1_red*> > ReducedVector;
846  ReducedVector.reserve(MasterSpline.size());
847 
848  // Loop over each parameter
849  for (OuterIt = MasterSpline.begin(); OuterIt != MasterSpline.end(); ++OuterIt) {
850  // Make the temp vector
851  std::vector<TF1_red*> TempVector;
852  TempVector.reserve(OuterIt->size());
853  // Loop over each TSpline3 pointer
854  for (InnerIt = OuterIt->begin(); InnerIt != OuterIt->end(); ++InnerIt) {
855  // Here's our delicious TSpline3 object
856  TF1* spline = (*InnerIt);
857  // Now make the reduced TSpline3 pointer (which deleted TSpline3)
858  TF1_red* red = nullptr;
859  if (spline != nullptr) {
860  red = new TF1_red(spline);
861  (*InnerIt) = spline;
862  }
863  // Push back onto new vector
864  TempVector.push_back(red);
865  } // End inner for loop
866  ReducedVector.push_back(TempVector);
867  } // End outer for loop
868  // Now have the reduced vector
869  return ReducedVector;
870 }

◆ ReduceTSpline3()

std::vector<std::vector<TSpline3_red*> > ReduceTSpline3 ( std::vector< std::vector< TSpline3 * > > &  MasterSpline)
inline

CW: Reduced the TSpline3 to TSpline3_red.

Parameters
MasterSplineVector of TSpline3_red pointers which we strip back

Definition at line 803 of file SplineStructs.h.

803  {
804 // *********************************
805  std::vector<std::vector<TSpline3*> >::iterator OuterIt;
806  std::vector<TSpline3*>::iterator InnerIt;
807 
808  // The return vector
809  std::vector<std::vector<TSpline3_red*> > ReducedVector;
810  ReducedVector.reserve(MasterSpline.size());
811 
812  // Loop over each parameter
813  for (OuterIt = MasterSpline.begin(); OuterIt != MasterSpline.end(); ++OuterIt) {
814  // Make the temp vector
815  std::vector<TSpline3_red*> TempVector;
816  TempVector.reserve(OuterIt->size());
817  // Loop over each TSpline3 pointer
818  for (InnerIt = OuterIt->begin(); InnerIt != OuterIt->end(); ++InnerIt) {
819  // Here's our delicious TSpline3 object
820  TSpline3 *spline = (*InnerIt);
821  // Now make the reduced TSpline3 pointer
822  TSpline3_red *red = nullptr;
823  if (spline != nullptr) {
824  red = new TSpline3_red(spline);
825  (*InnerIt) = spline;
826  }
827  // Push back onto new vector
828  TempVector.push_back(red);
829  } // End inner for loop
830  ReducedVector.push_back(TempVector);
831  } // End outer for loop
832  // Now have the reduced vector
833  return ReducedVector;
834 }