Skip to article frontmatterSkip to article content

Spin echo CPMG

CPMG condition for a simple spin-echo sequence

Notebook Cell
!pip install pypulseq &> /dev/null
!pip install  torchkbnufft --no-deps
!pip install MRzeroCore --no-deps
!pip install pydisseqt
!pip install ismrmrd

!wget https://github.com/MRsources/MRzero-Core/raw/main/documentation/playground_mr0/numerical_brain_cropped.mat &> /dev/null
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: torchkbnufft in /home/runner/.local/lib/python3.12/site-packages (1.5.2)
Defaulting to user installation because normal site-packages is not writeable
Collecting MRzeroCore
  Downloading MRzeroCore-0.4.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB)
Downloading MRzeroCore-0.4.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (367 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 367.8/367.8 kB 19.5 MB/s eta 0:00:00
Installing collected packages: MRzeroCore
Successfully installed MRzeroCore-0.4.1
Defaulting to user installation because normal site-packages is not writeable
Collecting pydisseqt
  Downloading pydisseqt-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (1.7 kB)
Downloading pydisseqt-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (471 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/471.2 kB ? eta -:--:--
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 471.2/471.2 kB 17.3 MB/s eta 0:00:00
Installing collected packages: pydisseqt
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
mrzerocore 0.4.1 requires ismrmrd, which is not installed.
mrzerocore 0.4.1 requires scikit-image, which is not installed.
mrzerocore 0.4.1 requires torch>=1.12, which is not installed.
mrzerocore 0.4.1 requires tqdm, which is not installed.
Successfully installed pydisseqt-0.2.0
Defaulting to user installation because normal site-packages is not writeable
Collecting ismrmrd
  Downloading ismrmrd-1.14.2-py3-none-any.whl.metadata (927 bytes)
Collecting h5py>=2.3 (from ismrmrd)
  Downloading h5py-3.15.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (3.0 kB)
Requirement already satisfied: numpy>=1.22.0 in /home/runner/.local/lib/python3.12/site-packages (from ismrmrd) (2.3.4)
Collecting xsdata>=22.12 (from ismrmrd)
  Downloading xsdata-25.7-py3-none-any.whl.metadata (5.5 kB)
Requirement already satisfied: typing-extensions>=4.7.0 in /usr/lib/python3/dist-packages (from xsdata>=22.12->ismrmrd) (4.10.0)
Downloading ismrmrd-1.14.2-py3-none-any.whl (32 kB)
Downloading h5py-3.15.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (5.1 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 152.6 MB/s eta 0:00:01
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1/5.1 MB 116.0 MB/s eta 0:00:00
Downloading xsdata-25.7-py3-none-any.whl (234 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 234.5/234.5 kB 66.8 MB/s eta 0:00:00
Installing collected packages: xsdata, h5py, ismrmrd
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
mrzerocore 0.4.1 requires scikit-image, which is not installed.
mrzerocore 0.4.1 requires torch>=1.12, which is not installed.
mrzerocore 0.4.1 requires tqdm, which is not installed.
Successfully installed h5py-3.15.1 ismrmrd-1.14.2 xsdata-25.7
import numpy as np

import MRzeroCore as mr0
import pypulseq as pp
import matplotlib.pyplot as plt

plt.rcParams['figure.figsize'] = [10, 5]
plt.rcParams['figure.dpi'] = 100 # 200 e.g. is really fine, but slower

experiment_id = 'CPMG'
# %% S1. SETUP sys
# choose the scanner limits
system = pp.Opts(
    max_grad=28, grad_unit='mT/m', max_slew=150, slew_unit='T/m/s',
    rf_ringdown_time=20e-6, rf_dead_time=100e-6,
    adc_dead_time=20e-6, grad_raster_time=50*10e-6
)
#@title CMPG in a brain phantom - sequence
# %% DEFINE the sequence, FOV and resolution
seq = pp.Sequence(system)
fov = 200e-3
Nread = 31    #@param {type:"slider", min:0, max:512, step:1}
Nphase = 1
slice_thickness = 8e-3  # slice
refocusing_angle=180 #@param {type:"slider", min:0, max:360, step:1}
# Define rf events
ETL=12 #@param {type:"slider", min:1, max:32, step:1}
TE_ms=1 #@param {type:"slider", min:1, max:32, step:1}
TE_ms*=1e-3

rf1, _, _ = pp.make_sinc_pulse(
    flip_angle=90 * np.pi / 180, duration=1e-3,
    slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4,
    delay=0, system=system, return_gz=True
)
# rf1 = pp.make_block_pulse(flip_angle=90 * np.pi / 180, duration=1e-3, system=system)
rf2, _, _ = pp.make_sinc_pulse(
    flip_angle=refocusing_angle * np.pi / 180, duration=1e-3, phase_offset=90 * np.pi / 180,
    slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4,
    system=system, return_gz=True
)

sym_rf_block_delay=pp.calc_duration(rf1)-rf1.ringdown_time+rf1.delay

# Define other gradients and ADC events
dwell_time=1e-4
adc = pp.make_adc(num_samples=Nread, duration=Nread*dwell_time, phase_offset=0 * np.pi / 180, system=system)
minTE = pp.calc_duration(adc)+sym_rf_block_delay
print("Set TE to minTE ",minTE)
TEdelay=(TE_ms-minTE)/2
if TEdelay<0: TEdelay=0

# ======
# CONSTRUCT SEQUENCE
# ======
seq.add_block(rf1,sym_rf_block_delay)
seq.add_block(pp.make_delay(TEdelay+minTE/2 - sym_rf_block_delay))
for i in range(0, ETL):
    seq.add_block(rf2,sym_rf_block_delay)
    seq.add_block(pp.make_delay(TEdelay))
    seq.add_block(adc)
    seq.add_block(pp.make_delay(TEdelay))

# %% SIMULATE  the external.seq file and add acquired signal to ADC plot
#quick 2D brain phantom sim and plot
signal = mr0.util.simulate_2d(seq)
# seq.plot(plot_now=False)
# mr0.util.insert_signal_plot(seq=seq, signal =signal.numpy())
# plt.show()
/tmp/ipykernel_2278/3227797924.py:14: UserWarning: Specified RF delay 0.00 us is less than the dead time 100 us. Delay was increased to the dead time.
  rf1, _, _ = pp.make_sinc_pulse(
/tmp/ipykernel_2278/3227797924.py:20: UserWarning: Specified RF delay 0.00 us is less than the dead time 100 us. Delay was increased to the dead time.
  rf2, _, _ = pp.make_sinc_pulse(
/tmp/ipykernel_2278/3227797924.py:30: UserWarning: Specified ADC delay 0.00 us is less than the dead time 20 us. Delay was increased to the dead time.
  adc = pp.make_adc(num_samples=Nread, duration=Nread*dwell_time, phase_offset=0 * np.pi / 180, system=system)
Set TE to minTE  0.0051400000000000005
DEPRECATED: util.simulate_2d will be removed in the future.
Use util.simulate() instead (together with util.load_phantom() if necessary
---------------------------------------------------------------------------
ParseError                                Traceback (most recent call last)
Cell In[3], line 49
     45     seq.add_block(pp.make_delay(TEdelay))
     47 # %% SIMULATE  the external.seq file and add acquired signal to ADC plot
     48 #quick 2D brain phantom sim and plot
---> 49 signal = mr0.util.simulate_2d(seq)
     50 # seq.plot(plot_now=False)
     51 # mr0.util.insert_signal_plot(seq=seq, signal =signal.numpy())
     52 # plt.show()

File ~/work/MRzero-Docs/MRzero-Docs/.venv/lib/python3.11/site-packages/MRzeroCore/util.py:870, in simulate_2d(seq, sim_size, noise_level, dB0, B0_scale, B0_polynomial)
    867 obj_p = obj_p.build()
    869 # MR zero simulation
--> 870 seq0 = mr0.Sequence.import_file(seq_filename)
    872 # Remove temporary sequence file
    873 if not isinstance(seq, str):

File ~/work/MRzero-Docs/MRzero-Docs/.venv/lib/python3.11/site-packages/MRzeroCore/sequence.py:457, in Sequence.import_file(cls, file_name, exact_trajectories, print_stats, default_shim, ref_voltage, resolution)
    455 start = time()
    456 if file_name.endswith(".seq"):
--> 457     parser = pydisseqt.load_pulseq(file_name)
    458 else:
    459     parser = pydisseqt.load_dsv(file_name, ref_voltage, resolution)

ParseError: No such file or directory (os error 2)
seq.plot(plot_now=False)
mr0.util.insert_signal_plot(seq=seq, signal =signal.numpy())
plt.close(plt.figure(2))
plt.show()
# Check whether the timing of the sequence is correct
ok, error_report = seq.check_timing()
if ok:
    print('Timing check passed successfully')
else:
    print('Timing check failed. Error listing follows:')
    [print(e) for e in error_report]

# Prepare the sequence output for the scanner
seq.set_definition('FOV', [fov, fov, slice_thickness])
seq.set_definition('Name', 'CPMG')
seq.write(experiment_id + ".seq")