From 3ed1b9a028fff9264c144693f6e1bd8b92b40c4c Mon Sep 17 00:00:00 2001 From: Lucas Gandel Date: Mon, 27 Apr 2020 10:35:19 +0200 Subject: [PATCH] ENH: Setup Sphinx documentation --- .readthedocs.yml | 20 ++++++ CMakeLists.txt | 7 +- GettingStarted.md | 4 +- conf.py | 66 +++++++++++++++++++ documentation/docs/CMakeLists.txt | 39 +++++++++++ .../docs/ExternalData/FetchExternalData.cmake | 28 ++++++++ documentation/docs/README.md | 57 ++++++++++++++++ documentation/{ => docs}/Release.md | 0 documentation/docs/requirements.txt | 5 ++ examples/FDK/Code2D.sh | 12 ++++ examples/FDK/Code3D.sh | 12 ++++ examples/FDK/README.md | 25 +++++++ .../FDK/SheppLogan-2D-Sinogram.png.sha512 | 1 + examples/FDK/SheppLogan-2D.png.sha512 | 1 + .../FDK/SheppLogan-3D-Sinogram.png.sha512 | 1 + examples/FDK/SheppLogan-3D.png.sha512 | 1 + examples/index.md | 8 +++ index.md | 34 ++++++++++ 18 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 .readthedocs.yml create mode 100644 conf.py create mode 100644 documentation/docs/CMakeLists.txt create mode 100644 documentation/docs/ExternalData/FetchExternalData.cmake create mode 100644 documentation/docs/README.md rename documentation/{ => docs}/Release.md (100%) create mode 100644 documentation/docs/requirements.txt create mode 100644 examples/FDK/Code2D.sh create mode 100644 examples/FDK/Code3D.sh create mode 100644 examples/FDK/README.md create mode 100644 examples/FDK/SheppLogan-2D-Sinogram.png.sha512 create mode 100644 examples/FDK/SheppLogan-2D.png.sha512 create mode 100644 examples/FDK/SheppLogan-3D-Sinogram.png.sha512 create mode 100644 examples/FDK/SheppLogan-3D.png.sha512 create mode 100644 examples/index.md create mode 100644 index.md diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000..a05f76220 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,20 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + apt_packages: + - fonts-roboto + +sphinx: + configuration: documentation/docs/conf.py + +python: + install: + - requirements: documentation/docs/requirements.txt \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dd7e6f72..71497c63f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,12 +124,17 @@ configure_file(${RTK_SOURCE_DIR}/rtkConfiguration.h.in ${RTK_BINARY_DIR}/rtkConfiguration.h) #========================================================= -# If choose to build documentation, then search for Doxygen executables. +# If choose to build documentation, then search for Doxygen/Sphinx executables. option(RTK_BUILD_DOXYGEN "Build Doxygen Documentation" OFF) if(RTK_BUILD_DOXYGEN) add_subdirectory(documentation/Doxygen) endif() +option(RTK_BUILD_SPHINX "Build Sphinx Documentation" OFF) +if(RTK_BUILD_SPHINX) + add_subdirectory(documentation/docs) +endif() + # Setup build locations. if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${RTK_BINARY_DIR}/bin) diff --git a/GettingStarted.md b/GettingStarted.md index 697086c9d..ee187a4fa 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -5,8 +5,8 @@ Here are suggested steps for the RTK beginner. 1. Install the software following [INSTALLATION.md](INSTALLATION.md). - 2. If you are not already familiar with ITK, [get started with ITK](https://github.com/InsightSoftwareConsortium/ITK/blob/master/GettingStarted.md). + 2. If you are not already familiar with ITK, [get started with ITK](https://github.com/InsightSoftwareConsortium/ITK/blob/master/GettingStarted.md#L1). - 3. Check out the [FirstReconstruction](examples/FirstReconstruction) example (both the [CMake](examples/FirstReconstruction/CMakeLists.txt) and the [C++](examples/FirstReconstruction/FirstReconstruction.cxx) codes). Many other examples are on the wiki using the applications (corresponding source code in the [applications](applications) subdirectory). + 3. Check out the [FirstReconstruction](https://github.com/SimonRit/RTK/blob/master/examples/FirstReconstruction) example (both the [CMake](https://github.com/SimonRit/RTK/blob/master/examples/FirstReconstruction/CMakeLists.txt) and the [C++](https://github.com/SimonRit/RTK/blob/master/examples/FirstReconstruction/FirstReconstruction.cxx) codes). Many other examples are on the wiki using the applications (corresponding source code in the [applications](https://github.com/SimonRit/RTK/blob/master/applications) subdirectory). 4. Ask question to the [user mailing list](https://www.creatis.insa-lyon.fr/mailman/listinfo/rtk-users). diff --git a/conf.py b/conf.py new file mode 100644 index 000000000..d202dfdd9 --- /dev/null +++ b/conf.py @@ -0,0 +1,66 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +from datetime import date + +import subprocess + +# -- Build setup ------------------------------------------------------------- +def setup(app): + # Fetch documentation images + subprocess.check_call("cmake -P documentation/docs/ExternalData/FetchExternalData.cmake", stderr=subprocess.STDOUT, shell=True) + +# -- Project information ----------------------------------------------------- +project = 'RTK' +copyright = f'{date.today().year}, Simon Rit' +author = 'RTK Consortium' + +# The full version, including alpha/beta/rc tags +# release = '2.6.0' + +# -- General configuration --------------------------------------------------- +extensions = [ + 'myst_parser', + 'sphinx_copybutton', +] + +myst_enable_extensions = [ + "attrs_inline", # inline image attributes + "colon_fence", + "dollarmath", # Support syntax for inline and block math using `$...$` and `$$...$$` + # (see https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#dollar-delimited-math) + "fieldlist", + "linkify", # convert bare links to hyperlinks +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# -- Options for HTML output ------------------------------------------------- +html_theme = 'furo' + +# Furo options +html_theme_options = { + "top_of_page_button": "edit", + "source_repository": "https://github.com/RTKConsortium/RTK/", + "source_branch": "master", + "source_directory": "", +} + +# Add any paths that contain custom static files (such as style sheets or icons) +# here, relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [] +html_logo = "https://www.openrtk.org/opensourcelogos/rtk75.png" +html_title = f"{project}'s documentation" + +# -- Master document ------------------------------------------------- +master_doc = 'index' diff --git a/documentation/docs/CMakeLists.txt b/documentation/docs/CMakeLists.txt new file mode 100644 index 000000000..7d5c2e8d5 --- /dev/null +++ b/documentation/docs/CMakeLists.txt @@ -0,0 +1,39 @@ +if(RTK_BUILD_SPHINX) + + # Build sphinx documentation in the build directory + set(RTK_DOC_OUTPUT_DIR ${CMAKE_BINARY_DIR}/sphinx) + + # Copy the source tree documentation to the build tree before calling sphinx. + # The images are downloaded when conf.py is run by sphinx. + add_custom_target(copy_sources ALL + COMMAND ${CMAKE_COMMAND} -E copy_directory "${RTK_SOURCE_DIR}/examples" "${RTK_DOC_OUTPUT_DIR}/examples" + COMMAND ${CMAKE_COMMAND} -E copy_directory "${RTK_SOURCE_DIR}/documentation" "${RTK_DOC_OUTPUT_DIR}/documentation" + COMMAND ${CMAKE_COMMAND} -E copy "${RTK_SOURCE_DIR}/conf.py" "${RTK_DOC_OUTPUT_DIR}/conf.py" + COMMAND ${CMAKE_COMMAND} -E copy "${RTK_SOURCE_DIR}/index.md" "${RTK_DOC_OUTPUT_DIR}/index.md" + COMMAND ${CMAKE_COMMAND} -E copy "${RTK_SOURCE_DIR}/GettingStarted.md" "${RTK_DOC_OUTPUT_DIR}/GettingStarted.md" + COMMAND ${CMAKE_COMMAND} -E copy "${RTK_SOURCE_DIR}/INSTALLATION.md" "${RTK_DOC_OUTPUT_DIR}/INSTALLATION.md" + COMMENT "Copying documentation sources" + ) + + find_program(SPHINX_EXECUTABLE + NAMES sphinx-build sphinx-build.exe + DOC "Sphinx documentation generator" + ) + + add_custom_target( sphinx_doc ALL + COMMAND ${SPHINX_EXECUTABLE} + -c ${RTK_DOC_OUTPUT_DIR} # conf.py directory + ${RTK_DOC_OUTPUT_DIR} # Source directory containing root index.md + "${RTK_DOC_OUTPUT_DIR}/_build" # Output directory + COMMENT "Generating sphinx documentation" + DEPENDS copy_sources + WORKING_DIRECTORY ${RTK_DOC_OUTPUT_DIR} + ) + + set_property( + DIRECTORY APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES + "${RTK_DOC_OUTPUT_DIR}/_build" + ) + +endif() diff --git a/documentation/docs/ExternalData/FetchExternalData.cmake b/documentation/docs/ExternalData/FetchExternalData.cmake new file mode 100644 index 000000000..a43f0bece --- /dev/null +++ b/documentation/docs/ExternalData/FetchExternalData.cmake @@ -0,0 +1,28 @@ +# Fetch external data from https://data.kitware.com +# Used by Sphinx conf.py during setup. +# +set(link_content sha512) + +if(NOT EXTERNAL_DATA_INPUT_ROOT) + set(EXTERNAL_DATA_INPUT_ROOT "${CMAKE_SOURCE_DIR}") +endif() + +if(NOT EXTERNAL_DATA_OUTPUT_ROOT) + set(EXTERNAL_DATA_OUTPUT_ROOT "${CMAKE_SOURCE_DIR}") +endif() + +file(GLOB_RECURSE content_files + "${EXTERNAL_DATA_INPUT_ROOT}/*${link_content}") + +foreach(content_file ${content_files}) + + file(RELATIVE_PATH content_file_rel_path ${EXTERNAL_DATA_INPUT_ROOT} ${content_file}) + get_filename_component(last_ext "${content_file_rel_path}" LAST_EXT) + string(REPLACE "${last_ext}" "" content_file_rel_path "${content_file_rel_path}") + + file(READ "${content_file}" hash) + set(URL "https://data.kitware.com:443/api/v1/file/hashsum/${link_content}/${hash}/download") + string(REGEX REPLACE "\n" "" URL "${URL}") + file(DOWNLOAD "${URL}" "${EXTERNAL_DATA_OUTPUT_ROOT}/${content_file_rel_path}") + +endforeach() diff --git a/documentation/docs/README.md b/documentation/docs/README.md new file mode 100644 index 000000000..7a8d3681c --- /dev/null +++ b/documentation/docs/README.md @@ -0,0 +1,57 @@ +# Contribute documentation improvements + +Thank you for improving our documentation! + +The sources of the RTK documentation are spread across the RTK source tree in multiple markdown (.md) files. +Edit existing documentation files, add new examples or documentation files, and open a merge request on the RTK repository. + +## Add a new documentation page +To add a new page to the documentation, create a new .md file in the RTK source tree. +Write plain markdown text or use the [MyST](https://myst-parser.readthedocs.io/en/latest/index.html) syntax to include technical and scientific content. +The MyST extension enabled when building the documentation are defined by the `myst_enable_extensions` variable in the sphinx `conf.py` configuration file. + +The new documentation page will appear in the documentation after being referenced in a `toctree` element of an `index.md` file. +Index files are markdown files using [TOC tree](https://sphinx-doc-zh.readthedocs.io/en/latest/markup/toctree.html) elements to define the table of content and sections of the documentation. +Add a reference to your new page in an existing section by adding the path to your file, relative to the `index.md` file, in an existing TOC tree element. +You may also add new `toctree` elements and new `index.md` file as needed. + +### Inline images +Images can be referenced with their URL in markdown, but this can delay their presentation in the page. +Another option is to store the images in the [RTK collection](https://data.kitware.com/?#collection/5a7706878d777f0649e04776/folder/5eaeaa2f9014a6d84e47adb3) on data.kitware.com and to push their content file (SHA512) to the RTK source tree. +Such images will be automatically downloaded when building the documentation and served as static files when navigating. +To add a new image: +1. Go to the [RTKDocumentationData](https://data.kitware.com/?#collection/5a7706878d777f0649e04776/folder/5eaeaa2f9014a6d84e47adb3) folder on data.kitware.com +2. Choose a folder or create a new one and click the "Upload here" button to drag & drop your images. +3. Once uploaded, click on the file to open its information page. +4. Under the "Files & Links" section click the information icon ("Show info") next to the file name +5. Download the key file from the SHA-512 section by pressing the key icon +6. Place this file in the RTK source tree next to the .md file that uses it + +The image can be referenced in markdown, e.g. `![img_2D](SheppLogan-2D.png){w=200px alt="Shepp-Logan 2D image"}` + +### Inline code +Code blocks from external files can also be included in the documentation pages using the [literalinclude](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-literalinclude) directive. +~~~ +```{literalinclude} code.py +``` +~~~ + +### Add an example +Create a new directory in the examples directory to place the example scripts. +Then add the content link files of the screenshots to presented in the documentation by following the instructions from the "Inline images" section above. +Include the images and scripts in a `README.md` file describing the example. +Add a reference to the README file in the `examples/index.md` to add the new example page to the documentation + +## Preview changes + +To preview documentation changes, build and serve the documentation locally: + +1. Install sphinx and the required packages: +```bash +cd RTK/documentation/docs +pip install -r requirements.txt +``` +2. Configure RTK with the CMake option `RTK_BUILD_SPHINX` turned on +3. Build the `sphinx_doc` target and open the `index.html` file generated in `RTK-build/sphinx/sphinx_build` + +The documentation is generated in the RTK build tree by first copying the documentation sources. To make sure new files are included in the local documentation builds, check that they belong to the list of files and directories copied by the `copy_sources` target in `documentation/docs/CMakeLists.txt`. \ No newline at end of file diff --git a/documentation/Release.md b/documentation/docs/Release.md similarity index 100% rename from documentation/Release.md rename to documentation/docs/Release.md diff --git a/documentation/docs/requirements.txt b/documentation/docs/requirements.txt new file mode 100644 index 000000000..dfb29ddb3 --- /dev/null +++ b/documentation/docs/requirements.txt @@ -0,0 +1,5 @@ +cmake +furo +myst-parser[linkify] +sphinx>=7.2.6 +sphinx-copybutton \ No newline at end of file diff --git a/examples/FDK/Code2D.sh b/examples/FDK/Code2D.sh new file mode 100644 index 000000000..d02b8a858 --- /dev/null +++ b/examples/FDK/Code2D.sh @@ -0,0 +1,12 @@ +# Create a simulated geometry +rtksimulatedgeometry -n 180 -o geometry.xml + +# Create projections of the phantom file +# Note the sinogram being 3 pixels wide in the y direction to allow back-projection interpolation in a 2D image +rtkprojectgeometricphantom -g geometry.xml -o projections.mha --spacing 2 --dimension=512,3,512 --phantomfile SheppLogan-2d.txt --phantomscale=256,1,256 + +# Reconstruct +rtkfdk -p . -r projections.mha -o fdk.mha -g geometry.xml --spacing 2 --dimension 256,1,256 + +# Create a reference volume for comparison +rtkdrawgeometricphantom --spacing 2 --dimension=256,1,256 --phantomfile SheppLogan-2d.txt -o ref.mha --phantomscale=256,1,256 diff --git a/examples/FDK/Code3D.sh b/examples/FDK/Code3D.sh new file mode 100644 index 000000000..c0176aa3a --- /dev/null +++ b/examples/FDK/Code3D.sh @@ -0,0 +1,12 @@ +# Create a simulated geometry +rtksimulatedgeometry -n 180 -o geometry.xml +# You may add "--arc 200" to make the scan short or "--proj_iso_x 200" to offset the detector + +# Create projections of the phantom file +rtkprojectgeometricphantom -g geometry.xml -o projections.mha --spacing 2 --dimension 256 --phantomfile SheppLogan.txt + +# Reconstruct +rtkfdk -p . -r projections.mha -o fdk.mha -g geometry.xml --spacing 2 --dimension 256 + +# Create a reference volume for comparison +rtkdrawgeometricphantom --spacing 2 --dimension 256 --phantomfile SheppLogan.txt -o ref.mha diff --git a/examples/FDK/README.md b/examples/FDK/README.md new file mode 100644 index 000000000..d8f16f92a --- /dev/null +++ b/examples/FDK/README.md @@ -0,0 +1,25 @@ +# FDK + +Reconstruction of the Shepp–Logan phantom using Feldkamp, David and Kress cone-beam reconstruction. + +## 3D + +![sin_3D](SheppLogan-3D-Sinogram.png){w=200px alt="Shepp-Logan 3D sinogram"} +![img_3D](SheppLogan-3D.png){w=200px alt="Shepp-Logan 3D image"} + +This script uses the file [SheppLogan.txt](https://data.kitware.com/api/v1/item/5b179c938d777f15ebe2020b/download) as input. + +```{literalinclude} Code3D.sh +``` + +## 2D + +![sin_2D](SheppLogan-2D-Sinogram.png){w=200px alt="Shepp-Logan 2D sinogram"} +![img_2D](SheppLogan-2D.png){w=200px alt="Shepp-Logan 2D image"} + +The same reconstruction can be performed using the original 2D Shepp-Logan phantom. +RTK can perform 2D reconstructions through images wide of 1 pixel in the y direction. +The following script performs the same reconstruction as above in a 2D environment and uses the [2D Shepp-Logan](http://wiki.openrtk.org/images/7/73/SheppLogan-2d.txt) phantom as input. + +```{literalinclude} Code2D.sh +``` diff --git a/examples/FDK/SheppLogan-2D-Sinogram.png.sha512 b/examples/FDK/SheppLogan-2D-Sinogram.png.sha512 new file mode 100644 index 000000000..a0bb763ee --- /dev/null +++ b/examples/FDK/SheppLogan-2D-Sinogram.png.sha512 @@ -0,0 +1 @@ +682d8c73cdb927fdfe6c68e224fbd99c9e39f7358eb7cab7964301eb6f83b1140aaa0d3560cdff421e047a2492116896187b01760ba3e195df03c8f2c66c7a4a \ No newline at end of file diff --git a/examples/FDK/SheppLogan-2D.png.sha512 b/examples/FDK/SheppLogan-2D.png.sha512 new file mode 100644 index 000000000..35844c515 --- /dev/null +++ b/examples/FDK/SheppLogan-2D.png.sha512 @@ -0,0 +1 @@ +7512e4922f53f636b0867a7440627173e58d05f43d9fd6770e16dab2fc6073b5cff5a0e9c7734da9ffdfd2b4f111a828dd7df642ab8cccd8ef9f195b5e8a1dab \ No newline at end of file diff --git a/examples/FDK/SheppLogan-3D-Sinogram.png.sha512 b/examples/FDK/SheppLogan-3D-Sinogram.png.sha512 new file mode 100644 index 000000000..3ee68262a --- /dev/null +++ b/examples/FDK/SheppLogan-3D-Sinogram.png.sha512 @@ -0,0 +1 @@ +6f448c7ff88f2703dbf5e0ca226c441d819b74785992a5b84cb5ac68b09efab04802e984df603c8f9bbec6fc295719cd947d002740ba99241f41b04e9741d5ec \ No newline at end of file diff --git a/examples/FDK/SheppLogan-3D.png.sha512 b/examples/FDK/SheppLogan-3D.png.sha512 new file mode 100644 index 000000000..58cf345d1 --- /dev/null +++ b/examples/FDK/SheppLogan-3D.png.sha512 @@ -0,0 +1 @@ +e8ca23464aee187bcd8d38a3d3bf3f2907e4e3e3a04fdee7cced6cf88031358abbc9a3dbeb3c441414de29554328d05690d4f5229cb2fd406757babe32d80f2c \ No newline at end of file diff --git a/examples/index.md b/examples/index.md new file mode 100644 index 000000000..b09db27a0 --- /dev/null +++ b/examples/index.md @@ -0,0 +1,8 @@ +Examples +======== + +```{toctree} +:maxdepth: 1 + +./FDK/README +``` \ No newline at end of file diff --git a/index.md b/index.md new file mode 100644 index 000000000..d480c62d6 --- /dev/null +++ b/index.md @@ -0,0 +1,34 @@ +# Welcome to RTK's documentation! + +The Reconstruction Toolkit (RTK) is an open-source and cross-platform software for fast circular cone-beam CT reconstruction based on the Insight Toolkit (ITK). RTK is developed by the RTK consortium. + +[![GitHub release](https://img.shields.io/github/release/RTKConsortium/RTK.svg)](https://github.com/RTKConsortium/RTK/releases/latest) +[![PyPI](https://img.shields.io/pypi/v/itk-rtk.svg)](https://pypi.python.org/pypi/itk-rtk) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/RTKConsortium/RTK/blob/master/LICENSE.TXT) + + +```{toctree} +:maxdepth: 1 +:caption: 💾 Download + +INSTALLATION +``` + +```{toctree} +:maxdepth: 1 +:caption: 📖 Learn + +GettingStarted +examples/index +``` + +```{toctree} +:maxdepth: 1 +:caption: 🔨 Develop + +API +Discussion +Issue tracker +documentation/docs/README +documentation/docs/Release +``` \ No newline at end of file