CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HPDIonFeedbackSim.cc
Go to the documentation of this file.
1 
2 // --------------------------------------------------------
3 // A class to simulated HPD ion feedback noise.
4 // The deliverable of the class is the ion feedback noise
5 // for an HcalDetId units of fC or GeV
6 //
7 // Project: HPD ion feedback
8 // Author: T.Yetkin University of Iowa, Feb. 16, 2010
9 // --------------------------------------------------------
10 
23 
24 
25 using namespace edm;
26 using namespace std;
27 
28 // constants for simulation/parameterization
29 double pe2Charge = 0.333333; // fC/p.e.
30 
32 : theDbService(0), theShapes(shapes),
33  theRandBinomial(0), theRandFlat(0), theRandGauss(0), theRandPoissonQ(0)
34 {
35 }
36 
38 {
40  if (theRandFlat) delete theRandFlat;
41  if (theRandGauss) delete theRandGauss;
42  if (theRandPoissonQ) delete theRandPoissonQ;
43 }
44 
45 
46 void HPDIonFeedbackSim::setRandomEngine(CLHEP::HepRandomEngine & engine)
47 {
49  if (theRandFlat) delete theRandFlat;
50  if (theRandGauss) delete theRandGauss;
51  if (theRandPoissonQ) delete theRandPoissonQ;
52 
53  theRandBinomial = new CLHEP::RandBinomial(engine);
54  theRandFlat = new CLHEP::RandFlat(engine);
55  theRandGauss = new CLHEP::RandGaussQ(engine);
56  theRandPoissonQ = new CLHEP::RandPoissonQ(engine);
57 }
58 
59 double HPDIonFeedbackSim::getIonFeedback(DetId detId, double signal, double pedWidth, bool doThermal, bool isInGeV)
60 {
61 
62  // HcalDetId id = detId;
63 
64  double GeVperfC = 1.;
65  if(isInGeV) GeVperfC = 1./fCtoGeV(detId);
66 
67  double charge = signal / GeVperfC;
68 
69  double noise = 0.; // fC
70  if (charge > 3. * pedWidth) { // 3 sigma away from pedestal mean
71  int npe = int (charge / pe2Charge);
72  if(doThermal) {
73  double electronEmission = 0.08;
74  npe += theRandPoissonQ->fire(electronEmission);
75  }
76 
77  noise = correctPE(detId, npe) - npe;
78  }
79  return (noise * GeVperfC);
80 
81 }
82 
83 
84 double HPDIonFeedbackSim::correctPE(const DetId & detId, double npe) const
85 {
86  double rateInTail = 0.000211988;//read this from XML file
87  double rateInSecondTail = 4.61579e-06;//read this from XML file
88 
89  // three gauss fit is applied to data to get ion feedback distribution
90  // parameters (in fC)
91  // first gaussian
92  // double p0 = 9.53192e+05;
93  // double p1 = -3.13653e-01;
94  // double p2 = 2.78350e+00;
95 
96  // second gaussian
97  // double p3 = 2.41611e+03;
98  double p4 = 2.06117e+01;
99  double p5 = 1.09239e+01;
100 
101  // third gaussian
102  // double p6 = 3.42793e+01;
103  double p7 = 5.45548e+01;
104  double p8 = 1.59696e+01;
105 
106  double noise = 0.; // fC
107  int nFirst = (int)(theRandBinomial->fire(npe, rateInTail));
108  int nSecond = (int)(theRandBinomial->fire(npe, rateInSecondTail));
109 
110  for (int j = 0; j < nFirst; ++j) {
111  noise += theRandGauss->fire(p4, p5);
112  }
113  for (int j = 0; j < nSecond; ++j) {
114  noise += theRandGauss->fire(p7, p8);
115  }
116 
117  return npe + std::max(noise/pe2Charge, 0.);
118 }
119 
120 
122 {
123  // make some chance to add a PE (with a chance of feedback)
124  // for each time sample
125  double meanPE = 0.02;
126  DetId detId(samples.id());
127  int nSamples = samples.size();
128  const CaloVShape * shape = theShapes->shape(detId);
129  for(int i = 0; i < nSamples; ++i)
130  {
131  double npe = theRandPoissonQ->fire(meanPE);
132  // TODOprobably should time-smear these
133  if(npe > 0.)
134  {
135  // chance of feedback
136  npe = correctPE(detId, npe);
137  for(int j = i; j < nSamples; ++j)
138  {
139  double timeFromPE = (j-i) * 25.;
140  samples[j] += (*shape)(timeFromPE) * npe;
141  }
142  }
143  }
144 }
145 
146 
147 double HPDIonFeedbackSim::fCtoGeV(const DetId & detId) const
148 {
149  assert(theDbService != 0);
150  HcalGenericDetId hcalGenDetId(detId);
151  const HcalGain* gains = theDbService->getGain(hcalGenDetId);
152  const HcalGainWidth* gwidths = theDbService->getGainWidth(hcalGenDetId);
153  if (!gains || !gwidths )
154  {
155  edm::LogError("HcalAmplifier") << "Could not fetch HCAL conditions for channel " << hcalGenDetId;
156  }
157  // only one gain will be recorded per channel, so just use capID 0 for now
158  double result = gains->getValue(0);
159  return result;
160 }
HPDIonFeedbackSim(const edm::ParameterSet &, const CaloShapes *shapes)
need a shaper in order to set thermal noise
const HcalGainWidth * getGainWidth(const HcalGenericDetId &fId) const
int i
Definition: DBlmapReader.cc:9
void addThermalNoise(CaloSamples &samples)
CLHEP::RandGaussQ * theRandGauss
double fCtoGeV(const DetId &detId) const
CLHEP::RandFlat * theRandFlat
Electronic response of the preamp.
Definition: CaloVShape.h:11
float getValue(int fCapId) const
get value for capId = 0..3
Definition: HcalGain.h:20
double pe2Charge
double charge(const std::vector< uint8_t > &Ampls)
const HcalDbService * theDbService
virtual double correctPE(const DetId &detId, double npe) const
const T & max(const T &a, const T &b)
void setRandomEngine(CLHEP::HepRandomEngine &engine)
need a shaper in order to set thermal noise
double p4[4]
Definition: TauolaWrapper.h:92
tuple result
Definition: query.py:137
int j
Definition: DBlmapReader.cc:9
CLHEP::RandBinomial * theRandBinomial
Definition: DetId.h:18
CLHEP::RandPoissonQ * theRandPoissonQ
int size() const
get the size
Definition: CaloSamples.h:24
const HcalGain * getGain(const HcalGenericDetId &fId) const
const CaloShapes * theShapes
DetId id() const
get the (generic) id
Definition: CaloSamples.h:21
double getIonFeedback(DetId detId, double signal, double pedWidth, bool doThermal, bool isInGeV)
virtual const CaloVShape * shape(const DetId &detId) const
Definition: CaloShapes.h:15