11 const std::shared_ptr<OscillationHandler>& OscillatorObj_) :
SampleHandlerBase() {
13 MACH3LOG_INFO(
"-------------------------------------------------------------------");
18 MACH3LOG_ERROR(
"You've passed me a nullptr to a SystematicHandlerGeneric... I need this to setup splines!");
25 if (OscillatorObj_ !=
nullptr) {
26 MACH3LOG_WARN(
"You have passed an Oscillator object through the constructor of a SampleHandlerFD object - this will be used for all oscillation channels");
75 auto ModeName = Get<std::string>(
SampleManager->raw()[
"MaCh3ModeConfig"], __FILE__ , __LINE__);
76 Modes = std::make_unique<MaCh3Modes>(ModeName);
91 if (!std::is_sorted(edgesx.begin(), edgesx.end())) {
92 MACH3LOG_ERROR(
"XVarBins must be in increasing order in sample config {}\n XVarBins: [{}]",
93 GetTitle(), fmt::join(edgesx,
", "));
106 if (!std::is_sorted(edgesy.begin(), edgesy.end())) {
107 MACH3LOG_ERROR(
"YBinEdges must be in increasing order in sample config {}\n YBinEdges: [{}]",
108 GetTitle(), fmt::join(edgesy,
", "));
113 MACH3LOG_ERROR(
"Please specify an X-variable string in sample config {}. I won't work only with a Y-variable",
SampleManager->GetFileName());
122 MACH3LOG_ERROR(
"Check that an XVarStr has been given in the sample config");
130 MACH3LOG_ERROR(
"No binning specified for either X or Y of sample binning, please add some binning to the sample config {}",
SampleManager->GetFileName());
135 MACH3LOG_ERROR(
"BinningFile not given in for sample {}, ReturnKinematicParameterBinning will not work",
GetTitle());
139 auto mtupleprefix = Get<std::string>(
SampleManager->raw()[
"InputFiles"][
"mtupleprefix"], __FILE__, __LINE__);
140 auto mtuplesuffix = Get<std::string>(
SampleManager->raw()[
"InputFiles"][
"mtuplesuffix"], __FILE__, __LINE__);
141 auto splineprefix = Get<std::string>(
SampleManager->raw()[
"InputFiles"][
"splineprefix"], __FILE__, __LINE__);
142 auto splinesuffix = Get<std::string>(
SampleManager->raw()[
"InputFiles"][
"splinesuffix"], __FILE__, __LINE__);
147 for (
auto const &osc_channel :
SampleManager->raw()[
"SubSamples"]) {
148 std::string MTupleFileName = mtupleprefix+osc_channel[
"mtuplefile"].as<std::string>()+mtuplesuffix;
151 OscInfo.
flavourName = osc_channel[
"Name"].as<std::string>();
152 OscInfo.flavourName_Latex = osc_channel[
"LatexName"].as<std::string>();
153 OscInfo.InitPDG =
static_cast<NuPDG>(osc_channel[
"nutype"].as<
int>());
154 OscInfo.FinalPDG =
static_cast<NuPDG>(osc_channel[
"oscnutype"].as<
int>());
155 OscInfo.ChannelIndex =
static_cast<int>(
OscChannels.size());
164 spline_files.push_back(splineprefix+osc_channel[
"splinefile"].as<std::string>()+splinesuffix);
168 for (
auto const &SelectionCuts :
SampleManager->raw()[
"SelectionCuts"]) {
169 auto TempBoundsVec =
GetBounds(SelectionCuts[
"Bounds"]);
174 MACH3LOG_INFO(
"Adding cut on {} with bounds {} to {}", SelectionCuts[
"KinematicStr"].as<std::string>(), TempBoundsVec[0], TempBoundsVec[1]);
179 for(
int iMode=0; iMode <
Modes->GetNModes(); iMode++ ) {
185 for(
int iMode=0; iMode<
Modes->GetNModes(); iMode++ ) {
186 std::string modeStr =
Modes->GetMaCh3ModeName(iMode);
188 double modeWeight =
SampleManager->raw()[
"NominalWeights"][modeStr].as<
double>();
196 for(
int iMode=0; iMode<
Modes->GetNModes(); iMode++ ) {
197 std::string modeStr =
Modes->GetMaCh3ModeName(iMode);
214 MACH3LOG_INFO(
"=============================================");
218 if (OscParams.size() > 0) {
221 MACH3LOG_INFO(
"You have passed an OscillatorBase object through the constructor of a SampleHandlerFD object - this will be used for all oscillation channels");
222 if(
Oscillator->isEqualBinningPerOscChannel() !=
true) {
223 MACH3LOG_ERROR(
"Trying to run shared NuOscillator without EqualBinningPerOscChannel, this will not work");
227 if(OscParams.size() !=
Oscillator->GetOscParamsSize()){
229 OscParams.size(),
Oscillator->GetOscParamsSize());
230 MACH3LOG_ERROR(
"This indicate misconfiguration in your Osc yaml");
238 MACH3LOG_WARN(
"Didn't find any oscillation params, thus will not enable oscillations");
253 MACH3LOG_INFO(
"=======================================================");
260 MACH3LOG_INFO(
"Map KinematicParameters or ReversedKinematicParameters hasn't been initialised");
265 const auto& key = pair.first;
266 const auto& value = pair.second;
310 TString histname1d = (
XVarStr).c_str();
319 _hPDF2D =
new TH2D(
"h" + histname2d +
GetTitle(),histtitle, 1, 0, 1, 1, 0, 1);
328 std::string XBinEdgesStr =
"";
329 std::string YBinEdgesStr =
"";
332 XBinEdgesStr += std::to_string(XBinEdge);
333 XBinEdgesStr +=
", ";
340 YBinEdgesStr += std::to_string(YBinEdge);
341 YBinEdgesStr +=
", ";
356 MACH3LOG_ERROR(
"Number of dimensions is not 1 or 2, this is unsupported at the moment");
364 const int SelectionSize =
static_cast<int>(
Selection.size());
365 for (
int iSelection = 0; iSelection < SelectionSize; ++iSelection) {
368 if ((Val < Cut.LowerBound) || (Val >= Cut.UpperBound)) {
378 for (
unsigned int iSelection=0;iSelection < SubEventCuts.size() ;iSelection++) {
380 if (nsubevents != Vec.size()) {
381 MACH3LOG_ERROR(
"Cannot apply kinematic cut on {} as it is of different size to plotting variable");
384 const double Val = Vec[iSubEvent];
385 if ((Val < SubEventCuts[iSelection].LowerBound) || (Val >= SubEventCuts[iSelection].UpperBound)) {
434 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
444 if (splineweight <= 0.){
455 MCEvent->
xsec_w = splineweight*normweight;
460 if (totalweight <= 0.){
466 const double XVar = *(MCEvent->
x_var);
470 const int YBinToFill = MCEvent->
NomYBin;
473 if (XBinToFill != -1 && YBinToFill != -1) {
483void SampleHandlerFD::FillArray_MP() {
491 double** SampleHandlerFD_array_private =
nullptr;
492 double** SampleHandlerFD_array_private_w2 =
nullptr;
495 #pragma omp parallel private(SampleHandlerFD_array_private, SampleHandlerFD_array_private_w2)
500 SampleHandlerFD_array_private_w2 =
new double*[
Binning.
nYBins];
502 SampleHandlerFD_array_private[yBin] =
new double[
Binning.
nXBins];
503 SampleHandlerFD_array_private_w2[yBin] =
new double[
Binning.
nXBins];
505 std::fill_n(SampleHandlerFD_array_private[yBin],
Binning.
nXBins, 0.0);
506 std::fill_n(SampleHandlerFD_array_private_w2[yBin],
Binning.
nXBins, 0.0);
523 const unsigned int NumberOfEvents =
GetNEvents();
525 for (
unsigned int iEvent = 0; iEvent < NumberOfEvents; ++iEvent) {
542 if (splineweight <= 0.){
552 MCEvent->
xsec_w = splineweight*normweight;
557 if (totalweight <= 0.){
564 const double XVar = (*(MCEvent->
x_var));
568 const int YBinToFill = MCEvent->
NomYBin;
574 if (XBinToFill != -1 && YBinToFill != -1) {
575 SampleHandlerFD_array_private[YBinToFill][XBinToFill] += totalweight;
576 SampleHandlerFD_array_private_w2[YBinToFill][XBinToFill] += totalweight*totalweight;
594 delete[] SampleHandlerFD_array_private[yBin];
595 delete[] SampleHandlerFD_array_private_w2[yBin];
597 delete[] SampleHandlerFD_array_private;
598 delete[] SampleHandlerFD_array_private_w2;
627 MACH3LOG_ERROR(
"Functional parameter {} already in funcParsNamesVec", fpName);
631 MACH3LOG_ERROR(
"Functional parameter enum {} already registered in funcParsFuncMap", fpEnum);
650 if (fp.name == name) {
659 MACH3LOG_ERROR(
"Functional parameter {} not found, did you define it in RegisterFunctionalParameters()?", fp.name);
666 for (std::size_t iEvent = 0; iEvent < static_cast<std::size_t>(
GetNEvents()); ++iEvent) {
668 for (std::vector<FunctionalParameter>::iterator it =
funcParsVec.begin(); it !=
funcParsVec.end(); ++it) {
676 bool IsSelected =
true;
677 if ((*it).hasKinBounds) {
678 const auto& kinVars = (*it).KinematicVarStr;
679 const auto& selection = (*it).Selection;
681 for (std::size_t iKinPar = 0; iKinPar < kinVars.size(); ++iKinPar) {
684 bool passedAnyBound =
false;
685 const auto& boundsList = selection[iKinPar];
687 for (
const auto& bounds : boundsList) {
688 if (kinVal > bounds[0] && kinVal <= bounds[1]) {
689 passedAnyBound =
true;
694 if (!passedAnyBound) {
695 MACH3LOG_TRACE(
"Event {}, missed kinematic check ({}) for dial {}",
696 iEvent, kinVars[iKinPar], (*it).name);
704 MACH3LOG_TRACE(
"Event {}, missed Kinematic var check for dial {}", iEvent, (*it).name);
720 const std::size_t nShifts = fpEnums.size();
722 for (std::size_t i = 0; i < nShifts; ++i) {
723 const int fpEnum = fpEnums[i];
746 for (
int iSpline = 0; iSpline < nSplines; ++iSpline) {
749 return spline_weight;
762 for (
int iParam = 0; iParam < nNorms; ++iParam)
764#pragma GCC diagnostic push
765#pragma GCC diagnostic ignored "-Wuseless-cast"
767#pragma GCC diagnostic pop
769 if (std::isnan(xsecw))
MACH3LOG_WARN(
"iParam= {} xsecweight=nan from norms", iParam);
779 std::vector< std::vector< int > > xsec_norms_bins(
GetNEvents());
793 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); ++iEvent) {
796 MCSamples[iEvent].xsec_norm_pointers.resize(xsec_norms_bins[iEvent].
size());
797 for(
auto const & norm_bin: xsec_norms_bins[iEvent]) {
809 std::vector<int> VerboseCounter(norm_parameters.size(), 0);
811 for(
unsigned int iEvent = 0; iEvent <
GetNEvents(); ++iEvent){
812 std::vector< int > NormBins = {};
822 for (std::vector<NormParameter>::iterator it = norm_parameters.begin(); it != norm_parameters.end(); ++it) {
826 MACH3LOG_TRACE(
"Event {}, missed target check ({}) for dial {}", iEvent, *(
MCSamples[iEvent].Target), (*it).name);
839 if (!FlavourUnoscMatch){
840 MACH3LOG_TRACE(
"Event {}, missed FlavourUnosc check ({}) for dial {}", iEvent,(*
MCSamples[iEvent].nupdgUnosc), (*it).name);
854 bool IsSelected =
true;
855 if ((*it).hasKinBounds) {
856 const auto& kinVars = (*it).KinematicVarStr;
857 const auto& selection = (*it).Selection;
859 for (std::size_t iKinPar = 0; iKinPar < kinVars.size(); ++iKinPar) {
862 bool passedAnyBound =
false;
863 const auto& boundsList = selection[iKinPar];
865 for (
const auto& bounds : boundsList) {
866 if (kinVal > bounds[0] && kinVal <= bounds[1]) {
867 passedAnyBound =
true;
872 if (!passedAnyBound) {
873 MACH3LOG_TRACE(
"Event {}, missed kinematic check ({}) for dial {}",
874 iEvent, kinVars[iKinPar], (*it).name);
882 MACH3LOG_TRACE(
"Event {}, missed Kinematic var check for dial {}", iEvent, (*it).name);
887 int bin = (*it).index;
889 NormBins.push_back(bin);
890 MACH3LOG_TRACE(
"Event {}, will be affected by dial {}", iEvent, (*it).name);
892 VerboseCounter[std::distance(norm_parameters.begin(), it)]++;
897 xsec_norms_bins[iEvent] = NormBins;
900 MACH3LOG_DEBUG(
"┌──────────────────────────────────────────────────────────┐");
901 for (std::size_t i = 0; i < norm_parameters.size(); ++i) {
902 const auto& norm = norm_parameters[i];
903 double eventRatio =
static_cast<double>(VerboseCounter[i]) /
static_cast<double>(
GetNEvents());
905 MACH3LOG_DEBUG(
"│ Param {:<15}, affects {:<8} events ({:>6.2f}%) │",
908 MACH3LOG_DEBUG(
"└──────────────────────────────────────────────────────────┘");
942 _hPDF1D->SetBins(
static_cast<int>(nbins),boundaries);
943 dathist->SetBins(
static_cast<int>(nbins),boundaries);
949 double YBinEdges_Arr[2];
954 _hPDF2D->SetBins(
static_cast<int>(nbins),boundaries,1,YBinEdges_Arr);
955 dathist2d->SetBins(
static_cast<int>(nbins),boundaries,1,YBinEdges_Arr);
964 for(
unsigned int event_i = 0; event_i <
GetNEvents(); event_i++){
1017 _hPDF1D->SetBins(
static_cast<int>(nbins1),boundaries1);
1018 dathist->SetBins(
static_cast<int>(nbins1),boundaries1);
1021 _hPDF2D->SetBins(
static_cast<int>(nbins1),boundaries1,
static_cast<int>(nbins2),boundaries2);
1022 dathist2d->SetBins(
static_cast<int>(nbins1),boundaries1,
static_cast<int>(nbins2),boundaries2);
1033 for(
unsigned int event_i = 0 ; event_i <
GetNEvents(); event_i++) {
1038 if (std::isnan(*
MCSamples[event_i].x_var) || std::isinf(*
MCSamples[event_i].x_var)) {
1042 if (std::isnan(*
MCSamples[event_i].y_var) || std::isinf(*
MCSamples[event_i].y_var)) {
1052 _hPDF2D->GetBinXYZ(bin, bin_x, bin_y, bin_z);
1096 if(Dimension == 1) {
1097 TH1D* W2Hist =
dynamic_cast<TH1D*
>(
_hPDF1D->Clone((
_hPDF1D->GetName() + std::string(
"_W2")).c_str()));
1105 }
else if(Dimension == 2) {
1106 TH2D* W2Hist =
dynamic_cast<TH2D*
>(
_hPDF2D->Clone((
_hPDF2D->GetName() + std::string(
"_W2")).c_str()));
1115 MACH3LOG_ERROR(
"Asking for {} with N Dimension = {}. This is not implemented", __func__, Dimension);
1123 if(Dimension == 1) {
1126 }
else if(Dimension == 2) {
1130 MACH3LOG_ERROR(
"Asdking for {} with N Dimension = {}. This is not implemented", __func__, Dimension);
1138 if(Dimension == 1) {
1140 }
else if(Dimension == 2) {
1143 MACH3LOG_ERROR(
"Asdking for {} with N Dimension = {}. This is not implemented", __func__, Dimension);
1153 MACH3LOG_ERROR(
"Trying to set a 1D 'data' histogram when the number of dimensions for this sample is {}",
GetNDim());
1154 MACH3LOG_ERROR(
"This won't work, please specify the correct dimensions in your sample config with the X and Y variables");
1158 for (
auto const& data_point : data){
1163 MACH3LOG_ERROR(
"SampleHandlerFD_data haven't been initialised yet");
1178 MACH3LOG_ERROR(
"Trying to set a 2D 'data' histogram when the number of dimensions for this sample is {}",
GetNDim());
1179 MACH3LOG_ERROR(
"This won't work, please specify the correct dimensions in your sample config with the X and Y variables");
1186 for (
int i = 0; i < int(data.size()); i++) {
1187 dathist2d->Fill(data.at(0)[i],data.at(1)[i]);
1191 MACH3LOG_ERROR(
"SampleHandlerFD_data haven't been initialised yet");
1204 MACH3LOG_INFO(
"Adding 1D data histogram: {} with {:.2f} events", Data->GetTitle(), Data->Integral());
1206 dathist =
static_cast<TH1D*
>(Data->Clone());
1209 MACH3LOG_ERROR(
"Trying to set a 1D 'data' histogram in a 2D sample - Quitting");
1215 MACH3LOG_ERROR(
"SampleHandlerFD_data haven't been initialised yet");
1228 MACH3LOG_INFO(
"Adding 2D data histogram: {} with {:.2f} events", Data->GetTitle(), Data->Integral());
1229 dathist2d =
static_cast<TH2D*
>(Data->Clone());
1233 MACH3LOG_ERROR(
"Trying to set a 2D 'data' histogram in a 1D sample - Quitting");
1237 MACH3LOG_ERROR(
"SampleHandlerFD_data haven't been initialised yet");
1252 auto NuOscillatorConfigFile = Get<std::string>(
SampleManager->raw()[
"NuOsc"][
"NuOscConfigFile"], __FILE__ , __LINE__);
1253 auto EqualBinningPerOscChannel = Get<bool>(
SampleManager->raw()[
"NuOsc"][
"EqualBinningPerOscChannel"], __FILE__ , __LINE__);
1256 if (EqualBinningPerOscChannel) {
1257 if (YAML::LoadFile(NuOscillatorConfigFile)[
"General"][
"CalculationType"].as<std::string>() ==
"Unbinned") {
1258 MACH3LOG_WARN(
"Tried using EqualBinningPerOscChannel while using Unbinned oscillation calculation, changing EqualBinningPerOscChannel to false");
1259 EqualBinningPerOscChannel =
false;
1263 if (OscParams.empty()) {
1265 MACH3LOG_ERROR(
"This likely indicates an error in your oscillation YAML configuration.");
1268 Oscillator = std::make_shared<OscillationHandler>(NuOscillatorConfigFile, EqualBinningPerOscChannel, OscParams,
static_cast<int>(
OscChannels.size()));
1270 if (!EqualBinningPerOscChannel) {
1271 for(
int iChannel = 0; iChannel < static_cast<int>(
OscChannels.size()); iChannel++) {
1272 std::vector<M3::float_t> EnergyArray;
1273 std::vector<M3::float_t> CosineZArray;
1275 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
1279 if (!
MCSamples[iEvent].isNC && Channel == iChannel) {
1283 std::sort(EnergyArray.begin(),EnergyArray.end());
1288 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
1292 if (!
MCSamples[iEvent].isNC && Channel == iChannel) {
1296 std::sort(CosineZArray.begin(),CosineZArray.end());
1298 Oscillator->SetOscillatorBinning(iChannel, EnergyArray, CosineZArray);
1304 for (
unsigned int iEvent=0;iEvent<
GetNEvents();iEvent++) {
1320 MACH3LOG_ERROR(
"Something has gone wrong in the mapping between MCSamples.nutype and the enum used within NuOscillator");
1332 MCSamples[iEvent].osc_w_pointer =
Oscillator->GetNuOscillatorPointers(OscIndex, InitFlav, FinalFlav, FLOAT_T(*(
MCSamples[iEvent].rw_etru)), FLOAT_T(*(
MCSamples[iEvent].rw_truecz)));
1335 MCSamples[iEvent].osc_w_pointer =
Oscillator->GetNuOscillatorPointers(OscIndex, InitFlav, FinalFlav, FLOAT_T(*(
MCSamples[iEvent].rw_etru)));
1357 const int nParams =
static_cast<int>(
MCSamples[iEntry].total_weight_pointers.size());
1361 for (
int iParam = 0; iParam < nParams; ++iParam) {
1362 totalweight *= *(
MCSamples[iEntry].total_weight_pointers[iParam]);
1373 for (
unsigned int j = 0; j <
GetNEvents(); ++j) {
1376 std::vector< std::vector<int> > EventSplines;
1386 MACH3LOG_ERROR(
"MaCh3 only supports splines binned in Etrue + the sample binning");
1387 MACH3LOG_ERROR(
"Please check the sample binning you specified in your sample config ");
1391 int NSplines = int(EventSplines.size());
1395 MCSamples[j].xsec_spline_pointers.resize(NSplines);
1396 for(
size_t spline = 0; spline <
MCSamples[j].xsec_spline_pointers.size(); spline++) {
1398 MCSamples[j].xsec_spline_pointers[spline] =
SplineHandler->retPointer(EventSplines[spline][0], EventSplines[spline][1],
1399 EventSplines[spline][2], EventSplines[spline][3],
1400 EventSplines[spline][4], EventSplines[spline][5],
1401 EventSplines[spline][6]);
1410 MACH3LOG_ERROR(
"Data sample is empty! Can't calculate a likelihood!");
1414 double negLogL = 0.;
1416 #pragma omp parallel for collapse(2) reduction(+:negLogL)
1447 std::unique_ptr<TH1> data_hist;
1451 data_hist->GetXaxis()->SetTitle(
XVarStr.c_str());
1452 data_hist->GetYaxis()->SetTitle(
"Number of Events");
1455 data_hist->GetXaxis()->SetTitle(
XVarStr.c_str());
1456 data_hist->GetYaxis()->SetTitle(
YVarStr.c_str());
1457 data_hist->GetZaxis()->SetTitle(
"Number of Events");
1468 data_hist->SetTitle((
"data_" +
GetTitle()).c_str());
1473 std::vector<std::string> spline_filepaths;
1474 for(
unsigned iChannel = 0 ; iChannel <
OscChannels.size() ; iChannel++){
1479 std::vector<std::string> SplineVarNames = {
"TrueNeutrinoEnergy"};
1481 SplineVarNames.push_back(
XVarStr);
1484 SplineVarNames.push_back(
YVarStr);
1501 int WeightStyle, TAxis* Axis,
const std::vector< KinematicCut >& SubEventSelectionVec) {
1504 std::vector< KinematicCut > tmp_Selection =
Selection;
1505 std::vector< KinematicCut > SelectionVecToApply;
1508 for (
size_t iSelec=0;iSelec<
Selection.size();iSelec++) {
1509 SelectionVecToApply.emplace_back(
Selection[iSelec]);
1513 for (
size_t iSelec=0;iSelec<EventSelectionVec.size();iSelec++) {
1514 SelectionVecToApply.emplace_back(EventSelectionVec[iSelec]);
1523 _h1DVar =
new TH1D(
"",
"",Axis->GetNbins(),Axis->GetXbins()->GetArray());
1526 _h1DVar =
new TH1D(
"",
"",
int(xBinEdges.size())-1, xBinEdges.data());
1536 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
1539 if (WeightStyle == 1) {
1543 _h1DVar->Fill(Var,Weight);
1557 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
1560 if (WeightStyle == 1) {
1564 size_t nsubevents = Vec.size();
1566 for (
unsigned int iSubEvent = 0; iSubEvent < nsubevents; iSubEvent++) {
1568 double Var = Vec[iSubEvent];
1569 _h1DVar->Fill(Var,Weight);
1578 const std::vector< KinematicCut >& EventSelectionVec,
int WeightStyle, TAxis* AxisX, TAxis* AxisY,
const std::vector< KinematicCut >& SubEventSelectionVec) {
1582 std::vector< KinematicCut > tmp_Selection =
Selection;
1583 std::vector< KinematicCut > SelectionVecToApply;
1586 for (
size_t iSelec=0;iSelec<
Selection.size();iSelec++) {
1587 SelectionVecToApply.emplace_back(
Selection[iSelec]);
1591 for (
size_t iSelec=0;iSelec<EventSelectionVec.size();iSelec++) {
1592 SelectionVecToApply.emplace_back(EventSelectionVec[iSelec]);
1600 if (AxisX && AxisY) {
1601 _h2DVar =
new TH2D(
"",
"",AxisX->GetNbins(),AxisX->GetXbins()->GetArray(),AxisY->GetNbins(),AxisY->GetXbins()->GetArray());
1605 _h2DVar =
new TH2D(
"",
"",
int(xBinEdges.size())-1, xBinEdges.data(),
int(yBinEdges.size())-1, yBinEdges.data());
1609 if (IsSubEventHist)
Fill2DSubEventHist(_h2DVar, ProjectionVar_StrX, ProjectionVar_StrY, SubEventSelectionVec, WeightStyle);
1616 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
1619 if (WeightStyle == 1) {
1624 _h2DVar->Fill(VarX,VarY,Weight);
1635 const std::vector< KinematicCut >& SubEventSelectionVec,
int WeightStyle) {
1639 int ProjectionVar_IntX, ProjectionVar_IntY;
1646 for (
unsigned int iEvent = 0; iEvent <
GetNEvents(); iEvent++) {
1649 if (WeightStyle == 1) {
1652 std::vector<double> VecX = {}, VecY = {};
1654 size_t nsubevents = 0;
1656 if (IsSubEventVarX && !IsSubEventVarY) {
1659 nsubevents = VecX.size();
1661 else if (!IsSubEventVarX && IsSubEventVarY) {
1664 nsubevents = VecY.size();
1669 if (VecX.size() != VecY.size()) {
1670 MACH3LOG_ERROR(
"Cannot plot {} of size {} against {} of size {}", ProjectionVar_StrX, VecX.size(), ProjectionVar_StrY, VecY.size());
1673 nsubevents = VecX.size();
1676 for (
unsigned int iSubEvent = 0; iSubEvent < nsubevents; iSubEvent++) {
1678 if (IsSubEventVarX) VarX = VecX[iSubEvent];
1679 if (IsSubEventVarY) VarY = VecY[iSubEvent];
1680 _h2DVar->Fill(VarX,VarY,Weight);
1694 MACH3LOG_ERROR(
"Did not recognise Kinematic Parameter type: {}", KinematicParameterStr);
1708 MACH3LOG_ERROR(
"Did not recognise Kinematic Parameter type: {}", KinematicParameter);
1721 MACH3LOG_ERROR(
"Did not recognise Kinematic Vector: {}", KinematicVectorStr);
1735 MACH3LOG_ERROR(
"Did not recognise Kinematic Vector: {}", KinematicVector);
1745 if(KinematicParameter ==
XVarStr) {
1747 }
else if (KinematicParameter ==
YVarStr) {
1751 auto MakeBins = [](
int nBins) {
1752 std::vector<double> bins(
nBins + 1);
1753 for (
int i = 0; i <=
nBins; ++i)
1754 bins[i] =
static_cast<double>(i) - 0.5;
1758 if (KinematicParameter ==
"OscillationChannel") {
1760 }
else if (KinematicParameter ==
"Mode") {
1761 return MakeBins(
Modes->GetNModes());
1766 if(BinningConfig[
GetTitle()] && BinningConfig[
GetTitle()][KinematicParameter]){
1767 auto BinningVect = Get<std::vector<double>>(BinningConfig[
GetTitle()][KinematicParameter], __FILE__, __LINE__);
1770 auto BinningVect = Get<std::vector<double>>(BinningConfig[KinematicParameter], __FILE__, __LINE__);
1782 MACH3LOG_ERROR(
"Attempted to plot kinematic variable {}, but it appears in both KinematicVectors and KinematicParameters", VarStr);
1791 int kModeToFill,
int kChannelToFill,
int WeightStyle, TAxis* Axis) {
1795 if (kChannelToFill != -1) {
1807 if (kModeToFill!=-1) {
1808 if (!(kModeToFill >= 0) && (kModeToFill < Modes->GetNModes())) {
1809 MACH3LOG_ERROR(
"Required mode is not available. kModeToFill should be between 0 and {}",
Modes->GetNModes());
1819 std::vector< KinematicCut > SelectionVec;
1826 SelectionVec.push_back(SelecMode);
1834 SelectionVec.push_back(SelecChannel);
1837 return Get1DVarHist(ProjectionVar_Str,SelectionVec,WeightStyle,Axis);
1841 int kModeToFill,
int kChannelToFill,
int WeightStyle, TAxis* AxisX, TAxis* AxisY) {
1845 if (kChannelToFill!=-1) {
1857 if (kModeToFill!=-1) {
1858 if (!(kModeToFill >= 0) && (kModeToFill < Modes->GetNModes())) {
1859 MACH3LOG_ERROR(
"Required mode is not available. kModeToFill should be between 0 and {}",
Modes->GetNModes());
1869 std::vector< KinematicCut > SelectionVec;
1876 SelectionVec.push_back(SelecMode);
1884 SelectionVec.push_back(SelecChannel);
1887 return Get2DVarHist(ProjectionVar_StrX,ProjectionVar_StrY,SelectionVec,WeightStyle,AxisX,AxisY);
1893 bool printToFile=
false;
1894 if (OutputFileName.CompareTo(
"/dev/null")) {printToFile =
true;}
1896 bool printToCSV=
false;
1897 if(OutputCSVFileName.CompareTo(
"/dev/null")) printToCSV=
true;
1899 std::ofstream outfile;
1901 outfile.open(OutputFileName.Data(), std::ios_base::app);
1902 outfile.precision(7);
1905 std::ofstream outcsv;
1907 outcsv.open(OutputCSVFileName, std::ios_base::app);
1908 outcsv.precision(7);
1911 double PDFIntegral = 0.;
1913 std::vector< std::vector< TH1* > > IntegralList;
1914 IntegralList.resize(
Modes->GetNModes());
1916 std::vector<double> ChannelIntegral;
1918 for (
unsigned int i=0;i<ChannelIntegral.size();i++) {ChannelIntegral[i] = 0.;}
1920 for (
int i=0;i<
Modes->GetNModes();i++) {
1928 MACH3LOG_INFO(
"-------------------------------------------------");
1931 outfile <<
"\\begin{table}[ht]" << std::endl;
1932 outfile <<
"\\begin{center}" << std::endl;
1933 outfile <<
"\\caption{Integral breakdown for sample: " <<
GetTitle() <<
"}" << std::endl;
1934 outfile <<
"\\label{" <<
GetTitle() <<
"-EventRate}" << std::endl;
1939 outfile <<
"\\begin{tabular}{|l" << nColumns.Data() <<
"}" << std::endl;
1940 outfile <<
"\\hline" << std::endl;
1945 outcsv<<
"Integral Breakdown for sample :"<<
GetTitle()<<
"\n";
1951 if (printToFile) {outfile << std::setw(space) <<
"Mode:";}
1952 if(printToCSV) {outcsv<<
"Mode,";}
1954 std::string table_headings = fmt::format(
"| {:<8} |",
"Mode");
1955 std::string table_footline =
"------------";
1957 table_headings += fmt::format(
" {:<17} |",
OscChannels[i].flavourName);
1958 table_footline +=
"--------------------";
1959 if (printToFile) {outfile <<
"&" << std::setw(space) <<
OscChannels[i].flavourName_Latex <<
" ";}
1960 if (printToCSV) {outcsv <<
OscChannels[i].flavourName <<
",";}
1962 if (printToFile) {outfile <<
"&" << std::setw(space) <<
"Total:" <<
"\\\\ \\hline" << std::endl;}
1963 if (printToCSV) {outcsv <<
"Total\n";}
1964 table_headings += fmt::format(
" {:<10} |",
"Total");
1965 table_footline +=
"-------------";
1970 for (
unsigned int i=0;i<IntegralList.size();i++) {
1971 double ModeIntegral = 0;
1972 if (printToFile) {outfile << std::setw(space) <<
Modes->GetMaCh3ModeName(i);}
1973 if(printToCSV) {outcsv <<
Modes->GetMaCh3ModeName(i) <<
",";}
1975 table_headings = fmt::format(
"| {:<8} |",
Modes->GetMaCh3ModeName(i));
1977 for (
unsigned int j=0;j<IntegralList[i].size();j++) {
1978 double Integral = IntegralList[i][j]->Integral();
1980 if (Integral<1e-100) {Integral=0;}
1982 ModeIntegral += Integral;
1983 ChannelIntegral[j] += Integral;
1984 PDFIntegral += Integral;
1986 if (printToFile) {outfile <<
"&" << std::setw(space) << Form(
"%4.5f",Integral) <<
" ";}
1987 if (printToCSV) {outcsv << Form(
"%4.5f", Integral) <<
",";}
1989 table_headings += fmt::format(
" {:<17.4f} |", Integral);
1991 if (printToFile) {outfile <<
"&" << std::setw(space) << Form(
"%4.5f",ModeIntegral) <<
" \\\\ \\hline" << std::endl;}
1992 if (printToCSV) {outcsv << Form(
"%4.5f", ModeIntegral) <<
"\n";}
1994 table_headings += fmt::format(
" {:<10.4f} |", ModeIntegral);
1999 if (printToFile) {outfile << std::setw(space) <<
"Total:";}
2000 if (printToCSV) {outcsv <<
"Total,";}
2003 table_headings = fmt::format(
"| {:<8} |",
"Total");
2004 for (
unsigned int i=0;i<ChannelIntegral.size();i++) {
2005 if (printToFile) {outfile <<
"&" << std::setw(space) << Form(
"%4.5f",ChannelIntegral[i]) <<
" ";}
2006 if (printToCSV) {outcsv << Form(
"%4.5f", ChannelIntegral[i]) <<
",";}
2007 table_headings += fmt::format(
" {:<17.4f} |", ChannelIntegral[i]);
2009 if (printToFile) {outfile <<
"&" << std::setw(space) << Form(
"%4.5f",PDFIntegral) <<
" \\\\ \\hline" << std::endl;}
2010 if (printToCSV) {outcsv << Form(
"%4.5f", PDFIntegral) <<
"\n\n\n\n";}
2012 table_headings += fmt::format(
" {:<10.4f} |", PDFIntegral);
2017 outfile <<
"\\end{tabular}" << std::endl;
2018 outfile <<
"\\end{center}" << std::endl;
2019 outfile <<
"\\end{table}" << std::endl;
2025 outfile << std::endl;
2031 std::vector<TH1*> hHistList;
2032 std::string legendEntry;
2038 if (Selection1 == 0) {
2039 iMax =
Modes->GetNModes();
2041 if (Selection1 == 1) {
2045 MACH3LOG_ERROR(
"You've passed me a Selection1 which was not implemented in ReturnHistsBySelection1D. Selection1 and Selection2 are counters for different indexable quantities");
2049 for (
int i=0;i<iMax;i++) {
2050 if (Selection1==0) {
2052 THStackLeg->AddEntry(hHistList[i],(
Modes->GetMaCh3ModeName(i)+Form(
" : (%4.2f)",hHistList[i]->Integral())).c_str(),
"f");
2054 hHistList[i]->SetFillColor(
static_cast<Color_t
>(
Modes->GetMaCh3ModePlotColor(i)));
2055 hHistList[i]->SetLineColor(
static_cast<Color_t
>(
Modes->GetMaCh3ModePlotColor(i)));
2057 if (Selection1==1) {
2059 THStackLeg->AddEntry(hHistList[i],(
OscChannels[i].flavourName+Form(
" | %4.2f",hHistList[i]->Integral())).c_str(),
"f");
2067 int Selection1,
int Selection2,
int WeightStyle,
2068 TAxis* XAxis, TAxis* YAxis) {
2069 std::vector<TH2*> hHistList;
2072 if (Selection1 == 0) {
2073 iMax =
Modes->GetNModes();
2075 if (Selection1 == 1) {
2079 MACH3LOG_ERROR(
"You've passed me a Selection1 which was not implemented in ReturnHistsBySelection1D. Selection1 and Selection2 are counters for different indexable quantities");
2083 for (
int i=0;i<iMax;i++) {
2084 if (Selection1==0) {
2087 if (Selection1==1) {
2096 std::vector<TH1*> HistList =
ReturnHistsBySelection1D(KinematicProjection, Selection1, Selection2, WeightStyle, XAxis);
2097 THStack* StackHist =
new THStack((
GetTitle()+
"_"+KinematicProjection+
"_Stack").c_str(),
"");
2098 for (
unsigned int i=0;i<HistList.size();i++) {
2099 StackHist->Add(HistList[i]);
int GetOscChannel(const std::vector< OscChannelInfo > &OscChannel, const int InitFlav, const int FinalFlav)
KS: Get Osc Channel Index based on initial and final PDG codes.
KS: Based on this https://github.com/gabime/spdlog/blob/a2b4262090fd3f005c2315dcb5be2f0f1774a005/incl...
std::function< void(const double *, std::size_t)> FuncParFuncType
NuPDG
Enum to track the incoming neutrino species.
TestStatistic
Make an enum of the test statistic that we're using.
Type GetFromManager(const YAML::Node &node, Type defval, const std::string File="", const int Line=1)
Get content of config file if node is not found take default value specified.
TMacro YAMLtoTMacro(const YAML::Node &yaml_node, const std::string &name)
Convert a YAML node to a ROOT TMacro object.
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
#define GetBounds(filename)
Custom exception class for MaCh3 errors.
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...
Class responsible for handling implementation of samples used in analysis, reweighting and returning ...
std::unique_ptr< MaCh3Modes > Modes
Holds information about used Generator and MaCh3 modes.
TestStatistic fTestStatistic
Test statistic tells what kind of likelihood sample is using.
M3::int_t nSamples
Contains how many samples we've got.
unsigned int nEvents
Number of MC events are there.
bool MatchCondition(const std::vector< T > &allowedValues, const T &value)
check if event is affected by following conditions, for example pdg, or modes etc
std::vector< std::vector< int > > funcParsGrid
HH - a grid of vectors of enums for each sample and event.
void CalcNormsBins(std::vector< NormParameter > &norm_parameters, std::vector< std::vector< int > > &xsec_norms_bins)
Check whether a normalisation systematic affects an event or not.
std::vector< FunctionalParameter > funcParsVec
HH - a vector that stores all the FuncPars struct.
virtual void resetShifts(int iEvent)
HH - reset the shifted values to the original values.
std::vector< FunctionalParameter * > funcParsMap
HH - a map that relates the funcpar enum to pointer of FuncPars struct HH - Changed to a vector of po...
virtual void Init()=0
Initialise any variables that your experiment specific SampleHandler needs.
std::string ReturnStringFromKinematicVector(const int KinematicVariable) const
std::vector< double > ReturnKinematicParameterBinning(const std::string &KinematicParameter)
Return the binning used to draw a kinematic parameter.
std::unique_ptr< BinnedSplineHandler > SplineHandler
Contains all your binned splines and handles the setup and the returning of weights from spline evalu...
virtual void CalcWeightFunc(int iEvent)
Calculate weights for function parameters.
SampleBinningInfo Binning
KS: This stores binning information, in future could be come vector to store binning for every used s...
virtual void SetupSplines()=0
initialise your splineXX object and then use InitialiseSplineObject to conviently setup everything up
bool IsEventSelected(const int iEvent)
DB Function which determines if an event is selected, where Selection double looks like {{ND280Kinema...
ParameterHandlerGeneric * ParHandler
std::string SampleTitle
the name of this sample e.g."muon-like"
bool FirstTimeW2
KS:Super hacky to update W2 or not.
std::unordered_map< std::string, NuPDG > FileToInitPDGMap
void InitialiseSplineObject()
std::vector< KinematicCut > Selection
a way to store selection cuts which you may push back in the get1DVar functions most of the time this...
virtual int SetupExperimentMC()=0
Experiment specific setup, returns the number of events which were loaded.
const std::unordered_map< int, std::string > * ReversedKinematicVectors
double ** SampleHandlerFD_array_w2
KS Array used for MC stat.
std::vector< KinematicCut > StoredSelection
What gets pulled from config options, these are constant after loading in this is of length 3: 0th in...
virtual std::vector< double > ReturnKinematicVector(std::string KinematicParameter, int iEvent)
std::vector< std::string > spline_files
names of spline files associated associated with this object
double GetLikelihood() override
DB Multi-threaded GetLikelihood.
std::unordered_map< std::string, NuPDG > FileToFinalPDGMap
std::unordered_map< int, FuncParFuncType > funcParsFuncMap
HH - a map that relates the funcpar enum to pointer of the actual function.
const double * GetPointerToOscChannel(const int iEvent) const
Get pointer to oscillation channel associated with given event. Osc channel is const.
std::vector< OscChannelInfo > OscChannels
void FindNominalBinAndEdges2D()
std::string XVarStr
the strings associated with the variables used for the binning e.g. "RecoNeutrinoEnergy"
const std::unordered_map< std::string, int > * KinematicVectors
void SetupNormParameters()
Setup the norm parameters by assigning each event with bin.
void SetupKinematicMap()
Ensure Kinematic Map is setup and make sure it is initialised correctly.
void FillSplineBins()
Finds the binned spline that an event should apply to and stored them in a a vector for easy evaluati...
virtual void PrepFunctionalParameters()
Update the functional parameter values to the latest proposed values. Needs to be called before every...
SampleHandlerFD(std::string ConfigFileName, ParameterHandlerGeneric *xsec_cov, const std::shared_ptr< OscillationHandler > &OscillatorObj_=nullptr)
Constructor.
void Fill2DSubEventHist(TH2D *_h2DVar, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &SubEventSelectionVec=std::vector< KinematicCut >(), int WeightStyle=0)
void Initialise()
Function which does a lot of the lifting regarding the workflow in creating different MC objects.
virtual ~SampleHandlerFD()
destructor
void FindNominalBinAndEdges1D()
std::vector< std::string > funcParsNamesVec
HH - a vector of string names for each functional parameter.
virtual void SetupFDMC()=0
Function which translates experiment struct into core struct.
void SaveAdditionalInfo(TDirectory *Dir) override
Store additional info in a chan.
std::unique_ptr< manager > SampleManager
The manager object used to read the sample yaml file.
M3::float_t GetEventWeight(const int iEntry) const
void Fill1DHist()
Fill a 1D histogram with the event-level information used in the fit.
void InitialiseNuOscillatorObjects()
including Dan's magic NuOscillator
void Fill2DHist()
Fill a 2D histogram with the event-level information used in the fit.
void RegisterIndividualFunctionalParameter(const std::string &fpName, int fpEnum, FuncParFuncType fpFunc)
HH - a helper function for RegisterFunctionalParameter.
M3::float_t CalcWeightNorm(const FarDetectorCoreInfo *MCEvent) const
Calculate the norm weight for a given event.
bool UpdateW2
KS:Super hacky to update W2 or not.
std::shared_ptr< OscillationHandler > Oscillator
Contains all your binned splines and handles the setup and the returning of weights from spline evalu...
double ** SampleHandlerFD_array
DB Array to be filled after reweighting.
bool IsSubEventSelected(const std::vector< KinematicCut > &SubEventCuts, const int iEvent, unsigned const int iSubEvent, size_t nsubevents)
JM Function which determines if a subevent is selected.
const std::unordered_map< std::string, int > * KinematicParameters
Mapping between string and kinematic enum.
void Set2DBinning(size_t nbins1, double *boundaries1, size_t nbins2, double *boundaries2)
set the binning for 2D sample used for the likelihood calculation
void InitialiseSingleFDMCObject()
function to create the member of the FarDetectorInfo struct so they are the appropriate size.
TH2 * Get2DVarHist(const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec=std::vector< KinematicCut >(), int WeightStyle=0, TAxis *AxisX=nullptr, TAxis *AxisY=nullptr, const std::vector< KinematicCut > &SubEventSelectionVec=std::vector< KinematicCut >())
virtual void RegisterFunctionalParameters()=0
HH - a experiment-specific function where the maps to actual functions are set up.
M3::float_t CalcWeightSpline(const FarDetectorCoreInfo *MCEvent) const
Calculate the spline weight for a given event.
std::vector< std::string > mc_files
names of mc files associated associated with this object
void ResetHistograms()
Helper function to reset histograms.
virtual double ReturnKinematicParameter(std::string KinematicParamter, int iEvent)=0
Return the value of an assocaited kinematic parameter for an event.
bool IsSubEventVarString(const std::string &VarStr)
JM Check if a kinematic parameter string corresponds to a subevent-level variable.
virtual void ApplyShifts(int iEvent)
ETA - generic function applying shifts.
std::unordered_map< std::string, double > _modeNomWeightMap
const std::unordered_map< int, std::string > * ReversedKinematicParameters
Mapping between kinematic enum and string.
int ReturnKinematicVectorFromString(const std::string &KinematicStr) const
double ** SampleHandlerFD_data
DB Array to be filled in AddData.
virtual void SetupWeightPointers()=0
DB Function to determine which weights apply to which types of samples pure virtual!...
void SetupSampleBinning()
wrapper to call set binning functions based on sample config info
void SetupNuOscillatorPointers()
virtual void SetupFunctionalParameters()
ETA - a function to setup and pass values to functional parameters where you need to pass a value to ...
void FillArray()
DB Nice new multi-threaded function which calculates the event weights and fills the relevant bins of...
int nDimensions
Keep track of the dimensions of the sample binning.
TLegend * THStackLeg
DB Miscellaneous Variables.
void PrintIntegral(TString OutputName="/dev/null", int WeightStyle=0, TString OutputCSVName="/dev/null")
std::vector< FarDetectorCoreInfo > MCSamples
void SetupReweightArrays(const size_t numberXBins, const size_t numberYBins)
Initialise data, MC and W2 histograms.
std::unordered_map< std::string, int > funcParsNamesMap
HH - a map that relates the name of the functional parameter to funcpar enum.
void Set1DBinning(size_t nbins, double *boundaries)
sets the binning used for the likelihood calculation, used for both data and MC
std::string SampleName
A unique ID for each sample based on powers of two for quick binary operator comparisons.
virtual const double * GetPointerToKinematicParameter(std::string KinematicParamter, int iEvent)=0
The manager class is responsible for managing configurations and settings.
const std::vector< NormParameter > GetNormParsFromSampleName(const std::string &SampleName) const
DB Get norm/func parameters depending on given SampleName.
std::string GetParFancyName(const int i) const
Get fancy name of the Parameter.
const std::vector< FunctionalParameter > GetFunctionalParametersFromSampleName(const std::string &SampleName) const
HH Get functional parameters for the relevant SampleName.
std::vector< const double * > GetOscParsFromSampleName(const std::string &SampleName)
Get pointers to Osc params from Sample name.
TH1 * Get1DVarHist(const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec=std::vector< KinematicCut >(), int WeightStyle=0, TAxis *Axis=nullptr, const std::vector< KinematicCut > &SubEventSelectionVec=std::vector< KinematicCut >())
std::string ReturnStringFromKinematicParameter(const int KinematicVariable) const
ETA function to generically convert a kinematic type from xsec cov to a string.
std::string GetSampleName(int iSample=0) const override
void Fill1DSubEventHist(TH1D *_h1DVar, const std::string &ProjectionVar, const std::vector< KinematicCut > &SubEventSelectionVec=std::vector< KinematicCut >(), int WeightStyle=0)
int GetNDim() const
DB Function to differentiate 1D or 2D binning.
unsigned int GetNEvents() const
std::vector< TH2 * > ReturnHistsBySelection2D(std::string KinematicProjectionX, std::string KinematicProjectionY, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *XAxis=0, TAxis *YAxis=0)
std::string GetTitle() const override
int GetNOscChannels() override
TH2 * Get2DVarHistByModeAndChannel(const std::string &ProjectionVar_StrX, const std::string &ProjectionVar_StrY, int kModeToFill=-1, int kChannelToFill=-1, int WeightStyle=0, TAxis *AxisX=nullptr, TAxis *AxisY=nullptr)
TH1 * GetW2Hist(const int Dimension)
Get W2 histogram.
TH1 * Get1DVarHistByModeAndChannel(const std::string &ProjectionVar_Str, int kModeToFill=-1, int kChannelToFill=-1, int WeightStyle=0, TAxis *Axis=nullptr)
TH1 * GetMCHist(const int Dimension)
Get MC histogram.
double GetTestStatLLH(double data, double mc) const
Calculate test statistic for a single bin using Poisson.
std::vector< TH1 * > ReturnHistsBySelection1D(std::string KinematicProjection, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *Axis=0)
int ReturnKinematicParameterFromString(const std::string &KinematicStr) const
ETA function to generically convert a string from xsec cov to a kinematic type.
TH1 * GetDataHist(const int Dimension)
Get Data histogram.
THStack * ReturnStackedHistBySelection1D(std::string KinematicProjection, int Selection1, int Selection2=-1, int WeightStyle=0, TAxis *Axis=0)
static constexpr const double _BAD_DOUBLE_
Default value used for double initialisation.
static constexpr const double _DEFAULT_RETURN_VAL_
static constexpr const float_t Unity
static constexpr const float_t Zero
static constexpr const int _BAD_INT_
Default value used for int initialisation.
int PDGToNuOscillatorFlavour(int NuPdg)
Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscilla...
constructors are same for all three so put in here
std::vector< const double * > xsec_norm_pointers
Pointers to normalisation weights which are being taken from Parameter Handler.
M3::float_t xsec_w
Total weight of norm and spline parameters.
std::vector< const M3::float_t * > xsec_spline_pointers
Pointers to spline weights which are being calculated by Splines Handler.
HH - Functional parameters Carrier for whether you want to apply a systematic to an event or not.
const double * valuePtr
Parameter value pointer.
FuncParFuncType * funcPtr
Function pointer.
KS: Small struct used for applying kinematic cuts.
double UpperBound
Upper bound on which we apply cut.
double LowerBound
Lower bound on which we apply cut.
int ParamToCutOnIt
Index or enum value identifying the kinematic variable to cut on.
KS: Store info about used osc channels.
std::string flavourName
Name of osc channel.
std::vector< double > YBinEdges
Vector to hold y-axis bin-edges.
std::vector< double > rw_upper_xbinedge
upper to check if Eb has moved the erec bin
size_t nXBins
Number of X axis bins in the histogram used for likelihood calculation.
std::vector< double > rw_lower_lower_xbinedge
lower to check if Eb has moved the erec bin
size_t nYBins
Number of Y axis bins in the histogram used for likelihood calculation.
std::vector< double > rw_lower_xbinedge
lower to check if Eb has moved the erec bin
std::vector< double > rw_upper_upper_xbinedge
upper to check if Eb has moved the erec bin
std::vector< double > XBinEdges
Vector to hold x-axis bin-edges.
int FindXBin(const double XVar, const int NomXBin) const
DB Find the relevant bin in the PDF for each event.