All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SBNDataNoiseBoard_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file SBNDataNoiseBoard.cc
3 /// \author F. Varanini
4 ////////////////////////////////////////////////////////////////////////
5 
6 #include <cmath>
7 #include "IGenNoise.h"
8 #include "art/Framework/Core/EDProducer.h"
9 #include "art/Utilities/ToolMacros.h"
10 #include "art/Utilities/make_tool.h"
11 #include "messagefacility/MessageLogger/MessageLogger.h"
12 #include "cetlib_except/exception.h"
15 #include "art_root_io/TFileService.h"
16 
18 
19 // art extensions
20 #include "nurandom/RandomUtils/NuRandomService.h"
21 
22 #include "icarus_signal_processing/WaveformTools.h"
23 
24 // CLHEP libraries
25 #include "CLHEP/Random/RandFlat.h"
26 #include "CLHEP/Random/RandGeneral.h"
27 #include "CLHEP/Random/RandGaussQ.h"
28 
29 #include "TH1F.h"
30 #include "TProfile.h"
31 #include "TFile.h"
32 
33 #include <Eigen/Core>
34 #include <unsupported/Eigen/FFT>
35 
36 #include <fstream>
37 
38 namespace icarus_tool
39 {
40 
42 {
43 public:
44  explicit SBNDataNoiseBoard(const fhicl::ParameterSet& pset);
45 
47 
48  void configure(const fhicl::ParameterSet& pset) override;
49 
50  void nextEvent() override;
51 
52  void generateNoise(CLHEP::HepRandomEngine&,
53  CLHEP::HepRandomEngine& ,
56  double,
57  const geo::PlaneID&,
58  unsigned int) override;
59 
60 private:
61  void GenerateCorrelatedNoise(CLHEP::HepRandomEngine&, icarusutil::TimeVec&, double, unsigned int);
62  void GenerateUncorrelatedNoise(CLHEP::HepRandomEngine&, icarusutil::TimeVec&, double, unsigned int);
63  void GenNoise(std::function<void (double[])>&, const icarusutil::TimeVec&, icarusutil::TimeVec&, float);
64  void ComputeRMSs();
65  void makeHistograms();
66  void SampleCorrelatedRMSs() ;
67  void ExtractUncorrelatedRMS(float&, int, int) const;
68  void makeBoardHistos(unsigned int) ;
69 
70  // Member variables from the fhicl file
71  size_t fPlane;
73  float fNoiseRand;
76  std::vector<float> fIncoherentNoiseFrac;
79  std::string fHistogramName;
84  std::string fTotalRMSHistoName;
85 
86  using WaveformTools = icarus_signal_processing::WaveformTools<icarusutil::SigProcPrecision>;
87 
89 
90  // We'll recover the bin contents and store in a vector
91  // with the likely false hope this will be faster...
92  using BoardToNoiseVecMap = std::unordered_map<unsigned int, icarusutil::TimeVec>;
93 
96 
97  std::vector<icarusutil::TimeVec> fCoherentNoiseVec; //< Input full noise frequency distribution
98  std::vector<icarusutil::TimeVec> fIncoherentNoiseVec; //< Input full noise frequency distribution
99 
100  using BoardToHistMap = std::unordered_map<unsigned int, TH1D*>;
101 
102  // Container for doing the work
104 
105  // Keep track of seed initialization for uncorrelated noise
106  bool fNeedFirstSeed=true;
107 
108  // Histograms
109  TProfile* fInputNoiseHist;
111  TProfile* fPeakNoiseHist;
112 
114 
115  std::vector<float> totalRMS;
116  std::vector<float> rmsUnc;
117  std::vector<float> rmsCorr;
118 
119  // Keep instance of the eigen FFT
120  Eigen::FFT<double> fEigenFFT;
121 
122 };
123 
124 //----------------------------------------------------------------------
125 // Constructor.
126 SBNDataNoiseBoard::SBNDataNoiseBoard(const fhicl::ParameterSet& pset)
127 {
128  // Recover the configuration of the tool from the input fhicl file and set up
129  configure(pset);
130  ComputeRMSs();
131 
132  // Output some histograms to catalogue what's been done
133  makeHistograms();
134  std::cout << " after making histos " << std::endl;
135 }
136 
138 {
139  // Close the input file
140  fHistogramFile->Close();
141 }
142 
143 void SBNDataNoiseBoard::configure(const fhicl::ParameterSet& pset)
144 {
145 std::cout << " configuring tool " << std::endl;
146  // Recover the histogram used for noise generation
147  fPlane = pset.get< size_t >("Plane");
148  fMedianNumBins = pset.get< int >("MedianNumBins");
149  fNoiseRand = pset.get< float >("NoiseRand");
150  fCorrelatedSeed = pset.get< long >("CorrelatedSeed",1000);
151  fUncorrelatedSeed = pset.get< long >("UncorrelatedSeed",5000);
152  std::vector<float> noiseFracVec = pset.get< std::vector<float> >("IncoherentNoiseFraction", std::vector<float>());
153  fStoreHistograms = pset.get< bool >("StoreHistograms");
154  fInputNoiseHistFileName = pset.get< std::string >("NoiseHistFileName");
155  fCorrelatedHistogramName = pset.get< std::string >("CorrelatedHistogramName");
156  fUncorrelatedHistogramName = pset.get< std::string >("UncorrelatedHistogramName");
157  fCorrelatedRMSHistoName = pset.get< std::string >("CorrelatedRMSHistoName");
158  fUncorrelatedRMSHistoName = pset.get< std::string >("UncorrelatedRMSHistoName");
159  fTotalRMSHistoName = pset.get< std::string >("TotalRMSHistoName");
160 
161  for(auto& noiseFrac : noiseFracVec) {
162  fIncoherentNoiseFrac.push_back(float(noiseFrac));
163  }
164 
165  std::string fullFileName;
166 
167  cet::search_path searchPath("FW_SEARCH_PATH");
168 
169  searchPath.find_file(fInputNoiseHistFileName, fullFileName);
170 
171  fHistogramFile = TFile::Open(fullFileName.c_str(), "READ");
172 
173  if (!fHistogramFile->IsOpen())
174  throw cet::exception("NoiseFromHist::configure") << "Unable to open input file: " << fInputNoiseHistFileName << std::endl;
175 
176  std::cout << " end configuring tool " << std::endl;
177  return;
178 }
179 
180 void SBNDataNoiseBoard::makeBoardHistos(unsigned int board)
181 {
183  {
184 
185  TH1D* corrHistPtr = (TH1D*)fHistogramFile->Get((fCorrelatedHistogramName+std::to_string(board)).c_str());
186  if (!corrHistPtr)
187  throw cet::exception("NoiseFromHist::configure") << "Unable to recover desired histogram: " << fCorrelatedHistogramName+std::to_string(board) << std::endl;
188 
190 
191  noiseVec.resize(corrHistPtr->GetNbinsX(),0.);
192  for(size_t histIdx = 0; histIdx < size_t(corrHistPtr->GetNbinsX()); histIdx++) noiseVec[histIdx] = corrHistPtr->GetBinContent(histIdx+1);
193  }
194 
196  {
197  TH1D* uncorrHistPtr = (TH1D*)fHistogramFile->Get((fUncorrelatedHistogramName+std::to_string(board)).c_str());
198  if (!uncorrHistPtr)
199  throw cet::exception("NoiseFromHist::configure") << "Unable to recover desired histogram: " << fUncorrelatedHistogramName << std::endl;
200 
202 
203  noiseVec.resize(uncorrHistPtr->GetNbinsX(),0.);
204  for(size_t histIdx = 0; histIdx < size_t(uncorrHistPtr->GetNbinsX()); histIdx++) noiseVec[histIdx] = uncorrHistPtr->GetBinContent(histIdx+1);
205  }
206 
207  // Should we store hists?
208  if (fStoreHistograms)
209  {
210  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
211  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clockData);
212 
213  // Define histograms
214  art::ServiceHandle<art::TFileService> tfs;
215 
216  art::TFileDirectory* histDirectory = tfs.get();
217 
218  // Make a directory for these histograms
219  art::TFileDirectory dir = histDirectory->mkdir(Form("CorNoisePlane%1zu",fPlane));
220 
221  float sampleRate = sampling_rate(clockData);
222  float readOutSize = detProp.ReadOutWindowSize();
223  float maxFreq = 1.e6 / (2. * sampleRate);
224  float minFreq = 1.e6 / (2. * sampleRate * readOutSize);
225  int numSamples = readOutSize / 2;
226 
227  fInputNoiseHist = dir.make<TProfile>("InNoise", ";freq(kHz)", numSamples, minFreq, maxFreq);
228  fMediaNoiseHist = dir.make<TH1D>("MedNoise", ";ADC", 100, -10., -10.);;
229  fPeakNoiseHist = dir.make<TProfile>("PeakNoise", ";freq(kHz)", numSamples, minFreq, maxFreq);;
230  }
231  //SampleCorrelatedRMSs();
232 }
233 
235 {
236  // We update the correlated seed because we want to see different noise event-by-event
237  fCorrelatedSeed = (333 * fCorrelatedSeed) % 900000000;
239 
240  return;
241 }
242 
243 void SBNDataNoiseBoard::generateNoise(CLHEP::HepRandomEngine& engine_unc,
244  CLHEP::HepRandomEngine& engine_corr,
245  icarusutil::TimeVec& noise,
247  double noise_factor,
248  const geo::PlaneID& planeID,
249  unsigned int board)
250 {
251  makeBoardHistos(board);
252 
253  //std::cout << " generating noise channel " << channel << std::endl;
254  //GET THE GEOMETRY.
255  art::ServiceHandle<geo::Geometry> geom;
256 
257  // We need to know the plane to look up parameters
258 // size_t cryostat=planeID.Cryostat;
259 // size_t tpc=planeID.TPC;
260 
261  //std::cout << " index " << index << " generating noise totalRMS " << totalRMS[index] << std::endl;
262  // Define a couple of vectors to hold intermediate work
263  icarusutil::TimeVec noise_unc(noise.size(),0.);
264  icarusutil::TimeVec noise_corr(noise.size(),0.);
265 
266  // Make sure the work vector is size right with the output
267  if (fNoiseFrequencyVec.size() != noise.size()) fNoiseFrequencyVec.resize(noise.size(),std::complex<float>(0.,0.));
268 
269  // If applying incoherent noise call the generator
270  GenerateUncorrelatedNoise(engine_unc,noise_unc,noise_factor, board);
271 
272  GenerateCorrelatedNoise(engine_corr, noise_corr, noise_factor, board);
273 
274  // std::cout << " summing noise " << std::endl;
275  // Take the noise as the simple sum of the two contributions
276  std::transform(noise_unc.begin(),noise_unc.end(),noise_corr.begin(),noise.begin(),std::plus<float>());
277 
278 // float mediaNoise=0;
279 // for(unsigned int jn=0;jn<noise.size();jn++) mediaNoise+=noise.at(jn);
280 
281 // mediaNoise/=(noise.size());
282 
283  //std::cout << " media noise size " << noise.size() << std::endl;
284  //fMediaNoiseHist->Fill(mediaNoise);
285  //std::cout << " media noise " << mediaNoise << std::endl;
286  return;
287 }
288 
289 void SBNDataNoiseBoard::GenerateUncorrelatedNoise(CLHEP::HepRandomEngine& engine, icarusutil::TimeVec &noise, double noise_factor, unsigned int board)
290 {
291  // Here we aim to produce a waveform consisting of incoherent noise
292  // Note that this is expected to be the dominate noise contribution
293  // Check for seed initialization
294  if (fNeedFirstSeed)
295  {
296  engine.setSeed(fUncorrelatedSeed,0);
297  fNeedFirstSeed = false;
298  }
299 
300  // Get the generator
301  CLHEP::RandFlat noiseGen(engine,0,1);
302 
303  std::function<void (double[])> randGenFunc = [&noiseGen](double randArray[]){noiseGen.fireArray(2,randArray);};
304 
305  GenNoise(randGenFunc, fIncoherentBoardToNoiseVecMap[board], noise, noise_factor);
306 
307  return;
308 }
309 
310 void SBNDataNoiseBoard::GenerateCorrelatedNoise(CLHEP::HepRandomEngine& engine, icarusutil::TimeVec &noise, double noise_factor, unsigned int board)
311 {
312 
313  // Set the engine seed to the board being considered
314  engine.setSeed(fCorrelatedSeed+board,0);
315 
316  CLHEP::RandFlat noiseGen(engine,0,1);
317 
318  std::function<void (double[])> randGenFunc = [&noiseGen](double randArray[]){noiseGen.fireArray(2,randArray);};
319 
320  GenNoise(randGenFunc, fCoherentBoardToNoiseVecMap[board], noise, noise_factor);
321 
322  return;
323 }
324 
325 void SBNDataNoiseBoard::GenNoise(std::function<void (double[])>& gen,const icarusutil::TimeVec& freqDist, icarusutil::TimeVec& noise, float scaleFactor)
326 {
327  double rnd_corr[2] = {0.,0.};
328  // std::cout << " noise size " << noise.size() << std::endl;
329  // Build out the frequency vector
330  for(size_t i=0; i< noise.size()/2; ++i)
331  {
332  //std::cout << " i " << i << " freqdist " << freqDist[i] << std::endl;
333  // exponential noise spectrum
334  gen(rnd_corr);
335  // if(i!=10) continue;
336  float pval = freqDist[i] * ((1-fNoiseRand) + 2 * fNoiseRand*rnd_corr[0]) * scaleFactor;
337  float phase = rnd_corr[1] * 2. * M_PI;
338  // float pval = freqDist[i]*scaleFactor ;
339  // float phase = 0;
340  std::complex<float> tc(pval*cos(phase),pval*sin(phase));
341 
342  fNoiseFrequencyVec[i] = tc;
343  //std::cout << " i " << i << " noise freqvec " << fNoiseFrequencyVec[i] << std::endl;
344  }
345 
346  // inverse FFT MCSignal
347  fEigenFFT.inv(noise, fNoiseFrequencyVec);
348  // for(unsigned int jn=0;jn<noise.size();jn++) std::cout << " jn " << jn << " noise sum " << noise.at(jn) << std::endl;
349  //exit(22);
350  //std::cout << " end gen noise " << std::endl;
351  return;
352 }
353 
355 {
356 
357  return;
358 }
359 
361 {
362 
363 
364 }
366 {
367 
368 }
369 void SBNDataNoiseBoard::ExtractUncorrelatedRMS(float& cf, int channel, int index) const
370 {
371 }
372 
373 
374 DEFINE_ART_CLASS_TOOL(SBNDataNoiseBoard)
375 }
icarus_signal_processing::WaveformTools< icarusutil::SigProcPrecision > WaveformTools
Utilities related to art service access.
static constexpr Sample_t transform(Sample_t sample)
void GenerateUncorrelatedNoise(CLHEP::HepRandomEngine &, icarusutil::TimeVec &, double, unsigned int)
void configure(const fhicl::ParameterSet &pset) override
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
void generateNoise(CLHEP::HepRandomEngine &, CLHEP::HepRandomEngine &, icarusutil::TimeVec &, detinfo::DetectorPropertiesData const &, double, const geo::PlaneID &, unsigned int) override
std::vector< ComplexVal > FrequencyVec
SBNDataNoiseBoard(const fhicl::ParameterSet &pset)
BoardToNoiseVecMap fIncoherentBoardToNoiseVecMap
std::vector< SigProcPrecision > TimeVec
std::vector< icarusutil::TimeVec > fIncoherentNoiseVec
void GenNoise(std::function< void(double[])> &, const icarusutil::TimeVec &, icarusutil::TimeVec &, float)
std::vector< icarusutil::TimeVec > fCoherentNoiseVec
void ExtractUncorrelatedRMS(float &, int, int) const
tuple dir
Definition: dropbox.py:28
icarusutil::FrequencyVec fNoiseFrequencyVec
BoardToNoiseVecMap fCoherentBoardToNoiseVecMap
void GenerateCorrelatedNoise(CLHEP::HepRandomEngine &, icarusutil::TimeVec &, double, unsigned int)
std::string to_string(WindowPattern const &pattern)
This is the interface class for a tool to handle a GenNoise for the overall response.
art::ServiceHandle< art::TFileService > tfs
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
std::unordered_map< unsigned int, icarusutil::TimeVec > BoardToNoiseVecMap
std::unordered_map< unsigned int, TH1D * > BoardToHistMap
art framework interface to geometry description
BEGIN_PROLOG could also be cout
auto const detProp