From ccc52e8b917814c0ba36efc17da81374b1147ec2 Mon Sep 17 00:00:00 2001
From: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk>
Date: Fri, 26 Jan 2024 14:27:05 +0000
Subject: [PATCH] Add concrete versions of instantaneous gradients/pulses

---
 src/gradients/instant_gradients.jl | 19 +++++++++++++++----
 src/pulses/instant_pulses.jl       | 22 +++++++++++++++++-----
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/gradients/instant_gradients.jl b/src/gradients/instant_gradients.jl
index e6e782c..ff8cd6a 100644
--- a/src/gradients/instant_gradients.jl
+++ b/src/gradients/instant_gradients.jl
@@ -2,7 +2,7 @@ module InstantGradients
 import JuMP: @constraint, @variable, VariableRef
 import ...BuildingBlocks: BuildingBlock, properties, BuildingBlockPlaceholder, set_simple_constraints!, duration
 import ...SequenceBuilders: SequenceBuilder, owner_model, start_time
-import ...ConcreteBlocks: to_concrete_block
+import ...ConcreteBlocks: to_concrete_block, AbstractConcreteBlock
 import ..IntegrateGradients: qval, bval
 
 """
@@ -21,7 +21,7 @@ This is a [`BuildingBlock`](@ref) for the [`SequenceBuilder`](@ref).
 struct InstantGradientBlock <: BuildingBlock
     builder::SequenceBuilder
     orientation :: Any
-    qval :: Union{VariableRef, Number}
+    qval :: VariableRef
 end
 
 InstantGradientBlock(; kwargs...) = BuildingBlockPlaceholder{InstantGradientBlock}(; kwargs...)
@@ -43,9 +43,20 @@ bval(instant::InstantGradientBlock) = 0.
 duration(instant::InstantGradientBlock) = 0.
 properties(::Type{<:InstantGradientBlock}) = [qval]
 
+"""
+    ConcreteInstantGradient(orientation, qval)
+
+Instantaneous MR gradient with no free variables.
+
+See [`InstantGradientBlock`](@ref) for a version where [`qval`](@ref) is variable.
+"""
+struct ConcreteInstantGradient <: AbstractConcreteBlock
+    orientation :: Any
+    qval :: Number
+end
 
-function to_concrete_block(builder::SequenceBuilder, block::InstantGradientBlock)
-    InstantGradientBlock(builder, block.orientation, value(qval(block)))
+function to_concrete_block(block::InstantGradientBlock)
+    return ConcreteInstantGradient(block.orientation, value(qval(block)))
 end
 
 
diff --git a/src/pulses/instant_pulses.jl b/src/pulses/instant_pulses.jl
index 71c26ae..0c018b1 100644
--- a/src/pulses/instant_pulses.jl
+++ b/src/pulses/instant_pulses.jl
@@ -2,13 +2,13 @@ module InstantPulses
 import JuMP: @constraint, @variable, VariableRef, value
 import ...BuildingBlocks: BuildingBlock, properties, BuildingBlockPlaceholder, set_simple_constraints!, duration
 import ...SequenceBuilders: SequenceBuilder, owner_model, start_time
-import ...ConcreteBlocks: to_concrete_block
+import ...ConcreteBlocks: to_concrete_block, AbstractConcreteBlock
 import ..Properties: flip_angle, phase
 
 struct InstantRFPulseBlock <: BuildingBlock
     builder :: SequenceBuilder
-    flip_angle :: Union{VariableRef, Number}
-    phase :: Union{VariableRef, Number}
+    flip_angle :: VariableRef
+    phase :: VariableRef
 end
 
 InstantRFPulseBlock(; kwargs...) = BuildingBlockPlaceholder{InstantRFPulseBlock}(; kwargs...)
@@ -30,8 +30,20 @@ duration(instant::InstantRFPulseBlock) = 0.
 properties(::Type{<:InstantRFPulseBlock}) = [flip_angle, phase]
 
 
-function to_concrete_block(builder::SequenceBuilder, block::InstantRFPulseBlock)
-    return InstantRFPulseBlock(builder, value(flip_angle(block)), value(phase(block)))
+"""
+    ConcreteInstantRFPulse(flip_angle, phase)
+
+Instantaneous RF pulse with no free variables.
+
+See [`InstantRFPulseBlock`](@ref) for a version where [`flip_angle`](@ref) and [`phase`](@ref) are variables.
+"""
+struct ConcreteInstantRFPulse <: AbstractConcreteBlock
+    flip_angle :: Number
+    phase :: Number
+end
+
+function to_concrete_block(block::InstantRFPulseBlock)
+    return ConcreteInstantRFPulse(value(flip_angle(block)), value(phase(block)))
 end
 
 end
\ No newline at end of file
-- 
GitLab