From 5f62adae48bc971c6a517c70a84d5c979359e9eb Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Wed, 7 Aug 2024 09:12:38 +0200 Subject: [PATCH 1/2] docs: add doc for analysing storage --- docs/using/running.rst | 170 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/docs/using/running.rst b/docs/using/running.rst index 118e01a3a..9476a8dd5 100644 --- a/docs/using/running.rst +++ b/docs/using/running.rst @@ -113,3 +113,173 @@ The ``collect`` command accepts the following additional arguments: * ``--help``: Show a help message. * ``--verbose``: Set the verbosity level. Options are ``warning``, ``info``, ``debug``. + + +.. _analysing_extracted_features: + +Analysing Results +================= + +After ``collect``-ing the results into a single file, we can analyse them as we +wish. We would need to do this programmatically so feel free to choose your +Python interpreter of choice or use it via a Python script. + +First we load the storage like so: + +.. code-block:: python + + from junifer.storage import HDF5FeatureStorage + + # You need to import and use SQLiteFeatureStorage if you chose that + # for storage while extracting features + storage = HDF5FeatureStorage("") + +The best way to start analysing would be to list all the extracted features +like so: + +.. code-block:: python + + # This would output a dictionary with MD5 checksum of the features as keys + # and metadata of the features as values + storage.list_features() + +.. code-block:: + + {'eb85b61eefba61f13d712d425264697b': {'datagrabber': {'class': 'SPMAuditoryTestingDataGrabber', + 'types': ['BOLD', 'T1w']}, + 'dependencies': {'scikit-learn': '1.3.0', 'nilearn': '0.9.2'}, + 'datareader': {'class': 'DefaultDataReader'}, + 'type': 'BOLD', + 'marker': {'class': 'FunctionalConnectivityParcels', + 'parcellation': 'Schaefer100x7', + 'agg_method': 'mean', + 'agg_method_params': None, + 'cor_method': 'covariance', + 'cor_method_params': {'empirical': False}, + 'masks': None, + 'name': 'schaefer_100x7_fc_parcels'}, + '_element_keys': ['subject'], + 'name': 'BOLD_schaefer_100x7_fc_parcels'}} + +Once we have this, we can retrieve a single feature like so: + +.. code-block:: python + + feature_dict = storage.read("") + +to get the stored dictionary or, + +.. code-block:: python + + feature_df = storage.read_df("") + +to get it as a :class:`pandas.DataFrame`. + +If there are features with duplicate ``name`` s, then we would need to use +the MD5 checksum and pass it like so: + +.. code-block:: python + + feature_df = storage.read_df(feature_md5="") + +We can now manipulate the dictionary or the :class:`pandas.DataFrame` as we +wish or use the DataFrame directly with `julearn`_ if desired. + + +On-the-fly transforms +--------------------- + +``junifer`` supports performing some computationally cheap operations +(like computing brain connectivity or BrainPrint post-analysis) directly +on the storage objects. To make sure everything works, install ``junifer`` +like so: + +.. code-block:: bash + + pip install junifer[onthefly] + +or if installed via ``conda``, everything should be there and no further action +is required. + +Computing brain connectivity via `bctpy `_ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can compute for example, the degree of each node considering an undirected +graph via `bctpy`_ like so: + +.. code-block:: python + + from junifer.onthefly import read_transform + + transformed_df = read_transform( + storage, + # md5 hash can also be passed via `feature_md5` + feature_name="", + # format is `package_function` + transform="bctpy_degrees_und", + ) + +Post-analysis of BrainPrint results +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To perform post-analysis on BrainPrint results, start by importing: + +.. code-block:: python + + from junifer.onthefly import brainprint + + +Normalising: +~~~~~~~~~~~~ + +Surface normalisation can be done by: + +.. code-block:: python + + surface_normalised_df = brainprint.normalize( + storage, + { + "areas": { + "feature_name": "", + # if md5 hash is passed, the above should be None + "feature_md5": None, + }, + "eigenvalues": { + "feature_name": "", + "feature_md5": None, + }, + }, + kind="surface", + ) + +and volume normalisation can be done by: + +.. code-block:: python + + volume_normalised_df = brainprint.normalize( + storage, + { + "volumes": { + "feature_name": "", + "feature_md5": None, + }, + "eigenvalues": { + "feature_name": "", + "feature_md5": None, + }, + }, + kind="volume", + ) + +Re-weighting: +~~~~~~~~~~~~~ + +To perform re-weighting, run like so: + +.. code-block:: python + + reweighted_df = brainprint.reweight( + storage, + # md5 hash can also be passed via `feature_md5` + feature_name="", + ) -- 2.52.0 From 7551cafbcfc0ed022a2bd575ac98d1c0c7f0997a Mon Sep 17 00:00:00 2001 From: Synchon Mandal Date: Mon, 12 Aug 2024 08:01:22 +0200 Subject: [PATCH 2/2] chore: add changelog 359.doc --- docs/changes/newsfragments/359.doc | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/changes/newsfragments/359.doc diff --git a/docs/changes/newsfragments/359.doc b/docs/changes/newsfragments/359.doc new file mode 100644 index 000000000..338d5fa10 --- /dev/null +++ b/docs/changes/newsfragments/359.doc @@ -0,0 +1 @@ +Add documentation on analysing extracted features by `Synchon Mandal`_ -- 2.52.0