MaCh3  2.2.3
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 51 of file SplineStructs.h.

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

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

100  {
101 // ***************************************************************************
102  if(Spline == nullptr) {
103  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));
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((XsecCov->GetParSplineKnotUpperBound(splineParsIndex) != M3::DefSplineKnotUpBound) || (XsecCov->GetParSplineKnotLowerBound(splineParsIndex) != M3::DefSplineKnotLowBound))
110  {
111  const int NValues = Spline->GetNp();
112  std::vector<double> XVals(NValues);
113  std::vector<double> YVals(NValues);
114  for(int knotId = 0; knotId < NValues; knotId++){
115  double x,y;
116  // Extract X and Y
117  Spline->GetKnot(knotId, x, y);
118 
119  y = std::min(y, XsecCov->GetParSplineKnotUpperBound(splineParsIndex));
120  y = std::max(y, XsecCov->GetParSplineKnotLowerBound(splineParsIndex));
121 
122  XVals[knotId] = x;
123  YVals[knotId] = y;
124  }
125  delete Spline;
126  // If we capped we have to make new TSpline3 to recalculate coefficients
127  Spline = new TSpline3(oldName.c_str(), XVals.data(), YVals.data(), NValues);
128  }
129 }

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

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

782  {
783 // *****************************************
784  int Np = spl->GetNp();
785  M3::float_t x, y, b, c, d;
786  // Go through spline segment parameters,
787  // Get y values for each spline knot,
788  // Every knot must evaluate to 1.0 to create a flat spline
789  for(int i = 0; i < Np; i++) {
790  spl->GetCoeff(i, x, y, b, c, d);
791  if (y != 1) {
792  return false;
793  }
794  }
795  return true;
796 }
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:30

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

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

801  {
802 // *********************************
803  std::vector<std::vector<TSpline3*> >::iterator OuterIt;
804  std::vector<TSpline3*>::iterator InnerIt;
805 
806  // The return vector
807  std::vector<std::vector<TSpline3_red*> > ReducedVector;
808  ReducedVector.reserve(MasterSpline.size());
809 
810  // Loop over each parameter
811  int OuterCounter = 0;
812  for (OuterIt = MasterSpline.begin(); OuterIt != MasterSpline.end(); ++OuterIt, ++OuterCounter) {
813  // Make the temp vector
814  std::vector<TSpline3_red*> TempVector;
815  TempVector.reserve(OuterIt->size());
816  int InnerCounter = 0;
817  // Loop over each TSpline3 pointer
818  for (InnerIt = OuterIt->begin(); InnerIt != OuterIt->end(); ++InnerIt, ++InnerCounter) {
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 != NULL) {
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 }