Metadata-Version: 2.3
Name: SDNorm
Version: 0.1.0
Summary: Streamline Density Normalization
License: MIT
Author: Yixue Feng
Requires-Python: >=3.9,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: antspyx (>=0.5.4,<0.6.0)
Requires-Dist: cvxpy (>=1.6.5,<2.0.0)
Requires-Dist: dipy (>=1.7.0,<2.0.0)
Requires-Dist: fury (>=0.9.0,<0.10.0)
Requires-Dist: matplotlib (>=3.7.0,<4.0.0)
Requires-Dist: nibabel (>=5.1.0,<6.0.0)
Requires-Dist: numpy (>=1.25.0,<2.0.0)
Requires-Dist: pandas (>=2.1.0,<3.0.0)
Requires-Dist: scipy (>=1.11.0,<2.0.0)
Description-Content-Type: text/markdown

# Streamline Density Normalization (SDNorm)

## Overview
SDNorm is a supervised method for reducing bundle variability by normalizing streamline density.

<div style="display: flex">
  <div>
    <img
    src="test_data/AF_L_orig.png"
    width="200">
  </div>
  <figcaption>AF_L before SDNorm</figcaption>
  <div>
    <img
    src="test_data/AF_L_espd8.png"
    width="200">
  </div>
  <figcaption>AF_L after SDNorm with eSPD=8</figcaption>
  <div>
  <img
    src="test_data/AF_L_espd12.png"
    width="200">
  </div>
  <figcaption>AF_L after SDNorm with eSPD=12</figcaption>
</div>


## Prerequisites
- Python (version 3.9+)
- Poetry ([official installation instructions](https://python-poetry.org/docs/#installing-with-pipx))

## Installation
```
git clone https://github.com/wendyfyx/SDNorm.git
cd SDNorm
poetry install
```

## Running SDNorm
To run SDNorm, the input bundle must be in the same space as the template map and they do not need to be in the MNI space. For testing purposes, we provided the template maps of 10 bundles in MNI space (1mm voxel size) used in our paper in `test_data/templates_mni`, and an example AF_L bundle in the same space. If you are doing tractometry, we recommend warping template maps to the subject space and running SDNorm there.
```
poetry run sdnorm -i test_data/AF_L.trk \
                  -temp test_data/templates_mni/AF_L_template_dm.nii.gz \
                  -o test_data/sdnorm_outputs/AF_L_sdnorm.trk \
                  -ow test_data/sdnorm_outputs/AF_L_sdnorm_weights.txt \
                  -oi test_data/sdnorm_outputs/AF_L_sdnorm_indices.txt \
                  -or test_data/sdnorm_outputs/AF_L_sdnorm_report.json \
                  -lambda 0.001 -espd 8 -step 0.5
```
If you already ran SDNorm, but want to prune bundles with different parameters without refitting the model, you can run
```
poetry run sdnorm_prune -i test_data/AF_L.trk \
                        -w test_data/sdnorm_outputs/AF_L_sdnorm_weights.txt \
                        -temp test_data/templates_mni/AF_L_template_dm.nii.gz \
                        -o test_data/sdnorm_outputs/AF_L_sdnorm_2.trk \
                        -oi test_data/sdnorm_outputs/AF_L_sdnorm_indices_2.txt \
                        -espd 12 -step 0.5

```
but make sure you save the streamline weights when you first run SDNorm!

To create your own template maps, you can create some density maps from extract bundles using `dipy.tracking.utils.density_map`. Then run this command to generate the template map
```
poetry run sdnorm_template -i your-folder/sub-*_AF_L.nii.gz \
                           -o AF_L_template.nii.gz \
```
