From d29191bceddc3061b3b8a126fefeb9fb99d9cc03 Mon Sep 17 00:00:00 2001
From: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk>
Date: Thu, 15 Feb 2024 16:17:10 +0000
Subject: [PATCH] add scanner_constraints!

---
 src/all_building_blocks/building_blocks.jl |  2 +-
 src/variables.jl                           | 36 ++++++++++++++++++++--
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/src/all_building_blocks/building_blocks.jl b/src/all_building_blocks/building_blocks.jl
index 1d61096..79c4b94 100644
--- a/src/all_building_blocks/building_blocks.jl
+++ b/src/all_building_blocks/building_blocks.jl
@@ -1,7 +1,7 @@
 module BuildingBlocks
 import LinearAlgebra: norm
 import ..BaseBuildingBlocks: BaseBuildingBlock, events, waveform_sequence
-import ...Variables: VariableType, duration, make_generic, get_pulse, get_readout
+import ...Variables: VariableType, duration, make_generic, get_pulse, get_readout, scanner_constraints!
 import ...Components: BaseComponent, DelayedEvent, RFPulseComponent, ReadoutComponent
 
 """
diff --git a/src/variables.jl b/src/variables.jl
index 2979512..d10a4e2 100644
--- a/src/variables.jl
+++ b/src/variables.jl
@@ -13,8 +13,8 @@ In addition this defines:
 """
 module Variables
 import JuMP: @constraint, @variable, Model, @objective, objective_function, value, AbstractJuMPScalar
-import ..Scanners: gradient_strength, slew_rate
-import ..BuildSequences: global_model
+import ..Scanners: gradient_strength, slew_rate, Scanner
+import ..BuildSequences: global_model, global_scanner
 
 """
 Parent type of all components, building block, and sequences that form an MRI sequence.
@@ -323,4 +323,36 @@ Returns a generic version of the `BaseSequence`, `BaseBuildingBlock`, or `BaseCo
 """
 function make_generic end
 
+
+"""
+    scanner_constraints!(block)
+
+Constraints [`gradient_strength`](@ref) and [`slew_rate`](@ref) to be less than the [`global_scanner`](@ref) maximum.
+"""
+function scanner_constraints!(bb::AbstractBlock)
+    try
+        global_scanner()
+    catch e
+        return
+    end
+    for f in (gradient_strength, slew_rate)
+        try
+            value = gradient_strength(bb)
+        catch e
+            if e isa VariableNotAvailable
+                continue
+            else
+                rethrow()
+            end
+        end
+        if value isa AbstractVector
+            for v in value
+                @constraint global_model() v <= f(global_scanner())
+            end
+        else
+            @constraint global_model() value <= f(global_scanner())
+        end
+    end
+end
+
 end
\ No newline at end of file
-- 
GitLab