cePulser.h
Go to the documentation of this file.
1 // cePulser.cxx
2 //
3 // David Adams
4 // January 2019
5 //
6 // ProtoDUNE CE pulser voltage and induced charge. See the circuit diagram
7 // http://internal.dunescience.org/people/dladams/docs/2019/pulserCircuit.pdf
8 
9 #ifndef cePulser_H
10 #define cePulser_H
11 
12 #include "TF1.h"
13 #include <string>
14 #include <iostream>
15 
16 //**********************************************************************
17 
18 // Function that returns the voltage on the FE injection capacitor.
19 // ia - gain setting (minus inverts charge)
20 // rLines - FPGA IO resistances (high to low) [kOhm]
21 // r6 - Fixed resistance to Vrail.
22 // cinj - Injection capacitance (fF)
23 // Returns charge in fC.
24 // Use cinj = 1 to get voltage in mV.
25 inline
26 double cePulserVoltage(int iaIn, const double rfLines[6], double r6, double vfpga) {
27  using Index = unsigned int;
28  if ( r6 < 0.0 ) return 0.0;
29  if ( iaIn < 0 ) return 0.0;
30  if ( iaIn > 63 ) return 0.0;
31  Index ia = iaIn;
32  double con1 = 0.0; // Conductance to V=0
33  double con2 = r6 > 0.0 ? 1.0/r6 : 0.0; // Conductance to V=Vfpga
34  for ( Index ilin=0; ilin<6; ++ilin ) {
35  double rfLine = rfLines[ilin];
36  if ( rfLine <= 0.0 ) continue; // Means this line is disconnected.
37  double conLine = 1.0/rfLine;
38  // If this bit is set then the path is to Vfpga.
39  if ( (ia >> ilin) & 0x1) con2 += conLine;
40  // Otherwise, the path is to ground.
41  else con1 += conLine;
42  }
43  double fac = 1.0;
44  if ( con1 > 0.0 ) {
45  double rtot = 1.0/con1 + 1.0/con2;
46  fac = 1.0/con1/rtot;
47  }
48  //const double vrail = 1.8;
49  return fac*vfpga;
50 }
51 
52 //**********************************************************************
53 
54 // Function that returns the voltage or charge on the FE injection capacitor
55 // offset to be zero for pulser gain setting ia = 0;
56 // ia - gain setting: 0 - 63 (minus inverts charge)
57 // rLines - FPGA IO resistances (high to low) [kOhm]
58 // r6 - Fixed resistance to Vrail.
59 // qvscale - Vfpga*Cinj where Cinj is the injection capacitance (fF)
60 inline
61 double cePulser(int ia, const double rfLines[6], double r6, double qvscale) {
62  if ( ia == 0 ) return 0.0;
63  if ( ia > 63 ) return 0.0;
64  if ( ia < 0 ) return cePulser(-ia, rfLines, r6, qvscale);
65  return cePulserVoltage(ia, rfLines, r6, qvscale) -
66  cePulserVoltage( 0, rfLines, r6, qvscale);
67 }
68 
69 //**********************************************************************
70 
71 // Pulser functions with Root syntax.
72 inline
73 double cePulserVoltage(double* x, double* pars) {
74  int ia = x[0];
75  //double* rfLines = pars;
76  double r6 = pars[6];
77  double qvscale = pars[7];
78  return cePulserVoltage(ia, pars, r6, qvscale);
79 }
80 
81 //**********************************************************************
82 
83 inline
84 double cePulser(double* x, double* pars) {
85  int ia = x[0];
86  //double* rfLines = pars;
87  double r6 = pars[6];
88  double qvscale = pars[7];
89  return cePulser(ia, pars, r6, qvscale);
90 }
91 
92 //**********************************************************************
93 
94 // Generate a TF1 for the pulser Voltage function.
95 inline
96 TF1* cePulserVoltageTF1(std::string fname="cepulserVoltage", double tol =0.01) {
97  using Index = unsigned int;
98  const Index npar = 8;
99  TF1* pf = new TF1(fname.c_str(), cePulserVoltage, 0, 63, npar);
100  pf->SetParName(0, "R0");
101  pf->SetParName(1, "R1");
102  pf->SetParName(2, "R2");
103  pf->SetParName(3, "R3");
104  pf->SetParName(4, "R4");
105  pf->SetParName(5, "R5");
106  pf->SetParName(6, "R6");
107  pf->SetParName(7, "Vfpga");
108  pf->SetParameter(0, 32.40);
109  pf->SetParameter(1, 16.02);
110  pf->SetParameter(2, 8.06);
111  pf->SetParameter(3, 4.02);
112  pf->SetParameter(4, 2.00);
113  pf->SetParameter(5, 1.00);
114  pf->SetParameter(6, 1.00);
115  pf->SetParameter(7, 1.8);
116  if ( tol > 0.0 && tol < 1.0 ) {
117  double fmin = 1 - tol;
118  double fmax = 1 + tol;
119  for ( Index ipar=0; ipar<npar; ++ipar ) {
120  double val = pf->GetParameter(ipar);
121  pf->SetParLimits(ipar, fmin*val, fmax*val);
122  }
123  }
124  return pf;
125 }
126 
127 //**********************************************************************
128 
129 // Set the parameters for a pulser function or a function constructed from
130 // a pulser function.
131 // pf - the function
132 // ipoff - Offset to the pulser section of the paramter list.
133 // tol - fractional limits for the parameters
134 inline
135 int initCePulserTF1(TF1* pf, unsigned int ipoff, double tol =0.01) {
136  using std::cout;
137  using std::endl;
138  const std::string myname = "initCePulserTF1: ";
139  using Index = unsigned int;
140  const Index npar = 8;
141  if ( pf->GetNpar() < int(npar) ) {
142  cout << myname << "Function has fewer than " << npar << " parameters." << endl;
143  return 1;
144  }
145  if ( pf->GetNpar() < int(ipoff + npar) ) {
146  cout << myname << "Function has fewer than " << npar << " parameters after offset "
147  << ipoff << "." << endl;
148  return 2;
149  }
150  pf->SetParName(ipoff + 0, "R0");
151  pf->SetParName(ipoff + 1, "R1");
152  pf->SetParName(ipoff + 2, "R2");
153  pf->SetParName(ipoff + 3, "R3");
154  pf->SetParName(ipoff + 4, "R4");
155  pf->SetParName(ipoff + 5, "R5");
156  pf->SetParName(ipoff + 6, "R6");
157  pf->SetParName(ipoff + 7, "QVscale");
158  pf->SetParameter(ipoff + 0, 32.40);
159  pf->SetParameter(ipoff + 1, 16.02);
160  pf->SetParameter(ipoff + 2, 8.06);
161  pf->SetParameter(ipoff + 3, 4.02);
162  pf->SetParameter(ipoff + 4, 2.00);
163  pf->SetParameter(ipoff + 5, 1.00);
164  pf->SetParameter(ipoff + 6, 1.00);
165  pf->SetParameter(ipoff + 7, 1.8*183.0);
166  if ( tol > 0.0 && tol < 1.0 ) {
167  double fmin = 1 - tol;
168  double fmax = 1 + tol;
169  for ( Index ipar=ipoff; ipar<ipoff+npar; ++ipar ) {
170  double val = pf->GetParameter(ipar);
171  pf->SetParLimits(ipar, fmin*val, fmax*val);
172  }
173  }
174  return 0;
175 }
176 
177 //**********************************************************************
178 
179 // Generate a TF1 for the pulser function.
180 inline
181 TF1* cePulserTF1(std::string fname="cepulser", double tol =0.01) {
182  using Index = unsigned int;
183  const Index npar = 8;
184  TF1* pf = new TF1(fname.c_str(), cePulser, -64, 64, npar);
185  initCePulserTF1(pf, 0, tol);
186  return pf;
187 }
188 
189 //**********************************************************************
190 
191 #endif
int initCePulserTF1(TF1 *pf, unsigned int ipoff, double tol=0.01)
Definition: cePulser.h:135
std::string string
Definition: nybbler.cc:12
auto const tol
Definition: SurfXYZTest.cc:16
unsigned int Index
TF1 * cePulserVoltageTF1(std::string fname="cepulserVoltage", double tol=0.01)
Definition: cePulser.h:96
double cePulser(int ia, const double rfLines[6], double r6, double qvscale)
Definition: cePulser.h:61
double cePulserVoltage(int iaIn, const double rfLines[6], double r6, double vfpga)
Definition: cePulser.h:26
list x
Definition: train.py:276
TF1 * cePulserTF1(std::string fname="cepulser", double tol=0.01)
Definition: cePulser.h:181
QTextStream & endl(QTextStream &s)