ExposureSource.cxx
Go to the documentation of this file.
2 
4 
6 
7 #include <iostream>
8 #include <map>
9 
10 namespace ana
11 {
12  // --------------------------------------------------------------------------
14  {
15  if(!fFinalized && !fCuts.empty()){
16  std::cout << "ExposureSource destroyed without Finalize() being called" << std::endl;
17  abort();
18  }
19  }
20 
21  // --------------------------------------------------------------------------
23  {
25 
26  // It's more important that we can iterate fast in HandleSpill() than that
27  // this function is fast.
28 
29  for(auto& it: fCuts){
30  if(it.first.ID() == cut.ID()){
31  it.second.sinks.push_back(s);
32  return;
33  }
34  }
35 
36  fCuts.push_back(std::make_pair(cut, CutDetails()));
37  fCuts.back().second.sinks.push_back(s);
38  }
39 
40  // --------------------------------------------------------------------------
42  {
44 
45  for(auto& it: fCuts){
46  const Cut& cut = it.first;
47  double pot = cut.POT(spill);
48  // Not implemented -> fall back to usual counting
49  if(pot < 0) pot = spill->spillpot;
50 
51 
52  // FD MC is 1 neutrino-per-event, so the livetime count will be all
53  // screwed up there. Just go with 0, ie "unknown".
54  double livetime = 0;
55  if(spill->det != caf::kFARDET || !spill->ismc) // TODO || fSource == kCosmic)
56  livetime = cut.Livetime(spill);
57 
58  // Not implemented -> no good way to count
59  if(livetime < 0){
60  if(spill->det == caf::kFARDET && !spill->ismc){
61  // People might well expect FD data to have a livetime. Warn.
62  static bool once = true;
63  if(once){
64  once = false;
65  std::cout << "WARNING: no way to compute livetime for FD data spectrum. If you want a livetime you need to be applying one of the cuts from TimingCuts.h or similar. You probably should be anyway to remove bad data near the spill ends." << std::endl;
66  }
67  }
68  // Otherwise the user probably doesn't care. Just don't sum it into the
69  // livetime
70  livetime = 0;
71  }
72 
73  it.second.pot += pot;
74  it.second.livetime += livetime;
75  }
76  }
77 
78  //----------------------------------------------------------------------
80  {
81  if(fFinalized){
82  std::cout << "ExposureSource::Finalize() called twice!" << std::endl;
83  abort();
84  }
85 
86  for(auto& it: fCuts){
87  for(IExposureSink* s: it.second.sinks){
88  s->HandlePOT(it.second.pot);
89  s->HandleLivetime(it.second.livetime);
90  }
91  }
92 
93  fFinalized = true;
94  }
95 
96  //----------------------------------------------------------------------
97  void POTPlusPercent(std::ostream& os, double pot, double denom)
98  {
99  os << pot << " POT";
100  if(denom != 0) os << " (" << int(100*pot/denom+.5)<< "%)";
101  }
102 
103  //----------------------------------------------------------------------
104  void ExposureSource::ReportExposures(double denom) const
105  {
106  std::cout << "Total exposure:" << std::endl;
107 
108  // Normally using a floating-point number as a key is a bad idea. But this
109  // seems to work, and if it goes wrong all it breaks is this printout.
110  std::map<double, int> livetimes;
111  std::map<double, int> pots;
112  for(auto it: fCuts){
113  livetimes[it.second.livetime] += it.second.sinks.size();
114  pots[it.second.pot] += it.second.sinks.size();
115  }
116 
117  if(pots.size() == 1){
118  std::cout << " ";
119  POTPlusPercent(std::cout, pots.begin()->first, denom);
120  std::cout << std::endl;
121  }
122  else{
123  for(auto it: pots){
124  std::cout << " ";
125  POTPlusPercent(std::cout, pots.begin()->first, denom);
126  std::cout << " for " << it.second << " spectra" << std::endl;
127  }
128  }
129 
130  if(livetimes.size() == 1){
131  if(livetimes.begin()->first == 0){
132  std::cout << " Unknown livetime" << std::endl;
133  }
134  else{
135  std::cout << " " << livetimes.begin()->first << " seconds" << std::endl;
136  }
137  }
138  else{
139  for(auto it: livetimes){
140  std::cout << " " << it.first << " seconds for " << it.second << " spectra" << std::endl;
141  }
142  }
143  }
144 }
Far Detector at Ash River.
Definition: SREnums.h:11
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
set< int >::iterator it
void HandleSpill(const caf::SRSpillProxy *spill) override
double Livetime(const caf::SRSpillProxy *spill) const
Provide a Livetime function if your cut is a timing cut etc.
Definition: Cut.h:39
int pots
caf::Proxy< float > spillpot
Definition: SRProxy.h:1407
double POT(const caf::SRSpillProxy *spill) const
Could be useful for cuts on specific batches?
Definition: Cut.h:45
std::pair< Spectrum *, CheatDecomp * > make_pair(SpectrumLoaderBase &loader_data, SpectrumLoaderBase &loader_mc, HistAxis *axis, Cut *cut, const SystShifts &shift, const Var &wei)
Definition: DataMCLoad.C:336
void AddSink(const Cut &cut, IExposureSink *s)
const XML_Char * s
Definition: expat.h:262
#define pot
int ID() const
Cuts with the same definition will have the same ID.
Definition: Cut.h:55
void POTPlusPercent(std::ostream &os, double pot, double denom)
virtual void HandleLivetime(double expo)=0
Proxy for caf::SRSpill.
Definition: SRProxy.h:1346
OStream cout
Definition: OStream.cxx:6
const Cut cut
Definition: exporter_fd.C:30
std::vector< std::pair< Cut, CutDetails > > fCuts
virtual void HandlePOT(double pot)=0
double livetime
Definition: saveFDMCHists.C:21
caf::Proxy< caf::Det_t > det
Definition: SRProxy.h:1361
caf::Proxy< bool > ismc
Definition: SRProxy.h:1378
assert(nhit_max >=nhit_nbins)
void Finalize()
POT/livetime is not filled into sinks until this is called!
void ReportExposures(double denom=0) const