.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_tds.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plot_tds.py: Extraction example ================== Tutorial. .. GENERATED FROM PYTHON SOURCE LINES 13-20 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import tdsxtract as tx .. GENERATED FROM PYTHON SOURCE LINES 21-22 Define sample thickness .. GENERATED FROM PYTHON SOURCE LINES 22-25 .. code-block:: Python sample_thickness = 500e-6 .. GENERATED FROM PYTHON SOURCE LINES 26-27 First we load the reference and sample signals .. GENERATED FROM PYTHON SOURCE LINES 27-34 .. code-block:: Python pos_ref, v_ref = tx.load(f"data/reference.txt") pos_samp, v_samp = tx.load(f"data/sample.txt") assert np.all(pos_ref == pos_samp) position = pos_ref * 1e-6 .. GENERATED FROM PYTHON SOURCE LINES 35-36 We convert the position to time delay and plot the data .. GENERATED FROM PYTHON SOURCE LINES 36-49 .. code-block:: Python time = tx.pos2time(position) time_ps = time * 1e12 plt.figure() plt.plot(time_ps, v_ref, label="reference", c="#5aa2a2") plt.plot(time_ps, v_samp, label="sample", c="#b5514c") plt.xlabel("time (ps)") plt.ylabel("transmitted signal (mV)") plt.xlim(time_ps[0], 30) plt.legend() plt.tight_layout() .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_001.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 50-52 By looking at the first peak shift, we can get a rough estimate of the permittivity .. GENERATED FROM PYTHON SOURCE LINES 52-56 .. code-block:: Python eps_guess = tx.get_epsilon_estimate(v_ref, v_samp, time, sample_thickness) print(eps_guess) .. rst-class:: sphx-glr-script-out .. code-block:: none 12.3904 .. GENERATED FROM PYTHON SOURCE LINES 57-58 We now switch to the frequency domain by computing the Fourier transform .. GENERATED FROM PYTHON SOURCE LINES 58-93 .. code-block:: Python freqs_ref, fft_ref = tx.fft(time, v_ref) freqs_samp, fft_samp = tx.fft(time, v_samp) freqs_THz = freqs_ref * 1e-12 plt.figure() plt.plot(freqs_THz, np.abs(fft_ref), label="reference", c="#5aa2a2") plt.plot(freqs_THz, np.abs(fft_samp), label="sample", c="#b5514c") plt.xlabel("frequency (THz)") plt.ylabel("transmitted signal amplitude (mV)") plt.xlim(0, 2) plt.legend() plt.tight_layout() plt.figure() plt.plot( freqs_THz, np.unwrap(np.angle(fft_ref)) * 180 / tx.pi, label="reference", c="#5aa2a2", ) plt.plot( freqs_THz, np.unwrap(np.angle(fft_samp)) * 180 / tx.pi, label="sample", c="#b5514c", ) plt.xlabel("frequency (THz)") plt.ylabel("transmitted signal phase (degrees)") plt.xlim(0, 2) plt.ylim(-10000, 0) plt.legend() plt.tight_layout() .. rst-class:: sphx-glr-horizontal * .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_002.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_002.png :class: sphx-glr-multi-img * .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_003.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_003.png :class: sphx-glr-multi-img .. GENERATED FROM PYTHON SOURCE LINES 94-95 Let's calculate the transmission coefficient .. GENERATED FROM PYTHON SOURCE LINES 95-179 .. code-block:: Python transmission = fft_samp / fft_ref #### TODO: wavelet transform check # import pywt # alpha = 0.01 # # cA, cD = pywt.dwt(fft_ref, "coif4", "smooth") # cD = pywt.threshold(cD, alpha, "soft") # fft_ref_wl = pywt.idwt(cA, cD, "coif4", "smooth") # # cA, cD = pywt.dwt(fft_samp, "coif4", "smooth") # cD = pywt.threshold(cD, alpha, "soft") # fft_samp_wl = pywt.idwt(cA, cD, "coif4", "smooth") # transmission_wl = fft_samp_wl / fft_ref_wl # # # cA, cD = pywt.dwt(transmission, "coif4", "smooth") # cD = pywt.threshold(cD, alpha, "soft") # transmission_wl = pywt.idwt(cA, cD, "coif4", "smooth") # # transmission_wl = transmission_wl[:513] # transmission = transmission_wl # # # freqs_THz, imin, imax = restrict(freqs_THz, 0.1, 2.5) # # transmission = transmission[imin:imax] # plt.close("all") # plt.figure() # plt.plot(freqs_THz, np.abs(transmission),"-") # plt.plot(freqs_THz, np.abs(transmission_wl),"--") # plt.xlabel("frequency (THz)") # plt.ylabel("transmission amplitude") # plt.xlim(0, 2) # plt.ylim(0, 1) # plt.tight_layout() # # plt.figure() # plt.plot(freqs_THz, (np.angle(transmission)) * 180 / np.pi,"-") # plt.plot(freqs_THz, (np.angle(transmission_wl)) * 180 / np.pi,"--") # plt.xlabel("frequency (THz)") # plt.ylabel("transmission phase (degree)") # plt.xlim(0, 2) # plt.tight_layout() #### adapted phase unwrapping scheme: discards the noisy phase at low frequencies, # and carries out a normal unwrapping with the reliable phase part. A missing phase # profile at low frequencies down to DC is then extrapolated from the unwrapped phase # at higher frequencies. In most cases the assumption of a linear phase is sufficient # (Duvillaret et al. 1996). The whole phase profile is then forced to start at zero. # # phi = np.angle(transmission) # phi_unwrapped = np.unwrap(phi) # freqs1, imin, imax = restrict(freqs_THz, 0.1, 1) # phi1 = phi[imin:imax] # # phi1_unwrapped = np.unwrap(phi1) # fit = np.polyfit(freqs1, phi1_unwrapped, 1) # # # plt.close("all") # plt.figure() # plt.plot(freqs_THz, phi_unwrapped) # plt.plot(freqs1, phi1_unwrapped, "o") # plt.plot(freqs_THz, fit[0] * freqs_THz) # plt.plot(freqs_THz, fit[0] * freqs_THz + fit[1], "--") # plt.show() # # # plt.xlabel("frequency (THz)") # plt.ylabel("transmission phase (rad)") # plt.tight_layout() # # phi = fit[0] * freqs_THz # transmission = np.abs(transmission) * np.exp(1j * phi) freqs_THz, imin, imax = tx.restrict(freqs_THz, 0.2, 1.5) transmission = transmission[imin:imax] .. GENERATED FROM PYTHON SOURCE LINES 180-181 To describe our sample we use a Sample object .. GENERATED FROM PYTHON SOURCE LINES 181-188 .. code-block:: Python sample = tx.Sample( { "unknown": {"epsilon": None, "mu": 1.0, "thickness": sample_thickness}, } ) .. GENERATED FROM PYTHON SOURCE LINES 189-190 We ar now ready to perform the extraction .. GENERATED FROM PYTHON SOURCE LINES 190-205 .. code-block:: Python wavelengths = tx.c / freqs_THz * 1e-12 epsilon_opt, h_opt, opt = tx.extract( sample, wavelengths, transmission, eps_re_min=1, eps_re_max=100, eps_im_min=-10, eps_im_max=10, epsilon_initial_guess=eps_guess, ) .. GENERATED FROM PYTHON SOURCE LINES 206-207 Smooth the permittivity data .. GENERATED FROM PYTHON SOURCE LINES 207-211 .. code-block:: Python eps_smooth = tx.smooth(epsilon_opt) .. GENERATED FROM PYTHON SOURCE LINES 212-213 Plot extracted values .. GENERATED FROM PYTHON SOURCE LINES 213-235 .. code-block:: Python plt.figure() plt.plot(freqs_THz, epsilon_opt.real, "o", label="raw", alpha=0.5, c="#5aa2a2") plt.plot(freqs_THz, eps_smooth.real, label="smoothed", c="#b5514c") plt.xlabel("frequency (THz)") plt.ylabel(r"Re $\varepsilon$") plt.ylim(10, 14) plt.legend() plt.tight_layout() plt.figure() plt.plot(freqs_THz, epsilon_opt.imag, "o", label="raw", alpha=0.5, c="#5aa2a2") plt.plot(freqs_THz, eps_smooth.imag, label="smoothed", c="#b5514c") plt.xlabel("frequency (THz)") plt.ylabel(r"Im $\varepsilon$") plt.ylim(-1, 1) plt.legend() plt.tight_layout() .. rst-class:: sphx-glr-horizontal * .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_004.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_004.png :class: sphx-glr-multi-img * .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_005.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_005.png :class: sphx-glr-multi-img .. GENERATED FROM PYTHON SOURCE LINES 236-237 Check the transmission .. GENERATED FROM PYTHON SOURCE LINES 237-322 .. code-block:: Python t_model = tx.sample_transmission( epsilon_opt, h_opt, sample=sample, wavelengths=wavelengths ) t_model_smooth = tx.sample_transmission( eps_smooth, h_opt, sample=sample, wavelengths=wavelengths ) gamma = 2 * tx.pi / wavelengths thickness_tot = sum([k["thickness"] for lay, k in sample.items()]) phasor = np.exp(-1j * gamma * thickness_tot) fig, ax = plt.subplots() ax.plot( freqs_THz, np.abs(transmission) ** 2, "s", label="meas.", alpha=0.3, lw=0, c="#656e7e", mew=0, ) ax.plot( freqs_THz, np.abs(t_model) ** 2, "-", label="sim. raw", alpha=0.3, lw=1, c="#656e7e", mew=0, ) ax.plot( freqs_THz, np.abs(t_model_smooth) ** 2, "-", label="sim. smooth", alpha=1, lw=1, c="#AE383E", ) ax.set_ylim(0, 1) ax.set_xlabel("frequency (THz)") ax.legend() ax.set_ylabel(r"amplitude") plt.tight_layout() fig, ax = plt.subplots() ax.plot( freqs_THz, (np.angle(phasor * transmission)) * 180 / tx.pi, "s", label="meas.", alpha=0.3, lw=0, c="#656e7e", mew=0, ) ax.plot( freqs_THz, (np.angle(t_model)) * 180 / tx.pi, "-", label="sim. raw", alpha=0.3, lw=1, c="#656e7e", mew=0, ) ax.plot( freqs_THz, (np.angle(t_model_smooth)) * 180 / tx.pi, "-", label="sim. smooth", alpha=1, lw=1, c="#AE383E", ) ax.set_xlabel("frequency (THz)") ax.legend() ax.set_ylabel(r"phase") plt.tight_layout() .. rst-class:: sphx-glr-horizontal * .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_006.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_006.png :class: sphx-glr-multi-img * .. image-sg:: /auto_examples/images/sphx_glr_plot_tds_007.png :alt: plot tds :srcset: /auto_examples/images/sphx_glr_plot_tds_007.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 8.213 seconds) .. _sphx_glr_download_auto_examples_plot_tds.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_tds.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_tds.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_