Measurement of Sound Velocity
Ultrasonic evaluations require quite frequently to measure the speed of sound through various metals. For example, having an accurate value for sound velocity in a specific alloy will help to get good resolution of metal thickness. This is very practical since the sound velocity is dependent of the material properties such as elasticity modulus, E, and Poisson's ratio, ν , through the following relationship
$$v = \sqrt{E(1-\nu) \over \rho(1+\nu)(1-2\nu)}.$$
NASA's researchers (Hull, Kautz, and Vary [1]) pioneered an elegant technique of extracting the time of flight through the cross-correlation (CC) of two consecutive back wall echoes. The method proved to produce accurate measurements for the speed of sound even when the sound propagates through highly attenuating materials. This is true as the CC function is not affected by distortions or low signal-to-noise ratio. The following video shows how to implement this technique in python and it is a great heuristic approach both for undergraduate and graduate students.
The python code that was used in the EGR 392 class of Nondestructive Test at Murray
State University. The script was written for Python 3.
# Written by George Bunget during NDE class EGR 392 at Murray State
#=======================================================================
# Procedure (pseudocode)
# 1) - import the data file (pulse/echo measurement) in python
# 2) - plot data so we see the waveform
# 3) - select echoes to measure the speed of sound
# 4) - Use the cross-correlation technique to measure the time of flight
# 5) - Calculate the speed of sound v = 2*thickness/(time of flight)
import numpy as np # numpy is a numerical library for python
import matplotlib.pyplot as plt # library used to plot figures in python
# 1) - import the data file (pulse/echo measurement) in python
#=======================================================================
data = np.loadtxt('L4_Sp80_3.22mm.csv',delimiter=',',skiprows = 2)
time = data[:,0]
wave = data[:,1]
dt = time[1]-time[0]
Thickness = 3.22 # in mm
# 2) - plot data so we see the waveform
#=======================================================================
fig = plt.figure(1)
plt.plot(time,wave,'-b')
plt.xlabel('Time, [$\mu$s]')
plt.ylabel('Amplitude, [a.u.]')
plt.grid(color='gray', linestyle=':', linewidth=0.5)
# 3) - select echoes to measure the speed of sound
#=======================================================================
# select the first backwall echo by isolating it from the rest of the wave
Marker1 = 1.0 # At 1 microsecond we put a marker
width = 500 # assume 200 data points for the width of the echoes
echo1 = np.array(wave) # create another array for echo 1
indexM1 = np.argmax(time>Marker1) # get the index of time value = 1 us
echo1[0:indexM1] = 0 # zero everything before Marker 1
indexend1 = indexM1+width
echo1[indexend1:] = 0# zero everything after the end of echo1
# select the second backwall echo by isolating it from the rest of the wave
Marker2 = 2.0 # At 1 microsecond we put a marker
echo2 = np.array(wave) # create another array for echo 2
indexM2 = np.argmax(time>Marker2) # get the index of time value = 1 us
echo2[0:indexM2] = 0 # zero everything before Marker 1
indexend2 = indexM2+width
echo2[indexend2:] = 0# zero everything after the end of echo1
fig = plt.figure(2)
plt.clf()
plt.plot(time,echo1,'-b',label='echo1')
plt.plot(time,echo2,'-c',label='echo2')
plt.xlabel('Time, [$\mu$s]')
plt.ylabel('Amplitude, [a.u.]')
plt.grid(color='gray', linestyle=':', linewidth=0.5)
plt.legend()
# 4) - Use the cross-correlation technique to measure the time of flight
#=======================================================================
Correlation_Function = np.correlate(echo2,echo1,"full")# cross-correlate the two echoes
Max_index = np.argmax((np.array(Correlation_Function)))# get the index of the max of
## the absolute value of Corr. Func
N = len(wave)
lag = np.arange(-N+1,N)# array with number of step (lags)
# if the original signal has N points then the cross-correlation function has 2*N+1
Correlation_Time = lag*dt
tau = Correlation_Time[Max_index] # time between echo1 and echo2
fig = plt.figure(3)
plt.clf()
plt.plot(Correlation_Time,(Correlation_Function),'-b',label='Correlation Function')
plt.xlabel('Time, [$\mu$s]')
plt.ylabel('Amplitude, [a.u.]')
plt.grid(color='gray', linestyle=':', linewidth=0.5)
# 5) - Calculate the speed of sound v = 2*thickness/(time of flight)
#=======================================================================
velocity = 2*Thickness/tau # in mm/us
print('Velocity = ',velocity)
plt.show()
Simplify Script by Creating a Function
The previous python code contains two sections that are repeated two times when we
single out the two echoes. For these
situations it is better to create a function that we call it any time we need to go through its
algorithm. In the next script, the function called 'echo' singles out echo 1 and 2 by zero-ing
everything else. This function has four inputs, Marker - the start of echo signal, width - the
width of the echo signal, the time and the waveform columns of the initial data.
This procedure of using a customized function becomes extremely handy when the
analysis requires iterations in a loop, either for loop or while loop.
# Written by George Bunget during NDE class EGR 392 at Murray State
#=======================================================================
# Procedure (pseudocode)
# 1) - import the data file (pulse/echo measurement) in python
# 2) - plot data so we see the waveform
# 3) - select echoes to measure the speed of sound
# 4) - Use the cross-correlation technique to measure the time of flight
# 5) - Calculate the speed of sound v = 2*thickness/(time of flight)
import numpy as np # numpy is a numerical library for python
import matplotlib.pyplot as plt # library used to plot figures in python
# 1) - import the data file (pulse/echo measurement) in python
#=======================================================================
data = np.loadtxt('L4_Sp80_3.22mm.csv',delimiter=',',skiprows = 2)
time = data[:,0]
wave = data[:,1]
dt = time[1]-time[0]
Thickness = 3.22 # in mm
# 2) - plot data so we see the waveform
#=======================================================================
fig = plt.figure(1)
plt.plot(time,wave,'-b')
plt.xlabel('Time, [$\mu$s]')
plt.ylabel('Amplitude, [a.u.]')
plt.grid(color='gray', linestyle=':', linewidth=0.5)
# 3) - select echoes to measure the speed of sound
#=======================================================================
# create a function called echo that will single out individual backwall
# echoes by isolating it from the rest of the wave
def echo(Marker,width,Time,signal):
echou = np.array(signal) # create another array to isolate echo
indexM = np.argmax(Time>Marker) # get the index of start time for echo
echou[0:indexM] = 0 # zero everything before Marker
indexend = indexM+width # get the index of the end of echo
echou[indexend:] = 0# zero everything after the end of echo1
return echou
# select two successive backwall echoes by isolating them from the rest
# of the wave
echo1 = echo(Marker=1.,width=500,Time=time,signal=wave)
echo2 = echo(Marker=2.,width=500,Time=time,signal=wave)
# Plot echoes to check our selections
fig = plt.figure(2)
plt.clf()
plt.plot(time,echo1,'-b',label='echo1')
plt.plot(time,echo2,'-c',label='echo2')
plt.xlabel('Time, [$\mu$s]')
plt.ylabel('Amplitude, [a.u.]')
plt.grid(color='gray', linestyle=':', linewidth=0.5)
plt.legend()
# 4) - Use the cross-correlation technique to measure the time of flight
#=======================================================================
Correlation_Function = np.correlate(echo2,echo1,"full")# cross-correlate the two echoes
Max_index = np.argmax((np.array(Correlation_Function)))# get the index of the max of
## the absolute value of Corr. Func
N = len(wave)
lag = np.arange(-N+1,N)# array with number of step (lags)
# if the original signal has N points then the cross-correlation function has 2*N+1
Correlation_Time = lag*dt
tau = Correlation_Time[Max_index] # time between echo1 and echo2
fig = plt.figure(3)
plt.clf()
plt.plot(Correlation_Time,abs(Correlation_Function),'-b',label='Correlation Function')
plt.xlabel('Time, [$\mu$s]')
plt.ylabel('Amplitude, [a.u.]')
plt.grid(color='gray', linestyle=':', linewidth=0.5)
# 5) - Calculate the speed of sound v = 2*thickness/(time of flight)
#=======================================================================
velocity = 2*Thickness/tau # in mm/us
print('Velocity = ',velocity)
plt.show()
References:
[1] Hull,D.R., Kautz, H.E.,Vary, A., "Ultrasonic Velocity Measurement Using Phase-Slope and Cross-Correlation Methods", Conference of the American Society for Nondestructive Testing, Denver, Colorado, May 21-24, 1984