I am not a signal processor but need to use Cepstrums in a bigger project I am writing to help identify echoes in seismic signals.
I need to understand why the Real and Complex Cepstrums I create, in Python, have the right hand side of the output being the mirror image of the left hand side. I get a similar result when I create the Complex Cepstrum - although here the mirroring effect is both left to right and up to down. I have based my code on numerous published articles available in the public domain (e.g the paper by R.B. Randall).
I have tried using both synthetic data and real seismic data. But all the results have this mirroring. For simplicity I show the results derived from the synthetic signal.
The last two images show the result of the (complex) frequency spectra and then the complex Cepstrum. Here the mirroring effect is a combination of flipping the right hand side both right to left and up to down.
What am I doing wrong? The mirroring is baffling me. Also I know the Cepstrum should be the same length as the input signal but taking the first half of the results I get means the Cepstrum is too short.
Once I have the Cepstrum what is the best way to then us sit to determine the echo in the original signal from the Cepstrum ?
Below is the Scipy / Python code I am using to derive the results shown above
el3 is the input signal
yfft = rfft(el3) xfft = rfftfreq(len(el3), 1 / SampRate) yfft_abs = (np.abs(yfft)) CEPsig = irfft(np.log(yfft_abs))
A_f = fft(el3) A_fft = fftfreq(len(el3), 1 / SampRate) C_CEPsig = ifft(np.log(A_f))
Code for plotting cepstrum is
plt.figure(figsize=(30,4)) plt.ylim(-1,1) plt.xticks(np.arange(0, len(CEPsig), 100)) plt.plot(CEPsig, color = "red") plt.title("Real Cepstrum of synthetic data", size = 20) plt.show()
Code for calculating magnitude and phase (in radians) from Complex Cepstrum is
C_CEPsig_abs = np.abs(C_CEPsig) C_CEPsig_ang = np.angle(C_CEPsig)
Code for plotting magnitude and phase is
plt.figure(figsize=(30,4)) plt.plot( C_CEPsig_ang, color = "black") plt.title("Phase of Cepstrum", size = 20) plt.show() plt.figure(figsize=(30,4)) plt.plot( C_CEPsig_abs, color = "red") plt.title("Magnitude of Cepstrum", size = 20) plt.show()
These plots are shown below. Although I think the Phase vs Quefrency plot may be OK (?) I still see the mirroring effect on the Magnitude of the Complex Cepstrum vs the Quefrency plot.
As an aside from the code below the number of samples in the quefrency_vector_impulse (= 901) is half that of the number of samples in the C_CEPsig (= 1800)
A_fft = fftfreq(len(el3), 1 / SampRate) df = A_fft - A_fft quefrency_vector_impulse = rfftfreq(C_CEPsig.size, df)