.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples\07-Circuit\Circuit_AMI.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_07-Circuit_Circuit_AMI.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_07-Circuit_Circuit_AMI.py:


Circuit: AMI PostProcessing
----------------------------------
This example shows how you can use PyAEDT to perform advanced postprocessing of AMI simulations.

.. GENERATED FROM PYTHON SOURCE LINES 8-11

Perform required imports
~~~~~~~~~~~~~~~~~~~~~~~~
Perform required imports and set the local path to the path for PyAEDT.

.. GENERATED FROM PYTHON SOURCE LINES 11-24

.. code-block:: Python


    # sphinx_gallery_thumbnail_path = 'Resources/spectrum_plot.png'

    import os
    from matplotlib import pyplot as plt
    import numpy as np

    import pyaedt

    # Set local path to path for PyAEDT
    temp_folder = pyaedt.generate_unique_folder_name()
    project_path = pyaedt.downloads.download_file("ami", "ami_usb.aedtz", temp_folder)








.. GENERATED FROM PYTHON SOURCE LINES 25-28

Set AEDT version
~~~~~~~~~~~~~~~~
Set AEDT version.

.. GENERATED FROM PYTHON SOURCE LINES 28-31

.. code-block:: Python


    aedt_version = "2024.1"








.. GENERATED FROM PYTHON SOURCE LINES 32-38

Set non-graphical mode
~~~~~~~~~~~~~~~~~~~~~~
Set non-graphical mode. 
You can set ``non_graphical`` either to ``True`` or ``False``.
The Boolean parameter ``new_thread`` defines whether to create a new instance
of AEDT or try to connect to an existing instance of it.

.. GENERATED FROM PYTHON SOURCE LINES 38-42

.. code-block:: Python


    non_graphical = False
    NewThread = True








.. GENERATED FROM PYTHON SOURCE LINES 43-48

Launch AEDT with Circuit and enable Pandas as the output format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All outputs obtained with the `get_solution_data` method will have the Pandas format.
Launch AEDT with Circuit. The :class:`pyaedt.Desktop` class initializes AEDT
and starts the specified version in the specified mode.

.. GENERATED FROM PYTHON SOURCE LINES 48-53

.. code-block:: Python


    pyaedt.settings.enable_pandas_output = True
    cir = pyaedt.Circuit(projectname=os.path.join(project_path), non_graphical=non_graphical,
                         specified_version=aedt_version, new_desktop_session=NewThread)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    C:\actions-runner\_work\_tool\Python\3.10.9\x64\lib\subprocess.py:1072: ResourceWarning: subprocess 12320 is still running
      _warn("subprocess %s is still running" % self.pid,
    C:\actions-runner\_work\pyaedt\pyaedt\.venv\lib\site-packages\pyaedt\generic\settings.py:383: ResourceWarning: unclosed file <_io.TextIOWrapper name='D:\\Temp\\pyaedt_ansys.log' mode='a' encoding='cp1252'>
      self._logger = val




.. GENERATED FROM PYTHON SOURCE LINES 54-57

Solve AMI setup
~~~~~~~~~~~~~~~
Solve the transient setup.

.. GENERATED FROM PYTHON SOURCE LINES 57-60

.. code-block:: Python


    cir.analyze()





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 61-64

Get AMI report
~~~~~~~~~~~~~~
Get AMI report data

.. GENERATED FROM PYTHON SOURCE LINES 64-73

.. code-block:: Python


    plot_name = "WaveAfterProbe<b_input_43.int_ami_rx>"
    cir.solution_type = "NexximAMI"
    original_data = cir.post.get_solution_data(expressions=plot_name, domain="Time",
                                               variations=cir.available_variations.nominal)
    original_data_value = original_data.full_matrix_real_imag[0]
    original_data_sweep = original_data.primary_sweep_values
    print(original_data_value)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

               WaveAfterProbe<b_input_43.int_ami_rx>
    0.000000                             -553.298382
    0.003125                             -553.298382
    0.006250                             -553.298382
    0.009375                             -553.298382
    0.012500                             -553.298382
    ...                                          ...
    99.984375                             -25.138119
    99.987500                              19.046320
    99.990625                              60.268984
    99.993750                              98.348353
    99.996875                             133.328724

    [32000 rows x 1 columns]




.. GENERATED FROM PYTHON SOURCE LINES 74-77

Plot data
~~~~~~~~~
Create a plot based on solution data.

.. GENERATED FROM PYTHON SOURCE LINES 77-80

.. code-block:: Python


    fig = original_data.plot()




.. image-sg:: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_001.png
   :alt: Simulation Results Plot
   :srcset: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.




.. GENERATED FROM PYTHON SOURCE LINES 81-84

Sample WaveAfterProbe waveform using receiver clock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extract waveform at specific clock time plus half unit interval

.. GENERATED FROM PYTHON SOURCE LINES 84-96

.. code-block:: Python


    probe_name = "b_input_43"
    source_name = "b_output4_42"
    plot_type = "WaveAfterProbe"
    setup_name = "AMIAnalysis"
    ignore_bits = 100
    unit_interval = 0.1e-9
    sample_waveform = cir.post.sample_ami_waveform(setup=setup_name, probe=probe_name, source=source_name,
                                                   variation_list_w_value=cir.available_variations.nominal,
                                                   unit_interval=unit_interval, ignore_bits=ignore_bits,
                                                   plot_type=plot_type)








.. GENERATED FROM PYTHON SOURCE LINES 97-100

Plot waveform and samples
~~~~~~~~~~~~~~~~~~~~~~~~~
Create the plot from a start time to stop time in seconds

.. GENERATED FROM PYTHON SOURCE LINES 100-142

.. code-block:: Python


    tstop = 55e-9
    tstart = 50e-9
    scale_time = pyaedt.constants.unit_converter(1, unit_system="Time", input_units="s",
                                                 output_units=original_data.units_sweeps["Time"])
    scale_data = pyaedt.constants.unit_converter(1, unit_system="Voltage", input_units="V",
                                                 output_units=original_data.units_data[plot_name])

    tstop_ns = scale_time * tstop
    tstart_ns = scale_time * tstart

    for time in original_data_value[plot_name].index:
        if tstart_ns <= time[0]:
            start_index_original_data = time[0]
            break
    for time in original_data_value[plot_name][start_index_original_data:].index:
        if time[0] >= tstop_ns:
            stop_index_original_data = time[0]
            break
    for time in sample_waveform[0].index:
        if tstart <= time:
            sample_index = sample_waveform[0].index == time
            start_index_waveform = sample_index.tolist().index(True)
            break
    for time in sample_waveform[0].index:
        if time >= tstop:
            sample_index = sample_waveform[0].index == time
            stop_index_waveform = sample_index.tolist().index(True)
            break

    original_data_zoom = original_data_value[start_index_original_data:stop_index_original_data]
    sampled_data_zoom = sample_waveform[0].values[start_index_waveform:stop_index_waveform] * scale_data
    sampled_time_zoom = sample_waveform[0].index[start_index_waveform:stop_index_waveform] * scale_time

    fig, ax = plt.subplots()
    ax.plot(sampled_time_zoom, sampled_data_zoom, "r*")
    ax.plot(np.array(list(original_data_zoom.index.values)), original_data_zoom.values)
    ax.set_title('WaveAfterProbe')
    ax.set_xlabel(original_data.units_sweeps["Time"])
    ax.set_ylabel(original_data.units_data[plot_name])
    plt.show()




.. image-sg:: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_002.png
   :alt: WaveAfterProbe
   :srcset: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_002.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 143-146

Plot Slicer Scatter
~~~~~~~~~~~~~~~~~~~
Create the plot from a start time to stop time in seconds

.. GENERATED FROM PYTHON SOURCE LINES 146-154

.. code-block:: Python


    fig, ax2 = plt.subplots()
    ax2.plot(sample_waveform[0].index, sample_waveform[0].values, "r*")
    ax2.set_title('Slicer Scatter: WaveAfterProbe')
    ax2.set_xlabel("s")
    ax2.set_ylabel("V")
    plt.show()




.. image-sg:: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_003.png
   :alt: Slicer Scatter: WaveAfterProbe
   :srcset: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_003.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 155-158

Plot scatter histogram
~~~~~~~~~~~~~~~~~~~~~~
Create the plot from a start time to stop time in seconds.

.. GENERATED FROM PYTHON SOURCE LINES 158-166

.. code-block:: Python


    fig, ax4 = plt.subplots()
    ax4.set_title('Slicer Histogram: WaveAfterProbe')
    ax4.hist(sample_waveform[0].values, orientation='horizontal')
    ax4.set_ylabel("V")
    ax4.grid()
    plt.show()




.. image-sg:: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_004.png
   :alt: Slicer Histogram: WaveAfterProbe
   :srcset: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_004.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 167-170

Get Transient report
~~~~~~~~~~~~~~~~~~~~
Get Transient report data

.. GENERATED FROM PYTHON SOURCE LINES 170-178

.. code-block:: Python


    plot_name = "V(b_input_43.int_ami_rx.eye_probe.out)"
    cir.solution_type = "NexximTransient"
    original_data = cir.post.get_solution_data(expressions=plot_name,
                                               domain="Time",
                                               setup_sweep_name="NexximTransient",
                                               variations=cir.available_variations.nominal)








.. GENERATED FROM PYTHON SOURCE LINES 179-182

Sample waveform using a user-defined clock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extract waveform at specific clock time plus half unit interval.

.. GENERATED FROM PYTHON SOURCE LINES 182-200

.. code-block:: Python


    original_data.enable_pandas_output = False
    original_data_value = original_data.data_real()
    original_data_sweep = original_data.primary_sweep_values
    waveform_unit = original_data.units_data[plot_name]
    waveform_sweep_unit = original_data.units_sweeps["Time"]
    tics = np.arange(20e-9, 100e-9, 1e-10, dtype=float)

    sample_waveform = cir.post.sample_waveform(
        waveform_data=original_data_value,
        waveform_sweep=original_data_sweep,
        waveform_unit=waveform_unit,
        waveform_sweep_unit=waveform_sweep_unit,
        unit_interval=unit_interval,
        clock_tics=tics,
        pandas_enabled=False,
    )








.. GENERATED FROM PYTHON SOURCE LINES 201-204

Plot waveform and samples
~~~~~~~~~~~~~~~~~~~~~~~~~
Create the plot from a start time to stop time in seconds.

.. GENERATED FROM PYTHON SOURCE LINES 204-251

.. code-block:: Python


    tstop = 40.0e-9
    tstart = 25.0e-9
    scale_time = pyaedt.constants.unit_converter(1, unit_system="Time", input_units="s",
                                                 output_units=waveform_sweep_unit)
    scale_data = pyaedt.constants.unit_converter(1, unit_system="Voltage", input_units="V",
                                                 output_units=waveform_unit)

    tstop_ns = scale_time * tstop
    tstart_ns = scale_time * tstart

    for time in original_data_sweep:
        if tstart_ns <= time:
            start_index_original_data = original_data_sweep.index(time)
            break
    for time in original_data_sweep[start_index_original_data:]:
        if time >= tstop_ns:
            stop_index_original_data = original_data_sweep.index(time)
            break
    cont = 0
    for frame in sample_waveform:
        if tstart <= frame[0]:
            start_index_waveform = cont
            break
        cont += 1
    for frame in sample_waveform[start_index_waveform:]:
        if frame[0] >= tstop:
            stop_index_waveform = cont
            break
        cont += 1

    original_data_zoom = original_data_value[start_index_original_data:stop_index_original_data]
    original_sweep_zoom = original_data_sweep[start_index_original_data:stop_index_original_data]
    original_data_zoom_array = np.array(list(map(list, zip(original_sweep_zoom, original_data_zoom))))
    original_data_zoom_array[:, 0] *= 1
    sampled_data_zoom_array = np.array(sample_waveform[start_index_waveform:stop_index_waveform])
    sampled_data_zoom_array[:, 0] *= scale_time
    sampled_data_zoom_array[:, 1] *= scale_data

    fig, ax = plt.subplots()
    ax.plot(sampled_data_zoom_array[:, 0], sampled_data_zoom_array[:, 1], "r*")
    ax.plot(original_sweep_zoom, original_data_zoom_array[:, 1])
    ax.set_title(plot_name)
    ax.set_xlabel(waveform_sweep_unit)
    ax.set_ylabel(waveform_unit)
    plt.show()




.. image-sg:: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_005.png
   :alt: V(b_input_43.int_ami_rx.eye_probe.out)
   :srcset: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_005.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 252-255

Plot slicer scatter
~~~~~~~~~~~~~~~~~~~
Create the plot from a start time to stop time in seconds.

.. GENERATED FROM PYTHON SOURCE LINES 255-264

.. code-block:: Python


    sample_waveform_array = np.array(sample_waveform)
    fig, ax2 = plt.subplots()
    ax2.plot(sample_waveform_array[:, 0], sample_waveform_array[:, 1], "r*")
    ax2.set_title('Slicer Scatter: ' + plot_name)
    ax2.set_xlabel("s")
    ax2.set_ylabel("V")
    plt.show()




.. image-sg:: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_006.png
   :alt: Slicer Scatter: V(b_input_43.int_ami_rx.eye_probe.out)
   :srcset: /examples/07-Circuit/images/sphx_glr_Circuit_AMI_006.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 265-268

Save project and close AEDT
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Save the project and close AEDT.

.. GENERATED FROM PYTHON SOURCE LINES 268-272

.. code-block:: Python


    cir.save_project()
    print("Project Saved in {}".format(cir.project_path))
    cir.release_desktop()




.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Project Saved in D:/Temp/pyaedt_prj_S8A/ami/

    True




.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (1 minutes 14.302 seconds)


.. _sphx_glr_download_examples_07-Circuit_Circuit_AMI.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: Circuit_AMI.ipynb <Circuit_AMI.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: Circuit_AMI.py <Circuit_AMI.py>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_