LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
EvtTimeFNALBeam.cxx
Go to the documentation of this file.
1 
35 #include "EvtTimeFNALBeam.h"
36 #include "EvtTimeShiftFactory.h"
38 
39 #include <iostream>
40 #include <iomanip>
41 #include <algorithm>
42 
43 //GENIE includes
44 #ifdef GENIE_PRE_R3
45  #include "GENIE/Utils/StringUtils.h"
46 #else
47  #include "GENIE/Framework/Utils/StringUtils.h"
48 #endif
50 #include "cetlib_except/exception.h"
51 
52 const double ksigma2fwhm = 2.0*std::sqrt(2.0*std::log(2.0));
53 
54 namespace evgb {
55 
56  EvtTimeFNALBeam::EvtTimeFNALBeam(const std::string& config)
57  // default to a NuMI config
58  : EvtTimeShiftI(config)
59  , fTimeBetweenBuckets(1e9/53.103e6)
60  , fBucketTimeSigma(0.750)
61  , fNBucketsPerBatch(84) // NOvA-era 81+3, MINOS-era 81+5
62  , fNFilledBucketsPerBatch(81) // 81 for both eras
63  , fDisallowedBatchMask(6,0) // don't disallow any
64  , fGlobalOffset(0)
65  {
66  std::vector<double> bi(6,1.0); // 6 equal batches
68  Config(config);
69  }
70 
72 
73  void EvtTimeFNALBeam::Config(const std::string& config)
74  {
75  // parse config string
76  if ( config == "" ) return;
77  // GENIEHelper does a PrintConfig() when it gets this object ...
78 
79  // not the most sophisticated of parsing ... but FHICL would be overkill
80 
81  std::vector<std::string> strs = GetConfigTokens(config);
82  // strings have all been tokenized and made lowercase
83 
84  size_t nstrs = strs.size();
85  for (size_t i=0; i<nstrs; ++i) {
86  if ( strs[i] == "numi" ) {
87  fTimeBetweenBuckets = 1e9/53.103e6;
88  fBucketTimeSigma = 0.750;
89  fNBucketsPerBatch = 84; // NOvA-era 81+3, MINOS-era 81+5
90  fNFilledBucketsPerBatch = 81; // 81 for both eras
91  fDisallowedBatchMask = std::vector<int>(6,0); // don't disallow any
92  fGlobalOffset = 0;
93  std::vector<double> bi(6,1.0); // 6 equal batches
95  } else
96  if ( strs[i] == "booster" ) {
97  fTimeBetweenBuckets = 1e9/53.103e6;
98  fBucketTimeSigma = 2.0;
99  fNBucketsPerBatch = 84; //
100  fNFilledBucketsPerBatch = 81; //
101  fDisallowedBatchMask = std::vector<int>(1,0); // don't disallow any
102  fGlobalOffset = 0;
103  std::vector<double> bi(1,1.0); // 1 batch
105  } else
106  if ( strs[i].find("intensity") != std::string::npos ) {
107  // a list of batch intensities ... sets # of batches
108  // eat values up until we see the end, or a word
109  std::vector<double> bi;
110  // count how many of next tokens are numbers (crude)
111  for (size_t jj=i+1; jj<nstrs; ++jj) {
112  // very crude check of being a number
113  // can be fooled by strange text
114  size_t pos = strs[jj].find_first_not_of("0123456789.-+eE");
115  if ( pos != std::string::npos ) break;
116  // looks like a numeric value
117  double val = atof(strs[jj].c_str());
118  if ( val < 0 ) {
119  mf::LogError("EvtTime")
120  << "EvtTimeFNALBeam 'intensity' value [" << (jj-i-1)
121  << "]=" << val << " '" << strs[jj] << "' "
122  << "can't be less than zero, setting to zero";
123  val = 0;
124  }
125  bi.push_back(val);
126  }
127  // ate up some strings ... move loop index
128  i += bi.size();
129  if ( bi.empty() ) {
130  mf::LogError("EvtTime")
131  << "EvtTimeFNALBeam error 'intensity' option didn't seem to have values";
132  } else {
134  }
135  } else
136  if ( strs[i] == "bdisallowed" ) {
137  mf::LogError("EvtTime")
138  << "EvtTimeFNALBeam sorry 'bdisallowed' option not yet implemented";
139  } else {
140  // all the rest take one numeric value
141  if ( i+1 >= nstrs ) {
142  mf::LogError("EvtTime")
143  << "EvtTimeFNALBeam sorry too few values for '" << strs[i] << "'";
144  continue;
145  }
146  const char* arg = strs[i+1].c_str();
147  if ( strs[i] == "sigma" ) fBucketTimeSigma = atof(arg);
148  else if ( strs[i] == "fwhm" ) fBucketTimeSigma = atof(arg)/ksigma2fwhm;
149  else if ( strs[i] == "dtbucket" ) fTimeBetweenBuckets = atof(arg);
150  else if ( strs[i] == "nperbatch" ) fNBucketsPerBatch = atoi(arg);
151  else if ( strs[i] == "nfilled" ) fNFilledBucketsPerBatch = atoi(arg);
152  else if ( strs[i] == "global" ) fGlobalOffset = atof(arg);
153  else if ( strs[i] == "seed" ) { ; } // handled in base
154  else {
155  mf::LogError("EvtTime")
156  << "unknown EvtTimeFNALBeam config key '" << strs[i] << "'";
157  continue;
158  }
159  ++i; // used up an argument
160  }
161  }
162  // consistency check
164  mf::LogError("EvtTime")
165  << "EvtTimeFNALBeam nfilled " << fNFilledBucketsPerBatch
166  << " of " << fNBucketsPerBatch << " buckets per batch,\n"
167  << "set nfilled to match buckets per batch";
169  }
170 
171  }
172 
174  {
175  // calculate in small to large
176 
177  // pick a time within a bucket
178  double offset = fRndmGen->Gaus(0.0,fBucketTimeSigma);
179 
180  // pick a bucket within a batch
181  // assume all ~ buckets constant in batch until we have another model
182  offset += fTimeBetweenBuckets *
183  (double)fRndmGen->Integer(fNFilledBucketsPerBatch);
184 
185  // pick a bucket
186  bool disallowed = true;
187  size_t ibatch = 0;
188  size_t nbatch = fCummulativeBatchPDF.size();
189  double r = 2;
190  while ( disallowed ) {
191  r = fRndmGen->Uniform();
192  for (ibatch=0; ibatch<nbatch; ++ibatch) {
193  if ( r <= fCummulativeBatchPDF[ibatch] ) break;
194  }
195  disallowed = ( fDisallowedBatchMask[ibatch] != 0 );
196  }
197  offset += fTimeBetweenBuckets*(double)fNBucketsPerBatch*(double)ibatch;
198 
199  // finally the global offset
200  return offset + fGlobalOffset;
201  }
202 
203  double EvtTimeFNALBeam::TimeOffset(std::vector<double> bi)
204  {
205  CalculateCPDF(bi);
206  return TimeOffset();
207  }
208 
209  void EvtTimeFNALBeam::PrintConfig(bool /* verbose */)
210  {
211 
212  std::ostringstream msg;
213  msg << "EvtTimeFNALBeam config: \n"
214  << " TimeBetweenBuckets: " << fTimeBetweenBuckets << " ns\n"
215  << " BucketTimeSigma: " << fBucketTimeSigma << " ns "
216  << "[FWHM " << fBucketTimeSigma*ksigma2fwhm << "]\n"
217  << " NBucketsPerBatch: " << fNBucketsPerBatch << "\n"
218  << " NFilledBucketsPerBatch: " << fNFilledBucketsPerBatch << "\n"
219  << " Relative Fractions: ";
220  double prev=0;
221  for (size_t i=0; i < fCummulativeBatchPDF.size(); ++i) {
222  double frac = fCummulativeBatchPDF[i] - prev;
223  bool skip = fDisallowedBatchMask[i];
224  msg << " ";
225  if (skip) msg << "{{";
226  msg << frac;
227  if (skip) msg << "}}";
228  prev = fCummulativeBatchPDF[i];
229  }
230  msg << "\n"
231  << " GlobalOffset: " << fGlobalOffset << " ns\n";
232 
233  mf::LogInfo("EvtTime") << msg.str();
234  }
235 
236 
237  void EvtTimeFNALBeam::SetBatchIntensities(std::vector<double> bi)
238  {
239  CalculateCPDF(bi);
240  }
241 
242  void EvtTimeFNALBeam::SetDisallowedBatchMask(std::vector<int> disallow)
243  {
244  size_t ndis = disallow.size();
245  size_t nbi = fCummulativeBatchPDF.size();
246  fDisallowedBatchMask = disallow;
247  // expand it so it's mirrors # of batch intensities
248  // but allow all that haven't been set
249  if ( nbi > ndis ) fDisallowedBatchMask.resize(nbi,0);
250  }
251 
252  void EvtTimeFNALBeam::CalculateCPDF(std::vector<double> bi)
253  {
254  fCummulativeBatchPDF.clear();
255  double sum = 0;
256  size_t nbi = bi.size();
257  for (size_t i=0; i < nbi; ++i) {
258  sum += bi[i];
259  fCummulativeBatchPDF.push_back(sum);
260  }
261  // normalize to unit probability
262  for (size_t i=0; i < nbi; ++i) fCummulativeBatchPDF[i] /= sum;
263  // make sure the mask vector keeps up (but never make it smaller)
264  // allowing all new batches
265  if ( nbi > fDisallowedBatchMask.size() )
266  fDisallowedBatchMask.resize(nbi,0);
267 
268  /*
269  for (size_t j=0; j<nbi; ++j) {
270  std::cout << " CPDF[" << j << "] " << fCummulativeBatchPDF[j]
271  << " " << ((fDisallowedBatchMask[j])?"dis":"") << "allowed"
272  << std::endl;
273  }
274  */
275 
276  }
277 
278 
279 } // namespace evgb
TRandom r
Definition: spectrum.C:23
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void SetBatchIntensities(std::vector< double > bi)
double fGlobalOffset
always displaced by this (in ns)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
configurable FNAL Beam time distribution
EvtTimeFNALBeam(const std::string &config)
const double ksigma2fwhm
double fBucketTimeSigma
how wide is distribution in bucket
interface for event time distribution
Definition: EvtTimeShiftI.h:29
virtual void PrintConfig(bool verbose=true)
provide a means of printing the configuration
void CalculateCPDF(std::vector< double > batchi)
std::vector< std::string > GetConfigTokens(const std::string &config)
virtual void Config(const std::string &config)
virtual double TimeOffset()
std::vector< int > fDisallowedBatchMask
disallow individual batches
double fTimeBetweenBuckets
time between buckets
A class for generating concrete EvtTimeShiftI derived classes based on the factory pattern...
Physics generators for neutrinos, cosmic rays, and others.
Definition: CRYHelper.cxx:33
Double_t sum
Definition: plot.C:31
std::vector< double > fCummulativeBatchPDF
summed prob for batches
void SetDisallowedBatchMask(std::vector< int > disallow)
#define TIMESHIFTREG3(_ns, _name, _fqname)