SPhaseChannelNoiseService_service.cc
Go to the documentation of this file.
1 // SPhaseChannelNoiseService.cxx
2 // Jingbo Wang
3 // January 2019
4 
7 #include <sstream>
11 #include "nurandom/RandomUtils/NuRandomService.h"
12 #include "art_root_io/TFileService.h"
13 #include "CLHEP/Random/JamesRandom.h"
14 #include "CLHEP/Random/RandFlat.h"
15 #include "CLHEP/Random/RandGauss.h"
16 #include "TH1F.h"
17 #include "TRandom3.h"
18 #include "TF1.h"
19 #include "TMath.h"
20 
21 using std::cout;
22 using std::ostream;
23 using std::endl;
24 using std::string;
25 using std::ostringstream;
26 using rndm::NuRandomService;
27 using CLHEP::HepJamesRandom;
28 
29 //**********************************************************************
30 
33 : fRandomSeed(0), fLogLevel(1),
34  fGausNoiseHistZ(nullptr), fGausNoiseHistU(nullptr), fGausNoiseHistV(nullptr),
35  fGausNoiseChanHist(nullptr),
36  fMicroBooNoiseHistZ(nullptr), fMicroBooNoiseHistU(nullptr), fMicroBooNoiseHistV(nullptr),
37  fMicroBooNoiseChanHist(nullptr),
38  fCohNoiseHist(nullptr), fCohNoiseChanHist(nullptr),
39  m_pran(nullptr) {
40  const string myname = "SPhaseChannelNoiseService::ctor: ";
41  fNoiseArrayPoints = pset.get<unsigned int>("NoiseArrayPoints");
42  bool haveSeed = pset.get_if_present<int>("RandomSeed", fRandomSeed);
43 
44  fEnableWhiteNoise = pset.get<bool>("EnableWhiteNoise");
45  fWhiteNoiseZ = pset.get<double>("WhiteNoiseZ");
46  fWhiteNoiseU = pset.get<double>("WhiteNoiseU");
47  fWhiteNoiseV = pset.get<double>("WhiteNoiseV");
48 
49  fEnableGaussianNoise = pset.get<bool>("EnableGaussianNoise");
50  fGausNormU = pset.get<std::vector<float>>("GausNormU");
51  fGausMeanU = pset.get<std::vector<float>>("GausMeanU");
52  fGausSigmaU = pset.get<std::vector<float>>("GausSigmaU");
53  fGausNormV = pset.get<std::vector<float>>("GausNormV");
54  fGausMeanV = pset.get<std::vector<float>>("GausMeanV");
55  fGausSigmaV = pset.get<std::vector<float>>("GausSigmaV");
56  fGausNormZ = pset.get<std::vector<float>>("GausNormZ");
57  fGausMeanZ = pset.get<std::vector<float>>("GausMeanZ");
58  fGausSigmaZ = pset.get<std::vector<float>>("GausSigmaZ");
59 
60  fEnableMicroBooNoise = pset.get<bool>("EnableMicroBooNoise");
61  fENOB = pset.get<double>("EffectiveNBits");
62  fWirelengthZ = pset.get<double>("WireLengthZ");
63  fWirelengthU = pset.get<double>("WireLengthU");
64  fWirelengthV = pset.get<double>("WireLengthV");
65  fNoiseFunctionParameters = pset.get<std::vector<float>>("NoiseFunctionParameters");
66 
67  fEnableCoherentNoise = pset.get<bool>("EnableCoherentNoise");
68  fCohNoiseArrayPoints = pset.get<unsigned int>("CohNoiseArrayPoints");
69  fCohExpNorm = pset.get<float>("CohExpNorm");
70  fCohExpWidth = pset.get<float>("CohExpWidth");
71  fCohExpOffset = pset.get<float>("CohExpOffset");
72  fCohGausNorm = pset.get<std::vector<float>>("CohGausNorm");
73  fCohGausMean = pset.get<std::vector<float>>("CohGausMean");
74  fCohGausSigma = pset.get<std::vector<float>>("CohGausSigma");
75  fNChannelsPerCoherentGroup = pset.get<unsigned int>("NChannelsPerCoherentGroup");
76 
77  if ( fRandomSeed == 0 ) haveSeed = false;
78  pset.get_if_present<int>("LogLevel", fLogLevel);
79  int seed = fRandomSeed;
81  fMicroBooNoiseHistZ = tfs->make<TH1F>("MicroBoo znoise", ";Z Noise [ADC counts];", 1000, -10., 10.);
82  fMicroBooNoiseHistU = tfs->make<TH1F>("MicroBoo unoise", ";U Noise [ADC counts];", 1000, -10., 10.);
83  fMicroBooNoiseHistV = tfs->make<TH1F>("MicroBoo vnoise", ";V Noise [ADC counts];", 1000, -10., 10.);
84  fMicroBooNoiseChanHist = tfs->make<TH1F>("MicroBoo NoiseChan", ";MicroBoo Noise channel;", fNoiseArrayPoints, 0, fNoiseArrayPoints);
85  fGausNoiseHistZ = tfs->make<TH1F>("Gaussian znoise", ";Z Noise [ADC counts];", 1000, -10., 10.);
86  fGausNoiseHistU = tfs->make<TH1F>("Gaussian unoise", ";U Noise [ADC counts];", 1000, -10., 10.);
87  fGausNoiseHistV = tfs->make<TH1F>("Gaussian vnoise", ";V Noise [ADC counts];", 1000, -10., 10.);
88  fGausNoiseChanHist = tfs->make<TH1F>("Gaussian NoiseChan", ";Gaussian Noise channel;", fNoiseArrayPoints, 0, fNoiseArrayPoints);
89  fCohNoiseHist = tfs->make<TH1F>("Cohnoise", ";Coherent Noise [ADC counts];", 1000, -10., 10.);
90  fCohNoiseChanHist = tfs->make<TH1F>("CohNoiseChan", ";CohNoise channel;", fCohNoiseArrayPoints, 0, fCohNoiseArrayPoints);// III = for each instance of this class.
91  string rname = "SPhaseChannelNoiseService";
92  if ( haveSeed ) {
93  if ( fLogLevel > 0 ) cout << myname << "WARNING: Using hardwired seed." << endl;
94  m_pran = new HepJamesRandom(seed);
95  } else {
96  if ( fLogLevel > 0 ) cout << myname << "Using NuRandomService." << endl;
98  m_pran = new HepJamesRandom;
99  if ( fLogLevel > 0 ) cout << myname << " Initial seed: " << m_pran->getSeed() << endl;
100  seedSvc->registerEngine(NuRandomService::CLHEPengineSeeder(m_pran), rname);
101  }
102  if ( fLogLevel > 0 ) cout << myname << " Registered seed: " << m_pran->getSeed() << endl;
103  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
104  generateNoise(clockData);
105  if ( fLogLevel > 1 ) print() << endl;
106 }
107 
108 //**********************************************************************
109 
112 : SPhaseChannelNoiseService(pset) { }
113 
114 //**********************************************************************
115 
117  const string myname = "SPhaseChannelNoiseService::dtor: ";
118  if ( fLogLevel > 0 ) {
119  cout << myname << "Deleting random engine with seed " << m_pran->getSeed() << endl;
120  }
121  delete m_pran;
122 }
123 
124 //**********************************************************************
125 
128  Channel chan, AdcSignalVector& sigs) const {
129  CLHEP::RandFlat flat(*m_pran);
130  CLHEP::RandGauss gaus(*m_pran);
131 
132  unsigned int microbooNoiseChan = flat.fire()*fNoiseArrayPoints;
133  if ( microbooNoiseChan == fNoiseArrayPoints ) --microbooNoiseChan;
134  fMicroBooNoiseChanHist->Fill(microbooNoiseChan);
135 
136  unsigned int gausNoiseChan = flat.fire()*fNoiseArrayPoints;
137  if ( gausNoiseChan == fNoiseArrayPoints ) --gausNoiseChan;
138  fGausNoiseChanHist->Fill(gausNoiseChan);
139 
140  unsigned int cohNoisechan = -999;
141  unsigned int groupNum = -999;
142  if ( fEnableCoherentNoise ) {
143  groupNum = getGroupNumberFromOfflineChannel(chan);
144  cohNoisechan = getCohNoiseChanFromGroup(groupNum);
145  if ( cohNoisechan == fCohNoiseArrayPoints ) cohNoisechan = fCohNoiseArrayPoints-1;
146  fCohNoiseChanHist->Fill(cohNoisechan);
147  }
148 
150  const geo::View_t view = geo->View(chan);
151  for ( unsigned int itck=0; itck<sigs.size(); ++itck ) {
152  double tnoise = 0;
153  if ( view==geo::kU ) {
154  if(fEnableWhiteNoise) tnoise += fWhiteNoiseU*gaus.fire();
155  if(fEnableMicroBooNoise) tnoise += fMicroBooNoiseU[microbooNoiseChan][itck];
156  if(fEnableGaussianNoise) tnoise += fGausNoiseU[gausNoiseChan][itck];
157  if(fEnableCoherentNoise) tnoise += fCohNoise[cohNoisechan][itck];
158  }
159  else if ( view==geo::kV ) {
160  if(fEnableWhiteNoise) tnoise = fWhiteNoiseV*gaus.fire();
161  if(fEnableMicroBooNoise) tnoise += fMicroBooNoiseV[microbooNoiseChan][itck];
162  if(fEnableGaussianNoise) tnoise += fGausNoiseV[gausNoiseChan][itck];
163  if(fEnableCoherentNoise) tnoise += fCohNoise[cohNoisechan][itck];
164  }
165  else {
166  if(fEnableWhiteNoise) tnoise += fWhiteNoiseZ*gaus.fire();
167  if(fEnableMicroBooNoise) tnoise += fMicroBooNoiseZ[microbooNoiseChan][itck];
168  if(fEnableGaussianNoise) tnoise += fGausNoiseZ[gausNoiseChan][itck];
169  if(fEnableCoherentNoise) tnoise += fCohNoise[cohNoisechan][itck];
170  }
171  sigs[itck] += tnoise;
172  }
173  return 0;
174 }
175 
176 //**********************************************************************
177 
178 ostream& SPhaseChannelNoiseService::print(ostream& out, string prefix) const {
179  out << prefix << "SPhaseChannelNoiseService: " << endl;
180 
181  out << prefix << " LogLevel: " << fLogLevel << endl;
182  out << prefix << " RandomSeed: " << fRandomSeed << endl;
183  out << prefix << " NoiseArrayPoints: " << fNoiseArrayPoints << endl;
184 
185  out << prefix << " EnableWhiteNoise: " << fEnableWhiteNoise << endl;
186  out << prefix << " WhiteNoiseZ: " << fWhiteNoiseZ << endl;
187  out << prefix << " WhiteNoiseU: " << fWhiteNoiseU << endl;
188  out << prefix << " WhiteNoiseV: " << fWhiteNoiseV << endl;
189 
190  out << prefix << "EnableGaussianNoise: " << fEnableGaussianNoise << endl;
191  out << prefix << " GausNormU: [ ";
192  for(int i=0; i<(int)fGausNormU.size(); i++) { out << fGausNormU.at(i) << " ";}
193  out << " ]" << endl;
194  out << prefix << " GausMeanU: [ ";
195  for(int i=0; i<(int)fGausMeanU.size(); i++) { out << fGausMeanU.at(i) << " ";}
196  out << " ]" << endl;
197  out << prefix << " GausSigmaU: [ ";
198  for(int i=0; i<(int)fGausSigmaU.size(); i++) { out << fGausSigmaU.at(i) << " ";}
199  out << " ]" << endl;
200  out << prefix << " GausNormV: [ ";
201  for(int i=0; i<(int)fGausNormV.size(); i++) { out << fGausNormV.at(i) << " ";}
202  out << " ]" << endl;
203  out << prefix << " GausMeanV: [ ";
204  for(int i=0; i<(int)fGausMeanV.size(); i++) { out << fGausMeanV.at(i) << " ";}
205  out << " ]" << endl;
206  out << prefix << " GausSigmaV: [ ";
207  for(int i=0; i<(int)fGausSigmaV.size(); i++) { out << fGausSigmaV.at(i) << " ";}
208  out << " ]" << endl;
209  out << prefix << " GausNormZ: [ ";
210  for(int i=0; i<(int)fGausNormZ.size(); i++) { out << fGausNormZ.at(i) << " ";}
211  out << " ]" << endl;
212  out << prefix << " GausMeanZ: [ ";
213  for(int i=0; i<(int)fGausMeanZ.size(); i++) { out << fGausMeanZ.at(i) << " ";}
214  out << " ]" << endl;
215  out << prefix << " GausSigmaZ: [ ";
216  for(int i=0; i<(int)fGausSigmaZ.size(); i++) { out << fGausSigmaZ.at(i) << " ";}
217  out << " ]" << endl;
218 
219  out << prefix << "EnableMicroBooNoise: " << fEnableMicroBooNoise << endl;
220  out << prefix << " EffectiveNBits: " << fENOB << endl;
221  out << prefix << " WireLengthU: " << fWirelengthU << endl;
222  out << prefix << " WireLengthV: " << fWirelengthV << endl;
223  out << prefix << " WireLengthZ: " << fWirelengthZ << endl;
224 
225  out << prefix << "EnableCoherentNoise: " << fEnableCoherentNoise << endl;
226  out << prefix << "ExpNoiseArrayPoints: " << fExpNoiseArrayPoints << endl;
227  out << prefix << "CohNoiseArrayPoints: " << fCohNoiseArrayPoints << endl;
228  out << prefix << "MicroBoo model parameters: [ ";
229  for(int i=0; i<(int)fNoiseFunctionParameters.size(); i++) { out << fNoiseFunctionParameters.at(i) << " ";}
230  out << " ]" << endl;
231 
232  out << prefix << " CohGausNorm: [ ";
233  for(int i=0; i<(int)fCohGausNorm.size(); i++) { out << fCohGausNorm.at(i) << " ";}
234  out << " ]" << endl;
235  out << prefix << " CohGausMean: [ ";
236  for(int i=0; i<(int)fCohGausMean.size(); i++) { out << fCohGausMean.at(i) << " ";}
237  out << " ]" << endl;
238  out << prefix << " CohGausSigma: [ ";
239  for(int i=0; i<(int)fCohGausSigma.size(); i++) { out << fCohGausSigma.at(i) << " ";}
240  out << " ]" << endl;
241 
242  out << prefix << " Actual random seed: " << m_pran->getSeed();
243  return out;
244 }
245 
246 //**********************************************************************
247 
250  float wirelength, float ENOB,
251  AdcSignalVector& noise, TH1* aNoiseHist) const {
252  const string myname = "SPhaseChannelNoiseService::generateCoherentNoise: ";
253  if ( fLogLevel > 1 ) {
254  cout << myname << "Generating noise." << endl;
255  if ( fLogLevel > 2 ) {
256  cout << myname << " Seed: " << m_pran->getSeed() << endl;
257  }
258  }
259  // Fetch sampling rate.
260  float sampleRate = sampling_rate(clockData);
261  // Fetch FFT service and # ticks.
263  unsigned int ntick = pfft->FFTSize();
264  // width of frequencyBin in kHz
265  double binWidth = 1.0/(ntick*sampleRate*1.0e-6);
266  CLHEP::RandFlat flat(*m_pran);
267  // Create noise spectrum in frequency.
268  unsigned nbin = ntick/2 + 1;
269  std::vector<TComplex> noiseFrequency(nbin, 0.);
270  double pval = 0.;
271  double phase = 0.;
272  double rnd[3] = {0.};
273 
274  ////////////////////////////// MicroBooNE noise model/////////////////////////////////
275  // vars
276  double params[1] = {0.};
277  double fitpar[9] = {0.};
278  double wldparams[2] = {0.};
279 
280  // calculate FFT magnitude of noise from ENOB
281  //double baseline_noise = std::sqrt(ntick*1.0/12)*std::pow(2, 12 - fENOB);
282  // wire length dependence function
283  TF1* _wld_f = new TF1("_wld_f", "[0] + [1]*x", 0.0, 1000);
284  // custom poisson
285  TF1* _poisson = new TF1("_poisson", "[0]**(x) * exp(-[0]) / ROOT::Math::tgamma(x+1.)", 0, 30);
286  // gain function in kHz
287  TF1* _pfn_f1 = new TF1("_pfn_f1", "([0]*1/(x/1000*[8]/2) + ([1]*exp(-0.5*(((x/1000*[8]/2)-[2])/[3])**2)*exp(-0.5*pow(x/1000*[8]/(2*[4]),[5])))*[6]) + [7]", 0.0, 0.5*ntick*binWidth);
288  // set data-driven parameters
289  // poisson mean
290  params[0] = 3.30762;
291  //wire length dependence parameters
292  wldparams[0] = 0.395;
293  wldparams[1] = 0.001304;
294  _wld_f->SetParameters(wldparams);
295  double wldValue = _wld_f->Eval(wirelength);
296  fitpar[0] = fNoiseFunctionParameters.at(0);
297  fitpar[1] = fNoiseFunctionParameters.at(1);
298  fitpar[2] = fNoiseFunctionParameters.at(2);
299  fitpar[3] = fNoiseFunctionParameters.at(3);
300  fitpar[4] = fNoiseFunctionParameters.at(4);
301  fitpar[5] = fNoiseFunctionParameters.at(5);
302  fitpar[6] = wldValue;
303  fitpar[7] = fNoiseFunctionParameters.at(7);
304  fitpar[8] = ntick;
305  _pfn_f1->SetParameters(fitpar);
306  _poisson->SetParameters(params);
307  _pfn_f1->SetNpx(1000);
308 
309  for ( unsigned int i=0; i<ntick/2+1; ++i ) {
310  //MicroBooNE noise model
311  double pfnf1val = _pfn_f1->Eval((i+0.5)*binWidth);
312  // define FFT parameters
313  double randomizer = _poisson->GetRandom()/params[0];
314  pval = pfnf1val * randomizer;
315  // random phase angle
316  flat.fireArray(2, rnd, 0, 1);
317  phase = rnd[1]*2.*TMath::Pi();
318  TComplex tc(pval*cos(phase),pval*sin(phase));
319  noiseFrequency[i] += tc;
320  }
321  // Obtain time spectrum from frequency spectrum.
322  noise.clear();
323  noise.resize(ntick,0.0);
324  std::vector<double> tmpnoise(noise.size());
325  pfft->DoInvFFT(noiseFrequency, tmpnoise);
326  noiseFrequency.clear();
327  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
328  noise[itck] = sqrt(ntick)*tmpnoise[itck];
329  }
330  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
331  aNoiseHist->Fill(noise[itck]);
332  }
333 }
334 
335 //**********************************************************************
336 
339  AdcSignalVector& noise, std::vector<float> gausNorm,
340  std::vector<float> gausMean, std::vector<float> gausSigma,
341  TH1* aNoiseHist) const {
342  const string myname = "SPhaseChannelNoiseService::generateGaussianNoise: ";
343  if ( fLogLevel > 1 ) {
344  cout << myname << "Generating Gaussian noise." << endl;
345  }
346  //--- get number of gaussians ---
347  int a = gausNorm.size();
348  int b = gausMean.size();
349  int c = gausSigma.size();
350  int NGausians = a<b?a:b;
351  NGausians = NGausians<c?NGausians:c;
352  //--- set function formula ---
353  std::stringstream name;
354  name.str("");
355  for(int i=0;i<NGausians;i++) {
356  name<<"["<<3*i<<"]*exp(-0.5*pow((x-["<<3*i+1<<"])/["<<3*i+2<<"],2))+";
357  }
358  name<<"0";
359  TF1 *funcGausNoise = new TF1("funcGausInhNoise",name.str().c_str(), 0, 1200);
360  funcGausNoise->SetNpx(12000);
361  for(int i=0;i<NGausians;i++) {
362  funcGausNoise->SetParameter(3*i, gausNorm.at(i));
363  funcGausNoise->SetParameter(3*i+1, gausMean.at(i));
364  funcGausNoise->SetParameter(3*i+2, gausSigma.at(i));
365  }
366 
367  // Fetch sampling rate.
368  float sampleRate = sampling_rate(clockData);
369  // Fetch FFT service and # ticks.
371  unsigned int ntick = pfft->FFTSize();
372  CLHEP::RandFlat flat(*m_pran);
373  // Create noise spectrum in frequency.
374  unsigned nbin = ntick/2 + 1;
375  std::vector<TComplex> noiseFrequency(nbin, 0.);
376  double pval = 0.;
377  double phase = 0.;
378  double rnd[2] = {0.};
379  // width of frequencyBin in kHz
380  double binWidth = 1.0/(ntick*sampleRate*1.0e-6);
381  for ( unsigned int i=0; i<ntick/2+1; ++i ) {
382  // coherent noise spectrum
383  pval = funcGausNoise->Eval((double)i*binWidth);
384  // randomize amplitude within 10%
385  flat.fireArray(2, rnd, 0, 1);
386  pval *= 0.9 + 0.2*rnd[0];
387  // randomize phase angle
388  phase = rnd[1]*2.*TMath::Pi();
389  TComplex tc(pval*cos(phase),pval*sin(phase));
390  noiseFrequency[i] += tc;
391  }
392  // Obtain time spectrum from frequency spectrum.
393  noise.clear();
394  noise.resize(ntick,0.0);
395  std::vector<double> tmpnoise(noise.size());
396  pfft->DoInvFFT(noiseFrequency, tmpnoise);
397  noiseFrequency.clear();
398 
399  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
400  noise[itck] = sqrt(ntick)*tmpnoise[itck];
401  }
402  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
403  aNoiseHist->Fill(noise[itck]);
404  }
405 
406  //free memory
407  delete funcGausNoise; funcGausNoise = 0;
408 }
409 ////**********************************************************************
410 
413  AdcSignalVector& noise, std::vector<float> gausNorm,
414  std::vector<float> gausMean, std::vector<float> gausSigma,
415  float cohExpNorm, float cohExpWidth, float cohExpOffset,
416  TH1* aNoiseHist) const {
417  const string myname = "SPhaseChannelNoiseService::generateCoherentGaussianNoise: ";
418  if ( fLogLevel > 1 ) {
419  cout << myname << "Generating Coherent Gaussian noise." << endl;
420  }
421  //--- get number of gaussians ---
422  int a = gausNorm.size();
423  int b = gausMean.size();
424  int c = gausSigma.size();
425  int NGausians = a<b?a:b;
426  NGausians = NGausians<c?NGausians:c;
427  //--- set function formula ---
428  std::stringstream name;
429  name.str("");
430  for(int i=0;i<NGausians;i++) {
431  name<<"["<<3*i<<"]*exp(-0.5*pow((x-["<<3*i+1<<"])/["<<3*i+2<<"],2))+";
432  }
433  name<<"["<<3*NGausians<<"]*exp(-x/["<<3*NGausians+1<<"]) + ["<<3*NGausians+2<<"]";
434  TF1 *funcCohNoise = new TF1("funcGausCohsNoise",name.str().c_str(), 0, 1200);
435  funcCohNoise->SetNpx(12000);
436  for(int i=0;i<NGausians;i++) {
437  funcCohNoise->SetParameter(3*i, gausNorm.at(i));
438  funcCohNoise->SetParameter(3*i+1, gausMean.at(i));
439  funcCohNoise->SetParameter(3*i+2, gausSigma.at(i));
440  }
441  funcCohNoise->SetParameter(3*NGausians, cohExpNorm);
442  funcCohNoise->SetParameter(3*NGausians+1, cohExpWidth);
443  funcCohNoise->SetParameter(3*NGausians+2, cohExpOffset);
444 
445  // custom poisson
446  TF1* _poisson = new TF1("_poisson", "[0]**(x) * exp(-[0]) / ROOT::Math::tgamma(x+1.)", 0, 30);
447  // poisson mean
448  double params[1] = {0.};
449  params[0] = 4; // hard-coded for now. To be updated with data
450  _poisson->SetParameters(params);
451  // Fetch sampling rate.
452  float sampleRate = sampling_rate(clockData);
453  // Fetch FFT service and # ticks.
455  unsigned int ntick = pfft->FFTSize();
456  CLHEP::RandFlat flat(*m_pran);
457  // Create noise spectrum in frequency.
458  unsigned nbin = ntick/2 + 1;
459  std::vector<TComplex> noiseFrequency(nbin, 0.);
460  double pval = 0.;
461  double phase = 0.;
462  double rnd[2] = {0.};
463  // width of frequencyBin in kHz
464  double binWidth = 1.0/(ntick*sampleRate*1.0e-6);
465  for ( unsigned int i=0; i<ntick/2+1; ++i ) {
466  // coherent noise spectrum
467  pval = funcCohNoise->Eval((double)i*binWidth);
468  // randomize amplitude within 10%
469  flat.fireArray(2, rnd, 0, 1);
470  pval *= 0.9 + 0.2*rnd[0];
471  // randomize amplitude with Poisson randomizers
472  // double randomizer = _poisson->GetRandom()/params[0];
473  // pval *= randomizer;
474  // phase information is not used in this model, but will be added soon.
475  // randomize phase angle assuming phases of different frequencies are uncorrelated
476  phase = rnd[1]*2.*TMath::Pi();
477  TComplex tc(pval*cos(phase),pval*sin(phase));
478  noiseFrequency[i] += tc;
479  }
480  // Obtain time spectrum from frequency spectrum.
481  noise.clear();
482  noise.resize(ntick,0.0);
483  std::vector<double> tmpnoise(noise.size());
484  pfft->DoInvFFT(noiseFrequency, tmpnoise);
485  noiseFrequency.clear();
486 
487  // Note: Assume that the frequency function is obtained from a fit
488  // of the foward FFT spectrum. In LArSoft, the forward
489  // FFT (doFFT) does not scale the frequency spectrum, but the backward FFT (DoInvFFT)
490  // does scale the waveform with 1/Nticks. If the frequency function is a fit to the
491  // LArSoft FFT spectrum, no scaling factor is needed after a backward FFT.
492  // However, the noise model described here is a fit to the scaled FFT spectrum
493  // (scaled with 1./sqrt(Nticks)).
494  // Therefore, after InvFFT, the waveform must be nomalized with sqrt(Nticks).
495 
496  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
497  noise[itck] = sqrt(ntick)*tmpnoise[itck];
498  }
499  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
500  aNoiseHist->Fill(noise[itck]);
501  }
502 
503  //free memory
504  delete funcCohNoise; funcCohNoise = 0;
505 }
506 
507 //**********************************************************************
508 
510  CLHEP::RandFlat flat(*m_pran);
511  CLHEP::RandGauss gaus(*m_pran);
513  const unsigned int nchan = geo->Nchannels();
514  fChannelGroupMap.resize(nchan);
515  unsigned int numberofgroups = 0;
516  if(nchan%nchpergroup == 0) numberofgroups = nchan/nchpergroup;
517  else numberofgroups = nchan/nchpergroup +1;
518  unsigned int cohGroupNo = 0;
519  for(unsigned int chan=0; chan<nchan; chan++) {
520  cohGroupNo = chan/nchpergroup; //group number
521  fChannelGroupMap[chan] = cohGroupNo;
522  }
523  fGroupCoherentNoiseMap.resize(numberofgroups);
524  for(unsigned int ng=0; ng<numberofgroups; ng++) {
525  unsigned int cohNoiseChan = flat.fire()*fCohNoiseArrayPoints;
526  fGroupCoherentNoiseMap[ng] = cohNoiseChan;
527  }
528 }
529 
530 //**********************************************************************
531 unsigned int SPhaseChannelNoiseService::getGroupNumberFromOfflineChannel(unsigned int offlinechan) const {
532  return fChannelGroupMap[offlinechan];
533 }
534 
535 //**********************************************************************
536 unsigned int SPhaseChannelNoiseService::getCohNoiseChanFromGroup(unsigned int cohgroup) const {
537  return fGroupCoherentNoiseMap[cohgroup];
538 }
539 
540 //**********************************************************************
541 
543 
548  for ( unsigned int i=0; i<fNoiseArrayPoints; ++i ) {
552  }
553  }
554 
559  for ( unsigned int i=0; i<fNoiseArrayPoints; ++i ) {
563  }
564  }
565 
569  for ( unsigned int i=0; i<fCohNoiseArrayPoints; ++i ) {
570  generateCoherentNoise(clockData,
573  fCohNoiseHist);
574  }
575  }
576 }
577 
578 //**********************************************************************
579 
581 
582 //**********************************************************************
static QCString name
Definition: declinfo.cpp:673
std::vector< float > fGausNormV
noise scale factor for the gaussian component in coherent noise
std::vector< float > fGausSigmaV
sigma of the gaussian component in coherent noise
void generateNoise(detinfo::DetectorClocksData const &clockData)
AdcSignalVectorVector fMicroBooNoiseU
std::vector< float > fGausMeanV
mean of the gaussian component in coherent noise
std::vector< int > fGroupCoherentNoiseMap
assign each group a noise
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string string
Definition: nybbler.cc:12
Planes which measure V.
Definition: geo_types.h:130
int fLogLevel
Log message level: 0=quiet, 1=init only, 2+=every event.
TH1 * fGausNoiseHistU
distribution of noise counts for U
TH1 * fGausNoiseHistZ
distribution of noise counts for Z
TH1 * fGausNoiseChanHist
distribution of accessed noise samples
std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const
unsigned int fNoiseArrayPoints
number of points in randomly generated noise array
std::vector< unsigned int > fChannelGroupMap
assign each channel a group number
int addNoise(detinfo::DetectorClocksData const &, detinfo::DetectorPropertiesData const &, Channel chan, AdcSignalVector &sigs) const
unsigned int fCohNoiseArrayPoints
number of points in randomly generated noise array
AdcSignalVectorVector fMicroBooNoiseZ
float fCohExpOffset
Amplitude offset of the exponential background component in coherent noise.
std::vector< float > fGausMeanU
mean of the gaussian component in coherent noise
void generateGaussianNoise(detinfo::DetectorClocksData const &clockData, AdcSignalVector &noise, std::vector< float > gausNorm, std::vector< float > gausMean, std::vector< float > gausSigma, TH1 *aNoiseHist) const
float fCohExpNorm
noise scale factor for the exponential component component in coherent noise
float fWhiteNoiseV
Level (per freq bin) for white noise for V.
std::vector< float > fNoiseFunctionParameters
Parameters in the MicroBooNE noise model.
std::vector< float > fGausSigmaZ
sigma of the gaussian component in coherent noise
float fWhiteNoiseZ
Level (per freq bin) for white noise for Z.
void makeCoherentGroupsByOfflineChannel(unsigned int nchpergroup)
art framework interface to geometry description
unsigned int fExpNoiseArrayPoints
number of points in randomly generated noise array
void DoInvFFT(std::vector< TComplex > &input, std::vector< T > &output)
Definition: LArFFT.h:120
unsigned int Nchannels() const
Returns the number of TPC readout channels in the detector.
TH1 * fCohNoiseChanHist
distribution of accessed noise samples
CLHEP::HepRandomEngine * m_pran
TH1 * fMicroBooNoiseHistZ
distribution of noise counts for Z
std::vector< float > fGausNormU
noise scale factor for the gaussian component in coherent noise
Planes which measure U.
Definition: geo_types.h:129
std::vector< float > fCohGausMean
mean of the gaussian component in coherent noise
std::vector< float > fGausNormZ
noise scale factor for the gaussian component in coherent noise
int FFTSize() const
Definition: LArFFT.h:69
unsigned int getGroupNumberFromOfflineChannel(unsigned int offlinechan) const
T gaus(T x, T amplitude, T mean, T sigma)
Tests GausssianFit object with a known input.
const double a
T get(std::string const &key) const
Definition: ParameterSet.h:271
bool fEnableMicroBooNoise
enable MicroBooNE noise model
std::vector< float > fGausSigmaU
sigma of the gaussian component in coherent noise
std::vector< float > fGausMeanZ
mean of the gaussian component in coherent noise
SPhaseChannelNoiseService(fhicl::ParameterSet const &pset)
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
float fCohExpWidth
width of the exponential component in coherent noise
std::vector< float > fCohGausSigma
sigma of the gaussian component in coherent noise
AdcSignalVectorVector fCohNoise
noise on each channel for each time for all planes
TH1 * fMicroBooNoiseHistV
distribution of noise counts for V
pval
Definition: tracks.py:168
unsigned int getCohNoiseChanFromGroup(unsigned int cohgroup) const
std::vector< float > fCohGausNorm
noise scale factor for the gaussian component in coherent noise
TH1 * fGausNoiseHistV
distribution of noise counts for V
Contains all timing reference information for the detector.
float fWhiteNoiseU
Level (per freq bin) for white noise for U.
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
void generateCoherentNoise(detinfo::DetectorClocksData const &clockData, AdcSignalVector &noise, std::vector< float > gausNorm, std::vector< float > gausMean, std::vector< float > gausSigma, float cohExpNorm, float cohExpWidth, float cohExpOffset, TH1 *aNoiseHist) const
int fRandomSeed
Seed for random number service. If absent or zero, use SeedSvc.
float fENOB
Effective number of bits.
static bool * b
Definition: config.cpp:1043
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
void generateMicroBooNoise(detinfo::DetectorClocksData const &clockData, float wirelength, float ENOB, AdcSignalVector &noise, TH1 *aNoiseHist) const
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
TH1 * fMicroBooNoiseHistU
distribution of noise counts for U
LArSoft geometry interface.
Definition: ChannelGeo.h:16
AdcSignalVectorVector fMicroBooNoiseV
QTextStream & endl(QTextStream &s)
TH1 * fCohNoiseHist
distribution of noise counts
TH1 * fMicroBooNoiseChanHist
distribution of accessed noise samples
#define DEFINE_ART_SERVICE_INTERFACE_IMPL(svc, iface)