junifer 0.0.5.dev240__py3-none-any.whl → 0.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- junifer/__init__.py +2 -31
- junifer/__init__.pyi +37 -0
- junifer/_version.py +9 -4
- junifer/api/__init__.py +3 -5
- junifer/api/__init__.pyi +4 -0
- junifer/api/decorators.py +14 -19
- junifer/api/functions.py +165 -109
- junifer/api/py.typed +0 -0
- junifer/api/queue_context/__init__.py +2 -4
- junifer/api/queue_context/__init__.pyi +5 -0
- junifer/api/queue_context/gnu_parallel_local_adapter.py +22 -6
- junifer/api/queue_context/htcondor_adapter.py +23 -6
- junifer/api/queue_context/py.typed +0 -0
- junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +3 -3
- junifer/api/queue_context/tests/test_htcondor_adapter.py +3 -3
- junifer/api/tests/test_functions.py +168 -74
- junifer/cli/__init__.py +24 -0
- junifer/cli/__init__.pyi +3 -0
- junifer/{api → cli}/cli.py +141 -125
- junifer/cli/parser.py +235 -0
- junifer/cli/py.typed +0 -0
- junifer/{api → cli}/tests/test_cli.py +8 -8
- junifer/{api/tests/test_api_utils.py → cli/tests/test_cli_utils.py} +5 -4
- junifer/{api → cli}/tests/test_parser.py +2 -2
- junifer/{api → cli}/utils.py +6 -16
- junifer/configs/juseless/__init__.py +2 -2
- junifer/configs/juseless/__init__.pyi +3 -0
- junifer/configs/juseless/datagrabbers/__init__.py +2 -12
- junifer/configs/juseless/datagrabbers/__init__.pyi +13 -0
- junifer/configs/juseless/datagrabbers/ixi_vbm.py +2 -2
- junifer/configs/juseless/datagrabbers/py.typed +0 -0
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +2 -2
- junifer/configs/juseless/datagrabbers/ucla.py +4 -4
- junifer/configs/juseless/py.typed +0 -0
- junifer/conftest.py +25 -0
- junifer/data/__init__.py +2 -42
- junifer/data/__init__.pyi +29 -0
- junifer/data/_dispatch.py +248 -0
- junifer/data/coordinates/__init__.py +9 -0
- junifer/data/coordinates/__init__.pyi +5 -0
- junifer/data/coordinates/_ants_coordinates_warper.py +104 -0
- junifer/data/coordinates/_coordinates.py +385 -0
- junifer/data/coordinates/_fsl_coordinates_warper.py +81 -0
- junifer/data/{tests → coordinates/tests}/test_coordinates.py +26 -33
- junifer/data/masks/__init__.py +9 -0
- junifer/data/masks/__init__.pyi +6 -0
- junifer/data/masks/_ants_mask_warper.py +177 -0
- junifer/data/masks/_fsl_mask_warper.py +106 -0
- junifer/data/masks/_masks.py +802 -0
- junifer/data/{tests → masks/tests}/test_masks.py +67 -63
- junifer/data/parcellations/__init__.py +9 -0
- junifer/data/parcellations/__init__.pyi +6 -0
- junifer/data/parcellations/_ants_parcellation_warper.py +166 -0
- junifer/data/parcellations/_fsl_parcellation_warper.py +89 -0
- junifer/data/parcellations/_parcellations.py +1388 -0
- junifer/data/{tests → parcellations/tests}/test_parcellations.py +165 -295
- junifer/data/pipeline_data_registry_base.py +76 -0
- junifer/data/py.typed +0 -0
- junifer/data/template_spaces.py +44 -79
- junifer/data/tests/test_data_utils.py +1 -2
- junifer/data/tests/test_template_spaces.py +8 -4
- junifer/data/utils.py +109 -4
- junifer/datagrabber/__init__.py +2 -26
- junifer/datagrabber/__init__.pyi +27 -0
- junifer/datagrabber/aomic/__init__.py +2 -4
- junifer/datagrabber/aomic/__init__.pyi +5 -0
- junifer/datagrabber/aomic/id1000.py +81 -52
- junifer/datagrabber/aomic/piop1.py +83 -55
- junifer/datagrabber/aomic/piop2.py +85 -56
- junifer/datagrabber/aomic/py.typed +0 -0
- junifer/datagrabber/aomic/tests/test_id1000.py +19 -12
- junifer/datagrabber/aomic/tests/test_piop1.py +52 -18
- junifer/datagrabber/aomic/tests/test_piop2.py +50 -17
- junifer/datagrabber/base.py +22 -18
- junifer/datagrabber/datalad_base.py +71 -34
- junifer/datagrabber/dmcc13_benchmark.py +31 -18
- junifer/datagrabber/hcp1200/__init__.py +2 -3
- junifer/datagrabber/hcp1200/__init__.pyi +4 -0
- junifer/datagrabber/hcp1200/datalad_hcp1200.py +3 -3
- junifer/datagrabber/hcp1200/hcp1200.py +26 -15
- junifer/datagrabber/hcp1200/py.typed +0 -0
- junifer/datagrabber/hcp1200/tests/test_hcp1200.py +8 -2
- junifer/datagrabber/multiple.py +14 -9
- junifer/datagrabber/pattern.py +132 -96
- junifer/datagrabber/pattern_validation_mixin.py +206 -94
- junifer/datagrabber/py.typed +0 -0
- junifer/datagrabber/tests/test_datalad_base.py +27 -12
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +28 -11
- junifer/datagrabber/tests/test_multiple.py +48 -2
- junifer/datagrabber/tests/test_pattern_datalad.py +1 -1
- junifer/datagrabber/tests/test_pattern_validation_mixin.py +6 -6
- junifer/datareader/__init__.py +2 -2
- junifer/datareader/__init__.pyi +3 -0
- junifer/datareader/default.py +6 -6
- junifer/datareader/py.typed +0 -0
- junifer/external/nilearn/__init__.py +2 -3
- junifer/external/nilearn/__init__.pyi +4 -0
- junifer/external/nilearn/junifer_connectivity_measure.py +25 -17
- junifer/external/nilearn/junifer_nifti_spheres_masker.py +4 -4
- junifer/external/nilearn/py.typed +0 -0
- junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +17 -16
- junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +2 -3
- junifer/markers/__init__.py +2 -38
- junifer/markers/__init__.pyi +37 -0
- junifer/markers/base.py +11 -14
- junifer/markers/brainprint.py +12 -14
- junifer/markers/complexity/__init__.py +2 -18
- junifer/markers/complexity/__init__.pyi +17 -0
- junifer/markers/complexity/complexity_base.py +9 -11
- junifer/markers/complexity/hurst_exponent.py +7 -7
- junifer/markers/complexity/multiscale_entropy_auc.py +7 -7
- junifer/markers/complexity/perm_entropy.py +7 -7
- junifer/markers/complexity/py.typed +0 -0
- junifer/markers/complexity/range_entropy.py +7 -7
- junifer/markers/complexity/range_entropy_auc.py +7 -7
- junifer/markers/complexity/sample_entropy.py +7 -7
- junifer/markers/complexity/tests/test_complexity_base.py +1 -1
- junifer/markers/complexity/tests/test_hurst_exponent.py +5 -5
- junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +5 -5
- junifer/markers/complexity/tests/test_perm_entropy.py +5 -5
- junifer/markers/complexity/tests/test_range_entropy.py +5 -5
- junifer/markers/complexity/tests/test_range_entropy_auc.py +5 -5
- junifer/markers/complexity/tests/test_sample_entropy.py +5 -5
- junifer/markers/complexity/tests/test_weighted_perm_entropy.py +5 -5
- junifer/markers/complexity/weighted_perm_entropy.py +7 -7
- junifer/markers/ets_rss.py +12 -11
- junifer/markers/falff/__init__.py +2 -3
- junifer/markers/falff/__init__.pyi +4 -0
- junifer/markers/falff/_afni_falff.py +38 -45
- junifer/markers/falff/_junifer_falff.py +16 -19
- junifer/markers/falff/falff_base.py +7 -11
- junifer/markers/falff/falff_parcels.py +9 -9
- junifer/markers/falff/falff_spheres.py +8 -8
- junifer/markers/falff/py.typed +0 -0
- junifer/markers/falff/tests/test_falff_spheres.py +3 -1
- junifer/markers/functional_connectivity/__init__.py +2 -12
- junifer/markers/functional_connectivity/__init__.pyi +13 -0
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +9 -8
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +8 -8
- junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +7 -7
- junifer/markers/functional_connectivity/functional_connectivity_base.py +13 -12
- junifer/markers/functional_connectivity/functional_connectivity_parcels.py +8 -8
- junifer/markers/functional_connectivity/functional_connectivity_spheres.py +7 -7
- junifer/markers/functional_connectivity/py.typed +0 -0
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +1 -2
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +1 -2
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +6 -6
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +5 -5
- junifer/markers/parcel_aggregation.py +22 -17
- junifer/markers/py.typed +0 -0
- junifer/markers/reho/__init__.py +2 -3
- junifer/markers/reho/__init__.pyi +4 -0
- junifer/markers/reho/_afni_reho.py +29 -35
- junifer/markers/reho/_junifer_reho.py +13 -14
- junifer/markers/reho/py.typed +0 -0
- junifer/markers/reho/reho_base.py +7 -11
- junifer/markers/reho/reho_parcels.py +10 -10
- junifer/markers/reho/reho_spheres.py +9 -9
- junifer/markers/sphere_aggregation.py +22 -17
- junifer/markers/temporal_snr/__init__.py +2 -3
- junifer/markers/temporal_snr/__init__.pyi +4 -0
- junifer/markers/temporal_snr/py.typed +0 -0
- junifer/markers/temporal_snr/temporal_snr_base.py +11 -10
- junifer/markers/temporal_snr/temporal_snr_parcels.py +8 -8
- junifer/markers/temporal_snr/temporal_snr_spheres.py +7 -7
- junifer/markers/tests/test_ets_rss.py +3 -3
- junifer/markers/tests/test_parcel_aggregation.py +24 -24
- junifer/markers/tests/test_sphere_aggregation.py +6 -6
- junifer/markers/utils.py +3 -3
- junifer/onthefly/__init__.py +2 -1
- junifer/onthefly/_brainprint.py +138 -0
- junifer/onthefly/read_transform.py +5 -8
- junifer/pipeline/__init__.py +2 -10
- junifer/pipeline/__init__.pyi +13 -0
- junifer/{markers/collection.py → pipeline/marker_collection.py} +8 -14
- junifer/pipeline/pipeline_component_registry.py +294 -0
- junifer/pipeline/pipeline_step_mixin.py +15 -11
- junifer/pipeline/py.typed +0 -0
- junifer/{markers/tests/test_collection.py → pipeline/tests/test_marker_collection.py} +2 -3
- junifer/pipeline/tests/test_pipeline_component_registry.py +200 -0
- junifer/pipeline/tests/test_pipeline_step_mixin.py +36 -37
- junifer/pipeline/tests/test_update_meta_mixin.py +4 -4
- junifer/pipeline/tests/test_workdir_manager.py +43 -0
- junifer/pipeline/update_meta_mixin.py +21 -17
- junifer/pipeline/utils.py +6 -6
- junifer/pipeline/workdir_manager.py +19 -5
- junifer/preprocess/__init__.py +2 -10
- junifer/preprocess/__init__.pyi +11 -0
- junifer/preprocess/base.py +10 -10
- junifer/preprocess/confounds/__init__.py +2 -2
- junifer/preprocess/confounds/__init__.pyi +3 -0
- junifer/preprocess/confounds/fmriprep_confound_remover.py +243 -64
- junifer/preprocess/confounds/py.typed +0 -0
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +121 -14
- junifer/preprocess/py.typed +0 -0
- junifer/preprocess/smoothing/__init__.py +2 -2
- junifer/preprocess/smoothing/__init__.pyi +3 -0
- junifer/preprocess/smoothing/_afni_smoothing.py +40 -40
- junifer/preprocess/smoothing/_fsl_smoothing.py +22 -32
- junifer/preprocess/smoothing/_nilearn_smoothing.py +35 -14
- junifer/preprocess/smoothing/py.typed +0 -0
- junifer/preprocess/smoothing/smoothing.py +11 -13
- junifer/preprocess/warping/__init__.py +2 -2
- junifer/preprocess/warping/__init__.pyi +3 -0
- junifer/preprocess/warping/_ants_warper.py +136 -32
- junifer/preprocess/warping/_fsl_warper.py +73 -22
- junifer/preprocess/warping/py.typed +0 -0
- junifer/preprocess/warping/space_warper.py +39 -11
- junifer/preprocess/warping/tests/test_space_warper.py +5 -9
- junifer/py.typed +0 -0
- junifer/stats.py +5 -5
- junifer/storage/__init__.py +2 -10
- junifer/storage/__init__.pyi +11 -0
- junifer/storage/base.py +47 -13
- junifer/storage/hdf5.py +95 -33
- junifer/storage/pandas_base.py +12 -11
- junifer/storage/py.typed +0 -0
- junifer/storage/sqlite.py +11 -11
- junifer/storage/tests/test_hdf5.py +86 -4
- junifer/storage/tests/test_sqlite.py +2 -2
- junifer/storage/tests/test_storage_base.py +5 -2
- junifer/storage/tests/test_utils.py +33 -7
- junifer/storage/utils.py +95 -9
- junifer/testing/__init__.py +2 -3
- junifer/testing/__init__.pyi +4 -0
- junifer/testing/datagrabbers.py +10 -11
- junifer/testing/py.typed +0 -0
- junifer/testing/registry.py +4 -7
- junifer/testing/tests/test_testing_registry.py +9 -17
- junifer/tests/test_stats.py +2 -2
- junifer/typing/__init__.py +9 -0
- junifer/typing/__init__.pyi +31 -0
- junifer/typing/_typing.py +68 -0
- junifer/utils/__init__.py +2 -12
- junifer/utils/__init__.pyi +18 -0
- junifer/utils/_config.py +110 -0
- junifer/utils/_yaml.py +16 -0
- junifer/utils/helpers.py +6 -6
- junifer/utils/logging.py +117 -8
- junifer/utils/py.typed +0 -0
- junifer/{pipeline → utils}/singleton.py +19 -14
- junifer/utils/tests/test_config.py +59 -0
- {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info}/METADATA +43 -38
- junifer-0.0.6.dist-info/RECORD +350 -0
- {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info}/WHEEL +1 -1
- junifer-0.0.6.dist-info/entry_points.txt +2 -0
- junifer/api/parser.py +0 -118
- junifer/data/coordinates.py +0 -408
- junifer/data/masks.py +0 -670
- junifer/data/parcellations.py +0 -1828
- junifer/pipeline/registry.py +0 -177
- junifer/pipeline/tests/test_registry.py +0 -150
- junifer-0.0.5.dev240.dist-info/RECORD +0 -275
- junifer-0.0.5.dev240.dist-info/entry_points.txt +0 -2
- /junifer/{api → cli}/tests/data/gmd_mean.yaml +0 -0
- /junifer/{api → cli}/tests/data/gmd_mean_htcondor.yaml +0 -0
- /junifer/{api → cli}/tests/data/partly_cloudy_agg_mean_tian.yml +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/AutobiographicalMemory_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAC_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAR_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/DMNBuckner_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Dosenbach2010_MNI_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Empathy_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Motor_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/MultiTask_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/PhysioStress_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2011_MNI_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2013_MNI_VOIs.tsv +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Rew_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Somatosensory_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/ToM_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/VigAtt_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/WM_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/eMDN_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/eSAD_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/extDMN_VOIs.txt +0 -0
- {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info/licenses}/AUTHORS.rst +0 -0
- {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info/licenses}/LICENSE.md +0 -0
- {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,6 @@
|
|
6
6
|
|
7
7
|
from copy import deepcopy
|
8
8
|
from pathlib import Path
|
9
|
-
from typing import Dict, Tuple
|
10
9
|
|
11
10
|
import h5py
|
12
11
|
import numpy as np
|
@@ -827,6 +826,70 @@ def test_store_timeseries(tmp_path: Path) -> None:
|
|
827
826
|
assert_array_equal(read_df.values, data)
|
828
827
|
|
829
828
|
|
829
|
+
def test_store_timeseries2d(tmp_path: Path) -> None:
|
830
|
+
"""Test 2D timeseries store.
|
831
|
+
|
832
|
+
Parameters
|
833
|
+
----------
|
834
|
+
tmp_path : pathlib.Path
|
835
|
+
The path to the test directory.
|
836
|
+
|
837
|
+
"""
|
838
|
+
uri = tmp_path / "test_store_timeseries_2d.hdf5"
|
839
|
+
storage = HDF5FeatureStorage(uri=uri)
|
840
|
+
# Metadata to store
|
841
|
+
element = {"subject": "test"}
|
842
|
+
meta = {
|
843
|
+
"element": element,
|
844
|
+
"dependencies": ["numpy"],
|
845
|
+
"marker": {"name": "fc"},
|
846
|
+
"type": "BOLD",
|
847
|
+
}
|
848
|
+
# Process the metadata
|
849
|
+
meta_md5, meta_to_store, element_to_store = process_meta(meta)
|
850
|
+
# Store metadata
|
851
|
+
storage.store_metadata(
|
852
|
+
meta_md5=meta_md5, element=element_to_store, meta=meta_to_store
|
853
|
+
)
|
854
|
+
|
855
|
+
# Data to store
|
856
|
+
data = np.array(
|
857
|
+
[[10, 11, 12], [20, 21, 22], [30, 31, 32], [40, 41, 42], [50, 51, 52]]
|
858
|
+
)
|
859
|
+
data = np.c_[[data + (i * 100) for i in range(4)]] # Generate timeseries
|
860
|
+
|
861
|
+
col_names = ["roi1", "roi2", "roi3"]
|
862
|
+
row_names = ["ev1", "ev2", "ev3", "ev4", "ev5"]
|
863
|
+
|
864
|
+
# Store 2D timeseries
|
865
|
+
storage.store_timeseries_2d(
|
866
|
+
meta_md5=meta_md5,
|
867
|
+
element=element_to_store,
|
868
|
+
data=data,
|
869
|
+
col_names=col_names,
|
870
|
+
row_names=row_names,
|
871
|
+
)
|
872
|
+
|
873
|
+
# Read into dataframe
|
874
|
+
read_data = storage.read(feature_md5=meta_md5)
|
875
|
+
# Check if data are equal
|
876
|
+
assert_array_equal(read_data["data"][0], data)
|
877
|
+
assert read_data["column_headers"] == col_names
|
878
|
+
assert read_data["row_headers"], row_names
|
879
|
+
|
880
|
+
read_df = storage.read_df(feature_md5=meta_md5)
|
881
|
+
flatted_names = [f"{row}~{col}" for row in row_names for col in col_names]
|
882
|
+
|
883
|
+
expected_flat_data = np.array(
|
884
|
+
[10, 11, 12, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 52]
|
885
|
+
)
|
886
|
+
expected_flat_data = np.c_[
|
887
|
+
[expected_flat_data + (i * 100) for i in range(4)]
|
888
|
+
] # Generate timeseries
|
889
|
+
assert_array_equal(read_df.values, expected_flat_data)
|
890
|
+
assert read_df.columns.to_list() == flatted_names
|
891
|
+
|
892
|
+
|
830
893
|
def test_store_scalar_table(tmp_path: Path) -> None:
|
831
894
|
"""Test scalar table store.
|
832
895
|
|
@@ -858,7 +921,7 @@ def test_store_scalar_table(tmp_path: Path) -> None:
|
|
858
921
|
col_names = ["roi1", "roi2"]
|
859
922
|
row_names = ["ev1", "ev2", "ev3"]
|
860
923
|
|
861
|
-
# Store
|
924
|
+
# Store scalar table
|
862
925
|
storage.store_scalar_table(
|
863
926
|
meta_md5=meta_md5,
|
864
927
|
element=element_to_store,
|
@@ -874,7 +937,7 @@ def test_store_scalar_table(tmp_path: Path) -> None:
|
|
874
937
|
assert_array_equal(read_df.values, data)
|
875
938
|
|
876
939
|
|
877
|
-
def _create_data_to_store(n_elements: int, kind: str) ->
|
940
|
+
def _create_data_to_store(n_elements: int, kind: str) -> tuple[str, dict]:
|
878
941
|
"""Create data to store.
|
879
942
|
|
880
943
|
Parameters
|
@@ -911,6 +974,12 @@ def _create_data_to_store(n_elements: int, kind: str) -> Tuple[str, Dict]:
|
|
911
974
|
"data": np.arange(20).reshape(2, 10),
|
912
975
|
"col_names": [f"col-{i}" for i in range(10)],
|
913
976
|
}
|
977
|
+
elif kind in "timeseries_2d":
|
978
|
+
data_to_store = {
|
979
|
+
"data": np.arange(120).reshape(6, 5, 4),
|
980
|
+
"row_names": [f"row-{i}" for i in range(5)],
|
981
|
+
"col_names": [f"col-{i}" for i in range(4)],
|
982
|
+
}
|
914
983
|
elif kind in "scalar_table":
|
915
984
|
data_to_store = {
|
916
985
|
"data": np.arange(50).reshape(5, 10),
|
@@ -962,6 +1031,7 @@ def _create_data_to_store(n_elements: int, kind: str) -> Tuple[str, Dict]:
|
|
962
1031
|
(10, 5, "matrix"),
|
963
1032
|
(10, 5, "timeseries"),
|
964
1033
|
(10, 5, "scalar_table"),
|
1034
|
+
(10, 5, "timeseries_2d"),
|
965
1035
|
],
|
966
1036
|
)
|
967
1037
|
def test_multi_output_store_and_collect(
|
@@ -983,7 +1053,9 @@ def test_multi_output_store_and_collect(
|
|
983
1053
|
"""
|
984
1054
|
uri = tmp_path / "test_multi_output_store_and_collect.hdf5"
|
985
1055
|
storage = HDF5FeatureStorage(
|
986
|
-
uri=uri,
|
1056
|
+
uri=uri,
|
1057
|
+
single_output=False,
|
1058
|
+
chunk_size=chunk_size,
|
987
1059
|
)
|
988
1060
|
|
989
1061
|
meta_md5, all_data = _create_data_to_store(n_elements, kind)
|
@@ -1014,6 +1086,12 @@ def test_multi_output_store_and_collect(
|
|
1014
1086
|
element=t_data["element"],
|
1015
1087
|
**t_data["data"],
|
1016
1088
|
)
|
1089
|
+
elif kind == "timeseries_2d":
|
1090
|
+
storage.store_timeseries_2d(
|
1091
|
+
meta_md5=meta_md5,
|
1092
|
+
element=t_data["element"],
|
1093
|
+
**t_data["data"],
|
1094
|
+
)
|
1017
1095
|
elif kind == "scalar_table":
|
1018
1096
|
storage.store_scalar_table(
|
1019
1097
|
meta_md5=meta_md5,
|
@@ -1053,6 +1131,10 @@ def test_multi_output_store_and_collect(
|
|
1053
1131
|
data_size = np.sum([x["data"]["data"].shape[0] for x in all_data])
|
1054
1132
|
assert len(all_df) == data_size
|
1055
1133
|
idx_names = [x for x in all_df.index.names if x != "timepoint"]
|
1134
|
+
elif kind == "timeseries_2d":
|
1135
|
+
data_size = np.sum([x["data"]["data"].shape[0] for x in all_data])
|
1136
|
+
assert len(all_df) == data_size
|
1137
|
+
idx_names = [x for x in all_df.index.names if x != "timepoint"]
|
1056
1138
|
elif kind == "scalar_table":
|
1057
1139
|
data_size = np.sum([x["data"]["data"].shape[0] for x in all_data])
|
1058
1140
|
assert len(all_df) == data_size
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# License: AGPL
|
6
6
|
|
7
7
|
from pathlib import Path
|
8
|
-
from typing import
|
8
|
+
from typing import Union
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
import pandas as pd
|
@@ -56,7 +56,7 @@ df_ignore = pd.DataFrame(
|
|
56
56
|
|
57
57
|
|
58
58
|
def _read_sql(
|
59
|
-
table_name: str, uri: str, index_col: Union[str,
|
59
|
+
table_name: str, uri: str, index_col: Union[str, list[str]]
|
60
60
|
) -> pd.DataFrame:
|
61
61
|
"""Read database table into a pandas DataFrame.
|
62
62
|
|
@@ -25,7 +25,7 @@ def test_BaseFeatureStorage() -> None:
|
|
25
25
|
"""Implement concrete class."""
|
26
26
|
|
27
27
|
def __init__(self, uri, single_output=True):
|
28
|
-
storage_types = ["matrix", "vector", "timeseries"]
|
28
|
+
storage_types = ["matrix", "vector", "timeseries", "timeseries_2d"]
|
29
29
|
super().__init__(
|
30
30
|
uri=uri,
|
31
31
|
storage_types=storage_types,
|
@@ -33,7 +33,7 @@ def test_BaseFeatureStorage() -> None:
|
|
33
33
|
)
|
34
34
|
|
35
35
|
def get_valid_inputs(self):
|
36
|
-
return ["matrix", "vector", "timeseries"]
|
36
|
+
return ["matrix", "vector", "timeseries", "timeseries_2d"]
|
37
37
|
|
38
38
|
def list_features(self):
|
39
39
|
super().list_features()
|
@@ -97,6 +97,9 @@ def test_BaseFeatureStorage() -> None:
|
|
97
97
|
with pytest.raises(NotImplementedError):
|
98
98
|
st.store(kind="timeseries", meta=meta)
|
99
99
|
|
100
|
+
with pytest.raises(NotImplementedError):
|
101
|
+
st.store(kind="timeseries_2d", meta=meta)
|
102
|
+
|
100
103
|
with pytest.raises(NotImplementedError):
|
101
104
|
st.store(kind="vector", meta=meta)
|
102
105
|
|
@@ -4,7 +4,8 @@
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
5
|
# License: AGPL
|
6
6
|
|
7
|
-
from
|
7
|
+
from collections.abc import Iterable
|
8
|
+
from typing import Union
|
8
9
|
|
9
10
|
import numpy as np
|
10
11
|
import pytest
|
@@ -16,6 +17,7 @@ from junifer.storage.utils import (
|
|
16
17
|
matrix_to_vector,
|
17
18
|
process_meta,
|
18
19
|
store_matrix_checks,
|
20
|
+
timeseries2d_to_vector,
|
19
21
|
)
|
20
22
|
|
21
23
|
|
@@ -198,7 +200,7 @@ def test_process_meta_invalid_metadata_key() -> None:
|
|
198
200
|
),
|
199
201
|
],
|
200
202
|
)
|
201
|
-
def test_process_meta_element(meta:
|
203
|
+
def test_process_meta_element(meta: dict, elements: list[str]) -> None:
|
202
204
|
"""Test metadata element after processing.
|
203
205
|
|
204
206
|
Parameters
|
@@ -215,7 +217,7 @@ def test_process_meta_element(meta: Dict, elements: List[str]) -> None:
|
|
215
217
|
assert "A" in processed_meta
|
216
218
|
assert "B" in processed_meta
|
217
219
|
assert "element" not in processed_meta
|
218
|
-
assert isinstance(processed_meta["dependencies"],
|
220
|
+
assert isinstance(processed_meta["dependencies"], dict)
|
219
221
|
assert all(
|
220
222
|
x in processed_meta["dependencies"] for x in meta["dependencies"]
|
221
223
|
)
|
@@ -232,7 +234,7 @@ def test_process_meta_element(meta: Dict, elements: List[str]) -> None:
|
|
232
234
|
({"subject": 1, "session": 2}, "element_1_2_"),
|
233
235
|
],
|
234
236
|
)
|
235
|
-
def test_element_to_prefix(element:
|
237
|
+
def test_element_to_prefix(element: dict, prefix: str) -> None:
|
236
238
|
"""Test converting element to prefix (for file naming).
|
237
239
|
|
238
240
|
Parameters
|
@@ -320,7 +322,7 @@ def test_element_to_prefix_invalid_type() -> None:
|
|
320
322
|
],
|
321
323
|
)
|
322
324
|
def test_store_matrix_checks(
|
323
|
-
params:
|
325
|
+
params: dict[str, Union[str, bool, tuple[int, int], int]], err_msg: str
|
324
326
|
) -> None:
|
325
327
|
"""Test matrix storing parameter checks.
|
326
328
|
|
@@ -401,9 +403,9 @@ def test_store_matrix_checks(
|
|
401
403
|
],
|
402
404
|
)
|
403
405
|
def test_matrix_to_vector(
|
404
|
-
params:
|
406
|
+
params: dict[str, Union[np.ndarray, Iterable[str], str, bool]],
|
405
407
|
expected_data: np.ndarray,
|
406
|
-
expected_columns:
|
408
|
+
expected_columns: list[str],
|
407
409
|
) -> None:
|
408
410
|
"""Test matrix to vector.
|
409
411
|
|
@@ -420,3 +422,27 @@ def test_matrix_to_vector(
|
|
420
422
|
data, columns = matrix_to_vector(**params) # type: ignore
|
421
423
|
assert_array_equal(data, expected_data)
|
422
424
|
assert columns == expected_columns
|
425
|
+
|
426
|
+
|
427
|
+
def test_timeseries2d_to_vector() -> None:
|
428
|
+
"""Test timeseries2d to vector."""
|
429
|
+
data = np.array(
|
430
|
+
[[10, 11, 12], [20, 21, 22], [30, 31, 32], [40, 41, 42], [50, 51, 52]]
|
431
|
+
)
|
432
|
+
data = np.c_[[data + (i * 100) for i in range(4)]] # Generate timeseries
|
433
|
+
col_names = ["c0", "c1", "c2"]
|
434
|
+
row_names = ["r0", "r1", "r2", "r3", "r4"]
|
435
|
+
flat_data, columns = timeseries2d_to_vector(
|
436
|
+
data=data,
|
437
|
+
col_names=col_names,
|
438
|
+
row_names=row_names,
|
439
|
+
)
|
440
|
+
|
441
|
+
expected_flat_data = np.array(
|
442
|
+
[10, 11, 12, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 52]
|
443
|
+
)
|
444
|
+
expected_flat_data = np.c_[
|
445
|
+
[expected_flat_data + (i * 100) for i in range(4)]
|
446
|
+
] # Generate timeseries
|
447
|
+
assert_array_equal(flat_data, expected_flat_data)
|
448
|
+
assert columns == [f"{r}~{c}" for r in row_names for c in col_names]
|
junifer/storage/utils.py
CHANGED
@@ -6,8 +6,8 @@
|
|
6
6
|
|
7
7
|
import hashlib
|
8
8
|
import json
|
9
|
+
from collections.abc import Iterable
|
9
10
|
from importlib.metadata import PackageNotFoundError, version
|
10
|
-
from typing import Dict, Iterable, List, Tuple
|
11
11
|
|
12
12
|
import numpy as np
|
13
13
|
|
@@ -15,11 +15,11 @@ from ..utils.logging import logger, raise_error
|
|
15
15
|
|
16
16
|
|
17
17
|
__all__ = [
|
18
|
+
"element_to_prefix",
|
18
19
|
"get_dependency_version",
|
20
|
+
"matrix_to_vector",
|
19
21
|
"process_meta",
|
20
|
-
"element_to_prefix",
|
21
22
|
"store_matrix_checks",
|
22
|
-
"matrix_to_vector",
|
23
23
|
]
|
24
24
|
|
25
25
|
|
@@ -50,7 +50,7 @@ def get_dependency_version(dependency: str) -> str:
|
|
50
50
|
return dep_version
|
51
51
|
|
52
52
|
|
53
|
-
def _meta_hash(meta:
|
53
|
+
def _meta_hash(meta: dict) -> str:
|
54
54
|
"""Compute the MD5 hash of the metadata.
|
55
55
|
|
56
56
|
Parameters
|
@@ -78,7 +78,7 @@ def _meta_hash(meta: Dict) -> str:
|
|
78
78
|
return meta_md5
|
79
79
|
|
80
80
|
|
81
|
-
def process_meta(meta:
|
81
|
+
def process_meta(meta: dict) -> tuple[str, dict, dict]:
|
82
82
|
"""Process the metadata for storage.
|
83
83
|
|
84
84
|
It removes the key "element" and adds the "_element_keys" with the keys
|
@@ -109,7 +109,7 @@ def process_meta(meta: Dict) -> Tuple[str, Dict, Dict]:
|
|
109
109
|
# Copy the metadata
|
110
110
|
t_meta = meta.copy()
|
111
111
|
# Remove key "element"
|
112
|
-
element:
|
112
|
+
element: dict = t_meta.pop("element", None)
|
113
113
|
if element is None:
|
114
114
|
raise_error(msg="`meta` must contain the key 'element'")
|
115
115
|
if "marker" not in t_meta:
|
@@ -128,7 +128,7 @@ def process_meta(meta: Dict) -> Tuple[str, Dict, Dict]:
|
|
128
128
|
return md5_hash, t_meta, element
|
129
129
|
|
130
130
|
|
131
|
-
def element_to_prefix(element:
|
131
|
+
def element_to_prefix(element: dict) -> str:
|
132
132
|
"""Convert the element metadata to prefix.
|
133
133
|
|
134
134
|
Parameters
|
@@ -156,7 +156,7 @@ def element_to_prefix(element: Dict) -> str:
|
|
156
156
|
def store_matrix_checks(
|
157
157
|
matrix_kind: str,
|
158
158
|
diagonal: bool,
|
159
|
-
data_shape:
|
159
|
+
data_shape: tuple[int, int],
|
160
160
|
row_names_len: int,
|
161
161
|
col_names_len: int,
|
162
162
|
) -> None:
|
@@ -181,6 +181,15 @@ def store_matrix_checks(
|
|
181
181
|
col_names_len : int
|
182
182
|
The length of column labels.
|
183
183
|
|
184
|
+
Raises
|
185
|
+
------
|
186
|
+
ValueError
|
187
|
+
If the matrix kind is invalid
|
188
|
+
If the diagonal is False and the matrix kind is "full"
|
189
|
+
If the matrix kind is "triu" or "tril" and the matrix is not square
|
190
|
+
If the number of row names does not match the number of rows
|
191
|
+
If the number of column names does not match the number of columns
|
192
|
+
|
184
193
|
"""
|
185
194
|
# Matrix kind validation
|
186
195
|
if matrix_kind not in ("triu", "tril", "full"):
|
@@ -212,13 +221,58 @@ def store_matrix_checks(
|
|
212
221
|
)
|
213
222
|
|
214
223
|
|
224
|
+
def store_timeseries_2d_checks(
|
225
|
+
data_shape: tuple[int, int, int],
|
226
|
+
row_names_len: int,
|
227
|
+
col_names_len: int,
|
228
|
+
) -> None:
|
229
|
+
"""Run parameter checks for store_timeseries_2d() methods.
|
230
|
+
|
231
|
+
Parameters
|
232
|
+
----------
|
233
|
+
data_shape : tuple of int and int
|
234
|
+
The shape of the matrix data to store.
|
235
|
+
row_names_len : int
|
236
|
+
The length of row labels.
|
237
|
+
col_names_len : int
|
238
|
+
The length of column labels.
|
239
|
+
|
240
|
+
Raises
|
241
|
+
------
|
242
|
+
ValueError
|
243
|
+
If the data is not a 3D array (timepoints, rows, columns)
|
244
|
+
If the number of row names does not match the number of rows
|
245
|
+
If the number of column names does not match the number of columns
|
246
|
+
|
247
|
+
"""
|
248
|
+
# data validation
|
249
|
+
if len(data_shape) != 3:
|
250
|
+
raise_error(
|
251
|
+
msg="Data must be a 3D array",
|
252
|
+
klass=ValueError,
|
253
|
+
)
|
254
|
+
|
255
|
+
# Row label validation
|
256
|
+
if row_names_len != data_shape[1]: # type: ignore
|
257
|
+
raise_error(
|
258
|
+
msg="Number of row names does not match number of rows",
|
259
|
+
klass=ValueError,
|
260
|
+
)
|
261
|
+
# Column label validation
|
262
|
+
if col_names_len != data_shape[2]: # type: ignore
|
263
|
+
raise_error(
|
264
|
+
msg="Number of column names does not match number of columns",
|
265
|
+
klass=ValueError,
|
266
|
+
)
|
267
|
+
|
268
|
+
|
215
269
|
def matrix_to_vector(
|
216
270
|
data: np.ndarray,
|
217
271
|
col_names: Iterable[str],
|
218
272
|
row_names: Iterable[str],
|
219
273
|
matrix_kind: str,
|
220
274
|
diagonal: bool,
|
221
|
-
) ->
|
275
|
+
) -> tuple[np.ndarray, list[str]]:
|
222
276
|
"""Convert matrix to vector based on parameters.
|
223
277
|
|
224
278
|
Parameters
|
@@ -268,3 +322,35 @@ def matrix_to_vector(
|
|
268
322
|
]
|
269
323
|
|
270
324
|
return flat_data, columns
|
325
|
+
|
326
|
+
|
327
|
+
def timeseries2d_to_vector(
|
328
|
+
data: np.ndarray,
|
329
|
+
col_names: Iterable[str],
|
330
|
+
row_names: Iterable[str],
|
331
|
+
) -> tuple[np.ndarray, list[str]]:
|
332
|
+
"""Convert matrix to vector based on parameters.
|
333
|
+
|
334
|
+
Parameters
|
335
|
+
----------
|
336
|
+
data : 2D / 3D numpy.ndarray
|
337
|
+
The matrix / tensor data to store / read.
|
338
|
+
col_names : list or tuple of str
|
339
|
+
The column labels.
|
340
|
+
row_names : list or tuple of str
|
341
|
+
The row labels.
|
342
|
+
|
343
|
+
Returns
|
344
|
+
-------
|
345
|
+
2D numpy.ndarray
|
346
|
+
The vector / matrix data.
|
347
|
+
list of str
|
348
|
+
The column labels.
|
349
|
+
|
350
|
+
"""
|
351
|
+
# Reshape data to 2D
|
352
|
+
flat_data = data.reshape(data.shape[0], -1)
|
353
|
+
# Generate flat 1D row X column names
|
354
|
+
columns = [f"{r}~{c}" for r in row_names for c in col_names]
|
355
|
+
|
356
|
+
return flat_data, columns
|
junifer/testing/__init__.py
CHANGED
@@ -4,8 +4,7 @@
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
5
|
# License: AGPL
|
6
6
|
|
7
|
-
|
8
|
-
from .utils import get_testing_data
|
7
|
+
import lazy_loader as lazy
|
9
8
|
|
10
9
|
|
11
|
-
__all__ =
|
10
|
+
__getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
|
junifer/testing/datagrabbers.py
CHANGED
@@ -6,7 +6,6 @@
|
|
6
6
|
|
7
7
|
import tempfile
|
8
8
|
from pathlib import Path
|
9
|
-
from typing import Dict, List
|
10
9
|
|
11
10
|
import nibabel as nib
|
12
11
|
from nilearn import datasets, image
|
@@ -16,8 +15,8 @@ from ..datagrabber.base import BaseDataGrabber
|
|
16
15
|
|
17
16
|
__all__ = [
|
18
17
|
"OasisVBMTestingDataGrabber",
|
19
|
-
"SPMAuditoryTestingDataGrabber",
|
20
18
|
"PartlyCloudyTestingDataGrabber",
|
19
|
+
"SPMAuditoryTestingDataGrabber",
|
21
20
|
]
|
22
21
|
|
23
22
|
|
@@ -35,7 +34,7 @@ class OasisVBMTestingDataGrabber(BaseDataGrabber):
|
|
35
34
|
types = ["VBM_GM"]
|
36
35
|
super().__init__(types=types, datadir=datadir)
|
37
36
|
|
38
|
-
def get_element_keys(self) ->
|
37
|
+
def get_element_keys(self) -> list[str]:
|
39
38
|
"""Get element keys.
|
40
39
|
|
41
40
|
Returns
|
@@ -46,7 +45,7 @@ class OasisVBMTestingDataGrabber(BaseDataGrabber):
|
|
46
45
|
"""
|
47
46
|
return ["subject"]
|
48
47
|
|
49
|
-
def get_item(self, subject: str) ->
|
48
|
+
def get_item(self, subject: str) -> dict[str, dict]:
|
50
49
|
"""Implement indexing support.
|
51
50
|
|
52
51
|
Parameters
|
@@ -80,7 +79,7 @@ class OasisVBMTestingDataGrabber(BaseDataGrabber):
|
|
80
79
|
self._dataset = datasets.fetch_oasis_vbm(n_subjects=10)
|
81
80
|
return self
|
82
81
|
|
83
|
-
def get_elements(self) ->
|
82
|
+
def get_elements(self) -> list[str]:
|
84
83
|
"""Get elements.
|
85
84
|
|
86
85
|
Returns
|
@@ -106,7 +105,7 @@ class SPMAuditoryTestingDataGrabber(BaseDataGrabber):
|
|
106
105
|
types = ["BOLD", "T1w"] # TODO: Check that they are T1w
|
107
106
|
super().__init__(types=types, datadir=datadir)
|
108
107
|
|
109
|
-
def get_element_keys(self) ->
|
108
|
+
def get_element_keys(self) -> list[str]:
|
110
109
|
"""Get element keys.
|
111
110
|
|
112
111
|
Returns
|
@@ -117,7 +116,7 @@ class SPMAuditoryTestingDataGrabber(BaseDataGrabber):
|
|
117
116
|
"""
|
118
117
|
return ["subject"]
|
119
118
|
|
120
|
-
def get_elements(self) ->
|
119
|
+
def get_elements(self) -> list[str]:
|
121
120
|
"""Get elements.
|
122
121
|
|
123
122
|
Returns
|
@@ -128,7 +127,7 @@ class SPMAuditoryTestingDataGrabber(BaseDataGrabber):
|
|
128
127
|
"""
|
129
128
|
return [f"sub{x:03d}" for x in list(range(1, 11))]
|
130
129
|
|
131
|
-
def get_item(self, subject: str) ->
|
130
|
+
def get_item(self, subject: str) -> dict[str, dict]:
|
132
131
|
"""Implement indexing support.
|
133
132
|
|
134
133
|
Parameters
|
@@ -208,7 +207,7 @@ class PartlyCloudyTestingDataGrabber(BaseDataGrabber):
|
|
208
207
|
)
|
209
208
|
return self
|
210
209
|
|
211
|
-
def get_element_keys(self) ->
|
210
|
+
def get_element_keys(self) -> list[str]:
|
212
211
|
"""Get element keys.
|
213
212
|
|
214
213
|
Returns
|
@@ -219,7 +218,7 @@ class PartlyCloudyTestingDataGrabber(BaseDataGrabber):
|
|
219
218
|
"""
|
220
219
|
return ["subject"]
|
221
220
|
|
222
|
-
def get_elements(self) ->
|
221
|
+
def get_elements(self) -> list[str]:
|
223
222
|
"""Get elements.
|
224
223
|
|
225
224
|
Returns
|
@@ -230,7 +229,7 @@ class PartlyCloudyTestingDataGrabber(BaseDataGrabber):
|
|
230
229
|
"""
|
231
230
|
return [f"sub-{x:02d}" for x in list(range(1, 11))]
|
232
231
|
|
233
|
-
def get_item(self, subject: str) ->
|
232
|
+
def get_item(self, subject: str) -> dict[str, dict]:
|
234
233
|
"""Implement indexing support.
|
235
234
|
|
236
235
|
Parameters
|
junifer/testing/py.typed
ADDED
File without changes
|
junifer/testing/registry.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
5
|
# License: AGPL
|
6
6
|
|
7
|
-
from ..pipeline
|
7
|
+
from ..pipeline import PipelineComponentRegistry
|
8
8
|
from .datagrabbers import (
|
9
9
|
OasisVBMTestingDataGrabber,
|
10
10
|
PartlyCloudyTestingDataGrabber,
|
@@ -13,20 +13,17 @@ from .datagrabbers import (
|
|
13
13
|
|
14
14
|
|
15
15
|
# Register testing DataGrabbers
|
16
|
-
register(
|
16
|
+
PipelineComponentRegistry().register(
|
17
17
|
step="datagrabber",
|
18
|
-
name="OasisVBMTestingDataGrabber",
|
19
18
|
klass=OasisVBMTestingDataGrabber,
|
20
19
|
)
|
21
20
|
|
22
|
-
register(
|
21
|
+
PipelineComponentRegistry().register(
|
23
22
|
step="datagrabber",
|
24
|
-
name="SPMAuditoryTestingDataGrabber",
|
25
23
|
klass=SPMAuditoryTestingDataGrabber,
|
26
24
|
)
|
27
25
|
|
28
|
-
register(
|
26
|
+
PipelineComponentRegistry().register(
|
29
27
|
step="datagrabber",
|
30
|
-
name="PartlyCloudyTestingDataGrabber",
|
31
28
|
klass=PartlyCloudyTestingDataGrabber,
|
32
29
|
)
|
@@ -1,24 +1,16 @@
|
|
1
1
|
"""Provide tests for testing registry."""
|
2
2
|
|
3
|
-
|
3
|
+
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
|
+
# License: AGPL
|
4
6
|
|
5
|
-
from junifer.pipeline
|
7
|
+
from junifer.pipeline import PipelineComponentRegistry
|
6
8
|
|
7
9
|
|
8
10
|
def test_testing_registry() -> None:
|
9
11
|
"""Test testing registry."""
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
assert "OasisVBMTestingDataGrabber" not in get_step_names("datagrabber")
|
16
|
-
assert "SPMAuditoryTestingDataGrabber" not in get_step_names("datagrabber")
|
17
|
-
assert "PartlyCloudyTestingDataGrabber" not in get_step_names(
|
18
|
-
"datagrabber"
|
19
|
-
)
|
20
|
-
importlib.reload(junifer.testing.registry) # type: ignore
|
21
|
-
|
22
|
-
assert "OasisVBMTestingDataGrabber" in get_step_names("datagrabber")
|
23
|
-
assert "SPMAuditoryTestingDataGrabber" in get_step_names("datagrabber")
|
24
|
-
assert "PartlyCloudyTestingDataGrabber" in get_step_names("datagrabber")
|
12
|
+
assert {
|
13
|
+
"OasisVBMTestingDataGrabber",
|
14
|
+
"SPMAuditoryTestingDataGrabber",
|
15
|
+
"PartlyCloudyTestingDataGrabber",
|
16
|
+
}.issubset(set(PipelineComponentRegistry().step_components("datagrabber")))
|
junifer/tests/test_stats.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
4
4
|
# License: AGPL
|
5
5
|
|
6
|
-
from typing import
|
6
|
+
from typing import Optional
|
7
7
|
|
8
8
|
import numpy as np
|
9
9
|
import pytest
|
@@ -25,7 +25,7 @@ from junifer.stats import count, get_aggfunc_by_name, select, winsorized_mean
|
|
25
25
|
("mode", {"keepdims": True}),
|
26
26
|
],
|
27
27
|
)
|
28
|
-
def test_get_aggfunc_by_name(name: str, params: Optional[
|
28
|
+
def test_get_aggfunc_by_name(name: str, params: Optional[dict]) -> None:
|
29
29
|
"""Test aggregation function retrieval by name.
|
30
30
|
|
31
31
|
Parameters
|