• Tidak ada hasil yang ditemukan

5.1 Properties of Water .1 Thermal Properties

5.1.6 Travel Time Analysis and Soil Water Content Measurement

86 Soil Liquid Phase and Soil–Water Interactions eqn (5.12) is solved for water content:

θ= bα

(1 –φf)sα+φfgα

lαgα

(5.13) The dielectric mixing model of eqn (5.13) can be written as a function of bulk density and the square root of the bulk dielectric permittivity:

θ=

bρb

ρs

s

1 –ρρb

s

g

l–√g

(5.14) To employ the dielectric mixing model, knowledge of the bulk density and dielectric permittivity of the solid phase is needed, as well as the dielectric permittivity of the liquid phase. Table 5.1 provides the dielectric permittivity for different materials.

Changes in dielectric properties of wet porous materials are complex, involving a variety of relaxation phenomena that depend on mineralogical properties, surface properties, geometrical arrangement and shape of soil particles, water content, solute concentration, frequency, and temperature. Therefore a dielectric measurement is influ- enced by all soil constituents and not just water. Empirical equations based only on bulk dielectric measurement (like the Toppet al.(1980) or Malickiet al.(1996) models) can therefore never be accurate for all soils. For a more detailed and extensive discussion of these phenomena, the reader should see Santamarinaet al.(2001) and Bittelliet al.

(2008b).

5.1.6 Travel Time Analysis and Soil Water Content

Properties of Water 87

Reflection coefficient –0.5 0.0 0.5 1.0

–1.0 0

Time [ns]

10 15 20 25 30 35

5

Figure 5.2 Time domain reflectometry waveform. The peakand thereflection pointare indicated by squares. The dots are the experimental waveform, the dashed line is the first derivative and the solid lines are the tangent lines.

4. PSP_TTwaterContent.py 5. PSP_TTplot.py

Themain.pyfile contains the user interface written using the moduletkinter, and the calls to the functions contained in the files PSP_travelTime.py and PSP_TTplot.py. The functions used for travel time analysis are written in the file PSP_travelTime.pyand will be described here. For brevity, the code written in the filesmain.pyand PSP_TTplot.pyis not shown, since it is made of a series of in- structions used to generate the interface. The filePSP_readDataFile.py,used to read the experimental data, is described in Appendix A.

Figure 5.3 depicts the user interface, obtained by running the program written in the filemain.py. The waveform is shown in Fig. 5.2 with time on thex-axis and reflection coefficient on they-axis. The output from the tangent lines procedure to obtain the travel time is also shown. The dashed line is the first derivative, while the solid straight lines are the tangent lines to the curve, used to identify the peak and the reflection point.

The three points indicated by squares are the inflection points. Specifically, they are as follows, from left to right: the first point is the transition from the cable into the probe handle, the second point corresponds to the end of the probe handle (beginning of the metal rods) and the third point is the reflection at the end of the probe. For travel time calculation, the second and third points are used. The correction for the travel time in the epoxy handle is obtained by knowing the relative dielectric permittivity of the epoxy.

Note that in the windows interface, there is a box for the permittivity of the handle

88 Soil Liquid Phase and Soil–Water Interactions Import data

Settings Compute

Header values

Vp [–]

Probe length [m]

Probe handle [m]

Bulk density [m^3]

Water temp. [c]

Window begin [m]

Window width [m]

Soil parameters

e handle

e liquid

e solid

alpha (geom. para Travel time results

point 0 × [ns] 1.389 2.338 6.305 3.967 15.40 0.282 0.295 0.303 point 1 × [ns]

point 2 × [ns]

Travel Time [ns]

Bulk permittivity Topp

Malicki Diel. mix model Water Content

8

0.99 0.15 0.0 5.0 0.108

1350 20 80.338 4.0 0.5 1.7

Figure 5.3 User interface for the travel time analysis program.

(ehandle). If this information is lacking, the correction for the handle must be performed through calibrations with dielectrics of known permittivity.

The following is an explanation of the user interface. The first button (Import data), must be clicked to import the experimental data. A window pops-up and the file with the experimental data can be imported. In this example, a filedataTDRSoil.dat is provided. Depending on the commercial TDR, the output data can be organized ei- ther in columns or in rows. The filePSP_readDataFile.py was written to be able to import both formats. Usually, output files obtained from TDR analysis contain a number of header lines, specifying the settings of the data acquisition device (i.e. the datalogger). For instance, for the Campbell Scientific TDR100, the output file contains eight header lines with the following parameters: wave average, wave velocity, number of output points, cable length, window length, probe length, probe offset and multiplier.

In this program, this information (needed for travel time analysis) is input by the user

Properties of Water 89 in the interface. Therefore these lines need not to be read by the program. In the win- dow on the right side of the buttonImport data, the number of header lines must be specified, such that the program reads only the experimental data and skips the header lines. This number must be entered before clickingImport data.

The sectionSettingsis used to specify the experimental settings such as the wave velocity, the probe length, the window beginning, the window width, the handle dimen- sions and the dielectric permittivity of the material used to build the probe handle (often specified by the manufacturer). This information is needed to account for the wave travel time in the probe handle, to be subtracted from the travel time calculation. Therefore, before clicking theComputebutton, this information must be written into the boxes.

The sectionSoil Parametersis written to input soil parameters needed to compute soil water content from knowledge of dielectric permittivity. These parameters will be described in more detail below.

The sections Travel Time Results and Water Content print the results of the computation. The output from travel time analysis comprises the points de- scribed above and, specifically, Point 0 x is the point where the wave enters the probe, Point 1 x is where the handle ends and the metal rods begin, and Point 2 x is the reflection point corresponding to the end of the metal rods. The names Topp,Malicky and the dielectric mix model are three different models used to compute volumetric water content from dielectric permittivity.

The computation of the relative dielectric permittivity is based on the measurement of the travel timet as described in eqn (5.9). The travel time is given by the differ- ence betweenPoint 1 xandPoint 2 x. Therefore the core of a travel time analysis algorithm is the correct measurement of thepeakand thereflection pointto identify these points.

The first reflection is usually called aspikeor apeakand is determined by the change in impedance from the cable to the probe. This point can be determined manually or by knowing the dielectric properties of the handle material. By looking at Fig. 5.2, the spike is identified as the abrupt change of slope of the signal at the beginning of the waveform. The algorithm identifies that point by the tangent lines method. However, this point corresponds to the change in impedance going from the cable into the TDR handle, and therefore it is not the point that should be used for travel time analysis. This point must be shifted to the right, by a given amount of time corresponding to the travel time over the probe handle, as indicated by the second dot from the left in the plot.

To know how far to shift this point to the right, it is necessary to know the dielectric permittivity of the material used to build the probe handle. Commonly, this is an epoxy or plastic material of known dielectric permittivity. The second reflection is determined by a tangent fitting procedure as shown in Fig. 5.2, by computing the first derivative with a Savitzky–Golay algorithm (Presset al., 1992). After obtaining the travel time and the dielectric permittivity, different equations are used to obtain the volumetric water content as described above.

The code of the file PSP_travelTime.py is shown below, since it contains the main variables and functions for travel time analysis. For readability, the code will be described in sections.

90 Soil Liquid Phase and Soil–Water Interactions

#PSP_travelTime

from _ _future_ _ import division import math

import numpy as np c = 299792458 NODATA = -9999 MAXDELTAINDEX = 6 SX = 0

DX = 1 class CLine:

a = NODATA b = NODATA class CPoint:

x = NODATA y = NODATA

flatLine = line1 = line2 = line3 = CLine() p0 = p1 = p2 = CPoint()

indexP0 = indexP2 = NODATA timeVector = []

reflecCoeff = []

dy =[]

deltaSpace = 0 deltaTime = 0

The variableMAXDELTAINDEXis used to define the maximum number of points to calculate the tangent lines, while the variablesSXandDXare used to define the direction.

This is used to choose the weight to be assigned to different points when using a weighted linear regression as detailed in the following, depending if the line comes from the right (DX) side or from the left (SX) side of the inflection point. The classcLineis defined for the slopeaand the interceptb. The straight lines used for travel time analysis will be obtained and plotted by using the instances of the classcLine. The classcPoint is written to define the points that will be computed with the travel time analysis. The variablesdeltaSpaceanddeltaTimeare initialized. These variables will be used to define the incremental values of space and time read from the experimental data.

A variety of functions are written to compute the tangent lines. The function in- dexofMaxVector() finds the index of the vector x with maximum value, within the imported experimental values. On the other hand, the function indexofMinVector() finds the index of the vector x with minimum value. The average vector (avg()) is then computed, while the functionnormalizeVector() is used to compute a normalized vector, to express the reflection coefficient values between –1 and 1.

Properties of Water 91 def indexOfMaxVector(y, first, last):

myMax = max(y[first:last]) for i in range(first, last):

if (y[i] == myMax):

return(i)

def indexOfMinVector(y, first, last):

myMin = min(y[first:last]) for i in range(first, last):

if (y[i] == myMin):

return(i) def avg(y, index1, index2):

if (index2 < index1):return(NODATA) first = max(index1, 0)

last = min(index2+1, len(y)) nrValues = last - first

return sum(y[first:last]) / nrValues def normalizeVector(y):

y = (y-min(y))/(max(y) - min(y)) avgFirstValues = avg(y, 1, 6) return (y - avgFirstValues)

The following functions are used to compute the waveform parameters. The vari- able Vp is the wave velocity and probeHandle is the physical length of the probe handle. The variableswindowBeginandwindowWidthdefine the beginning and the width of the TDR window used for the measurement; thennrPointsdefines the num- ber of points acquired during the experiment. To obtain the space increment between each point (deltaSpace),windowWidthis divided bynrPoints-1. Then, the time increment (deltaTime) is obtained by multiplyingdeltaSpaceby two and then div- iding it by the speed of light times the velocity parameter. The multiplication by two is performed because the wave travels back and forth (reflection measurement). The speed of light is multiplied by the velocity parameter (ranging from 0.6 to 0.99) that can be set in the TDR device. This parameter defines the wave velocity across the cable. Then a time vector is defined (timeVector), which is an incremental value of time given by the multiplication of the incremental time by the number of points.

A running average functionrunningAverage() is written to smooth the experimental data and thus allow for identification of the dominant reflection point, rather than minor oscillations due to scattered experimental data points. The function has two arguments yandnrPoints. The first is the variable containing the experimental data, while the second defines the number of points used to compute the running average.

An important part of this program relies on the computation of the derivative of the travel time data. A five-point derivative functionfirstDerivative5Points() is employed.

Discussion of numerical derivatives and an example code are provided in Appendix B.1.

Computation of the derivative allows for identification of slope changes and inflection

92 Soil Liquid Phase and Soil–Water Interactions

points. Figure 5.2 shows the change in the derivative values (dashed line) and their correspondence to the reflection points of the experimental waveform.

def WF_parameters(Vp, probeHandle, windowBegin, windowWidth, nrPoints):

global deltaTime, deltaSpace, timeVector

#abs. time [s] corresponding to the 1st point firstPointTime = 2. * windowBegin / (c*Vp) deltaSpace = windowWidth /(nrPoints - 1) deltaTime = 2. * deltaSpace /(c*Vp) timeVector = np.zeros(nrPoints, float) for i in range(nrPoints):

timeVector[i] = firstPointTime + deltaTime * i def runningAverage(y, nrPoints):

smooth = np.zeros(len(y), float) for i in range(len(y)):

smooth[i] = avg(y, i-nrPoints, i+nrPoints) return smooth / max(abs(smooth))

def firstDerivative5Points(y):

dy = np.zeros(len(y), float) for i in range(2):

dy[i] = 0.

for i in range(2, len(y)-2):

dy[i] = (1./(12.)) * (y[i-2] - 8.*y[i-1] + 8.*y[i+1] - y[i+1]) for i in range(len(y)-2, len(y)):

dy[i] = 0.

return dy / max(abs(dy))

After obtaining the raw data, transforming the data points into travel time increments and computing the running average and a numerical derivative, the next step is the identification of the reflection points. This task is based on computation of regression lines that are fitted to the curve. To identify an accurate value corresponding to the reflection point, two weighted linear regression lines are fitted to the experimental data, corresponding to the change of slope indicated by the derivative. After the parameter of the line (slope and intercept) has been found, the intersection point is obtained.

The function used to compute the weighted linear regression is calledweightedLine- arRegression(). The equation of the slope for a weighted linear regressions is described by Kleinbaumet al.(2008). In this algorithm, the weight assigned to the points, differed depending on the direction. If the points were weighted towards the left (SX), and there- fore from right to left, the weight assigned to the point was different with respect to the points that went towards the right (DX), and therefore from left to right. The flexibility of a weighted regression line is necessary because the slopes of the two branches may be substantially different (see the example in Fig. 5.4); therefore, depending on how many points are used, the intercept between the two regression lines may differ.

Properties of Water 93

DX

SX myPoint –0.1

–0.2

12 –0.3

10 Time [ns]

Reflection coefficient

–0.4

8 –0.5

6 –0.7

–0.8 –0.6

4

Figure 5.4 Detail of the waveform and weighted linear regression for travel time analysis. The symbols DX and SX indicates the direction for weighting the regression points.

Specifically DX indicates towards the right and SX towards the left.

A function was written to identify the index (position) of the flat point, called checkIndexFlatPoint(), while another function was written to check the index clos- est to the intersection of thex-axis. This function is calledcheckIndexZeroValue()and is used to find the index when the derivative is zero or closest to zero.

Finally, the intersection point of the two regression lines was computed by the func- tionlineIntersection(). This function returns the variablemyPoint, which is the point used to compute the travel time. Figure 5.4 shows a detail of the waveform around the reflection point, indicating the two regression lines obtained from the function weightedLinearRegression()and the identification of the intersection point.

The functions that implement the equation described above are written in the following code:

# return a line structure with intercept (b) and slope (a) def weightedLinearRegression (x, y, index1, index2, versus):

sumX = sumY = 0.

sumX2 = sumXY = 0.

if(index1 == index2):

index1 -= 1 index2 += 1

#check index range if (index1 < 0):

index1 = 0

94 Soil Liquid Phase and Soil–Water Interactions if (index2 >= len(y)):

index2 = len(y)-1 nrPoints = index2-index1+1 if (versus == SX):

for i in range(nrPoints-1, -1, -1):

for j in range (i+1):

sumX += x[index1+i]

sumY += y[index1+i]

sumX2 += (x[index1+i]* x[index1+i]) sumXY += x[index1+i] * y[index1+i]

else:

for i in range(nrPoints):

for j in range (i+1):

sumX += x[index1+i]

sumY += y[index1+i]

sumX2 += (x[index1+i]* x[index1+i]) sumXY += x[index1+i] * y[index1+i]

n = (nrPoints*(nrPoints+1))/2 line = CLine()

line.a = (sumXY - sumX * sumY/n) / (sumX2 - sumX * sumX/n) line.b = (sumY - line.a * sumX)/n

return(line)

#backward function

def checkFlatPoint(y, indexMaxDy):

index = indexMaxDy

dy = abs(y[index] - y[index-1]) threshold = dy / 1000.

while ((dy > threshold) and (index > 0)):

index -= 1

dy = abs(y[index]-y[index-1]) return (index)

#backward function

def checkZeroValue(y, indexMaxY):

index = indexMaxY

while ((y[index] > 0) and (index > 0)):

index -= 1

if ((index == 0) and (y[index] > 0)):

return(NODATA) else:

if (abs(y[index]) < abs(y[index+1])):

return (index) else:

return (index+1)

Properties of Water 95 def lineIntersection(line1, line2):

myPoint = CPoint() if (line1.a != line2.a):

myPoint.x = (line2.b - line1.b) / (line1.a - line2.a) myPoint.y = myPoint.x * line1.a + line1.b

else:

myPoint.x = NODATA myPoint.y = NODATA return(myPoint)

After the point (myPoint) where the wave is reflected back from the end of the probe has been obtained, the travel time can finally be computed. This task is performed in the functioncomputeTravelTime(), shown below. This function identifies the point where the derivative has maximum value. The first reflection is used to identify the first peak.

The first peak is found by searching for the first flat section of the waveform, while the reflection point is obtained as detailed above.

def computeTravelTime(probeHandle, permittivity, Vp):

global dy, flatLine, line1, line2, line3

global indexFlatLine, indexRegr1, indexRegr2, indexRegr3 global p0, p1, p2

dy = firstDerivative5Points(reflecCoeff) dy = runningAverage(dy, 5)

indexMaxDerivative = indexOfMaxVector(dy, 0, len(dy)) indexMinDerivative = indexOfMinVector(dy, 0, len(dy))

#check first maximum

if (indexMaxDerivative > indexMinDerivative):

indexMaxDerivative = indexOfMaxVector(dy, 0,

indexMinDerivative)

#search first reflection

indexFlatLine = checkFlatPoint(reflecCoeff, indexMaxDerivative) nrPoints = len(reflecCoeff)

step = int(8.0 * (nrPoints / 256.0))

average = avg(reflecCoeff, indexFlatLine - step, indexFlatLine) flatLine.a = 0

flatLine.b = average

delta = min((indexMaxDerivative - indexFlatLine), MAXDELTAINDEX) indexRegr1 = indexFlatLine + delta

line1 = weightedLinearRegression(timeVector, reflecCoeff, indexRegr1 - delta, indexRegr1 + delta, SX) p0 = lineIntersection(flatLine, line1)

dt0 = (2. * probeHandle * math.sqrt(permittivity)) / (c*Vp)

96 Soil Liquid Phase and Soil–Water Interactions p1.x = p0.x + dt0

index = int(p1.x / deltaTime) p1.y = reflecCoeff[index]

#search second reflection

indexSecondMaxDerivative = indexOfMaxVector(dy,

indexMinDerivative, len(dy))

indexZeroDerivative = checkZeroValue(dy, indexSecondMaxDerivative) delta = min((indexSecondMaxDerivative - indexZeroDerivative),

MAXDELTAINDEX)

indexRegr2 = indexZeroDerivative - delta indexRegr3 = indexZeroDerivative + delta

line2 = weightedLinearRegression(timeVector, reflecCoeff, indexRegr2 - delta, indexRegr2 + delta, DX) line3 = weightedLinearRegression(timeVector, reflecCoeff,

indexRegr3 - delta, indexRegr3 + delta, SX) p2 = lineIntersection(line2, line3)

The next step is to calculate the dielectric permittivity, which is used to obtain the soil water content. The functions used to compute the bulk dielectric permittivity and then calculate the water content are written into a file calledPSP_TTwaterContent.py.

The first function,getLiquidPermittivity(), is written to account for the liquid water dielectric permittivity as a function of temperature. This equation is used in the dielectric mixing model to account for the variation of the liquid-phase dielectric permittivity with temperature. If this information is available from experiments, it can be input by the user in the sectionSoil Parameters of the window user interface. Otherwise, the program utilizes a default value of 20C.

The following functiongetBulkPermittivity() computes the dielectric permittivity from knowledge of the travel time as described in eqn (5.9):

#PSP_TTwaterContent.py

from _ _future_ _ import division from math import sqrt

c = 299792458

airPermittivity = 1.00058986

#Lide, Handbook of Chemistry and Physics, CRC 1992 def getLiquidPermittivity(temperature):

deltaT = temperature - 25.

return(78.54 * (1-4.579E-03 * deltaT))

def getBulkPermittivity(probleLenght, travelTime, Vp):

return(((c * Vp * travelTime) / (2. * probleLenght))**2)