From c54a257b7058a1b15aaf06bceb2407a731dc0e24 Mon Sep 17 00:00:00 2001 From: Spiros Maggioros Date: Sat, 30 Nov 2024 12:41:34 +0200 Subject: [PATCH 1/4] [Update] New read-the-docs --- README.md | 178 ----------------------------- README.rst | 103 +++++++++++++++++ docs/{spare_scores.rst => api.rst} | 4 +- docs/conf.py | 10 +- docs/contributors.rst | 76 ++++++++++++ docs/help.rst | 12 ++ docs/index.rst | 29 ++--- docs/installation.rst | 38 ++++++ docs/models.rst | 100 ++++++++++++++++ docs/usage.rst | 35 ++++++ 10 files changed, 383 insertions(+), 202 deletions(-) delete mode 100644 README.md create mode 100644 README.rst rename docs/{spare_scores.rst => api.rst} (96%) create mode 100644 docs/contributors.rst create mode 100644 docs/help.rst create mode 100644 docs/installation.rst create mode 100644 docs/models.rst create mode 100644 docs/usage.rst diff --git a/README.md b/README.md deleted file mode 100644 index ee521c2..0000000 --- a/README.md +++ /dev/null @@ -1,178 +0,0 @@ -[![codecov](https://codecov.io/gh/CBICA/spare_score/graph/badge.svg?token=7yk7pkydHE)](https://codecov.io/gh/CBICA/spare_score) -![macos tests](https://github.com/CBICA/spare_score/actions/workflows/macos-tests-3.12.yml/badge.svg) -![ubuntu tests](https://github.com/CBICA/spare_score/actions/workflows/ubuntu-tests-3.12.yml/badge.svg) - -# Compute SPARE Scores for Your Case - -"SPARE" is short for "Spatial Pattern of Abnormalities for Recognition of ..." If you have brain images of a case population, such as the Alzheimer's disease (AD), the SPARE model will try to find characteristic brain patterns of AD with respect to a control population, such as cognitively normal. This would be an example of a classification-based SPARE model (currently powered by support vector machine or SVM). This model (that we named SPARE-AD) then computes SPARE-AD scores on an individual-basis that indicates how much the individual carries the learned brain patterns of AD. - -Alternatively, you may want to find the spatial pattern related to brain aging (BA). In this case, you would provide sample images and indicate that chronological age is what you expect the model to learn patterns for. This would be an example of a regression-based SPARE model (also powered by SVM). This model (that we named SPARE-BA) then computes SPARE-BA scores on an individual-basis that predicts your brain age. -\ -\ -\ -For detailed documentation, please see here: **[spare_scores](https://cbica.github.io/spare_score/)** - -## Installation - -You can install the spare_score package for python 3.8 up to python 3.12 -Please open an issue if you find any bugs for the newer versions of spare_score - -### Conda environment using pip - -```bash - conda create -n spare python=3.8 # (up to python=3.12) - conda activate spare - conda install pip - pip install spare_scores -``` - -### Python3 virtual environment using pip - -```bash - python3 -m venv env spare - source spare/bin/activate - pip install spare_scores -``` - -### Manually build spare_score - -```bash - # for python 3.12 - git clone https://github.com/CBICA/spare_score.git - cd spare_score - python -m pip install . - - # for python 3.8 - python setup.py bdist_wheel - cd dist && pip install ... - -``` - -## Usage - -```text -spare_scores v1.2.4 -SPARE model training & scores calculation -required arguments: - [ACTION] The action to be performed, either 'train' or 'test' - [-a, --action] - - [INPUT] The dataset to be used for training / testing. Can be - [-i, --input] a filepath string of a .csv file. - -optional arguments: - [OUTPUT] The filename for the model (as a .pkl.gz) to be saved - [-o, --output] at, if training. If testing, the filepath of the - resulting SPARE score dataframe (as a .csv file) to be - saved. If not given, nothing will be saved. - - [MODEL] The model to be used (only) for testing. Can be a - [-m, --model, filepath string of a .pkl.gz file. Required for testing - --model_file] - - [KEY_VAR] The key variable to be used for training. This could - [-kv, be a string of a column name that can uniquely - --key_var, identify a row of the dataset. - --identifier] For example (if a row_ID doesn't exist), it could be: - --key_var PTID - If not given, the first column of the dataset is - considered the primary key of the dataset. Required for - training. - - [DATA_VARS] The list of predictors to be used for training. List. - [-dv, If not given, training will assume that all (apart from - --data_vars, the key variables) variables will be used as - --predictors] predictors, with the ignore variables ignored. - - [IGNORE_VARS] The list of predictors to be ignored for training. Can - [-iv, be a list, or empty. - --ignore_vars, - --ignore] - - [TARGET] The characteristic to be predicted in the course of the - [-t, training. String of the name of the column. Required - --target, for training. - --to_predict] - - [POS_GROUP] Group to assign a positive SPARE score (only for - -pg, classification). String. Required for training. - --pos_group] - - [MODEL_TYPE] The type of model to be used for training. String. - [-mt, 'SVM' or 'MLP'. Required for training. - --model_type] - - [KERNEL] The kernel for SVM training. 'linear' or 'rbf' (only - -k, linear is supported currently in regression). - --kernel] - - [SPARE_VAR] The name of the column to be used for SPARE score. If - [-sv, not given, the column will be named 'SPARE_score'. - --spare_var] - - [VERBOSE] Verbosity. Int. - [-v, 0: Warnings - --verbose, 1: Info - --verbosity] 2: Debug - 3: Errors - 4: Critical - - [LOGS] Where to save log file. If not given, logs will be - [-l, printed out. - --logs] - - [VERSION] Display the version of the package. - [-V, --version] - - [HELP] Show this help message and exit. - [-h, --help] -``` - -## Examples - -Example of training a model (given the example data): - -```bash -spare_score --action train \ - --input spare_scores/data/example_data.csv \ - --predictors H_MUSE_Volume_11 H_MUSE_Volume_23 H_MUSE_Volume_30 \ - --ignore_vars Sex \ - --to_predict Age \ - --kernel linear \ - --verbose 2 \ - --output my_model.pkl.gz -``` - -Example of testing (applying) a model (given the example data): - -```bash -spare_score -a test \ - -i spare_scores/data/example_data.csv \ - --model my_model.pkl.gz \ - -o test_spare_data.csv \ - -v 0 \ - --logs test_logs.txt -``` - -## References - -- SPARE-AD - - Davatzikos, C., Xu, F., An, Y., Fan, Y. & Resnick, S. M. Longitudinal progression of Alzheimer's-like patterns of atrophy in normal older adults: the SPARE-AD index. Brain 132, 2026-2035, [doi:10.1093/brain/awp091](https://doi.org/10.1093/brain/awp091) (2009). - -- SPARE-BA - - Habes, M. et al. Advanced brain aging: relationship with epidemiologic and genetic risk factors, and overlap with Alzheimer disease atrophy patterns. Transl Psychiatry 6, e775, [doi:10.1038/tp.2016.39](https://doi.org/10.1038/tp.2016.39) (2016). - -- diSPARE-AD - - Hwang, G. et al. Disentangling Alzheimer's disease neurodegeneration from typical brain ageing using machine learning. Brain Commun 4, fcac117, [doi:10.1093/braincomms/fcac117](https://doi.org/10.1093/braincomms/fcac117) (2022). - -## Disclaimer - -- The software has been designed for research purposes only and has neither been reviewed nor approved for clinical use by the Food and Drug Administration (FDA) or by any other federal/state agency. -- By using spare_scores, the user agrees to the following license: [CBICA Software License](https://www.med.upenn.edu/cbica/software-agreement-non-commercial.html) - -## Contact - -For more information and support, please post on the [Discussions](https://github.com/CBICA/spare_score/discussions) section or contact [CBICA Software](mailto:software@cbica.upenn.edu) diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..959ffe6 --- /dev/null +++ b/README.rst @@ -0,0 +1,103 @@ +.. image:: https://codecov.io/gh/CBICA/spare_score/graph/badge.svg?token=7yk7pkydHE + :target: https://codecov.io/gh/CBICA/spare_score + +.. image:: https://github.com/CBICA/spare_score/actions/workflows/macos-tests-3.12.yml/badge.svg + :alt: macos tests + +.. image:: https://github.com/CBICA/spare_score/actions/workflows/ubuntu-tests-3.12.yml/badge.svg + :alt: ubuntu tests + + +Overview +-------- + +"SPARE" is short for "Spatial Pattern of Abnormalities for Recognition of ..." If you have brain images of a case population, such as the Alzheimer's disease (AD), the SPARE model will try to find characteristic brain patterns of AD with respect to a control population, such as cognitively normal. This would be an example of a classification-based SPARE model (currently powered by support vector machine or SVM). This model (that we named SPARE-AD) then computes SPARE-AD scores on an individual-basis that indicates how much the individual carries the learned brain patterns of AD. + +Alternatively, you may want to find the spatial pattern related to brain aging (BA). In this case, you would provide sample images and indicate that chronological age is what you expect the model to learn patterns for. This would be an example of a regression-based SPARE model (also powered by SVM). This model (that we named SPARE-BA) then computes SPARE-BA scores on an individual-basis that predicts your brain age. +\ +\ +\ +For detailed documentation, please see here: **[spare_scores](https://cbica.github.io/spare_score/)** + +Installation +____________ + +You can install the spare_score package for python 3.8 up to python 3.12 +Please open an issue if you find any bugs for the newer versions of spare_score + +********* +Using pip +********* + +You can install our latest stable PyPI wheel: :: + + $ pip install spare_scores + +************************** +Manually build spare_score +************************** + +You can install spare_scores from source: :: + + # for python 3.12 + $ git clone https://github.com/CBICA/spare_score.git + cd spare_score + python -m pip install . + + # for python 3.8 and similar + # python setup.py bdist_wheel + cd dist && pip install + + +Usage +_____ + +Example of training a model (given the example data): :: + + $ spare_score --action train \ + --input spare_scores/data/example_data.csv \ + --predictors H_MUSE_Volume_11 H_MUSE_Volume_23 H_MUSE_Volume_30 \ + --ignore_vars Sex \ + --to_predict Age \ + --kernel linear \ + --verbose 2 \ + --output my_model.pkl.gz + +Example of testing (applying) a model (given the example data): :: + + $ spare_score -a test \ + -i spare_scores/data/example_data.csv \ + --model my_model.pkl.gz \ + -o test_spare_data.csv \ + -v 0 \ + --logs test_logs.txt + +.. note:: + + You can always see all of the CLI documentation with ``spare_score -h`` + +References +__________ + +- SPARE-AD + + Davatzikos, C., Xu, F., An, Y., Fan, Y. & Resnick, S. M. Longitudinal progression of Alzheimer's-like patterns of atrophy in normal older adults: the SPARE-AD index. Brain 132, 2026-2035, [doi:10.1093/brain/awp091](https://doi.org/10.1093/brain/awp091) (2009). + +- SPARE-BA + + Habes, M. et al. Advanced brain aging: relationship with epidemiologic and genetic risk factors, and overlap with Alzheimer disease atrophy patterns. Transl Psychiatry 6, e775, [doi:10.1038/tp.2016.39](https://doi.org/10.1038/tp.2016.39) (2016). + +- diSPARE-AD + + Hwang, G. et al. Disentangling Alzheimer's disease neurodegeneration from typical brain ageing using machine learning. Brain Commun 4, fcac117, [doi:10.1093/braincomms/fcac117](https://doi.org/10.1093/braincomms/fcac117) (2022). + +Disclaimer +__________ + +- The software has been designed for research purposes only and has neither been reviewed nor approved for clinical use by the Food and Drug Administration (FDA) or by any other federal/state agency. +- By using spare_scores, the user agrees to the following license: [CBICA Software License](https://www.med.upenn.edu/cbica/software-agreement-non-commercial.html) + +Contact +_______ + +For more information and support, please post on the [Discussions](https://github.com/CBICA/spare_score/discussions) section or contact [CBICA Software](mailto:software@cbica.upenn.edu) diff --git a/docs/spare_scores.rst b/docs/api.rst similarity index 96% rename from docs/spare_scores.rst rename to docs/api.rst index e7085ee..8c6c29e 100644 --- a/docs/spare_scores.rst +++ b/docs/api.rst @@ -1,5 +1,5 @@ -spare\_scores package -===================== +spare\_scores source code +========================= Submodules ---------- diff --git a/docs/conf.py b/docs/conf.py index bb6636c..c9ec5d6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,11 +9,11 @@ import os import sys -sys.path.insert(0, os.path.abspath("../spare_scores/")) +sys.path.insert(0, os.path.abspath("../")) -project = "spare-scores" -copyright = "2024, Gyujoon Hwang, George Aidinis" -author = "Gyujoon Hwang, George Aidinis" +project = "spare scores" +copyright = "2024, Ashish Singh, Guray Erus, George Aidinis" +author = "Ashish Singh, Guray Erus, George Aidinis" release = "2024" # -- General configuration --------------------------------------------------- @@ -35,7 +35,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output github_username = "CBICA" -github_repository = "github.com/CBICA/spare_score" +github_repository = "github.com/CBICA/spare_scores" html_theme = "sphinx_rtd_theme" html_static_path = ["_static"] diff --git a/docs/contributors.rst b/docs/contributors.rst new file mode 100644 index 0000000..364f664 --- /dev/null +++ b/docs/contributors.rst @@ -0,0 +1,76 @@ +############ +Contributing +############ + +This document explains how to prepare your environment to contribute to our package. +Note that we always update our main branch if we want to update the stable release on PyPI, thus, creating +your own branch is recommended so that you can open a pull request. + +***************** +Third party tools +***************** + +We use pre-commit as our main tool for code formatting and checking. You always have to make sure that pre-commit pass in order to open a pull request. +You can perform this test just following these steps: :: + + # If you don't have pre-commit installed + $ pip install pre-commit && pre-commit install + + # Then run pre-commit + pre-commit run --color=always --all-files + +We already have all the necessairy hooks at our `configuration <../../../.pre-commit-config.yaml>`_. + +For our unit testing, we use pytest. Again, in order to contribute you need to make sure that all of the unit tests pass. +You can perform this test following these steps: :: + + # If you don't have pytest installed + $ pip install pytest pytest-cov + + # Run pytest + cd tests/ && pytest + +.. note:: + + We highly suggest you to install the dev requirements before contributing: :: + + $ pip install -r requirements.txt + +************ +Coding style +************ + +We follow a specific coding style that, luckily, can be easily checked with pre-commit. First and foremost, you should always add documentation to any new features you add. +We follow ``sphinx``'s docstring style so that the parser can detect the code comments and display them beautifully at our read-the-docs. Let's assume that you add a new function: + +.. code-block:: python + + def foo(param1: int, param2: str, param3: list) -> int: + """ + Brief explanation of what foo does. + + :param param1: Description of param1. + :type param1: int + :param param2: Description of param2. + :type param2: str + :param param3: Description of param3. + :type param3: list + :return: Description of the return value. + :rtype: int + """ + +``pre-commit`` will also check if you include libraries that are not needed, any extra spaces you might have, logic errors and much more. + +Also, as you see above, you should always add types and return types to every function and class. We only write Python 3 code. If you don't follow all of the above, ``pre-commit`` won't pass, and a maintainer won't review your pull request. + +************** +Good practices +************** + + - At your pull request, explain your additions, why are they useful or what they fix. There are currently no templates to follow for this, but you can just write a sufficient explanation so that a maintainer can understand your additions/fixes. + + - Write a nice commit message. + + - Make sure to follow the issue template if you want to open an issue. + + - Make sure to always add any third-party libraries that you add at the requirements so that the actions can install them. diff --git a/docs/help.rst b/docs/help.rst new file mode 100644 index 0000000..3aa7232 --- /dev/null +++ b/docs/help.rst @@ -0,0 +1,12 @@ +############ +Getting help +############ + +If you have a problem or would like to ask a question about the inner workings of **spare_scores** you can directly +message our maintaners via email. + +.. note:: + +You can reach out to all our maintaners by sending an email to software@cbica.upenn.edu + +If you have a bug or you like to suggest a feature request please follow the `contribution guide <../../../.github/CONTRIBUTE/>`_ and the `issue guide <../../../.github/ISSUE_TEMPLATE/>`_. diff --git a/docs/index.rst b/docs/index.rst index 488a440..8bf569d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,20 +1,15 @@ -.. spare-scores documentation master file, created by - sphinx-quickstart on Mon Jul 15 15:13:44 2024. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. include:: ../README.rst -Welcome to spare-scores's documentation! -======================================== +######## +Contents +######## .. toctree:: - :maxdepth: 2 - :caption: Contents: - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - - + :maxdepth: 3 + + installation + usage + models + contributors + api + help diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..9181dbe --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,38 @@ +############ +Installation +############ + +You can install the ``spare_score`` package with Python 3.8 up to Python 3.12. Please open an issue if you find any bugs for the +newer versions of spare_score. + +**************** +Install with pip +**************** + +To install ``spare_score`` with pip, just do: :: + + $ pip install spare_scores + +We always have our latest stable version on PyPI, so we highly suggest you to install it this way, as this package is under heavy development and +building from source can lead to crashes and bugs. + +******************* +Manual installation +******************* + +You can manually build the package from source by running: :: + + $ git clone https://github.com/CBICA/spare_score + + # for python 3.12 + $cd spare_score && python3 -m pip install -e . + + # for python 3.8 + $ python3 setup.py bdist_wheel + cd dist && pip install + +Currently, these are the only ways to install our package. We will add more ways soon. + +.. note:: + We **do not** recommend installing the package directly from source as the repository above is under heavy development and can cause + crashes and bugs. diff --git a/docs/models.rst b/docs/models.rst new file mode 100644 index 0000000..5e39d31 --- /dev/null +++ b/docs/models.rst @@ -0,0 +1,100 @@ +######### +ML Models +######### + +This document explains the inner workings of our 2 ML models. + + +MLP models +__________ + +We use a total of 2 MLP models. One is implemented with sklearn and the other +with torch. + +**************** +MLP with Sklearn +**************** + +The MLP model implemented with sklearn can be found at `mlp.py <../../../spare_scores/mlp.py>`_. +The MLP model class takes a total of 4 arguments, plus, extra parameters if needed. + +.. code-block:: python + + def __init__( + self, + predictors: list, + to_predict: str, + key_var: str, + verbose: int = 1, + **kwargs: Any, + ) -> None + +The usage of each parameter is explained at `usage.rst <../../usage.rst>`_. Valid extra +pamaters are "k", "n_repeats", "task" and "param_grid". We perform thorough checking to +always make sure that the parameters are valid and to ensure valid training and testing. + +.. note:: + + If you notice any bugs with training and testing, please report it with an issue. + +If the extra parameters are not passed, we use our default ones. +For optimization, we use sklearn's ``GridSearchCV``. As we explained, you can specify the param grid, +otherwise we use our default. As metrics, we use ``AUC``, ``Accuracy``, ``Sensitivity``, ``Specificity``, +``Precision``, ``Recall`` and ``F1`` for classification and ``MAE``, ``RMSE`` and ``R2`` for regression. Also note that by default, the model performs regression, +so always **make sure that you specified the task if you want to perform classification**. +You can always get all the stats with the ``get_stats`` function and print them with ``output_stats``. + +************** +MLP with torch +************** + +The MLP model implemented with torch can be found at `mlp_torch.py <../../../spare_scores/mlp_torch.py>`_. +The torch MLP model class takes a total of 4 arguments, plus, extra parameters if needed. + +.. code-block:: python + + def __init__( + self, + predictors: list, + to_predict: str, + key_var: str, + verbose: int = 1, + **kwargs: Any, + ) -> None + +As you can see, it's the same parameters as the sklearn implementation. Valid extra parameters +are "task", "bs"(batch size) and "num_epochs". We use the same metrics as the sklearn model, but now, +we perform optimization with optuna instead of GridSearchCV. Each fit creates an optuna study that tries +to maximize the values if the task is classification, otherwise, trying to minimize the error if the task is +regression. +You can always get all the stats with the ``get_stats`` function and print them with ``output_stats``. + + +Note that the MLP implementation exists at a different class in the same file with name ``SimpleMLP``. +Also, we implemented a class to manage the data we pass to our MLP model. This class also exists in the +same file with name ``MLPDataset``. + +SVM model +_________ + +The SVM model can be found at `svm.py <../../../spare_scores/svm.py>`_. +The SVL model class takes a total of 4 arguments, plus, extra parameters if needed. + +.. code-block:: python + + def __init__( + self, + predictors: list, + to_predict: str, + key_var: str, + verbose: int = 1, + **kwargs: Any, + ) -> None + +As you can see again, it's the same parameters as the other models. Valid extra parameters are +"kernel", "k", "n_repeats", "task" and "param_grid". If the task is classification and the kernel is +linear, we use ``LinearSVC``, if the kernel is not linear(i.e. rbf) we use ``SVC``. If the task is regression we use +``LinearSVR`` with ``squared epsilon insensitive`` as a loss function. As metrics, we use ``AUC``, ``Accuracy``, +``Sensitivity``, ``Specificity``, ``Precision``, ``Recall`` and ``F1`` for classification and ``MAE``, ``RMSE`` and ``R2`` +for regression. +You can always get all the stats with the ``get_stats`` function and print them with ``output_stats``. diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..3c92506 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,35 @@ +##### +Usage +##### + +In order to use ``spare_scores``, you have to use our CLI. The CLI can perform training and testing. For training we use 2 models, a SVM and +a MLP. To perform **training**, you can just do: :: + + $ spare_score --action train \ + --input spare_scores/data/example_data.csv \ + --predictors H_MUSE_Volume_11 H_MUSE_Volume_23 H_MUSE_Volume_30 \ + --ignore_vars Sex \ + --to_predict Age \ + --kernel linear \ + --verbose 2 \ + --output my_model.pkl.gz + +- With the ``--action`` parameter, you specify if you want to perform training or testing. +- With the ``--input`` parameter, you specify the directory of the input data(has to be .csv). +- The ``--predictors`` parameter is a list that represents the columns that will be used by the models for training. +- With the ``--ignore_vars`` parameter, you specify(if needed) any columns than you want the models to ignore. +- ``--to_predict`` represents the target column. +- ``--kernel`` represents the kernel of regression/classification. Currently only ``linear`` is supported as an option for regression. +- ``--verbose`` you can pass a value != 0 to enable verbosity on training/testing. +- With the ``--output`` parameter, you specify the directory of the output. This is where the trained model will be saved. + +To perform **testing**, you can just do: :: + + $ spare_score -a test \ + -i spare_scores/data/example_data.csv \ + --model my_model.pkl.gz \ + -o test_spare_data.csv \ + -v 0 \ + --logs test_logs.txt + +The only new parameter here is ``--logs`` that represents the filename of the logger. From 70be590ed2ccd01459ca8471ab72e8364857a89f Mon Sep 17 00:00:00 2001 From: Spiros Maggioros Date: Sat, 30 Nov 2024 12:44:04 +0200 Subject: [PATCH 2/4] [Update] Fix authors and conf --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c9ec5d6..f5de87c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,8 +12,8 @@ sys.path.insert(0, os.path.abspath("../")) project = "spare scores" -copyright = "2024, Ashish Singh, Guray Erus, George Aidinis" -author = "Ashish Singh, Guray Erus, George Aidinis" +copyright = "2024, Gyujoon Hwang, George Aidinis" +author = "Gyujoon Hwang, George Aidinis" release = "2024" # -- General configuration --------------------------------------------------- From 649370a4fee9f0d7bc1857ba98755f672493de2f Mon Sep 17 00:00:00 2001 From: Spiros Maggioros Date: Sat, 30 Nov 2024 12:45:58 +0200 Subject: [PATCH 3/4] [Update] Add title to README --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 959ffe6..70e8422 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,6 @@ +spare scores +============ + .. image:: https://codecov.io/gh/CBICA/spare_score/graph/badge.svg?token=7yk7pkydHE :target: https://codecov.io/gh/CBICA/spare_score From 2c703b4e953a7404178e12f9b73413469a663855 Mon Sep 17 00:00:00 2001 From: Spiros Maggioros Date: Sat, 30 Nov 2024 12:46:52 +0200 Subject: [PATCH 4/4] [BUG] Fix readme.md error at setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3c373f7..944890a 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import find_packages, setup this_directory = Path(__file__).parent -long_description = (this_directory / "README.md").read_text() +long_description = (this_directory / "README.rst").read_text() setup( name="spare_scores",