MaCh3  2.8.0
Reference Guide
OscillationHandler.cpp
Go to the documentation of this file.
1 #include "OscillationHandler.h"
2 
4 #include "Oscillator/OscillatorFactory.h"
5 #include "Constants/OscillatorConstants.h"
7 
8 // ************************************************
9 OscillationHandler::OscillationHandler(const std::string& NuOscillatorConfigFile, bool BinningPerOscChannel_,
10  std::vector<const M3::float_t*> OscParams_, std::vector<std::string> NuOscNames_, const int SubChannels) {
11 // ************************************************
12  EqualBinningPerOscChannel = BinningPerOscChannel_;
13  OscParams = OscParams_;
14  NuOscNames = NuOscNames_;
15  // KS: Be aware we might be running with double on M3 but float in NuOsc
16  #pragma GCC diagnostic push
17  #pragma GCC diagnostic ignored "-Wuseless-cast"
18  OscParamsNuOsc.resize(OscParams.size(), static_cast<FLOAT_T>(M3::_BAD_DOUBLE_));
19  #pragma GCC diagnostic pop
20  // Add first sample
21  NuOscProbCalcers.resize(1);
22 
23  auto OscillFactory = std::make_unique<OscillatorFactory>();
24  //DB's explanation of EqualBinningPerOscChannel:
25  //In the situation where we are applying binning oscillation probabilities to a SampleHandler object, it maybe the case that there is identical binning per oscillation channel
26  //In which case, and remembering that each NuOscillator::Oscillator object calculate the oscillation probabilities for all channels, we just have to create one Oscillator object and use the results from that
27  //This means that we can get up to a factor of 12 reduction in the calculation time of the oscillation probabilities, because we don't need to repeat the operation per oscillation channel
28 
30  NuOscProbCalcers[0].resize(1);
31  LoggerPrint("NuOscillator",
32  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
33  [this, &OscillFactory, &NuOscillatorConfigFile]() {
34  this->NuOscProbCalcers[0][0] = std::unique_ptr<OscillatorBase>(OscillFactory->CreateOscillator(NuOscillatorConfigFile));
35  });
36 
37  for (size_t i = 0; i < OscParams.size(); i++) {
38  NuOscProbCalcers[0][0]->DefineParameter(NuOscNames[i], &OscParamsNuOsc[i]);
39  }
40  if (!NuOscProbCalcers[0][0]->EvalPointsSetInConstructor()) {
41  MACH3LOG_ERROR("Attempted to use equal binning per oscillation channel, but not binning has been set in the NuOscillator::Oscillator object");
42  throw MaCh3Exception(__FILE__, __LINE__);
43  }
44  LoggerPrint("NuOscillator",
45  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
46  [this]() {
47  NuOscProbCalcers[0][0]->Setup();
48  });
49  } else {
50  NuOscProbCalcers[0].resize(SubChannels);
51  for (int iChannel = 0; iChannel < SubChannels; iChannel++) {
52  MACH3LOG_INFO("Setting up NuOscillator::Oscillator object in OscillationChannel: {}/{}", iChannel, SubChannels);
53 
54  LoggerPrint("NuOscillator",
55  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
56  [this, iChannel, &OscillFactory, &NuOscillatorConfigFile]() {
57  this->NuOscProbCalcers[0][iChannel] = std::unique_ptr<OscillatorBase>(
58  OscillFactory->CreateOscillator(NuOscillatorConfigFile));
59  });
60  for (size_t i = 0; i < OscParams.size(); i++) {
61  NuOscProbCalcers[0][iChannel]->DefineParameter(NuOscNames[i], &OscParamsNuOsc[i]);
62  }
63  }
64  }
65 }
66 
67 // ************************************************
69 // ************************************************
70 }
71 
72 // ************************************************
73 void OscillationHandler::AddSample(const std::string& NuOscillatorConfigFile, const int SubChannels) {
74 // ************************************************
76  MACH3LOG_ERROR("Trying to add sample while EqualBinningPerOscChannel is enabled. This will not work...");
77  throw MaCh3Exception(__FILE__, __LINE__);
78  }
79  auto OscillFactory = std::make_unique<OscillatorFactory>();
80 
81  std::vector<std::unique_ptr<OscillatorBase>> OscProbCalcersTemp(SubChannels);
82 
83  for (int iChannel = 0; iChannel < SubChannels; iChannel++) {
84  MACH3LOG_INFO("Setting up NuOscillator::Oscillator object in OscillationChannel: {}/{}", iChannel, SubChannels);
85 
86  LoggerPrint("NuOscillator",
87  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
88  [&OscProbCalcersTemp, iChannel, &OscillFactory, &NuOscillatorConfigFile]() {
89  OscProbCalcersTemp[iChannel] = std::unique_ptr<OscillatorBase>(
90  OscillFactory->CreateOscillator(NuOscillatorConfigFile));
91  });
92  for (size_t i = 0; i < OscParams.size(); i++) {
93  OscProbCalcersTemp[iChannel]->DefineParameter(NuOscNames[i], &OscParamsNuOsc[i]);
94  }
95  }
96  NuOscProbCalcers.push_back(std::move(OscProbCalcersTemp));
97 }
98 
99 // ************************************************
101 // ************************************************
102  // NuOscillator is using FLOAT_T while MaCh3 M3::float_t
103  // Moslty they are same however it is possible to have double on M3
104  // but float on NuOsc hence we need conversion
105  for (size_t iPar = 0; iPar < OscParams.size(); ++iPar) {
106  #pragma GCC diagnostic push
107  #pragma GCC diagnostic ignored "-Wuseless-cast"
108  OscParamsNuOsc[iPar] = static_cast<FLOAT_T>(*OscParams[iPar]);
109  #pragma GCC diagnostic pop
110  }
111 
113  NuOscProbCalcers[0][0]->CalculateProbabilities();
114  } else {
115  for (size_t iSample = 0; iSample < NuOscProbCalcers.size(); iSample++) {
116  for (size_t iChannel = 0; iChannel < NuOscProbCalcers[iSample].size(); iChannel++) {
117  NuOscProbCalcers[iSample][iChannel]->CalculateProbabilities();
118  }
119  }
120  }
121 }
122 
123 
124 // ************************************************
125 const M3::float_t* OscillationHandler::GetNuOscillatorPointers(const int Sample, const int Channel, const int InitFlav,
126  const int FinalFlav, const FLOAT_T TrueEnu, const FLOAT_T TrueCosZenith) {
127 // ************************************************
128  int IndexSample = 0;
129  int IndexChannel = 0;
131  IndexSample = Sample;
132  IndexChannel = Channel;
133  }
134 
135  if(TrueCosZenith != -999) {
136  return NuOscProbCalcers[IndexSample][IndexChannel]->ReturnWeightPointer(InitFlav ,FinalFlav, TrueEnu, TrueCosZenith);
137  } else {
138  return NuOscProbCalcers[IndexSample][IndexChannel]->ReturnWeightPointer(InitFlav ,FinalFlav, TrueEnu);
139  }
140 }
141 
142 
143 // ************************************************
144 void OscillationHandler::SetOscillatorBinning(const int Sample, const int Channel, const std::vector<M3::float_t>& EnergyArray,
145  const std::vector<M3::float_t>& CosineZArray) {
146 // ************************************************
147  if (!NuOscProbCalcers[Sample][Channel]->EvalPointsSetInConstructor()) {
148  NuOscProbCalcers[Sample][Channel]->SetEnergyArrayInCalcer(EnergyArray);
149  if(CosineZArray.size() != 0) NuOscProbCalcers[Sample][Channel]->SetCosineZArrayInCalcer(CosineZArray);
150  }
151  LoggerPrint("NuOscillator",
152  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
153  [this, Sample, Channel]() {
154  NuOscProbCalcers[Sample][Channel]->Setup();
155  });
156 }
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
Definition: Core.h:126
#define _MaCh3_Safe_Include_End_
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
void LoggerPrint(const std::string &LibName, LogFunc logFunction, Func &&func, Args &&... args)
KS: This is bit convoluted but this is to allow redirecting cout and errors from external library int...
Definition: MaCh3Logger.h:99
Custom exception class used throughout MaCh3.
void AddSample(const std::string &NuOscillatorConfigFile, const int SubChannels)
Add different oscillator for sample.
std::vector< std::string > NuOscNames
Names used to match MaCh3 params with NuOsc params.
std::vector< std::vector< std::unique_ptr< OscillatorBase > > > NuOscProbCalcers
DB Variables required for oscillation.
void Evaluate()
DB Evaluate oscillation weights for each defined event/bin.
virtual ~OscillationHandler()
Destructor.
const M3::float_t * GetNuOscillatorPointers(const int Sample, const int Channel, const int InitFlav, const int FinalFlav, const FLOAT_T TrueEnu, const FLOAT_T TrueCosZenith=-999)
Get pointer to oscillation weight.
std::vector< const M3::float_t * > OscParams
pointer to osc params, since not all params affect every sample, we perform some operations before ha...
void SetOscillatorBinning(const int Sample, const int Channel, const std::vector< M3::float_t > &EnergyArray, const std::vector< M3::float_t > &CosineZArray)
Setup binning, arrays correspond to events and their energy bins.
std::vector< FLOAT_T > OscParamsNuOsc
Values to which NuOsc has pointer.
bool EqualBinningPerOscChannel
flag used to define whether all oscillation channels have a probability calculated using the same bin...
OscillationHandler(const std::string &ConfigFile, bool EqualBinningPerChannel, std::vector< const M3::float_t * > OscParams_, std::vector< std::string > NuOscOscNames_, const int SubChannels)
Constructor.
constexpr static const double _BAD_DOUBLE_
Default value used for double initialisation.
Definition: Core.h:53
double float_t
Definition: Core.h:37