Skip to content

Commit

Permalink
Merge branch 'master' into compathelper/new_version/2024-10-15-00-47-…
Browse files Browse the repository at this point in the history
…05-396-00907762767
  • Loading branch information
cncastillo authored Jan 6, 2025
2 parents d5fa392 + 1523467 commit 437b9b6
Show file tree
Hide file tree
Showing 70 changed files with 2,976 additions and 1,299 deletions.
14 changes: 8 additions & 6 deletions .buildkite/runbenchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ steps:
artifact_paths:
- "benchmarks/results/*"
agents:
queue: "benchmark"
arch: "aarch64"
queue: "juliaecosystem"
num_cpus: "8"
env:
BENCHMARK_GROUP: CPU
JULIA_NUM_THREADS: "{{matrix.threads}}"
timeout_in_minutes: 120
timeout_in_minutes: 30

- label: "AMDGPU: Run Benchmarks"
plugins:
Expand Down Expand Up @@ -57,7 +59,7 @@ steps:
rocmgpu: "gfx1101"
env:
BENCHMARK_GROUP: AMDGPU
timeout_in_minutes: 120
timeout_in_minutes: 30

- label: "CUDA: Run Benchmarks"
plugins:
Expand Down Expand Up @@ -85,7 +87,7 @@ steps:
cuda: "*"
env:
BENCHMARK_GROUP: CUDA
timeout_in_minutes: 120
timeout_in_minutes: 30

- label: "Metal: Run Benchmarks"
plugins:
Expand Down Expand Up @@ -113,7 +115,7 @@ steps:
arch: "aarch64"
env:
BENCHMARK_GROUP: Metal
timeout_in_minutes: 120
timeout_in_minutes: 30

- label: "oneAPI: Run Benchmarks"
plugins:
Expand All @@ -140,7 +142,7 @@ steps:
intel: "*"
env:
BENCHMARK_GROUP: oneAPI
timeout_in_minutes: 120
timeout_in_minutes: 30

- wait: ~

Expand Down
18 changes: 8 additions & 10 deletions .buildkite/runtests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ steps:
plugins:
- JuliaCI/julia#v1:
version: "{{matrix.version}}"
- JuliaCI/julia-coverage#v1:
codecov: true
dirs:
- KomaMRICore/src
- KomaMRICore/ext
env:
TEST_GROUP: $TEST_GROUP
command: |
julia -e 'println("--- :julia: Instantiating project")
using Pkg
Expand All @@ -27,10 +20,15 @@ steps:
julia -e 'println("--- :julia: Running tests")
using Pkg
Pkg.test("KomaMRICore"; coverage=true, julia_args=`--threads=auto`)'
Pkg.test("KomaMRICore")'
agents:
queue: "juliagpu"
timeout_in_minutes: 60
arch: "aarch64"
queue: "juliaecosystem"
num_cpus: "4"
env:
TEST_GROUP: $TEST_GROUP
JULIA_NUM_THREADS: "4"
timeout_in_minutes: 30

- label: "AMDGPU: Run tests on v{{matrix.version}}"
matrix:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
version:
- '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
os: [ubuntu-latest, windows-latest, macos-latest]
arch: [x64]
include:
- os: ubuntu-latest
Expand Down
5 changes: 3 additions & 2 deletions KomaMRIBase/src/KomaMRIBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ include("timing/KeyValuesCalculation.jl")
include("datatypes/Sequence.jl")
include("datatypes/sequence/Delay.jl")
# Motion
include("motion/AbstractMotion.jl")
include("motion/MotionList.jl")
include("motion/NoMotion.jl")
# Phantom
include("datatypes/Phantom.jl")
# Simulator
Expand All @@ -52,7 +53,7 @@ export MotionList, NoMotion, Motion
export Translate, TranslateX, TranslateY, TranslateZ
export Rotate, RotateX, RotateY, RotateZ
export HeartBeat, Path, FlowPath
export TimeRange, Periodic
export TimeRange, Periodic, TimeCurve
export SpinRange, AllSpins
export get_spin_coords
# Secondary
Expand Down
8 changes: 4 additions & 4 deletions KomaMRIBase/src/datatypes/Phantom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ a property value representing a spin. This struct serves as an input for the sim
- `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`: (`::AbstractMotion{T<:Real}`) motion
- `motion`: (`::Union{NoMotion, Motion{T<:Real} MotionList{T<:Real}}`) motion
# Returns
- `obj`: (`::Phantom`) Phantom struct
Expand All @@ -31,7 +31,7 @@ julia> obj.ρ
"""
@with_kw mutable struct Phantom{T<:Real}
name::String = "spins"
x :: AbstractVector{T}
x::AbstractVector{T} = @isdefined(T) ? T[] : Float64[]
y::AbstractVector{T} = zeros(eltype(x), size(x))
z::AbstractVector{T} = zeros(eltype(x), size(x))
ρ::AbstractVector{T} = ones(eltype(x), size(x))
Expand All @@ -47,7 +47,7 @@ julia> obj.ρ
::AbstractVector{T} = zeros(eltype(x), size(x))
#Diff::Vector{DiffusionModel} #Diffusion map
#Motion
motion::AbstractMotion{T} = NoMotion{eltype(x)}()
motion::Union{NoMotion, Motion{T}, MotionList{T}} = NoMotion()
end

const NON_STRING_PHANTOM_FIELDS = Iterators.filter(x -> fieldtype(Phantom, x) != String, fieldnames(Phantom))
Expand Down Expand Up @@ -115,7 +115,7 @@ function get_dims(obj::Phantom)
push!(dims, any(x -> x != 0, obj.x))
push!(dims, any(x -> x != 0, obj.y))
push!(dims, any(x -> x != 0, obj.z))
return dims
return sum(dims) > 0 ? dims : Bool[1, 0, 0]
end

"""
Expand Down
4 changes: 2 additions & 2 deletions KomaMRIBase/src/datatypes/simulation/DiscreteSequence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ based on simulation parameters.
# Returns
- `seqd`: (`::DiscreteSequence`) DiscreteSequence struct
"""
function discretize(seq::Sequence; sampling_params=default_sampling_params())
t, Δt = get_variable_times(seq; Δt=sampling_params["Δt"], Δt_rf=sampling_params["Δt_rf"])
function discretize(seq::Sequence; sampling_params=default_sampling_params(), motion=NoMotion())
t, Δt = get_variable_times(seq; Δt=sampling_params["Δt"], Δt_rf=sampling_params["Δt_rf"], motion=motion)
B1, Δf = get_rfs(seq, t)
Gx, Gy, Gz = get_grads(seq, t)
tadc = get_adc_sampling_times(seq)
Expand Down
11 changes: 0 additions & 11 deletions KomaMRIBase/src/motion/AbstractMotion.jl

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,6 @@ const Interpolator2D = Interpolations.GriddedInterpolation{
Itp<:Interpolations.Gridded,
K<:Tuple{AbstractVector{TNodes}, AbstractVector{TNodes}},
}

abstract type ArbitraryAction{T<:Real} <: AbstractAction{T} end

function Base.getindex(action::ArbitraryAction, p)
return typeof(action)([getfield(action, d)[p,:] for d in fieldnames(typeof(action))]...)
end
function Base.view(action::ArbitraryAction, p)
return typeof(action)([@view(getfield(action, d)[p,:]) for d in fieldnames(typeof(action))]...)
end

Base.:(==)(m1::ArbitraryAction, m2::ArbitraryAction) = (typeof(m1) == typeof(m2)) & reduce(&, [getfield(m1, field) == getfield(m2, field) for field in fieldnames(typeof(m1))])
Base.:()(m1::ArbitraryAction, m2::ArbitraryAction) = (typeof(m1) == typeof(m2)) & reduce(&, [getfield(m1, field) getfield(m2, field) for field in fieldnames(typeof(m1))])

function GriddedInterpolation(nodes, A, ITP)
return Interpolations.GriddedInterpolation{eltype(A), length(nodes), typeof(A), typeof(ITP), typeof(nodes)}(nodes, A, ITP)
end
Expand Down Expand Up @@ -70,26 +57,10 @@ function resample(itp::Interpolator2D, t)
return itp.(id, t)
end

function displacement_x!(ux, action::ArbitraryAction, x, y, z, t)
itp = interpolate(action.dx, Gridded(Linear()), Val(size(action.dx,1)), t)
ux .= resample(itp, t)
return nothing
end

function displacement_y!(uy, action::ArbitraryAction, x, y, z, t)
itp = interpolate(action.dy, Gridded(Linear()), Val(size(action.dy,1)), t)
uy .= resample(itp, t)
return nothing
end

function displacement_z!(uz, action::ArbitraryAction, x, y, z, t)
itp = interpolate(action.dz, Gridded(Linear()), Val(size(action.dz,1)), t)
uz .= resample(itp, t)
return nothing
function interpolate_times(t, t_unit, periodic, tq)
itp = GriddedInterpolation((t, ), t_unit, Gridded(Linear()))
return extrapolate(itp, periodic ? Interpolations.Periodic() : Flat()).(tq)
end

_similar(a, N) = similar(a, N)
_similar(a::Real, N) = zeros(typeof(a), N)

include("arbitraryactions/Path.jl")
include("arbitraryactions/FlowPath.jl")
_similar(a::Real, N) = zeros(typeof(a), N)
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ that are affected by that motion.
# Arguments
- `action`: (`::AbstractAction{T<:Real}`) action, such as [`Translate`](@ref) or [`Rotate`](@ref)
- `time`: (`::AbstractTimeSpan{T<:Real}`, `=TimeRange(0.0)`) time information about the motion
- `time`: (`::TimeCurve{T<:Real}`, `=TimeRange(0.0)`) time information about the motion
- `spins`: (`::AbstractSpinSpan`, `=AllSpins()`) spin indexes affected by the motion
# Returns
Expand All @@ -28,8 +28,22 @@ julia> motion = Motion(
"""
@with_kw mutable struct Motion{T<:Real}
action::AbstractAction{T}
time ::AbstractTimeSpan{T} = TimeRange(zero(typeof(action).parameters[1]))
spins ::AbstractSpinSpan = AllSpins()
time ::TimeCurve{T} = TimeRange(t_start=zero(typeof(action).parameters[1]), t_end=eps(typeof(action).parameters[1]))
spins ::AbstractSpinSpan = AllSpins()
end

# Main constructors
function Motion(action)
T = first(typeof(action).parameters)
return Motion(action, TimeRange(t_start=zero(T), t_end=eps(T)), AllSpins())
end
function Motion(action, time::TimeCurve)
T = first(typeof(action).parameters)
return Motion(action, time, AllSpins())
end
function Motion(action, spins::AbstractSpinSpan)
T = first(typeof(action).parameters)
return Motion(action, TimeRange(t_start=zero(T), t_end=eps(T)), spins)
end

# Custom constructors
Expand All @@ -40,7 +54,7 @@ end
- `dx`: (`::Real`, `[m]`) translation in x
- `dy`: (`::Real`, `[m]`) translation in y
- `dz`: (`::Real`, `[m]`) translation in z
- `time`: (`::AbstractTimeSpan{T<:Real}`) time information about the motion
- `time`: (`::TimeCurve{T<:Real}`) time information about the motion
- `spins`: (`::AbstractSpinSpan`) spin indexes affected by the motion
# Returns
Expand All @@ -51,7 +65,7 @@ end
julia> translate = Translate(0.01, 0.02, 0.03, TimeRange(0.0, 1.0), SpinRange(1:10))
```
"""
function Translate(dx, dy, dz, time=TimeRange(zero(eltype(dx))), spins=AllSpins())
function Translate(dx, dy, dz, time=TimeRange(t_start=zero(eltype(dx)), t_end=eps(eltype(dx))), spins=AllSpins())
return Motion(Translate(dx, dy, dz), time, spins)
end

Expand All @@ -62,7 +76,7 @@ end
- `pitch`: (`::Real`, `[º]`) rotation in x
- `roll`: (`::Real`, `[º]`) rotation in y
- `yaw`: (`::Real`, `[º]`) rotation in z
- `time`: (`::AbstractTimeSpan{T<:Real}`) time information about the motion
- `time`: (`::TimeCurve{T<:Real}`) time information about the motion
- `spins`: (`::AbstractSpinSpan`) spin indexes affected by the motion
# Returns
Expand All @@ -73,7 +87,7 @@ end
julia> rotate = Rotate(15.0, 0.0, 20.0, TimeRange(0.0, 1.0), SpinRange(1:10))
```
"""
function Rotate(pitch, roll, yaw, time=TimeRange(zero(eltype(pitch))), spins=AllSpins())
function Rotate(pitch, roll, yaw, time=TimeRange(t_start=zero(eltype(pitch)), t_end=eps(eltype(pitch))), spins=AllSpins())
return Motion(Rotate(pitch, roll, yaw), time, spins)
end

Expand All @@ -84,7 +98,7 @@ end
- `circumferential_strain`: (`::Real`) contraction parameter
- `radial_strain`: (`::Real`) contraction parameter
- `longitudinal_strain`: (`::Real`) contraction parameter
- `time`: (`::AbstractTimeSpan{T<:Real}`) time information about the motion
- `time`: (`::TimeCurve{T<:Real}`) time information about the motion
- `spins`: (`::AbstractSpinSpan`) spin indexes affected by the motion
# Returns
Expand All @@ -95,7 +109,7 @@ end
julia> heartbeat = HeartBeat(-0.3, -0.2, 0.0, TimeRange(0.0, 1.0), SpinRange(1:10))
```
"""
function HeartBeat(circumferential_strain, radial_strain, longitudinal_strain, time=TimeRange(zero(eltype(circumferential_strain))), spins=AllSpins())
function HeartBeat(circumferential_strain, radial_strain, longitudinal_strain, time=TimeRange(t_start=zero(eltype(circumferential_strain)), t_end=eps(eltype(circumferential_strain))), spins=AllSpins())
return Motion(HeartBeat(circumferential_strain, radial_strain, longitudinal_strain), time, spins)
end

Expand All @@ -106,7 +120,7 @@ end
- `dx`: (`::AbstractArray{T<:Real}`, `[m]`) displacements in x
- `dy`: (`::AbstractArray{T<:Real}`, `[m]`) displacements in y
- `dz`: (`::AbstractArray{T<:Real}`, `[m]`) displacements in z
- `time`: (`::AbstractTimeSpan{T<:Real}`) time information about the motion
- `time`: (`::TimeCurve{T<:Real}`) time information about the motion
- `spins`: (`::AbstractSpinSpan`) spin indexes affected by the motion
# Returns
Expand All @@ -123,7 +137,7 @@ julia> path = Path(
)
```
"""
function Path(dx, dy, dz, time=TimeRange(zero(eltype(dx))), spins=AllSpins())
function Path(dx, dy, dz, time=TimeRange(t_start=zero(eltype(dx)), t_end=eps(eltype(dx))), spins=AllSpins())
return Motion(Path(dx, dy, dz), time, spins)
end

Expand All @@ -135,7 +149,7 @@ end
- `dy`: (`::AbstractArray{T<:Real}`, `[m]`) displacements in y
- `dz`: (`::AbstractArray{T<:Real}`, `[m]`) displacements in z
- `spin_reset`: (`::AbstractArray{Bool}`) reset spin state flags
- `time`: (`::AbstractTimeSpan{T<:Real}`) time information about the motion
- `time`: (`::TimeCurve{T<:Real}`) time information about the motion
- `spins`: (`::AbstractSpinSpan`) spin indexes affected by the motion
# Returns
Expand All @@ -153,7 +167,7 @@ julia> flowpath = FlowPath(
)
```
"""
function FlowPath(dx, dy, dz, spin_reset, time=TimeRange(zero(eltype(dx))), spins=AllSpins())
function FlowPath(dx, dy, dz, spin_reset, time=TimeRange(t_start=zero(eltype(dx)), t_end=eps(eltype(dx))), spins=AllSpins())
return Motion(FlowPath(dx, dy, dz, spin_reset), time, spins)
end

Expand All @@ -164,13 +178,30 @@ Base.:(≈)(m1::Motion, m2::Motion) = (typeof(m1) == typeof(m2)) & reduce(&, [g
""" Motion sub-group """
function Base.getindex(m::Motion, p)
idx, spin_range = m.spins[p]
return idx !== nothing ? Motion(m.action[idx], m.time, spin_range) : nothing
return idx !== nothing ? Motion(m.action[idx], m.time, spin_range) : NoMotion()
end
function Base.view(m::Motion, p)
idx, spin_range = @view(m.spins[p])
return idx !== nothing ? Motion(@view(m.action[idx]), m.time, spin_range) : nothing
return idx !== nothing ? Motion(@view(m.action[idx]), m.time, spin_range) : NoMotion()
end

"""
x, y, z = get_spin_coords(motion, x, y, z, t)
"""
function get_spin_coords(
m::Motion{T}, x::AbstractVector{T}, y::AbstractVector{T}, z::AbstractVector{T}, t
) where {T<:Real}
ux, uy, uz = x .* (0*t), y .* (0*t), z .* (0*t) # Buffers for displacements
t_unit = unit_time(t, m.time.t, m.time.t_unit, m.time.periodic, m.time.periods)
idx = get_indexing_range(m.spins)
displacement_x!(@view(ux[idx, :]), m.action, @view(x[idx]), @view(y[idx]), @view(z[idx]), t_unit)
displacement_y!(@view(uy[idx, :]), m.action, @view(x[idx]), @view(y[idx]), @view(z[idx]), t_unit)
displacement_z!(@view(uz[idx, :]), m.action, @view(x[idx]), @view(y[idx]), @view(z[idx]), t_unit)
return x .+ ux, y .+ uy, z .+ uz
end

# Auxiliary functions
times(m::Motion) = times(m.time)
is_composable(m::Motion) = is_composable(m.action)
times(m::Motion) = times(m.time.t, m.time.periods)
is_composable(m::Motion) = is_composable(m.action)
add_jump_times!(t, m::Motion) = add_jump_times!(t, m.action, m.time)
add_jump_times!(t, ::AbstractAction, ::TimeCurve) = nothing
Loading

0 comments on commit 437b9b6

Please sign in to comment.