Skip to content

Commit 4913215

Browse files
peterhollendergoogle-labs-jules[bot]arhowe00
authored
Add pandas table representation for Protocols (#360)
* feat: Add to_table method to Protocol class This commit introduces a `to_table` method to the `Protocol` class, which returns a Pandas DataFrame summarizing the protocol's parameters. This is useful for displaying protocol information in a structured format. - Added `to_table` method to `Protocol` class. - Added `get_table` methods to `FocalPattern`, `SimSetup`, `DelayMethod`, `ApodizationMethod`, and `SegmentationMethod` classes and their subclasses. - Added tests for the new `to_table` method. - Added an example of the table output to the `to_table` method's docstring. * touch up to_table * add param constrains and target constraints for #360 * switch `get_table` to `to_table` #360 There was a mix of `get_table` and `to_table` already driving `protocol.to_table`. Since the `get_table` methods were all lower-level, I've switched everything to be `to_table`. * Update unit test #360 * Revert some seg_method tests #360 * Adjust import order * Fix `to_table` example output The example output table was not accurate * Fix ref_material not being referenced * Fix Uniform display typo #361 --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Andrew Howe <arhowe00@gmail.com>
1 parent 82edab1 commit 4913215

18 files changed

Lines changed: 250 additions & 2 deletions

File tree

src/openlifu/bf/apod_methods/apodmethod.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Any
66

77
import numpy as np
8+
import pandas as pd
89
import xarray as xa
910

1011
from openlifu.bf import apod_methods
@@ -30,3 +31,12 @@ def from_dict(d):
3031
module_dict = apod_methods.__dict__
3132
class_constructor = module_dict[short_classname]
3233
return class_constructor(**d)
34+
35+
@abstractmethod
36+
def to_table(self) -> pd.DataFrame:
37+
"""
38+
Get a table of the apodization method parameters
39+
40+
:returns: Pandas DataFrame of the apodization method parameters
41+
"""
42+
pass

src/openlifu/bf/apod_methods/maxangle.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Annotated
55

66
import numpy as np
7+
import pandas as pd
78
import xarray as xa
89

910
from openlifu.bf.apod_methods import ApodizationMethod
@@ -36,3 +37,13 @@ def calc_apodization(self, arr: Transducer, target: Point, params: xa.Dataset, t
3637
apod = np.zeros(arr.numelements())
3738
apod[angles <= self.max_angle] = 1
3839
return apod
40+
41+
def to_table(self) -> pd.DataFrame:
42+
"""
43+
Get a table of the apodization method parameters
44+
45+
:returns: Pandas DataFrame of the apodization method parameters
46+
"""
47+
records = [{"Name": "Type", "Value": "Max Angle", "Unit": ""},
48+
{"Name": "Max Angle", "Value": self.max_angle, "Unit": self.units}]
49+
return pd.DataFrame.from_records(records)

src/openlifu/bf/apod_methods/piecewiselinear.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Annotated
55

66
import numpy as np
7+
import pandas as pd
78
import xarray as xa
89

910
from openlifu.bf.apod_methods import ApodizationMethod
@@ -46,3 +47,16 @@ def calc_apodization(self, arr: Transducer, target: Point, params: xa.Dataset, t
4647
f = ((self.zero_angle - angles) / (self.zero_angle - self.rolloff_angle))
4748
apod = np.maximum(0, np.minimum(1, f))
4849
return apod
50+
51+
def to_table(self) -> pd.DataFrame:
52+
"""
53+
Get a table of the apodization method parameters
54+
55+
:returns: Pandas DataFrame of the apodization method parameters
56+
"""
57+
records = [
58+
{"Name": "Type", "Value": "Piecewise-Linear", "Unit": ""},
59+
{"Name": "Zero Angle", "Value": self.zero_angle, "Unit": self.units},
60+
{"Name": "Rolloff Angle", "Value": self.rolloff_angle, "Unit": self.units},
61+
]
62+
return pd.DataFrame.from_records(records)

src/openlifu/bf/apod_methods/uniform.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Annotated
55

66
import numpy as np
7+
import pandas as pd
78
import xarray as xa
89

910
from openlifu.bf.apod_methods import ApodizationMethod
@@ -19,3 +20,13 @@ class Uniform(ApodizationMethod):
1920

2021
def calc_apodization(self, arr: Transducer, target: Point, params: xa.Dataset, transform:np.ndarray | None=None):
2122
return np.full(arr.numelements(), self.value)
23+
24+
def to_table(self):
25+
"""
26+
Get a table of the apodization method parameters
27+
28+
:returns: Pandas DataFrame of the apodization method parameters
29+
"""
30+
records = [{"Name": "Type", "Value": "Uniform", "Unit": ""},
31+
{"Name": "Value", "Value": self.value, "Unit": ""}]
32+
return pd.DataFrame.from_records(records)

src/openlifu/bf/delay_methods/delaymethod.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from dataclasses import dataclass
55

66
import numpy as np
7+
import pandas as pd
78
import xarray as xa
89

910
from openlifu.bf import delay_methods
@@ -29,3 +30,12 @@ def from_dict(d):
2930
module_dict = delay_methods.__dict__
3031
class_constructor = module_dict[short_classname]
3132
return class_constructor(**d)
33+
34+
@abstractmethod
35+
def to_table(self) -> pd.DataFrame:
36+
"""
37+
Get a table of the delay method parameters
38+
39+
:returns: Pandas DataFrame of the delay method parameters
40+
"""
41+
pass

src/openlifu/bf/delay_methods/direct.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Annotated
55

66
import numpy as np
7+
import pandas as pd
78
import xarray as xa
89

910
from openlifu.bf.delay_methods import DelayMethod
@@ -35,3 +36,13 @@ def calc_delays(self, arr: Transducer, target: Point, params: xa.Dataset | None=
3536
tof = dists / c
3637
delays = max(tof) - tof
3738
return delays
39+
40+
def to_table(self) -> pd.DataFrame:
41+
"""
42+
Get a table of the delay method parameters
43+
44+
:returns: Pandas DataFrame of the delay method parameters
45+
"""
46+
records = [{"Name": "Type", "Value": "Direct", "Unit": ""},
47+
{"Name": "Default Sound Speed", "Value": self.c0, "Unit": "m/s"}]
48+
return pd.DataFrame.from_records(records)

src/openlifu/bf/focal_patterns/focal_pattern.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from dataclasses import dataclass
55
from typing import Annotated
66

7+
import pandas as pd
8+
79
from openlifu.bf import focal_patterns
810
from openlifu.geo import Point
911
from openlifu.util.annotations import OpenLIFUFieldData
@@ -72,3 +74,12 @@ def from_dict(d):
7274
module_dict = focal_patterns.__dict__
7375
class_constructor = module_dict[short_classname]
7476
return class_constructor(**d)
77+
78+
@abstractmethod
79+
def to_table(self) -> pd.DataFrame:
80+
"""
81+
Get a table of the focal pattern parameters
82+
83+
:returns: Pandas DataFrame of the focal pattern parameters
84+
"""
85+
pass

src/openlifu/bf/focal_patterns/single.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from dataclasses import dataclass
44

5+
import pandas as pd
6+
57
from openlifu.bf.focal_patterns import FocalPattern
68
from openlifu.geo import Point
79

@@ -29,3 +31,13 @@ def num_foci(self):
2931
:returns: Number of foci (1)
3032
"""
3133
return 1
34+
35+
def to_table(self) -> pd.DataFrame:
36+
"""
37+
Get a table of the focal pattern parameters
38+
39+
:returns: Pandas DataFrame of the focal pattern parameters
40+
"""
41+
records = [{"Name": "Type", "Value": "Single Point", "Unit": ""},
42+
{"Name": "Target Pressure", "Value": self.target_pressure, "Unit": self.units}]
43+
return pd.DataFrame.from_records(records)

src/openlifu/bf/focal_patterns/wheel.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Annotated
55

66
import numpy as np
7+
import pandas as pd
78

89
from openlifu.bf.focal_patterns import FocalPattern
910
from openlifu.geo import Point
@@ -70,3 +71,18 @@ def num_foci(self) -> int:
7071
:returns: Number of foci
7172
"""
7273
return int(self.center) + self.num_spokes
74+
75+
def to_table(self) -> pd.DataFrame:
76+
"""
77+
Get a table of the focal pattern parameters
78+
79+
:returns: Pandas DataFrame of the focal pattern parameters
80+
"""
81+
records = [
82+
{"Name": "Type", "Value": "Wheel", "Unit": ""},
83+
{"Name": "Target Pressure", "Value": self.target_pressure, "Unit": self.units},
84+
{"Name": "Center", "Value": self.center, "Unit": ""},
85+
{"Name": "Number of Spokes", "Value": self.num_spokes, "Unit": ""},
86+
{"Name": "Spoke Radius", "Value": self.spoke_radius, "Unit": self.distance_units},
87+
]
88+
return pd.DataFrame.from_records(records)

src/openlifu/bf/pulse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def calc_time(self, dt: float):
5151
"""
5252
return np.arange(0, self.duration, dt)
5353

54-
def get_table(self):
54+
def to_table(self) -> pd.DataFrame:
5555
"""
5656
Get a table of the pulse parameters
5757

0 commit comments

Comments
 (0)