{"id":19735991,"url":"https://github.com/m-pilia/disptools","last_synced_at":"2025-10-15T23:02:29.304Z","repository":{"id":31598769,"uuid":"125835343","full_name":"m-pilia/disptools","owner":"m-pilia","description":"Generate displacement fields with known volume changes","archived":false,"fork":false,"pushed_at":"2024-09-06T18:04:22.000Z","size":7649,"stargazers_count":24,"open_issues_count":7,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-16T00:12:47.278Z","etag":null,"topics":["cuda","image-processing","jacobian","python3"],"latest_commit_sha":null,"homepage":"https://martinopilia.com/disptools","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m-pilia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-19T09:44:06.000Z","updated_at":"2025-01-08T14:04:00.000Z","dependencies_parsed_at":"2022-08-07T16:30:35.083Z","dependency_job_id":null,"html_url":"https://github.com/m-pilia/disptools","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fdisptools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fdisptools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fdisptools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fdisptools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m-pilia","download_url":"https://codeload.github.com/m-pilia/disptools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251642954,"owners_count":21620397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cuda","image-processing","jacobian","python3"],"created_at":"2024-11-12T01:04:38.812Z","updated_at":"2025-10-15T23:02:29.196Z","avatar_url":"https://github.com/m-pilia.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"disptools\n=========\nGenerate displacement fields with known volume changes\n------------------------------------------------------\n[![GitHub release](https://img.shields.io/github/release/m-pilia/disptools.svg)](https://github.com/m-pilia/disptools/releases/latest)\n[![PyPI](https://img.shields.io/pypi/v/disptools.svg)](https://pypi.python.org/pypi/disptools)\n[![Wheels](https://img.shields.io/pypi/wheel/disptools.svg)](https://pypi.org/project/disptools)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/m-pilia/disptools/blob/master/LICENSE)\n[![GitHub Actions](https://github.com/m-pilia/disptools/workflows/ChecksLinux/badge.svg)](https://github.com/m-pilia/disptools/actions/workflows/checks_linux.yml)\n[![codecov](https://codecov.io/gh/m-pilia/disptools/branch/master/graph/badge.svg)](https://codecov.io/gh/m-pilia/disptools/branch/master)\n[![Downloads](https://pepy.tech/badge/disptools)](https://pepy.tech/project/disptools)\n\nThis library provides utilities to generate and manipulate displacement fields with known volume changes. It implements three search-based algorithms for the generation of deformation fields, along with a small collection of utility functions, and provides optional GPU acceleration through a CUDA implementation.\n\nThe three algorithms implemented are referred as:\n+ \u003ctt\u003egradient\u003c/tt\u003e: a gradient descent method (default).\n+ \u003ctt\u003egreedy\u003c/tt\u003e: a greedy search method proposed in [[1]](#1).\n+ \u003ctt\u003ematching\u003c/tt\u003e: a volume matching method proposed in [[2]](#2) and [[3]](#3). The implementation comes from the [PREDICT atrophysim tool](https://www.nitrc.org/projects/atrophysim).\n\nThe library is built on top of SimpleITK, in order to provide a simple yet powerful set of functionalities for image analysis. Images stored as numpy arrays can be easily converted from and to [SimpleITK](http://simpleitk.github.io/SimpleITK-Notebooks/01_Image_Basics.html) and [ITK](https://blog.kitware.com/convert-itk-data-structures-to-numpy-arrays/) image objects.\n\n### Documentation\n\nThe complete documentation for this package is available on https://martinopilia.com/disptools.\n\n### Quick example\n```python\nimport SimpleITK as sitk\nimport disptools.displacements as dsp\nimport disptools.drawing as drw\n\n# Create an example Jacobian map\n# A spherical ROI with a Jacobian of 1.1 (expansion)\njacobian = drw.create_sphere(10, 40, fg_val=1.1, bg_val=1.0)\n\n# Create a binary mask for the ROI\nmask = drw.create_sphere(10, 40) \u003e 0\n\n# Generate the displacement\ndisplacement = dsp.displacement(jacobian, mask=mask)\n\n# Check the correctness of the result within the ROI\nerror = jacobian - dsp.jacobian(displacement)\nerror = sitk.Mask(error, mask)\n```\n\nA 3D rendering of the resulting displacement field with [ParaView](https://www.paraview.org/), and a visualisation of the the error on the Jacobian within the ROI:\n\n\u003cimg src=\"https://github.com/m-pilia/disptools/blob/master/sphinx/img/example_2.png?raw=true\" alt=\"displacement\" width=45% /\u003e \u003cimg src=\"https://github.com/m-pilia/disptools/blob/master/sphinx/img/example_1.png?raw=true\" alt=\"error\" width=45% /\u003e\n\n### Architecture\n\nThe project is structured in three layers:\n+ a pure standard [C99](https://en.wikipedia.org/wiki/C99) library (whose headers are in \u003ctt\u003esrc/headers\u003c/tt\u003e), with no external dependencies, implementing the core algorithms for the generation of deformation fields. It is a standalone library that can be directly included in a C or C++ project. It is paired with an optional [CUDA](https://en.wikipedia.org/wiki/CUDA) library, whose headers are in \u003ctt\u003ecuda/headers\u003c/tt\u003e, that depends on \u003ctt\u003esrc/headers\u003c/tt\u003e and provides a GPGPU implementation of the key routines.\n+ a [Python C extension](https://docs.python.org/3.6/extending/extending.html) package \u003ctt\u003e_disptools\u003c/tt\u003e (whose source is in the file \u003ctt\u003epython_c_extension/_disptools.c\u003c/tt\u003e), providing a bare Python wrapper to the aforementioned library, using the [NumPy C API](https://docs.scipy.org/doc/numpy-1.14.0/reference/c-api.html) to pass arrays. This can be directly included in a Python project with no dependencies other than NumPy.\n+ a Python package (\u003ctt\u003edisptools\u003c/tt\u003e), that wraps the \u003ctt\u003e_disptools\u003c/tt\u003e package providing file IO (through SimpleITK) and implementing high-level features (such as the multi-resolution framework) and auxiliary utilities and functions.\n    - \u003ctt\u003edisptools.displacements\u003c/tt\u003e: module providing the main functions for the generation and manipulation of displacement fields.\n    - \u003ctt\u003edisptools.drawing\u003c/tt\u003e: collection of utilities to create test images.\n    - \u003ctt\u003edisptools.io\u003c/tt\u003e: collection of utilities to read and write to file.\n    - \u003ctt\u003edisptools.measure\u003c/tt\u003e: collection of utilities to measure some image features.\n    - \u003ctt\u003edisptools.simulatrophy\u003c/tt\u003e: routines to interface with the [Simul@atrophy](https://github.com/Inria-Asclepios/simul-atrophy) tool.\n    - \u003ctt\u003edisptools.predict\u003c/tt\u003e: routines to interface with the [PREDICT](https://www.nitrc.org/projects/atrophysim) tool.\n\n### Install\n\nThis package is available on [PyPI](https://pypi.org/project/disptools) both as source distribution and as a Windows pre-compiled binary wheel. You can install it with \u003ctt\u003epip\u003c/tt\u003e:\n```bash\n python3 -m pip install disptools\n```\n\nAs always, it is recommended to use the package inside a [virtual environment](https://docs.python.org/3/tutorial/venv.html).\n\n### Build from source\n\n#### Requirements\n\nRequirements are specified by the \u003ctt\u003erequirements.txt\u003c/tt\u003e file and can be installed with \u003ctt\u003epip\u003c/tt\u003e.\n```bash\npython3 -m pip install -r requirements.txt\n```\n\nThe library is a cross-platform Python 3.5+ package, with a compiled C extension. The Python dependencies are:\n+ [numpy](https://github.com/numpy/numpy) ([pypi package](https://pypi.python.org/pypi/numpy))\n+ [scipy](https://github.com/scipy/scipy) ([pypi package](https://pypi.org/pypi/scipy))\n+ [SimpleITK](https://github.com/SimpleITK/SimpleITK) ([pypi package](https://pypi.org/pypi/SimpleITK))\n\nBuild dependencies are a standard C compiler (tested with gcc 8.2 on Linux, mingw-w64 7.2 and MSVC 19 on Windows 10), [CMake](https://cmake.org/), the [numpy](https://pypi.python.org/pypi/numpy) and the [setuptools](https://pypi.python.org/pypi/setuptools) packages. [scikit-build](https://pypi.python.org/pypi/scikit-build) may be required to build the other Python dependencies.\n\nSome optional dependencies are required only for a limited set of features, and the package should build and run without them:\n+ [itk](https://github.com/InsightSoftwareConsortium/ITK) ([pypi package](https://pypi.org/project/itk)): for \u003ctt\u003edisptools.drawing.sitk_to_itk\u003c/tt\u003e\n+ [vtk](https://github.com/Kitware/VTK) ([pypi package](https://pypi.org/project/vtk)): for \u003ctt\u003edisptools.io.write_vtk_points\u003c/tt\u003e\n+ [ply](https://github.com/dabeaz/ply) ([pypi package](https://pypi.org/project/ply)): for \u003ctt\u003edisptools.io.read_elastix_parameters\u003c/tt\u003e\n+ [scikit-image](https://github.com/scikit-image/scikit-image) ([pypi package](https://pypi.org/project/scikit-image)): for some features of \u003ctt\u003edisptools.drawing.extract_slice\u003c/tt\u003e, and to run the unit tests\n\n#### Build options\n\nThe following environment variables affect the \u003ctt\u003esetup.py\u003c/tt\u003e:\n+ \u003ctt\u003eDISPTOOLS_OPT=ON\u003c/tt\u003e: enable non-portable optimisations.\n+ \u003ctt\u003eDISPTOOLS_DEBUG=ON\u003c/tt\u003e: disable optimisations, compile with debug symbols.\n+ \u003ctt\u003eDISPTOOLS_CUDA_SUPPORT=ON\u003c/tt\u003e: enable CUDA support.\n\n#### Windows (Visual Studio) and Linux\n\nInstall the dependencies with your favourite package manager. For example, with \u003ctt\u003epip\u003c/tt\u003e:\n```bash\npython3 -m pip install -r requirements.txt\n```\n\nThe package provides a \u003ctt\u003esetuptools\u003c/tt\u003e based install script. To install the library, run from the project root folder\n```bash\npython3 setup.py install\n```\nwhich should build the C extension and install the Python package.\n\n#### Windows (MinGW)\n\n1. First, be sure that [mingw](https://mingw-w64.org), CMake and Python are installed and their executables [are in your PATH](https://docs.python.org/3/using/windows.html#excursus-setting-environment-variables).\n\n2. Ensure that \u003ctt\u003egcc\u003c/tt\u003e is working correctly:\n```none\n\u003e gcc --version\ngcc (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 7.2.0\nCopyright (C) 2017 Free Software Foundation, Inc.\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n```\n\n3. Ensure that \u003ctt\u003edistutils\u003c/tt\u003e correctly recognises your version of Visual Studio (even when using \u003ctt\u003emingw\u003c/tt\u003e). Open the file \u003ctt\u003eC:\\Users\\yourname\\AppData\\Local\\Programs\\Python\\Python3x\\Lib\\distutils\\cygwinccompiler.py\u003c/tt\u003e (the exact location may vary according to your setup) and check that your version of Visual Studio is present in the function \u003ctt\u003eget_msvcr()\u003c/tt\u003e; if not, adjust it according to the following:\n```python\ndef get_msvcr():\n    \"\"\"Include the appropriate MSVC runtime library if Python was built\n    with MSVC 7.0 or later.\n    \"\"\"\n    msc_pos = sys.version.find('MSC v.')\n    if msc_pos != -1:\n        msc_ver = sys.version[msc_pos+6:msc_pos+10]\n        if msc_ver == '1300':\n            # MSVC 7.0\n            return ['msvcr70']\n        elif msc_ver == '1310':\n            # MSVC 7.1\n            return ['msvcr71']\n        elif msc_ver == '1400':\n            # VS2005 / MSVC 8.0\n            return ['msvcr80']\n        elif msc_ver == '1500':\n            # VS2008 / MSVC 9.0\n            return ['msvcr90']\n        elif msc_ver == '1600':\n            # VS2010 / MSVC 10.0\n            return ['msvcr100']\n        elif msc_ver == '1700':\n            # Visual Studio 2012 / Visual C++ 11.0\n            return ['msvcr110']\n        elif msc_ver == '1800':\n            # Visual Studio 2013 / Visual C++ 12.0\n            return ['msvcr120']\n        elif msc_ver == '1900':\n            # Visual Studio 2015 / Visual C++ 14.0\n            # \"msvcr140.dll no longer exists\" http://blogs.msdn.com/b/vcblog/archive/2014/06/03/visual-studio-14-ctp.aspx\n            return ['vcruntime140']\n        else:\n            raise ValueError(\"Unknown MS Compiler version %s \" % msc_ver)\n```\n\n4. Ensure that the library \u003ctt\u003evcruntime140.dll\u003c/tt\u003e is present in your library path. Otherwise, download it and place it in \u003ctt\u003eC:\\Users\\yourname\\AppData\\Local\\Programs\\Python\\Python3x\\libs\u003c/tt\u003e (the exact path may vary according to your setup).\n\n5. Clone the sources of this package with \u003ctt\u003egit\u003c/tt\u003e, or download and extract them as a \u003ctt\u003ezip\u003c/tt\u003e archive. Move to the root folder of the sources (\u003ctt\u003eC:\\Users\\yourname\\disptools\u003c/tt\u003e in this example), specify the right compiler, and launch the setup script to build and install the package.\n```cmd\n\u003e cd C:\\Users\\yourname\\disptools\n\u003e python setup.py setopt --command=build --option=compiler --set-value=mingw32\n\u003e python -m pip install -r requirements.txt\n\u003e python setup.py install\n```\n\n### References\n+ \u003ca id=\"1\"\u003e\u003c/a\u003e[1] van Eede, M. C., Scholz, J., Chakravarty, M. M., Henkelman, R. M., and Lerch, J. P. *Mapping registration sensitivity in MR mouse brain images.* Neuroimage 82 (2013), 226–236.\n+ \u003ca id=\"2\"\u003e\u003c/a\u003e[2] Karaçali, B., and Davatzikos, C. *Estimating topology preserving and smooth displacement fields.* IEEE Transactions on Medical Imaging 23, 7 (2004), 868–880.\n+ \u003ca id=\"3\"\u003e\u003c/a\u003e[3] Karaçali, B., and Davatzikos, C. *Simulation of tissue atrophy using a topology preserving transformation model.* IEEE transactions on medical imaging 25, 5 (2006), 649–652.\n\n### License\n\nThe software is distributed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-pilia%2Fdisptools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm-pilia%2Fdisptools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-pilia%2Fdisptools/lists"}