All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SBNDThermalNoiseServiceInFreq_service.cc
Go to the documentation of this file.
1 // SBNDThermalNoiseServiceInFreq.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 //**********************************************************************
19 
21 SBNDThermalNoiseServiceInFreq(fhicl::ParameterSet const& pset)
22  : fRandomSeed(0), fLogLevel(1), m_pran(nullptr), fNoiseEngine(nullptr)
23 {
24  const string myname = "SBNDThermalNoiseServiceInFreq::ctor: ";
25  fNoiseArrayPoints = pset.get<unsigned int>("NoiseArrayPoints");
26  bool haveSeed = pset.get_if_present<int>("RandomSeed", fRandomSeed);
27 
28 
29  fShapingTimeOrder = { {0.5, 0 }, {1.0, 1}, {2.0, 2}, {3.0, 3} };
30  fNoiseWidth = pset.get< double >("NoiseWidth");
31  fNoiseRand = pset.get< double >("NoiseRand");
32  fLowCutoff = pset.get< double >("LowCutoff");
33 
34 
35  if ( fRandomSeed == 0 ) haveSeed = false;
36  pset.get_if_present<int>("LogLevel", fLogLevel);
37  int seed = fRandomSeed;
38 
39  string rname = "SBNDThermalNoiseServiceInFreq";
40  if ( haveSeed ) {
41  if ( fLogLevel > 0 ) cout << myname << "WARNING: Using hardwired seed." << endl;
42  m_pran = new HepJamesRandom(seed);
43  } else {
44  if ( fLogLevel > 0 ) cout << myname << "Using NuRandomService." << endl;
45  art::ServiceHandle<NuRandomService> seedSvc;
46  m_pran = new HepJamesRandom;
47  if ( fLogLevel > 0 ) cout << myname << " Initial seed: " << m_pran->getSeed() << endl;
48  seedSvc->registerEngine(NuRandomService::CLHEPengineSeeder(m_pran), rname);
49  }
50  if ( fLogLevel > 0 ) cout << myname << " Registered seed: " << m_pran->getSeed() << endl;
51  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
52  generateNoise(clockData);
53  if ( fLogLevel > 1 ) print() << endl;
54 }
55 
56 //**********************************************************************
57 
59 SBNDThermalNoiseServiceInFreq(fhicl::ParameterSet const& pset, art::ActivityRegistry&)
61 
62 //**********************************************************************
63 
65  const string myname = "SBNDThermalNoiseServiceInFreq::dtor: ";
66  if ( fLogLevel > 0 ) {
67  cout << myname << "Deleting random engine with seed " << m_pran->getSeed() << endl;
68  }
69  delete m_pran;
70 }
71 
72 //**********************************************************************
73 
75  Channel chan, AdcSignalVector& sigs) const {
76 
77  //Get services.
78  art::ServiceHandle<geo::Geometry> geo;
79  art::ServiceHandle<util::SignalShapingServiceSBND> sss;
80  art::ServiceHandle<util::LArFFT> fFFT;
81 
82  //Generate Noise:
83  size_t view = (size_t)geo->View(chan);
84 
85  double noise_factor;
86  auto tempNoiseVec = sss->GetNoiseFactVec();
87  double shapingTime = 2.0; //sss->GetShapingTime(chan);
88  double asicGain = sss->GetASICGain(chan);
89 
90  size_t fNTicks = fFFT->FFTSize();
91 
92 
93  if (fShapingTimeOrder.find( shapingTime ) != fShapingTimeOrder.end() ) {
94  noise_factor = tempNoiseVec[view].at( fShapingTimeOrder.find( shapingTime )->second );
95  noise_factor *= asicGain/4.7;
96  }
97  else {
98  throw cet::exception("SBNDThermalNoiseServiceInFreq_service.cc")
99  << "\033[93m"
100  << "Shaping Time recieved from signalshapingservices_sbnd.fcl is not one of the allowed values"
101  << std::endl
102  << "Allowed values: 0.5, 1.0, 2.0, 3.0 us"
103  << "\033[00m"
104  << std::endl;
105  }
106 
107 
108  CLHEP::RandFlat flat(*fNoiseEngine, -1, 1);
109 
110 
111  if (sigs.size() != fNTicks)
112  throw cet::exception("SBNDThermalNoiseServiceInFreq_service.cc")
113  << "\033[93m"
114  << "Frequency noise vector length must match fNTicks (FFT size)"
115  << " ... " << sigs.size() << " != " << fNTicks
116  << "\033[00m"
117  << std::endl;
118 
119  // noise in frequency space
120  std::vector<TComplex> noiseFrequency(fNTicks / 2 + 1, 0.);
121 
122  double pval = 0.;
123  double lofilter = 0.;
124  double phase = 0.;
125  double rnd[2] = {0.};
126 
127  // width of frequencyBin in kHz
128  double binWidth = 1.0 / (fNTicks * fSampleRate * 1.0e-6);
129 
130  for (size_t i = 0; i < fNTicks / 2 + 1; ++i) {
131  // exponential noise spectrum
132  flat.fireArray(2, rnd, 0, 1);
133  std::cout << "rnd[0]: " << rnd[0] << std::endl;
134  std::cout << "rnd[1]: " << rnd[1] << std::endl;
135 
136  pval = noise_factor * exp(-(double)i * binWidth / fNoiseWidth);
137  // low frequency cutoff
138  lofilter = 1.0 / (1.0 + exp(-(i - fLowCutoff / binWidth) / 0.5));
139  // randomize 10%
140 
141  pval *= lofilter * ((1 - fNoiseRand) + 2 * fNoiseRand * rnd[0]);
142 
143  /*
144  //if not from histo or in time --> then hardcoded freq. spectrum
145  if ( !fGetNoiseFromHisto )
146  {
147  pval = noise_factor * exp(-(double)i * binWidth / fNoiseWidth);
148  // low frequency cutoff
149  lofilter = 1.0 / (1.0 + exp(-(i - fLowCutoff / binWidth) / 0.5));
150  // randomize 10%
151 
152  pval *= lofilter * ((1 - fNoiseRand) + 2 * fNoiseRand * rnd[0]);
153  }
154 
155 
156  else
157  {
158 
159  pval = fNoiseHist->GetBinContent(i) * ((1 - fNoiseRand) + 2 * fNoiseRand * rnd[0]) * noise_factor;
160  }
161  */
162  phase = rnd[1] * 2.*TMath::Pi();
163  TComplex tc(pval * cos(phase), pval * sin(phase));
164  noiseFrequency.at(i) += tc;
165  }
166 
167 
168  // inverse FFT MCSignal
169  fFFT->DoInvFFT(noiseFrequency, sigs);
170 
171  noiseFrequency.clear();
172 
173  // multiply each noise value by fNTicks as the InvFFT
174  // divides each bin by fNTicks assuming that a forward FFT
175  // has already been done.
176  for (unsigned int i = 0; i < sigs.size(); ++i) {
177  sigs.at(i) *= 1.*fNTicks;
178  }
179 
180  return 0;
181 }
182 
183 
184 //**********************************************************************
185 
186 ostream& SBNDThermalNoiseServiceInFreq::print(ostream& out, string prefix) const {
187  out << prefix << "SBNDThermalNoiseServiceInFreq: " << endl;
188 
189  out << prefix << " LogLevel: " << fLogLevel << endl;
190  out << prefix << " RandomSeed: " << fRandomSeed << endl;
191  out << prefix << " NoiseArrayPoints: " << fNoiseArrayPoints << endl;
192 
193  return out;
194 }
195 
196 
197 
198 //**********************************************************************
199 
200 DEFINE_ART_SERVICE_INTERFACE_IMPL(SBNDThermalNoiseServiceInFreq, ChannelNoiseService)
201 
202 //**********************************************************************
double fNoiseRand
fraction of random &quot;wiggle&quot; in noise in freq. spectrum
unsigned int fNoiseArrayPoints
number of points in randomly generated noise array
double fLowCutoff
low frequency filter cutoff (kHz)
SBNDThermalNoiseServiceInFreq(fhicl::ParameterSet const &pset)
unsigned int seed
std::ostream & print(std::ostream &out=std::cout, std::string prefix="") const override
int addNoise(detinfo::DetectorClocksData const &clockData, Channel chan, AdcSignalVector &sigs) const override
int fRandomSeed
Seed for random number service. If absent or zero, use SeedSvc.
double fNoiseWidth
exponential noise width (kHz)
std::vector< AdcSignal > AdcSignalVector
Contains all timing reference information for the detector.
virtual void generateNoise(detinfo::DetectorClocksData const &)
BEGIN_PROLOG could also be cout
int fLogLevel
Log message level: 0=quiet, 1=init only, 2+=every event.