4 #pragma GCC diagnostic ignored "-Wuseless-cast"
5 #pragma GCC diagnostic ignored "-Wfloat-conversion"
17 MACH3LOG_ERROR(
"Trying to create BinnedSplineHandler with uninitialized covariance object");
23 MACH3LOG_ERROR(
"Trying to create BinnedSplineHandler with uninitialized MaCh3Modes object");
68 const std::string& SampleTitle,
69 const std::vector<std::string>& OscChanFileNames,
70 const std::vector<std::string>& SplineVarNames)
76 Dimensions.push_back(
static_cast<int>(SplineVarNames.size()));
96 MACH3LOG_INFO(
"SplineModeVecs_Sample is of size {}", SplineModeVecs_Sample.size());
101 int nOscChan = int(OscChanFileNames.size());
106 std::vector<std::vector<TAxis *>> SampleBinning(nOscChan);
107 for (
int iOscChan = 0; iOscChan < nOscChan; iOscChan++)
109 SampleBinning[iOscChan] =
FindSplineBinning(OscChanFileNames[iOscChan], SampleTitle);
111 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
116 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
119 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
126 std::map<unsigned int, std::map<unsigned int, std::map<std::string, std::pair<unsigned int, unsigned int>>>> systZeroCounts;
128 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++) {
132 std::vector<std::string> SplineFileParPrefixNames_Sample =
135 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++) {
136 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++) {
137 unsigned int zeroCount = 0;
138 unsigned int totalSplines = 0;
140 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++) {
142 std::string modeSuffix =
145 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++) {
146 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++) {
147 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++) {
149 if (
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3] == 0) {
152 systZeroCounts[iSample][iSyst][modeSuffix] = {totalSplines, zeroCount};
155 "Sample '{}' | OscChan {} | Syst '{}' | Mode '{}' | Var1 {} | Var2 {} | Var3 {} => Value: {}",
158 SplineFileParPrefixNames_Sample[iSyst],
163 indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3]
175 for (
const auto& samplePair : systZeroCounts) {
176 unsigned int iSample = samplePair.first;
178 for (
const auto& systPair : samplePair.second) {
179 unsigned int iSyst = systPair.first;
180 const auto& systName = SplineFileParPrefixNames_Sample[iSyst];
181 for (
const auto& modePair : systPair.second) {
182 const auto& modeSuffix = modePair.first;
183 const auto& counts = modePair.second;
185 "Sample '{}': Systematic '{}' has missing splines in mode '{}'. Expected Splines: {}, Missing Splines: {}",
206 MACH3LOG_ERROR(
"Something's gone wrong when we tried to get the size of your monolith");
221 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
223 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
225 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++)
227 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
229 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
231 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
233 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
235 int splineindex=
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
238 bool foundUniqueSpline =
false;
239 for (
int iUniqueSyst = 0; iUniqueSyst <
nParams; iUniqueSyst++)
244 foundUniqueSpline =
true;
248 if (!foundUniqueSpline)
253 for (
int iUniqueSyst = 0; iUniqueSyst <
nParams; iUniqueSyst++)
272 for(
int i = 0; i < splineKnots; i++){
279 delete[] tmpXCoeffArr;
280 delete[] tmpManyCoeffArr;
313 #pragma omp parallel for simd
319 const short int currentsegment = short(
SplineSegments[uniqueIndex]);
322 const int coeffOffset = segCoeff *
_nCoeff_;
341 if(weight < 0){weight = 0.;}
358 indexvec.emplace_back(nOscChannels);
360 for (
int iOscChan = 0; iOscChan < nOscChannels; ++iOscChan)
362 indexvec.back()[iOscChan].resize(nSplineSysts);
363 for (
int iSyst = 0; iSyst < nSplineSysts; ++iSyst)
365 int nModesInSyst =
static_cast<int>(
SplineModeVecs[iSample][iSyst].size());
366 indexvec.back()[iOscChan][iSyst].resize(nModesInSyst);
368 for (
int iMode = 0; iMode < nModesInSyst; ++iMode)
370 const int nBins1 =
SplineBinning[iSample][iOscChan][0]->GetNbins();
371 const int nBins2 =
SplineBinning[iSample][iOscChan][1]->GetNbins();
372 const int nBins3 =
SplineBinning[iSample][iOscChan][2]->GetNbins();
374 indexvec.back()[iOscChan][iSyst][iMode]
375 .resize(nBins1,std::vector<std::vector<int>>(nBins2, std::vector<int>(nBins3, 0)));
388 constexpr
int nDummyBins = 1;
389 constexpr
double DummyEdges[2] = {-1e15, 1e15};
390 TAxis* DummyAxis =
new TAxis(nDummyBins, DummyEdges);
391 TH2F* Hist2D =
nullptr;
392 TH3F* Hist3D =
nullptr;
394 auto File = std::unique_ptr<TFile>(
TFile::Open(FileName.c_str(),
"READ"));
395 if (!File || File->IsZombie())
398 MACH3LOG_ERROR(
"This is caused by something here! {} : {}", __FILE__, __LINE__);
405 std::string TemplateName =
"dev_tmp_0_0";
406 TObject *Obj = File->Get(TemplateName.c_str());
410 TemplateName =
"dev_tmp.0.0";
411 Obj = File->Get(TemplateName.c_str());
414 MACH3LOG_ERROR(
"Could not find dev_tmp_0_0 in spline file. Spline binning cannot be set!");
421 bool isHist2D = Obj->IsA() == TH2F::Class();
423 bool isHist3D = Obj->IsA() == TH3F::Class();
424 if (!isHist2D && !isHist3D)
426 MACH3LOG_ERROR(
"Object doesn't inherit from either TH2D and TH3D - Odd A");
437 Hist2D = File->Get<TH2F>(TemplateName.c_str());
442 Hist3D = File->Get<TH3F>((TemplateName.c_str()));
444 if (
Dimensions[iSample] != 3 && Hist3D->GetZaxis()->GetNbins() != 1)
449 Hist3D = File->Get<TH3F>(TemplateName.c_str());
452 std::vector<TAxis*> ReturnVec;
457 ReturnVec[0] =
static_cast<TAxis*
>(Hist2D->GetXaxis()->Clone());
458 ReturnVec[1] =
static_cast<TAxis*
>(Hist2D->GetYaxis()->Clone());
459 ReturnVec[2] =
static_cast<TAxis*
>(DummyAxis->Clone());
460 }
else if (isHist3D) {
461 ReturnVec[0] =
static_cast<TAxis*
>(Hist3D->GetXaxis()->Clone());
462 ReturnVec[1] =
static_cast<TAxis*
>(Hist3D->GetYaxis()->Clone());
463 ReturnVec[2] =
static_cast<TAxis*
>(DummyAxis->Clone());
466 ReturnVec[0] =
static_cast<TAxis*
>(Hist3D->GetXaxis()->Clone());
467 ReturnVec[1] =
static_cast<TAxis*
>(Hist3D->GetYaxis()->Clone());
468 ReturnVec[2] =
static_cast<TAxis*
>(Hist3D->GetZaxis()->Clone());
474 for (
unsigned int iAxis = 0; iAxis < ReturnVec.size(); ++iAxis) {
488 int SampleCounter_NonFlat = 0;
489 int SampleCounter_All = 0;
490 int FullCounter_NonFlat = 0;
491 int FullCounter_All = 0;
493 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
495 SampleCounter_NonFlat = 0;
496 SampleCounter_All = 0;
498 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
500 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++)
502 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
504 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
506 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
508 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
512 int splineindex =
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
515 SampleCounter_NonFlat += 1;
517 SampleCounter_All += 1;
525 MACH3LOG_DEBUG(
"{:<10} has {:<10} splines, of which {:<10} are not flat",
SampleTitles[iSample], SampleCounter_All, SampleCounter_NonFlat);
527 FullCounter_NonFlat += SampleCounter_NonFlat;
528 FullCounter_All += SampleCounter_All;
533 MACH3LOG_INFO(
"Total number of splines loaded: {}", FullCounter_All);
534 MACH3LOG_INFO(
"Total number of non-flat splines loaded: {}", FullCounter_NonFlat);
538 return FullCounter_NonFlat;
540 return FullCounter_All;
547 std::vector<TSpline3_red*> UniqueSystSplines;
552 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
554 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][0].size(); iSyst++)
557 bool FoundSyst =
false;
561 for (
unsigned int iFoundSyst = 0; iFoundSyst <
UniqueSystNames.size(); iFoundSyst++)
570 bool FoundNonFlatSpline =
false;
573 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
575 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
577 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
579 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
581 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
583 int splineindex=
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
588 FoundNonFlatSpline =
true;
590 if (FoundNonFlatSpline) {
break;}
592 if (FoundNonFlatSpline) {
break;}
594 if (FoundNonFlatSpline){
break; }
596 if (FoundNonFlatSpline){
break; }
598 if (FoundNonFlatSpline) {
break; }
601 if(FoundNonFlatSpline){
605 if (!FoundNonFlatSpline)
607 MACH3LOG_INFO(
"{} syst has no response in sample {}", SystName, iSample);
608 MACH3LOG_INFO(
"Whilst this isn't necessarily a problem, it seems odd");
615 nParams =
static_cast<short int>(UniqueSystSplines.size());
621 for (
int iSpline = 0; iSpline <
nParams; iSpline++)
630 UniqueSystSplines[iSpline]->GetKnot(iKnot, xPoint, yPoint);
639 MACH3LOG_INFO(
"{:<15} | {:<20} | {:<6}",
"Spline Index",
"Syst Name",
"nKnots");
640 for (
int iUniqueSyst = 0; iUniqueSyst <
nParams; iUniqueSyst++)
647 int nCombinations_FlatSplines = 0;
648 int nCombinations_All = 0;
650 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
652 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
654 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++)
656 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
659 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
661 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
663 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
665 int splineindex=
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
668 nCombinations_All += 1;
670 nCombinations_FlatSplines += 1;
671 nCombinations_All += 1;
681 MACH3LOG_INFO(
"Number of combinations of Sample, OscChan, Syst and Mode which have entirely flat response: {} / {}", nCombinations_FlatSplines, nCombinations_All);
691 for (
int i = 0; i < nPoints; i++) {
693 for (
int j = 0; j <
_nCoeff_; j++) {
698 for(
int i=0; i<nPoints; i++) {
725 if(Axis > DimensionLabels[iSample].size()){
726 MACH3LOG_ERROR(
"The spline Axis you are trying to get the label of is larger than the number of dimensions");
727 MACH3LOG_ERROR(
"You are trying to get axis {} but have only got {}", Axis, Dimensions[iSample]);
730 return DimensionLabels.at(iSample).at(Axis);
737 for (
size_t iSample = 0; iSample <
SampleTitles.size(); ++iSample) {
739 return static_cast<int>(iSample);
750 const int iSample = GetSampleIndex(SampleTitle);
752 MACH3LOG_INFO(
"Details about sample: {:<20}", SampleTitles[iSample]);
754 MACH3LOG_INFO(
"\t nSplineParam: {:<35}", nSplineParams[iSample]);
762 int iSample = GetSampleIndex(SampleTitle);
763 int nOscChannels = int(indexvec[iSample].size());
764 MACH3LOG_INFO(
"Sample {} has {} oscillation channels", SampleTitle, nOscChannels);
766 for (
int iOscChan = 0; iOscChan < nOscChannels; iOscChan++)
768 int nSysts = int(indexvec[iSample][iOscChan].size());
769 MACH3LOG_INFO(
"Oscillation channel {} has {} systematics", iOscChan, nSysts);
772 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
773 MACH3LOG_INFO(
"Printing no. of modes affected by each systematic for each oscillation channel");
774 for (
unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++) {
775 std::string modes = fmt::format(
"OscChan: {}\t", iOscChan);
776 for (
unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++) {
777 modes += fmt::format(
"{} ", indexvec[iSample][iOscChan][iSyst].size());
781 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
792 auto checkIndex = [&isValid](
int index,
size_t size,
const std::string& name) {
793 if (index < 0 || index >=
int(size)) {
794 MACH3LOG_ERROR(
"{} index is invalid! 0 <= Index < {} ", name, size);
799 checkIndex(iSample,
indexvec.size(),
"Sample");
800 if (isValid) checkIndex(iOscChan,
indexvec[iSample].size(),
"OscChan");
801 if (isValid) checkIndex(iSyst,
indexvec[iSample][iOscChan].size(),
"Syst");
802 if (isValid) checkIndex(iMode,
indexvec[iSample][iOscChan][iSyst].size(),
"Mode");
803 if (isValid) checkIndex(iVar1,
indexvec[iSample][iOscChan][iSyst][iMode].size(),
"Var1");
804 if (isValid) checkIndex(iVar2,
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(),
"Var2");
805 if (isValid) checkIndex(iVar3,
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(),
"Var3");
827 const int NBins = Axis->GetNbins();
828 std::string text =
"";
829 for (
int iBin = 0; iBin <= NBins; iBin++) {
830 text += fmt::format(
"{} ", Axis->GetXbins()->GetAt(iBin));
839 std::vector<std::vector<int>> ReturnVec;
841 int nSplineSysts =
static_cast<int>(
indexvec[SampleIndex][iOscChan].size());
855 int Var1Bin =
SplineBinning[SampleIndex][iOscChan][0]->FindBin(Var1Val)-1;
856 if (Var1Bin < 0 || Var1Bin >=
SplineBinning[SampleIndex][iOscChan][0]->GetNbins()) {
860 int Var2Bin =
SplineBinning[SampleIndex][iOscChan][1]->FindBin(Var2Val)-1;
861 if (Var2Bin < 0 || Var2Bin >=
SplineBinning[SampleIndex][iOscChan][1]->GetNbins()) {
865 int Var3Bin =
SplineBinning[SampleIndex][iOscChan][2]->FindBin(Var3Val)-1;
866 if (Var3Bin < 0 || Var3Bin >=
SplineBinning[SampleIndex][iOscChan][2]->GetNbins()){
870 for(
int iSyst=0; iSyst<nSplineSysts; iSyst++){
871 std::vector<int> spline_modes =
SplineModeVecs[SampleIndex][iSyst];
872 int nSampleModes =
static_cast<int>(spline_modes.size());
875 for(
int iMode = 0; iMode<nSampleModes ; iMode++){
877 if (Mode == spline_modes[iMode]) {
878 int splineID=
indexvec[SampleIndex][iOscChan][iSyst][iMode][Var1Bin][Var2Bin][Var3Bin];
881 ReturnVec.push_back({SampleIndex, iOscChan, iSyst, iMode, Var1Bin, Var2Bin, Var3Bin});
894 size_t InputVectorSize = InputVector.size();
895 std::vector< std::vector<int> > ReturnVec(InputVectorSize);
898 for (
size_t iSyst=0;iSyst<InputVectorSize;iSyst++) {
899 std::vector<int> TmpVec;
900 std::vector<std::string> TestVec;
903 for (
unsigned int iMode = 0 ; iMode < InputVector[iSyst].size() ; iMode++) {
904 int Mode = InputVector[iSyst][iMode];
907 bool IncludeMode =
true;
908 for (
auto TestString : TestVec) {
909 if (ModeName == TestString) {
916 TmpVec.push_back(Mode);
917 TestVec.push_back(ModeName);
921 ReturnVec[iSyst] = TmpVec;
931 for (
int iOscChan = 0; iOscChan < nOscChannels; iOscChan++) {
933 TSpline3* mySpline =
nullptr;
936 int nKnots, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin =
M3::_BAD_INT_;
940 std::set<std::string> SplineFileNames;
942 auto File = std::unique_ptr<TFile>(
TFile::Open(OscChanFileNames[iOscChan].c_str()));
944 if (!File || File->IsZombie()) {
951 for (
auto k : *File->GetListOfKeys()) {
952 auto Key =
static_cast<TKey*
>(k);
953 TClass *Class = gROOT->GetClass(Key->GetClassName(),
false);
954 if(!Class->InheritsFrom(
"TSpline3")) {
958 std::string FullSplineName = std::string(Key->GetName());
960 if (SplineFileNames.count(FullSplineName) > 0) {
961 MACH3LOG_CRITICAL(
"Skipping spline - Found a spline whose name has already been encountered before: {}", FullSplineName);
964 SplineFileNames.insert(FullSplineName);
969 MACH3LOG_ERROR(
"Invalid tokens from spline name - Expected {} tokens. Check implementation in GetTokensFromSplineName()",
static_cast<int>(
kNTokens));
990 MACH3LOG_DEBUG(
"Couldn't Match any systematic name in ParameterHandler with spline name: {}" , FullSplineName);
995 for (
unsigned int iMode = 0; iMode <
SplineModeVecs[iSample][SystNum].size(); iMode++) {
1002 if (ModeNum == -1) {
1005 MACH3LOG_DEBUG(
"Couldn't find mode for {} in {}. Problem Spline is : {} ", Mode, Syst, FullSplineName);
1009 mySpline = Key->ReadObject<TSpline3>();
1011 if (
isValidSplineIndex(SampleTitle, iOscChan, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin)) {
1012 MACH3LOG_TRACE(
"Pushed back monolith for spline {}", FullSplineName);
1014 nKnots = mySpline->GetNp();
1016 for (
int iKnot = 0; iKnot < nKnots; iKnot++) {
1017 mySpline->GetKnot(iKnot, x, y);
1018 if (y < 0.99999 || y > 1.00001)
1035 if(mySpline)
delete mySpline;
1062 size_t pos = FileName.find(
' ');
1063 if (pos != std::string::npos) {
1064 MACH3LOG_WARN(
"Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1065 while ((pos = FileName.find(
' ')) != std::string::npos) {
1066 FileName[pos] =
'_';
1069 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"OPEN");
1071 TMacro *ConfigCov = SplineFile->Get<TMacro>(
"ParameterHandler");
1079 MACH3LOG_ERROR(
"Loading precomputed spline file, however encountered different YAML config, please regenerate input");
1088 for (
int iSpline = 0; iSpline <
nParams; iSpline++) {
1091 SplineFile->Close();
1098 TTree *Settings = SplineFile->Get<TTree>(
"Settings");
1099 int CoeffIndex_temp, MonolithSize_temp;
1100 short int nParams_temp;
1101 Settings->SetBranchAddress(
"CoeffIndex", &CoeffIndex_temp);
1102 Settings->SetBranchAddress(
"MonolithSize", &MonolithSize_temp);
1103 Settings->SetBranchAddress(
"nParams", &nParams_temp);
1104 int indexvec_sizes[7];
1105 for (
int i = 0; i < 7; ++i) {
1106 Settings->SetBranchAddress((
"indexvec_size" + std::to_string(i+1)).c_str(), &indexvec_sizes[i]);
1109 int SplineBinning_size1, SplineBinning_size2, SplineBinning_size3;
1110 Settings->SetBranchAddress(
"SplineBinning_size1", &SplineBinning_size1);
1111 Settings->SetBranchAddress(
"SplineBinning_size2", &SplineBinning_size2);
1112 Settings->SetBranchAddress(
"SplineBinning_size3", &SplineBinning_size3);
1113 int SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3;
1114 Settings->SetBranchAddress(
"SplineModeVecs_size1", &SplineModeVecs_size1);
1115 Settings->SetBranchAddress(
"SplineModeVecs_size2", &SplineModeVecs_size2);
1116 Settings->SetBranchAddress(
"SplineModeVecs_size3", &SplineModeVecs_size3);
1117 std::vector<std::string>* SampleNames_temp =
nullptr;
1118 Settings->SetBranchAddress(
"SampleNames", &SampleNames_temp);
1119 std::vector<std::string>* SampleTitles_temp =
nullptr;
1120 Settings->SetBranchAddress(
"SampleTitles", &SampleTitles_temp);
1121 Settings->GetEntry(0);
1134 indexvec.resize(indexvec_sizes[0]);
1135 for (
int i = 0; i < indexvec_sizes[0]; ++i) {
1136 indexvec[i].resize(indexvec_sizes[1]);
1137 for (
int j = 0; j < indexvec_sizes[1]; ++j) {
1138 indexvec[i][j].resize(indexvec_sizes[2]);
1139 for (
int k = 0; k < indexvec_sizes[2]; ++k) {
1140 indexvec[i][j][k].resize(indexvec_sizes[3]);
1141 for (
int l = 0; l < indexvec_sizes[3]; ++l) {
1142 indexvec[i][j][k][l].resize(indexvec_sizes[4]);
1143 for (
int m = 0; m < indexvec_sizes[4]; ++m) {
1144 indexvec[i][j][k][l][m].resize(indexvec_sizes[5]);
1145 for (
int n = 0; n < indexvec_sizes[5]; ++n) {
1146 indexvec[i][j][k][l][m][n].resize(indexvec_sizes[6]);
1154 auto Resize3D = [](
auto& vec,
int d1,
int d2,
int d3) {
1156 for (
int i = 0; i < d1; ++i) {
1158 for (
int j = 0; j < d2; ++j) {
1159 vec[i][j].resize(d3);
1164 Resize3D(
SplineBinning, SplineBinning_size1, SplineBinning_size2, SplineBinning_size3);
1165 Resize3D(
SplineModeVecs, SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3);
1172 TTree *MonolithTree = SplineFile->Get<TTree>(
"MonolithTree");
1178 MonolithTree->SetBranchAddress(
"isflatarray",
isflatarray);
1181 std::vector<int>* coeffindexvec_temp =
nullptr;
1182 MonolithTree->SetBranchAddress(
"coeffindexvec", &coeffindexvec_temp);
1183 std::vector<int>* uniquecoeffindices_temp =
nullptr;
1184 MonolithTree->SetBranchAddress(
"uniquecoeffindices", &uniquecoeffindices_temp);
1185 std::vector<int>* uniquesplinevec_Monolith_temp =
nullptr;
1186 MonolithTree->SetBranchAddress(
"uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1187 std::vector<int>* UniqueSystIndices_temp =
nullptr;
1188 MonolithTree->SetBranchAddress(
"UniqueSystIndices", &UniqueSystIndices_temp);
1192 MonolithTree->SetBranchAddress(
"xcoeff",
xcoeff_arr);
1194 MonolithTree->GetEntry(0);
1206 TTree *IndexTree = SplineFile->Get<TTree>(
"IndexVec");
1208 std::vector<int> Dim(7);
1210 for (
int d = 0; d < 7; ++d) {
1211 IndexTree->SetBranchAddress(Form(
"dim%d", d+1), &Dim[d]);
1213 IndexTree->SetBranchAddress(
"value", &value);
1216 for (Long64_t i = 0; i < IndexTree->GetEntries(); ++i) {
1217 IndexTree->GetEntry(i);
1218 indexvec[Dim[0]][Dim[1]][Dim[2]][Dim[3]][Dim[4]][Dim[5]][Dim[6]] = value;
1222 TTree *SplineBinningTree = SplineFile->Get<TTree>(
"SplineBinningTree");
1223 std::vector<int> indices(3);
1224 SplineBinningTree->SetBranchAddress(
"i", &indices[0]);
1225 SplineBinningTree->SetBranchAddress(
"j", &indices[1]);
1226 SplineBinningTree->SetBranchAddress(
"k", &indices[2]);
1227 TAxis* axis =
nullptr;
1228 SplineBinningTree->SetBranchAddress(
"axis", &axis);
1231 for (Long64_t entry = 0; entry < SplineBinningTree->GetEntries(); ++entry) {
1232 SplineBinningTree->GetEntry(entry);
1236 SplineBinning[i][j][k] =
static_cast<TAxis*
>(axis->Clone());
1239 std::vector<int> indices_mode(3);
1241 TTree *SplineModeTree = SplineFile->Get<TTree>(
"SplineModeTree");
1242 SplineModeTree->SetBranchAddress(
"i", &indices_mode[0]);
1243 SplineModeTree->SetBranchAddress(
"j", &indices_mode[1]);
1244 SplineModeTree->SetBranchAddress(
"k", &indices_mode[2]);
1245 SplineModeTree->SetBranchAddress(
"value", &mode_value);
1248 for (Long64_t entry = 0; entry < SplineModeTree->GetEntries(); ++entry) {
1249 SplineModeTree->GetEntry(entry);
1250 int i = indices_mode[0];
1251 int j = indices_mode[1];
1252 int k = indices_mode[2];
1263 size_t pos = FileName.find(
' ');
1264 if (pos != std::string::npos) {
1265 MACH3LOG_WARN(
"Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1266 while ((pos = FileName.find(
' ')) != std::string::npos) {
1267 FileName[pos] =
'_';
1271 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"recreate");
1273 TMacro ConfigSave =
YAMLtoTMacro(ConfigCurrent,
"ParameterHandler");
1282 SplineFile->Close();
1288 TTree *Settings =
new TTree(
"Settings",
"Settings");
1291 short int nParams_temp =
nParams;
1293 Settings->Branch(
"CoeffIndex", &CoeffIndex_temp,
"CoeffIndex/I");
1294 Settings->Branch(
"MonolithSize", &MonolithSize_temp,
"MonolithSize/I");
1295 Settings->Branch(
"nParams", &nParams_temp,
"nParams/S");
1297 int indexvec_sizes[7];
1298 indexvec_sizes[0] =
static_cast<int>(
indexvec.size());
1299 indexvec_sizes[1] = (indexvec_sizes[0] > 0) ?
static_cast<int>(
indexvec[0].size()) : 0;
1300 indexvec_sizes[2] = (indexvec_sizes[1] > 0) ?
static_cast<int>(
indexvec[0][0].size()) : 0;
1301 indexvec_sizes[3] = (indexvec_sizes[2] > 0) ?
static_cast<int>(
indexvec[0][0][0].size()) : 0;
1302 indexvec_sizes[4] = (indexvec_sizes[3] > 0) ?
static_cast<int>(
indexvec[0][0][0][0].size()) : 0;
1303 indexvec_sizes[5] = (indexvec_sizes[4] > 0) ?
static_cast<int>(
indexvec[0][0][0][0][0].size()) : 0;
1304 indexvec_sizes[6] = (indexvec_sizes[5] > 0) ?
static_cast<int>(
indexvec[0][0][0][0][0][0].size()) : 0;
1306 for (
int i = 0; i < 7; ++i) {
1307 Settings->Branch((
"indexvec_size" + std::to_string(i+1)).c_str(),
1308 &indexvec_sizes[i], (
"indexvec_size" + std::to_string(i+1) +
"/I").c_str());
1311 int SplineBinning_size1 =
static_cast<int>(
SplineBinning.size());
1312 int SplineBinning_size2 = (SplineBinning_size1 > 0) ?
static_cast<int>(
SplineBinning[0].size()) : 0;
1313 int SplineBinning_size3 = (SplineBinning_size2 > 0) ?
static_cast<int>(
SplineBinning[0][0].size()) : 0;
1315 Settings->Branch(
"SplineBinning_size1", &SplineBinning_size1,
"SplineBinning_size1/I");
1316 Settings->Branch(
"SplineBinning_size2", &SplineBinning_size2,
"SplineBinning_size2/I");
1317 Settings->Branch(
"SplineBinning_size3", &SplineBinning_size3,
"SplineBinning_size3/I");
1319 int SplineModeVecs_size1 =
static_cast<int>(
SplineModeVecs.size());
1320 int SplineModeVecs_size2 = (SplineModeVecs_size1 > 0) ?
static_cast<int>(
SplineModeVecs[0].size()) : 0;
1321 int SplineModeVecs_size3 = (SplineModeVecs_size2 > 0) ?
static_cast<int>(
SplineModeVecs[0][0].size()) : 0;
1323 Settings->Branch(
"SplineModeVecs_size1", &SplineModeVecs_size1,
"SplineModeVecs_size1/I");
1324 Settings->Branch(
"SplineModeVecs_size2", &SplineModeVecs_size2,
"SplineModeVecs_size2/I");
1325 Settings->Branch(
"SplineModeVecs_size3", &SplineModeVecs_size3,
"SplineModeVecs_size3/I");
1327 std::vector<std::string> SampleNames_temp =
SampleNames;
1328 Settings->Branch(
"SampleNames", &SampleNames_temp);
1329 std::vector<std::string> SampleTitles_temp =
SampleTitles;
1330 Settings->Branch(
"SampleTitles", &SampleTitles_temp);
1341 TTree *MonolithTree =
new TTree(
"MonolithTree",
"MonolithTree");
1346 MonolithTree->Branch(
"coeffindexvec", &coeffindexvec_temp);
1348 MonolithTree->Branch(
"uniquecoeffindices", &uniquecoeffindices_temp);
1350 MonolithTree->Branch(
"uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1352 MonolithTree->Branch(
"UniqueSystIndices", &UniqueSystIndices_temp);
1355 MonolithTree->Fill();
1357 MonolithTree->Write();
1358 delete MonolithTree;
1365 TTree *IndexTree =
new TTree(
"IndexVec",
"IndexVec");
1368 std::vector<int> Dim(7);
1372 for (
int d = 0; d < 7; ++d) {
1373 IndexTree->Branch(Form(
"dim%d", d+1), &Dim[d], Form(
"dim%d/I", d+1));
1375 IndexTree->Branch(
"value", &value,
"value/I");
1378 for (
size_t i = 0; i <
indexvec.size(); ++i) {
1379 for (
size_t j = 0; j <
indexvec[i].size(); ++j) {
1380 for (
size_t k = 0; k <
indexvec[i][j].size(); ++k) {
1381 for (
size_t l = 0; l <
indexvec[i][j][k].size(); ++l) {
1382 for (
size_t m = 0; m <
indexvec[i][j][k][l].size(); ++m) {
1383 for (
size_t n = 0; n <
indexvec[i][j][k][l][m].size(); ++n) {
1384 for (
size_t p = 0; p <
indexvec[i][j][k][l][m][n].size(); ++p) {
1385 Dim[0] =
static_cast<int>(i);
1386 Dim[1] =
static_cast<int>(j);
1387 Dim[2] =
static_cast<int>(k);
1388 Dim[3] =
static_cast<int>(l);
1389 Dim[4] =
static_cast<int>(m);
1390 Dim[5] =
static_cast<int>(n);
1391 Dim[6] =
static_cast<int>(p);
1392 value =
static_cast<int>(
indexvec[i][j][k][l][m][n][p]);
1412 TTree *SplineBinningTree =
new TTree(
"SplineBinningTree",
"SplineBinningTree");
1413 std::vector<int> indices(3);
1414 TAxis* axis =
nullptr;
1415 SplineBinningTree->Branch(
"i", &indices[0],
"i/I");
1416 SplineBinningTree->Branch(
"j", &indices[1],
"j/I");
1417 SplineBinningTree->Branch(
"k", &indices[2],
"k/I");
1418 SplineBinningTree->Branch(
"axis",
"TAxis", &axis);
1425 indices[0] =
static_cast<int>(i);
1426 indices[1] =
static_cast<int>(j);
1427 indices[2] =
static_cast<int>(k);
1428 SplineBinningTree->Fill();
1433 SplineBinningTree->Write();
1434 delete SplineBinningTree;
1436 std::vector<int> indices_mode(3);
1439 TTree *SplineModeTree =
new TTree(
"SplineModeTree",
"SplineModeTree");
1441 SplineModeTree->Branch(
"i", &indices_mode[0],
"i/I");
1442 SplineModeTree->Branch(
"j", &indices_mode[1],
"j/I");
1443 SplineModeTree->Branch(
"k", &indices_mode[2],
"k/I");
1444 SplineModeTree->Branch(
"value", &mode_value,
"value/I");
1450 indices_mode[0] =
static_cast<int>(i);
1451 indices_mode[1] =
static_cast<int>(j);
1452 indices_mode[2] =
static_cast<int>(k);
1454 SplineModeTree->Fill();
1460 SplineModeTree->Write();
1461 delete SplineModeTree;
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
KS: Restore warning checking after including external headers.
#define MACH3LOG_CRITICAL
void CleanContainer(T &)
Base case: do nothing for non-pointer types.
void CleanVector(T &)
Base case: do nothing for non-vector types.
@ kSpline
For splined parameters (1D)
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...
void ApplyKnotWeightCapTSpline3(TSpline3 *&Spline, const int splineParsIndex, ParameterHandlerGeneric *XsecCov)
EM: Apply capping to knot weight for specified spline parameter. param graph needs to have been set i...
bool isFlat(TSpline3_red *&spl)
CW: Helper function used in the constructor, tests to see if the spline is flat.
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
YAML::Node TMacroToYAML(const TMacro ¯o)
KS: Convert a ROOT TMacro object to a YAML node.
bool compareYAMLNodes(const YAML::Node &node1, const YAML::Node &node2, bool Mute=false)
Compare if yaml nodes are identical.
void getSplineCoeff_SepMany(int splineindex, M3::float_t *&xArray, M3::float_t *&manyArray)
std::string getDimLabel(const int BinningOpt, const unsigned int Axis) const
void PrepareSplineFile(std::string FileName) override
KS: Prepare spline file that can be used for fast loading.
bool * isflatarray
Need to keep track of which splines are flat and which aren't.
void LoadIndexDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Index.
int CountNumberOfLoadedSplines(bool NonFlat=false, int Verbosity=0)
std::vector< std::vector< std::vector< std::vector< std::vector< std::vector< std::vector< int > > > > > > > indexvec
Variables related to determined which modes have splines and which piggy-back of other modes.
std::vector< std::vector< std::string > > SplineFileParPrefixNames
void CalcSplineWeights() override
CPU based code which eval weight for each spline.
void LoadSettingsDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Settings.
std::vector< int > coeffindexvec
void cleanUpMemory()
Remove setup variables not needed for spline evaluations.
void PrintBinning(TAxis *Axis) const
ParameterHandlerGeneric * xsec
Pointer to covariance from which we get information about spline params.
void InvestigateMissingSplines() const
This function will find missing splines in file.
void Evaluate() override
CW: This Eval should be used when using two separate x,{y,a,b,c,d} arrays to store the weights; proba...
std::vector< int > nSplineParams
void ModifyWeights() override
Calc total event weight, not used by Bin-by-bin splines.
std::vector< std::vector< std::vector< int > > > SplineModeVecs
std::vector< int > nOscChans
M3::float_t * xcoeff_arr
x coefficients for each spline
std::vector< std::string > SampleTitles
void LoadSplineFile(std::string FileName) override
KS: Load preprocessed spline file.
void PrintSampleDetails(const std::string &SampleTitle) const
Print info like Sample ID of spline params etc.
std::vector< std::string > UniqueSystNames
name of each spline parameter
std::vector< std::vector< SplineInterpolation > > SplineInterpolationTypes
spline interpolation types for each sample. These vectors are from a call to GetSplineInterpolationFr...
std::vector< std::vector< int > > GetEventSplines(const std::string &SampleTitle, int iOscChan, int EventMode, double Var1Val, double Var2Val, double Var3Val)
Return the splines which affect a given event.
std::vector< int > Dimensions
std::vector< int > uniquesplinevec_Monolith
Maps single spline object with single parameter.
void PrepareIndexDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Index Info within SplineFile.
void BuildSampleIndexingArray(const std::string &SampleTitle)
std::vector< std::vector< int > > StripDuplicatedModes(const std::vector< std::vector< int > > &InputVector)
Check if there are any repeated modes. This is used to reduce the number of modes in case many intera...
virtual void FillSampleArray(std::string SampleTitle, std::vector< std::string > OscChanFileNames)
Loads and processes splines from ROOT files for a given sample.
std::vector< M3::float_t > weightvec_Monolith
Stores weight from spline evaluation for each single spline.
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
std::vector< TAxis * > FindSplineBinning(const std::string &FileName, const std::string &SampleTitle)
Grab histograms with spline binning.
std::vector< std::vector< std::string > > DimensionLabels
void PrepareMonolithDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Monolith Info within SplineFile.
BinnedSplineHandler(ParameterHandlerGeneric *xsec_, MaCh3Modes *Modes_)
Constructor.
void LoadMonolithDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed Monolith.
std::vector< std::vector< std::vector< TAxis * > > > SplineBinning
bool isValidSplineIndex(const std::string &SampleTitle, int iSyst, int iOscChan, int iMode, int iVar1, int iVar2, int iVar3)
Ensure we have spline for a given bin.
virtual std::vector< std::string > GetTokensFromSplineName(std::string FullSplineName)=0
std::vector< TSpline3_red * > splinevec_Monolith
holds each spline object before stripping into coefficient monolith
std::vector< int > uniquecoeffindices
Unique coefficient indices.
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.
MaCh3Modes * Modes
pointer to MaCh3 Mode from which we get spline suffix
void PrintArrayDetails(const std::string &SampleTitle) const
std::vector< std::vector< int > > GlobalSystIndex
This holds the global spline index and is used to grab the current parameter value to evaluate spline...
virtual ~BinnedSplineHandler()
Destructor.
std::vector< std::string > SampleNames
void TransferToMonolith()
flatten multidimensional spline array into proper monolith
std::vector< int > UniqueSystIndices
Global index of each spline param, it allows us to match spline ordering with global.
int GetSampleIndex(const std::string &SampleTitle) const
Get index of sample based on name.
M3::float_t * manycoeff_arr
ybcd coefficients for each spline
Custom exception class used throughout MaCh3.
KS: Class describing MaCh3 modes used in the analysis, it is being initialised from config.
int GetNModes() const
KS: Get number of modes, keep in mind actual number is +1 greater due to unknown category.
std::string GetSplineSuffixFromMaCh3Mode(const int Index)
DB: Get binned spline mode suffic from MaCh3 Mode.
const double * RetPointer(const int iParam)
DB Pointer return to param position.
YAML::Node GetConfig() const
Getter to return a copy of the YAML node.
Class responsible for handling of systematic error parameters with different types defined in the con...
const std::vector< int > GetGlobalSystIndexFromSampleName(const std::string &SampleName, const SystType Type)
DB Get spline parameters depending on given SampleName.
int GetNumParamsFromSampleName(const std::string &SampleName, const SystType Type)
DB Grab the number of parameters for the relevant SampleName.
const std::vector< std::string > GetParsNamesFromSampleName(const std::string &SampleName, const SystType Type)
DB Grab the parameter names for the relevant SampleName.
const std::vector< std::string > GetSplineParsNamesFromSampleName(const std::string &SampleName)
DB Get spline parameters depending on given SampleName.
const std::vector< SplineInterpolation > GetSplineInterpolationFromSampleName(const std::string &SampleName)
Get the interpolation types for splines affecting a particular SampleName.
const std::vector< std::vector< int > > GetSplineModeVecFromSampleName(const std::string &SampleName)
DB Grab the Spline Modes for the relevant SampleName.
Base class for calculating weight from spline.
short int nParams
Number of parameters that have splines.
void FindSplineSegment()
CW:Code used in step by step reweighting, Find Spline Segment for each param.
short int * SplineSegments
std::vector< FastSplineInfo > SplineInfoArray
float * ParamValues
Store parameter values they are not in FastSplineInfo as in case of GPU we need to copy paste it to G...
void LoadFastSplineInfoDir(std::unique_ptr< TFile > &SplineFile)
KS: Load preprocessed FastSplineInfo.
void PrepareFastSplineInfoDir(std::unique_ptr< TFile > &SplineFile) const
KS: Prepare Fast Spline Info within SplineFile.
CW: Reduced TSpline3 class.
constexpr static const double _BAD_DOUBLE_
Default value used for double initialisation.
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.
constexpr static const char * float_t_str_repr
constexpr static const int _BAD_INT_
Default value used for int initialisation.
constexpr T fmaf_t(T x, T y, T z)
Function template for fused multiply-add.
void AddPath(std::string &FilePath)
Prepends the MACH3 environment path to FilePath if it is not already present.