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)) {
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});
895 size_t InputVectorSize = InputVector.size();
896 std::vector< std::vector<int> > ReturnVec(InputVectorSize);
899 for (
size_t iSyst=0;iSyst<InputVectorSize;iSyst++) {
900 std::vector<int> TmpVec;
901 std::vector<std::string> TestVec;
904 for (
unsigned int iMode = 0 ; iMode < InputVector[iSyst].size() ; iMode++) {
905 int Mode = InputVector[iSyst][iMode];
908 bool IncludeMode =
true;
909 for (
auto TestString : TestVec) {
910 if (ModeName == TestString) {
917 TmpVec.push_back(Mode);
918 TestVec.push_back(ModeName);
922 ReturnVec[iSyst] = TmpVec;
932 for (
int iOscChan = 0; iOscChan < nOscChannels; iOscChan++) {
934 TSpline3* mySpline =
nullptr;
937 int nKnots, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin =
M3::_BAD_INT_;
941 std::set<std::string> SplineFileNames;
943 auto File = std::unique_ptr<TFile>(
TFile::Open(OscChanFileNames[iOscChan].c_str()));
945 if (!File || File->IsZombie()) {
952 for (
auto k : *File->GetListOfKeys()) {
953 auto Key =
static_cast<TKey*
>(k);
954 TClass *Class = gROOT->GetClass(Key->GetClassName(),
false);
955 if(!Class->InheritsFrom(
"TSpline3")) {
959 std::string FullSplineName = std::string(Key->GetName());
961 if (SplineFileNames.count(FullSplineName) > 0) {
962 MACH3LOG_CRITICAL(
"Skipping spline - Found a spline whose name has already been encountered before: {}", FullSplineName);
965 SplineFileNames.insert(FullSplineName);
970 MACH3LOG_ERROR(
"Invalid tokens from spline name - Expected {} tokens. Check implementation in GetTokensFromSplineName()",
static_cast<int>(
kNTokens));
991 MACH3LOG_DEBUG(
"Couldn't Match any systematic name in ParameterHandler with spline name: {}" , FullSplineName);
996 for (
unsigned int iMode = 0; iMode <
SplineModeVecs[iSample][SystNum].size(); iMode++) {
1003 if (ModeNum == -1) {
1006 MACH3LOG_DEBUG(
"Couldn't find mode for {} in {}. Problem Spline is : {} ", Mode, Syst, FullSplineName);
1010 mySpline = Key->ReadObject<TSpline3>();
1012 if (
isValidSplineIndex(SampleTitle, iOscChan, SystNum, ModeNum, Var1Bin, Var2Bin, Var3Bin)) {
1013 MACH3LOG_DEBUG(
"Pushed back monolith for spline {}", FullSplineName);
1015 nKnots = mySpline->GetNp();
1017 for (
int iKnot = 0; iKnot < nKnots; iKnot++) {
1018 mySpline->GetKnot(iKnot, x, y);
1019 if (y < 0.99999 || y > 1.00001)
1036 if(mySpline)
delete mySpline;
1063 size_t pos = FileName.find(
' ');
1064 if (pos != std::string::npos) {
1065 MACH3LOG_WARN(
"Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1066 while ((pos = FileName.find(
' ')) != std::string::npos) {
1067 FileName[pos] =
'_';
1070 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"OPEN");
1076 for (
int iSpline = 0; iSpline <
nParams; iSpline++) {
1079 SplineFile->Close();
1086 TTree *Settings = SplineFile->Get<TTree>(
"Settings");
1087 int CoeffIndex_temp, MonolithSize_temp;
1088 short int nParams_temp;
1089 Settings->SetBranchAddress(
"CoeffIndex", &CoeffIndex_temp);
1090 Settings->SetBranchAddress(
"MonolithSize", &MonolithSize_temp);
1091 Settings->SetBranchAddress(
"nParams", &nParams_temp);
1092 int indexvec_sizes[7];
1093 for (
int i = 0; i < 7; ++i) {
1094 Settings->SetBranchAddress((
"indexvec_size" + std::to_string(i+1)).c_str(), &indexvec_sizes[i]);
1097 int SplineBinning_size1, SplineBinning_size2, SplineBinning_size3;
1098 Settings->SetBranchAddress(
"SplineBinning_size1", &SplineBinning_size1);
1099 Settings->SetBranchAddress(
"SplineBinning_size2", &SplineBinning_size2);
1100 Settings->SetBranchAddress(
"SplineBinning_size3", &SplineBinning_size3);
1101 int SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3;
1102 Settings->SetBranchAddress(
"SplineModeVecs_size1", &SplineModeVecs_size1);
1103 Settings->SetBranchAddress(
"SplineModeVecs_size2", &SplineModeVecs_size2);
1104 Settings->SetBranchAddress(
"SplineModeVecs_size3", &SplineModeVecs_size3);
1105 std::vector<std::string>* SampleNames_temp =
nullptr;
1106 Settings->SetBranchAddress(
"SampleNames", &SampleNames_temp);
1107 std::vector<std::string>* SampleTitles_temp =
nullptr;
1108 Settings->SetBranchAddress(
"SampleTitles", &SampleTitles_temp);
1109 Settings->GetEntry(0);
1122 indexvec.resize(indexvec_sizes[0]);
1123 for (
int i = 0; i < indexvec_sizes[0]; ++i) {
1124 indexvec[i].resize(indexvec_sizes[1]);
1125 for (
int j = 0; j < indexvec_sizes[1]; ++j) {
1126 indexvec[i][j].resize(indexvec_sizes[2]);
1127 for (
int k = 0; k < indexvec_sizes[2]; ++k) {
1128 indexvec[i][j][k].resize(indexvec_sizes[3]);
1129 for (
int l = 0; l < indexvec_sizes[3]; ++l) {
1130 indexvec[i][j][k][l].resize(indexvec_sizes[4]);
1131 for (
int m = 0; m < indexvec_sizes[4]; ++m) {
1132 indexvec[i][j][k][l][m].resize(indexvec_sizes[5]);
1133 for (
int n = 0; n < indexvec_sizes[5]; ++n) {
1134 indexvec[i][j][k][l][m][n].resize(indexvec_sizes[6]);
1142 auto Resize3D = [](
auto& vec,
int d1,
int d2,
int d3) {
1144 for (
int i = 0; i < d1; ++i) {
1146 for (
int j = 0; j < d2; ++j) {
1147 vec[i][j].resize(d3);
1152 Resize3D(
SplineBinning, SplineBinning_size1, SplineBinning_size2, SplineBinning_size3);
1153 Resize3D(
SplineModeVecs, SplineModeVecs_size1, SplineModeVecs_size2, SplineModeVecs_size3);
1160 TTree *MonolithTree = SplineFile->Get<TTree>(
"MonolithTree");
1166 MonolithTree->SetBranchAddress(
"isflatarray",
isflatarray);
1169 std::vector<int>* coeffindexvec_temp =
nullptr;
1170 MonolithTree->SetBranchAddress(
"coeffindexvec", &coeffindexvec_temp);
1171 std::vector<int>* uniquecoeffindices_temp =
nullptr;
1172 MonolithTree->SetBranchAddress(
"uniquecoeffindices", &uniquecoeffindices_temp);
1173 std::vector<int>* uniquesplinevec_Monolith_temp =
nullptr;
1174 MonolithTree->SetBranchAddress(
"uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1175 std::vector<int>* UniqueSystIndices_temp =
nullptr;
1176 MonolithTree->SetBranchAddress(
"UniqueSystIndices", &UniqueSystIndices_temp);
1180 MonolithTree->SetBranchAddress(
"xcoeff",
xcoeff_arr);
1182 MonolithTree->GetEntry(0);
1194 TTree *IndexTree = SplineFile->Get<TTree>(
"IndexVec");
1196 std::vector<int> Dim(7);
1198 for (
int d = 0; d < 7; ++d) {
1199 IndexTree->SetBranchAddress(Form(
"dim%d", d+1), &Dim[d]);
1201 IndexTree->SetBranchAddress(
"value", &value);
1204 for (Long64_t i = 0; i < IndexTree->GetEntries(); ++i) {
1205 IndexTree->GetEntry(i);
1206 indexvec[Dim[0]][Dim[1]][Dim[2]][Dim[3]][Dim[4]][Dim[5]][Dim[6]] = value;
1210 TTree *SplineBinningTree = SplineFile->Get<TTree>(
"SplineBinningTree");
1211 std::vector<int> indices(3);
1212 SplineBinningTree->SetBranchAddress(
"i", &indices[0]);
1213 SplineBinningTree->SetBranchAddress(
"j", &indices[1]);
1214 SplineBinningTree->SetBranchAddress(
"k", &indices[2]);
1215 TAxis* axis =
nullptr;
1216 SplineBinningTree->SetBranchAddress(
"axis", &axis);
1219 for (Long64_t entry = 0; entry < SplineBinningTree->GetEntries(); ++entry) {
1220 SplineBinningTree->GetEntry(entry);
1224 SplineBinning[i][j][k] =
static_cast<TAxis*
>(axis->Clone());
1227 std::vector<int> indices_mode(3);
1229 TTree *SplineModeTree = SplineFile->Get<TTree>(
"SplineModeTree");
1230 SplineModeTree->SetBranchAddress(
"i", &indices_mode[0]);
1231 SplineModeTree->SetBranchAddress(
"j", &indices_mode[1]);
1232 SplineModeTree->SetBranchAddress(
"k", &indices_mode[2]);
1233 SplineModeTree->SetBranchAddress(
"value", &mode_value);
1236 for (Long64_t entry = 0; entry < SplineModeTree->GetEntries(); ++entry) {
1237 SplineModeTree->GetEntry(entry);
1238 int i = indices_mode[0];
1239 int j = indices_mode[1];
1240 int k = indices_mode[2];
1251 size_t pos = FileName.find(
' ');
1252 if (pos != std::string::npos) {
1253 MACH3LOG_WARN(
"Filename ({}) contains spaces. Replacing spaces with underscores.", FileName);
1254 while ((pos = FileName.find(
' ')) != std::string::npos) {
1255 FileName[pos] =
'_';
1259 auto SplineFile = std::make_unique<TFile>(FileName.c_str(),
"recreate");
1266 SplineFile->Close();
1272 TTree *Settings =
new TTree(
"Settings",
"Settings");
1275 short int nParams_temp =
nParams;
1277 Settings->Branch(
"CoeffIndex", &CoeffIndex_temp,
"CoeffIndex/I");
1278 Settings->Branch(
"MonolithSize", &MonolithSize_temp,
"MonolithSize/I");
1279 Settings->Branch(
"nParams", &nParams_temp,
"nParams/S");
1281 int indexvec_sizes[7];
1282 indexvec_sizes[0] =
static_cast<int>(
indexvec.size());
1283 indexvec_sizes[1] = (indexvec_sizes[0] > 0) ?
static_cast<int>(
indexvec[0].
size()) : 0;
1284 indexvec_sizes[2] = (indexvec_sizes[1] > 0) ?
static_cast<int>(
indexvec[0][0].
size()) : 0;
1285 indexvec_sizes[3] = (indexvec_sizes[2] > 0) ?
static_cast<int>(
indexvec[0][0][0].
size()) : 0;
1286 indexvec_sizes[4] = (indexvec_sizes[3] > 0) ?
static_cast<int>(
indexvec[0][0][0][0].
size()) : 0;
1287 indexvec_sizes[5] = (indexvec_sizes[4] > 0) ?
static_cast<int>(
indexvec[0][0][0][0][0].
size()) : 0;
1288 indexvec_sizes[6] = (indexvec_sizes[5] > 0) ?
static_cast<int>(
indexvec[0][0][0][0][0][0].
size()) : 0;
1290 for (
int i = 0; i < 7; ++i) {
1291 Settings->Branch((
"indexvec_size" + std::to_string(i+1)).c_str(),
1292 &indexvec_sizes[i], (
"indexvec_size" + std::to_string(i+1) +
"/I").c_str());
1295 int SplineBinning_size1 =
static_cast<int>(
SplineBinning.size());
1296 int SplineBinning_size2 = (SplineBinning_size1 > 0) ?
static_cast<int>(
SplineBinning[0].
size()) : 0;
1297 int SplineBinning_size3 = (SplineBinning_size2 > 0) ?
static_cast<int>(
SplineBinning[0][0].
size()) : 0;
1299 Settings->Branch(
"SplineBinning_size1", &SplineBinning_size1,
"SplineBinning_size1/I");
1300 Settings->Branch(
"SplineBinning_size2", &SplineBinning_size2,
"SplineBinning_size2/I");
1301 Settings->Branch(
"SplineBinning_size3", &SplineBinning_size3,
"SplineBinning_size3/I");
1303 int SplineModeVecs_size1 =
static_cast<int>(
SplineModeVecs.size());
1304 int SplineModeVecs_size2 = (SplineModeVecs_size1 > 0) ?
static_cast<int>(
SplineModeVecs[0].
size()) : 0;
1305 int SplineModeVecs_size3 = (SplineModeVecs_size2 > 0) ?
static_cast<int>(
SplineModeVecs[0][0].
size()) : 0;
1307 Settings->Branch(
"SplineModeVecs_size1", &SplineModeVecs_size1,
"SplineModeVecs_size1/I");
1308 Settings->Branch(
"SplineModeVecs_size2", &SplineModeVecs_size2,
"SplineModeVecs_size2/I");
1309 Settings->Branch(
"SplineModeVecs_size3", &SplineModeVecs_size3,
"SplineModeVecs_size3/I");
1311 std::vector<std::string> SampleNames_temp =
SampleNames;
1312 Settings->Branch(
"SampleNames", &SampleNames_temp);
1313 std::vector<std::string> SampleTitles_temp =
SampleTitles;
1314 Settings->Branch(
"SampleTitles", &SampleTitles_temp);
1325 TTree *MonolithTree =
new TTree(
"MonolithTree",
"MonolithTree");
1330 MonolithTree->Branch(
"coeffindexvec", &coeffindexvec_temp);
1332 MonolithTree->Branch(
"uniquecoeffindices", &uniquecoeffindices_temp);
1334 MonolithTree->Branch(
"uniquesplinevec_Monolith", &uniquesplinevec_Monolith_temp);
1336 MonolithTree->Branch(
"UniqueSystIndices", &UniqueSystIndices_temp);
1339 MonolithTree->Fill();
1341 MonolithTree->Write();
1342 delete MonolithTree;
1349 TTree *IndexTree =
new TTree(
"IndexVec",
"IndexVec");
1352 std::vector<int> Dim(7);
1356 for (
int d = 0; d < 7; ++d) {
1357 IndexTree->Branch(Form(
"dim%d", d+1), &Dim[d], Form(
"dim%d/I", d+1));
1359 IndexTree->Branch(
"value", &value,
"value/I");
1362 for (
size_t i = 0; i <
indexvec.size(); ++i) {
1363 for (
size_t j = 0; j <
indexvec[i].size(); ++j) {
1364 for (
size_t k = 0; k <
indexvec[i][j].size(); ++k) {
1365 for (
size_t l = 0; l <
indexvec[i][j][k].size(); ++l) {
1366 for (
size_t m = 0; m <
indexvec[i][j][k][l].size(); ++m) {
1367 for (
size_t n = 0; n <
indexvec[i][j][k][l][m].size(); ++n) {
1368 for (
size_t p = 0; p <
indexvec[i][j][k][l][m][n].size(); ++p) {
1369 Dim[0] =
static_cast<int>(i);
1370 Dim[1] =
static_cast<int>(j);
1371 Dim[2] =
static_cast<int>(k);
1372 Dim[3] =
static_cast<int>(l);
1373 Dim[4] =
static_cast<int>(m);
1374 Dim[5] =
static_cast<int>(n);
1375 Dim[6] =
static_cast<int>(p);
1376 value =
static_cast<int>(
indexvec[i][j][k][l][m][n][p]);
1396 TTree *SplineBinningTree =
new TTree(
"SplineBinningTree",
"SplineBinningTree");
1397 std::vector<int> indices(3);
1398 TAxis* axis =
nullptr;
1399 SplineBinningTree->Branch(
"i", &indices[0],
"i/I");
1400 SplineBinningTree->Branch(
"j", &indices[1],
"j/I");
1401 SplineBinningTree->Branch(
"k", &indices[2],
"k/I");
1402 SplineBinningTree->Branch(
"axis",
"TAxis", &axis);
1409 indices[0] =
static_cast<int>(i);
1410 indices[1] =
static_cast<int>(j);
1411 indices[2] =
static_cast<int>(k);
1412 SplineBinningTree->Fill();
1417 SplineBinningTree->Write();
1418 delete SplineBinningTree;
1420 std::vector<int> indices_mode(3);
1423 TTree *SplineModeTree =
new TTree(
"SplineModeTree",
"SplineModeTree");
1425 SplineModeTree->Branch(
"i", &indices_mode[0],
"i/I");
1426 SplineModeTree->Branch(
"j", &indices_mode[1],
"j/I");
1427 SplineModeTree->Branch(
"k", &indices_mode[2],
"k/I");
1428 SplineModeTree->Branch(
"value", &mode_value,
"value/I");
1434 indices_mode[0] =
static_cast<int>(i);
1435 indices_mode[1] =
static_cast<int>(j);
1436 indices_mode[2] =
static_cast<int>(k);
1438 SplineModeTree->Fill();
1444 SplineModeTree->Write();
1445 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.
std::vector< bool > isFlat
#define MACH3LOG_CRITICAL
void CleanVector(std::vector< T > &vec)
Generic cleanup function.
void CleanContainer(std::vector< T * > &container)
Generic cleanup function.
@ 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...
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 for MaCh3 errors.
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.
Class responsible for handling of systematic error parameters with different types defined in the con...
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.
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.
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.