Calibration of a thermometer (GUM H3)
An example from Appendix H3 of the GUM [1].
Code
from __future__ import print_function
from GTC import *
print("""
-------------------------------
Example from Appendix H3 of GUM
-------------------------------
""")
# Thermometer readings (degrees C)
t = (21.521,22.012,22.512,23.003,23.507,23.999,24.513,25.002,25.503,26.010,26.511)
# Observed differences with calibration standard (degrees C)
b = (-0.171,-0.169,-0.166,-0.159,-0.164,-0.165,-0.156,-0.157,-0.159,-0.161,-0.160)
# Arbitrary offset temperature (degrees C)
t_0 = 20.0
# Calculate the temperature relative to t_0
t_rel = [ t_k - t_0 for t_k in t ]
# Least-squares regression
cal = type_a.line_fit(t_rel,b)
print( cal )
print
# Apply correction at 30 C
b_30 = cal.intercept + cal.slope*(30.0 - t_0)
print("Correction at 30 C: {}".format(b_30))
Explanation
A thermometer is calibrated by comparing 11 readings \(t_k\) with corresponding values of a temperature reference standard \(t_{\mathrm{R}\cdot k}\).
The readings and the differences \(b_k = t_{\mathrm{R}\cdot k} - t_k\) are used to calculate the slope and intercept of a calibration line, which can be used to estimate a temperature correction for a thermometer reading, including the uncertainty.
A linear model of the thermometer is assumed,
An arbitrary fixed temperature \(t_0\) is chosen for convenience, \(t_k\) is the temperature indicated by the thermometer and \(B_k\) is the correction that should be applied to a reading. The constants \(Y_1\) and \(Y_2\) define a linear relationship between the indicated temperature and the correction \(B_k\) (\(Y_1\) and \(Y_2\) correspond to the intercept and slope).
The accuracy of the temperature standard is high, so values of \(t_{\mathrm{R}\cdot k}\) have no significant error. However, the estimates obtained for the difference between the actual temperature and the indicated temperature are \(b_k\) are subject to error.
Estimates of the intercept and slope are obtained by least-squares regression on \(b_k\) and \(t_k\). The uncertainty in these estimates is due to random fluctuations in the measurement system (represented by \(E_k\)) .
In the GTC
calculation, data are contained in a pair of sequences. The function type_a.line_fit()
performs the regression.
# Thermometer readings (degrees C)
t = (21.521,22.012,22.512,23.003,23.507,23.999,24.513,25.002,25.503,26.010,26.511)
# Observed differences with calibration standard (degrees C)
b = (-0.171,-0.169,-0.166,-0.159,-0.164,-0.165,-0.156,-0.157,-0.159,-0.161,-0.160)
# Arbitrary offset temperature (degrees C)
t_0 = 20.0
# Calculate the temperature relative to t_0
t_rel = [ t_k - t_0 for t_k in t ]
# Least-squares regression
cal = type_a.line_fit(t_rel,b)
print cal
print
The fitted calibration line can be used to calculate a correction for a reading of 30 C
# Apply correction at 30 C
b_30 = cal.intercept + cal.slope*(30.0 - t_0)
print("Correction at 30 C: {}".format(b_30))
The results agree with the numbers reported in the GUM
-------------------------------
Example from Appendix H3 of GUM
-------------------------------
Ordinary Least-Squares Results:
Intercept: -0.1712(29)
Slope: 0.00218(67)
Correlation: -0.93
Sum of the squared residuals: 0.000110096583109
Number of points: 11
Correction at 30 C: -0.1494(41)
Other error models
In GUM appendix H.3.6, two alternative scenarios are considered for the thermometer calibration.
Known variance
In the first, the variance of the b_k
data is assumed known from prior calibrations.
There are two ways to do this regression problem with GTC
.
One way is to define a sequence with the uncertainties of the respective b_k
observations. This sequence can be used with type_a.line_fit_wls()
to obtain the slope and intercept.
The other way is to define a sequence of uncertain real numbers representing the b_k
data and use the function type_b.line_fit()
u_b = 0.001 # an arbitrary value, just as an example
cal = type_b.line_fit(t_rel,[ureal(b_i,u_b) for b_i in b])
in either case, the results obtained can be used as above to evaluate corrections.
Systematic error in the standard temperature
The other scenario considers a systematic error that causes all b_k
values to have some constant offset error. A type-A analysis can still be used on the data to evaluate the contribution to uncertainty due to system instability. However, the systematic error cannot be evaluated by a statistical analysis (it is constant).
This can be handled by combining the results from both type-A and type-B regression analyses.
First, we define a sequence of uncertain real numbers for the b_k
data, in which a term representing the systematic error is included
E_sys = ureal(0,0.005)
b_sys = [b_i + E_sys for b_i in b]
cal_b = type_b.line_fit(t_rel,b_sys)
print cal_b
Note that E_sys
, which represents the systematic error, is defined outside the list and then added to each list element. The results are
Ordinary Least-Squares Results:
Intercept: -0.1712(50)
Slope: 0.00218269773988727725(16)
Correlation: -1
Sum of the squared residuals: 0.000110096583109
Number of points: 11
The standard uncertainty in the slope is effectively zero (the small non-zero value can be attributed to numerical round-off error), as expected: an error in the temperature standard shifts all values of b_k
by the same amount, so the slope does not change.
Second, a type-A regression analysis is done on the same b_k
data sequence (this processes the uncertain-number values, but ignores the uncertainies)
cal_a = ta.line_fit(t_rel,b_sys)
print cal_a
The results are
Ordinary Least-Squares Results:
Intercept: -0.1712(29)
Slope: 0.00218(67)
Correlation: -0.93
Sum of the squared residuals: 0.000110096583109
Number of points: 11
Notice that the slope and intercept are the same, but not the uncertainties or the correlation coefficient.
In a final step, the results are combined
intercept = ta.merge(cal_a.intercept,cal_b.intercept)
slope = ta.merge(cal_a.slope,cal_b.slope)
print( repr(intercept) )
print( repr(slope) )
which displays
ureal(-0.17120379013135004,0.00576893138292676,145.37964721007157)
ureal(0.0021826977398872894,0.0006679387732278323,9.0)
Notice that neither of the estimates, or the standard uncertainty in the slope, change as a result of merging. However, the standard uncertainty of the intercept does increase, due to uncertainty about the systematic error, as described in H.3.6 in the GUM.
Footnotes