diff --git a/docs/changes/newsfragments/477.enh b/docs/changes/newsfragments/477.enh new file mode 100644 index 000000000..af12220aa --- /dev/null +++ b/docs/changes/newsfragments/477.enh @@ -0,0 +1 @@ +Improve ``Marker`` interface and implementations by `Synchon Mandal`_ diff --git a/junifer/markers/base.py b/junifer/markers/base.py index cc7a8b684..16636fc6a 100644 --- a/junifer/markers/base.py +++ b/junifer/markers/base.py @@ -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) diff --git a/junifer/markers/complexity/tests/test_hurst_exponent.py b/junifer/markers/complexity/tests/test_hurst_exponent.py index 771e28d35..4e6063517 100644 --- a/junifer/markers/complexity/tests/test_hurst_exponent.py +++ b/junifer/markers/complexity/tests/test_hurst_exponent.py @@ -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( diff --git a/junifer/markers/complexity/tests/test_multiscale_entropy_auc.py b/junifer/markers/complexity/tests/test_multiscale_entropy_auc.py index fa5b3c0a9..de65c5a82 100644 --- a/junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +++ b/junifer/markers/complexity/tests/test_multiscale_entropy_auc.py @@ -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( diff --git a/junifer/markers/complexity/tests/test_perm_entropy.py b/junifer/markers/complexity/tests/test_perm_entropy.py index 580446995..ac0db77b2 100644 --- a/junifer/markers/complexity/tests/test_perm_entropy.py +++ b/junifer/markers/complexity/tests/test_perm_entropy.py @@ -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" ) diff --git a/junifer/markers/complexity/tests/test_range_entropy.py b/junifer/markers/complexity/tests/test_range_entropy.py index 873a0d2b8..ba477fffe 100644 --- a/junifer/markers/complexity/tests/test_range_entropy.py +++ b/junifer/markers/complexity/tests/test_range_entropy.py @@ -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" ) diff --git a/junifer/markers/complexity/tests/test_range_entropy_auc.py b/junifer/markers/complexity/tests/test_range_entropy_auc.py index 5955e12ff..4cfac4720 100644 --- a/junifer/markers/complexity/tests/test_range_entropy_auc.py +++ b/junifer/markers/complexity/tests/test_range_entropy_auc.py @@ -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( diff --git a/junifer/markers/complexity/tests/test_sample_entropy.py b/junifer/markers/complexity/tests/test_sample_entropy.py index 73139343f..fc79cad8c 100644 --- a/junifer/markers/complexity/tests/test_sample_entropy.py +++ b/junifer/markers/complexity/tests/test_sample_entropy.py @@ -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( diff --git a/junifer/markers/complexity/tests/test_weighted_perm_entropy.py b/junifer/markers/complexity/tests/test_weighted_perm_entropy.py index 3ebe57894..485df7f4e 100644 --- a/junifer/markers/complexity/tests/test_weighted_perm_entropy.py +++ b/junifer/markers/complexity/tests/test_weighted_perm_entropy.py @@ -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( diff --git a/junifer/markers/falff/tests/test_falff_maps.py b/junifer/markers/falff/tests/test_falff_maps.py index aee7a92b2..12e2c6b9b 100644 --- a/junifer/markers/falff/tests/test_falff_maps.py +++ b/junifer/markers/falff/tests/test_falff_maps.py @@ -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 ) diff --git a/junifer/markers/falff/tests/test_falff_parcels.py b/junifer/markers/falff/tests/test_falff_parcels.py index 34fcd94ff..c9a55b756 100644 --- a/junifer/markers/falff/tests/test_falff_parcels.py +++ b/junifer/markers/falff/tests/test_falff_parcels.py @@ -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: diff --git a/junifer/markers/falff/tests/test_falff_spheres.py b/junifer/markers/falff/tests/test_falff_spheres.py index f57022e35..4a254448e 100644 --- a/junifer/markers/falff/tests/test_falff_spheres.py +++ b/junifer/markers/falff/tests/test_falff_spheres.py @@ -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: diff --git a/junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py b/junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py index 67a046286..19584a731 100644 --- a/junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +++ b/junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py @@ -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( diff --git a/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py b/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py index ae44c9d07..84b763925 100644 --- a/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py +++ b/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py @@ -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" ) diff --git a/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py b/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py index a7f0519d7..e6083b960 100644 --- a/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +++ b/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py @@ -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" ) diff --git a/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py b/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py index f142a8467..db9f76b24 100644 --- a/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +++ b/junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py @@ -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" ) diff --git a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py index c4f92ccc3..281ad3210 100644 --- a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py +++ b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py @@ -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" ) diff --git a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py index 07757e1d0..8f495b460 100644 --- a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +++ b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py @@ -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" ) diff --git a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py index 854961804..f80ea1f3e 100644 --- a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +++ b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py @@ -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" ) diff --git a/junifer/markers/reho/tests/test_reho_maps.py b/junifer/markers/reho/tests/test_reho_maps.py index 42db2d987..3dac74678 100644 --- a/junifer/markers/reho/tests/test_reho_maps.py +++ b/junifer/markers/reho/tests/test_reho_maps.py @@ -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" ) diff --git a/junifer/markers/reho/tests/test_reho_parcels.py b/junifer/markers/reho/tests/test_reho_parcels.py index d7737e335..db0bcf245 100644 --- a/junifer/markers/reho/tests/test_reho_parcels.py +++ b/junifer/markers/reho/tests/test_reho_parcels.py @@ -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" ) diff --git a/junifer/markers/reho/tests/test_reho_spheres.py b/junifer/markers/reho/tests/test_reho_spheres.py index 9f89b036a..aeee29c68 100644 --- a/junifer/markers/reho/tests/test_reho_spheres.py +++ b/junifer/markers/reho/tests/test_reho_spheres.py @@ -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" ) diff --git a/junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py b/junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py index 173509fa2..320467421 100644 --- a/junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py +++ b/junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py @@ -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" ) diff --git a/junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py b/junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py index cb97b3882..8cb535b05 100644 --- a/junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +++ b/junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py @@ -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" ) diff --git a/junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py b/junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py index 7957458b2..81e871c6c 100644 --- a/junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +++ b/junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py @@ -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" ) diff --git a/junifer/markers/tests/test_brainprint.py b/junifer/markers/tests/test_brainprint.py index 41557b8ee..65ef387a2 100644 --- a/junifer/markers/tests/test_brainprint.py +++ b/junifer/markers/tests/test_brainprint.py @@ -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 ) diff --git a/junifer/markers/tests/test_ets_rss.py b/junifer/markers/tests/test_ets_rss.py index 73f38e473..5f478cc60 100644 --- a/junifer/markers/tests/test_ets_rss.py +++ b/junifer/markers/tests/test_ets_rss.py @@ -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: diff --git a/junifer/markers/tests/test_maps_aggregation.py b/junifer/markers/tests/test_maps_aggregation.py index 9c2b3e8bb..10babfa30 100644 --- a/junifer/markers/tests/test_maps_aggregation.py +++ b/junifer/markers/tests/test_maps_aggregation.py @@ -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( diff --git a/junifer/markers/tests/test_parcel_aggregation.py b/junifer/markers/tests/test_parcel_aggregation.py index 6e7098073..a0ff8c378 100644 --- a/junifer/markers/tests/test_parcel_aggregation.py +++ b/junifer/markers/tests/test_parcel_aggregation.py @@ -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: diff --git a/junifer/markers/tests/test_sphere_aggregation.py b/junifer/markers/tests/test_sphere_aggregation.py index 1f9ba2db1..2f41efe79 100644 --- a/junifer/markers/tests/test_sphere_aggregation.py +++ b/junifer/markers/tests/test_sphere_aggregation.py @@ -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: