CMS 3D CMS Logo

HcalAmplifier.cc
Go to the documentation of this file.
15 
17 
18 #include "CLHEP/Random/RandGaussQ.h"
19 #include "CLHEP/Random/RandFlat.h"
20 
21 #include <cmath>
22 #include <math.h>
23 
24 HcalAmplifier::HcalAmplifier(const CaloVSimParameterMap * parameters, bool addNoise, bool PreMix1, bool PreMix2) :
25  theDbService(nullptr),
26  theParameterMap(parameters),
27  theNoiseSignalGenerator(nullptr),
28  theIonFeedbackSim(nullptr),
29  theTimeSlewSim(nullptr),
30  theStartingCapId(0),
31  addNoise_(addNoise),
32  preMixDigi_(PreMix1),
33  preMixAdd_(PreMix2)
34 { }
35 
36 
38  theDbService = service;
40 }
41 
42 
43 void HcalAmplifier::amplify(CaloSamples & frame, CLHEP::HepRandomEngine* engine) const {
45  {
46  theIonFeedbackSim->addThermalNoise(frame, engine);
47  }
48  pe2fC(frame);
49  // don't bother for blank signals
50  if(theTimeSlewSim && frame.size()>4 && frame[4] > 1.e-6)
51  {
52  theTimeSlewSim->delay(frame, engine);
53  }
54 
55  // if we are combining pre-mixed digis, we need noise and peds
57  {
58  addPedestals(frame, engine);
59  }
60  LogDebug("HcalAmplifier") << frame;
61 }
62 
63 
64 void HcalAmplifier::pe2fC(CaloSamples & frame) const
65 {
67  frame *= parameters.photoelectronsToAnalog(frame.id());
68 }
69 
70 void HcalAmplifier::addPedestals(CaloSamples & frame, CLHEP::HepRandomEngine* engine) const
71 {
72  assert(theDbService != 0);
73  HcalGenericDetId hcalGenDetId(frame.id());
74  HcalGenericDetId::HcalGenericSubdetector hcalSubDet = hcalGenDetId.genericSubdet();
75 
76  if ( !( (frame.id().subdetId()==HcalGenericDetId::HcalGenBarrel) ||
79  (frame.id().subdetId()==HcalGenericDetId::HcalGenOuter) ) ) return;
80 
81  if(hcalGenDetId.isHcalCastorDetId()) return;
82  if(hcalGenDetId.isHcalZDCDetId()) return;
83 
84  const HcalCalibrationWidths & calibWidths = theDbService->getHcalCalibrationWidths(hcalGenDetId);
85  const HcalCalibrations& calibs = theDbService->getHcalCalibrations(hcalGenDetId);
86 
87  double noise [32] = {0.}; //big enough
88  if(addNoise_)
89  {
90  double gauss [32]; //big enough
91  for (int i = 0; i < frame.size(); i++) gauss[i] = CLHEP::RandGaussQ::shoot(engine, 0., 1.);
92  makeNoise(hcalSubDet, calibWidths, frame.size(), gauss, noise);
93  }
94 
95  if(!preMixDigi_){ // if we are doing initial premix, no pedestals
96  for (int tbin = 0; tbin < frame.size(); ++tbin) {
97  int capId = (theStartingCapId + tbin)%4;
98  double pedestal = calibs.pedestal(capId) + noise[tbin];
99  frame[tbin] += pedestal;
100  }
101  }
102 }
103 
104 void HcalAmplifier::makeNoise(HcalGenericDetId::HcalGenericSubdetector hcalSubDet, const HcalCalibrationWidths& width, int fFrames, double* fGauss, double* fNoise) const
105 {
106  // This is a simplified noise generation scheme using only the diagonal elements
107  // (proposed by Salavat Abduline).
108  // This is direct adaptation of the code in HcalPedestalWidth.cc
109 
110  // average over capId's
111  double s_xx_mean = 0.25 * (width.pedestal(0)*width.pedestal(0) +
112  width.pedestal(1)*width.pedestal(1) +
113  width.pedestal(2)*width.pedestal(2) +
114  width.pedestal(3)*width.pedestal(3));
115 
116 
117  // Off-diagonal element approximation
118  // In principle should come from averaging the values of elements (0.1), (1,2), (2,3), (3,0)
119  // For now use the definition below (but keep structure of the code structure for development)
120  double s_xy_mean = -0.5 * s_xx_mean;
121  // Use different parameter for HF to reproduce the noise rate after zero suppression.
122  // Steven Won/Jim Hirschauer/Radek Ofierzynski 18.03.2010
123  if (hcalSubDet == HcalGenericDetId::HcalGenForward) s_xy_mean = 0.08 * s_xx_mean;
124 
125  double term = s_xx_mean*s_xx_mean - 2.*s_xy_mean*s_xy_mean;
126 
127  if (term < 0.) term = 1.e-50 ;
128  double sigma = sqrt (0.5 * (s_xx_mean + sqrt(term)));
129  double corr = sigma == 0. ? 0. : 0.5*s_xy_mean / sigma;
130 
131  for (int i = 0; i < fFrames; i++) {
132  fNoise [i] = fGauss[i]*sigma;
133  if (i > 0) fNoise [i] += fGauss[i-1]*corr;
134  if (i < fFrames-1) fNoise [i] += fGauss[i+1]*corr;
135  }
136 }
137 
#define LogDebug(id)
void setDbService(const HcalDbService *service)
the Producer will probably update this every event
const CaloVNoiseSignalGenerator * theNoiseSignalGenerator
Definition: HcalAmplifier.h:50
const CaloVSimParameterMap * theParameterMap
Definition: HcalAmplifier.h:49
double pedestal(int fCapId) const
get pedestal for capid=0..3
#define nullptr
Main class for Parameters in different subdetectors.
HcalAmplifier(const CaloVSimParameterMap *parameters, bool addNoise, bool PreMix1, bool PreMix2)
void addThermalNoise(CaloSamples &samples, CLHEP::HepRandomEngine *)
void delay(CaloSamples &samples, CLHEP::HepRandomEngine *) const
double pedestal(int fCapId) const
get pedestal width for capid=0..3
const HcalDbService * theDbService
Definition: HcalAmplifier.h:48
T sqrt(T t)
Definition: SSEVec.h:18
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
bool contains(const DetId &detId) const
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
const HcalCalibrationWidths & getHcalCalibrationWidths(const HcalGenericDetId &fId) const
virtual void amplify(CaloSamples &linearFrame, CLHEP::HepRandomEngine *) const
HcalTimeSlewSim * theTimeSlewSim
Definition: HcalAmplifier.h:52
JetCorrectorParameters corr
Definition: classes.h:5
int size() const
get the size
Definition: CaloSamples.h:24
unsigned theStartingCapId
Definition: HcalAmplifier.h:53
void addPedestals(CaloSamples &frame, CLHEP::HepRandomEngine *) const
void pe2fC(CaloSamples &frame) const
void makeNoise(HcalGenericDetId::HcalGenericSubdetector hcalSubDet, const HcalCalibrationWidths &width, int fFrames, double *fGauss, double *fNoise) const
DetId id() const
get the (generic) id
Definition: CaloSamples.h:21
HPDIonFeedbackSim * theIonFeedbackSim
Definition: HcalAmplifier.h:51
HcalGenericSubdetector genericSubdet() const
const HcalCalibrations & getHcalCalibrations(const HcalGenericDetId &fId) const
void setDbService(const HcalDbService *service)
double photoelectronsToAnalog() const
the factor which goes from photoelectrons to whatever gets read by ADCs