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 <cmath>
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 
39 }
40 
41 void HcalAmplifier::amplify(CaloSamples& frame, CLHEP::HepRandomEngine* engine) const {
42  if (theIonFeedbackSim) {
44  }
45  pe2fC(frame);
46 
47  if (frame.id().det() == DetId::Hcal && ((frame.id().subdetId() == HcalGenericDetId::HcalGenBarrel) ||
48  (frame.id().subdetId() == HcalGenericDetId::HcalGenEndcap))) {
49  const HcalSimParameters& params = static_cast<const HcalSimParameters&>(theParameterMap->simParameters(frame.id()));
50  if (abs(params.delayQIE()) <= 25)
51  applyQIEdelay(frame, params.delayQIE());
52  }
53 
54  // don't bother for blank signals
55  if (theTimeSlewSim && frame.size() > 4 && frame[4] > 1.e-6) {
57  }
58 
59  // if we are combining pre-mixed digis, we need noise and peds
61  addPedestals(frame, engine);
62  }
63  LogDebug("HcalAmplifier") << frame;
64 }
65 
68  frame *= parameters.photoelectronsToAnalog(frame.id());
69 }
70 
72  DetId detId(cs.id());
73  int maxbin = cs.size();
74  int precisebin = cs.preciseSize();
75  CaloSamples data(detId, maxbin, precisebin); // make a temporary copy
76  data = cs;
77  data.setBlank();
78  data.resetPrecise();
79 
80  for (int i = 0; i < precisebin; i++) {
81  int j = i + 2 * delayQIE;
82  data.preciseAtMod(i) +=
83  // value positive (signal moves earlier in time)
84  delayQIE > 0 ? (j < precisebin ? cs.preciseAt(j) : 0.) :
85  // value = 0 or negative (signal gets delayed)
86  (j < 0 ? 0. : cs.preciseAt(j));
87 
88  int samplebin = (int)i * maxbin / precisebin;
89  data[samplebin] += data.preciseAt(i);
90  }
91 
92  cs = data; // update the sample
93 }
94 
95 void HcalAmplifier::addPedestals(CaloSamples& frame, CLHEP::HepRandomEngine* engine) const {
96  assert(theDbService != nullptr);
97  HcalGenericDetId hcalGenDetId(frame.id());
98  HcalGenericDetId::HcalGenericSubdetector hcalSubDet = hcalGenDetId.genericSubdet();
99 
100  if (!((frame.id().subdetId() == HcalGenericDetId::HcalGenBarrel) ||
101  (frame.id().subdetId() == HcalGenericDetId::HcalGenEndcap) ||
102  (frame.id().subdetId() == HcalGenericDetId::HcalGenForward) ||
103  (frame.id().subdetId() == HcalGenericDetId::HcalGenOuter)))
104  return;
105 
106  if (hcalGenDetId.isHcalCastorDetId())
107  return;
108  if (hcalGenDetId.isHcalZDCDetId())
109  return;
110 
111  const HcalCalibrationWidths& calibWidths = theDbService->getHcalCalibrationWidths(hcalGenDetId);
112  const HcalCalibrations& calibs = theDbService->getHcalCalibrations(hcalGenDetId);
113 
114  double noise[32] = {0.}; //big enough
115  if (addNoise_) {
116  double gauss[32]; //big enough
117  for (int i = 0; i < frame.size(); i++)
118  gauss[i] = CLHEP::RandGaussQ::shoot(engine, 0., 1.);
119  makeNoise(hcalSubDet, calibWidths, frame.size(), gauss, noise);
120  }
121 
122  if (!preMixDigi_) { // if we are doing initial premix, no pedestals
123  for (int tbin = 0; tbin < frame.size(); ++tbin) {
124  int capId = (theStartingCapId + tbin) % 4;
125  double pedestal = calibs.pedestal(capId) + noise[tbin];
126  frame[tbin] += pedestal;
127  }
128  }
129 }
130 
133  int fFrames,
134  double* fGauss,
135  double* fNoise) const {
136  // This is a simplified noise generation scheme using only the diagonal elements
137  // (proposed by Salavat Abduline).
138  // This is direct adaptation of the code in HcalPedestalWidth.cc
139 
140  // average over capId's
141  double s_xx_mean = 0.25 * (width.pedestal(0) * width.pedestal(0) + width.pedestal(1) * width.pedestal(1) +
142  width.pedestal(2) * width.pedestal(2) + width.pedestal(3) * width.pedestal(3));
143 
144  // Off-diagonal element approximation
145  // In principle should come from averaging the values of elements (0.1), (1,2), (2,3), (3,0)
146  // For now use the definition below (but keep structure of the code structure for development)
147  double s_xy_mean = -0.5 * s_xx_mean;
148  // Use different parameter for HF to reproduce the noise rate after zero suppression.
149  // Steven Won/Jim Hirschauer/Radek Ofierzynski 18.03.2010
150  if (hcalSubDet == HcalGenericDetId::HcalGenForward)
151  s_xy_mean = 0.08 * s_xx_mean;
152 
153  double term = s_xx_mean * s_xx_mean - 2. * s_xy_mean * s_xy_mean;
154 
155  if (term < 0.)
156  term = 1.e-50;
157  double sigma = sqrt(0.5 * (s_xx_mean + sqrt(term)));
158  double corr = sigma == 0. ? 0. : 0.5 * s_xy_mean / sigma;
159 
160  for (int i = 0; i < fFrames; i++) {
161  fNoise[i] = fGauss[i] * sigma;
162  if (i > 0)
163  fNoise[i] += fGauss[i - 1] * corr;
164  if (i < fFrames - 1)
165  fNoise[i] += fGauss[i + 1] * corr;
166  }
167 }
void setDbService(const HcalDbService *service)
the Producer will probably update this every event
const CaloVNoiseSignalGenerator * theNoiseSignalGenerator
Definition: HcalAmplifier.h:56
const CaloVSimParameterMap * theParameterMap
Definition: HcalAmplifier.h:55
const HcalTimeSlew * theTimeSlew
Definition: HcalAmplifier.h:37
void pe2fC(CaloSamples &frame) const
assert(be >=bs)
Main class for Parameters in different subdetectors.
const HcalCalibrationWidths & getHcalCalibrationWidths(const HcalGenericDetId &fId) const
HcalAmplifier(const CaloVSimParameterMap *parameters, bool addNoise, bool PreMix1, bool PreMix2)
constexpr double pedestal(int fCapId) const
get pedestal for capid=0..3
void addThermalNoise(CaloSamples &samples, CLHEP::HepRandomEngine *)
const HcalCalibrations & getHcalCalibrations(const HcalGenericDetId &fId) const
dictionary corr
const HcalDbService * theDbService
Definition: HcalAmplifier.h:54
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
virtual const CaloSimParameters & simParameters(const DetId &id) const =0
HcalTimeSlewSim * theTimeSlewSim
Definition: HcalAmplifier.h:58
void applyQIEdelay(CaloSamples &frame, int delayQIE) const
void makeNoise(HcalGenericDetId::HcalGenericSubdetector hcalSubDet, const HcalCalibrationWidths &width, int fFrames, double *fGauss, double *fNoise) const
HcalGenericSubdetector genericSubdet() const
Definition: DetId.h:17
unsigned theStartingCapId
Definition: HcalAmplifier.h:59
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
HPDIonFeedbackSim * theIonFeedbackSim
Definition: HcalAmplifier.h:57
void delay(CaloSamples &samples, CLHEP::HepRandomEngine *, const HcalTimeSlew *hcalTimeSlew_delay) const
void setDbService(const HcalDbService *service)
bool contains(const DetId &detId) const
virtual void amplify(CaloSamples &linearFrame, CLHEP::HepRandomEngine *) const
#define LogDebug(id)
void addPedestals(CaloSamples &frame, CLHEP::HepRandomEngine *) const