MaCh3  2.5.1
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_, const int SubChannels) {
11 // ************************************************
12  EqualBinningPerOscChannel = BinningPerOscChannel_;
13  OscParams = OscParams_;
14  // Add first sample
15  NuOscProbCalcers.resize(1);
16 
17  auto OscillFactory = std::make_unique<OscillatorFactory>();
18  //DB's explanation of EqualBinningPerOscChannel:
19  //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
20  //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
21  //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
22 
24  NuOscProbCalcers[0].resize(1);
25  LoggerPrint("NuOscillator",
26  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
27  [this, &OscillFactory, &NuOscillatorConfigFile]() {
28  this->NuOscProbCalcers[0][0] = std::unique_ptr<OscillatorBase>(OscillFactory->CreateOscillator(NuOscillatorConfigFile));
29  });
30 
31  if (!NuOscProbCalcers[0][0]->EvalPointsSetInConstructor()) {
32  MACH3LOG_ERROR("Attempted to use equal binning per oscillation channel, but not binning has been set in the NuOscillator::Oscillator object");
33  throw MaCh3Exception(__FILE__, __LINE__);
34  }
35  LoggerPrint("NuOscillator",
36  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
37  [this]() {
38  NuOscProbCalcers[0][0]->Setup();
39  });
40  } else {
41  NuOscProbCalcers[0].resize(SubChannels);
42  for (int iChannel = 0; iChannel < SubChannels; iChannel++) {
43  MACH3LOG_INFO("Setting up NuOscillator::Oscillator object in OscillationChannel: {}/{}", iChannel, SubChannels);
44 
45  LoggerPrint("NuOscillator",
46  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
47  [this, iChannel, &OscillFactory, &NuOscillatorConfigFile]() {
48  this->NuOscProbCalcers[0][iChannel] = std::unique_ptr<OscillatorBase>(
49  OscillFactory->CreateOscillator(NuOscillatorConfigFile));
50  });
51  }
52  }
53 }
54 
55 // ************************************************
57 // ************************************************
58 }
59 
60 // ************************************************
61 void OscillationHandler::AddSample(const std::string& NuOscillatorConfigFile, const int SubChannels) {
62 // ************************************************
64  MACH3LOG_ERROR("Trying to add sample while EqualBinningPerOscChannel is enabled. This will not work...");
65  throw MaCh3Exception(__FILE__, __LINE__);
66  }
67  auto OscillFactory = std::make_unique<OscillatorFactory>();
68 
69  std::vector<std::unique_ptr<OscillatorBase>> OscProbCalcersTemp(SubChannels);
70 
71  for (int iChannel = 0; iChannel < SubChannels; iChannel++) {
72  MACH3LOG_INFO("Setting up NuOscillator::Oscillator object in OscillationChannel: {}/{}", iChannel, SubChannels);
73 
74  LoggerPrint("NuOscillator",
75  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
76  [&OscProbCalcersTemp, iChannel, &OscillFactory, &NuOscillatorConfigFile]() {
77  OscProbCalcersTemp[iChannel] = std::unique_ptr<OscillatorBase>(
78  OscillFactory->CreateOscillator(NuOscillatorConfigFile));
79  });
80  }
81  NuOscProbCalcers.push_back(std::move(OscProbCalcersTemp));
82 }
83 
84 // ************************************************
86 // ************************************************
87  // NuOscillator is using FLOAT_T while MaCh3 M3::float_t
88  // Moslty they are same however it is possible to have double on M3
89  // but float on NuOsc hence we need conversion
90  std::vector<FLOAT_T> OscVec(OscParams.size());
91  for (size_t iPar = 0; iPar < OscParams.size(); ++iPar) {
92  #pragma GCC diagnostic push
93  #pragma GCC diagnostic ignored "-Wuseless-cast"
94  OscVec[iPar] = static_cast<FLOAT_T>(*OscParams[iPar]);
95  #pragma GCC diagnostic pop
96  }
97 
99  NuOscProbCalcers[0][0]->CalculateProbabilities(OscVec);
100  } else {
101  for (size_t iSample = 0; iSample < NuOscProbCalcers.size(); iSample++) {
102  for (size_t iChannel = 0; iChannel < NuOscProbCalcers[iSample].size(); iChannel++) {
103  NuOscProbCalcers[iSample][iChannel]->CalculateProbabilities(OscVec);
104  }
105  }
106  }
107 }
108 
109 
110 // ************************************************
111 const M3::float_t* OscillationHandler::GetNuOscillatorPointers(const int Sample, const int Channel, const int InitFlav,
112  const int FinalFlav, const FLOAT_T TrueEnu, const FLOAT_T TrueCosZenith) {
113 // ************************************************
114  int IndexSample = 0;
115  int IndexChannel = 0;
117  IndexSample = Sample;
118  IndexChannel = Channel;
119  }
120 
121  if(TrueCosZenith != -999) {
122  return NuOscProbCalcers[IndexSample][IndexChannel]->ReturnWeightPointer(InitFlav ,FinalFlav, TrueEnu, TrueCosZenith);
123  } else {
124  return NuOscProbCalcers[IndexSample][IndexChannel]->ReturnWeightPointer(InitFlav ,FinalFlav, TrueEnu);
125  }
126 }
127 
128 
129 // ************************************************
130 void OscillationHandler::SetOscillatorBinning(const int Sample, const int Channel, const std::vector<M3::float_t>& EnergyArray,
131  const std::vector<M3::float_t>& CosineZArray) {
132 // ************************************************
133  if (!NuOscProbCalcers[Sample][Channel]->EvalPointsSetInConstructor()) {
134  NuOscProbCalcers[Sample][Channel]->SetEnergyArrayInCalcer(EnergyArray);
135  if(CosineZArray.size() != 0) NuOscProbCalcers[Sample][Channel]->SetCosineZArrayInCalcer(CosineZArray);
136  }
137  LoggerPrint("NuOscillator",
138  [](const std::string& message) { MACH3LOG_INFO("{}", message); },
139  [this, Sample, Channel]() {
140  NuOscProbCalcers[Sample][Channel]->Setup();
141  });
142 }
#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:100
Custom exception class used throughout MaCh3.
void AddSample(const std::string &NuOscillatorConfigFile, const int SubChannels)
Add different oscillator for sample.
OscillationHandler(const std::string &ConfigFile, bool EqualBinningPerChannel, std::vector< const M3::float_t * > OscParams_, const int SubChannels)
Constructor.
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.
bool EqualBinningPerOscChannel
flag used to define whether all oscillation channels have a probability calculated using the same bin...
double float_t
Definition: Core.h:37