-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft for discussion : Subspace implementation #148
Conversation
Hi, |
Would it help discoverability to house it under MRIReco? |
Probably :). I guess the best way might be to change ownership to MagneticResonanceImaging? I think I was just hesitant to do so because the package is still WIP. In terms of MRIReco.jl itself, I have no objections against wrappers, but I would be hesitant to move the into MRIReco as I personally prefer a more low-level interface. |
oops, i meant |
Codecov ReportPatch coverage:
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. Additional details and impacted files@@ Coverage Diff @@
## master #148 +/- ##
===========================================
+ Coverage 65.56% 84.16% +18.59%
===========================================
Files 9 10 +1
Lines 273 322 +49
===========================================
+ Hits 179 271 +92
+ Misses 94 51 -43
☔ View full report in Codecov by Sentry. |
Ha, fair point! OK, I will move it. |
I have some kind of implementation + test ready. @JakobAsslaender I suppose your implementation is faster than mine. Do you think we should keep the high level implementation ? |
shape mismatch with wavelet regularization :) |
I have some weird instability for the reconstruction with multiCoilMultiEcho acquisition. I tried :
any idea ? Somebody else can also try to reproduce the error with that branch (if needed I can share the dataset). @alexjaffray maybe you can also try with one of your MESE datasets :/ High and Low level reco : using CairoMakie
using ImageUtils: shepp_logan
using LinearAlgebra
using MRIReco, MRISimulation, MRICoilSensitivities, MRISampling
T = ComplexF32
N=128
TEnum = collect(7:7:30*7)
x = T.(shepp_logan(N))
rmap = 5.0*abs.(x)
coilsens = T.(birdcageSensitivity(N, 4, 1.5))
TEnum = collect(2.e-2:2.e-2:50.e-2)
# simulation
params = Dict{Symbol, Any}()
params[:simulation] = "fast"
params[:trajName] = "Cartesian"
params[:numProfiles] = floor(Int64, N)
params[:numSamplingPerProfile] = N
params[:r2map] = rmap
params[:T_echo] = TEnum
params[:seqName] = "ME"
params[:refocusingAngles] = Float64.(repeat([pi],length(TEnum)))
params[:senseMaps] = coilsens
acq1 = simulation( real(x), params)
sens = espirit(acq1,eigThresh_2=0.0)
#= REAL DATA
b=BrukerFile("/Users/aurelien/Downloads/MESE_QUEU/")
raw = RawAcquisitionData(b)
acq=AcquisitionData(raw)
# extract 1 slice and take only 10 first echoes
acq1 = deepcopy(acq)
acq1.kdata = acq.kdata[1:30,5:5,:]
acq1.subsampleIndices = acq.subsampleIndices[1:30]
acq1.traj=acq.traj[1:30]
sens = espirit(acq1,eigThresh_2=0.0)
=#
begin
params = Dict{Symbol, Any}()
params[:reconSize] = acq1.encodingSize
params[:reco] = "multiCoilMultiEcho"
#params[:sparseTrafo] = "nothing" #"nothing" #sparse trafo
params[:regularization] = "L2"
params[:λ] = 1.e-3
params[:iterations] = 1
params[:solver] = "cgnr"
params[:senseMaps] = sens
x_approx= reconstruction(acq1,params);
p1 = (64,64)
f=Figure()
ax=Axis(f[1,1])
heatmap!(ax,abs.(x_approx[:,:,1,10,1,1]))
scatter!(ax,p1,color=:red)
ax=Axis(f[1,2])
lines!(ax,abs.(x_approx[p1...,1,:,1,1]))
f
end
## try again with low level
begin
numContr = MRIReco.numContrasts(acq1)
numChan = MRIReco.numChannels(acq1)
shape_ = acq1.encodingSize
#tr = [trajectory(acq_copy,i) for i=1:numContr]
tr = acq1.traj
idx = acq1.subsampleIndices
ftOp = [fourierEncodingOp(acq1.encodingSize, tr[i], "fast",subsampleIdx=idx[i]) for i=1:numContr]
S = SensitivityOp(reshape(sens,:,numChan),length(ftOp))
E = DiagOp(repeat(ftOp, inner=numChan)...) ∘ S
kdata = multiCoilMultiEchoData(acq1, 1);
im_res = E' * vec(kdata);
im_res = abs.(reshape(im_res,shape_...,:));
p1 = (64,64)
f=Figure()
ax=Axis(f[1,1])
heatmap!(ax,im_res[:,:,10])
scatter!(ax,p1,color=:red)
ax=Axis(f[1,2])
lines!(ax,im_res[p1...,:])
#ylims!(ax, 0,60)
f
end weirdly for real dataset if I run all this code the instability is gone. But if I run multiple times only from the lines |
@JakobAsslaender I am not able to get a working "multiCoil" reconstruction with the diagonal operator build like that : E = DiagOp(repeat(ftOp, inner=numChan)...) ∘ S # do not work but it works (and is stable) with this line (which correspond to the high level implementation of "multiCoil"- E = DiagOp(ftOp[1], numChan) ∘ S It is an issue with "repeat" it works if I replace it by ops2 = [copy(ftOp[1]) for n=1:numChan]
E= DiagOp(ops2...) I have to check how to change that in the high level interface |
Thanks @aTrotier for pushing this forward. As far as the question about repeat() vs. copy(), my intuition is that operators which maintain any computed or mutating internal variables must be copied. I will pull this and try it out with some of my data |
Thank @alexjaffray, I don't see any reason to broke my branch :) |
Seems good on my side. We will have to benchmark the speed / memory / precision against BART |
Can I merge It ? |
Hi,
I am working on a subspace reconstruction for T2 mapping Multi-Echo Spin-Echo sequence. I am currently doing the reconstruction part with BART.
This is a draft to implement the reconstruction in Julia. It seems to work (at least on fully datasets) :
params[:reco] = "multiCoilMultiEchoSubspace"
. Maybe we can directly put it in the multi-echoes operators ?Let me know what you think I should change ?
I think @JakobAsslaender and @alexjaffray are also interested in / using a similar implementation
example :