CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GaussianTailNoiseGenerator.cc
Go to the documentation of this file.
2 #include "CLHEP/Random/RandPoissonQ.h"
3 #include "CLHEP/Random/RandGaussQ.h"
4 #include "CLHEP/Random/RandFlat.h"
5 
6 #include <math.h>
7 
8 #include <gsl/gsl_sf_erf.h>
9 #include <gsl/gsl_sf_result.h>
10 
12  gaussDistribution_(eng),
13  poissonDistribution_(eng),
14  flatDistribution_(eng)
15 {
16  // we have two cases: 512 and 768 channels
17  // other cases are not allowed so far (performances issue)
18  for(unsigned int i=0;i<512;++i) channel512_[i]=i;
19  for(unsigned int i=0;i<768;++i) channel768_[i]=i;
20 }
21 
22 // this version is used by pixel
23 void GaussianTailNoiseGenerator::generate(int NumberOfchannels,
24  float threshold,
25  float noiseRMS,
26  std::map<int,float, std::less<int> >& theMap ) {
27 
28  // Gaussian tail probability
29  gsl_sf_result result;
30  int status = gsl_sf_erf_Q_e(threshold, &result);
31 
32  if (status != 0) std::cerr<<"GaussianTailNoiseGenerator::could not compute gaussian tail probability for the threshold chosen"<<std::endl;
33 
34  float probabilityLeft = result.val;
35  float meanNumberOfNoisyChannels = probabilityLeft * NumberOfchannels;
36  int numberOfNoisyChannels = poissonDistribution_.fire(meanNumberOfNoisyChannels);
37 
38  float lowLimit = threshold * noiseRMS;
39  for (int i = 0; i < numberOfNoisyChannels; i++) {
40 
41  // Find a random channel number
42  int theChannelNumber = (int)flatDistribution_.fire(NumberOfchannels);
43 
44  // Find random noise value
45  double noise = generate_gaussian_tail(lowLimit, noiseRMS);
46 
47  // Fill in map
48  theMap[theChannelNumber] = noise;
49 
50  }
51 }
52 
53 // this version is used by strips
54 void GaussianTailNoiseGenerator::generate(int NumberOfchannels,
55  float threshold,
56  float noiseRMS,
57  std::vector<std::pair<int,float> > &theVector ) {
58  // Compute number of channels with noise above threshold
59  // Gaussian tail probability
60  gsl_sf_result result;
61  int status = gsl_sf_erf_Q_e(threshold, &result);
62  if (status != 0) std::cerr<<"GaussianTailNoiseGenerator::could not compute gaussian tail probability for the threshold chosen"<<std::endl;
63  double probabilityLeft = result.val;
64  double meanNumberOfNoisyChannels = probabilityLeft * NumberOfchannels;
65  int numberOfNoisyChannels = poissonDistribution_.fire(meanNumberOfNoisyChannels);
66  if(numberOfNoisyChannels>NumberOfchannels) numberOfNoisyChannels=NumberOfchannels;
67 
68  // Compute the list of noisy channels
69  theVector.reserve(numberOfNoisyChannels);
70  float lowLimit = threshold * noiseRMS;
71  int* channels = getRandomChannels(numberOfNoisyChannels,NumberOfchannels);
72 
73  for (int i = 0; i < numberOfNoisyChannels; i++) {
74  // Find random noise value
75  double noise = generate_gaussian_tail(lowLimit, noiseRMS);
76  // Fill in the vector
77  theVector.push_back(std::pair<int, float>(channels[i], noise));
78  }
79 }
80 
81 /*
82 // used by strips in VR mode
83 void GaussianTailNoiseGenerator::generateRaw(int NumberOfchannels,
84  float noiseRMS,
85  std::vector<std::pair<int,float> > &theVector ) {
86  theVector.reserve(NumberOfchannels);
87  for (int i = 0; i < NumberOfchannels; i++) {
88  // Find random noise value
89  float noise = gaussDistribution_.fire(0.,noiseRMS);
90  // Fill in the vector
91  theVector.push_back(std::pair<int, float>(i,noise));
92  }
93 }
94 */
95 
96 // used by strips in VR mode
98  std::vector<double> &theVector ) {
99  // it was shown that a complex approach, inspired from the ZS case,
100  // does not allow to gain much.
101  // A cut at 2 sigmas only saves 25% of the processing time, while the cost
102  // in terms of meaning is huge.
103  // We therefore use here the trivial approach (as in the early 2XX cycle)
104  unsigned int numberOfchannels = theVector.size();
105  for (unsigned int i = 0; i < numberOfchannels; ++i) {
106  if(theVector[i]==0) theVector[i] = gaussDistribution_.fire(0.,noiseRMS);
107  }
108 }
109 
110 int*
111 GaussianTailNoiseGenerator::getRandomChannels(int numberOfNoisyChannels, int numberOfchannels) {
112  if(numberOfNoisyChannels>numberOfchannels) numberOfNoisyChannels = numberOfchannels;
113  int* array = channel512_;
114  if(numberOfchannels==768) array = channel768_;
115  int theChannelNumber;
116  for(int j=0;j<numberOfNoisyChannels;++j) {
117  theChannelNumber = (int)flatDistribution_.fire(numberOfchannels-j)+j;
118  // swap the two array elements... this is optimized by the compiler
119  int b = array[j];
120  array[j] = array[theChannelNumber];
121  array[theChannelNumber] = b;
122  }
123  return array;
124 }
125 
126 double
127 GaussianTailNoiseGenerator::generate_gaussian_tail(const double a, const double sigma){
128  /* Returns a gaussian random variable larger than a
129  * This implementation does one-sided upper-tailed deviates.
130  */
131 
132  double s = a/sigma;
133 
134  if (s < 1){
135  /*
136  For small s, use a direct rejection method. The limit s < 1
137  can be adjusted to optimise the overall efficiency
138  */
139  double x;
140 
141  do{
142  x = gaussDistribution_.fire(0.,1.0);
143  }
144  while (x < s);
145  return x * sigma;
146 
147  }else{
148 
149  /* Use the "supertail" deviates from the last two steps
150  * of Marsaglia's rectangle-wedge-tail method, as described
151  * in Knuth, v2, 3rd ed, pp 123-128. (See also exercise 11, p139,
152  * and the solution, p586.)
153  */
154 
155  double u, v, x;
156 
157  do{
158  u = flatDistribution_.fire();
159  do{
160  v = flatDistribution_.fire();
161  }while (v == 0.0);
162  x = sqrt(s * s - 2 * log(v));
163  }
164  while (x * u > s);
165  return x * sigma;
166  }
167 }
int i
Definition: DBlmapReader.cc:9
dictionary map
Definition: Association.py:205
T sqrt(T t)
Definition: SSEVec.h:48
tuple result
Definition: query.py:137
int j
Definition: DBlmapReader.cc:9
void generateRaw(float noiseRMS, std::vector< double > &)
double generate_gaussian_tail(const double, const double)
double b
Definition: hdecay.h:120
void generate(int NumberOfchannels, float threshold, float noiseRMS, std::map< int, float > &theMap)
double a
Definition: hdecay.h:121
Definition: DDAxes.h:10
tuple status
Definition: ntuplemaker.py:245
GaussianTailNoiseGenerator(CLHEP::HepRandomEngine &eng)