Skip to content

Commit d8f8ed1

Browse files
committed
wip 2
1 parent ee94e6f commit d8f8ed1

File tree

6 files changed

+32
-14
lines changed

6 files changed

+32
-14
lines changed

db_dvc.dvc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
outs:
2-
- md5: 4e002abfa508c89a5c7afdff8c3c61a1.dir
2+
- md5: b61cbb96c629b2ea7130c5a06166975e.dir
33
nfiles: 257
44
hash: md5
55
path: db_dvc
6-
size: 933884330
6+
size: 933883287

notebooks/test_solution_analysis.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# ---
1414
from __future__ import annotations
1515

16+
import numpy as np
17+
1618
from openlifu.bf import Pulse, Sequence, apod_methods, focal_patterns
1719
from openlifu.geo import Point
1820
from openlifu.plan import Protocol
@@ -27,7 +29,7 @@
2729
focal_pattern = focal_patterns.SinglePoint(target_pressure=1.2e6)
2830
focal_pattern = focal_patterns.Wheel(center=False, spoke_radius=5, num_spokes=3, target_pressure=1.2e6)
2931
apod_method = apod_methods.MaxAngle(30)
30-
sim_setup = SimSetup(x_extent=[-30,30], y_extent=[-30,30], z_extent=[-4,70])
32+
sim_setup = SimSetup(x_extent=(-30,30), y_extent=(-30,30), z_extent=(-4,70))
3133
protocol = Protocol(
3234
id='test_protocol',
3335
name='Test Protocol',
@@ -37,7 +39,8 @@
3739
apod_method=apod_method,
3840
sim_setup=sim_setup)
3941

40-
target = Point(position=(0,0,50), units="mm", radius=2)
42+
target = Point(position=np.array([0, 0, 50]), units="mm", radius=2)
43+
# You can't assign kerf as 0.5 because it's an int
4144
trans = Transducer.gen_matrix_array(nx=8, ny=8, pitch=4, kerf=0.5, id="m3", name="openlifu", impulse_response=1e6/10)
4245
# -
4346

@@ -48,12 +51,14 @@
4851
scale=True)
4952

5053
pc = {"MI":ParameterConstraint('<', 1.8, 1.85), "TIC":ParameterConstraint('<', 2.0), 'global_isppa_Wcm2':ParameterConstraint('within', error_value=(49, 190))}
51-
scaled_analysis.to_table(constraints=pc).set_index('Param')[['Value', 'Units', 'Status']]
54+
if scaled_analysis is not None:
55+
scaled_analysis.to_table(constraints=pc).set_index('Param')[['Value', 'Units', 'Status']]
5256

5357
protocol = Protocol.from_file('../tests/resources/example_db/protocols/example_protocol/example_protocol.json')
5458
solution, sim_res, analysis = protocol.calc_solution(
5559
target=target,
5660
transducer=trans,
5761
simulate=True,
5862
scale=True)
59-
analysis.to_table().set_index('Param')[['Value', 'Units', 'Status']]
63+
if analysis is not None:
64+
analysis.to_table().set_index('Param')[['Value', 'Units', 'Status']]

src/openlifu/plan/param_constraint.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from dataclasses import dataclass
44
from typing import Annotated, Literal, Tuple
55

6-
from openlifu.util.dict_conversion import DictMixin
76
from openlifu.util.annotations import OpenLIFUFieldData
7+
from openlifu.util.dict_conversion import DictMixin
88

99
PARAM_STATUS_SYMBOLS = {
1010
"ok": "✅",
@@ -27,13 +27,19 @@ def __post_init__(self):
2727
if self.warning_value is None and self.error_value is None:
2828
raise ValueError("At least one of warning_value or error_value must be set")
2929
if self.operator in ['within','inside','outside','outside_inclusive']:
30-
if self.warning_value is not None:
31-
if not isinstance(self.warning_value, tuple) or len(self.warning_value) != 2 or (self.warning_value[0] >= self.warning_value[1]):
32-
raise ValueError("Warning value must be a sorted tuple of two numbers")
30+
if self.warning_value is not None and (
31+
not isinstance(self.warning_value, tuple) or
32+
len(self.warning_value) != 2 or
33+
self.warning_value[0] >= self.warning_value[1]
34+
):
35+
raise ValueError("Warning value must be a sorted tuple of two numbers")
3336

34-
if self.error_value is not None:
35-
if not isinstance(self.error_value, tuple) or len(self.error_value) != 2 or not (self.error_value[0] >= self.error_value[1]):
36-
raise ValueError("Error value must be a sorted tuple of two numbers")
37+
if self.error_value is not None and (
38+
not isinstance(self.error_value, tuple) or
39+
len(self.error_value) != 2 or
40+
self.error_value[0] >= self.error_value[1]
41+
):
42+
raise ValueError("Error value must be a sorted tuple of two numbers")
3743
elif self.operator in ['<','<=','>','>=']:
3844
if self.warning_value is not None and not isinstance(self.warning_value, (int, float)):
3945
raise ValueError("Warning value must be a single value")

src/openlifu/plan/solution.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def num_foci(self) -> int:
9999
def analyze(self,
100100
transducer: Transducer,
101101
options: SolutionAnalysisOptions = SolutionAnalysisOptions(),
102-
param_constraints: Dict[str,ParameterConstraint] = {}) -> SolutionAnalysis:
102+
param_constraints: Dict[str,ParameterConstraint] | None = None) -> SolutionAnalysis:
103103
"""Analyzes the treatment solution.
104104
105105
Args:
@@ -108,6 +108,9 @@ def analyze(self,
108108
109109
Returns: A struct containing the results of the analysis.
110110
"""
111+
# Avoid using a mutable default argument ({}); it can lead to unexpected shared state across function calls. Use None and initialize inside the function instead.
112+
if param_constraints is None:
113+
param_constraints = {}
111114
solution_analysis = SolutionAnalysis()
112115

113116
if transducer.id != self.transducer_id:

src/openlifu/plan/solution_analysis.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
import pandas as pd
99
import xarray as xa
1010

11+
from openlifu.plan.param_constraint import PARAM_STATUS_SYMBOLS, ParameterConstraint
1112
from openlifu.util.annotations import OpenLIFUFieldData
1213
from openlifu.util.dict_conversion import DictMixin
1314

1415
DEFAULT_ORIGIN = np.zeros(3)
1516

17+
# We might have some redundancies here to fix later, but it should be easy to
18+
# resolve these things
1619
PARAM_FORMATS = {
1720
"mainlobe_pnp_MPa": ["max", "0.3f", "MPa", "Mainlobe Peak Negative Pressure"],
1821
"mainlobe_isppa_Wcm2": ["max", "0.3f", "W/cm^2", "Mainlobe I_SPPA"],

tests/test_solution.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def example_transducer() -> Transducer:
2020
return Transducer(
2121
id="trans_456",
2222
name="Test Transducer",
23+
# I'm getting a type mismatch here. Currently, elements is a Tuple of a single Element. I think you should change it to a list of elements, but I don't know if this will affect the codebase in many places (@ebrahimebrahim, any thoughts?); TODO: fix
2324
elements=[
2425
Element(index=1, x=-14, y=-14, units="m"),
2526
Element(index=2, x=-2, y=-2, units="m"),

0 commit comments

Comments
 (0)