Skip to content

Instantly share code, notes, and snippets.

@fzimmermann89
Created February 6, 2024 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fzimmermann89/d91a8403d4ae0b407512c10b43a58ba2 to your computer and use it in GitHub Desktop.
Save fzimmermann89/d91a8403d4ae0b407512c10b43a58ba2 to your computer and use it in GitHub Desktop.
pulseq slice profile
import math
from pathlib import Path
from datetime import datetime
import pypulseq as pp
### SETTINGS ###
timestamp = datetime.now().strftime("%y%m%d-%H%M%S")
filename = Path(f"profile_{timestamp}.seq")
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=10e-6,
)
excitation_settings = dict(
slice_thickness=6e-3,
flip_angle_degree=5,
rf_duration=1e-3,
rf_tbp=6,
)
profile_settings = dict(
Nz=1000,
dwell_time=5e-6,
repeats=100,
TR=1e-1,
)
################
def slice_selective_exication(system, flip_angle_degree, rf_tbp, rf_duration, slice_thickness, **kwargs):
return pp.make_sinc_pulse(
flip_angle=math.radians(flip_angle_degree),
duration=rf_duration,
slice_thickness=slice_thickness,
apodization=0.5,
time_bw_product=rf_tbp,
system=system,
return_gz=True,
)
seq = pp.Sequence()
rf_phase = rf_inc = 0.0
for i in range(profile_settings["repeats"]):
# The slice selective pulse
rf, gz, _ = slice_selective_exication(system, **excitation_settings)
# We scale down the read out gradient to have a longer dwell time
scale = profile_settings["Nz"] * profile_settings["dwell_time"] / gz.flat_time
gz_minus = pp.make_trapezoid(
channel="z",
flat_time=gz.flat_time * scale,
flat_area=gz.flat_area,
rise_time=gz.rise_time * scale,
fall_time=gz.fall_time * scale,
)
adc = pp.make_adc(
num_samples=profile_settings["Nz"],
duration=gz_minus.flat_time,
delay=gz_minus.rise_time,
system=system,
)
## RF Spoiling
rf.phase_offset = math.radians(rf_phase)
adc.phase_offset = math.radians(rf_phase)
rf_inc = (rf_inc + 117) % 360
rf_phase = (rf_phase + rf_inc) % 360
seq.add_block(rf, gz)
label = pp.make_label(label="REP", type="SET", value=i)
seq.add_block(adc, gz_minus, label)
# Gradient spoiling
spoiler_z = pp.make_trapezoid(channel="z", system=system, area=gz.area, duration=2 * gz.flat_time)
spoiler_xy = pp.make_trapezoid(channel="xy"[i % 2], system=system, area=gz.area, duration=2 * gz.flat_time)
seq.add_block(spoiler_xy, spoiler_z)
if delay := profile_settings["TR"] - max(pp.calc_duration(spoiler_z), pp.calc_duration(spoiler_xy)) > 0:
seq.add_block(pp.make_delay(delay))
print("Test report....")
print(seq.test_report())
for key, value in (profile_settings | excitation_settings).items():
seq.set_definition(key, value)
seq.write(filename)
print(f"written to {str(filename})")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment