From 629755f91398fa03e7f90903eabc5776c1b9dd57 Mon Sep 17 00:00:00 2001
From: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk>
Date: Wed, 14 Feb 2024 16:55:02 +0000
Subject: [PATCH] Implement main sequence type

---
 src/all_sequences/all_sequences.jl |  5 ++++
 src/all_sequences/sequences.jl     | 46 ++++++++++++++++++++++++++++++
 src/container_blocks.jl            |  2 +-
 3 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100644 src/all_sequences/sequences.jl

diff --git a/src/all_sequences/all_sequences.jl b/src/all_sequences/all_sequences.jl
index 3dade41..e69ed23 100644
--- a/src/all_sequences/all_sequences.jl
+++ b/src/all_sequences/all_sequences.jl
@@ -1,3 +1,8 @@
 module AllSequences
+include("base_sequences.jl")
+include("sequences.jl")
+
+import .BaseSequences: BaseSequence, nrepeat
+import .Sequences: Sequence
 
 end
\ No newline at end of file
diff --git a/src/all_sequences/sequences.jl b/src/all_sequences/sequences.jl
new file mode 100644
index 0000000..7028276
--- /dev/null
+++ b/src/all_sequences/sequences.jl
@@ -0,0 +1,46 @@
+module Sequences
+import StaticArrays: SVector
+import ..BaseSequences: ContainerBlock, BaseSequence, nrepeat
+import ...Variables: get_free_variable, TR, VariableType
+import ...BuildingBlocks: WaitBlock
+
+"""
+    Sequence(blocks; TR=:min, nrepeat=0)
+    Sequence(blocks...; TR=:min, nrepeat=0)
+
+Defines an MRI sequence from a vector of building blocks.
+
+## Arguments
+- [`nrepeat`](@ref): how often the sequence will repeat itself (keep at default of 0 to repeat indefinetely).
+- [`TR`](@ref): how long between repeats in ms (defaults to the duration of the sequence). Can be set to `nothing` to be a free variable.
+"""
+struct Sequence{N} <: BaseSequence{N}
+    blocks :: SVector{N, <:ContainerBlock}
+    TR :: Float64
+    nrepeat :: Int
+end
+
+function Sequence(blocks::AbstractVector; TR=:min, nrepeat=0)
+    if TR == :min
+        TR = sum(duration, blocks; init=0.)
+    end
+    return sequence(SVector{length(blocks)}(to_block.(blocks)), get_free_variable(TR), nrepeat)
+end
+
+Sequence(blocks...; kwargs...) = Sequence([blocks...]; kwargs...)
+
+
+"""
+    to_block(block_like)
+
+Converst object into something that can be included in the sequence:
+- :min/:max/number/variable/nothing => [`WaitBlock`](@ref).
+- `building_block` or `sequence` => no change.
+"""
+to_block(cb::ContainerBlock) = cb
+to_block(s::Symbol) = to_block(Val(s))
+to_block(s::Union{VariableType, Nothing, Val{:min}, Val{:max}}) = WaitBlock(s)
+
+
+
+end
\ No newline at end of file
diff --git a/src/container_blocks.jl b/src/container_blocks.jl
index 37b5b37..e20828f 100644
--- a/src/container_blocks.jl
+++ b/src/container_blocks.jl
@@ -2,7 +2,7 @@ module ContainerBlocks
 import ..Variables: AbstractBlock, duration, effective_time
 
 """
-Parent type for `BuildingBlock` or `AbstractSequence`, i.e., any building block that contains other MRI components/blocks.
+Parent type for `BuildingBlock` or `BaseSequence`, i.e., any building block that contains other MRI components/blocks.
 
 Iterate over them to get the individual components.
 """
-- 
GitLab