From f1aa8a439ffceb7188dc7be4b97fcd48723d5369 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Wed, 9 Oct 2024 14:14:44 +0200 Subject: [PATCH 1/8] First commit --- KomaMRIPlots/src/ui/DisplayFunctions.jl | 2 +- .../{1-sequence.md => 3-sequence.md} | 2 +- .../{2-seq-events.md => 4-seq-events.md} | 0 .../{3-simulation.md => 5-simulation.md} | 2 +- ...pu-explanation.md => 6-gpu-explanation.md} | 0 docs/src/explanation/lit-1-phantom.jl | 50 +++++++++++++++++++ docs/src/explanation/lit-2-motion.jl | 1 + 7 files changed, 54 insertions(+), 3 deletions(-) rename docs/src/explanation/{1-sequence.md => 3-sequence.md} (99%) rename docs/src/explanation/{2-seq-events.md => 4-seq-events.md} (100%) rename docs/src/explanation/{3-simulation.md => 5-simulation.md} (99%) rename docs/src/explanation/{4-gpu-explanation.md => 6-gpu-explanation.md} (100%) create mode 100644 docs/src/explanation/lit-1-phantom.jl create mode 100644 docs/src/explanation/lit-2-motion.jl diff --git a/KomaMRIPlots/src/ui/DisplayFunctions.jl b/KomaMRIPlots/src/ui/DisplayFunctions.jl index 81e0bb198..d2300efdd 100644 --- a/KomaMRIPlots/src/ui/DisplayFunctions.jl +++ b/KomaMRIPlots/src/ui/DisplayFunctions.jl @@ -1244,7 +1244,7 @@ function plot_phantom_map( ) for (i, t0) in enumerate(t) ], - currentvalue_prefix="x = ", + currentvalue_prefix="t = ", currentvalue_suffix="ms", )] l[:margin] = attr(t=50, l=0, r=0) diff --git a/docs/src/explanation/1-sequence.md b/docs/src/explanation/3-sequence.md similarity index 99% rename from docs/src/explanation/1-sequence.md rename to docs/src/explanation/3-sequence.md index 6f5206e7f..21aa0b50a 100644 --- a/docs/src/explanation/1-sequence.md +++ b/docs/src/explanation/3-sequence.md @@ -2,7 +2,7 @@ This section delves into some details about how a sequence is constructed. The sequence definition in **KomaMRI** is strongly related to the [Pulseq](https://pulseq.github.io/index.html) definition. After reading this section, you should be able to create your own **Sequence** structs for conducting custom simulations using the **KomaMRI** package. -## Sequence Overview +## KomaMRI Sequence Overview Let's introduce the following simple sequence figure to expand from a visual example to a more general sequence definition: ```@raw html diff --git a/docs/src/explanation/2-seq-events.md b/docs/src/explanation/4-seq-events.md similarity index 100% rename from docs/src/explanation/2-seq-events.md rename to docs/src/explanation/4-seq-events.md diff --git a/docs/src/explanation/3-simulation.md b/docs/src/explanation/5-simulation.md similarity index 99% rename from docs/src/explanation/3-simulation.md rename to docs/src/explanation/5-simulation.md index 5810e8a35..d64f6b4e8 100644 --- a/docs/src/explanation/3-simulation.md +++ b/docs/src/explanation/5-simulation.md @@ -24,7 +24,7 @@ From the programming perspective, it is needed to call the [`simulate`](@ref) fu | `"gpu"` | is a boolean that determines whether to use GPU or CPU hardware resources, as long as they are available on the host computer. | | `"gpu_device"` | sets the index ID of the available GPU in the host computer. | -For instance, if you want to perform a simulation on the CPU with float64 precision using the `BlochDict()` method (assuming you have already defined `obj` and `seq`), you can do so like this: +For instance, if you want to perform a simulation on the CPU with float64 precision using the `BlochDict()` method (assuming you have already defined `obj`, `seq` and `sys`), you can do so like this: ```julia # Set non-default simulation parameters and run simulation sim_params = KomaMRICore.default_sim_params() diff --git a/docs/src/explanation/4-gpu-explanation.md b/docs/src/explanation/6-gpu-explanation.md similarity index 100% rename from docs/src/explanation/4-gpu-explanation.md rename to docs/src/explanation/6-gpu-explanation.md diff --git a/docs/src/explanation/lit-1-phantom.jl b/docs/src/explanation/lit-1-phantom.jl new file mode 100644 index 000000000..045a828ed --- /dev/null +++ b/docs/src/explanation/lit-1-phantom.jl @@ -0,0 +1,50 @@ +# # Phantom + +using KomaMRIBase # hide +using PlotlyJS # hide + +# The first input argument that **KomaMRI** needs for simulating is the phantom. + +# This section goes over the concept of digital phantom +# and shows how it applies to the specific case of **KomaMRI**. +# We'll go into detail about the [`Phantom`](@ref) structure +# and present the ''.phantom'' file format, which makes it easy +# to share phantoms and reproduce experiments on any computer. + +# ## Digital Phantom + +# A digital phantom is basically a computer model of a physical object +# (like the human body or a body part) which is used in simulations +# to mimic the characteristics and behaviour that would be obtained +# from real MRI. Instead of using a physical object for testing, +# the digital phantom allows for virtual experiments. + +# This computer model should essentially contain information about +# the position and/or displacements of the tissues, as well as +# their MRI-related (T1, T2, PD, off-resonance...) values. + +# ## KomaMRI Phantom Overview + +# **KomaMRI** relies on the [`Phantom`](@ref) struct to define its digital phantom: +# ```julia +# @with_kw mutable struct Phantom{T<:Real} +# name::String = "spins" +# x::AbstractVector{T} +# y::AbstractVector{T} = zeros(eltype(x), size(x)) +# z::AbstractVector{T} = zeros(eltype(x), size(x)) +# ρ::AbstractVector{T} = ones(eltype(x), size(x)) +# T1::AbstractVector{T} = ones(eltype(x), size(x)) * 1_000_000 +# T2::AbstractVector{T} = ones(eltype(x), size(x)) * 1_000_000 +# T2s::AbstractVector{T} = ones(eltype(x), size(x)) * 1_000_000 +# #Off-resonance related +# Δw::AbstractVector{T} = zeros(eltype(x), size(x)) +# #Diffusion +# Dλ1::AbstractVector{T} = zeros(eltype(x), size(x)) +# Dλ2::AbstractVector{T} = zeros(eltype(x), size(x)) +# Dθ::AbstractVector{T} = zeros(eltype(x), size(x)) +# #Motion +# motion::AbstractMotion{T} = NoMotion{eltype(x)}() +# end +# ``` + +## Phantom File Format \ No newline at end of file diff --git a/docs/src/explanation/lit-2-motion.jl b/docs/src/explanation/lit-2-motion.jl new file mode 100644 index 000000000..e289ab73c --- /dev/null +++ b/docs/src/explanation/lit-2-motion.jl @@ -0,0 +1 @@ +# # Motion \ No newline at end of file From 64c02fa5363e63a95d8067f6e9c511c9f4402329 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Wed, 9 Oct 2024 23:47:00 +0200 Subject: [PATCH 2/8] Commit of the following: - Solve MotionList(rot) bug - Pass Docs CI - Add useful constructors to `Motion` --- KomaMRIBase/src/motion/motionlist/Motion.jl | 14 ++++++++++++++ KomaMRIBase/src/motion/motionlist/MotionList.jl | 2 +- docs/src/explanation/lit-1-phantom.jl | 3 +-- docs/src/explanation/lit-2-motion.jl | 6 +++++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/KomaMRIBase/src/motion/motionlist/Motion.jl b/KomaMRIBase/src/motion/motionlist/Motion.jl index d035b562b..869d0e06c 100644 --- a/KomaMRIBase/src/motion/motionlist/Motion.jl +++ b/KomaMRIBase/src/motion/motionlist/Motion.jl @@ -32,6 +32,20 @@ julia> motion = Motion( spins ::AbstractSpinSpan = AllSpins() end +# Main constructors +function Motion(action) + T = first(typeof(action).parameters) + return Motion(action, TimeRange(zero(T)), AllSpins()) +end +function Motion(action, time::AbstractTimeSpan) + 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(zero(T)), spins) +end + # Custom constructors """ translate = Translate(dx, dy, dz, time, spins) diff --git a/KomaMRIBase/src/motion/motionlist/MotionList.jl b/KomaMRIBase/src/motion/motionlist/MotionList.jl index 75e6460a2..b75841f7c 100644 --- a/KomaMRIBase/src/motion/motionlist/MotionList.jl +++ b/KomaMRIBase/src/motion/motionlist/MotionList.jl @@ -32,7 +32,7 @@ struct MotionList{T<:Real} <: AbstractMotion{T} end """ Constructors """ -MotionList(motions...) = length([motions]) > 0 ? MotionList([motions...]) : @error "You must provide at least one motion as input argument. If you do not want to define motion, use `NoMotion{T}()`" +MotionList(motions::Motion...) = length([motions]) > 0 ? MotionList([motions...]) : @error "You must provide at least one motion as input argument. If you do not want to define motion, use `NoMotion{T}()`" """ MotionList sub-group """ function Base.getindex(mv::MotionList{T}, p) where {T<:Real} diff --git a/docs/src/explanation/lit-1-phantom.jl b/docs/src/explanation/lit-1-phantom.jl index 045a828ed..86ec89de9 100644 --- a/docs/src/explanation/lit-1-phantom.jl +++ b/docs/src/explanation/lit-1-phantom.jl @@ -1,7 +1,6 @@ # # Phantom -using KomaMRIBase # hide -using PlotlyJS # hide +using KomaMRI # hide # The first input argument that **KomaMRI** needs for simulating is the phantom. diff --git a/docs/src/explanation/lit-2-motion.jl b/docs/src/explanation/lit-2-motion.jl index e289ab73c..428dea955 100644 --- a/docs/src/explanation/lit-2-motion.jl +++ b/docs/src/explanation/lit-2-motion.jl @@ -1 +1,5 @@ -# # Motion \ No newline at end of file +# # Motion + +using KomaMRI # hide + +# ToDo \ No newline at end of file From 38b96de38945a2c0ab93349988273c0b0fbe6977 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Fri, 11 Oct 2024 11:04:44 +0200 Subject: [PATCH 3/8] Commit of the following: - Finish lit-1-phantom.jl - New lit-3-phantom-format.jl - Upload svg files for phantom file tree - Update cross references --- README.md | 4 +- docs/src/assets/ph-action-types-dark.svg | 824 ++++++++++++++++++ docs/src/assets/ph-action-types-light.svg | 817 +++++++++++++++++ .../assets/ph-phantom-file-format-dark.svg | 683 +++++++++++++++ .../assets/ph-phantom-file-format-light.svg | 682 +++++++++++++++ docs/src/assets/ph-spinspan-types-dark.svg | 200 +++++ docs/src/assets/ph-spinspan-types-light.svg | 198 +++++ docs/src/assets/ph-timepan-types-dark.svg | 277 ++++++ docs/src/assets/ph-timepan-types-light.svg | 277 ++++++ .../{3-sequence.md => 4-sequence.md} | 4 +- .../{4-seq-events.md => 5-seq-events.md} | 0 .../{5-simulation.md => 6-simulation.md} | 0 ...pu-explanation.md => 7-gpu-explanation.md} | 0 docs/src/explanation/lit-1-phantom.jl | 108 ++- docs/src/explanation/lit-2-motion.jl | 6 + docs/src/explanation/lit-3-phantom-format.jl | 40 + docs/src/how-to/1-getting-started.md | 2 +- docs/src/how-to/2-3-use-koma-scripts.md | 12 +- examples/3.tutorials/lit-05-SimpleMotion.jl | 16 +- 19 files changed, 4117 insertions(+), 33 deletions(-) create mode 100644 docs/src/assets/ph-action-types-dark.svg create mode 100644 docs/src/assets/ph-action-types-light.svg create mode 100644 docs/src/assets/ph-phantom-file-format-dark.svg create mode 100644 docs/src/assets/ph-phantom-file-format-light.svg create mode 100644 docs/src/assets/ph-spinspan-types-dark.svg create mode 100644 docs/src/assets/ph-spinspan-types-light.svg create mode 100644 docs/src/assets/ph-timepan-types-dark.svg create mode 100644 docs/src/assets/ph-timepan-types-light.svg rename docs/src/explanation/{3-sequence.md => 4-sequence.md} (96%) rename docs/src/explanation/{4-seq-events.md => 5-seq-events.md} (100%) rename docs/src/explanation/{5-simulation.md => 6-simulation.md} (100%) rename docs/src/explanation/{6-gpu-explanation.md => 7-gpu-explanation.md} (100%) create mode 100644 docs/src/explanation/lit-3-phantom-format.jl diff --git a/README.md b/README.md index 92bc54cde..8363b666f 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ KomaMRI.jl is a Julia package for highly efficient ⚡ MRI simulations. KomaMRI ## News - **(1 Oct 2024)** [KomaMRI v0.9](https://github.com/JuliaHealth/KomaMRI.jl/releases/tag/v0.9.0): device-agnostic simulations, improved performance (**4-5x faster and 80x less memory**), distributed simulations, GPU benchmarking, mix-and-match motion definitions, improved dynamic phantom plotting, and a new phantom file format! -- **(29 Aug 2024)** Our first GSoC student, Ryan Kierulf, presented his fantastic work at the JuliaHealth monthly meeting 🥳! (presentation available [here](https://www.youtube.com/watch?v=R6Z20G0J4bM)) More info in the docs: [GPU Parallelization](https://juliahealth.org/KomaMRI.jl/dev/explanation/4-gpu-explanation/), [Distributed Simulations](https://juliahealth.org/KomaMRI.jl/dev/how-to/4-run-distributed-simulations/) and [Ryan's JuliaHealth blog](https://juliahealth.org/JuliaHealthBlog/posts/ryan-gsoc/Ryan_GSOC.html) +- **(29 Aug 2024)** Our first GSoC student, Ryan Kierulf, presented his fantastic work at the JuliaHealth monthly meeting 🥳! (presentation available [here](https://www.youtube.com/watch?v=R6Z20G0J4bM)) More info in the docs: [GPU Parallelization](https://juliahealth.org/KomaMRI.jl/dev/explanation/7-gpu-explanation/), [Distributed Simulations](https://juliahealth.org/KomaMRI.jl/dev/how-to/4-run-distributed-simulations/) and [Ryan's JuliaHealth blog](https://juliahealth.org/JuliaHealthBlog/posts/ryan-gsoc/Ryan_GSOC.html) - **(7 Dec 2023)** Koma was present in [MRI Together](https://mritogether.esmrmb.org/) 😼. The talk is available [here](https://www.youtube.com/watch?v=9mRQH8um4-A). Also, I uploaded the promised [educational example](https://juliahealth.org/KomaMRI.jl/stable/tutorial-pluto/01-gradient-echo-spin-echo/). - **(17 Nov 2023)** Pretty excited of being part of [ISMRM Pulseq's virtual meeting](https://github.com/pulseq/ISMRM-Virtual-Meeting--November-15-17-2023). The slides available [here](https://github.com/pulseq/ISMRM-Virtual-Meeting--November-15-17-2023/blob/35a8da7eaa0bf42f2127e1338a440ccd4e3ef53c/slides/day3_KomaMRI_simulator_Quantitative_MRI.pdf). - **(27 Jul 2023)** I gave a talk at MIT 😄 for [JuliaCon 2023](https://juliacon.org/2023/)! A video of the presentation can be seen [here](https://www.youtube.com/watch?v=WVT9wJegC6Q). @@ -117,7 +117,7 @@ KomaUI() Press the button that says "Simulate!" to do your first simulation :). Then, a notification will emerge telling you that the simulation was successful. In this notification, you can either select to (1) see the Raw Data or (2) to proceed with the reconstruction. > [!IMPORTANT] -> Starting from **KomaMRI v0.9** we are using [package extensions](https://pkgdocs.julialang.org/v1/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)) to deal with GPU dependencies, meaning that to run simulations on the GPU, installing (`add CUDA/AMDGPU/Metal/oneAPI`) and loading (`using CUDA/AMDGPU/Metal/oneAPI`) the desired backend will be necessary (see [GPU Parallelization](https://JuliaHealth.github.io/KomaMRI.jl/dev/explanation/4-gpu-explanation) and [Tested compatibility](#tested-compatibility)). +> Starting from **KomaMRI v0.9** we are using [package extensions](https://pkgdocs.julialang.org/v1/creating-packages/#Conditional-loading-of-code-in-packages-(Extensions)) to deal with GPU dependencies, meaning that to run simulations on the GPU, installing (`add CUDA/AMDGPU/Metal/oneAPI`) and loading (`using CUDA/AMDGPU/Metal/oneAPI`) the desired backend will be necessary (see [GPU Parallelization](https://JuliaHealth.github.io/KomaMRI.jl/dev/explanation/7-gpu-explanation) and [Tested compatibility](#tested-compatibility)). ## How to Contribute KomaMRI exists thanks to all our contributors: diff --git a/docs/src/assets/ph-action-types-dark.svg b/docs/src/assets/ph-action-types-dark.svg new file mode 100644 index 000000000..2ef49a7da --- /dev/null +++ b/docs/src/assets/ph-action-types-dark.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-action-types-light.svg b/docs/src/assets/ph-action-types-light.svg new file mode 100644 index 000000000..9989cb360 --- /dev/null +++ b/docs/src/assets/ph-action-types-light.svg @@ -0,0 +1,817 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-phantom-file-format-dark.svg b/docs/src/assets/ph-phantom-file-format-dark.svg new file mode 100644 index 000000000..6b2975d03 --- /dev/null +++ b/docs/src/assets/ph-phantom-file-format-dark.svg @@ -0,0 +1,683 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-phantom-file-format-light.svg b/docs/src/assets/ph-phantom-file-format-light.svg new file mode 100644 index 000000000..6e4e26859 --- /dev/null +++ b/docs/src/assets/ph-phantom-file-format-light.svg @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-spinspan-types-dark.svg b/docs/src/assets/ph-spinspan-types-dark.svg new file mode 100644 index 000000000..c2f081f4c --- /dev/null +++ b/docs/src/assets/ph-spinspan-types-dark.svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-spinspan-types-light.svg b/docs/src/assets/ph-spinspan-types-light.svg new file mode 100644 index 000000000..7f3839a4c --- /dev/null +++ b/docs/src/assets/ph-spinspan-types-light.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-timepan-types-dark.svg b/docs/src/assets/ph-timepan-types-dark.svg new file mode 100644 index 000000000..fcd1709f7 --- /dev/null +++ b/docs/src/assets/ph-timepan-types-dark.svg @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/assets/ph-timepan-types-light.svg b/docs/src/assets/ph-timepan-types-light.svg new file mode 100644 index 000000000..1d34ba4e2 --- /dev/null +++ b/docs/src/assets/ph-timepan-types-light.svg @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/explanation/3-sequence.md b/docs/src/explanation/4-sequence.md similarity index 96% rename from docs/src/explanation/3-sequence.md rename to docs/src/explanation/4-sequence.md index 21aa0b50a..d11c52617 100644 --- a/docs/src/explanation/3-sequence.md +++ b/docs/src/explanation/4-sequence.md @@ -34,7 +34,7 @@ mutable struct Sequence end ``` -As you can see, a **Sequence** struct contains 5 field names: ''DEF'' contains information for reconstruction steps (so it is not mandatory to fill it), ''DUR'' is a vector that contains the time durations of each block, ''ADC'' is also a vector with the acquisition samples for every block (an vector of **ADC** structs), ''GR'' is a 2D matrix which 3 rows representing the x-y-z gradients and columns having the samples of each block (a matrix of **Grad** structs) and ''RF'' is also a 2D matrix where each row represents a different coil and the columns are for different block samples too (a matrix of **RF** structs). The **RF**, **Grad** and **ADC** are MRI events that will be explained in the section [Events Definitions](2-seq-events.md). +As you can see, a **Sequence** struct contains 5 field names: ''DEF'' contains information for reconstruction steps (so it is not mandatory to fill it), ''DUR'' is a vector that contains the time durations of each block, ''ADC'' is also a vector with the acquisition samples for every block (an vector of **ADC** structs), ''GR'' is a 2D matrix which 3 rows representing the x-y-z gradients and columns having the samples of each block (a matrix of **Grad** structs) and ''RF'' is also a 2D matrix where each row represents a different coil and the columns are for different block samples too (a matrix of **RF** structs). The **RF**, **Grad** and **ADC** are MRI events that will be explained in the section [Events Definitions](5-seq-events.md). !!! warning So far, **KomaMRI** can only manage one coil for RF excitations. However, in future versions, parallel transmit pTX will be managed by adding more ``rows'' to the RF matrix of the Sequence field name. @@ -88,7 +88,7 @@ julia> seq.DUR 0.0004042313086942605 ``` -Additionally, you can access a subset of blocks in a **Sequence** by slicing or indexing. The result will also be a **Sequence** struct, allowing you to perform the same operations as you would with a full Sequence. For example, if you want to analyze the first 11 blocks, you can do the following: +Additionally, you can access a subset of blocks in a **Sequence** by slicing or indexing. The result will also be a **Sequence** struct, allowing you to perform the same operations as you would with a full Sequence (just a heads-up: this is analogous for the [Phantom](1-phantom.md) structure). For example, if you want to analyze the first 11 blocks, you can do the following: ```julia-repl julia> seq[1:11] Sequence[ τ = 3.837 ms | blocks: 11 | ADC: 5 | GR: 11 | RF: 1 | DEF: 5 ] diff --git a/docs/src/explanation/4-seq-events.md b/docs/src/explanation/5-seq-events.md similarity index 100% rename from docs/src/explanation/4-seq-events.md rename to docs/src/explanation/5-seq-events.md diff --git a/docs/src/explanation/5-simulation.md b/docs/src/explanation/6-simulation.md similarity index 100% rename from docs/src/explanation/5-simulation.md rename to docs/src/explanation/6-simulation.md diff --git a/docs/src/explanation/6-gpu-explanation.md b/docs/src/explanation/7-gpu-explanation.md similarity index 100% rename from docs/src/explanation/6-gpu-explanation.md rename to docs/src/explanation/7-gpu-explanation.md diff --git a/docs/src/explanation/lit-1-phantom.jl b/docs/src/explanation/lit-1-phantom.jl index 86ec89de9..aee0c08fc 100644 --- a/docs/src/explanation/lit-1-phantom.jl +++ b/docs/src/explanation/lit-1-phantom.jl @@ -4,27 +4,25 @@ using KomaMRI # hide # The first input argument that **KomaMRI** needs for simulating is the phantom. -# This section goes over the concept of digital phantom -# and shows how it applies to the specific case of **KomaMRI**. -# We'll go into detail about the [`Phantom`](@ref) structure -# and present the ''.phantom'' file format, which makes it easy -# to share phantoms and reproduce experiments on any computer. +# This section goes over the concept of digital phantom and shows how it applies to the specific case +# of **KomaMRI**. We'll go into detail about the [`Phantom`](@ref) structure and its supported operations. # ## Digital Phantom -# A digital phantom is basically a computer model of a physical object -# (like the human body or a body part) which is used in simulations -# to mimic the characteristics and behaviour that would be obtained -# from real MRI. Instead of using a physical object for testing, -# the digital phantom allows for virtual experiments. +# A digital phantom is basically a computer model of a physical object (like the human body or a body part) +# which is used in simulations to mimic the characteristics and behaviour that would be obtained from +# real MRI. Instead of using a physical object for testing, the digital phantom allows for virtual experiments. -# This computer model should essentially contain information about -# the position and/or displacements of the tissues, as well as -# their MRI-related (T1, T2, PD, off-resonance...) values. +# This computer model should essentially contain information about the position and/or displacements +# of the tissues, as well as their MRI-related (T1, T2, PD, off-resonance...) values. # ## KomaMRI Phantom Overview +# In Koma, a phantom is made up of a set of spins (which in many cases are also known as ''isochromats''). +# Each spin is independent of the others in terms of properties, position and state. +# This is a key feature of **KomaMRI**, as it is explained in the [Simulation](6-simulation.md) section. -# **KomaMRI** relies on the [`Phantom`](@ref) struct to define its digital phantom: +# Let's take a look at the definition of the [`Phantom`](@ref) struct +# inside Koma's source code to see what it looks like: # ```julia # @with_kw mutable struct Phantom{T<:Real} # name::String = "spins" @@ -46,4 +44,84 @@ using KomaMRI # hide # end # ``` -## Phantom File Format \ No newline at end of file +# This structure consists of several elements. Most of them are vectors, except for +# the `name` (self-explanatory) and `motion` (explained below) fields. +# These vectors represent object properties, with each element holding a value associated +# with a single magnetization (i.e. a single spin). +# Specifically, `x`, `y` and `z` are the spatial (starting) coordinates of each spin. +# `ρ` stands for the proton density, and `T1`, `T2` and `T2s` (standing for T2*) +# are the well-known relaxation times. `Δw` accounts for off-resonance effects. +# `Dλ1`, `Dλ2` and `Dθ` are diffusion-related fields which are not in use at the moment. +# Last, the `motion` field stands for spin displacements, which are added to `x`, `y` and `z` +# when simulating in order to obtain the spin positions at each time step. For more information about +# motion, refer to [Motion](2-motion.md) section. + +# To get an even better understanding on how it works, let's look at an example of a brain phantom: + +obj = brain_phantom2D() + +# You can visualize the **Phantom** struct using the [`plot_phantom_map`](@ref) function, +# which is part of the **KomaMRIPlots** subdependency. This function plots the magnitude of a property for +# each magnetization at a specific spatial position. You can observe properties such as proton density +# and relaxation times, so feel free to replace the `:ρ` symbol with another property of the phantom in the example below: + +p1 = plot_phantom_map(obj, :ρ; height=450) + +#md savefig(p1, "../assets/doc-1-phantom.html") # hide +#jl display(p1) + +#md # ```@raw html +#md #
+#md # ``` + +# You can access and filter information for the all the field names of a **Phantom** using the dot notation: +obj.name +#- +obj.x +#- +obj.motion + +# ## Phantom Operations + +# In addition, **KomaMRI** supports some phantom operations: + +# ### Phantom Subset + +# It is possible to access a subset of spins in a **Phantom** by slicing or indexing. The result will also be a +# **Phantom** struct, allowing you to perform the same operations as you would with a full Phantom: + +obj[1:1000] +p2 = plot_phantom_map(obj[1:1000], :T2 ; height=450) # hide + +#md savefig(p2, "../assets/tut-5-phantom-subset.html") # hide +#jl display(p2) + +#md # ```@raw html +#md #
+#md # ``` + +# ### Combination of Phantoms + +# In the same way, we can add two or more phantoms, resulting in another [`Phantom`](@ref) struct: +obj2 = pelvis_phantom2D() +obj2.motion = MotionList(Translate(0.0, 0.0, -0.5, TimeRange(0.0))) +obj_sum = obj1 + obj2 +p3 = plot_phantom_map(obj_sum, :T1 ; height=450) # hide + +#md savefig(p3, "../assets/tut-5-phantom-sum.html") # hide +#jl display(p3) + +#md # ```@raw html +#md #
+#md # ``` + +# ### Scalar multiplication of a Phantom + +# Finally, multiplying a phantom by a scalar multiplies its proton density (`ρ`) by that amount: +obj_mul = 3*obj +obj.ρ +#- +obj_mul.ρ + +# ## Phantom Storage and Sharing +# Phantoms can be stored and shared thanks to our new [Phantom File Format](3-phantom-format.md). \ No newline at end of file diff --git a/docs/src/explanation/lit-2-motion.jl b/docs/src/explanation/lit-2-motion.jl index 428dea955..62384da68 100644 --- a/docs/src/explanation/lit-2-motion.jl +++ b/docs/src/explanation/lit-2-motion.jl @@ -2,4 +2,10 @@ using KomaMRI # hide +# ## `NoMotion` struct + +# ToDo + +# ## `Motion` & `MotionList` + # ToDo \ No newline at end of file diff --git a/docs/src/explanation/lit-3-phantom-format.jl b/docs/src/explanation/lit-3-phantom-format.jl new file mode 100644 index 000000000..c24ff9ffe --- /dev/null +++ b/docs/src/explanation/lit-3-phantom-format.jl @@ -0,0 +1,40 @@ +# # Phantom File Format + +# ## Introduction + +# While there is already an open and fairly standardised format for MRI sequences +# such as [Pulseq](https://pulseq.github.io/index.html), this is not the case for digital phantoms. +# That's why we defined a new ''.phantom'' format, which relies on the [HDF5 standard](https://www.hdfgroup.org/solutions/hdf5/). +# HDF5 is specially designed to store large amounts of heterogeneous data and to make it readable +# and writable quickly and easily. In addition, it allows the storage of metadata. +# For all these reasons, it is the ideal file format for storing phantoms. + +# ## File Format Specification + +# ### Phantom File Tree + +#md # ```@raw html +#md

+#md

+# ``` + +# ### Action types + +#md # ```@raw html +#md

+#md

+# ``` + +# ### TimeSpan types + +#md # ```@raw html +#md

+#md

+# ``` + +# ### SpinSpan types + +#md # ```@raw html +#md

+#md

+# ``` \ No newline at end of file diff --git a/docs/src/how-to/1-getting-started.md b/docs/src/how-to/1-getting-started.md index 734f0339a..8f818a281 100644 --- a/docs/src/how-to/1-getting-started.md +++ b/docs/src/how-to/1-getting-started.md @@ -24,7 +24,7 @@ Then press `Ctrl+C` or `backspace` to return to the `julia>` prompt. --- ## My First MRI Simulation -For our first simulation we will use **KomaMRI**'s graphical user interface (GUI). For this, you will first need to load **KomaMRI** by typing `using KomaMRI`, and then launch the GUI with the [`KomaUI`](@ref) function. Note that if you want to run simulations on the GPU (for example, using CUDA), then `using CUDA` is also necessary (see [GPU Parallelization](../explanation/4-gpu-explanation.md)). +For our first simulation we will use **KomaMRI**'s graphical user interface (GUI). For this, you will first need to load **KomaMRI** by typing `using KomaMRI`, and then launch the GUI with the [`KomaUI`](@ref) function. Note that if you want to run simulations on the GPU (for example, using CUDA), then `using CUDA` is also necessary (see [GPU Parallelization](../explanation/7-gpu-explanation.md)). ```julia-repl julia> using KomaMRI, CUDA diff --git a/docs/src/how-to/2-3-use-koma-scripts.md b/docs/src/how-to/2-3-use-koma-scripts.md index 68b3ab3e2..b66f8e0fc 100644 --- a/docs/src/how-to/2-3-use-koma-scripts.md +++ b/docs/src/how-to/2-3-use-koma-scripts.md @@ -83,7 +83,9 @@ Scanner The Phantom struct created in this example represents a slice of a brain. To create it, we use the function `brain_phantom2D`, which is part of the subdependency **KomaMRICore**. While **KomaMRI** provides some phantom examples for experimentation, you may also want to create your custom **Phantom** struct tailored to your specific requirements. -The **Phantom** struct contains MRI parameters related to the magnetization properties of an object. These parameters include magnetization positions, proton density, relaxation times, off-resonance, among others. To view all the keys and values of the object, you can do so in the **Julia REPL** as follows: +The **Phantom** struct contains MRI parameters related to the magnetization properties of an object. These parameters include magnetization positions, proton density, relaxation times, off-resonance, among others. +For more information about Koma's Phantom and what it can do, as well as how to store and share it, check out the [Phantom](../explanation/1-phantom.md) section. +To view all the keys and values of the object, you can do so in the **Julia REPL** as follows: ```julia-repl julia> obj Phantom{Float64} @@ -99,11 +101,11 @@ Phantom{Float64} Dλ1: Array{Float64}((6506,)) [0.0, 0.0, … 0.0, 0.0] Dλ2: Array{Float64}((6506,)) [0.0, 0.0, … 0.0, 0.0] Dθ: Array{Float64}((6506,)) [0.0, 0.0, … 0.0, 0.0] + motion: NoMotion{Float64} NoMotion{Float64}() ... ``` -As you can see, attributes of the **Phantom** struct are vectors representing object properties, with each element holding a value associated with a single magnetization. -You can also visualize the **Phantom** struct using the [`plot_phantom_map`](@ref) function, which is part of the **KomaMRIPlots** subdependency. This function plots the magnitude of a property for each magnetization at a specific spatial position. You can observe properties such as proton density and relaxation times, so feel free to replace the `:ρ` symbol with another property of the phantom in the example below: +You can also visualize the **Phantom** struct using the [`plot_phantom_map`](@ref) function: ```julia-repl julia> plot_phantom_map(obj, :ρ) ``` @@ -126,7 +128,7 @@ julia> plot_phantom_map(sphere, :T2) The **Sequence** struct in the example represents one of the most basic MRI sequences. It excites the object with a 90° RF pulse and then uses EPI gradients to fill the k-space in a "square" manner. While you may want to create your sequences for experiments, you can always use some of the examples already available in **KomaMRI**. -In MRI, the sequence must be carefully designed with precise timing to obtain an image. It includes subcomponents such as gradients, radio-frequency excitation signals, and sample acquisition. For more information on constructing a **Sequence** struct, refer to the [Sequence](../explanation/1-sequence.md) section. +In MRI, the sequence must be carefully designed with precise timing to obtain an image. It includes subcomponents such as gradients, radio-frequency excitation signals, and sample acquisition. For more information on constructing a **Sequence** struct, refer to the [Sequence](../explanation/4-sequence.md) section. You can view general information about a **Sequence** struct by displaying it in the **Julia REPL**: ```julia-repl @@ -191,7 +193,7 @@ Dict{String, Any} with 9 entries: "Δt_rf" => 5.0e-5 ``` -All of these parameters deserve special attention. We will explain some of the most important ones here. For instance, `"Δt"` and `"Δt_rf"` represent the raster times for the gradients and RFs. `"return_type"` specifies the type of variable returned by the simulator (by default, it returns an object ready for use with **MRIReco** for reconstruction, but you can use the value `"mat"` to return a simple vector). `"gpu"` indicates whether you want to use your GPU device for simulations, and `"precision"` sets the floating-point precision. For more details on how to set these parameters, please refer to the [Simulation Parameters Section](../explanation/3-simulation.md). +All of these parameters deserve special attention. We will explain some of the most important ones here. For instance, `"Δt"` and `"Δt_rf"` represent the raster times for the gradients and RFs. `"return_type"` specifies the type of variable returned by the simulator (by default, it returns an object ready for use with **MRIReco** for reconstruction, but you can use the value `"mat"` to return a simple vector). `"gpu"` indicates whether you want to use your GPU device for simulations, and `"precision"` sets the floating-point precision. For more details on how to set these parameters, please refer to the [Simulation Parameters Section](../explanation/6-simulation.md). ### Raw Signal diff --git a/examples/3.tutorials/lit-05-SimpleMotion.jl b/examples/3.tutorials/lit-05-SimpleMotion.jl index d20929f62..ae1e2d29d 100644 --- a/examples/3.tutorials/lit-05-SimpleMotion.jl +++ b/examples/3.tutorials/lit-05-SimpleMotion.jl @@ -21,11 +21,11 @@ obj.motion = MotionList( ) p1 = plot_phantom_map(obj, :T2 ; height=450, time_samples=4) # hide -#md savefig(p1, "../assets/5-phantom1.html") # hide +#md savefig(p1, "../assets/tut-5-phantom.html") # hide #jl display(p1) #md # ```@raw html -#md #
+#md #
#md # ``` ## Read Sequence # hide @@ -46,12 +46,12 @@ image1 = reconstruction(acq1, reconParams) # hide # we will observe motion-induced artifacts in the reconstructed image. ## Plotting the recon # hide p2 = plot_image(abs.(image1[:, :, 1]); height=400) # hide -#md savefig(p2, "../assets/5-recon1.html") # hide +#md savefig(p2, "../assets/tut-5-recon1.html") # hide #jl display(p2) #md # ```@raw html #md #
-#md # +#md # #md #
#md # ``` @@ -83,11 +83,11 @@ p3 = plot( # hide )) # hide restyle!(p3,1:3, name=["ux(t)", "uy(t)", "uz(t)"]) # hide -#md savefig(p3, "../assets/5-displacements.html") # hide +#md savefig(p3, "../assets/tut-5-displacements.html") # hide #jl display(p3) #md # ```@raw html -#md #
+#md #
#md # ``` # We can now get the necessary phase shift for each sample: @@ -101,7 +101,7 @@ image2 = reconstruction(acq1, reconParams) # hide p4 = plot_image(abs.(image2[:, :, 1]); height=400) # hide -#md savefig(p4, "../assets/5-recon2.html") # hide +#md savefig(p4, "../assets/tut-5-recon2.html") # hide #jl display(p2) #jl display(p4) @@ -109,5 +109,5 @@ p4 = plot_image(abs.(image2[:, :, 1]); height=400) # hide # Finally, we compare the original image ▶️ and the motion-corrected reconstruction ⏸️: #md # ```@raw html -#md # +#md # #md # ``` From 0548186ceccde219af7c36095384f322ade300e4 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Fri, 11 Oct 2024 11:25:18 +0200 Subject: [PATCH 4/8] Solve bugs: - Typo in lit-1-phantom.jl - Typo in ph-timespan-type svg filenames - Fix light mode for ph-timespan-type --- ...es-dark.svg => ph-timespan-types-dark.svg} | 0 ...-light.svg => ph-timespan-types-light.svg} | 92 +++++++++---------- docs/src/explanation/lit-1-phantom.jl | 2 +- 3 files changed, 47 insertions(+), 47 deletions(-) rename docs/src/assets/{ph-timepan-types-dark.svg => ph-timespan-types-dark.svg} (100%) rename docs/src/assets/{ph-timepan-types-light.svg => ph-timespan-types-light.svg} (97%) diff --git a/docs/src/assets/ph-timepan-types-dark.svg b/docs/src/assets/ph-timespan-types-dark.svg similarity index 100% rename from docs/src/assets/ph-timepan-types-dark.svg rename to docs/src/assets/ph-timespan-types-dark.svg diff --git a/docs/src/assets/ph-timepan-types-light.svg b/docs/src/assets/ph-timespan-types-light.svg similarity index 97% rename from docs/src/assets/ph-timepan-types-light.svg rename to docs/src/assets/ph-timespan-types-light.svg index 1d34ba4e2..5589a7b29 100644 --- a/docs/src/assets/ph-timepan-types-light.svg +++ b/docs/src/assets/ph-timespan-types-light.svg @@ -25,7 +25,7 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="1.5246212" - inkscape:cx="101.6646" + inkscape:cx="101.99255" inkscape:cy="107.89565" inkscape:window-width="1458" inkscape:window-height="1011" @@ -51,53 +51,53 @@ id="g2" aria-label="TimeSpantypes TimeRange ..." transform="matrix(1.3333333,0,0,1.3333333,113.38533,88.874667)" - style="fill:#ffffff;fill-opacity:1"> + style="fill:#000000;fill-opacity:1"> + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:#000000;fill-opacity:1"> + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.697333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" /> Date: Fri, 11 Oct 2024 12:44:12 +0200 Subject: [PATCH 5/8] Commit of the following: - Change phantom-format file to pure markdown - Try `execute=true` option for Literate.markdown function - Change `plot_phantom_map` example to display T1 - Remove buildkite test to avoid overloading --- .buildkite/pipeline.yml | 70 ++++++++++---------- docs/src/explanation/3-phantom-format.md | 40 +++++++++++ docs/src/explanation/lit-1-phantom.jl | 4 +- docs/src/explanation/lit-3-phantom-format.jl | 40 ----------- docs/src/index.md | 2 +- docs/utils.jl | 3 +- 6 files changed, 80 insertions(+), 79 deletions(-) create mode 100644 docs/src/explanation/3-phantom-format.md delete mode 100644 docs/src/explanation/lit-3-phantom-format.jl diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 25aada17f..0a0e22515 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -1,39 +1,39 @@ steps: - - label: ":pipeline: Upload NoMotion Tests" - env: - TEST_GROUP: "nomotion" - command: buildkite-agent pipeline upload .buildkite/runtests.yml - agents: - queue: "juliagpu" + # - 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" + # - label: ":pipeline: Upload Motion Tests" + # env: + # TEST_GROUP: "motion" + # command: buildkite-agent pipeline upload .buildkite/runtests.yml + # agents: + # queue: "juliagpu" - - label: ":pipeline: Launch Benchmarks" - if: build.message !~ /skip benchmarks/ - agents: - queue: "juliagpu" - plugins: - - monorepo-diff#v1.0.1: - diff: "git diff --name-only HEAD~1" - interpolation: false - watch: - - path: - - "KomaMRICore/src/**/*" - - "KomaMRICore/ext/**/*" - - "KomaMRICore/Project.toml" - - "KomaMRIBase/src/**/*" - - "KomaMRIBase/Project.toml" - - "benchmarks/**/*" - - ".buildkite/**/*" - - ".github/workflows/Benchmark.yml" - - "Project.toml" - config: - command: "buildkite-agent pipeline upload .buildkite/runbenchmarks.yml" - agents: - queue: "juliagpu" + # - label: ":pipeline: Launch Benchmarks" + # if: build.message !~ /skip benchmarks/ + # agents: + # queue: "juliagpu" + # plugins: + # - monorepo-diff#v1.0.1: + # diff: "git diff --name-only HEAD~1" + # interpolation: false + # watch: + # - path: + # - "KomaMRICore/src/**/*" + # - "KomaMRICore/ext/**/*" + # - "KomaMRICore/Project.toml" + # - "KomaMRIBase/src/**/*" + # - "KomaMRIBase/Project.toml" + # - "benchmarks/**/*" + # - ".buildkite/**/*" + # - ".github/workflows/Benchmark.yml" + # - "Project.toml" + # config: + # command: "buildkite-agent pipeline upload .buildkite/runbenchmarks.yml" + # agents: + # queue: "juliagpu" diff --git a/docs/src/explanation/3-phantom-format.md b/docs/src/explanation/3-phantom-format.md new file mode 100644 index 000000000..e79458037 --- /dev/null +++ b/docs/src/explanation/3-phantom-format.md @@ -0,0 +1,40 @@ +# Phantom File Format + +## Introduction + +While there is already an open and fairly standardised format for MRI sequences +such as [Pulseq](https://pulseq.github.io/index.html), this is not the case for digital phantoms. +That's why we defined a new ''.phantom'' format, which relies on the [HDF5 standard](https://www.hdfgroup.org/solutions/hdf5/). +HDF5 is specially designed to store large amounts of heterogeneous data and to make it readable +and writable quickly and easily. In addition, it allows the storage of metadata. +For all these reasons, it is the ideal file format for storing phantoms. + +## File Format Specification + +### Phantom File Tree + +```@raw html +

+

+``` + +### Action types + +```@raw html +

+

+``` + +### TimeSpan types + +```@raw html +

+

+``` + +### SpinSpan types + +```@raw html +

+

+``` \ No newline at end of file diff --git a/docs/src/explanation/lit-1-phantom.jl b/docs/src/explanation/lit-1-phantom.jl index fce109962..6cfc6fb66 100644 --- a/docs/src/explanation/lit-1-phantom.jl +++ b/docs/src/explanation/lit-1-phantom.jl @@ -63,9 +63,9 @@ obj = brain_phantom2D() # You can visualize the **Phantom** struct using the [`plot_phantom_map`](@ref) function, # which is part of the **KomaMRIPlots** subdependency. This function plots the magnitude of a property for # each magnetization at a specific spatial position. You can observe properties such as proton density -# and relaxation times, so feel free to replace the `:ρ` symbol with another property of the phantom in the example below: +# and relaxation times, so feel free to replace the `:T1` symbol with another property of the phantom in the example below: -p1 = plot_phantom_map(obj, :ρ; height=450) +p1 = plot_phantom_map(obj, :T1; height=450) #md savefig(p1, "../assets/doc-1-phantom.html") # hide #jl display(p1) diff --git a/docs/src/explanation/lit-3-phantom-format.jl b/docs/src/explanation/lit-3-phantom-format.jl deleted file mode 100644 index c24ff9ffe..000000000 --- a/docs/src/explanation/lit-3-phantom-format.jl +++ /dev/null @@ -1,40 +0,0 @@ -# # Phantom File Format - -# ## Introduction - -# While there is already an open and fairly standardised format for MRI sequences -# such as [Pulseq](https://pulseq.github.io/index.html), this is not the case for digital phantoms. -# That's why we defined a new ''.phantom'' format, which relies on the [HDF5 standard](https://www.hdfgroup.org/solutions/hdf5/). -# HDF5 is specially designed to store large amounts of heterogeneous data and to make it readable -# and writable quickly and easily. In addition, it allows the storage of metadata. -# For all these reasons, it is the ideal file format for storing phantoms. - -# ## File Format Specification - -# ### Phantom File Tree - -#md # ```@raw html -#md

-#md

-# ``` - -# ### Action types - -#md # ```@raw html -#md

-#md

-# ``` - -# ### TimeSpan types - -#md # ```@raw html -#md

-#md

-# ``` - -# ### SpinSpan types - -#md # ```@raw html -#md

-#md

-# ``` \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md index a3fdd9429..9281dff90 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,7 +6,7 @@ ```@raw html

-

+

``` We organized the documentation following the philosophy presented by [David Laing](https://documentation.divio.com/). diff --git a/docs/utils.jl b/docs/utils.jl index 6005042fc..a78e510fc 100644 --- a/docs/utils.jl +++ b/docs/utils.jl @@ -65,7 +65,8 @@ function literate_doc_folder(input_folder, output_doc_section; lit_pattern="lit- input_folder; repo_root_url, preprocess=_link_example(filename_gen), - name=filename_gen + name=filename_gen, + execute=true ) Literate.script(tutorial_src, input_folder; name=filename_gen, repo_root_url) Literate.notebook(tutorial_src, input_folder; name=filename_gen, execute=false) From d631815ca1705acb83563b750330b817993409c5 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Fri, 11 Oct 2024 17:06:22 +0200 Subject: [PATCH 6/8] Commit with the following: - Remove `execute=true` - Update svg files for file format section - Display outputs in phantom section --- docs/src/assets/ph-timespan-types-dark.svg | 129 ++++++++++---------- docs/src/assets/ph-timespan-types-light.svg | 113 ++++++++--------- docs/src/explanation/3-phantom-format.md | 16 +-- docs/src/explanation/lit-1-phantom.jl | 84 ++++++++++--- docs/utils.jl | 3 +- 5 files changed, 199 insertions(+), 146 deletions(-) diff --git a/docs/src/assets/ph-timespan-types-dark.svg b/docs/src/assets/ph-timespan-types-dark.svg index fcd1709f7..a63c35930 100644 --- a/docs/src/assets/ph-timespan-types-dark.svg +++ b/docs/src/assets/ph-timespan-types-dark.svg @@ -7,7 +7,7 @@ width="440" height="250" viewBox="0 0 440 250" - sodipodi:docname="ph_timepan_types_dark.svg" + sodipodi:docname="ph-timespan-types-light.svg" inkscape:version="1.3.2 (091e20e, 2023-11-25)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -25,14 +25,15 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="1.5246212" - inkscape:cx="101.6646" - inkscape:cy="107.89565" - inkscape:window-width="1458" + inkscape:cx="198.40994" + inkscape:cy="67.885714" + inkscape:window-width="1280" inkscape:window-height="1011" - inkscape:window-x="1102" + inkscape:window-x="1280" inkscape:window-y="32" inkscape:window-maximized="0" - inkscape:current-layer="g1"> + inkscape:current-layer="g1" + showgrid="false"> + style="fill:#fefefe;fill-opacity:1"> + d="m 30.957811,-6.3057813 c 0.140625,0 0.398437,0 0.398437,-0.3046875 0,-0.3046875 -0.246093,-0.3046875 -0.398437,-0.3046875 h -1.804688 c -0.328125,0 -0.398437,0.09375 -0.398437,0.4101563 v 6.92578125 c 0,0.3046875 0.05859,0.41015625 0.398437,0.41015625 h 1.804688 c 0.140625,0 0.398437,0 0.398437,-0.3046875 0,-0.3046875 -0.246093,-0.3046875 -0.398437,-0.3046875 h -1.523438 v -6.5273438 z m 3.776367,3.7617188 c -0.222656,-0.035156 -0.421875,-0.070312 -0.667969,-0.1171875 -0.292968,-0.035156 -0.972656,-0.1640625 -0.972656,-0.5507813 0,-0.2578125 0.316406,-0.5625 1.265625,-0.5625 0.832031,0 0.960938,0.2929688 0.996094,0.5507813 0.01172,0.1757812 0.03516,0.3398437 0.339844,0.3398437 0.351562,0 0.351562,-0.2109375 0.351562,-0.4101562 V -3.97375 c 0,-0.1640625 0,-0.4101563 -0.304687,-0.4101563 -0.234375,0 -0.28125,0.140625 -0.292969,0.2109375 -0.445313,-0.2109375 -0.878906,-0.2109375 -1.066406,-0.2109375 -1.664063,0 -1.898438,0.8203125 -1.898438,1.171875 0,0.9140625 1.042969,1.0898438 1.96875,1.2304688 0.480469,0.082031 1.277344,0.2109375 1.277344,0.7382812 0,0.3632813 -0.363281,0.6914063 -1.265625,0.6914063 -0.46875,0 -1.03125,-0.10546875 -1.277344,-0.8789063 -0.05859,-0.1875 -0.09375,-0.2929687 -0.351562,-0.2929687 -0.351563,0 -0.351563,0.2109375 -0.351563,0.4101562 v 0.96093755 c 0,0.1640625 0,0.41015625 0.304688,0.41015625 0.08203,0 0.246093,-0.01171875 0.363281,-0.375 0.492187,0.3515625 1.019531,0.375 1.300781,0.375 1.570313,0 1.886719,-0.8203125 1.886719,-1.3007813 0,-1.0429687 -1.277344,-1.2539062 -1.605469,-1.3007812 z M 40.010545,-6.505 c 0,-0.3046875 -0.05859,-0.4101563 -0.398437,-0.4101563 H 37.80742 c -0.152343,0 -0.398437,0 -0.398437,0.3046875 0,0.3046875 0.234375,0.3046875 0.398437,0.3046875 h 1.511719 V 0.2215625 H 37.80742 c -0.152343,0 -0.398437,0 -0.398437,0.29296875 0,0.31640625 0.234375,0.31640625 0.398437,0.31640625 h 1.804688 c 0.328125,0 0.398437,-0.09375 0.398437,-0.41015625 z m 0,0" + style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + d="m -120.40541,22.885625 h 1.75781 c 1.38282,0 2.54297,-0.714844 2.54297,-1.875 0,-1.101563 -0.98437,-1.945313 -2.63672,-1.945313 h -4.16015 v 0.46875 h 1.07812 v 5.894532 h -1.07812 v 0.46875 c 0.375,-0.03516 1.35937,-0.03516 1.78125,-0.03516 0.43359,0 1.40625,0 1.78125,0.03516 v -0.46875 h -1.06641 z m 1.26563,-0.410156 h -1.32422 v -2.941407 h 1.33594 c 1.5,0 1.5,0.75 1.5,1.476563 0,0.703125 0,1.464844 -1.51172,1.464844 z m 7.96875,1.253906 c 0.21093,0 0.3164,0 0.3164,-0.269531 0,-0.316407 -0.0586,-1.042969 -0.5625,-1.535157 -0.36328,-0.363281 -0.89062,-0.539062 -1.58203,-0.539062 -1.59375,0 -2.46094,1.019531 -2.46094,2.273437 0,1.335938 0.9961,2.296875 2.60157,2.296875 1.57031,0 2.0039,-1.054687 2.0039,-1.21875 0,-0.1875 -0.1875,-0.1875 -0.23437,-0.1875 -0.17578,0 -0.19922,0.04687 -0.25781,0.210938 -0.21094,0.480469 -0.77344,0.796875 -1.41797,0.796875 -1.40625,0 -1.41797,-1.324219 -1.41797,-1.828125 z m -3.01172,-0.328125 c 0.0234,-0.398438 0.0352,-0.808594 0.23437,-1.136719 0.26953,-0.398437 0.66797,-0.515625 0.94922,-0.515625 1.17188,0 1.1836,1.300781 1.19531,1.652344 z m 5.68359,-0.855469 v -1.136719 l -1.66406,0.08203 v 0.46875 c 0.62109,0 0.69141,0 0.69141,0.386718 v 3.082032 h -0.69141 v 0.46875 c 0.35156,-0.01172 0.79687,-0.03516 1.26562,-0.03516 0.375,0 1.00782,0 1.3711,0.03516 v -0.46875 h -0.86719 V 23.6825 c 0,-0.691406 0.24609,-1.910156 1.24219,-1.910156 -0.0117,0.01172 -0.1875,0.175781 -0.1875,0.457031 0,0.410156 0.3164,0.609375 0.60937,0.609375 0.29297,0 0.60938,-0.210938 0.60938,-0.609375 0,-0.527344 -0.53906,-0.820313 -1.05469,-0.820313 -0.70312,0 -1.10156,0.503907 -1.32422,1.136719 z m 4.91895,-1.136719 -1.72266,0.08203 v 0.46875 c 0.58594,0 0.65625,0 0.65625,0.386718 v 3.082032 h -0.69141 v 0.46875 c 0.30469,-0.01172 0.79688,-0.03516 1.21875,-0.03516 0.29297,0 0.8086,0.02344 1.16016,0.03516 v -0.46875 h -0.62109 z m 0.10547,-1.652343 c 0,-0.445313 -0.36329,-0.785157 -0.77344,-0.785157 -0.4336,0 -0.78516,0.351563 -0.78516,0.785157 0,0.421875 0.35156,0.773437 0.78516,0.773437 0.41015,0 0.77344,-0.339844 0.77344,-0.773437 z m 6.251945,3.972656 c 0,-1.335938 -0.914059,-2.34375 -2.542969,-2.34375 -1.628906,0 -2.542966,1.019531 -2.542966,2.34375 0,1.230469 0.87891,2.226562 2.542966,2.226562 1.67578,0 2.542969,-1.007812 2.542969,-2.226562 z m -2.542969,1.828125 c -1.265626,0 -1.265626,-1.078125 -1.265626,-1.945313 0,-0.445312 0,-0.949218 0.16407,-1.289062 0.19922,-0.375 0.60937,-0.574219 1.101556,-0.574219 0.42187,0 0.83203,0.152344 1.05469,0.503906 0.21093,0.339844 0.21093,0.890625 0.21093,1.359375 0,0.867188 0,1.945313 -1.26562,1.945313 z m 7.347656,-0.09375 v 0.492187 l 1.828125,-0.05859 v -0.46875 c -0.621094,0 -0.691406,0 -0.691406,-0.386719 v -6.058594 l -1.757813,0.08203 v 0.46875 c 0.609375,0 0.679688,0 0.679688,0.386719 v 1.945313 c -0.492188,-0.386719 -1.007813,-0.457032 -1.335938,-0.457032 -1.453125,0 -2.507812,0.878907 -2.507812,2.285157 0,1.3125 0.925781,2.261718 2.390625,2.261718 0.609375,0 1.089844,-0.234375 1.394531,-0.492187 z m 0,-3.082031 v 2.484375 c -0.128906,0.1875 -0.539062,0.726562 -1.289062,0.726562 -1.21875,0 -1.21875,-1.195312 -1.21875,-1.898437 0,-0.480469 0,-1.019532 0.257812,-1.40625 0.292969,-0.410157 0.761719,-0.515625 1.066406,-0.515625 0.574219,0 0.972657,0.316406 1.183594,0.609375 z m 4.432617,-0.972657 -1.722656,0.08203 v 0.46875 c 0.585938,0 0.65625,0 0.65625,0.386718 v 3.082032 h -0.691406 v 0.46875 c 0.304687,-0.01172 0.796875,-0.03516 1.21875,-0.03516 0.292969,0 0.808594,0.02344 1.160156,0.03516 v -0.46875 h -0.621094 z m 0.105469,-1.652343 c 0,-0.445313 -0.363281,-0.785157 -0.773437,-0.785157 -0.433594,0 -0.785157,0.351563 -0.785157,0.785157 0,0.421875 0.351563,0.773437 0.785157,0.773437 0.410156,0 0.773437,-0.339844 0.773437,-0.773437 z m 4.435547,2.085937 c -0.175781,0.164063 -0.199219,0.363281 -0.199219,0.457031 0,0.445313 0.351563,0.632813 0.621094,0.632813 0.304688,0 0.621094,-0.210938 0.621094,-0.632813 0,-0.855468 -1.148438,-0.914062 -1.734375,-0.914062 -1.78125,0 -2.519531,1.148437 -2.519531,2.296875 0,1.324219 0.9375,2.273437 2.472656,2.273437 1.617187,0 1.910156,-1.160156 1.910156,-1.21875 0,-0.140625 -0.140625,-0.140625 -0.234375,-0.140625 -0.175781,0 -0.1875,0.01172 -0.234375,0.140625 -0.269531,0.632813 -0.738281,0.820313 -1.253906,0.820313 -1.382813,0 -1.382813,-1.464844 -1.382813,-1.921875 0,-0.5625 0,-1.851563 1.289063,-1.851563 0.351562,0 0.515625,0.02344 0.644531,0.05859 z m 0,0" + style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + d="m -96.74283,43.662969 c 0,-0.363282 -0.29296,-0.621094 -0.60937,-0.621094 -0.38672,0 -0.63281,0.304687 -0.63281,0.609375 0,0.375 0.30468,0.632812 0.62109,0.632812 0.375,0 0.62109,-0.304687 0.62109,-0.621093 z m 5.2295,0 c 0,-0.363282 -0.29297,-0.621094 -0.60938,-0.621094 -0.38672,0 -0.63281,0.304687 -0.63281,0.609375 0,0.375 0.30469,0.632812 0.62109,0.632812 0.375,0 0.6211,-0.304687 0.6211,-0.621093 z m 5.22949,0 c 0,-0.363282 -0.29297,-0.621094 -0.60938,-0.621094 -0.38672,0 -0.63281,0.304687 -0.63281,0.609375 0,0.375 0.30469,0.632812 0.62109,0.632812 0.375,0 0.6211,-0.304687 0.6211,-0.621093 z m 0,0" + style="fill:#fefefe;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + inkscape:current-layer="g2" + showgrid="false">

-

+

+

``` ### Action types ```@raw html -

-

+

+

``` ### TimeSpan types ```@raw html -

-

+

+

``` ### SpinSpan types ```@raw html -

-

+

+

``` \ No newline at end of file diff --git a/docs/src/explanation/lit-1-phantom.jl b/docs/src/explanation/lit-1-phantom.jl index 6cfc6fb66..540fcc287 100644 --- a/docs/src/explanation/lit-1-phantom.jl +++ b/docs/src/explanation/lit-1-phantom.jl @@ -1,6 +1,6 @@ # # Phantom -using KomaMRI # hide +using KomaMRI #hide # The first input argument that **KomaMRI** needs for simulating is the phantom. @@ -59,6 +59,22 @@ using KomaMRI # hide # To get an even better understanding on how it works, let's look at an example of a brain phantom: obj = brain_phantom2D() +# ```julia-repl +# Phantom{Float64} +# name: String "brain2D_axial" +# x: Array{Float64}((6506,)) [-0.084, -0.084, -0.084, -0.084, -0.084, -0.084, -0.084, -0.084, -0.084, -0.084 … 0.084, 0.084, 0.084, 0.084, 0.086, 0.086, 0.086, 0.086, 0.086, 0.086] +# y: Array{Float64}((6506,)) [-0.03, -0.028, -0.026, -0.024, -0.022, -0.02, -0.018, -0.016, -0.014, -0.012 … 0.006, 0.008, 0.01, 0.012, -0.008, -0.006, -0.004, -0.002, 0.0, 0.002] +# z: Array{Float64}((6506,)) [-0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 … 0.0, 0.0, 0.0, 0.0, -0.0, -0.0, -0.0, -0.0, 0.0, 0.0] +# ρ: Array{Float64}((6506,)) [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 … 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] +# T1: Array{Float64}((6506,)) [0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569 … 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569, 0.569] +# T2: Array{Float64}((6506,)) [0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329 … 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329, 0.329] +# T2s: Array{Float64}((6506,)) [0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058 … 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058, 0.058] +# Δw: Array{Float64}((6506,)) [-0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 … -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0] +# Dλ1: Array{Float64}((6506,)) [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 … 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +# Dλ2: Array{Float64}((6506,)) [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 … 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +# Dθ: Array{Float64}((6506,)) [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 … 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] +# motion: NoMotion{Float64} NoMotion{Float64}() +# ``` # You can visualize the **Phantom** struct using the [`plot_phantom_map`](@ref) function, # which is part of the **KomaMRIPlots** subdependency. This function plots the magnitude of a property for @@ -67,7 +83,7 @@ obj = brain_phantom2D() p1 = plot_phantom_map(obj, :T1; height=450) -#md savefig(p1, "../assets/doc-1-phantom.html") # hide +#md savefig(p1, "../assets/doc-1-phantom.html") #hide #jl display(p1) #md # ```@raw html @@ -75,11 +91,28 @@ p1 = plot_phantom_map(obj, :T1; height=450) #md # ``` # You can access and filter information for the all the field names of a **Phantom** using the dot notation: -obj.name -#- -obj.x -#- -obj.motion + +# ```julia-repl +# julia> obj.name +# "brain2D_axial" +# ``` + +# ```julia-repl +# julia> obj.x +# 6506-element Vector{Float64}: +# -0.084 +# -0.084 +# -0.084 +# ⋮ +# 0.086 +# 0.086 +# 0.086 +# ``` + +# ```julia-repl +# julia> obj.motion +# NoMotion{Float64}() +# ``` # ## Phantom Operations @@ -90,10 +123,10 @@ obj.motion # It is possible to access a subset of spins in a **Phantom** by slicing or indexing. The result will also be a # **Phantom** struct, allowing you to perform the same operations as you would with a full Phantom: -obj[1:1000] -p2 = plot_phantom_map(obj[1:1000], :T2 ; height=450) # hide +obj[1:2000] +p2 = plot_phantom_map(obj[1:1000], :T2 ; height=450) #hide -#md savefig(p2, "../assets/tut-5-phantom-subset.html") # hide +#md savefig(p2, "../assets/tut-5-phantom-subset.html") #hide #jl display(p2) #md # ```@raw html @@ -104,11 +137,11 @@ p2 = plot_phantom_map(obj[1:1000], :T2 ; height=450) # hide # In the same way, we can add two or more phantoms, resulting in another [`Phantom`](@ref) struct: obj2 = pelvis_phantom2D() -obj2.motion = MotionList(Translate(0.0, 0.0, -0.5, TimeRange(0.0))) +obj2.x .+= 0.1; obj.x.-= 0.1 #hide obj_sum = obj + obj2 -p3 = plot_phantom_map(obj_sum, :T1 ; height=450) # hide +p3 = plot_phantom_map(obj_sum, :T1 ; height=450) #hide -#md savefig(p3, "../assets/tut-5-phantom-sum.html") # hide +#md savefig(p3, "../assets/tut-5-phantom-sum.html") #hide #jl display(p3) #md # ```@raw html @@ -119,9 +152,28 @@ p3 = plot_phantom_map(obj_sum, :T1 ; height=450) # hide # Finally, multiplying a phantom by a scalar multiplies its proton density (`ρ`) by that amount: obj_mul = 3*obj -obj.ρ -#- -obj_mul.ρ + +# ```julia-repl +# julia> obj.ρ +# 6506-element Vector{Float64}: +# 1.0 +# 1.0 +# 1.0 +# ⋮ +# 1.0 +# 1.0 +# 1.0 +# +# julia> obj_mul.ρ +# 6506-element Vector{Float64}: +# 3.0 +# 3.0 +# 3.0 +# ⋮ +# 3.0 +# 3.0 +# 3.0 +# ``` # ## Phantom Storage and Sharing # Phantoms can be stored and shared thanks to our new [Phantom File Format](3-phantom-format.md). \ No newline at end of file diff --git a/docs/utils.jl b/docs/utils.jl index a78e510fc..6005042fc 100644 --- a/docs/utils.jl +++ b/docs/utils.jl @@ -65,8 +65,7 @@ function literate_doc_folder(input_folder, output_doc_section; lit_pattern="lit- input_folder; repo_root_url, preprocess=_link_example(filename_gen), - name=filename_gen, - execute=true + name=filename_gen ) Literate.script(tutorial_src, input_folder; name=filename_gen, repo_root_url) Literate.notebook(tutorial_src, input_folder; name=filename_gen, execute=false) From 5f0f8fe8a018e4d5a4de4f12f650b849e0b26d69 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Fri, 11 Oct 2024 17:10:07 +0200 Subject: [PATCH 7/8] Recover buildkite pipeline --- .buildkite/pipeline.yml | 70 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 0a0e22515..25aada17f 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -1,39 +1,39 @@ steps: - # - label: ":pipeline: Upload NoMotion Tests" - # env: - # TEST_GROUP: "nomotion" - # command: buildkite-agent pipeline upload .buildkite/runtests.yml - # agents: - # queue: "juliagpu" + - 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" + - label: ":pipeline: Upload Motion Tests" + env: + TEST_GROUP: "motion" + command: buildkite-agent pipeline upload .buildkite/runtests.yml + agents: + queue: "juliagpu" - # - label: ":pipeline: Launch Benchmarks" - # if: build.message !~ /skip benchmarks/ - # agents: - # queue: "juliagpu" - # plugins: - # - monorepo-diff#v1.0.1: - # diff: "git diff --name-only HEAD~1" - # interpolation: false - # watch: - # - path: - # - "KomaMRICore/src/**/*" - # - "KomaMRICore/ext/**/*" - # - "KomaMRICore/Project.toml" - # - "KomaMRIBase/src/**/*" - # - "KomaMRIBase/Project.toml" - # - "benchmarks/**/*" - # - ".buildkite/**/*" - # - ".github/workflows/Benchmark.yml" - # - "Project.toml" - # config: - # command: "buildkite-agent pipeline upload .buildkite/runbenchmarks.yml" - # agents: - # queue: "juliagpu" + - label: ":pipeline: Launch Benchmarks" + if: build.message !~ /skip benchmarks/ + agents: + queue: "juliagpu" + plugins: + - monorepo-diff#v1.0.1: + diff: "git diff --name-only HEAD~1" + interpolation: false + watch: + - path: + - "KomaMRICore/src/**/*" + - "KomaMRICore/ext/**/*" + - "KomaMRICore/Project.toml" + - "KomaMRIBase/src/**/*" + - "KomaMRIBase/Project.toml" + - "benchmarks/**/*" + - ".buildkite/**/*" + - ".github/workflows/Benchmark.yml" + - "Project.toml" + config: + command: "buildkite-agent pipeline upload .buildkite/runbenchmarks.yml" + agents: + queue: "juliagpu" From 402439b7bb47e5123dfafb6a1e9dca83a81853a6 Mon Sep 17 00:00:00 2001 From: Pablo Villacorta Aylagas Date: Thu, 17 Oct 2024 13:13:09 +0200 Subject: [PATCH 8/8] Solve `plot_phantom_map` bug for 2D and 1D phantoms --- KomaMRIBase/src/datatypes/Phantom.jl | 2 +- KomaMRIPlots/src/ui/DisplayFunctions.jl | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/KomaMRIBase/src/datatypes/Phantom.jl b/KomaMRIBase/src/datatypes/Phantom.jl index 5f155f28e..c804caeda 100644 --- a/KomaMRIBase/src/datatypes/Phantom.jl +++ b/KomaMRIBase/src/datatypes/Phantom.jl @@ -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 """ diff --git a/KomaMRIPlots/src/ui/DisplayFunctions.jl b/KomaMRIPlots/src/ui/DisplayFunctions.jl index d2300efdd..c2aeb29ac 100644 --- a/KomaMRIPlots/src/ui/DisplayFunctions.jl +++ b/KomaMRIPlots/src/ui/DisplayFunctions.jl @@ -1135,9 +1135,21 @@ function plot_phantom_map( l = Layout(;title=obj.name*": "*string(key)) if view_2d # 2D + function get_displayed_dims(v) + if sum(v) == 1 + idx = argmax(v)[1] + return [idx in [1, 3], idx in [1, 2], idx in [2,3]] + else + return v + end + end + # Layout config + dims = get_displayed_dims(KomaMRIBase.get_dims(obj)) + axis = ["x", "y", "z"][dims] + l[:xaxis] = attr( - title="x", + title=axis[1], range=[x0, xf], ticksuffix=" cm", backgroundcolor=plot_bgcolor, @@ -1146,7 +1158,7 @@ function plot_phantom_map( scaleanchor="y" ) l[:yaxis] = attr( - title="y", + title=axis[2], range=[x0, xf], ticksuffix=" cm", backgroundcolor=plot_bgcolor, @@ -1158,8 +1170,8 @@ function plot_phantom_map( # Add traces for i in 1:length(t) push!(traces, scattergl( - x=(x[:,i])*1e2, - y=(y[:,i])*1e2, + x=dims[1] ? (x[:,i])*1e2 : (y[:,i])*1e2, + y=dims[1] & dims[2] ? (y[:,i])*1e2 : (z[:,i])*1e2, mode="markers", marker=attr(color=getproperty(obj,key)*factor, showscale=colorbar,