Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
push:
branches:
- main
- develop
tags: '*'
pull_request:
concurrency:
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MPIMagneticFields"
uuid = "f6dda52a-86e9-4b50-afb7-f39836a99446"
authors = ["Marija Boberg <[email protected]> and contributors"]
version = "0.0.3"
version = "0.0.4"

[deps]
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Package for handling the magnetic fields used in [Magnetic Particle Imaging](https://en.wikipedia.org/wiki/Magnetic_particle_imaging).

[![Documentation](https://img.shields.io/badge/docs-stable-blue.svg)](https://magneticparticleimaging.github.io/MPIMagneticFields.jl/main/)
[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://magneticparticleimaging.github.io/MPIMagneticFields.jl/dev/)
[![Build status](https://github.com/MagneticParticleImaging/MPIMagneticFields.jl/workflows/CI/badge.svg)](https://github.com/MagneticParticleImaging/MPIMagneticFields.jl/actions)
[![codecov.io](https://codecov.io/gh/MagneticParticleImaging/MPIMagneticFields.jl/branch/main/graph/badge.svg)](https://app.codecov.io/github/MagneticParticleImaging/MPIMagneticFields.jl/tree/main)
Expand Down
9 changes: 9 additions & 0 deletions example/FFLOrientation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using MPIMagneticFields
using PyPlot

field = IdealXYFFL(5.0)

for angle in 0:pi/10:2pi
imshow([sign(val[1]) == sign(val[2]) ? sign(val[1]) + sign(val[2]) > 0 : sign(val[1]) - sign(val[2]) > 0 for val in value(field, [-0.02:0.001:0.02, -0.02:0.001:0.02, 0], angle)])
sleep(1)
end
36 changes: 36 additions & 0 deletions example/NewDefinition.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using MPIMagneticFields
using PyPlot
using LinearAlgebra

mutable struct IdealDipoleField{T, V} <: AbstractMagneticField where {T <: Number, V <: AbstractVector{T}}
magneticMoment::V

function IdealDipoleField(magneticMoment::V) where {T <: Number, V <: AbstractVector{T}}
return new{T, V}(magneticMoment)
end
end

MPIMagneticFields.FieldStyle(::IdealDipoleField) = OtherField()
MPIMagneticFields.FieldDefinitionStyle(::IdealDipoleField) = MethodBasedFieldDefinition()
MPIMagneticFields.FieldTimeDependencyStyle(::IdealDipoleField) = TimeConstant()

function MPIMagneticFields.value_(field::IdealDipoleField, r)
if norm(r) == 0
return zeros(eltype(field.magneticMoment), length(field.magneticMoment))
else
return MPIMagneticFields.μ₀/(4*π) * (3 .* r .* dot(field.magneticMoment, r) ./ norm(r)^5 .- field.magneticMoment*norm(r)^3)
end
end

dipole = IdealDipoleField([0.1, 0.0, 0.0])

xyRange = -0.02:0.0001:0.02
quiverPoints = [(x, y) for x in xyRange[1:50:end] for y in xyRange[1:50:end]]
X = [x for (x, y) in quiverPoints]
Y = [y for (x, y) in quiverPoints]
U = [dipole[x, y, 0][1] for (x, y) in quiverPoints]
V = [dipole[x, y, 0][2] for (x, y) in quiverPoints]

figure(1)
imshow(log.(norm.(dipole[xyRange, xyRange, 0])), extent=(minimum(xyRange), maximum(xyRange), minimum(xyRange), maximum(xyRange)))
quiver(X, Y, U, V)
13 changes: 13 additions & 0 deletions example/Superposition.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using MPIMagneticFields
using PyPlot
using LinearAlgebra

gradient = IdealFFP([1, 1, 2])
focusfield = IdealHomogeneousField([0.01, 0, 0])
superimposed = gradient + focusfield

figure(1)
imshow(norm.(gradient[-0.02:0.001:0.02, -0.02:0.001:0.02, 0]))

figure(2)
imshow(norm.(superimposed[-0.02:0.001:0.02, -0.02:0.001:0.02, 0]))
53 changes: 50 additions & 3 deletions src/Common.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,53 @@
#Base.size(S::SquaresVector) = (S.count,)
Base.IndexStyle(::Type{<:AbstractMagneticField}) = IndexCartesian()
Base.getindex(field::AbstractMagneticField, r...) = value(field, [r...]) # TODO: How to deal with rotation and translation?
Base.getindex(field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), field, args...)

# TODO: This only works with eachindex() available, which is only the case for fields defining a grid. How shall we solve this? Create a container?
#LinearAlgebra.norm(field::AbstractMagneticField) = [norm(field[i]) for i ∈ eachindex(field)]
getindex_(::TimeConstant, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), field, args...)

getindex_(::TimeConstant, ::NoMovement, field::AbstractMagneticField, args...) = value(field, [args...])

getindex_(::TimeConstant, ::RotationalMovement, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), RotationalDimensionalityStyle(field), field, args...)
getindex_(::TimeConstant, ::RotationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-1]...], [args[end]...])
getindex_(::TimeConstant, ::RotationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-2]...], [args[end-1:end]...])
getindex_(::TimeConstant, ::RotationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-3]...], [args[end-2:end]...])

getindex_(::TimeConstant, ::TranslationalMovement, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), TranslationalDimensionalityStyle(field), field, args...)
getindex_(::TimeConstant, ::TranslationalMovement, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-1]...], [args[end]...])
getindex_(::TimeConstant, ::TranslationalMovement, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-2]...], [args[end-1:end]...])
getindex_(::TimeConstant, ::TranslationalMovement, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-3]...], [args[end-2:end]...])

getindex_(::TimeConstant, ::RotationalTranslationalMovement, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), RotationalDimensionalityStyle(field), TranslationalDimensionalityStyle(field), field, args...)
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-2]...], [args[end-1]...], [args[end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-3]...], [args[end-2]...], [args[end-1:end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-4]...], [args[end-3]...], [args[end-2:end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-3]...], [args[end-2:end-1]...], [args[end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-4]...], [args[end-3:end-2]...], [args[end-1:end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-5]...], [args[end-4:end-3]...], [args[end-2:end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-4]...], [args[end-3:end-1]...], [args[end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-5]...], [args[end-4:end-2]...], [args[end-1:end]...])
getindex_(::TimeConstant, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, [args[1:end-6]...], [args[end-5:end-3]...], [args[end-2:end]...])

getindex_(::TimeVarying, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), field, args...)

getindex_(::TimeVarying, ::NoMovement, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end]...])

getindex_(::TimeVarying, ::RotationalMovement, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), RotationalDimensionalityStyle(field), field, args...)
getindex_(::TimeVarying, ::RotationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end-1]...], [args[end]...])
getindex_(::TimeVarying, ::RotationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end-2]...], [args[end-1:end]...])
getindex_(::TimeVarying, ::RotationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end-3]...], [args[end-2:end]...])

getindex_(::TimeVarying, ::TranslationalMovement, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), TranslationalDimensionalityStyle(field), field, args...)
getindex_(::TimeVarying, ::TranslationalMovement, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end-1]...], [args[end]...])
getindex_(::TimeVarying, ::TranslationalMovement, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end-2]...], [args[end-1:end]...])
getindex_(::TimeVarying, ::TranslationalMovement, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[2:end-3]...], [args[end-2:end]...])

getindex_(::TimeVarying, ::RotationalTranslationalMovement, field::AbstractMagneticField, args...) = getindex_(FieldTimeDependencyStyle(field), FieldMovementStyle(field), RotationalDimensionalityStyle(field), TranslationalDimensionalityStyle(field), field, args...)
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-4:end-2]...], [args[end-1]...], [args[end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-5:end-3]...], [args[end-2]...], [args[end-1:end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{OneDimensional}, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-6:end-4]...], [args[end-3]...], [args[end-2:end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-5:end-3]...], [args[end-2:end-1]...], [args[end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-6:end-4]...], [args[end-3:end-2]...], [args[end-1:end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{TwoDimensional}, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-7:end-5]...], [args[end-4:end-3]...], [args[end-2:end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, ::TranslationalDimensionalityStyle{OneDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-6:end-4]...], [args[end-3:end-1]...], [args[end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, ::TranslationalDimensionalityStyle{TwoDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-7:end-5]...], [args[end-4:end-2]...], [args[end-1:end]...])
getindex_(::TimeVarying, ::RotationalTranslationalMovement, ::RotationalDimensionalityStyle{ThreeDimensional}, ::TranslationalDimensionalityStyle{ThreeDimensional}, field::AbstractMagneticField, args...) = value(field, args[1], [args[end-8:end-6]...], [args[end-5:end-3]...], [args[end-2:end]...])
53 changes: 0 additions & 53 deletions src/CommonFields.jl

This file was deleted.

4 changes: 4 additions & 0 deletions src/CommonFields/CommonFields.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

include("FFL.jl")
include("FFP.jl")
include("Homogeneous.jl")
12 changes: 12 additions & 0 deletions src/CommonFields/FFL.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export IdealXYFFL
mutable struct IdealXYFFL{GT} <: AbstractMagneticField where {GT <: Number}
gradient::GT
end

FieldStyle(::IdealXYFFL) = GradientField()
FieldDefinitionStyle(::IdealXYFFL) = MethodBasedFieldDefinition()
FieldTimeDependencyStyle(::IdealXYFFL) = TimeConstant()
GradientFieldStyle(::IdealXYFFL) = FFLGradientField()
FieldMovementStyle(::IdealXYFFL) = RotationalMovement()

value_(field::IdealXYFFL, r, ϕ) = [-sin(ϕ)^2 -sin(ϕ)*cos(ϕ) 0; -sin(ϕ)*cos(ϕ) -cos(ϕ)^2 0; 0 0 1]*r.*field.gradient
11 changes: 11 additions & 0 deletions src/CommonFields/FFP.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export IdealFFP
mutable struct IdealFFP{GT} <: AbstractMagneticField where {GT <: Number}
gradient::Vector{GT}
end

FieldStyle(::IdealFFP) = GradientField()
FieldDefinitionStyle(::IdealFFP) = MethodBasedFieldDefinition()
FieldTimeDependencyStyle(::IdealFFP) = TimeConstant()
GradientFieldStyle(::IdealFFP) = FFPGradientField()

value_(field::IdealFFP, r) = r.*field.gradient
27 changes: 27 additions & 0 deletions src/CommonFields/Homogeneous.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export IdealHomogeneousField
mutable struct IdealHomogeneousField{U} <: AbstractMagneticField where {T <: Number, U <: AbstractVector{T}}
value::U

function IdealHomogeneousField(value::U) where {T <: Number, U <: AbstractVector{T}}
new{U}(value)
end
end

FieldStyle(::IdealHomogeneousField) = HomogeneousField()
FieldDefinitionStyle(::IdealHomogeneousField) = MethodBasedFieldDefinition()
FieldTimeDependencyStyle(::IdealHomogeneousField) = TimeConstant()

value_(field::IdealHomogeneousField, r) = field.value

# TODO: Define other combinations
export IdealXYRotatedHomogeneousField
mutable struct IdealXYRotatedHomogeneousField{T} <: AbstractMagneticField where {T <: Number}
amplitude::T
end

FieldStyle(::IdealXYRotatedHomogeneousField) = HomogeneousField()
FieldDefinitionStyle(::IdealXYRotatedHomogeneousField) = MethodBasedFieldDefinition()
FieldTimeDependencyStyle(::IdealXYRotatedHomogeneousField) = TimeConstant()
FieldMovementStyle(::IdealXYRotatedHomogeneousField) = RotationalMovement()

value_(field::IdealXYRotatedHomogeneousField, r, ϕ) = [sin(ϕ), cos(ϕ), 0].*field.amplitude
7 changes: 0 additions & 7 deletions src/Grid.jl

This file was deleted.

Loading