File indexing completed on 2024-04-06 11:58:05
0001 #ifndef CalibCalorimetry_HcalAlgos_QIE8Simulator_h_
0002 #define CalibCalorimetry_HcalAlgos_QIE8Simulator_h_
0003
0004 #include "CalibCalorimetry/HcalAlgos/interface/ConstantStepOdeSolver.h"
0005 #include "CalibCalorimetry/HcalAlgos/interface/AbsElectronicODERHS.h"
0006
0007
0008
0009
0010
0011 class QIE8Simulator {
0012 public:
0013 static const unsigned maxlen = HcalInterpolatedPulse::maxlen;
0014
0015
0016
0017 QIE8Simulator();
0018
0019
0020 QIE8Simulator(const AbsElectronicODERHS& model,
0021 unsigned chargeNode,
0022 bool interpolateCubic = false,
0023 double preampOutputCut = -1.0e100,
0024 double inputGain = 1.0,
0025 double outputGain = 1.0);
0026
0027 void setRHS(const AbsElectronicODERHS& rhs, unsigned chargeNode, bool interpolateCubic = false);
0028
0029 inline const AbsElectronicODERHS& getRHS() const {
0030 const AbsODERHS* ptr = solver_.getRHS();
0031 if (!ptr)
0032 throw cms::Exception("In QIE8Simulator::getRHS: RHS is not set");
0033 return *(static_cast<const AbsElectronicODERHS*>(ptr));
0034 }
0035
0036
0037 inline double getInputGain() const { return inputGain_; }
0038 inline double getOutputGain() const { return outputGain_; }
0039 inline unsigned long getRunCount() const { return runCount_; }
0040 inline double getPreampOutputCut() const { return preampOutputCut_; }
0041
0042
0043 inline unsigned nParameters() const { return getRHS().nParameters(); }
0044 inline double getParameter(const unsigned which) const { return getRHS().getParameter(which); }
0045
0046
0047 inline void setInputGain(const double g) {
0048 inputGain_ = g;
0049 validateGain();
0050 }
0051 inline void setOutputGain(const double g) {
0052 outputGain_ = g;
0053 validateGain();
0054 }
0055
0056
0057 void setInitialConditions(const double* values, const unsigned len);
0058 void zeroInitialConditions();
0059
0060
0061 inline void setParameter(const unsigned which, const double p) { modifiableRHS().setParameter(which, p); }
0062 inline void setLeadingParameters(const double* values, const unsigned len) {
0063 modifiableRHS().setLeadingParameters(values, len);
0064 }
0065
0066
0067 inline void setPreampOutputCut(const double p) { preampOutputCut_ = p; }
0068
0069
0070 template <class Signal>
0071 inline void setInputSignal(const Signal& inputSignal) {
0072 modifiableRHS().setInputPulse(inputSignal);
0073 modifiableRHS().inputPulse() *= inputGain_;
0074 }
0075
0076
0077 inline const HcalInterpolatedPulse& getInputSignal() const { return getRHS().inputPulse(); }
0078
0079
0080
0081 template <class Real>
0082 inline void setInputShape(const Real* values, const unsigned len) {
0083 modifiableRHS().inputPulse().setShape(values, len);
0084 modifiableRHS().inputPulse() *= inputGain_;
0085 }
0086
0087
0088 inline void scaleInputSignal(const double s) { modifiableRHS().inputPulse() *= s; }
0089
0090
0091 inline double getInputAmplitude() const { return getRHS().inputPulse().getPeakValue() / inputGain_; }
0092
0093 inline void setInputAmplitude(const double a) { modifiableRHS().inputPulse().setPeakValue(a * inputGain_); }
0094
0095
0096 inline double getInputIntegral() const { return getRHS().inputPulse().getIntegral() / inputGain_; }
0097
0098 inline void setInputIntegral(const double d) { modifiableRHS().inputPulse().setIntegral(d * inputGain_); }
0099
0100
0101 inline double getInputStartTime() const { return getRHS().inputPulse().getStartTime(); }
0102
0103 inline void setInputStartTime(const double newStartTime) { modifiableRHS().inputPulse().setStartTime(newStartTime); }
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 unsigned run(double dt, double tstop, double tDigitize, double* TS, unsigned lenTS);
0123
0124
0125 double lastStopTime() const;
0126 double totalIntegratedCharge(double t) const;
0127 double preampPeakTime() const;
0128
0129
0130
0131 double preampOutput(double t) const;
0132 double controlOutput(double t) const;
0133
0134
0135 static inline double adcTSWidth() { return 25.0; }
0136
0137 private:
0138 inline AbsElectronicODERHS& modifiableRHS() {
0139 AbsODERHS* ptr = solver_.getRHS();
0140 if (!ptr)
0141 throw cms::Exception("In QIE8Simulator::modifiableRHS: no RHS");
0142 return *(static_cast<AbsElectronicODERHS*>(ptr));
0143 }
0144
0145 inline double getCharge(const double t) const {
0146 double q;
0147 if (integrateToGetCharge_)
0148 q = solver_.interpolateIntegrated(chargeNode_, t, useCubic_);
0149 else
0150 q = solver_.interpolateCoordinate(chargeNode_, t, useCubic_);
0151 return q;
0152 }
0153
0154 void validateGain() const;
0155
0156 RK4 solver_;
0157 std::vector<double> initialConditions_;
0158 std::vector<double> historyBuffer_;
0159 double preampOutputCut_;
0160 double inputGain_;
0161 double outputGain_;
0162 unsigned long runCount_;
0163 unsigned chargeNode_;
0164 bool integrateToGetCharge_;
0165 bool useCubic_;
0166 };
0167
0168 #endif