
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "generated/autoexamples/01-framework/04-description-based-simulation.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

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

        :ref:`Go to the end <sphx_glr_download_generated_autoexamples_01-framework_04-description-based-simulation.py>`
        to download the full example code or to run this example in your browser via Binder.

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

.. _sphx_glr_generated_autoexamples_01-framework_04-description-based-simulation.py:


================================
4. Description-based simulation
================================

In lesson 3 the events were generated by the layout. They can also come from
an existing sequence: a Pulseq file written with another tool, or the
sequence description a scanner streams during acquisition. This lesson
simulates such descriptions directly, without restating the sequence
parameters.

**Learning objectives**

- Inspect a sequence description: events, timestamps and RF definitions.
- Simulate a description with ``from_description``, and understand the role
  of the handlers.
- Simulate a Pulseq file with ``from_pulseq``.

Previous: :doc:`03-custom-signal-model`. Next: :doc:`05-custom-operator`, which
adds a custom preparation and readout.

.. GENERATED FROM PYTHON SOURCE LINES 24-30

.. colab-link::
   :needs_gpu: 0

   !pip install blochsim matplotlib
   !wget --quiet --no-clobber https://raw.githubusercontent.com/pulserver/blochsim/main/docs/figure_style.py
   !wget --quiet --no-clobber https://raw.githubusercontent.com/pulserver/blochsim/main/examples/01-framework/fse.seq

.. GENERATED FROM PYTHON SOURCE LINES 30-48








.. GENERATED FROM PYTHON SOURCE LINES 49-60

Sequence description
--------------------

A *sequence description* (:class:`~blochsim.SequenceDescription`) lists the
events of one repetition: RF pulses, ADC windows and waits, each with its
timestamp and parameters (flip angle, phase, RF definition). It is the input
of every simulation.

The default description of a simulator is generated by its layout from the
sequence parameters, and ``describe`` returns it. For the 60-degree FSE of
lesson 1:

.. GENERATED FROM PYTHON SOURCE LINES 60-78

.. code-block:: Python

    import torch

    from blochsim.simulators import FSESimulator

    fse = FSESimulator(ESP=5.0, TR=3000.0)
    flip = torch.full((48,), 60.0)

    description = fse.describe(flip=flip, ESP=5.0, TR=3000.0)
    print(f"{len(description.events)} events, {len(description.adc_events)} readouts")





.. image-sg:: /generated/autoexamples/01-framework/images/sphx_glr_04-description-based-simulation_001.png
   :alt: 04 description based simulation
   :srcset: /generated/autoexamples/01-framework/images/sphx_glr_04-description-based-simulation_001.png
   :class: sphx-glr-single-img


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

 .. code-block:: none

    145 events, 48 readouts




.. GENERATED FROM PYTHON SOURCE LINES 79-88

The first 30 ms show the excitation and the refocusing pulses centred
between readouts. The description contains no gradients: the scanner stream
does not carry them, and blochsim does not read them from a Pulseq file.

Simulation from a description
-----------------------------

``from_description`` constructs a simulator from a description, bypassing
the layout. Only tissue properties and simulation settings are passed:

.. GENERATED FROM PYTHON SOURCE LINES 88-91

.. code-block:: Python

    from_events = FSESimulator.from_description(description, states=48, T1=1000.0, T2=80.0)
    signal = from_events.simulate()








.. GENERATED FROM PYTHON SOURCE LINES 92-98

The handlers of the class are still used: they play each event and define
the dephasing between events, which the description does not specify.
``FSESimulator`` places crushers around each refocusing pulse. The same
events played with :class:`~blochsim.simulators.MRFSimulator`, whose readout
applies one unit of dephasing after each sample, describe a different
sequence:

.. GENERATED FROM PYTHON SOURCE LINES 98-121

.. code-block:: Python

    from blochsim.simulators import MRFSimulator

    as_mrf = MRFSimulator.from_description(description, states=48, T1=1000.0, T2=80.0)
    wrong = as_mrf.simulate()





.. image-sg:: /generated/autoexamples/01-framework/images/sphx_glr_04-description-based-simulation_002.png
   :alt: 04 description based simulation
   :srcset: /generated/autoexamples/01-framework/images/sphx_glr_04-description-based-simulation_002.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 122-141

With the FSE handlers the result matches the shipped simulator up to a small
offset: ``FSESimulator`` also applies the T1 recovery between trains, which is
not an event and is therefore absent from the description. With the MRF
handlers the CPMG condition is not met and the echo amplitudes oscillate and
decay. The class therefore specifies how the events are to be interpreted.

Scanner stream
--------------

During acquisition, pulserver streams the description of the running
sequence with the raw data. :func:`~blochsim.read_mrd_description` reads it
from an MRD stream, and ``from_description`` simulates it as above. A
reconstruction can thus simulate the sequence that was actually played.

Pulseq file
-----------

``from_pulseq`` reads the description from a ``.seq`` file, parsed by
pypulseq. The file below is a short FSE:

.. GENERATED FROM PYTHON SOURCE LINES 141-160

.. code-block:: Python

    from_file = FSESimulator.from_pulseq(SEQ_FILE, states=20)
    file_signal = from_file.simulate(T1=1000.0, T2=torch.tensor([80.0, 110.0]))





.. image-sg:: /generated/autoexamples/01-framework/images/sphx_glr_04-description-based-simulation_003.png
   :alt: 04 description based simulation
   :srcset: /generated/autoexamples/01-framework/images/sphx_glr_04-description-based-simulation_003.png
   :class: sphx-glr-single-img


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

 .. code-block:: none

    8 echoes, 6.3 ms apart




.. GENERATED FROM PYTHON SOURCE LINES 161-181

Echo spacing, echo train length, refocusing angle and RF shapes are read
from the file; only the tissue and the handler class are specified.

The number of blocks per repetition is taken from the ``TRSize`` definition
of the file. Each readout is timestamped at the sample where the trajectory
crosses the k-space centre, i.e. at the echo time.

Specification
-------------

What this lesson did, stated the way you would ask an agent for it:

.. code-block:: text

   With blochsim, read the sequence in fse.seq with FSESimulator.from_pulseq
   and simulate it in white matter and grey matter (T1 1 s; T2 80 and
   110 ms). Plot the events of one repetition and the signal at each echo
   time. Separately, take the description of a 48-echo, 60-degree FSE and
   simulate it with the FSE handlers and with the MRF handlers, to show that
   the handlers decide what happens between the events.


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

   **Total running time of the script:** (0 minutes 2.436 seconds)


.. _sphx_glr_download_generated_autoexamples_01-framework_04-description-based-simulation.py:

.. only:: html

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

    .. container:: binder-badge

      .. image:: images/binder_badge_logo.svg
        :target: https://mybinder.org/v2/gh/pulserver/blochsim/gh-pages?urlpath=lab/tree/latest/notebooks/generated/autoexamples/01-framework/04-description-based-simulation.ipynb
        :alt: Launch binder
        :width: 150 px

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

      :download:`Download Jupyter notebook: 04-description-based-simulation.ipynb <04-description-based-simulation.ipynb>`

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

      :download:`Download Python source code: 04-description-based-simulation.py <04-description-based-simulation.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: 04-description-based-simulation.zip <04-description-based-simulation.zip>`


.. only:: html

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

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