[ENH]: Improve Marker interface #477
30 changed files with 72 additions and 71 deletions
1
docs/changes/newsfragments/477.enh
Normal file
1
docs/changes/newsfragments/477.enh
Normal file
|
|
@ -0,0 +1 @@
|
|||
Improve ``Marker`` interface and implementations by `Synchon Mandal`_
|
||||
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
|
|
||||
from abc import ABC, abstractmethod
|
||||
from copy import deepcopy
|
||||
from typing import Any, Optional, Union
|
||||
from typing import Any, ClassVar, Optional, Union
|
||||
|
||||
from ..pipeline import PipelineStepMixin, UpdateMetaMixin
|
||||
from ..typing import StorageLike
|
||||
from ..typing import MarkerInOutMappings, StorageLike
|
||||
from ..utils import logger, raise_error
|
||||
|
||||
|
||||
|
|
@ -17,9 +17,9 @@ __all__ = ["BaseMarker"]
|
|||
|
||||
|
||||
class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
|
||||
"""Abstract base class for all markers.
|
||||
"""Abstract base class for marker.
|
||||
|
||||
For every interface that is required, one needs to provide a concrete
|
||||
For every marker, one needs to provide a concrete
|
||||
implementation of this abstract class.
|
||||
|
||||
Parameters
|
||||
|
|
@ -34,12 +34,14 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
|
|||
Raises
|
||||
------
|
||||
AttributeError
|
||||
If the marker does not have `_MARKER_INOUT_MAPPINGS` attribute.
|
||||
If the marker does not have ``_MARKER_INOUT_MAPPINGS`` attribute.
|
||||
ValueError
|
||||
If required input data type(s) is(are) not found.
|
||||
|
||||
"""
|
||||
|
||||
_MARKER_INOUT_MAPPINGS: ClassVar[MarkerInOutMappings]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
on: Optional[Union[list[str], str]] = None,
|
||||
|
|
@ -105,8 +107,8 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
|
|||
"""
|
||||
return list(self._MARKER_INOUT_MAPPINGS.keys())
|
||||
|
||||
def get_output_type(self, input_type: str, output_feature: str) -> str:
|
||||
"""Get output type.
|
||||
def storage_type(self, input_type: str, output_feature: str) -> str:
|
||||
"""Get storage type for a feature.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -172,7 +174,7 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
|
|||
The storage class, for example, SQLiteFeatureStorage.
|
||||
|
||||
"""
|
||||
output_type_ = self.get_output_type(type_, feature)
|
||||
output_type_ = self.storage_type(type_, feature)
|
||||
logger.debug(f"Storing {output_type_} in {storage}")
|
||||
storage.store(kind=output_type_, **out)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test HurstExponent get_output_type()."""
|
||||
assert "vector" == HurstExponent(
|
||||
parcellation=PARCELLATION
|
||||
).get_output_type(input_type="BOLD", output_feature="complexity")
|
||||
def test_storage_type() -> None:
|
||||
"""Test HurstExponent storage_type."""
|
||||
assert "vector" == HurstExponent(parcellation=PARCELLATION).storage_type(
|
||||
input_type="BOLD", output_feature="complexity"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test MultiscaleEntropyAUC get_output_type()."""
|
||||
def test_storage_type() -> None:
|
||||
"""Test MultiscaleEntropyAUC storage_type."""
|
||||
assert "vector" == MultiscaleEntropyAUC(
|
||||
parcellation=PARCELLATION
|
||||
).get_output_type(input_type="BOLD", output_feature="complexity")
|
||||
).storage_type(input_type="BOLD", output_feature="complexity")
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test PermEntropy get_output_type()."""
|
||||
assert "vector" == PermEntropy(parcellation=PARCELLATION).get_output_type(
|
||||
def test_storage_type() -> None:
|
||||
"""Test PermEntropy storage_type."""
|
||||
assert "vector" == PermEntropy(parcellation=PARCELLATION).storage_type(
|
||||
input_type="BOLD", output_feature="complexity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test RangeEntropy get_output_type()."""
|
||||
assert "vector" == RangeEntropy(parcellation=PARCELLATION).get_output_type(
|
||||
def test_storage_type() -> None:
|
||||
"""Test RangeEntropy storage_type."""
|
||||
assert "vector" == RangeEntropy(parcellation=PARCELLATION).storage_type(
|
||||
input_type="BOLD", output_feature="complexity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test RangeEntropyAUC get_output_type()."""
|
||||
assert "vector" == RangeEntropyAUC(
|
||||
parcellation=PARCELLATION
|
||||
).get_output_type(input_type="BOLD", output_feature="complexity")
|
||||
def test_storage_type() -> None:
|
||||
"""Test RangeEntropyAUC storage_type."""
|
||||
assert "vector" == RangeEntropyAUC(parcellation=PARCELLATION).storage_type(
|
||||
input_type="BOLD", output_feature="complexity"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test SampleEntropy get_output_type()."""
|
||||
assert "vector" == SampleEntropy(
|
||||
parcellation=PARCELLATION
|
||||
).get_output_type(input_type="BOLD", output_feature="complexity")
|
||||
def test_storage_type() -> None:
|
||||
"""Test SampleEntropy storage_type."""
|
||||
assert "vector" == SampleEntropy(parcellation=PARCELLATION).storage_type(
|
||||
input_type="BOLD", output_feature="complexity"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ def test_compute() -> None:
|
|||
assert feature_map["BOLD"]["complexity"]["data"].ndim == 2
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test WeightedPermEntropy get_output_type()."""
|
||||
def test_storage_type() -> None:
|
||||
"""Test WeightedPermEntropy storage_type."""
|
||||
assert "vector" == WeightedPermEntropy(
|
||||
parcellation=PARCELLATION
|
||||
).get_output_type(input_type="BOLD", output_feature="complexity")
|
||||
).storage_type(input_type="BOLD", output_feature="complexity")
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ MAPS = "Smith_rsn_10"
|
|||
"falff",
|
||||
],
|
||||
)
|
||||
def test_ALFFMaps_get_output_type(feature: str) -> None:
|
||||
"""Test ALFFMaps get_output_type().
|
||||
def test_ALFFMaps_storage_type(feature: str) -> None:
|
||||
"""Test ALFFMaps storage_type.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -39,7 +39,7 @@ def test_ALFFMaps_get_output_type(feature: str) -> None:
|
|||
assert "vector" == ALFFMaps(
|
||||
maps=MAPS,
|
||||
using="junifer",
|
||||
).get_output_type(input_type="BOLD", output_feature=feature)
|
||||
).storage_type(input_type="BOLD", output_feature=feature)
|
||||
|
||||
|
||||
def test_ALFFMaps(
|
||||
|
|
@ -74,7 +74,7 @@ def test_ALFFMaps(
|
|||
)
|
||||
# Check correct output
|
||||
for name in ["alff", "falff"]:
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature=name
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ PARCELLATION = "TianxS1x3TxMNInonlinear2009cAsym"
|
|||
"falff",
|
||||
],
|
||||
)
|
||||
def test_ALFFParcels_get_output_type(feature: str) -> None:
|
||||
"""Test ALFFParcels get_output_type().
|
||||
def test_ALFFParcels_storage_type(feature: str) -> None:
|
||||
"""Test ALFFParcels storage_type.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -40,7 +40,7 @@ def test_ALFFParcels_get_output_type(feature: str) -> None:
|
|||
assert "vector" == ALFFParcels(
|
||||
parcellation=PARCELLATION,
|
||||
using="junifer",
|
||||
).get_output_type(input_type="BOLD", output_feature=feature)
|
||||
).storage_type(input_type="BOLD", output_feature=feature)
|
||||
|
||||
|
||||
def test_ALFFParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ COORDINATES = "DMNBuckner"
|
|||
"falff",
|
||||
],
|
||||
)
|
||||
def test_ALFFSpheres_get_output_type(feature: str) -> None:
|
||||
"""Test ALFFSpheres get_output_type().
|
||||
def test_ALFFSpheres_storage_type(feature: str) -> None:
|
||||
"""Test ALFFSpheres storage_type.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -40,7 +40,7 @@ def test_ALFFSpheres_get_output_type(feature: str) -> None:
|
|||
assert "vector" == ALFFSpheres(
|
||||
coords=COORDINATES,
|
||||
using="junifer",
|
||||
).get_output_type(input_type="BOLD", output_feature=feature)
|
||||
).storage_type(input_type="BOLD", output_feature=feature)
|
||||
|
||||
|
||||
def test_ALFFSpheres(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
||||
|
|
|
|||
|
|
@ -31,13 +31,11 @@ def test_init() -> None:
|
|||
)
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test CrossParcellationFC get_output_type()."""
|
||||
def test_storage_type() -> None:
|
||||
"""Test CrossParcellationFC storage_type."""
|
||||
assert "matrix" == CrossParcellationFC(
|
||||
parcellation_one=parcellation_one, parcellation_two=parcellation_two
|
||||
).get_output_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
).storage_type(input_type="BOLD", output_feature="functional_connectivity")
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ def test_EdgeCentricFCMaps(
|
|||
conn_method_params=conn_method_params,
|
||||
)
|
||||
# Check correct output
|
||||
assert "matrix" == marker.get_output_type(
|
||||
assert "matrix" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ def test_EdgeCentricFCParcels(
|
|||
conn_method_params=conn_method_params,
|
||||
)
|
||||
# Check correct output
|
||||
assert "matrix" == marker.get_output_type(
|
||||
assert "matrix" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ def test_EdgeCentricFCSpheres(
|
|||
conn_method_params=conn_method_params,
|
||||
)
|
||||
# Check correct output
|
||||
assert "matrix" == marker.get_output_type(
|
||||
assert "matrix" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ def test_FunctionalConnectivityMaps(
|
|||
conn_method_params=conn_method_params,
|
||||
)
|
||||
# Check correct output
|
||||
assert "matrix" == marker.get_output_type(
|
||||
assert "matrix" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ def test_FunctionalConnectivityParcels(
|
|||
conn_method_params=conn_method_params,
|
||||
)
|
||||
# Check correct output
|
||||
assert "matrix" == marker.get_output_type(
|
||||
assert "matrix" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ def test_FunctionalConnectivitySpheres(
|
|||
conn_method_params=conn_method_params,
|
||||
)
|
||||
# Check correct output
|
||||
assert "matrix" == marker.get_output_type(
|
||||
assert "matrix" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="functional_connectivity"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ def test_ReHoMaps(
|
|||
using="junifer",
|
||||
)
|
||||
# Check correct output
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="reho"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|||
using="junifer",
|
||||
)
|
||||
# Check correct output
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="reho"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def test_ReHoSpheres(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|||
coords=COORDINATES, using="junifer", radius=10.0
|
||||
)
|
||||
# Check correct output
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="reho"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ def test_TemporalSNRMaps_computation(
|
|||
element_data = DefaultDataReader().fit_transform(element)
|
||||
marker = TemporalSNRMaps(maps="Smith_rsn_10")
|
||||
# Check correct output
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="tsnr"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ def test_TemporalSNRParcels_computation() -> None:
|
|||
parcellation="TianxS1x3TxMNInonlinear2009cAsym"
|
||||
)
|
||||
# Check correct output
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="tsnr"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ def test_TemporalSNRSpheres_computation() -> None:
|
|||
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
||||
marker = TemporalSNRSpheres(coords="DMNBuckner", radius=5.0)
|
||||
# Check correct output
|
||||
assert "vector" == marker.get_output_type(
|
||||
assert "vector" == marker.storage_type(
|
||||
input_type="BOLD", output_feature="tsnr"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ from junifer.pipeline.utils import _check_freesurfer
|
|||
("distances", "vector"),
|
||||
],
|
||||
)
|
||||
def test_get_output_type(feature: str, storage_type: str) -> None:
|
||||
"""Test BrainPrint get_output_type().
|
||||
def test_storage_type(feature: str, storage_type: str) -> None:
|
||||
"""Test BrainPrint storage_type.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
@ -33,7 +33,7 @@ def test_get_output_type(feature: str, storage_type: str) -> None:
|
|||
The parametrized storage type.
|
||||
|
||||
"""
|
||||
assert storage_type == BrainPrint().get_output_type(
|
||||
assert storage_type == BrainPrint().storage_type(
|
||||
input_type="FreeSurfer", output_feature=feature
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ def test_compute() -> None:
|
|||
assert extacted_timeseries.shape[0] == len(rss_ets["rss_ets"]["data"])
|
||||
|
||||
|
||||
def test_get_output_type() -> None:
|
||||
"""Test RSS ETS get_output_type()."""
|
||||
def test_storage_type() -> None:
|
||||
"""Test RSS ETS storage_type."""
|
||||
assert "timeseries" == RSSETSMarker(
|
||||
parcellation=PARCELLATION
|
||||
).get_output_type(input_type="BOLD", output_feature="rss_ets")
|
||||
).storage_type(input_type="BOLD", output_feature="rss_ets")
|
||||
|
||||
|
||||
def test_store(tmp_path: Path) -> None:
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ def test_MapsAggregation_input_output(
|
|||
"""
|
||||
assert storage_type == MapsAggregation(
|
||||
maps="Smith_rsn_10", on=input_type
|
||||
).get_output_type(input_type=input_type, output_feature="aggregation")
|
||||
).storage_type(input_type=input_type, output_feature="aggregation")
|
||||
|
||||
|
||||
def test_MapsAggregation_3D(
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ def test_ParcelAggregation_input_output(
|
|||
"""
|
||||
assert storage_type == ParcelAggregation(
|
||||
parcellation="Schaefer100x7", method="mean", on=input_type
|
||||
).get_output_type(input_type=input_type, output_feature="aggregation")
|
||||
).storage_type(input_type=input_type, output_feature="aggregation")
|
||||
|
||||
|
||||
def test_ParcelAggregation_3D() -> None:
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ def test_SphereAggregation_input_output(
|
|||
coords="DMNBuckner",
|
||||
method="mean",
|
||||
on=input_type,
|
||||
).get_output_type(input_type=input_type, output_feature="aggregation")
|
||||
).storage_type(input_type=input_type, output_feature="aggregation")
|
||||
|
||||
|
||||
def test_SphereAggregation_3D() -> None:
|
||||
|
|
|
|||
Loading…
Reference in a new issue
This is MRI-specific and should not be here.