SpectrumHandler.cxx
Go to the documentation of this file.
2 
3 // Standard includes
4 #include <iostream>
5 #include <exception>
6 #include <string>
7 #include <vector>
8 
9 // CAFE includes
10 #include "CAFAna/Core/Binning.h"
11 #include "CAFAna/Core/Var.h"
12 #include "CAFAna/Core/MultiVar.h"
13 #include "CAFAna/Core/Cut.h"
14 #include "CAFAna/Core/Spectrum.h"
16 #include "CAFAna/Core/SystShifts.h"
17 
18 // ROOT includes
19 #include <TROOT.h>
20 #include <TFile.h>
21 
22 // This constructor creates a new SpectrumHandler using existing loaders. This is greatly beneficial when
23 ana::SpectrumHandler::SpectrumHandler(const std::vector<SpectrumLoaderBase*> loaders, const std::vector<std::string> dataset_labels){
24  // this->SetLoaders(loaders, dataset_labels);
25  fNLoaders = loaders.size();
26  fLoaders = loaders;
27  fLoader_labels = dataset_labels;
28 
30 }
31 
32 bool ana::SpectrumHandler::SetLoaders(const std::vector<std::string>& datasets, const std::vector<std::string>& dataset_labels){
34  throw std::runtime_error("Attempt to set loaders while SpecHelper is not unloaded.");
35 
36  if (datasets.size() != dataset_labels.size()){
37  std::cerr << "Number of datasets not equal to number of dataset labels. Please fix that." << std::endl;
38  return false;
39  }
40 
41  fNLoaders = datasets.size();
42  for (unsigned int idataset = 0; idataset < fNLoaders; idataset++){
44  loader = new SpectrumLoader(datasets[idataset]);
45  fLoaders.push_back(loader);
46  fLoader_labels.push_back(dataset_labels[idataset]);
47  }
49  return true;
50 }
51 
52 bool ana::SpectrumHandler::SetLoaders(const std::vector<SpectrumLoaderBase*> loaders, const std::vector<std::string> loader_labels){
54  throw std::runtime_error("Attempt to set loaders while SpecHelper is not unloaded.");
55 
56  if (loaders.size() != loader_labels.size()){
57  std::cerr << "Number of loaders not equal to number of loader labels." << std::endl;
58  return false;
59  }
60 
61  fNLoaders = loaders.size();
62  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++){
63  SpectrumLoaderBase * loader = loaders[iloader];
64  if (!loader || loader == NULL)
65  throw std::runtime_error("Attempt to use a non-existent loader: " + loader_labels[iloader]);
66  fLoaders.push_back(loader);
67  fLoader_labels.push_back(loader_labels[iloader]);
68  }
70  return true;
71 }
72 
73 bool ana::SpectrumHandler::SetSpillCuts(const std::vector<SpillCut> spillcuts){
75  throw std::runtime_error("Attempt to set spill cuts sometime NOT right after setting loaders. Only allow setting spill cuts IMMEDIATELY after setting loaders.");
76 
77  if (fNLoaders != spillcuts.size()){
78  std::cerr << "Warning: Number of spill cuts ( " << std::to_string(spillcuts.size()) << " ) not equal to number of loaders ( " << std::to_string(fNLoaders) << " ).\n\tFailed to set spill cuts." << std::endl;
79  return false;
80  }
81 
82  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++)
83  fLoaders[iloader]->SetSpillCut(spillcuts[iloader]);
84 
85  return true;
86 }
87 
90  throw std::runtime_error("Attempt to set spill cuts sometime NOT right after setting loaders. Only allow setting spill cuts IMMEDIATELY after setting loaders.");
91 
92  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++)
93  fLoaders[iloader]->SetSpillCut(cut);
94 
95  return true;
96 }
97 
99  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++)
100  if (fLoader_labels[iloader] == label)
101  return fLoaders[iloader];
102  return NULL;
103 }
104 
105 std::vector<ana::SpectrumLoaderBase*> ana::SpectrumHandler::GetLoaders(const std::vector<std::string> loader_labels){
106  std::vector<SpectrumLoaderBase*> loaderList;
107  for (unsigned int ilabel = 0; ilabel < loader_labels.size(); ilabel++){
108  SpectrumLoaderBase * loader = GetLoader(loader_labels[ilabel]);
109  if (loader == NULL)
110  throw std::runtime_error("Could not find loader with label \"" + loader_labels[ilabel] + "\". Skipping.");
111  loaderList.push_back(loader);
112  }
113  return loaderList;
114 }
115 
116 bool ana::SpectrumHandler::SetVars(const std::vector<Var> vars, const std::vector<std::string> var_labels, const std::vector<std::string> var_titles, const std::vector<Binning> var_bins){
118  throw std::runtime_error("Attempt to set the vars too late. The spectrums are either ready, or already had go() called on them.");
119 
120  if (vars.size() != var_labels.size() || vars.size() != var_titles.size() || vars.size() != var_bins.size()){
121  std::cerr << "Number of vars not equal to number of var labels / titles. Fix that." << std::endl;
122  return false;
123  }
124 
125  fVars = vars;
126  fVar_labels = var_labels;
127  fVar_titles = var_titles;
128  fVar_bins = var_bins;
129 
130  fNVars = fVars.size();
131 
132  return true;
133 }
134 
135 bool ana::SpectrumHandler::SetCuts(const std::vector<Cut> cuts, const std::vector<std::string> cut_labels){
137  throw std::runtime_error("Attempt to set the vars too late. The spectrums are either ready, or already had go() called on them.");
138 
139  if (cuts.size() != cut_labels.size()){
140  std::cerr << "Number of cuts not equal to number of cut labels. Fix that." << std::endl;
141  return false;
142  }
143 
144  fCuts = cuts;
146 
147  fNCuts = fCuts.size();
148 
149  return true;
150 }
151 
152 bool ana::SpectrumHandler::SetWeights(const std::vector<Var> weights, const std::vector<std::string> weight_labels){
154  throw std::runtime_error("Attempt to set the vars too late. The spectrums are either ready, or already had go() called on them.");
155 
156  if (weights.size() != weight_labels.size()){
157  std::cerr << "Number of Weights not equal to number of weight labels. Fix that." << std::endl;
158  return false;
159  }
160 
161  fWeights = weights;
162  fWeight_labels = weight_labels;
163 
164  fNWeights = fWeights.size();
165 
166  return true;
167 }
168 
169 bool ana::SpectrumHandler::SetShifts(const std::vector<SystShifts> shifts, const std::vector<std::string> shift_labels){
171  throw std::runtime_error("Attempt to set the vars too late. The spectrums are either ready, or already had go() called on them.");
172 
173  if (shifts.size() != shift_labels.size()){
174  std::cerr << "Number of shifts not equal to number of shift labels. Ignoring shifts." << std::endl;
175  return false;
176  }
177 
178  fShifts = shifts;
179  fShift_labels = shift_labels;
180 
181  fNShifts = fShifts.size();
182 
183  return true;
184 }
185 
186 bool ana::SpectrumHandler::SetHistAxes(const std::vector<HistAxis> haxes, const std::vector<std::string> haxis_labels){
188  throw std::runtime_error("Attempt to set the vars too late. The spectrums are either ready, or already had go() called on them.");
189 
190  if (haxes.size() != haxis_labels.size()){
191  std::cerr << "Number of HistAxis not equal to number of HistAxis labels. Ignoring HistAxes." << std::endl;
192  return false;
193  }
194 
195  fHistAxes = haxes;
196  fHistAxis_labels = haxis_labels;
197 
198  fNHistAxes = fHistAxes.size();
199 
200  return true;
201 }
202 
204  if (fStatus != kSpecHelpLoaders)
205  return false;
206  bool loadersgood = fLoaders.size() && fLoaders.size() == fLoader_labels.size();
207  bool varsgood = fVars.size() > 0 && fVars.size() == fVar_labels.size() && fVars.size() == fVar_titles.size() && fVars.size() == fVar_bins.size();
208  bool histaxesgood = fHistAxes.size() > 0 && fHistAxes.size() == fHistAxis_labels.size();
209  bool cutsgood = fCuts.size() > 0 && fCuts.size() == fCut_labels.size();
210  bool weightsgood = fWeights.size() > 0 && fWeight_labels.size() == fWeights.size();
211  bool shiftsgood = fShifts.size() > 0 && fShift_labels.size() == fShifts.size();
212 
213  bool allready = loadersgood && (varsgood || histaxesgood) && cutsgood && weightsgood && shiftsgood;
214  if (allready)
216  return allready;
217 }
218 
220  if (fStatus != kSpecHelpReady){
221  if (fStatus != kSpecHelpLoaders || !this->CheckReady()){
222  std::cerr << "Not ready to create spectrums. Doing nothing..." << std::endl;
223  return false;
224  } // We just checked that we had a loader, and CheckReady() returned true. Can continue.
225  assert(fStatus == kSpecHelpReady); // Now we KNOW it is ready... right?
226  }
227 
228  unsigned long numSpec = fNLoaders * (fNVars + fNHistAxes) * fNCuts * fNWeights * fNShifts;
229  std::cout << "Spectrum Helper: Creating all spectrum definitions.\n\tThere are a total of " << std::to_string(numSpec) << " Spectrums from:" <<
230  "\n\tLoaders: " << std::to_string(fNLoaders) <<
231  "\n\tVars: " << std::to_string(fNVars) <<
232  "\n\tHistAxes: " << std::to_string(fNHistAxes) <<
233  "\n\tCuts: " << std::to_string(fNCuts) <<
234  "\n\tWeights: " << std::to_string(fNWeights) <<
235  "\n\tShifts: " << std::to_string(fNShifts) << std::endl;
236 
239 
241 
242  return true;
243 }
244 
246  // Loop through loaders
247  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++){
248  std::vector<std::vector<std::vector<std::vector<Spectrum* > > > > lspecs;
249  // Loop through vars
250  for (unsigned int ivar = 0; ivar < fNVars; ivar++){
251  std::vector<std::vector<std::vector<Spectrum* > > > vspecs;
252  // Loop through cuts
253  for (unsigned int icut = 0; icut < fNCuts; icut++){
254  std::vector<std::vector<Spectrum* > > cspecs;
255  // Now some actual logic.
256  for (unsigned int iweight = 0; iweight < fNWeights; iweight++){
257  std::vector<Spectrum* > wspecs;
258  // Loop through shifts
259  for (unsigned int ishift = 0; ishift < fNShifts; ishift++)
260  wspecs.push_back(new Spectrum(
261  fVar_titles[ivar],
262  fVar_bins[ivar],
263  *fLoaders[iloader],
264  fVars[ivar],
265  fCuts[icut],
266  fShifts[ishift],
267  fWeights[iweight] ));
268  cspecs.push_back(wspecs);
269  }
270  vspecs.push_back(cspecs);
271  }
272  lspecs.push_back(vspecs);
273  }
274  fSpecs.push_back(lspecs); // Put into the actual spec holder (5D std::vector: loader -> var -> cut -> weight -> shift)
275  }
276 }
277 
279  // Loop through loaders
280  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++){
281  std::vector<std::vector<std::vector<std::vector<Spectrum* > > > > lspecs;
282  // Loop through vars
283  for (unsigned int ihaxis = 0; ihaxis < fNHistAxes; ihaxis++){
284  std::vector<std::vector<std::vector<Spectrum* > > > hspecs;
285  // Loop through cuts
286  for (unsigned int icut = 0; icut < fNCuts; icut++){
287  std::vector<std::vector<Spectrum* > > cspecs;
288  // Now some actual logic.
289  for (unsigned int iweight = 0; iweight < fNWeights; iweight++){
290  std::vector<Spectrum* > wspecs;
291  // Loop through shifts
292  for (unsigned int ishift = 0; ishift < fNShifts; ishift++)
293  wspecs.push_back(new Spectrum(
294  *fLoaders[iloader],
295  fHistAxes[ihaxis],
296  fCuts[icut],
297  fShifts[ishift],
298  fWeights[iweight] ));
299  cspecs.push_back(wspecs);
300  }
301  hspecs.push_back(cspecs);
302  }
303  lspecs.push_back(hspecs);
304  }
305  fHistAxisSpecs.push_back(lspecs); // Put into the actual spec holder (5D std::vector: loader -> var -> cut -> weight -> shift)
306  }
307 }
308 
310  if (fStatus != kSpecHelpReady){
311  std::cerr << "You didn't create any spectrums yet." << std::endl;
312  return false;
313  }
314  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++){
315  SpectrumLoaderBase * loader = fLoaders[iloader];
316  if (!loader || loader == NULL)
317  throw std::runtime_error("Trying to call Go() on Loader[" + std::to_string(iloader) + "], which was not defined.");
318  else if (loader->Gone()){
319  std::cout << "Loader: \"" + fLoader_labels[iloader] + "\" has already Gone() (likely by another instance of SpectrumHandler)." << std::endl;
320  continue;
321  }
322  fLoaders[iloader]->Go();
323  }
324 
326  return true;
327 }
328 
330  if (fStatus == kSpecHelpUnloaded){
331  std::cerr << "No loaders have been set yet." << std::endl;
332  return false;
333  }
334  // Loop throuh all loaders
335  for (SpectrumLoaderBase * l : fLoaders)
336  // If any loader has had Go() already called, return true
337  if (l->Gone())
338  return true;
339 
340  // No loaders had Go() called yet.
341  return false;
342 }
343 
345  if (fStatus != kSpecHelpWent){
346  std::cerr << "You didn't create the spectrums and fill them yet!!! Create them, and call Go() on loaders." << std::endl;
347  return false;
348  }
349  // Check file exists, is writable here?
350  if (!fout || fout == NULL || fout->IsZombie()){
351  std::cerr << "File not writable. Aborting save." << std::endl;
352  return false;
353  }
354 
355  // Only loop through loaders once to prevent trying to make directories twice
356  for (unsigned int iloader = 0; iloader < fNLoaders; iloader++){
357  // Switch to the top-level directory of the output file.
358  fout->cd();
359  TDirectory* loaderDir = fout->GetDirectory("/");
360 
361  // If multiple loaders, each gets its own directory for simplicity.
362  if (fLoader_labels.size() > iloader && !fLoader_labels[iloader].empty())
363  loaderDir = fout->mkdir(fLoader_labels[iloader].c_str());
364 
365  SaveVarSpectrums(loaderDir, iloader);
366  SaveHistAxisSpectrums(loaderDir, iloader);
367 
368  } // End loop through loaders
369 
370  return true;
371 }
372 
373 void ana::SpectrumHandler::SaveVarSpectrums(TDirectory * loaderDir, unsigned int iloader){
374  // Loop through vars
375  for (unsigned int ivar = 0; ivar < fNVars; ivar++){
376  std::string vlabel = fVar_labels[ivar];
377 
378  // Loop through cuts
379  for (unsigned int icut = 0; icut < fNCuts; icut++){
380  std::string clabel = fCut_labels[icut];
381 
382  // Loop through weights
383  for (unsigned int iweight = 0; iweight < fNWeights; iweight++){
384  std::string wlabel = fWeight_labels[iweight];
385 
386  // Loop through shifts
387  for (unsigned int ishift = 0; ishift < fNShifts; ishift++){
388  std::string slabel = fShift_labels[ishift];
389 
390  std::string specname = vlabel + "_" + clabel;
391  if (!wlabel.empty())
392  specname = specname + "_" + wlabel;
393  if (!slabel.empty())
394  specname = specname + "_" + slabel;
395 
396  fSpecs[iloader][ivar][icut][iweight][ishift]->SaveTo(loaderDir, specname);
397 
398  }
399 
400  }
401  }
402  }
403 }
404 
405 void ana::SpectrumHandler::SaveHistAxisSpectrums(TDirectory * loaderDir, unsigned int iloader){
406  // Loop through hist axes
407  for (unsigned int ihaxis = 0; ihaxis < fNHistAxes; ihaxis++){
408  std::string hlabel = fHistAxis_labels[ihaxis];
409 
410  // Loop through cuts
411  for (unsigned int icut = 0; icut < fNCuts; icut++){
412  std::string clabel = fCut_labels[icut];
413 
414  // Loop through weights
415  for (unsigned int iweight = 0; iweight < fNWeights; iweight++){
416  std::string wlabel = fWeight_labels[iweight];
417 
418  // Loop through shifts
419  for (unsigned int ishift = 0; ishift < fNShifts; ishift++){
420  std::string slabel = fShift_labels[ishift];
421 
422  std::string specname = hlabel + "_" + clabel;
423  if (!wlabel.empty())
424  specname = specname + "_" + wlabel;
425  if (!slabel.empty())
426  specname = specname + "_" + slabel;
427 
428  fHistAxisSpecs[iloader][ihaxis][icut][iweight][ishift]->SaveTo(loaderDir, specname);
429 
430  }
431 
432  }
433  }
434  }
435 }
std::vector< std::string > fHistAxis_labels
std::vector< Binning > fVar_bins
std::vector< Var > fWeights
SpectrumLoaderBase * GetLoader(const std::string label)
bool SaveSpectrums(TFile *f)
bool SetVars(const std::vector< Var > v, const std::vector< std::string > vl, const std::vector< std::string > vt, const std::vector< Binning > vb)
bool SetShifts(const std::vector< SystShifts > s, const std::vector< std::string > sl)
OStream cerr
Definition: OStream.cxx:7
std::vector< SpectrumLoaderBase * > fLoaders
std::vector< std::string > fWeight_labels
bool SetSpillCuts(const std::vector< SpillCut > spillcuts)
std::vector< std::string > cut_labels
Representation of a spectrum in any variable, with associated POT.
Definition: Spectrum.h:40
const char * label
std::vector< Cut > fCuts
void SaveVarSpectrums(TDirectory *d, unsigned int il)
std::vector< std::string > fShift_labels
std::vector< SpectrumLoaderBase * > GetLoaders(const std::vector< std::string > labels)
Var weights
std::vector< std::string > fVar_titles
const std::map< std::pair< std::string, std::string >, Variable > vars
loader
Definition: demo0.py:10
void SaveHistAxisSpectrums(TDirectory *d, unsigned int il)
bool SetHistAxes(const std::vector< HistAxis > h, const std::vector< std::string > hl)
std::vector< SystShifts > fShifts
OStream cout
Definition: OStream.cxx:6
std::vector< std::string > fVar_labels
bool SetLoaders(const std::vector< std::string > &ds, const std::vector< std::string > &dsnames)
Base class for the various types of spectrum loader.
const Cut cut
Definition: exporter_fd.C:30
Collaborates with Spectrum and OscillatableSpectrum to fill spectra from CAF files.
std::vector< Loaders * > loaders
Definition: syst_header.h:386
std::vector< std::vector< std::vector< std::vector< std::vector< Spectrum * > > > > > fSpecs
assert(nhit_max >=nhit_nbins)
std::vector< std::vector< std::vector< std::vector< std::vector< Spectrum * > > > > > fHistAxisSpecs
std::vector< std::string > fLoader_labels
std::vector< HistAxis > fHistAxes
std::string to_string(ModuleType mt)
Definition: ModuleType.h:32
Template for Cut and SpillCut.
Definition: Cut.h:15
std::vector< std::string > fCut_labels
bool SetCuts(const std::vector< Cut > c, const std::vector< std::string > cl)
std::vector< Dataset > datasets
Definition: Periods.h:3
virtual bool Gone() const
Indicate whether or not Go has been called.
bool SetWeights(const std::vector< Var > w, const std::vector< std::string > wl)
std::vector< Var > fVars
enum BeamMode string