All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SBNDuBooNEDataDrivenNoiseService_service.cc
Go to the documentation of this file.
1 // SBNDuBooNEDataDrivenNoiseService.cxx
2 // Andrew Scarff
3 // July 2019
4 // Based upon SPhaseChannelNoiseService.cxx developed by Jingbo Wang for ProtoDUNE.
5 
8 #include "art/Framework/Services/Registry/ServiceDefinitionMacros.h"
9 
10 using std::cout;
11 using std::ostream;
12 using std::endl;
13 using std::string;
14 using std::ostringstream;
15 using rndm::NuRandomService;
16 using CLHEP::HepJamesRandom;
17 
18 namespace{
19  constexpr double kPoissonMean = 3.30762;
20 }
21 
22 //**********************************************************************
23 
25 SBNDuBooNEDataDrivenNoiseService(fhicl::ParameterSet const& pset)
26  : fRandomSeed(0), fLogLevel(pset.get<int>("LogLevel")),
27  fGausNoiseHistZ(nullptr), fGausNoiseHistU(nullptr), fGausNoiseHistV(nullptr),
28  fGausNoiseChanHist(nullptr),
29  fMicroBooNoiseHistZ(nullptr), fMicroBooNoiseHistU(nullptr), fMicroBooNoiseHistV(nullptr),
30  fMicroBooNoiseChanHist(nullptr),
31  fCohNoiseHist(nullptr), fCohNoiseChanHist(nullptr),
32  haveSeed(pset.get_if_present<int>("RandomSeed", fRandomSeed)),
33  m_pran(ConstructRandomEngine(haveSeed)),
34  fTRandom3(new TRandom3(m_pran->getSeed()))
35 {
36 
37  fNoiseArrayPoints = pset.get<unsigned int>("NoiseArrayPoints");
38 
39  fEnableWhiteNoise = pset.get<bool>("EnableWhiteNoise");
40  fWhiteNoiseZ = pset.get<double>("WhiteNoiseZ");
41  fWhiteNoiseU = pset.get<double>("WhiteNoiseU");
42  fWhiteNoiseV = pset.get<double>("WhiteNoiseV");
43 
44  fEnableGaussianNoise = pset.get<bool>("EnableGaussianNoise");
45  fGausNormU = pset.get<std::vector<float>>("GausNormU");
46  fGausMeanU = pset.get<std::vector<float>>("GausMeanU");
47  fGausSigmaU = pset.get<std::vector<float>>("GausSigmaU");
48  fGausNormV = pset.get<std::vector<float>>("GausNormV");
49  fGausMeanV = pset.get<std::vector<float>>("GausMeanV");
50  fGausSigmaV = pset.get<std::vector<float>>("GausSigmaV");
51  fGausNormZ = pset.get<std::vector<float>>("GausNormZ");
52  fGausMeanZ = pset.get<std::vector<float>>("GausMeanZ");
53  fGausSigmaZ = pset.get<std::vector<float>>("GausSigmaZ");
54 
55  fEnableMicroBooNoise = pset.get<bool>("EnableMicroBooNoise");
56  fENOB = pset.get<double>("EffectiveNBits");
57  fIncludeJumpers = pset.get<bool>("IncludeJumpers");
58  fJumperCapacitance = pset.get<double>("JumperCapacitance");
59  fUFirstJumper = pset.get<double>("UFirstJumper");
60  fULastJumper = pset.get<double>("ULastJumper");
61  fVFirstJumper = pset.get<double>("VFirstJumper");
62  fVLastJumper = pset.get<double>("VLastJumper");
63  fNoiseFunctionParameters = pset.get<std::vector<float>>("NoiseFunctionParameters");
64 
65  fEnableCoherentNoise = pset.get<bool>("EnableCoherentNoise");
66  fCohNoiseArrayPoints = pset.get<unsigned int>("CohNoiseArrayPoints");
67  fCohExpNorm = pset.get<float>("CohExpNorm");
68  fCohExpWidth = pset.get<float>("CohExpWidth");
69  fCohExpOffset = pset.get<float>("CohExpOffset");
70  fCohGausNorm = pset.get<std::vector<float>>("CohGausNorm");
71  fCohGausMean = pset.get<std::vector<float>>("CohGausMean");
72  fCohGausSigma = pset.get<std::vector<float>>("CohGausSigma");
73  fNChannelsPerCoherentGroup = pset.get<std::vector<unsigned int>>("NChannelsPerCoherentGroup");
74 
75  art::ServiceHandle<art::TFileService> tfs;
76  fMicroBooNoiseHistZ = tfs->make<TH1F>("MicroBoo znoise", ";Z Noise [ADC counts];", 1000, -10., 10.);
77  fMicroBooNoiseHistU = tfs->make<TH1F>("MicroBoo unoise", ";U Noise [ADC counts];", 1000, -10., 10.);
78  fMicroBooNoiseHistV = tfs->make<TH1F>("MicroBoo vnoise", ";V Noise [ADC counts];", 1000, -10., 10.);
79  fMicroBooNoiseChanHist = tfs->make<TH1F>("MicroBoo NoiseChan", ";MicroBoo Noise channel;", fNoiseArrayPoints, 0, fNoiseArrayPoints);
80  fGausNoiseHistZ = tfs->make<TH1F>("Gaussian znoise", ";Z Noise [ADC counts];", 1000, -10., 10.);
81  fGausNoiseHistU = tfs->make<TH1F>("Gaussian unoise", ";U Noise [ADC counts];", 1000, -10., 10.);
82  fGausNoiseHistV = tfs->make<TH1F>("Gaussian vnoise", ";V Noise [ADC counts];", 1000, -10., 10.);
83  fGausNoiseChanHist = tfs->make<TH1F>("Gaussian NoiseChan", ";Gaussian Noise channel;", fNoiseArrayPoints, 0, fNoiseArrayPoints);
84  fCohNoiseHist = tfs->make<TH1F>("Cohnoise", ";Coherent Noise [ADC counts];", 1000, -10., 10.);
85  fCohNoiseChanHist = tfs->make<TH1F>("CohNoiseChan", ";CohNoise channel;", fCohNoiseArrayPoints, 0, fCohNoiseArrayPoints);// III = for each instance of this class.
86 
87  //generateNoise(); //This has been replaced by the same function in SimWireSBND. This is so the noise arrays are recalculated for each event.
88 
89  // Wirelength dependance function
90  _wld_f = new TF1("_wld_f", "[0] + [1]*x", 0.0, 1000);
91  wldparams[0] = 0.395;
92  wldparams[1] = 0.001304;
93  _wld_f->SetParameters(wldparams);
94 
95  _poisson = new TF1("_poisson", "[0]**(x) * exp(-[0]) / ROOT::Math::tgamma(x+1.)", 0, 30);
96  _poisson->SetParameter(0, kPoissonMean);
97 
98  if ( fLogLevel > 1 ) print() << endl;
99 
100 }
101 
102 //**********************************************************************
103 
105 SBNDuBooNEDataDrivenNoiseService(fhicl::ParameterSet const& pset, art::ActivityRegistry&)
107 
108 //**********************************************************************
109 
111  const string myname = "SBNDuBooNEDataDrivenNoiseService::dtor: ";
112  if ( fLogLevel > 0 ) {
113  cout << myname << "Deleting random engine with seed " << m_pran->getSeed() << endl;
114  }
115  delete m_pran;
116 }
117 
118 //**********************************************************************
119 
120 CLHEP::HepRandomEngine* SBNDuBooNEDataDrivenNoiseService::ConstructRandomEngine(const bool haveSeed) {
121  string myname = "SBNDuBooNEDataDrivenNoiseService::ctor: ";
122  string rname = "SBNDuBooNEDataDrivenNoiseService";
123 
124  if ( haveSeed ) {
125  if ( fLogLevel > 0 ) cout << myname << "WARNING: Using hardwired seed." << endl;
126  m_pran = new HepJamesRandom(fRandomSeed);
127  } else {
128  if ( fLogLevel > 0 ) cout << myname << "Using NuRandomService." << endl;
129  art::ServiceHandle<NuRandomService> seedSvc;
130  m_pran = new HepJamesRandom;
131  if ( fLogLevel > 0 ) cout << myname << " Initial seed: " << m_pran->getSeed() << endl;
132  seedSvc->registerEngine(NuRandomService::CLHEPengineSeeder(m_pran), rname);
133  }
134  if ( fLogLevel > 0 ) cout << myname << " Registered seed: " << m_pran->getSeed() << endl;
135 
136  return m_pran;
137 }
138 
140  TRandom* gRandomTemp = gRandom;
141  gRandom = fTRandom3;
142  double randomVal(func->GetRandom());
143  gRandom = gRandomTemp;
144  return randomVal;
145 }
146 
147 //**********************************************************************
148 
150  CLHEP::RandFlat flat(*m_pran);
151  CLHEP::RandGaussQ gaus(*m_pran);
152 
153  unsigned int microbooNoiseChan = flat.fire()*fNoiseArrayPoints;
154  if ( microbooNoiseChan == fNoiseArrayPoints ) --microbooNoiseChan;
155  fMicroBooNoiseChanHist->Fill(microbooNoiseChan);
156 
157  unsigned int gausNoiseChan = flat.fire()*fNoiseArrayPoints;
158  if ( gausNoiseChan == fNoiseArrayPoints ) --gausNoiseChan;
159  fGausNoiseChanHist->Fill(gausNoiseChan);
160 
161  unsigned int cohNoisechan = -999;
162  unsigned int groupNum = -999;
163  if ( fEnableCoherentNoise ) {
164  groupNum = getGroupNumberFromOfflineChannel(chan);
165  cohNoisechan = getCohNoiseChanFromGroup(groupNum);
166  if ( cohNoisechan == fCohNoiseArrayPoints ) cohNoisechan = fCohNoiseArrayPoints-1;
167  fCohNoiseChanHist->Fill(cohNoisechan);
168  }
169 
170  art::ServiceHandle<geo::Geometry> geo;
171  std::vector<geo::WireID> wireIDs = geo->ChannelToWire(chan);
172  unsigned int wireID = wireIDs.front().Wire;
173  unsigned int planeID = wireIDs.front().Plane;
174 
175  geo::WireGeo const& wire = geo->Wire(wireIDs.front());
176  double wirelength = wire.Length(); //wirelength in cm.
177 
178  if(fIncludeJumpers){
179  if( (planeID==0 && wireID >= fUFirstJumper && wireID <= fULastJumper) || (planeID==1 && wireID >= fVFirstJumper && wireID <= fVLastJumper) ){ //Add jumper term only for appropriate wires on U and V planes.
180  double jumperLength = (fJumperCapacitance/16.75)*100; //Using wire value of 16.75 pF/m to convert jumper capacitance to equivalent wire length. x100 to convert to cm.
181  wirelength = wirelength + jumperLength;
182  }
183  }
184  //include for 0 wirelength tests.
185  //wirelength = 0;
186 
187 
188  ///This part below has been moved from the generateMicroBooNoise section as it needs to be done differently for SBND due to different wirelengths.
189 
190  ////////////////////////////// MicroBooNE noise model/////////////////////////////////
191  // vars
192 
193  // Fetch sampling rate.
194  float sampleRate = sampling_rate(clockData);
195  // Fetch FFT service and # ticks.
196  art::ServiceHandle<util::LArFFT> pfft;
197  unsigned int ntick = pfft->FFTSize(); //waveform_size
198  // width of frequencyBin in kHz
199  double binWidth = 1.0/(ntick*sampleRate*1.0e-6);
200 
201  // Create noise spectrum in frequency.
202  unsigned nbin = ntick/2 + 1;
203  std::vector<TComplex> noiseFrequency(nbin, 0.);
204  double pval = 0.;
205  double phase = 0.;
206  double rnd[3] = {0.};
207 
208  std::vector<double> noisevector(ntick,0.0);
209  double fitpar[9] = {0.};
210 
211  // gain function in kHz
212  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);
213  // set data-driven parameters
214 
215  double wldValue = _wld_f->Eval(wirelength);
216 
217  fitpar[0] = fNoiseFunctionParameters.at(0);
218  fitpar[1] = fNoiseFunctionParameters.at(1);
219  fitpar[2] = fNoiseFunctionParameters.at(2);
220  fitpar[3] = fNoiseFunctionParameters.at(3);
221  fitpar[4] = fNoiseFunctionParameters.at(4);
222  fitpar[5] = fNoiseFunctionParameters.at(5);
223  fitpar[6] = wldValue; //wire length parameter
224  fitpar[7] = fNoiseFunctionParameters.at(7); //baseline_noise
225  fitpar[8] = 9596; //uBooNE nticks. Using SBND (or ProtoDUNE) nticks changes the model significantly, so we stick with the uBooNE nticks.
226 
227  _pfn_f1->SetParameters(fitpar);
228  _pfn_f1->SetNpx(1000);
229 
230  for ( unsigned int i=0; i<ntick/2+1; ++i ) {
231  //MicroBooNE noise model
232  double pfnf1val = _pfn_f1->Eval((i+0.5)*binWidth);
233  // define FFT parameters
234  double randPoisson = GetRandomTF1(_poisson);
235  double randomizer = randPoisson/kPoissonMean;
236  pval = pfnf1val * randomizer;
237  // random phase angle
238  flat.fireArray(2, rnd, 0, 1);
239  phase = rnd[1]*2.*TMath::Pi();
240  TComplex tc(pval*cos(phase),pval*sin(phase));
241  noiseFrequency[i] += tc;
242  }
243 
244 
245  // Obtain time spectrum from frequency spectrum.
246  std::vector<double> tmpnoise(noisevector.size());
247  pfft->DoInvFFT(noiseFrequency, tmpnoise);
248  noiseFrequency.clear();
249  for ( unsigned int itck=0; itck<noisevector.size(); ++itck ) {
250  noisevector[itck] = sqrt(ntick)*tmpnoise[itck];
251  }
252  // end of moved section.
253 
254  _pfn_f1->Delete();
255 
256 
257 
258  const geo::View_t view = geo->View(chan);
259  for ( unsigned int itck=0; itck<sigs.size(); ++itck ) {
260  double tnoise = 0;
261  if ( view==geo::kU ) {
262  if(fEnableWhiteNoise) tnoise += fWhiteNoiseU*gaus.fire();
263  if(fEnableMicroBooNoise) tnoise += noisevector[itck];
264  if(fEnableGaussianNoise) tnoise += fGausNoiseU[gausNoiseChan][itck];
265  if(fEnableCoherentNoise) tnoise += fCohNoiseU[cohNoisechan][itck];
266  }
267  else if ( view==geo::kV ) {
268  if(fEnableWhiteNoise) tnoise += fWhiteNoiseV*gaus.fire();
269  if(fEnableMicroBooNoise) tnoise += noisevector[itck];
270  if(fEnableGaussianNoise) tnoise += fGausNoiseV[gausNoiseChan][itck];
271  if(fEnableCoherentNoise) tnoise += fCohNoiseV[cohNoisechan][itck];
272  }
273  else {
274  if(fEnableWhiteNoise) tnoise += fWhiteNoiseZ*gaus.fire();
275  if(fEnableMicroBooNoise) tnoise += noisevector[itck];
276  if(fEnableGaussianNoise) tnoise += fGausNoiseZ[gausNoiseChan][itck];
277  if(fEnableCoherentNoise) tnoise += fCohNoiseZ[cohNoisechan][itck];
278  }
279  sigs[itck] += tnoise;
280  }
281  return 0;
282 }
283 
284 //**********************************************************************
285 
286 ostream& SBNDuBooNEDataDrivenNoiseService::print(ostream& out, string prefix) const {
287  out << prefix << "SBNDuBooNEDataDrivenNoiseService: " << endl;
288 
289  out << prefix << " LogLevel: " << fLogLevel << endl;
290  out << prefix << " RandomSeed: " << fRandomSeed << endl;
291  out << prefix << " NoiseArrayPoints: " << fNoiseArrayPoints << endl;
292 
293  out << prefix << " EnableWhiteNoise: " << fEnableWhiteNoise << endl;
294  out << prefix << " WhiteNoiseZ: " << fWhiteNoiseZ << endl;
295  out << prefix << " WhiteNoiseU: " << fWhiteNoiseU << endl;
296  out << prefix << " WhiteNoiseV: " << fWhiteNoiseV << endl;
297 
298  out << prefix << "EnableGaussianNoise: " << fEnableGaussianNoise << endl;
299  out << prefix << " GausNormU: [ ";
300  for(int i=0; i<(int)fGausNormU.size(); i++) { out << fGausNormU.at(i) << " ";}
301  out << " ]" << endl;
302  out << prefix << " GausMeanU: [ ";
303  for(int i=0; i<(int)fGausMeanU.size(); i++) { out << fGausMeanU.at(i) << " ";}
304  out << " ]" << endl;
305  out << prefix << " GausSigmaU: [ ";
306  for(int i=0; i<(int)fGausSigmaU.size(); i++) { out << fGausSigmaU.at(i) << " ";}
307  out << " ]" << endl;
308  out << prefix << " GausNormV: [ ";
309  for(int i=0; i<(int)fGausNormV.size(); i++) { out << fGausNormV.at(i) << " ";}
310  out << " ]" << endl;
311  out << prefix << " GausMeanV: [ ";
312  for(int i=0; i<(int)fGausMeanV.size(); i++) { out << fGausMeanV.at(i) << " ";}
313  out << " ]" << endl;
314  out << prefix << " GausSigmaV: [ ";
315  for(int i=0; i<(int)fGausSigmaV.size(); i++) { out << fGausSigmaV.at(i) << " ";}
316  out << " ]" << endl;
317  out << prefix << " GausNormZ: [ ";
318  for(int i=0; i<(int)fGausNormZ.size(); i++) { out << fGausNormZ.at(i) << " ";}
319  out << " ]" << endl;
320  out << prefix << " GausMeanZ: [ ";
321  for(int i=0; i<(int)fGausMeanZ.size(); i++) { out << fGausMeanZ.at(i) << " ";}
322  out << " ]" << endl;
323  out << prefix << " GausSigmaZ: [ ";
324  for(int i=0; i<(int)fGausSigmaZ.size(); i++) { out << fGausSigmaZ.at(i) << " ";}
325  out << " ]" << endl;
326 
327  out << prefix << "EnableMicroBooNoise: " << fEnableMicroBooNoise << endl;
328  out << prefix << " EffectiveNBits: " << fENOB << endl;
329  out << prefix << " JumperCapacitance: " << fJumperCapacitance << endl;
330  out << prefix << " UFirstJumper: " << fUFirstJumper << endl;
331  out << prefix << " ULastJumper: " << fULastJumper << endl;
332  out << prefix << " VFirstJumper: " << fVFirstJumper << endl;
333  out << prefix << " VLastJumper: " << fVLastJumper << endl;
334 
335  out << prefix << "MicroBoo model parameters: [ ";
336  for(int i=0; i<(int)fNoiseFunctionParameters.size(); i++) { out << fNoiseFunctionParameters.at(i) << " ";}
337  out << " ]" << endl;
338 
339  out << prefix << "EnableCoherentNoise: " << fEnableCoherentNoise << endl;
340  out << prefix << "ExpNoiseArrayPoints: " << fExpNoiseArrayPoints << endl;
341  out << prefix << "CohNoiseArrayPoints: " << fCohNoiseArrayPoints << endl;
342 
343  out << prefix << " CohGausNorm: [ ";
344  for(int i=0; i<(int)fCohGausNorm.size(); i++) { out << fCohGausNorm.at(i) << " ";}
345  out << " ]" << endl;
346  out << prefix << " CohGausMean: [ ";
347  for(int i=0; i<(int)fCohGausMean.size(); i++) { out << fCohGausMean.at(i) << " ";}
348  out << " ]" << endl;
349  out << prefix << " CohGausSigma: [ ";
350  for(int i=0; i<(int)fCohGausSigma.size(); i++) { out << fCohGausSigma.at(i) << " ";}
351  out << " ]" << endl;
352 
353  out << prefix << " Actual random seed: " << m_pran->getSeed();
354  return out;
355 }
356 
357 //**********************************************************************
358 
361  AdcSignalVector& noise, std::vector<float> gausNorm,
362  std::vector<float> gausMean, std::vector<float> gausSigma,
363  TH1* aNoiseHist) const {
364  const string myname = "SBNDuBooNEDataDrivenNoiseService::generateGaussianNoise: ";
365  if ( fLogLevel > 1 ) {
366  cout << myname << "Generating Gaussian noise." << endl;
367  }
368  //--- get number of gaussians ---
369  int a = gausNorm.size();
370  int b = gausMean.size();
371  int c = gausSigma.size();
372  int NGausians = a<b?a:b;
373  NGausians = NGausians<c?NGausians:c;
374  //--- set function formula ---
375  std::stringstream name;
376  name.str("");
377  for(int i=0;i<NGausians;i++) {
378  name<<"["<<3*i<<"]*exp(-0.5*pow((x-["<<3*i+1<<"])/["<<3*i+2<<"],2))+";
379  }
380  name<<"0";
381  TF1 *funcGausNoise = new TF1("funcGausInhNoise",name.str().c_str(), 0, 1200);
382  funcGausNoise->SetNpx(12000);
383  for(int i=0;i<NGausians;i++) {
384  funcGausNoise->SetParameter(3*i, gausNorm.at(i));
385  funcGausNoise->SetParameter(3*i+1, gausMean.at(i));
386  funcGausNoise->SetParameter(3*i+2, gausSigma.at(i));
387  }
388 
389  // Fetch sampling rate.
390  float sampleRate = sampling_rate(clockData);
391  // Fetch FFT service and # ticks.
392  art::ServiceHandle<util::LArFFT> pfft;
393  unsigned int ntick = pfft->FFTSize();
394  CLHEP::RandFlat flat(*m_pran);
395  // Create noise spectrum in frequency.
396  unsigned nbin = ntick/2 + 1;
397  std::vector<TComplex> noiseFrequency(nbin, 0.);
398  double pval = 0.;
399  double phase = 0.;
400  double rnd[2] = {0.};
401  // width of frequencyBin in kHz
402  double binWidth = 1.0/(ntick*sampleRate*1.0e-6);
403  for ( unsigned int i=0; i<ntick/2+1; ++i ) {
404  // coherent noise spectrum
405  pval = funcGausNoise->Eval((double)i*binWidth);
406  // randomize amplitude within 10%
407  flat.fireArray(2, rnd, 0, 1);
408  pval *= 0.9 + 0.2*rnd[0];
409  // randomize phase angle
410  phase = rnd[1]*2.*TMath::Pi();
411  TComplex tc(pval*cos(phase),pval*sin(phase));
412  noiseFrequency[i] += tc;
413  }
414  // Obtain time spectrum from frequency spectrum.
415  noise.clear();
416  noise.resize(ntick,0.0);
417  std::vector<double> tmpnoise(noise.size());
418  pfft->DoInvFFT(noiseFrequency, tmpnoise);
419  noiseFrequency.clear();
420 
421  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
422  noise[itck] = sqrt(ntick)*tmpnoise[itck];
423  }
424  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
425  aNoiseHist->Fill(noise[itck]);
426  }
427 
428  //free memory
429  delete funcGausNoise; funcGausNoise = 0;
430 }
431 ////**********************************************************************
432 
434  AdcSignalVector& noise, std::vector<float> gausNorm,
435  std::vector<float> gausMean, std::vector<float> gausSigma,
436  float cohExpNorm, float cohExpWidth, float cohExpOffset,
437  TH1* aNoiseHist) const {
438  const string myname = "SBNDuBooNEDataDrivenNoiseService::generateCoherentGaussianNoise: ";
439  if ( fLogLevel > 1 ) {
440  cout << myname << "Generating Coherent Gaussian noise." << endl;
441  }
442  //--- get number of gaussians ---
443  int a = gausNorm.size();
444  int b = gausMean.size();
445  int c = gausSigma.size();
446  int NGausians = a<b?a:b;
447  NGausians = NGausians<c?NGausians:c;
448  //--- set function formula ---
449  std::stringstream name;
450  name.str("");
451  for(int i=0;i<NGausians;i++) {
452  name<<"["<<3*i<<"]*exp(-0.5*pow((x-["<<3*i+1<<"])/["<<3*i+2<<"],2))+";
453  }
454  name<<"["<<3*NGausians<<"]*exp(-x/["<<3*NGausians+1<<"]) + ["<<3*NGausians+2<<"]";
455  TF1 *funcCohNoise = new TF1("funcGausCohsNoise",name.str().c_str(), 0, 1200);
456  funcCohNoise->SetNpx(12000);
457  for(int i=0;i<NGausians;i++) {
458  funcCohNoise->SetParameter(3*i, gausNorm.at(i));
459  funcCohNoise->SetParameter(3*i+1, gausMean.at(i));
460  funcCohNoise->SetParameter(3*i+2, gausSigma.at(i));
461  }
462  funcCohNoise->SetParameter(3*NGausians, cohExpNorm);
463  funcCohNoise->SetParameter(3*NGausians+1, cohExpWidth);
464  funcCohNoise->SetParameter(3*NGausians+2, cohExpOffset);
465 
466  // custom poisson
467  TF1* _poisson = new TF1("_poisson", "[0]**(x) * exp(-[0]) / ROOT::Math::tgamma(x+1.)", 0, 30);
468  // poisson mean
469  double params[1] = {0.};
470  params[0] = 4; // hard-coded for now. To be updated with data
471  _poisson->SetParameters(params);
472  // Fetch sampling rate.
473  float sampleRate = sampling_rate(clockData);
474  // Fetch FFT service and # ticks.
475  art::ServiceHandle<util::LArFFT> pfft;
476  unsigned int ntick = pfft->FFTSize();
477  CLHEP::RandFlat flat(*m_pran);
478  // Create noise spectrum in frequency.
479  unsigned nbin = ntick/2 + 1;
480  std::vector<TComplex> noiseFrequency(nbin, 0.);
481  double pval = 0.;
482  double phase = 0.;
483  double rnd[2] = {0.};
484  // width of frequencyBin in kHz
485  double binWidth = 1.0/(ntick*sampleRate*1.0e-6);
486  for ( unsigned int i=0; i<ntick/2+1; ++i ) {
487  // coherent noise spectrum
488  pval = funcCohNoise->Eval((double)i*binWidth);
489  // randomize amplitude within 10%
490  flat.fireArray(2, rnd, 0, 1);
491  pval *= 0.9 + 0.2*rnd[0];
492  phase = rnd[1]*2.*TMath::Pi();
493  TComplex tc(pval*cos(phase),pval*sin(phase));
494  noiseFrequency[i] += tc;
495  }
496  // Obtain time spectrum from frequency spectrum.
497  noise.clear();
498  noise.resize(ntick,0.0);
499  std::vector<double> tmpnoise(noise.size());
500  pfft->DoInvFFT(noiseFrequency, tmpnoise);
501  noiseFrequency.clear();
502 
503  // Note: Assume that the frequency function is obtained from a fit
504  // of the foward FFT spectrum. In LArSoft, the forward
505  // FFT (doFFT) does not scale the frequency spectrum, but the backward FFT (DoInvFFT)
506  // does scale the waveform with 1/Nticks. If the frequency function is a fit to the
507  // LArSoft FFT spectrum, no scaling factor is needed after a backward FFT.
508  // However, the noise model described here is a fit to the scaled FFT spectrum
509  // (scaled with 1./sqrt(Nticks)).
510  // Therefore, after InvFFT, the waveform must be nomalized with sqrt(Nticks).
511 
512  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
513  noise[itck] = sqrt(ntick)*tmpnoise[itck];
514  }
515  for ( unsigned int itck=0; itck<noise.size(); ++itck ) {
516  aNoiseHist->Fill(noise[itck]);
517  }
518 
519  //free memory
520  delete funcCohNoise; funcCohNoise = 0;
521 }
522 
523 //**********************************************************************
524 
526  CLHEP::RandFlat flat(*m_pran);
527  CLHEP::RandGauss gaus(*m_pran);
528  art::ServiceHandle<geo::Geometry> geo;
529  const unsigned int nchan = geo->Nchannels();
530  fChannelGroupMap.resize(nchan);
531  unsigned int numberofgroups = 0;
532  if(nchan%nchpergroup == 0) numberofgroups = nchan/nchpergroup;
533  else numberofgroups = nchan/nchpergroup +1;
534  unsigned int cohGroupNo = 0;
535  for(unsigned int chan=0; chan<nchan; chan++) {
536  cohGroupNo = chan/nchpergroup; //group number
537  fChannelGroupMap[chan] = cohGroupNo;
538  }
539  fGroupCoherentNoiseMap.resize(numberofgroups);
540  for(unsigned int ng=0; ng<numberofgroups; ng++) {
541  unsigned int cohNoiseChan = flat.fire()*fCohNoiseArrayPoints;
542  fGroupCoherentNoiseMap[ng] = cohNoiseChan;
543  }
544 }
545 
546 //**********************************************************************
547 unsigned int SBNDuBooNEDataDrivenNoiseService::getGroupNumberFromOfflineChannel(unsigned int offlinechan) const {
548  return fChannelGroupMap[offlinechan];
549 }
550 
551 //**********************************************************************
552 unsigned int SBNDuBooNEDataDrivenNoiseService::getCohNoiseChanFromGroup(unsigned int cohgroup) const {
553  return fGroupCoherentNoiseMap[cohgroup];
554 }
555 
556 //**********************************************************************
557 
559 
564  for ( unsigned int i=0; i<fNoiseArrayPoints; ++i ) {
568  }
569  }
570 
572  // U plane
575  for ( unsigned int i=0; i<fCohNoiseArrayPoints; ++i ) {
578  fCohNoiseHist);
579  }
580 
581  // V plane
583  fCohNoiseV.resize(fCohNoiseArrayPoints);
584  for ( unsigned int i=0; i<fCohNoiseArrayPoints; ++i ) {
587  fCohNoiseHist);
588  }
589 
590  // Z plane
592  fCohNoiseZ.resize(fCohNoiseArrayPoints);
593  for ( unsigned int i=0; i<fCohNoiseArrayPoints; ++i ) {
594 
597  fCohNoiseHist);
598  }
599  }
600 }
601 
602 //**********************************************************************
603 
604 DEFINE_ART_SERVICE_INTERFACE_IMPL(SBNDuBooNEDataDrivenNoiseService, ChannelNoiseService)
605 
606 //**********************************************************************
float fCohExpOffset
Amplitude offset of the exponential background component in coherent noise.
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
Definition: WireGeo.h:65
AdcSignalVectorVector fCohNoiseZ
noise on each channel for each time for all planes
TH1 * fGausNoiseHistU
distribution of noise counts for U
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 fLogLevel
Log message level: 0=quiet, 1=init only, 2+=every event.
std::vector< float > fGausMeanU
mean of the gaussian component in coherent noise
int addNoise(detinfo::DetectorClocksData const &clockData, Channel chan, AdcSignalVector &sigs) const override
float fWhiteNoiseV
Level (per freq bin) for white noise for V.
TH1 * fMicroBooNoiseHistV
distribution of noise counts for V
void generateGaussianNoise(detinfo::DetectorClocksData const &clockData, AdcSignalVector &noise, std::vector< float > gausNorm, std::vector< float > gausMean, std::vector< float > gausSigma, TH1 *aNoiseHist) const
TH1 * fMicroBooNoiseChanHist
distribution of accessed noise samples
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
AdcSignalVectorVector fCohNoiseU
noise on each channel for each time for all planes
Planes which measure V.
Definition: geo_types.h:130
double Length() const
Returns the wire length in centimeters.
Definition: WireGeo.h:236
void makeCoherentGroupsByOfflineChannel(unsigned int nchpergroup)
std::vector< float > fGausMeanV
mean of the gaussian component in coherent noise
SBNDuBooNEDataDrivenNoiseService(fhicl::ParameterSet const &pset)
TH1 * fCohNoiseChanHist
distribution of accessed noise samples
std::vector< float > fGausNormV
noise scale factor for the gaussian component in coherent noise
std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const override
unsigned int getGroupNumberFromOfflineChannel(unsigned int offlinechan) const
float fJumperCapacitance
Capacitance of jumper cables in pF. Defaults to 0 if not included.
std::vector< int > fGroupCoherentNoiseMap
assign each group a noise
AdcSignalVectorVector fCohNoiseV
noise on each channel for each time for all planes
std::vector< unsigned int > fChannelGroupMap
assign each channel a group number
int fRandomSeed
Seed for random number service. If absent or zero, use SeedSvc.
std::vector< float > fCohGausSigma
sigma of the gaussian component in coherent noise
process_name gaushit a
std::vector< float > fNoiseFunctionParameters
Parameters in the MicroBooNE noise model.
bool fEnableMicroBooNoise
enable MicroBooNE noise model
float fCohExpNorm
noise scale factor for the exponential component component in coherent noise
Planes which measure U.
Definition: geo_types.h:129
unsigned int fExpNoiseArrayPoints
number of points in randomly generated noise array
float fWhiteNoiseZ
Level (per freq bin) for white noise for Z.
std::vector< float > fGausSigmaV
sigma of the gaussian component in coherent noise
T gaus(T x, T amplitude, T mean, T sigma)
Tests GausssianFit object with a known input.
void generateNoise(detinfo::DetectorClocksData const &clockData) override
float fWhiteNoiseU
Level (per freq bin) for white noise for U.
std::vector< float > fGausMeanZ
mean of the gaussian component in coherent noise
TH1 * fMicroBooNoiseHistU
distribution of noise counts for U
float fULastJumper
Wire number of last wire on U layer to include a jumper cable. Defaults to 0 if not included...
float fVFirstJumper
Wire number of first wire on V layer to include a jumper cable. Defaults to 0 if not included...
std::vector< float > fGausSigmaU
sigma of the gaussian component in coherent noise
std::vector< AdcSignal > AdcSignalVector
std::vector< float > fGausSigmaZ
sigma of the gaussian component in coherent noise
std::vector< float > fCohGausMean
mean of the gaussian component in coherent noise
Contains all timing reference information for the detector.
TH1 * fCohNoiseHist
distribution of noise counts
std::vector< float > fGausNormZ
noise scale factor for the gaussian component in coherent noise
unsigned int fCohNoiseArrayPoints
number of points in randomly generated noise array
float fVLastJumper
Wire number of last wire on V layer to include a jumper cable. Defaults to 0 if not included...
then echo fcl name
TH1 * fMicroBooNoiseHistZ
distribution of noise counts for Z
CLHEP::HepRandomEngine * ConstructRandomEngine(const bool haveSeed)
art::ServiceHandle< art::TFileService > tfs
TH1 * fGausNoiseHistV
distribution of noise counts for V
TH1 * fGausNoiseHistZ
distribution of noise counts for Z
unsigned int fNoiseArrayPoints
number of points in randomly generated noise array
float fUFirstJumper
Wire number of first wire on U layer to include a jumper cable. Defaults to 0 if not included...
float fCohExpWidth
width of the exponential component in coherent noise
std::vector< unsigned int > fNChannelsPerCoherentGroup
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
std::vector< float > fCohGausNorm
noise scale factor for the gaussian component in coherent noise
unsigned int getCohNoiseChanFromGroup(unsigned int cohgroup) const
TH1 * fGausNoiseChanHist
distribution of accessed noise samples
BEGIN_PROLOG could also be cout
std::vector< float > fGausNormU
noise scale factor for the gaussian component in coherent noise