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: {}",
205 MACH3LOG_ERROR(
"Something's gone wrong when we tried to get the size of your monolith");
220 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
222 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
224 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++)
226 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
228 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
230 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
232 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
234 int splineindex=
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
237 bool foundUniqueSpline =
false;
238 for (
int iUniqueSyst = 0; iUniqueSyst <
nParams; iUniqueSyst++)
243 foundUniqueSpline =
true;
247 if (!foundUniqueSpline)
252 for (
int iUniqueSyst = 0; iUniqueSyst <
nParams; iUniqueSyst++)
271 for(
int i = 0; i < splineKnots; i++){
278 delete[] tmpXCoeffArr;
279 delete[] tmpManyCoeffArr;
308 #pragma omp parallel for simd
314 const short int currentsegment = short(
SplineSegments[uniqueIndex]);
317 const int coeffOffset = segCoeff *
_nCoeff_;
336 if(weight < 0){weight = 0.;}
352 indexvec.emplace_back(nOscChannels);
354 for (
int iOscChan = 0; iOscChan < nOscChannels; ++iOscChan)
356 indexvec.back()[iOscChan].resize(nSplineSysts);
357 for (
int iSyst = 0; iSyst < nSplineSysts; ++iSyst)
359 int nModesInSyst =
static_cast<int>(
SplineModeVecs[iSample][iSyst].size());
360 indexvec.back()[iOscChan][iSyst].resize(nModesInSyst);
362 for (
int iMode = 0; iMode < nModesInSyst; ++iMode)
364 const int nBins1 =
SplineBinning[iSample][iOscChan][0]->GetNbins();
365 const int nBins2 =
SplineBinning[iSample][iOscChan][1]->GetNbins();
366 const int nBins3 =
SplineBinning[iSample][iOscChan][2]->GetNbins();
368 indexvec.back()[iOscChan][iSyst][iMode]
369 .resize(nBins1,std::vector<std::vector<int>>(nBins2, std::vector<int>(nBins3, 0)));
381 constexpr
int nDummyBins = 1;
382 constexpr
double DummyEdges[2] = {-1e15, 1e15};
383 TAxis* DummyAxis =
new TAxis(nDummyBins, DummyEdges);
384 TH2F* Hist2D =
nullptr;
385 TH3F* Hist3D =
nullptr;
387 auto File = std::unique_ptr<TFile>(
TFile::Open(FileName.c_str(),
"READ"));
388 if (!File || File->IsZombie())
391 MACH3LOG_ERROR(
"This is caused by something here! {} : {}", __FILE__, __LINE__);
398 std::string TemplateName =
"dev_tmp_0_0";
399 TObject *Obj = File->Get(TemplateName.c_str());
403 TemplateName =
"dev_tmp.0.0";
404 Obj = File->Get(TemplateName.c_str());
407 MACH3LOG_ERROR(
"Could not find dev_tmp_0_0 in spline file. Spline binning cannot be set!");
414 bool isHist2D = Obj->IsA() == TH2F::Class();
416 bool isHist3D = Obj->IsA() == TH3F::Class();
417 if (!isHist2D && !isHist3D)
419 MACH3LOG_ERROR(
"Object doesn't inherit from either TH2D and TH3D - Odd A");
430 Hist2D = File->Get<TH2F>(TemplateName.c_str());
435 Hist3D = File->Get<TH3F>((TemplateName.c_str()));
437 if (
Dimensions[iSample] != 3 && Hist3D->GetZaxis()->GetNbins() != 1)
442 Hist3D = File->Get<TH3F>(TemplateName.c_str());
445 std::vector<TAxis*> ReturnVec;
450 ReturnVec[0] =
static_cast<TAxis*
>(Hist2D->GetXaxis()->Clone());
451 ReturnVec[1] =
static_cast<TAxis*
>(Hist2D->GetYaxis()->Clone());
452 ReturnVec[2] =
static_cast<TAxis*
>(DummyAxis->Clone());
453 }
else if (isHist3D) {
454 ReturnVec[0] =
static_cast<TAxis*
>(Hist3D->GetXaxis()->Clone());
455 ReturnVec[1] =
static_cast<TAxis*
>(Hist3D->GetYaxis()->Clone());
456 ReturnVec[2] =
static_cast<TAxis*
>(DummyAxis->Clone());
459 ReturnVec[0] =
static_cast<TAxis*
>(Hist3D->GetXaxis()->Clone());
460 ReturnVec[1] =
static_cast<TAxis*
>(Hist3D->GetYaxis()->Clone());
461 ReturnVec[2] =
static_cast<TAxis*
>(Hist3D->GetZaxis()->Clone());
467 for (
unsigned int iAxis = 0; iAxis < ReturnVec.size(); ++iAxis) {
480 int SampleCounter_NonFlat = 0;
481 int SampleCounter_All = 0;
482 int FullCounter_NonFlat = 0;
483 int FullCounter_All = 0;
485 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
487 SampleCounter_NonFlat = 0;
488 SampleCounter_All = 0;
490 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
492 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++)
494 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
496 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
498 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
500 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
504 int splineindex =
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
507 SampleCounter_NonFlat += 1;
509 SampleCounter_All += 1;
517 MACH3LOG_DEBUG(
"{:<10} has {:<10} splines, of which {:<10} are not flat",
SampleTitles[iSample], SampleCounter_All, SampleCounter_NonFlat);
519 FullCounter_NonFlat += SampleCounter_NonFlat;
520 FullCounter_All += SampleCounter_All;
525 MACH3LOG_INFO(
"Total number of splines loaded: {}", FullCounter_All);
526 MACH3LOG_INFO(
"Total number of non-flat splines loaded: {}", FullCounter_NonFlat);
530 return FullCounter_NonFlat;
532 return FullCounter_All;
539 std::vector<TSpline3_red*> UniqueSystSplines;
544 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
546 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][0].size(); iSyst++)
549 bool FoundSyst =
false;
553 for (
unsigned int iFoundSyst = 0; iFoundSyst <
UniqueSystNames.size(); iFoundSyst++)
562 bool FoundNonFlatSpline =
false;
565 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
567 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
569 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
571 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
573 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
575 int splineindex=
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
580 FoundNonFlatSpline =
true;
582 if (FoundNonFlatSpline) {
break;}
584 if (FoundNonFlatSpline) {
break;}
586 if (FoundNonFlatSpline){
break; }
588 if (FoundNonFlatSpline){
break; }
590 if (FoundNonFlatSpline) {
break; }
593 if(FoundNonFlatSpline){
597 if (!FoundNonFlatSpline)
599 MACH3LOG_INFO(
"{} syst has no response in sample {}", SystName, iSample);
600 MACH3LOG_INFO(
"Whilst this isn't necessarily a problem, it seems odd");
607 nParams =
static_cast<short int>(UniqueSystSplines.size());
613 for (
int iSpline = 0; iSpline <
nParams; iSpline++)
622 UniqueSystSplines[iSpline]->GetKnot(iKnot, xPoint, yPoint);
631 MACH3LOG_INFO(
"{:<15} | {:<20} | {:<6}",
"Spline Index",
"Syst Name",
"nKnots");
632 for (
int iUniqueSyst = 0; iUniqueSyst <
nParams; iUniqueSyst++)
639 int nCombinations_FlatSplines = 0;
640 int nCombinations_All = 0;
642 for (
unsigned int iSample = 0; iSample <
indexvec.size(); iSample++)
644 for (
unsigned int iOscChan = 0; iOscChan <
indexvec[iSample].size(); iOscChan++)
646 for (
unsigned int iSyst = 0; iSyst <
indexvec[iSample][iOscChan].size(); iSyst++)
648 for (
unsigned int iMode = 0; iMode <
indexvec[iSample][iOscChan][iSyst].size(); iMode++)
651 for (
unsigned int iVar1 = 0; iVar1 <
indexvec[iSample][iOscChan][iSyst][iMode].size(); iVar1++)
653 for (
unsigned int iVar2 = 0; iVar2 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(); iVar2++)
655 for (
unsigned int iVar3 = 0; iVar3 <
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(); iVar3++)
657 int splineindex=
indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2][iVar3];
660 nCombinations_All += 1;
662 nCombinations_FlatSplines += 1;
663 nCombinations_All += 1;
673 MACH3LOG_INFO(
"Number of combinations of Sample, OscChan, Syst and Mode which have entirely flat response: {} / {}", nCombinations_FlatSplines, nCombinations_All);
683 for (
int i = 0; i < nPoints; i++) {
685 for (
int j = 0; j <
_nCoeff_; j++) {
690 for(
int i=0; i<nPoints; i++) {
717 if(Axis > DimensionLabels[iSample].size()){
718 MACH3LOG_ERROR(
"The spline Axis you are trying to get the label of is larger than the number of dimensions");
719 MACH3LOG_ERROR(
"You are trying to get axis {} but have only got {}", Axis, Dimensions[iSample]);
722 return DimensionLabels.at(iSample).at(Axis);
729 for (
size_t iSample = 0; iSample <
SampleTitles.size(); ++iSample) {
731 return static_cast<int>(iSample);
742 const int iSample = GetSampleIndex(SampleTitle);
744 MACH3LOG_INFO(
"Details about sample: {:<20}", SampleTitles[iSample]);
746 MACH3LOG_INFO(
"\t nSplineParam: {:<35}", nSplineParams[iSample]);
754 int iSample = GetSampleIndex(SampleTitle);
755 int nOscChannels = int(indexvec[iSample].size());
756 MACH3LOG_INFO(
"Sample {} has {} oscillation channels", SampleTitle, nOscChannels);
758 for (
int iOscChan = 0; iOscChan < nOscChannels; iOscChan++)
760 int nSysts = int(indexvec[iSample][iOscChan].size());
761 MACH3LOG_INFO(
"Oscillation channel {} has {} systematics", iOscChan, nSysts);
764 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
765 MACH3LOG_INFO(
"Printing no. of modes affected by each systematic for each oscillation channel");
766 for (
unsigned int iOscChan = 0; iOscChan < indexvec[iSample].size(); iOscChan++) {
767 std::string modes = fmt::format(
"OscChan: {}\t", iOscChan);
768 for (
unsigned int iSyst = 0; iSyst < indexvec[iSample][iOscChan].size(); iSyst++) {
769 modes += fmt::format(
"{} ", indexvec[iSample][iOscChan][iSyst].size());
773 MACH3LOG_INFO(
"#----------------------------------------------------------------------------------------------------------------------------------#");
780 int iSample = GetSampleIndex(SampleTitle);
784 auto checkIndex = [&isValid](
int index,
size_t size,
const std::string& name) {
785 if (index < 0 || index >=
int(size)) {
786 MACH3LOG_ERROR(
"{} index is invalid! 0 <= Index < {} ", name, size);
791 checkIndex(iSample, indexvec.size(),
"Sample");
792 if (isValid) checkIndex(iOscChan, indexvec[iSample].size(),
"OscChan");
793 if (isValid) checkIndex(iSyst, indexvec[iSample][iOscChan].size(),
"Syst");
794 if (isValid) checkIndex(iMode, indexvec[iSample][iOscChan][iSyst].size(),
"Mode");
795 if (isValid) checkIndex(iVar1, indexvec[iSample][iOscChan][iSyst][iMode].size(),
"Var1");
796 if (isValid) checkIndex(iVar2, indexvec[iSample][iOscChan][iSyst][iMode][iVar1].size(),
"Var2");
797 if (isValid) checkIndex(iVar3, indexvec[iSample][iOscChan][iSyst][iMode][iVar1][iVar2].size(),
"Var3");
819 const int NBins = Axis->GetNbins();
820 std::string text =
"";
821 for (
int iBin = 0; iBin <= NBins; iBin++) {
822 text += fmt::format(
"{} ", Axis->GetXbins()->GetAt(iBin));
830 std::vector<std::vector<int>> ReturnVec;
832 int nSplineSysts =
static_cast<int>(
indexvec[SampleIndex][iOscChan].size());
846 std::vector<int> bins;
847 std::vector<double> vars = {Var1Val, Var2Val, Var3Val};
848 for (
size_t i = 0; i < vars.size(); ++i) {
849 int bin =
SplineBinning[SampleIndex][iOscChan][i]->FindBin(vars[i]) - 1;
850 if (bin < 0 || bin >=
SplineBinning[SampleIndex][iOscChan][i]->GetNbins()) {
855 int Var1Bin = bins[0];
int Var2Bin = bins[1];
int Var3Bin = bins[2];
857 for(
int iSyst=0; iSyst<nSplineSysts; iSyst++){
858 std::vector<int> spline_modes =
SplineModeVecs[SampleIndex][iSyst];
859 int nSampleModes =
static_cast<int>(spline_modes.size());
862 for(
int iMode = 0; iMode<nSampleModes; iMode++){
864 if (Mode == spline_modes[iMode]) {
865 int splineID=
indexvec[SampleIndex][iOscChan][iSyst][iMode][Var1Bin][Var2Bin][Var3Bin];
868 ReturnVec.push_back({SampleIndex, iOscChan, iSyst, iMode, Var1Bin, Var2Bin, Var3Bin});
883 size_t InputVectorSize = InputVector.size();
884 std::vector< std::vector<int> > ReturnVec(InputVectorSize);
887 for (
size_t iSyst=0;iSyst<InputVectorSize;iSyst++) {
888 std::vector<int> TmpVec;
889 std::vector<std::string> TestVec;
892 for (
unsigned int iMode = 0 ; iMode < InputVector[iSyst].size() ; iMode++) {
893 int Mode = InputVector[iSyst][iMode];
896 bool IncludeMode =
true;
897 for (
auto TestString : TestVec) {
898 if (ModeName == TestString) {
905 TmpVec.push_back(Mode);
906 TestVec.push_back(ModeName);
910 ReturnVec[iSyst] = TmpVec;
920 for (
int iOscChan = 0; iOscChan < nOscChannels; iOscChan++) {
922 TSpline3* mySpline =
nullptr;
925 int nKnots, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin =
M3::_BAD_INT_;
929 std::set<std::string> SplineFileNames;
931 auto File = std::unique_ptr<TFile>(
TFile::Open(OscChanFileNames[iOscChan].c_str()));
933 if (!File || File->IsZombie()) {
940 for (
auto k : *File->GetListOfKeys()) {
941 auto Key =
static_cast<TKey*
>(k);
942 TClass *Class = gROOT->GetClass(Key->GetClassName(),
false);
943 if(!Class->InheritsFrom(
"TSpline3")) {
947 std::string FullSplineName = std::string(Key->GetName());
949 if (SplineFileNames.count(FullSplineName) > 0) {
950 MACH3LOG_CRITICAL(
"Skipping spline - Found a spline whose name has already been encountered before: {}", FullSplineName);
953 SplineFileNames.insert(FullSplineName);
958 MACH3LOG_ERROR(
"Invalid tokens from spline name - Expected {} tokens. Check implementation in GetTokensFromSplineName()",
static_cast<int>(
kNTokens));
979 MACH3LOG_DEBUG(
"Couldn't Match any systematic name in ParameterHandler with spline name: {}" , FullSplineName);
984 for (
unsigned int iMode = 0; iMode <
SplineModeVecs[iSample][SystNum].size(); iMode++) {
994 MACH3LOG_DEBUG(
"Couldn't find mode for {} in {}. Problem Spline is : {} ", Mode, Syst, FullSplineName);
998 mySpline = Key->ReadObject<TSpline3>();
1000 if (
isValidSplineIndex(SampleTitle, iOscChan, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin)) {
1001 MACH3LOG_TRACE(
"Pushed back monolith for spline {}", FullSplineName);
1003 nKnots = mySpline->GetNp();
1005 for (
int iKnot = 0; iKnot < nKnots; iKnot++) {
1006 mySpline->GetKnot(iKnot, x, y);
1007 if (y < 0.99999 || y > 1.00001)
1024 if(mySpline)
delete mySpline;
1051 size_t pos = FileName.find(
' ');
1052 if (pos != std::string::npos) {
1053 MACH3LOG_WARN(
"Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1054 while ((pos = FileName.find(
' ')) != std::string::npos) {
1055 FileName[pos] =
'_';
1058 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"OPEN");
1060 TMacro *ConfigCov = SplineFile->Get<TMacro>(
"ParameterHandler");
1068 MACH3LOG_ERROR(
"Loading precomputed spline file, however encountered different YAML config, please regenerate input");
1077 for (
int iSpline = 0; iSpline <
nParams; iSpline++) {
1080 SplineFile->Close();
1087 TTree *Settings = SplineFile->Get<TTree>(
"Settings");
1088 int CoeffIndex_temp, MonolithSize_temp;
1089 short int nParams_temp;
1090 Settings->SetBranchAddress(
"CoeffIndex", &CoeffIndex_temp);
1091 Settings->SetBranchAddress(
"MonolithSize", &MonolithSize_temp);
1092 Settings->SetBranchAddress(
"nParams", &nParams_temp);
1093 int indexvec_sizes[7];
1094 for (
int i = 0; i < 7; ++i) {
1095 Settings->SetBranchAddress((
"indexvec_size" + std::to_string(i+1)).c_str(), &indexvec_sizes[i]);
1098 int SplineBinning_size1, SplineBinning_size2, SplineBinning_size3;
1099 Settings->SetBranchAddress(
"SplineBinning_size1", &SplineBinning_size1);
1100 Settings->SetBranchAddress(
"SplineBinning_size2", &SplineBinning_size2);
1101 Settings->SetBranchAddress(
"SplineBinning_size3", &SplineBinning_size3);
1102 int SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3;
1103 Settings->SetBranchAddress(
"SplineModeVecs_size1", &SplineModeVecs_size1);
1104 Settings->SetBranchAddress(
"SplineModeVecs_size2", &SplineModeVecs_size2);
1105 Settings->SetBranchAddress(
"SplineModeVecs_size3", &SplineModeVecs_size3);
1106 std::vector<std::string>* SampleNames_temp =
nullptr;
1107 Settings->SetBranchAddress(
"SampleNames", &SampleNames_temp);
1108 std::vector<std::string>* SampleTitles_temp =
nullptr;
1109 Settings->SetBranchAddress(
"SampleTitles", &SampleTitles_temp);
1110 Settings->GetEntry(0);
1123 indexvec.resize(indexvec_sizes[0]);
1124 for (
int i = 0; i < indexvec_sizes[0]; ++i) {
1125 indexvec[i].resize(indexvec_sizes[1]);
1126 for (
int j = 0; j < indexvec_sizes[1]; ++j) {
1127 indexvec[i][j].resize(indexvec_sizes[2]);
1128 for (
int k = 0; k < indexvec_sizes[2]; ++k) {
1129 indexvec[i][j][k].resize(indexvec_sizes[3]);
1130 for (
int l = 0; l < indexvec_sizes[3]; ++l) {
1131 indexvec[i][j][k][l].resize(indexvec_sizes[4]);
1132 for (
int m = 0; m < indexvec_sizes[4]; ++m) {
1133 indexvec[i][j][k][l][m].resize(indexvec_sizes[5]);
1134 for (
int n = 0; n < indexvec_sizes[5]; ++n) {
1135 indexvec[i][j][k][l][m][n].resize(indexvec_sizes[6]);
1143 auto Resize3D = [](
auto& vec,
int d1,
int d2,
int d3) {
1145 for (
int i = 0; i < d1; ++i) {
1147 for (
int j = 0; j < d2; ++j) {
1148 vec[i][j].resize(d3);
1153 Resize3D(
SplineBinning, SplineBinning_size1, SplineBinning_size2, SplineBinning_size3);
1154 Resize3D(
SplineModeVecs, SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3);
1161 TTree *MonolithTree = SplineFile->Get<TTree>(
"MonolithTree");
1167 MonolithTree->SetBranchAddress(
"isflatarray",
isflatarray);
1170 std::vector<int>* coeffindexvec_temp =
nullptr;
1171 MonolithTree->SetBranchAddress(
"coeffindexvec", &coeffindexvec_temp);
1172 std::vector<int>* uniquecoeffindices_temp =
nullptr;
1173 MonolithTree->SetBranchAddress(
"uniquecoeffindices", &uniquecoeffindices_temp);
1174 std::vector<int>* uniquesplinevec_Monolith_temp =
nullptr;
1175 MonolithTree->SetBranchAddress(
"uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1176 std::vector<int>* UniqueSystIndices_temp =
nullptr;
1177 MonolithTree->SetBranchAddress(
"UniqueSystIndices", &UniqueSystIndices_temp);
1181 MonolithTree->SetBranchAddress(
"xcoeff",
xcoeff_arr);
1183 MonolithTree->GetEntry(0);
1195 TTree *IndexTree = SplineFile->Get<TTree>(
"IndexVec");
1197 std::vector<int> Dim(7);
1199 for (
int d = 0; d < 7; ++d) {
1200 IndexTree->SetBranchAddress(Form(
"dim%d", d+1), &Dim[d]);
1202 IndexTree->SetBranchAddress(
"value", &value);
1205 for (Long64_t i = 0; i < IndexTree->GetEntries(); ++i) {
1206 IndexTree->GetEntry(i);
1207 indexvec[Dim[0]][Dim[1]][Dim[2]][Dim[3]][Dim[4]][Dim[5]][Dim[6]] = value;
1211 TTree *SplineBinningTree = SplineFile->Get<TTree>(
"SplineBinningTree");
1212 std::vector<int> indices(3);
1213 SplineBinningTree->SetBranchAddress(
"i", &indices[0]);
1214 SplineBinningTree->SetBranchAddress(
"j", &indices[1]);
1215 SplineBinningTree->SetBranchAddress(
"k", &indices[2]);
1216 TAxis* axis =
nullptr;
1217 SplineBinningTree->SetBranchAddress(
"axis", &axis);
1220 for (Long64_t entry = 0; entry < SplineBinningTree->GetEntries(); ++entry) {
1221 SplineBinningTree->GetEntry(entry);
1225 SplineBinning[i][j][k] =
static_cast<TAxis*
>(axis->Clone());
1228 std::vector<int> indices_mode(3);
1230 TTree *SplineModeTree = SplineFile->Get<TTree>(
"SplineModeTree");
1231 SplineModeTree->SetBranchAddress(
"i", &indices_mode[0]);
1232 SplineModeTree->SetBranchAddress(
"j", &indices_mode[1]);
1233 SplineModeTree->SetBranchAddress(
"k", &indices_mode[2]);
1234 SplineModeTree->SetBranchAddress(
"value", &mode_value);
1237 for (Long64_t entry = 0; entry < SplineModeTree->GetEntries(); ++entry) {
1238 SplineModeTree->GetEntry(entry);
1239 int i = indices_mode[0];
1240 int j = indices_mode[1];
1241 int k = indices_mode[2];
1252 size_t pos = FileName.find(
' ');
1253 if (pos != std::string::npos) {
1254 MACH3LOG_WARN(
"Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1255 while ((pos = FileName.find(
' ')) != std::string::npos) {
1256 FileName[pos] =
'_';
1260 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"recreate");
1262 TMacro ConfigSave =
YAMLtoTMacro(ConfigCurrent,
"ParameterHandler");
1271 SplineFile->Close();
1277 TTree *Settings =
new TTree(
"Settings",
"Settings");
1280 short int nParams_temp =
nParams;
1282 Settings->Branch(
"CoeffIndex", &CoeffIndex_temp,
"CoeffIndex/I");
1283 Settings->Branch(
"MonolithSize", &MonolithSize_temp,
"MonolithSize/I");
1284 Settings->Branch(
"nParams", &nParams_temp,
"nParams/S");
1286 int indexvec_sizes[7];
1287 indexvec_sizes[0] =
static_cast<int>(
indexvec.size());
1288 indexvec_sizes[1] = (indexvec_sizes[0] > 0) ?
static_cast<int>(
indexvec[0].size()) : 0;
1289 indexvec_sizes[2] = (indexvec_sizes[1] > 0) ?
static_cast<int>(
indexvec[0][0].size()) : 0;
1290 indexvec_sizes[3] = (indexvec_sizes[2] > 0) ?
static_cast<int>(
indexvec[0][0][0].size()) : 0;
1291 indexvec_sizes[4] = (indexvec_sizes[3] > 0) ?
static_cast<int>(
indexvec[0][0][0][0].size()) : 0;
1292 indexvec_sizes[5] = (indexvec_sizes[4] > 0) ?
static_cast<int>(
indexvec[0][0][0][0][0].size()) : 0;
1293 indexvec_sizes[6] = (indexvec_sizes[5] > 0) ?
static_cast<int>(
indexvec[0][0][0][0][0][0].size()) : 0;
1295 for (
int i = 0; i < 7; ++i) {
1296 Settings->Branch((
"indexvec_size" + std::to_string(i+1)).c_str(),
1297 &indexvec_sizes[i], (
"indexvec_size" + std::to_string(i+1) +
"/I").c_str());
1300 int SplineBinning_size1 =
static_cast<int>(
SplineBinning.size());
1301 int SplineBinning_size2 = (SplineBinning_size1 > 0) ?
static_cast<int>(
SplineBinning[0].size()) : 0;
1302 int SplineBinning_size3 = (SplineBinning_size2 > 0) ?
static_cast<int>(
SplineBinning[0][0].size()) : 0;
1304 Settings->Branch(
"SplineBinning_size1", &SplineBinning_size1,
"SplineBinning_size1/I");
1305 Settings->Branch(
"SplineBinning_size2", &SplineBinning_size2,
"SplineBinning_size2/I");
1306 Settings->Branch(
"SplineBinning_size3", &SplineBinning_size3,
"SplineBinning_size3/I");
1308 int SplineModeVecs_size1 =
static_cast<int>(
SplineModeVecs.size());
1309 int SplineModeVecs_size2 = (SplineModeVecs_size1 > 0) ?
static_cast<int>(
SplineModeVecs[0].size()) : 0;
1310 int SplineModeVecs_size3 = (SplineModeVecs_size2 > 0) ?
static_cast<int>(
SplineModeVecs[0][0].size()) : 0;
1312 Settings->Branch(
"SplineModeVecs_size1", &SplineModeVecs_size1,
"SplineModeVecs_size1/I");
1313 Settings->Branch(
"SplineModeVecs_size2", &SplineModeVecs_size2,
"SplineModeVecs_size2/I");
1314 Settings->Branch(
"SplineModeVecs_size3", &SplineModeVecs_size3,
"SplineModeVecs_size3/I");
1316 std::vector<std::string> SampleNames_temp =
SampleNames;
1317 Settings->Branch(
"SampleNames", &SampleNames_temp);
1318 std::vector<std::string> SampleTitles_temp =
SampleTitles;
1319 Settings->Branch(
"SampleTitles", &SampleTitles_temp);
1330 TTree *MonolithTree =
new TTree(
"MonolithTree",
"MonolithTree");
1335 MonolithTree->Branch(
"coeffindexvec", &coeffindexvec_temp);
1337 MonolithTree->Branch(
"uniquecoeffindices", &uniquecoeffindices_temp);
1339 MonolithTree->Branch(
"uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1341 MonolithTree->Branch(
"UniqueSystIndices", &UniqueSystIndices_temp);
1344 MonolithTree->Fill();
1346 MonolithTree->Write();
1347 delete MonolithTree;
1354 TTree *IndexTree =
new TTree(
"IndexVec",
"IndexVec");
1357 std::vector<int> Dim(7);
1361 for (
int d = 0; d < 7; ++d) {
1362 IndexTree->Branch(Form(
"dim%d", d+1), &Dim[d], Form(
"dim%d/I", d+1));
1364 IndexTree->Branch(
"value", &value,
"value/I");
1367 for (
size_t i = 0; i <
indexvec.size(); ++i) {
1368 for (
size_t j = 0; j <
indexvec[i].size(); ++j) {
1369 for (
size_t k = 0; k <
indexvec[i][j].size(); ++k) {
1370 for (
size_t l = 0; l <
indexvec[i][j][k].size(); ++l) {
1371 for (
size_t m = 0; m <
indexvec[i][j][k][l].size(); ++m) {
1372 for (
size_t n = 0; n <
indexvec[i][j][k][l][m].size(); ++n) {
1373 for (
size_t p = 0; p <
indexvec[i][j][k][l][m][n].size(); ++p) {
1374 Dim[0] =
static_cast<int>(i);
1375 Dim[1] =
static_cast<int>(j);
1376 Dim[2] =
static_cast<int>(k);
1377 Dim[3] =
static_cast<int>(l);
1378 Dim[4] =
static_cast<int>(m);
1379 Dim[5] =
static_cast<int>(n);
1380 Dim[6] =
static_cast<int>(p);
1381 value =
static_cast<int>(
indexvec[i][j][k][l][m][n][p]);
1401 TTree *SplineBinningTree =
new TTree(
"SplineBinningTree",
"SplineBinningTree");
1402 std::vector<int> indices(3);
1403 TAxis* axis =
nullptr;
1404 SplineBinningTree->Branch(
"i", &indices[0],
"i/I");
1405 SplineBinningTree->Branch(
"j", &indices[1],
"j/I");
1406 SplineBinningTree->Branch(
"k", &indices[2],
"k/I");
1407 SplineBinningTree->Branch(
"axis",
"TAxis", &axis);
1414 indices[0] =
static_cast<int>(i);
1415 indices[1] =
static_cast<int>(j);
1416 indices[2] =
static_cast<int>(k);
1417 SplineBinningTree->Fill();
1422 SplineBinningTree->Write();
1423 delete SplineBinningTree;
1425 std::vector<int> indices_mode(3);
1428 TTree *SplineModeTree =
new TTree(
"SplineModeTree",
"SplineModeTree");
1430 SplineModeTree->Branch(
"i", &indices_mode[0],
"i/I");
1431 SplineModeTree->Branch(
"j", &indices_mode[1],
"j/I");
1432 SplineModeTree->Branch(
"k", &indices_mode[2],
"k/I");
1433 SplineModeTree->Branch(
"value", &mode_value,
"value/I");
1439 indices_mode[0] =
static_cast<int>(i);
1440 indices_mode[1] =
static_cast<int>(j);
1441 indices_mode[2] =
static_cast<int>(k);
1443 SplineModeTree->Fill();
1449 SplineModeTree->Write();
1450 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)
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::string getDimLabel(const int BinningOpt, const unsigned int Axis) const
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.
ParameterHandlerGeneric * ParHandler
Pointer to covariance from which we get information about spline params.
void CalcSplineWeights() final
CPU based code which eval weight for each spline.
std::vector< std::vector< std::string > > SplineFileParPrefixNames
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.
bool isValidSplineIndex(const std::string &SampleTitle, int iSyst, int iOscChan, int iMode, int iVar1, int iVar2, int iVar3) const
Ensure we have spline for a given bin.
void PrintBinning(TAxis *Axis) const
void PrepareSplineFile(std::string FileName) final
KS: Prepare spline file that can be used for fast loading.
void InvestigateMissingSplines() const
This function will find missing splines in file.
std::vector< int > nSplineParams
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 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.
void Evaluate() final
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 > 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< 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
std::vector< std::vector< int > > StripDuplicatedModes(const std::vector< std::vector< int > > &InputVector) const
Check if there are any repeated modes. This is used to reduce the number of modes in case many intera...
void LoadSplineFile(std::string FileName) final
KS: Load preprocessed spline file.
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
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.
virtual std::vector< std::string > GetTokensFromSplineName(const std::string &FullSplineName)=0
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 M3::float_t * 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.