99from __future__ import annotations
1010
1111from abc import ABC , abstractmethod
12- from typing import TYPE_CHECKING , Any , ClassVar , Generator , Union
12+ from typing import TYPE_CHECKING , Any , ClassVar , Generator
1313
1414from sigima .objects import ImageObj , SignalObj
1515
1616if TYPE_CHECKING :
1717 import pandas as pd
18+ from sigima .objects .scalar import GeometryResult , TableResult
1819
1920
2021class BaseResultAdapter (ABC ):
@@ -31,7 +32,7 @@ class BaseResultAdapter(ABC):
3132 META_PREFIX : ClassVar [str ] = ""
3233 SUFFIX : ClassVar [str ] = ""
3334
34- def __init__ (self , result : Any ) -> None :
35+ def __init__ (self , result : TableResult | GeometryResult ) -> None :
3536 self .result = result
3637
3738 def set_applicative_attr (self , key : str , value : Any ) -> None :
@@ -58,22 +59,14 @@ def get_applicative_attr(self, key: str, default: Any = None) -> Any:
5859 self .result .attrs [key ] = default
5960 return self .result .attrs .get (key , default )
6061
61- @abstractmethod
62- def to_dataframe (self ) -> "pd.DataFrame" :
63- """Convert the result to a pandas DataFrame.
64-
65- Returns:
66- DataFrame with columns as in self.headers, and optional 'roi_index' column.
67- """
68-
6962 @property
70- @abstractmethod
7163 def title (self ) -> str :
7264 """Get the title.
7365
7466 Returns:
7567 Title
7668 """
69+ return self .result .title
7770
7871 @property
7972 @abstractmethod
@@ -143,7 +136,7 @@ def label_contents(self) -> tuple[tuple[int, str], ...]:
143136 """
144137 return tuple (enumerate (self .headers ))
145138
146- def add_to (self , obj : Union [ SignalObj , ImageObj ] ) -> None :
139+ def add_to (self , obj : SignalObj | ImageObj ) -> None :
147140 """Add result to object metadata.
148141
149142 Args:
@@ -153,7 +146,7 @@ def add_to(self, obj: Union[SignalObj, ImageObj]) -> None:
153146 metadata_key = f"{ self .META_PREFIX } { self .title } { self .SUFFIX } "
154147 obj .metadata [metadata_key ] = self .result .to_dict ()
155148
156- def remove_from (self , obj : Union [ SignalObj , ImageObj ] ) -> None :
149+ def remove_from (self , obj : SignalObj | ImageObj ) -> None :
157150 """Remove result from object metadata.
158151
159152 Args:
@@ -164,7 +157,7 @@ def remove_from(self, obj: Union[SignalObj, ImageObj]) -> None:
164157 obj .metadata .pop (metadata_key , None )
165158
166159 @classmethod
167- def remove_all_from (cls , obj : Union [ SignalObj , ImageObj ] ) -> None :
160+ def remove_all_from (cls , obj : SignalObj | ImageObj ) -> None :
168161 """Remove all results of this type from object metadata.
169162
170163 Args:
@@ -189,7 +182,7 @@ def match(cls, key: str, _value: Any) -> bool:
189182
190183 @classmethod
191184 @abstractmethod
192- def from_metadata_entry (cls , obj : Union [ SignalObj , ImageObj ] , key : str ):
185+ def from_metadata_entry (cls , obj : SignalObj | ImageObj , key : str ):
193186 """Create a result adapter from a metadata entry.
194187
195188 Args:
@@ -204,7 +197,9 @@ def from_metadata_entry(cls, obj: Union[SignalObj, ImageObj], key: str):
204197 """
205198
206199 @classmethod
207- def iterate_from_obj (cls , obj : Union [SignalObj , ImageObj ]) -> Generator :
200+ def iterate_from_obj (
201+ cls , obj : SignalObj | ImageObj
202+ ) -> Generator ["BaseResultAdapter" , None , None ]:
208203 """Iterate over results stored in an object's metadata.
209204
210205 Args:
@@ -220,3 +215,64 @@ def iterate_from_obj(cls, obj: Union[SignalObj, ImageObj]) -> Generator:
220215 except (ValueError , TypeError ):
221216 # Skip invalid entries
222217 pass
218+
219+ def to_dataframe (self ) -> "pd.DataFrame" :
220+ """Convert the geometry result to a pandas DataFrame.
221+
222+ Returns:
223+ DataFrame with columns as in self.headers, and optional 'roi_index' column.
224+ """
225+ return self .result .to_dataframe ()
226+
227+ def to_html (
228+ self ,
229+ obj = None ,
230+ visible_headers : list [str ] = None ,
231+ transpose_single_row : bool = True ,
232+ ** kwargs ,
233+ ) -> str :
234+ """Convert the result to HTML format.
235+
236+ Args:
237+ obj: Optional SignalObj or ImageObj for ROI title extraction
238+ visible_headers: Optional list of headers to show (filters columns)
239+ transpose_single_row: If True, transpose the table when there's only one row
240+ **kwargs: Additional arguments passed to DataFrame.to_html()
241+
242+ Returns:
243+ HTML representation of the result
244+ """
245+ # Use visible headers from display preferences if not specified
246+ if visible_headers is None :
247+ visible_headers = self .result .get_visible_headers ()
248+
249+ return self .result .to_html (
250+ obj = obj ,
251+ visible_headers = visible_headers ,
252+ transpose_single_row = transpose_single_row ,
253+ ** kwargs ,
254+ )
255+
256+ def get_display_preferences (self ) -> dict [str , bool ]:
257+ """Get display preferences.
258+
259+ Returns:
260+ Dictionary mapping header names to visibility (True=visible, False=hidden)
261+ """
262+ return self .result .get_display_preferences ()
263+
264+ def set_display_preferences (self , preferences : dict [str , bool ]) -> None :
265+ """Set display preferences.
266+
267+ Args:
268+ preferences: Dictionary mapping header names to visibility
269+ """
270+ self .result .set_display_preferences (preferences )
271+
272+ def get_visible_headers (self ) -> list [str ]:
273+ """Get list of currently visible headers based on display preferences.
274+
275+ Returns:
276+ List of header names that should be displayed
277+ """
278+ return self .result .get_visible_headers ()
0 commit comments