MaCh3  2.4.2
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 xsec 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 *xsecgraph, const int splineParsIndex, ParameterHandlerGeneric *XsecCov)
 EM: Apply capping to knot weight for specified spline parameter. param graph needs to have been set in xsecgraph array first. More...
 
void ApplyKnotWeightCapTSpline3 (TSpline3 *&Spline, const int splineParsIndex, ParameterHandlerGeneric *XsecCov)
 EM: Apply capping to knot weight for specified spline parameter. param graph needs to have been set 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

Definition in file SplineStructs.h.

Function Documentation

◆ ApplyKnotWeightCap()

void ApplyKnotWeightCap ( TGraph *  xsecgraph,
const int  splineParsIndex,
ParameterHandlerGeneric XsecCov 
)
inline

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

Definition at line 49 of file SplineStructs.h.

49  {
50 // ***************************************************************************
51  if(xsecgraph == nullptr){
52  MACH3LOG_ERROR("hmmm looks like you're trying to apply capping for spline parameter {} but it hasn't been set in xsecgraph yet", XsecCov->GetParFancyName(splineParsIndex));
53  throw MaCh3Exception(__FILE__ , __LINE__ );
54  }
55 
56  // EM: cap the weights of the knots if specified in the config
57  if(
58  (XsecCov->GetParSplineKnotUpperBound(splineParsIndex) != M3::DefSplineKnotUpBound)
59  || (XsecCov->GetParSplineKnotLowerBound(splineParsIndex) != M3::DefSplineKnotLowBound))
60  {
61  for(int knotId = 0; knotId < xsecgraph->GetN(); knotId++){
62  double x,y;
63 
64  // EM: get the x and y of the point. Also double check that the requested point was valid just to be super safe
65  if( xsecgraph->GetPoint(knotId, x, y) == -1) {
66  MACH3LOG_ERROR("Invalid knot requested: {}", knotId);
67  throw MaCh3Exception(__FILE__ , __LINE__ );
68  }
69 
70  y = std::min(y, XsecCov->GetParSplineKnotUpperBound(splineParsIndex));
71  y = std::max(y, XsecCov->GetParSplineKnotLowerBound(splineParsIndex));
72 
73  xsecgraph->SetPoint(knotId, x, y);
74  }
75 
76  // EM: check if our cap made the spline flat, if so we set to 1 knot to avoid problems later on
77  bool isFlat = true;
78  for(int knotId = 0; knotId < xsecgraph->GetN(); knotId++){
79  double x,y;
80 
81  // EM: get the x and y of the point. Also double check that the requested point was valid just to be super safe
82  if( xsecgraph->GetPoint(knotId, x, y) == -1) {
83  MACH3LOG_ERROR("Invalid knot requested: {}", knotId);
84  throw MaCh3Exception(__FILE__ , __LINE__ );
85  }
86  if(std::abs(y - 1.0) > 1e-5) isFlat = false;
87  }
88 
89  if(isFlat){
90  xsecgraph->Set(1);
91  xsecgraph->SetPoint(0, 0.0, 1.0);
92  }
93  }
94 }
#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 XsecCov 
)
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 98 of file SplineStructs.h.

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

◆ 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 879 of file SplineStructs.h.

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

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

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

◆ 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 800 of file SplineStructs.h.

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