Correction of Slab/Slice Profile
Here, we show how to correct the errors generated by the slice/slab profile of the excitation pulse.
Corrupted MP2RAGE image
using QuantitativeMRI
using JLD2, CairoMakie
d = load(joinpath(pwd(),"../..","data","corrupted.jld2"))
MP2RAGE = d["MP2RAGE"]
T1map = d["T1map"]
p_MP2 = d["params_MP2RAGE"]
angle_profile = d["angle_profile"]
TI1 = d["im_reco"][:,:,1]
TI2 = d["im_reco"][:,:,2]
f=Figure(size=(300,300))
ax = Axis(f[1,1], title="Corrupted MP2RAGE image",xlabel="phase encoding direction", ylabel="partition encoding direction",aspect = 1)
heatmap!(ax,MP2RAGE,colormap=:grays)
hidedecorations!(ax,label=false)
f

You can see that the image is corrupted by the slab profile of the excitation pulse along the Y axis, which corresponds to the partition encoding direction.
This is due to an inappropriate choice of excitation pulse—here, a Hermite shape. We can take a look at the corresponding excitation profile:
f=Figure(size=(300,200))
ax = Axis(f[1,1], title="Corrupted MP2RAGE image",xlabel="partition encoding direction", ylabel="effective flip angle [degrees]")
lines!(ax,angle_profile)
f

Fixing the T1 Map
Fortunately, if we know the effective flip angle profile, we can correct the resulting T1 map.
p = deepcopy(p_MP2)
T1corr = similar(MP2RAGE)
T1,range_T1,LUT = mp2rage_T1maps(MP2RAGE,p_MP2)
LUT_vec = []
range_T1_vec = []
for i=1:size(MP2RAGE,2)
p.α₁ = d["angle_profile"][i]
p.α₂ = d["angle_profile"][i] ./ p_MP2.α₁ .* p_MP2.α₂
T1corr[:,i], range_T1, LUT= mp2rage_T1maps(MP2RAGE[:,i],p)
push!(LUT_vec,LUT)
push!(range_T1_vec,range_T1)
end
f=Figure(size=(400,300))
ax = Axis(f[1,1], title="Initial T1 map",aspect = 1)
heatmap!(ax,T1,colorrange = (800,2000))
hidedecorations!(ax)
ax = Axis(f[1,2], title="Corrected T1 map",aspect = 1)
h=heatmap!(ax,T1corr,colorrange = (800,2000))
hidedecorations!(ax)
Colorbar(f[1,3], h, label="T1 [ms]",tellheight=true)
rowsize!(f.layout, 1, ax.scene.px_area[].widths[2])
f

The idea is to compute a different lookup table (LUT) for each partition position, using the effective flip angle profile. This allows us to correct the T1 map for the slab profile effect.
Let's take a look at two different LUTs:
f=Figure(size=(400,300))
ax = Axis(f[1,1], title="LUT for partition position 1 and 96")
xlims!(ax,0,range_T1_vec[96][end])
ylims!(ax,-0.5,0.5)
lines!(ax,range_T1_vec[1],LUT_vec[1],label="angle = $(angle_profile[1])",color=:blue)
lines!(ax,range_T1_vec[96],LUT_vec[96],label="angle = $(angle_profile[96])",color=:green)
val_MP2 = 0.1
idxFirst1 = searchsortedfirst(LUT_vec[1], val_MP2,lt= >=)
idxFirst2 = searchsortedfirst(LUT_vec[96], val_MP2,lt= >=)
hlines!(ax,val_MP2,xmax=range_T1_vec[96][idxFirst2]/range_T1_vec[96][end],color=:red,linestyle=:dot)
vlines!(ax,range_T1_vec[1][idxFirst1],color=:blue,linestyle=:dash)
vlines!(ax,range_T1_vec[96][idxFirst2],color=:green,linestyle=:dash)
f

You can see that the different effective flip angle profiles lead to different LUTs, which allows us to correct the T1 map for the slab profile effect.
Correcting the MP2RAGE Image
We can also correct the MP2RAGE image using the corrected T1 map.
res = QuantitativeMRI.T1maps_mp2rage(T1corr,p_MP2)
begin
sl=[:,:]
f = Figure()
ax=Axis(f[1,1],title="Initial MP2RAGE",aspect = 1)
h=heatmap!(ax,MP2RAGE,colormap=:grays)
ax=Axis(f[1,2],title="corrected MP2RAGE",aspect = 1)
h=heatmap!(ax,res[1], colormap=:grays)
for ax in f.content # hide decoration befor adding colorbar
hidedecorations!(ax)
end
f
end

As you can see, the corrected MP2RAGE image is now free of the slab profile effect.
Unfortunately, we cannot generate the corrected TI₁ and TI₂ images from the corrected T1 map. Even if we are able to generate the signal equation knowing the T1 map, we would also need to know the T2*, B1-, and proton density for each voxel.