Skip to content
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

New Motion #442

Merged
merged 100 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
2b491ff
Initial commit
pvillacorta Jul 11, 2024
b948d49
Delete `Static`
pvillacorta Jul 11, 2024
8f2ead2
Merge branch 'master' into new-motion
pvillacorta Jul 11, 2024
7ad003e
Apply suggested change by @rkierulf
pvillacorta Aug 1, 2024
447cbf7
Merge branch 'master' into new-motion
pvillacorta Aug 1, 2024
2804413
Solve bug
pvillacorta Aug 1, 2024
596af23
Enable all testsitems
pvillacorta Aug 1, 2024
fe9c8c2
Suggested changes
pvillacorta Aug 8, 2024
79596ad
Solve bug
pvillacorta Aug 9, 2024
ea91613
Solve bug
pvillacorta Aug 9, 2024
e10660f
Export `AbstractMotionList`
pvillacorta Aug 12, 2024
211337f
Remove periodic motions from docs
pvillacorta Aug 12, 2024
c78838e
Update `contracting_ring.phantom` example
pvillacorta Aug 12, 2024
c603fd0
Recover `tmp` variable for now
pvillacorta Aug 13, 2024
a21e3d7
Solve docs bug
pvillacorta Aug 13, 2024
76895c2
Update docs to pass CI
pvillacorta Aug 13, 2024
056c615
Docstrings to pass CI
pvillacorta Aug 14, 2024
4901df7
Test `get_spin_coords` in core
pvillacorta Aug 19, 2024
130a7f1
Continue testing
pvillacorta Aug 19, 2024
b4ac68e
Correct bug
pvillacorta Aug 19, 2024
5b59214
Add SimpleMotion test
pvillacorta Aug 19, 2024
0aa8540
Solve bug
pvillacorta Aug 19, 2024
36f96be
Try again...
pvillacorta Aug 19, 2024
02c539d
Again...
pvillacorta Aug 19, 2024
25360e2
Check if only fails with oneAPI
pvillacorta Aug 19, 2024
0d8a541
Try now
pvillacorta Aug 19, 2024
59d6ecc
Aux comments
pvillacorta Aug 19, 2024
0d2c134
Try with simple motion
pvillacorta Aug 19, 2024
2cbfa29
comments
pvillacorta Aug 19, 2024
77b9530
Recover to initial state
pvillacorta Aug 19, 2024
b5609c6
Merge branch 'master' into new-motion
pvillacorta Aug 19, 2024
0416bb0
Comments
pvillacorta Aug 19, 2024
b268578
More comments
pvillacorta Aug 19, 2024
c32b9bb
Try again
pvillacorta Aug 19, 2024
b90b791
Merge branch 'master' into new-motion
pvillacorta Aug 20, 2024
648a3d9
Merge branch 'master' into new-motion
cncastillo Aug 20, 2024
2995074
Big change
pvillacorta Aug 23, 2024
ee24363
Merge branch 'new-motion' of https://github.com/JuliaHealth/KomaMRI.j…
pvillacorta Aug 23, 2024
725e68a
Try again to test cpu multi-thread error
pvillacorta Aug 24, 2024
057ba72
Docstrings to pass CI
pvillacorta Aug 24, 2024
a1330a4
Solve multi-thread bug
pvillacorta Aug 24, 2024
8e44e49
Solve bug, now it is
pvillacorta Aug 24, 2024
53c1f6b
Merge branch 'master' into new-motion
pvillacorta Aug 24, 2024
0121d2d
Solve docs CI?
pvillacorta Aug 24, 2024
c63aa40
Compare MotionLists' lengths
pvillacorta Aug 26, 2024
d550bcd
Solve bugs
pvillacorta Aug 26, 2024
8db53d4
Auxiliary `length` method for SpinRanges
pvillacorta Aug 26, 2024
d7a3ed4
Solve bugs for flow
pvillacorta Aug 27, 2024
fd125e7
Merge branch 'master' into new-motion
pvillacorta Aug 27, 2024
afa7c83
Update docstrings
pvillacorta Aug 28, 2024
5d5a9a1
Fix some docstrings
pvillacorta Aug 29, 2024
36bc578
Remove unnecessary docstring
pvillacorta Aug 29, 2024
71960f7
Try to include docstring of `Translate` function
pvillacorta Aug 29, 2024
e81f617
It worked, so add the rest of the functions
pvillacorta Aug 29, 2024
15c33b2
Not export `reset_magnetization!`
pvillacorta Aug 29, 2024
c943212
Fix typo in docstring
pvillacorta Aug 29, 2024
0baf29c
Try to separate tests for core and motion (see Oceananigans.jl)
pvillacorta Aug 29, 2024
e29418c
Try to fix error on runtests.yml
pvillacorta Aug 29, 2024
911544f
Try to fix buildkite tests
pvillacorta Aug 29, 2024
e792aff
Change test group title for buildkite
pvillacorta Aug 29, 2024
007ee25
Try to interpolate env variable with $$
pvillacorta Aug 29, 2024
316fabf
Try with only one $
pvillacorta Aug 29, 2024
7049c60
Define env for each buildkite step
pvillacorta Aug 29, 2024
d88ecba
Motion and NoMotion tests separated for buildkite
pvillacorta Aug 29, 2024
9913be1
Only test `get_spin_coords` for ArbitraryAction in gpu
pvillacorta Aug 30, 2024
a156553
Fix test to use Float32
pvillacorta Aug 30, 2024
2655f0d
Disable benchmarks temporarily
pvillacorta Aug 30, 2024
44debdd
Only test ArbitraryMotion for oneAPI
pvillacorta Aug 30, 2024
67f2f33
New example phantoms
pvillacorta Aug 30, 2024
2a9aac7
Test ArbitraryMotion with all vendors again
pvillacorta Aug 30, 2024
d7ea6b7
Trying to find out where the error produces for oneAPI
pvillacorta Aug 30, 2024
42c21d2
Keep trying
pvillacorta Aug 30, 2024
0210669
Merge branch `new-motion-debug` into `new-motion`
pvillacorta Sep 3, 2024
fb7a740
Leave core tests as they were before debugging
pvillacorta Sep 3, 2024
51c71cc
`_ = sum(t)`
pvillacorta Sep 3, 2024
7d1ddc0
New function `_unit_time`
pvillacorta Sep 3, 2024
86a5760
Merge branch 'master' into new-motion
pvillacorta Sep 3, 2024
f0707aa
Squashed commit of the following:
pvillacorta Sep 12, 2024
586adcf
Uncomment informative messages
pvillacorta Sep 12, 2024
2177410
Change compat from julia 1.9 to 1.10
pvillacorta Sep 13, 2024
32cd42d
Requested changes
pvillacorta Sep 13, 2024
e5c9dd8
consts in upper case
pvillacorta Sep 15, 2024
0b1f31a
Fix and rename aux motion functions
pvillacorta Sep 15, 2024
717ee28
Add functor to Motion. MotionList cannot have a functor
pvillacorta Sep 15, 2024
d7666f6
Fix tests
pvillacorta Sep 15, 2024
ad10265
`cis` -> `_cis`
pvillacorta Sep 15, 2024
27ecbe5
Formatting and renaming
pvillacorta Sep 15, 2024
5e71f16
Back to `(cos.(ϕ) .+ im .* sin.(ϕ))`
pvillacorta Sep 15, 2024
b79a28b
Add `KomaMRIBase` into `sort_motions!` call
pvillacorta Sep 15, 2024
b4a878b
Add issue to Interpolations.jl
pvillacorta Sep 16, 2024
30cc9cc
`outflow_spin_reset!` inside all methods
pvillacorta Sep 17, 2024
12f6fed
Workgroup size back to 512
pvillacorta Sep 17, 2024
108886d
Remove `*`, since it produces errors in CPU
pvillacorta Sep 17, 2024
0430560
Suggested changes for flow functions
pvillacorta Sep 18, 2024
19d54e0
Suggested changes about `plot_phantom_map`
pvillacorta Sep 18, 2024
e7c4db2
Remove unnecessary `T` declaration
pvillacorta Sep 18, 2024
5780c31
Squashed commit of the following:
pvillacorta Sep 19, 2024
567e406
Add tests to new `plot_phantom_map` method
pvillacorta Sep 19, 2024
f2ad03b
Solve bug with `TimeRange` in the KomaMRIPlots tests
pvillacorta Sep 19, 2024
e416800
Suggested changes
pvillacorta Sep 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
steps:
- label: ":pipeline: Launch Tests"
- label: ":pipeline: Upload NoMotion Tests"
env:
TEST_GROUP: "nomotion"
command: buildkite-agent pipeline upload .buildkite/runtests.yml
agents:
queue: "juliagpu"

- label: ":pipeline: Upload Motion Tests"
env:
TEST_GROUP: "motion"
command: buildkite-agent pipeline upload .buildkite/runtests.yml
agents:
queue: "juliagpu"
Expand Down
21 changes: 16 additions & 5 deletions .buildkite/runtests.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
steps:
- group: ":julia: Tests"
- group: ":julia: ($TEST_GROUP) Tests"
steps:
- label: "CPU: Run tests on v{{matrix.version}}"
matrix:
setup:
version:
- "1.9"
- "1.10"
- "1"
plugins:
- JuliaCI/julia#v1:
Expand All @@ -15,6 +15,8 @@ steps:
dirs:
- KomaMRICore/src
- KomaMRICore/ext
env:
TEST_GROUP: $TEST_GROUP
command: |
julia -e 'println("--- :julia: Instantiating project")
using Pkg
Expand All @@ -34,6 +36,7 @@ steps:
matrix:
setup:
version:
- "1.10"
- "1"
plugins:
- JuliaCI/julia#v1:
Expand All @@ -43,6 +46,8 @@ steps:
dirs:
- KomaMRICore/src
- KomaMRICore/ext
env:
TEST_GROUP: $TEST_GROUP
command: |
julia -e 'println("--- :julia: Instantiating project")
using Pkg
Expand All @@ -67,7 +72,7 @@ steps:
matrix:
setup:
version:
- "1.9"
- "1.10"
- "1"
plugins:
- JuliaCI/julia#v1:
Expand All @@ -77,6 +82,8 @@ steps:
dirs:
- KomaMRICore/src
- KomaMRICore/ext
env:
TEST_GROUP: $TEST_GROUP
command: |
julia -e 'println("--- :julia: Instantiating project")
using Pkg
Expand All @@ -101,11 +108,13 @@ steps:
matrix:
setup:
version:
- "1.9"
- "1.10"
- "1"
plugins:
- JuliaCI/julia#v1:
version: "{{matrix.version}}"
env:
TEST_GROUP: $TEST_GROUP
command: |
julia -e 'println("--- :julia: Instantiating project")
using Pkg
Expand All @@ -131,7 +140,7 @@ steps:
matrix:
setup:
version:
- "1.9"
- "1.10"
- "1"
plugins:
- JuliaCI/julia#v1:
Expand All @@ -141,6 +150,8 @@ steps:
dirs:
- KomaMRICore/src
- KomaMRICore/ext
env:
TEST_GROUP: $TEST_GROUP
command: |
julia -e 'println("--- :julia: Instantiating project")
using Pkg
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.9' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
- '1.10' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
- '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia.
os: [ubuntu-latest, windows-latest, macos-12] # macos-latest] <- M1 Mac was generating problems #386, commented for now
arch: [x64]
Expand Down
14 changes: 8 additions & 6 deletions KomaMRIBase/src/KomaMRIBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ include("datatypes/sequence/ADC.jl")
include("timing/KeyValuesCalculation.jl")
include("datatypes/Sequence.jl")
include("datatypes/sequence/Delay.jl")
# Motion
include("motion/AbstractMotion.jl")
# Phantom
include("datatypes/Phantom.jl")
# Simulator
include("datatypes/simulation/DiscreteSequence.jl")
include("timing/TimeStepCalculation.jl")
include("timing/TrapezoidalIntegration.jl")
include("timing/UnitTime.jl")

# Main
export γ # gyro-magnetic ratio [Hz/T]
Expand All @@ -47,11 +48,12 @@ export kfoldperm, trapz, cumtrapz
# Phantom
export brain_phantom2D, brain_phantom3D, pelvis_phantom2D, heart_phantom
# Motion
export MotionModel
export NoMotion, SimpleMotion, ArbitraryMotion
export SimpleMotionType
export Translation, Rotation, HeartBeat
export PeriodicTranslation, PeriodicRotation, PeriodicHeartBeat
export MotionList, NoMotion, Motion
export Translate, TranslateX, TranslateY, TranslateZ
export Rotate, RotateX, RotateY, RotateZ
export HeartBeat, Path, FlowPath
export TimeRange, Periodic
export SpinRange, AllSpins
export get_spin_coords
# Secondary
export get_kspace, rotx, roty, rotz
Expand Down
92 changes: 47 additions & 45 deletions KomaMRIBase/src/datatypes/Phantom.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
abstract type MotionModel{T<:Real} end

#Motion models:
include("phantom/motion/SimpleMotion.jl")
include("phantom/motion/ArbitraryMotion.jl")
include("phantom/motion/NoMotion.jl")

"""
obj = Phantom(name, x, y, z, ρ, T1, T2, T2s, Δw, Dλ1, Dλ2, Dθ, motion)

Expand All @@ -24,7 +17,7 @@
- `Dλ1`: (`::AbstractVector{T<:Real}`) spin Dλ1 (diffusion) parameter vector
- `Dλ2`: (`::AbstractVector{T<:Real}`) spin Dλ2 (diffusion) parameter vector
- `Dθ`: (`::AbstractVector{T<:Real}`) spin Dθ (diffusion) parameter vector
- `motion`: (`::MotionModel{T<:Real}`) motion model
- `motion`: (`::AbstractMotion{T<:Real}`) motion

# Returns
- `obj`: (`::Phantom`) Phantom struct
Expand Down Expand Up @@ -54,9 +47,12 @@
Dθ::AbstractVector{T} = zeros(eltype(x), size(x))
#Diff::Vector{DiffusionModel} #Diffusion map
#Motion
motion::MotionModel{T} = NoMotion{eltype(x)}()
motion::AbstractMotion{T} = NoMotion{eltype(x)}()
end

const NON_STRING_PHANTOM_FIELDS = Iterators.filter(x -> fieldtype(Phantom, x) != String, fieldnames(Phantom))
const VECTOR_PHANTOM_FIELDS = Iterators.filter(x -> fieldtype(Phantom, x) <: AbstractVector, fieldnames(Phantom))

"""Size and length of a phantom"""
size(x::Phantom) = size(x.ρ)
Base.length(x::Phantom) = length(x.ρ)
Expand All @@ -65,43 +61,45 @@
Base.iterate(x::Phantom, i::Integer) = (i <= length(x)) ? (x[i], i + 1) : nothing
Base.lastindex(x::Phantom) = length(x)
Base.getindex(x::Phantom, i::Integer) = x[i:i]
Base.view(x::Phantom, i::Integer) = @view(x[i:i])

Check warning on line 64 in KomaMRIBase/src/datatypes/Phantom.jl

View check run for this annotation

Codecov / codecov/patch

KomaMRIBase/src/datatypes/Phantom.jl#L64

Added line #L64 was not covered by tests

"""Compare two phantoms"""
Base.:(==)(obj1::Phantom, obj2::Phantom) = reduce(
&,
[getfield(obj1, field) == getfield(obj2, field) for field in Iterators.filter(x -> !(x == :name), fieldnames(Phantom))],
)
Base.:(≈)(obj1::Phantom, obj2::Phantom) = reduce(&, [getfield(obj1, field) ≈ getfield(obj2, field) for field in Iterators.filter(x -> !(x == :name), fieldnames(Phantom))])
Base.:(==)(m1::MotionModel, m2::MotionModel) = false
Base.:(≈)(m1::MotionModel, m2::MotionModel) = false
function Base.:(==)(obj1::Phantom, obj2::Phantom)
if length(obj1) != length(obj2) return false end
return reduce(&, [getfield(obj1, field) == getfield(obj2, field) for field in NON_STRING_PHANTOM_FIELDS])
end
function Base.:(≈)(obj1::Phantom, obj2::Phantom)
if length(obj1) != length(obj2) return false end
return reduce(&, [getfield(obj1, field) ≈ getfield(obj2, field) for field in NON_STRING_PHANTOM_FIELDS])

Check warning on line 73 in KomaMRIBase/src/datatypes/Phantom.jl

View check run for this annotation

Codecov / codecov/patch

KomaMRIBase/src/datatypes/Phantom.jl#L71-L73

Added lines #L71 - L73 were not covered by tests
end

"""Separate object spins in a sub-group"""
Base.getindex(obj::Phantom, p::Union{AbstractRange,AbstractVector,Colon}) = begin
function Base.getindex(obj::Phantom, p)
fields = []
for field in Iterators.filter(x -> !(x == :name), fieldnames(Phantom))
for field in NON_STRING_PHANTOM_FIELDS
push!(fields, (field, getfield(obj, field)[p]))
end
return Phantom(; name=obj.name, fields...)
end

"""Separate object spins in a sub-group (lightweigth)."""
Base.view(obj::Phantom, p::Union{AbstractRange,AbstractVector,Colon}) = begin
function Base.view(obj::Phantom, p)
fields = []
for field in Iterators.filter(x -> !(x == :name), fieldnames(Phantom))
for field in NON_STRING_PHANTOM_FIELDS
push!(fields, (field, @view(getfield(obj, field)[p])))
end
return Phantom(; name=obj.name, fields...)
end

"""Addition of phantoms"""
+(obj1::Phantom, obj2::Phantom) = begin
name = first(obj1.name * "+" * obj2.name, 50) # The name is limited to 50 characters
fields = []
for field in Iterators.filter(x -> !(x == :name), fieldnames(Phantom))
for field in VECTOR_PHANTOM_FIELDS
push!(fields, (field, [getfield(obj1, field); getfield(obj2, field)]))
end
Nmaxchars = 50
name = first(obj1.name * "+" * obj2.name, Nmaxchars)
return Phantom(; name=name, fields...)
return Phantom(;
name = name,
fields...,
motion = vcat(obj1.motion, obj2.motion, length(obj1), length(obj2)))
end

"""Scalar multiplication of a phantom"""
Expand All @@ -121,25 +119,30 @@
end

"""
obj = heart_phantom(...)
obj = heart_phantom(
circumferential_strain, radial_strain, rotation_angle;
heart_rate, asymmetry
)

Heart-like LV 2D phantom. The variable `circumferential_strain` and `radial_strain` are for streching (if positive)
or contraction (if negative). `rotation_angle` is for rotation.

# Arguments
- `circumferential_strain`: (`::Real`, `=-0.3`) contraction parameter
- `radial_strain`: (`::Real`, `=-0.3`) contraction parameter
- `rotation_angle`: (`::Real`, `=1`) rotation parameter
# Keywords
- `circumferential_strain`: (`::Real`, `=-0.3`) contraction parameter. Between -1 and 1
- `radial_strain`: (`::Real`, `=-0.3`) contraction parameter. Between -1 and 1
- `rotation_angle`: (`::Real`, `=15.0`, `[º]`) maximum rotation angle
- `heart_rate`: (`::Real`, `=60`, `[bpm]`) heartbeat frequency
- `temporal_asymmetry`: (`::Real`, `=0.2`) time fraction of the period in which the systole occurs. Therefore, diastole lasts for `period * (1 - temporal_asymmetry)`

# Returns
- `phantom`: (`::Phantom`) Heart-like LV phantom struct
- `obj`: (`::Phantom`) Heart-like LV phantom struct
"""
function heart_phantom(
function heart_phantom(;
circumferential_strain=-0.3,
radial_strain=-0.3,
rotation_angle=15.0;
rotation_angle=15.0,
heart_rate=60,
asymmetry=0.2,
temporal_asymmetry=0.2,
)
#PARAMETERS
FOV = 10e-2 # [m] Diameter ventricule
Expand Down Expand Up @@ -177,16 +180,15 @@
Dλ1=Dλ1[ρ .!= 0],
Dλ2=Dλ2[ρ .!= 0],
Dθ=Dθ[ρ .!= 0],
motion=SimpleMotion(
PeriodicHeartBeat(;
period=period,
asymmetry=asymmetry,
circumferential_strain=circumferential_strain,
radial_strain=radial_strain,
longitudinal_strain=0.0,
motion=MotionList(
HeartBeat(
circumferential_strain,
radial_strain,
0.0,
Periodic(; period=period, asymmetry=temporal_asymmetry),
),
PeriodicRotation(;
period=period, asymmetry=asymmetry, yaw=rotation_angle, pitch=0.0, roll=0.0
Rotate(
0.0, 0.0, rotation_angle, Periodic(; period=period, asymmetry=temporal_asymmetry)
),
),
)
Expand Down Expand Up @@ -318,7 +320,7 @@
end

"""
obj = brain_phantom3D(; ss=4, us=1)
obj = brain_phantom3D(; ss=4, us=1, start_end=[160,200])

Creates a three-dimentional brain Phantom struct.
Default ss=4 sample spacing is 2 mm. Original file (ss=1) sample spacing is .5 mm.
Expand Down
Loading
Loading