All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SBNWeightSysts.cxx
Go to the documentation of this file.
2 
4 
6 
7 #include "sbnanaobj/StandardRecord/Proxy/SRProxy.h"
8 
9 #include <cassert>
10 #include <iostream>
11 
12 namespace ana
13 {
14  // --------------------------------------------------------------------------
15  UniverseWeight::UniverseWeight(const std::string& psetName, int univIdx)
16  : fPSetName(psetName), fPSetIdx(-1), fUnivIdx(univIdx)
17  {
18  }
19 
20  // --------------------------------------------------------------------------
22  {
23  if(sr->truth.index < 0) return 1;
24 
25  if(fPSetIdx == -1){
28  }
29 
30  const caf::Proxy<std::vector<caf::SRMultiverse>>& wgts = sr->truth.wgt;
31  if(wgts.empty()) return 1;
32 
33  const int Nwgts = wgts[fPSetIdx].univ.size();
34 
35  static bool once = true;
36  if(!once && fUnivIdx >= Nwgts){
37  once = false;
38  std::cout << "UniverseWeight: WARNING requesting universe " << fUnivIdx << " in parameter set " << fPSetName << " which only has size " << Nwgts << ". Will wrap-around and suppress future warnings." << std::endl;
39  }
40 
41  const unsigned int unividx = fUnivIdx % Nwgts;
42 
43  return wgts[fPSetIdx].univ[unividx];
44  }
45 
46  // --------------------------------------------------------------------------
47  SBNWeightSyst::SBNWeightSyst(const std::string& systName)
48  : ISyst(systName, systName),
49  fIdx(-1)
50  {
51  }
52 
53  // --------------------------------------------------------------------------
54  void SBNWeightSyst::Shift(double x, caf::SRSliceProxy* sr, double& weight) const
55  {
56  if(sr->truth.index < 0) return;
57 
59 
60  const caf::Proxy<std::vector<caf::SRMultiverse>>& wgts = sr->truth.wgt;
61  if(wgts.empty()) return;
62 
63  const Univs u = GetUnivs(x);
64 
65  double y = 0;
66  if(u.w0 != 0) y += u.w0 * wgts[fIdx].univ[u.i0];
67  if(u.w1 != 0) y += u.w1 * wgts[fIdx].univ[u.i1];
68 
69  weight *= y;
70  }
71 
72  // --------------------------------------------------------------------------
74  {
75  auto it = fUnivs.find(x);
76  if(it != fUnivs.end()) return it->second;
77 
78  Univs u;
80  // Neighbours
81  double x0, x1;
82  u.i0 = uo.ClosestShiftIndex(ShortName(), x, ESide::kBelow, &x0);
83 
84  if(x0 == x){
85  // Found an exact match (this is OK for small integer shifts, even with
86  // floating point comparisons
87  u.i1 = -1;
88  u.w0 = 1;
89  u.w1 = 0;
90  fUnivs[x] = u;
91  return u;
92  }
93 
94  // Otherwise we're interpolating
95  u.i1 = uo.ClosestShiftIndex(ShortName(), x, ESide::kAbove, &x1);
96  // Interpolation weights
97  u.w0 = (x1-x)/(x1-x0);
98  u.w1 = (x-x0)/(x1-x0);
99 
100  // std::cout << ShortName() << " " << x << " sigma, found indices " << u.i0 << " and " << u.i1 << " at " << x0 << " and " << x1 << ", will use weights " << u.w0 << " and " << u.w1 << std::endl;
101 
102  // If one of the neighbours wasn't found, we fall back to just using the
103  // neighbour we did find. It would probably be better to find two
104  // neighbours on the same side and extrapolate.
105  if(u.i0 == -1){u.i0 = u.i1; u.w0 = u.w1 = 0.5;}
106  if(u.i1 == -1){u.i1 = u.i0; u.w0 = u.w1 = 0.5;}
107 
108  fUnivs[x] = u;
109  return u;
110  }
111 
112  // --------------------------------------------------------------------------
113  std::vector<std::string> GetSBNGenieWeightNames()
114  {
115  // We can't ask the UniverseOracle about this, because it doesn't get
116  // properly configured until it's seen its first CAF file.
117  return {"AhtBY",
118  "BhtBY",
119  "CV1uBY",
120  "CV2uBY",
121  "EtaNCEL",
122  "FormZone",
123  "FrAbs_N",
124  "FrAbs_pi",
125  "FrCEx_N",
126  "FrCEx_pi",
127  "FrInel_N",
128  "FrInel_pi",
129  "FrPiProd_N",
130  "FrPiProd_pi",
131  "MFP_N",
132  "MFP_pi",
133  "MaCCQE",
134  "MaCCRES",
135  "MaNCEL",
136  "MaNCRES",
137  "MvCCRES",
138  "MvNCRES",
139  "NonRESBGvbarnCC1pi",
140  "NonRESBGvbarnCC2pi",
141  "NonRESBGvbarnNC1pi",
142  "NonRESBGvbarnNC2pi",
143  "NonRESBGvbarpCC1pi",
144  "NonRESBGvbarpCC2pi",
145  "NonRESBGvbarpNC1pi",
146  "NonRESBGvbarpNC2pi",
147  "NonRESBGvnCC1pi",
148  "NonRESBGvnCC2pi",
149  "NonRESBGvnNC1pi",
150  "NonRESBGvnNC2pi",
151  "NonRESBGvpCC1pi",
152  "NonRESBGvpCC2pi",
153  "NonRESBGvpNC1pi",
154  "NonRESBGvpNC2pi",
155  };
156  }
157 
158  // --------------------------------------------------------------------------
159  const std::vector<const ISyst*>& GetSBNGenieWeightSysts()
160  {
161  static std::vector<const ISyst*> ret;
162  if(!ret.empty()) return ret;
163 
164  for(const std::string& name: GetSBNGenieWeightNames())
165  ret.push_back(new SBNWeightSyst(name));
166 
167  return ret;
168  }
169 
170  // -------------------------------------------------------------------------
171 
172  std::vector<std::string> GetSBNBoosterFluxWeightNames()
173  {
174  // We can't ask the UniverseOracle about this, because it doesn't get
175  // properly configured until it's seen its first CAF file.
176  return {"expskin",
177  "horncurrent",
178  "nucleoninexsec",
179  "nucleonqexsec",
180  "nucleontotxsec",
181  "pioninexsec",
182  "pionqexsec",
183  "piontotxsec"};
184  }
185 
186  // --------------------------------------------------------------------------
187 
188  const std::vector<const ISyst*>& GetSBNBoosterFluxWeightSysts()
189  {
190  static std::vector<const ISyst*> ret;
191  if(!ret.empty()) return ret;
192 
193  for(const std::string& name: GetSBNBoosterFluxWeightNames())
194  ret.push_back(new SBNWeightSyst(name));
195 
196  return ret;
197  }
198 
199  // --------------------------------------------------------------------------
200  const std::vector<const ISyst*>& GetSBNWeightSysts()
201  {
202  static std::vector<const ISyst*> ret;
203  if(ret.empty()){
204  const std::vector<const ISyst*>& g = GetSBNGenieWeightSysts();
205  const std::vector<const ISyst*>& f = GetSBNBoosterFluxWeightSysts();
206  ret.reserve(g.size()+f.size());
207  ret.insert(ret.end(), g.begin(), g.end());
208  ret.insert(ret.end(), f.begin(), f.end());
209  }
210  return ret;
211  }
212 
213 }
unsigned int SystIndex(const std::string &name) const
Which index in the weights array corresponds to the shifting of just this syst (in any parameter set)...
std::string fPSetName
process_name opflash particleana ie x
double operator()(const caf::SRSliceProxy *sr) const
const std::vector< const ISyst * > & GetSBNBoosterFluxWeightSysts()
void Shift(double x, caf::SRSliceProxy *sr, double &weight) const override
Perform the systematic shift.
UniverseWeight(const std::string &psetName, int univIdx)
process_name opflashCryoW ana
BEGIN_PROLOG g
std::unordered_map< double, Univs > fUnivs
static UniverseOracle & Instance()
Encapsulate code to systematically shift a caf::StandardRecord.
Definition: ISyst.h:14
caf::Proxy< caf::SRSlice > SRSliceProxy
Definition: EpilogFwd.h:2
virtual std::string ShortName() const final
The name printed out to the screen.
Definition: ISyst.h:30
process_name opflash particleana ie ie y
SBNWeightSyst(const std::string &systName)
const std::vector< const ISyst * > & GetSBNGenieWeightSysts()
std::vector< std::string > GetSBNBoosterFluxWeightNames()
Univs GetUnivs(double x) const
unsigned int ParameterSetIndex(const std::string &name) const
Which index in the weights array corresponds to this parameter set?
const std::vector< const ISyst * > & GetSBNWeightSysts()
unsigned int ClosestShiftIndex(const std::string &name, double shift, ESide side=ESide::kEither, double *trueShift=0) const
Within that entry, which index corresponds most closely to &#39;shift&#39;?
then echo fcl name
std::vector< std::string > GetSBNGenieWeightNames()
BEGIN_PROLOG could also be cout