CMS 3D CMS Logo

QIE8Simulator.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <cfloat>
3 
5 
7  : preampOutputCut_(-1.0e100),
8  inputGain_(1.0),
9  outputGain_(1.0),
10  runCount_(0),
11  chargeNode_(AbsElectronicODERHS::invalidNode),
12  integrateToGetCharge_(false),
13  useCubic_(false) {}
14 
16  const unsigned chargeNode,
17  const bool interpolateCubic,
18  const double preampOutputCut,
19  const double inputGain,
20  const double outputGain)
21  : solver_(model),
22  preampOutputCut_(preampOutputCut),
23  inputGain_(inputGain),
24  outputGain_(outputGain),
25  runCount_(0),
26  chargeNode_(chargeNode),
27  useCubic_(interpolateCubic) {
28  if (chargeNode >= AbsElectronicODERHS::invalidNode)
29  throw cms::Exception("In QIE8Simulator constructor: invalid charge collection node");
30  integrateToGetCharge_ = chargeNode == model.outputNode();
31  validateGain();
33 }
34 
36  const double dt, const double tstop, const double tDigitize, double* TS, const unsigned lenTS) {
38  throw cms::Exception("In QIE8Simulator::run: preamp model is not set");
39 
40  // Check arguments for validity
41  if (dt <= 0.0)
42  throw cms::Exception("In QIE8Simulator::run: invalid time step");
43 
44  if (tstop < dt)
45  throw cms::Exception("In QIE8Simulator::run: invalid stopping time");
46 
47  if (lenTS && tDigitize < 0.0)
48  throw cms::Exception("In QIE8Simulator::run: can't digitize at t < 0");
49 
50  // Determine the number of time steps
51  const double dsteps = tstop / dt;
52  unsigned n = dsteps;
53  if (dsteps != static_cast<double>(n))
54  ++n;
55  if (n >= maxlen)
56  n = maxlen - 1;
57 
58  // Run the simulation
60  const unsigned numNodes = rhs.numberOfNodes();
61  if (numNodes) {
62  assert(initialConditions_.size() == numNodes);
63  solver_.run(&initialConditions_[0], numNodes, dt, n);
64  } else {
65  // Special situation: the simulation does not
66  // need to solve any ODE. Instead, it will fill
67  // out the output directly.
68  if (!(integrateToGetCharge_ && chargeNode_ == 0U))
69  throw cms::Exception(
70  "In QIE8Simulator::run: "
71  "invalid mode of operation");
72  const unsigned runLen = n + 1U;
73  if (historyBuffer_.size() < runLen)
74  historyBuffer_.resize(runLen);
75  double* hbuf = &historyBuffer_[0];
76  for (unsigned istep = 0; istep < runLen; ++istep, ++hbuf)
77  rhs.calc(istep * dt, nullptr, 0U, hbuf);
78  solver_.setHistory(dt, &historyBuffer_[0], 1U, runLen);
79  }
80 
81  // Truncate the preamp output if this will affect subsequent results
82  if (integrateToGetCharge_ && preampOutputCut_ > -0.9e100)
84 
85  // Digitize the accumulated charge
86  unsigned filled = 0;
87  if (lenTS) {
88  assert(TS);
89  const double lastTStop = solver_.lastMaxT();
90  const double tsWidth = this->adcTSWidth();
91  double oldCharge = getCharge(tDigitize);
92  for (unsigned its = 0; its < lenTS; ++its) {
93  const double t0 = tDigitize + its * tsWidth;
94  if (t0 < lastTStop) {
95  double t1 = t0 + tsWidth;
96  if (t1 > lastTStop)
97  t1 = lastTStop;
98  else
99  ++filled;
100  const double q = getCharge(t1);
101  TS[its] = (q - oldCharge) * outputGain_;
102  oldCharge = q;
103  } else
104  TS[its] = 0.0;
105  }
106  }
107  ++runCount_;
108  return filled;
109 }
110 
111 double QIE8Simulator::preampOutput(const double t) const {
112  if (!runCount_)
113  throw cms::Exception("In QIE8Simulator::preampOutput: please run the simulation first");
114  const unsigned preampNode = getRHS().outputNode();
115  if (preampNode >= AbsElectronicODERHS::invalidNode)
116  return 0.0;
117  else
118  return outputGain_ * solver_.interpolateCoordinate(preampNode, t, useCubic_);
119 }
120 
121 double QIE8Simulator::controlOutput(const double t) const {
122  if (!runCount_)
123  throw cms::Exception("In QIE8Simulator::controlOutput: please run the simulation first");
124  const unsigned controlNode = getRHS().controlNode();
125  if (controlNode >= AbsElectronicODERHS::invalidNode)
126  return 0.0;
127  else
128  return solver_.interpolateCoordinate(controlNode, t, useCubic_);
129 }
130 
132  if (!runCount_)
133  throw cms::Exception("In QIE8Simulator::preampPeakTime: please run the simulation first");
134  const unsigned preampNode = getRHS().outputNode();
135  if (preampNode >= AbsElectronicODERHS::invalidNode)
136  throw cms::Exception("In QIE8Simulator::preampPeakTime: no preamp node in the circuit");
137  return solver_.getPeakTime(preampNode);
138 }
139 
140 void QIE8Simulator::setInitialConditions(const double* values, const unsigned sz) {
141  const unsigned nExpected = getRHS().numberOfNodes();
142  if (sz != nExpected)
143  throw cms::Exception(
144  "In QIE8Simulator::setInitialConditions: unexpected number "
145  "of initial conditions");
146  assert(sz == initialConditions_.size());
147  if (sz) {
148  double* c = &initialConditions_[0];
149  for (unsigned i = 0; i < sz; ++i)
150  *c++ = *values++;
151  }
152 }
153 
155  const unsigned chargeNode,
156  const bool useCubicInterpolation) {
157  if (chargeNode >= AbsElectronicODERHS::invalidNode)
158  throw cms::Exception("In QIE8Simulator::setRHS invalid charge collection node");
159  solver_.setRHS(rhs);
160  chargeNode_ = chargeNode;
161  integrateToGetCharge_ = chargeNode == rhs.outputNode();
162  useCubic_ = useCubicInterpolation;
164 }
165 
167  const unsigned sz = getRHS().numberOfNodes();
168  if (initialConditions_.size() != sz)
169  initialConditions_.resize(sz);
170  if (sz) {
171  double* c = &initialConditions_[0];
172  for (unsigned i = 0; i < sz; ++i)
173  *c++ = 0.0;
174  }
175 }
176 
178  if (inputGain_ <= 0.0)
179  throw cms::Exception("In QIE8Simulator::validateGain: invalid input gain");
180 }
181 
183  if (!runCount_)
184  throw cms::Exception("In QIE8Simulator::lastStopTime: please run the simulation first");
185  return solver_.lastMaxT();
186 }
187 
188 double QIE8Simulator::totalIntegratedCharge(const double t) const {
189  if (!runCount_)
190  throw cms::Exception(
191  "In QIE8Simulator::totalIntegratedCharge: "
192  "please run the simulation first");
193  return outputGain_ * getCharge(t);
194 }
QIE8Simulator::preampOutputCut_
double preampOutputCut_
Definition: QIE8Simulator.h:159
mps_fire.i
i
Definition: mps_fire.py:428
ConstantStepOdeSolver::lastMaxT
double lastMaxT() const
Definition: ConstantStepOdeSolver.h:41
funct::false
false
Definition: Factorize.h:29
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
AbsODERHS::calc
virtual void calc(double t, const double *x, unsigned lenX, double *derivative)=0
ConstantStepOdeSolver::truncateCoordinate
void truncateCoordinate(unsigned which, double minValue, double maxValue)
Definition: ConstantStepOdeSolver.cc:144
QIE8Simulator::getCharge
double getCharge(const double t) const
Definition: QIE8Simulator.h:145
AbsElectronicODERHS::controlNode
virtual unsigned controlNode() const
Definition: AbsElectronicODERHS.h:46
QIE8Simulator::initialConditions_
std::vector< double > initialConditions_
Definition: QIE8Simulator.h:157
QIE8Simulator::inputGain_
double inputGain_
Definition: QIE8Simulator.h:160
QIE8Simulator::QIE8Simulator
QIE8Simulator()
Definition: QIE8Simulator.cc:6
cms::cuda::assert
assert(be >=bs)
QIE8Simulator::maxlen
static const unsigned maxlen
Definition: QIE8Simulator.h:13
QIE8Simulator::zeroInitialConditions
void zeroInitialConditions()
Definition: QIE8Simulator.cc:166
ReggeGribovPartonMC_EposLHC_2760GeV_PbPb_cfi.model
model
Definition: ReggeGribovPartonMC_EposLHC_2760GeV_PbPb_cfi.py:11
ConstantStepOdeSolver::interpolateCoordinate
double interpolateCoordinate(unsigned which, double t, bool cubic=false) const
Definition: ConstantStepOdeSolver.cc:159
QIE8Simulator::controlOutput
double controlOutput(double t) const
Definition: QIE8Simulator.cc:121
AbsElectronicODERHS::outputNode
virtual unsigned outputNode() const =0
ConstantStepOdeSolver::setRHS
void setRHS(const AbsODERHS &rhs)
Definition: ConstantStepOdeSolver.h:30
dt
float dt
Definition: AMPTWrapper.h:136
AbsElectronicODERHS
Definition: AbsElectronicODERHS.h:16
RandomServiceHelper.t1
t1
Definition: RandomServiceHelper.py:256
FrontierCondition_GT_autoExpress_cfi.t0
t0
Definition: FrontierCondition_GT_autoExpress_cfi.py:149
QIE8Simulator::lastStopTime
double lastStopTime() const
Definition: QIE8Simulator.cc:182
QIE8Simulator::historyBuffer_
std::vector< double > historyBuffer_
Definition: QIE8Simulator.h:158
contentValuesCheck.values
values
Definition: contentValuesCheck.py:38
ConstantStepOdeSolver::getPeakTime
double getPeakTime(unsigned which) const
Definition: ConstantStepOdeSolver.cc:9
ConstantStepOdeSolver::setHistory
void setHistory(double dt, const double *data, unsigned dim, unsigned runLen)
Definition: ConstantStepOdeSolver.cc:239
QIE8Simulator::outputGain_
double outputGain_
Definition: QIE8Simulator.h:161
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
QIE8Simulator.h
QIE8Simulator::validateGain
void validateGain() const
Definition: QIE8Simulator.cc:177
QIE8Simulator::solver_
RK4 solver_
Definition: QIE8Simulator.h:156
QIE8Simulator::runCount_
unsigned long runCount_
Definition: QIE8Simulator.h:162
QIE8Simulator::adcTSWidth
static double adcTSWidth()
Definition: QIE8Simulator.h:135
AbsElectronicODERHS::numberOfNodes
virtual unsigned numberOfNodes() const =0
QIE8Simulator::run
unsigned run(double dt, double tstop, double tDigitize, double *TS, unsigned lenTS)
Definition: QIE8Simulator.cc:35
QIE8Simulator::preampOutput
double preampOutput(double t) const
Definition: QIE8Simulator.cc:111
submitPVResolutionJobs.q
q
Definition: submitPVResolutionJobs.py:84
QIE8Simulator::chargeNode_
unsigned chargeNode_
Definition: QIE8Simulator.h:163
QIE8Simulator::getRHS
const AbsElectronicODERHS & getRHS() const
Definition: QIE8Simulator.h:29
QIE8Simulator::totalIntegratedCharge
double totalIntegratedCharge(double t) const
Definition: QIE8Simulator.cc:188
QIE8Simulator::setRHS
void setRHS(const AbsElectronicODERHS &rhs, unsigned chargeNode, bool interpolateCubic=false)
Definition: QIE8Simulator.cc:154
Exception
Definition: hltDiff.cc:245
ConstantStepOdeSolver::run
void run(const double *initialConditions, unsigned lenConditions, double dt, unsigned nSteps)
Definition: ConstantStepOdeSolver.cc:260
QIE8Simulator::preampPeakTime
double preampPeakTime() const
Definition: QIE8Simulator.cc:131
QIE8Simulator::integrateToGetCharge_
bool integrateToGetCharge_
Definition: QIE8Simulator.h:164
QIE8Simulator::setInitialConditions
void setInitialConditions(const double *values, const unsigned len)
Definition: QIE8Simulator.cc:140
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:46
QIE8Simulator::modifiableRHS
AbsElectronicODERHS & modifiableRHS()
Definition: QIE8Simulator.h:138
submitPVValidationJobs.t
string t
Definition: submitPVValidationJobs.py:644
AbsElectronicODERHS::invalidNode
static const unsigned invalidNode
Definition: AbsElectronicODERHS.h:18
QIE8Simulator::useCubic_
bool useCubic_
Definition: QIE8Simulator.h:165