diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..40bb61de3 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,411 @@ +version: 2.1 + +orbs: + coverage-reporter: codacy/coverage-reporter@11.0.1 + +jobs: + + build: + environment: + TZ: "/usr/share/zoneinfo/Europe/Zurich" + SCRATCH: "/scratch" + docker: + - image: docker:19.03.1-git + working_directory: tmp/src/mialsuperresolutiontoolkit + steps: + - run: + name: Install parallel gzip and python2 + command: | + apk add --no-cache pigz python2 + - restore_cache: + keys: + - docker-{{ .Branch }}-{{ epoch }} + - docker-{{ .Branch }}- + - docker-master- + - docker- + paths: + - /tmp/cache/docker.tar.gz + - checkout + - setup_remote_docker: + docker_layer_caching: false + - run: + name: Load Docker image layer cache + no_output_timeout: 30m + command: | + docker info + set +o pipefail + if [ -f /tmp/cache/docker.tar.gz ]; then + pigz -d --stdout /tmp/cache/docker.tar.gz | docker load + docker images + fi + - run: + name: Build Docker image + no_output_timeout: 120m + command: | + # Get version, update files. + THISVERSION=v$( python get_version.py ) + echo "THISVERSION : ${THISVERSION}" + echo "CIRCLE_TAG : ${CIRCLE_TAG}" + if [[ ${THISVERSION:0:1} == "0" ]] ; then + echo "WARNING: latest git tag could not be found" + echo "Please, make sure you fetch all tags from upstream with" + echo "the command ``git fetch --tags --verbose`` and push" + echo "them to your fork with ``git push origin --tags``" + fi + + # Build main docker image + ls -la . + e=1 && for i in {1..5}; do + docker build --cache-from sebastientourbier/mialsuperresolutiontoolkit-ubuntu14.04 --rm=false --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=$VCS_REF --build-arg VERSION="${CIRCLE_TAG:-$THISVERSION}" -t sebastientourbier/mialsuperresolutiontoolkit-ubuntu14.04 . \ + && e=0 && break || sleep 15 + done && [ "$e" -eq "0" ] + # Build CMP BIDS App docker image + ls -la ./docker/bidsapp + e=1 && for i in {1..5}; do + docker build --cache-from sebastientourbier/mialsuperresolutiontoolkit-bidsapp --rm=false --build-arg MAIN_DOCKER="sebastientourbier/mialsuperresolutiontoolkit-ubuntu14.04" --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse --short HEAD` --build-arg VERSION="${CIRCLE_TAG:-$THISVERSION}" -t sebastientourbier/mialsuperresolutiontoolkit-bidsapp ./docker/bidsapp \ + && e=0 && break || sleep 15 + done && [ "$e" -eq "0" ] + - run: + name: Save Docker Images + no_output_timeout: 40m + command: | + # Get version, update files. + THISVERSION=$( python get_version.py ) + mkdir -p /tmp/cache + docker save sebastientourbier/mialsuperresolutiontoolkit-ubuntu14.04 sebastientourbier/mialsuperresolutiontoolkit-bidsapp \ + | pigz -8 -p 3 > /tmp/cache/docker.tar.gz + - persist_to_workspace: + root: /tmp + paths: + - cache/docker.tar.gz + - src/mialsuperresolutiontoolkit + + + test: + machine: + # Ubuntu 16.04, docker 18.09.3, docker-compose 1.23.1 + image: ubuntu-1604:201903-01 + + working_directory: /tmp/src/mialsuperresolutiontoolkit/data + + steps: + - checkout: + path: /home/circleci/src/mialsuperresolutiontoolkit + - run: + name: Check whether test should be skipped + command: | + cd /home/circleci/src/mialsuperresolutiontoolkit + if [[ "$( git log --format=oneline -n 1 $CIRCLE_SHA1 | grep -i -E '\[skip[ _]?test]' )" != "" ]]; then + echo "Skipping test" + circleci step halt + fi + - attach_workspace: + at: /tmp + # - restore_cache: + # keys: + # - ds-sample-derivatives-{{ .Branch }}-{{ epoch }} + # - ds-sample-derivatives-{{ .Branch }} + # - ds-sample-derivatives-master + # - ds-sample-derivatives- + - run: + name: Load Docker image layer cache + no_output_timeout: 30m + command: | + docker info + set +o pipefail + if [ -f /tmp/cache/docker.tar.gz ]; then + wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - + sudo apt-get update && sudo apt-get -y install pigz + pigz -d --stdout /tmp/cache/docker.tar.gz | docker load + docker images + fi + - run: + name: Create the data/test folder + no_output_timeout: 1h + command: | + mkdir -p /tmp/src/mialsuperresolutiontoolkit/data/test + - run: + name: Test-01 - Run super-resolution pipelines on sample testing dataset with manual masks + no_output_timeout: 6h + command: | + # Get version, update files. + #THISVERSION=v$( python /home/circleci/src/mialsuperresolutiontoolkit/get_version.py ) + #echo "THISVERSION : ${THISVERSION}" + ls -la /tmp/src/mialsuperresolutiontoolkit/data + ls -la /tmp/src/mialsuperresolutiontoolkit/data/code + ls -la /tmp/src/mialsuperresolutiontoolkit/data/derivatives + + #Execute BIDS App + docker run -it --rm --entrypoint /app/run_srr_coverage.sh \ + -v /tmp/src/mialsuperresolutiontoolkit/data:/bids_dir \ + -v /tmp/src/mialsuperresolutiontoolkit/data/derivatives:/output_dir \ + sebastientourbier/mialsuperresolutiontoolkit-bidsapp \ + /bids_dir /output_dir participant --participant_label 01 \ + --param_file /bids_dir/code/participants_params.json \ + --manual + + # Rename log + mv /tmp/src/mialsuperresolutiontoolkit/data/code/log.txt /tmp/src/mialsuperresolutiontoolkit/data/test/test-01_log.txt + + # Rename partial coverage + mv /tmp/src/mialsuperresolutiontoolkit/data/code/coverage.xml /tmp/src/mialsuperresolutiontoolkit/data/test/test-01_coverage.xml + # - save_cache: + # key: ds-sample-derivatives-{{ .Branch }}-{{ epoch }} + # paths: + # - /tmp/data/ds-sample/derivatives + - run: + name: Test-01 - Checking outputs of MIALSRTK BIDS App run + command: | + # Get all files in derivatives except the _*.json interface hash generated by nipype (find) / remove the full path of the derivatives (sed) / sort the files and write it to a text file + sudo find /tmp/src/mialsuperresolutiontoolkit/data/derivatives -path */figures -prune -o -not -name "_*.json" -type f -print | sed s+/tmp/src/mialsuperresolutiontoolkit/data/derivatives/++ | sort > /tmp/src/mialsuperresolutiontoolkit/data/test/test-01_outputs.out + diff /home/circleci/src/mialsuperresolutiontoolkit/.circleci/test-01_outputs.txt /tmp/src/mialsuperresolutiontoolkit/data/test/test-01_outputs.out + exit $? + - run: + name: Test-02 - Run super-resolution pipelines on sample testing dataset with automatic brain extraction + no_output_timeout: 6h + command: | + # Get version, update files. + #THISVERSION=v$( python /home/circleci/src/mialsuperresolutiontoolkit/get_version.py ) + #echo "THISVERSION : ${THISVERSION}" + ls -la /tmp/src/mialsuperresolutiontoolkit/data + ls -la /tmp/src/mialsuperresolutiontoolkit/data/code + ls -la /tmp/src/mialsuperresolutiontoolkit/data/derivatives + + rm -R /tmp/src/mialsuperresolutiontoolkit/data/derivatives/* + + #Execute BIDS App + docker run -it --rm --entrypoint /app/run_srr_coverage.sh \ + -v /tmp/src/mialsuperresolutiontoolkit/data:/bids_dir \ + -v /tmp/src/mialsuperresolutiontoolkit/data/derivatives:/output_dir \ + sebastientourbier/mialsuperresolutiontoolkit-bidsapp \ + /bids_dir /output_dir participant --participant_label 01 \ + --param_file /bids_dir/code/participants_params.json + + # Rename log + mv /tmp/src/mialsuperresolutiontoolkit/data/code/log.txt /tmp/src/mialsuperresolutiontoolkit/data/test/test-02_log.txt + + # Rename partial coverage + mv /tmp/src/mialsuperresolutiontoolkit/data/code/coverage.xml /tmp/src/mialsuperresolutiontoolkit/data/test/test-02_coverage.xml + - run: + name: Test-02 - Checking outputs of MIALSRTK BIDS App run + command: | + # Get all files in derivatives except the _*.json interface hash generated by nipype (find) / remove the full path of the derivatives (sed) / sort the files and write it to a text file + sudo find /tmp/src/mialsuperresolutiontoolkit/data/derivatives -path */figures -prune -o -not -name "_*.json" -type f -print | sed s+/tmp/src/mialsuperresolutiontoolkit/data/derivatives/++ | sort > /tmp/src/mialsuperresolutiontoolkit/data/test/test-02_outputs.out + diff /home/circleci/src/mialsuperresolutiontoolkit/.circleci/test-02_outputs.txt /tmp/src/mialsuperresolutiontoolkit/data/test/test-02_outputs.out + exit $? + - run: + name: Clean working directory + when: always + command: | + sudo chown $(id -un):$(id -gn) -R /tmp/src/mialsuperresolutiontoolkit/data + find /tmp/src/mialsuperresolutiontoolkit/data/derivatives -not -name "*.svg" -not -name "*.png" -not -name "*.html" -not -name "*.nii.gz" -not -name "*.rst" \ + -not -name "*.mat" -not -name "*.gpickle" -not -name "*.lta" -not -name "*.json" -not -name "*.txt" -not -name "*.pklz" -type f -delete + - persist_to_workspace: + root: /tmp + paths: + - src/mialsuperresolutiontoolkit/data/test + - store_artifacts: + path: /tmp/src/mialsuperresolutiontoolkit/data/code + - store_artifacts: + path: /tmp/src/mialsuperresolutiontoolkit/data/test + - store_artifacts: + path: /tmp/src/mialsuperresolutiontoolkit/data/derivatives + + codacy-coverage-report: + docker: + - image: 'circleci/openjdk:8-jdk' + + working_directory: /tmp/src/mialsuperresolutiontoolkit/data/test + + steps: + - attach_workspace: + at: /tmp + - coverage-reporter/send_report: + # With parcellation tests + # coverage-reports: '/tmp/src/mialsuperresolutiontoolkit/data/test/test-01_coverage.xml' + coverage-reports: '/tmp/src/mialsuperresolutiontoolkit/data/test/test-01_coverage.xml,/tmp/src/mialsuperresolutiontoolkit/data/test/test-02_coverage.xml' + project-token: ${CODACY_PROJECT_TOKEN} + # build_docs: + # machine: + # # Ubuntu 16.04, docker 18.09.3, docker-compose 1.23.1 + # image: ubuntu-1604:201903-01 + # working_directory: /home/circleci/out/docs + # steps: + # - checkout: + # path: /home/circleci/src/connectomemapper3 + # - run: + # name: Check whether build should be skipped + # command: | + # cd /home/circleci/src/connectomemapper3 + # if [[ "$( git log --format=oneline -n 1 $CIRCLE_SHA1 | grep -i -E '\[skip[ _]?docs\]' )" != "" ]]; then + # echo "Skipping documentation build job" + # circleci step halt + # fi + + # - attach_workspace: + # at: /tmp + # - run: + # name: Load Docker image layer cache + # no_output_timeout: 30m + # command: | + # docker info + # set +o pipefail + # if [ -f /tmp/cache/docker.tar.gz ]; then + # wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - + # sudo apt-get update && sudo apt-get -y install pigz + # pigz -d --stdout /tmp/cache/docker.tar.gz | docker load + # docker images + # fi + # - run: + # name: Build Connectome Mapper 3 documentation + # no_output_timeout: 2h + # command: | + # docker run -ti --rm=false -v $PWD:/_build_html \ + # --entrypoint=sphinx-build sebastientourbier/connectomemapper3:latest \ + # -T -E -b html -d _build/doctrees-readthedocs -W -D \ + # language=en /root/src/connectomemapper3/docs/ /_build_html 2>&1 \ + # | tee $PWD/builddocs.log + # cat $PWD/builddocs.log + # grep -qv "ERROR" $PWD/builddocs.log + # - store_artifacts: + # path: /home/circleci/out/docs + + deploy_docker_release: + machine: + # Ubuntu 14.04 with Docker 17.10.0-ce + image: ubuntu-1604:201903-01 + working_directory: /tmp/src/mialsuperresolutiontoolkit + steps: + - checkout: + path: /home/circleci/src/mialsuperresolutiontoolkit + - attach_workspace: + at: /tmp + - run: + name: Load Docker image layer cache + no_output_timeout: 30m + command: | + docker info + set +o pipefail + if [ -f /tmp/cache/docker.tar.gz ]; then + wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - + sudo apt-get update && sudo apt-get -y install pigz + pigz -d --stdout /tmp/cache/docker.tar.gz | docker load + docker images + fi + - run: + name: Deploy release with version tag to Docker Hub + no_output_timeout: 40m + command: | + # Get version, update files. + THISVERSION=$( python /home/circleci/src/mialsuperresolutiontoolkit/get_version.py ) + echo "THISVERSION : ${THISVERSION}" + echo "CIRCLE_TAG : ${CIRCLE_TAG}" + + if [[ -n "$DOCKER_PASS" ]]; then + docker login -u $DOCKER_USER -p $DOCKER_PASS + if [[ -n "$CIRCLE_TAG" ]]; then + docker tag sebastientourbier/mialsuperresolutiontoolkit-bidsapp sebastientourbier/mialsuperresolutiontoolkit-bidsapp:$CIRCLE_TAG + docker push sebastientourbier/mialsuperresolutiontoolkit-bidsapp:$CIRCLE_TAG + fi + fi + + deploy_docker_latest: + machine: + # Ubuntu 14.04 with Docker 17.10.0-ce + image: ubuntu-1604:201903-01 + working_directory: /tmp/src/mialsuperresolutiontoolkit + steps: + - checkout: + path: /home/circleci/src/mialsuperresolutiontoolkit + - attach_workspace: + at: /tmp + - run: + name: Load Docker image layer cache + no_output_timeout: 30m + command: | + docker info + set +o pipefail + if [ -f /tmp/cache/docker.tar.gz ]; then + wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - + sudo apt-get update && sudo apt-get -y install pigz + pigz -d --stdout /tmp/cache/docker.tar.gz | docker load + docker images + fi + - run: + name: Deploy latest master to Docker Hub + no_output_timeout: 40m + command: | + # Get version, update files. + THISVERSION=$( python /home/circleci/src/mialsuperresolutiontoolkit/get_version.py ) + echo "THISVERSION : ${THISVERSION}" + echo "CIRCLE_BRANCH : ${CIRCLE_BRANCH}" + + if [[ -n "$DOCKER_PASS" ]]; then + docker login -u $DOCKER_USER -p $DOCKER_PASS + docker tag sebastientourbier/mialsuperresolutiontoolkit-bidsapp sebastientourbier/mialsuperresolutiontoolkit-bidsapp:latest + docker push sebastientourbier/mialsuperresolutiontoolkit-bidsapp:latest + fi + +workflows: + version: 2 + build_test_deploy: + jobs: + - build: + filters: + tags: + only: /.*/ + + # - build_docs: + # requires: + # - build + # filters: + # branches: + # ignore: + # - /ds-sample\/.*/ + # tags: + # only: /.*/ + + - test: + requires: + # - update_cache + - build + filters: + branches: + ignore: + - /docs?\/.*/ + tags: + only: /.*/ + + - codacy-coverage-report: + requires: + - test + filters: + branches: + ignore: + - /docs?\/.*/ + tags: + only: /.*/ + + - deploy_docker_release: + requires: + - build + # - build_docs + - test + filters: + # ignore any commit on any branch by default + branches: + ignore: /.*/ + # only: master + # only act on version tags + tags: + only: /^v.*/ + + - deploy_docker_latest: + requires: + - build + # - build_docs + - test + filters: + # ignore any commit on any branch by default + branches: + only: master diff --git a/.circleci/test-01_outputs.txt b/.circleci/test-01_outputs.txt new file mode 100644 index 000000000..8534eba5f --- /dev/null +++ b/.circleci/test-01_outputs.txt @@ -0,0 +1,212 @@ +manual_masks/dataset_description.json +manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.json +manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.nii.gz +manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.json +manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.nii.gz +manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.json +manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.nii.gz +manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.json +manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.nii.gz +manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.json +manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.nii.gz +manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.json +manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.nii.gz +nipype/sub-01/rec-1/pypeline.log +nipype/sub-01/rec-1/srr_pipeline/d3.js +nipype/sub-01/rec-1/srr_pipeline/data_grabber/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/data_grabber/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/data_grabber/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/data_grabber/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/data_grabber/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/data_grabber/result_data_grabber.pklz +nipype/sub-01/rec-1/srr_pipeline/data_sinker/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/data_sinker/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/data_sinker/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/data_sinker/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/data_sinker/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/data_sinker/result_data_sinker.pklz +nipype/sub-01/rec-1/srr_pipeline/graph1.json +nipype/sub-01/rec-1/srr_pipeline/graph.dot +nipype/sub-01/rec-1/srr_pipeline/graph.json +nipype/sub-01/rec-1/srr_pipeline/graph.png +nipype/sub-01/rec-1/srr_pipeline/index.html +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/result_nlmDenoise.pklz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/sub-01_run-1_T2w_nlm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/sub-01_run-3_T2w_nlm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/sub-01_run-5_T2w_nlm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/result_srtkCorrectSliceIntensity01_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/sub-01_run-1_T2w_nlm_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/sub-01_run-3_T2w_nlm_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/sub-01_run-5_T2w_nlm_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/result_srtkCorrectSliceIntensity01.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/sub-01_run-1_T2w_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/sub-01_run-3_T2w_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/sub-01_run-5_T2w_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/result_srtkCorrectSliceIntensity02_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/sub-01_run-1_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/sub-01_run-3_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/sub-01_run-5_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/result_srtkCorrectSliceIntensity02.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/sub-01_run-1_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/sub-01_run-3_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/sub-01_run-5_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/result_srtkHistogramNormalization_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/result_srtkHistogramNormalization.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/sub-01_run-1_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/sub-01_run-3_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/sub-01_run-5_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/result_srtkImageReconstruction.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/SDI_sub-01_3V_rad1.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm_transform_3V.txt +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm_transform_3V.txt +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm_transform_3V.txt +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/result_srtkIntensityStandardization01_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/sub-01_run-1_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/sub-01_run-3_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/sub-01_run-5_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/result_srtkIntensityStandardization01.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/sub-01_run-1_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/sub-01_run-3_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/sub-01_run-5_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/result_srtkIntensityStandardization02_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/result_srtkIntensityStandardization02.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/sub-01_run-1_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/sub-01_run-3_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/sub-01_run-5_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/result_srtkMaskImage01.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/result_srtkMaskImage02.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/SRTV_sub-01_3V_rad1.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/result_srtkN4BiasFieldCorrection.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/SRTV_sub-01_3V_rad1_gbcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/result_srtkRefineHRMaskByIntersection.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/sub-01_T2w_uni_bcorr_histnorm_srMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/result_srtkSliceBySliceCorrectBiasField.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/sub-01_run-1_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/sub-01_run-3_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/sub-01_run-5_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/result_srtkSliceBySliceN4BiasFieldCorrection.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-1_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-1_T2w_nlm_uni_n4bias.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-3_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-3_T2w_nlm_uni_n4bias.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-5_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-5_T2w_nlm_uni_n4bias.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/result_srtkTVSuperResolution.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/SRTV_sub-01_3V_rad1.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SDI_id-1_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SR_id-1_T2w_desc-brain_mask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SR_id-1_T2w.json +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SR_id-1_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-1_id-1_desc-preprocSDI_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-1_id-1_desc-preprocSR_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-3_id-1_desc-preprocSDI_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-3_id-1_desc-preprocSR_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-5_id-1_desc-preprocSDI_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-5_id-1_desc-preprocSR_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/xfm/sub-01_run-1_id-1_T2w_from-origin_to-SDI_mode-image_xfm.txt +pymialsrtk-2.0.0/sub-01/xfm/sub-01_run-3_id-1_T2w_from-origin_to-SDI_mode-image_xfm.txt +pymialsrtk-2.0.0/sub-01/xfm/sub-01_run-5_id-1_T2w_from-origin_to-SDI_mode-image_xfm.txt diff --git a/.circleci/test-02_outputs.txt b/.circleci/test-02_outputs.txt new file mode 100644 index 000000000..df80e83f4 --- /dev/null +++ b/.circleci/test-02_outputs.txt @@ -0,0 +1,217 @@ +nipype/sub-01/rec-1/pypeline.log +nipype/sub-01/rec-1/srr_pipeline/d3.js +nipype/sub-01/rec-1/srr_pipeline/data_grabber/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/data_grabber/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/data_grabber/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/data_grabber/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/data_grabber/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/data_grabber/result_data_grabber.pklz +nipype/sub-01/rec-1/srr_pipeline/data_sinker/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/data_sinker/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/data_sinker/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/data_sinker/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/data_sinker/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/data_sinker/result_data_sinker.pklz +nipype/sub-01/rec-1/srr_pipeline/graph1.json +nipype/sub-01/rec-1/srr_pipeline/graph.dot +nipype/sub-01/rec-1/srr_pipeline/graph.json +nipype/sub-01/rec-1/srr_pipeline/graph.png +nipype/sub-01/rec-1/srr_pipeline/index.html +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/result_Multiple_Brain_extraction.pklz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/sub-01_run-1_T2w_brainMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/sub-01_run-2_T2w_brainMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/sub-01_run-3_T2w_brainMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/sub-01_run-4_T2w_brainMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/sub-01_run-5_T2w_brainMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/Multiple_Brain_extraction/sub-01_run-6_T2w_brainMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/result_nlmDenoise.pklz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/sub-01_run-1_T2w_nlm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/sub-01_run-3_T2w_nlm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/nlmDenoise/sub-01_run-5_T2w_nlm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/result_srtkCorrectSliceIntensity01_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/sub-01_run-1_T2w_nlm_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/sub-01_run-3_T2w_nlm_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01_nlm/sub-01_run-5_T2w_nlm_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/result_srtkCorrectSliceIntensity01.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/sub-01_run-1_T2w_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/sub-01_run-3_T2w_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity01/sub-01_run-5_T2w_uni.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/result_srtkCorrectSliceIntensity02_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/sub-01_run-1_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/sub-01_run-3_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02_nlm/sub-01_run-5_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/result_srtkCorrectSliceIntensity02.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/sub-01_run-1_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/sub-01_run-3_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkCorrectSliceIntensity02/sub-01_run-5_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/result_srtkHistogramNormalization_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization_nlm/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/result_srtkHistogramNormalization.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/sub-01_run-1_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/sub-01_run-3_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkHistogramNormalization/sub-01_run-5_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/result_srtkImageReconstruction.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/SDI_sub-01_3V_rad1.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm_transform_3V.txt +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm_transform_3V.txt +nipype/sub-01/rec-1/srr_pipeline/srtkImageReconstruction/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm_transform_3V.txt +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/result_srtkIntensityStandardization01_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/sub-01_run-1_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/sub-01_run-3_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01_nlm/sub-01_run-5_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/result_srtkIntensityStandardization01.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/sub-01_run-1_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/sub-01_run-3_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization01/sub-01_run-5_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/result_srtkIntensityStandardization02_nlm.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02_nlm/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/result_srtkIntensityStandardization02.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/sub-01_run-1_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/sub-01_run-3_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkIntensityStandardization02/sub-01_run-5_T2w_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/result_srtkMaskImage01.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/sub-01_run-1_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/sub-01_run-3_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage01/sub-01_run-5_T2w_nlm_uni_bcorr_histnorm.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/result_srtkMaskImage02.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkMaskImage02/SRTV_sub-01_3V_rad1.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/result_srtkN4BiasFieldCorrection.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkN4BiasFieldCorrection/SRTV_sub-01_3V_rad1_gbcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/result_srtkRefineHRMaskByIntersection.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkRefineHRMaskByIntersection/sub-01_T2w_uni_bcorr_histnorm_srMask.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/result_srtkSliceBySliceCorrectBiasField.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/sub-01_run-1_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/sub-01_run-3_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceCorrectBiasField/sub-01_run-5_T2w_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/result_srtkSliceBySliceN4BiasFieldCorrection.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-1_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-1_T2w_nlm_uni_n4bias.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-3_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-3_T2w_nlm_uni_n4bias.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-5_T2w_nlm_uni_bcorr.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkSliceBySliceN4BiasFieldCorrection/sub-01_run-5_T2w_nlm_uni_n4bias.nii.gz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/_inputs.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/_node.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/provenance.provn +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/provenance.ttl +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/_report/report.rst +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/result_srtkTVSuperResolution.pklz +nipype/sub-01/rec-1/srr_pipeline/srtkTVSuperResolution/SRTV_sub-01_3V_rad1.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SDI_id-1_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SR_id-1_T2w_desc-brain_mask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SR_id-1_T2w.json +pymialsrtk-2.0.0/sub-01/anat/sub-01_rec-SR_id-1_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-1_desc-brain_mask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-1_id-1_desc-preprocSDI_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-1_id-1_desc-preprocSR_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-2_T2w_brainMask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-3_desc-brain_mask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-3_id-1_desc-preprocSDI_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-3_id-1_desc-preprocSR_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-4_T2w_brainMask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-5_desc-brain_mask.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-5_id-1_desc-preprocSDI_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-5_id-1_desc-preprocSR_T2w.nii.gz +pymialsrtk-2.0.0/sub-01/anat/sub-01_run-6_T2w_brainMask.nii.gz +pymialsrtk-2.0.0/sub-01/xfm/sub-01_run-1_id-1_T2w_from-origin_to-SDI_mode-image_xfm.txt +pymialsrtk-2.0.0/sub-01/xfm/sub-01_run-3_id-1_T2w_from-origin_to-SDI_mode-image_xfm.txt +pymialsrtk-2.0.0/sub-01/xfm/sub-01_run-5_id-1_T2w_from-origin_to-SDI_mode-image_xfm.txt diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..906ce597e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +*.pklz +*.pyc +*.npz +*.xdebug_tkmedit +*.mp4 +atom-config.txt + +.DS_Store? +.DS_Store +ehthumbs.db +Icon? +Thumbs.db + +docs +docs/* + +debian +debian/* + +dist +dist/* + +build +build/* + +_build +_static +_templates + +*.ipynb_checkpoints diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..faeca864b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +Unet.ckpt-* filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index c4280ee6f..cad64dceb 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,11 @@ *.*~ *.save +# python # +################################# +*.ipynb_checkpoints +*__pycache__ + # Generated testing images # ############################ superresolution.nii.gz @@ -66,8 +71,15 @@ Build-debug build build-dbg build-debug +_build release bin bin-dbg Bin RECON + +# Data derivatives # +##################### +data/derivatives/mialsrtk* +data/derivatives/nipype* +data/derivatives/pymialsrtk* diff --git a/docker/.gitkeep b/.gitkeep similarity index 100% rename from docker/.gitkeep rename to .gitkeep diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000..6b66dc47e --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,29 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: documentation/conf.py + +# Build documentation with MkDocs +#mkdocs: +# configuration: mkdocs.yml + +# Optionally build your docs in additional formats such as PDF +formats: + - htmlzip + - pdf + +# # Install the pymialsrtk conda environment with all dependencies required to build the doc +# conda: +# environment: docker/bidsapp/environment.yml + +# Optionally set the version of Python and requirements required to build your docs +python: + version: 3.6 + install: + - requirements: documentation/requirements.txt diff --git a/.travis.yml.old b/.travis.yml.old deleted file mode 100644 index 638944adf..000000000 --- a/.travis.yml.old +++ /dev/null @@ -1,79 +0,0 @@ -language: cpp -dist: trusty -matrix: - include: - - #dist: trusty - sudo: required - compiler: - - gcc - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - - cmake - - libtclap-dev - - libinsighttoolkit4.5 - - libinsighttoolkit4-dev - - libvtk5-dev - - libvtk5-qt4-dev - - libvtk5.8 - - libvtk5.8-qt4 - - tcl-vtk - - libvtk-java - - python-vtk - - python-vtkgdcm - - libncurses5 - - libncurses5-dev - - libann-dev - #- libgdcm2-dev - #- libvtkgdcm2-dev - #- libgdcm-tools - #- libvtkgdcm-tools - - dist: xenial - sudo: required - compiler: - - gcc - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - - cmake - - libtclap-dev - - libinsighttoolkit4.9 - - libinsighttoolkit4-dev - - libvtk5-dev - - libvtk5-qt4-dev - - libvtk5.10 - - libvtk5.10-qt4 - - tcl-vtk - - libvtk-java - - python-vtk - - python-vtkgdcm - - libncurses5 - - libncurses5-dev - - libann-dev - -#before_script: -# - mkdir build -# - cd build -# - cmake ../src -script: - # Link gcc-4.8 and g++-4.8 to their standard commands - - sudo ln -s /usr/bin/gcc-4.8 /usr/local/bin/gcc - - sudo ln -s /usr/bin/g++-4.8 /usr/local/bin/g++ - # Export CC and CXX to tell cmake which compiler to use - - export CC=/usr/bin/gcc-4.8 - - export CXX=/usr/bin/g++-4.8 - # Check versions of gcc, g++ and cmake - - gcc -v && g++ -v && cmake --version - # Run your build commands next - - mkdir build - - cd build - - cmake ../src - - make diff --git a/.zenodo.json b/.zenodo.json index 0459a70b3..452db21d2 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -3,13 +3,11 @@ "keywords": [ "fetal", "neuroimaging", - "workflow", "pipeline", "super-resolution", "registration", "MRI", - "BIDS", - "BIDS-App" + "BIDS" ], "publication_date": "2019-03-19", "creators": [ @@ -18,6 +16,10 @@ "affiliation": "Department of Radiology, Lausanne University Hospital (CHUV), Switzerland", "orcid": "0000-0002-4441-899X" }, + { + "name": "Bresson, Xavier", + "affiliation": "Data Science and AI Center (DSAIR), Nanyang Technological University (NTU), Singapore" + }, { "name": "Bach Cuadra, Meritxell", "affiliation": "Department of Radiology, Lausanne University Hospital (CHUV), Switzerland", diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..7586b12ba --- /dev/null +++ b/Dockerfile @@ -0,0 +1,86 @@ +FROM ubuntu:14.04 + +RUN apt-get update && \ + apt-get install software-properties-common -y && \ + apt-add-repository ppa:saiarcot895/myppa -y && \ + apt-get update && \ + apt-get -y install apt-fast \ + && apt-fast install -y \ + build-essential \ + exfat-fuse \ + exfat-utils \ + npm \ + curl \ + bzip2 \ + xvfb \ + x11-apps \ + git \ + gcc-4.8 \ + g++-4.8 \ + cmake \ + libtclap-dev \ + libinsighttoolkit4.5 \ + libinsighttoolkit4-dev \ + libvtk5-dev \ + libvtk5-qt4-dev \ + libvtk5.8 \ + libvtk5.8-qt4 \ + tcl-vtk \ + libvtk-java \ + python-vtk \ + python-vtkgdcm \ + libncurses5 \ + libncurses5-dev \ + libann-dev \ + python-qt4 \ + python-nibabel \ + python-numpy \ + python-scipy \ + python-matplotlib && \ + curl -sSL https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -o /tmp/miniconda.sh && \ + bash /tmp/miniconda.sh -bfp /opt/conda && \ + rm -rf /tmp/miniconda.sh && \ + apt-get clean + + +ENV PATH /opt/conda/bin:$PATH + +RUN conda update conda && \ + conda clean --all --yes + +RUN groupadd -r -g 1000 mialsrtk && \ + useradd -r -M -u 1000 -g mialsrtk mialsrtk + +WORKDIR /opt/mialsuperresolutiontoolkit + +COPY . /opt/mialsuperresolutiontoolkit + +RUN mkdir build +WORKDIR /opt/mialsuperresolutiontoolkit/build + +RUN cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D USE_OMP:BOOL=ON ../src \ + && make -j2 && make install + +# Make MIALSRTK happy +ENV BIN_DIR "/usr/local/bin" +ENV PATH ${BIN_DIR}:$PATH + +ENV DISPLAY :0 + +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION + +#Metadata +LABEL org.label-schema.build-date=$BUILD_DATE +LABEL org.label-schema.name="MIAL Super-Resolution ToolKit Ubuntu 14.04" +LABEL org.label-schema.description="Computing environment of the MIAL Super-Resolution BIDS App based on Ubuntu 14.04." +LABEL org.label-schema.url="https://mialsuperresolutiontoolkit.readthedocs.io" +LABEL org.label-schema.vcs-ref=$VCS_REF +LABEL org.label-schema.vcs-url="https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit" +LABEL org.label-schema.version=$VERSION +LABEL org.label-schema.maintainer="Sebastien Tourbier " +LABEL org.label-schema.vendor="Centre Hospitalier Universitaire Vaudois (CHUV), Lausanne, Switzerland" +LABEL org.label-schema.schema-version="1.0" +LABEL org.label-schema.docker.cmd="docker run --rm -v ~/data/bids_dataset:/tmp -t sebastientourbier/mialsuperresolutiontoolkit-ubuntu16.04:${VERSION}" + diff --git a/README.md b/README.md index f4a86c141..f7fb26994 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,78 @@ -![MIALSRTK logo](https://cloud.githubusercontent.com/assets/22279770/24004342/5e78836a-0a66-11e7-8b7d-058961cfe8e8.png) +# ![MIALSRTK logo](https://raw.githubusercontent.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit/dev-pgd-hk/documentation/images/mialsrtk-logo.png) --- -Copyright © 2016-2017 Medical Image Analysis Laboratory, University Hospital Center and University of Lausanne (UNIL-CHUV), Switzerland +Copyright © 2016-2020 Medical Image Analysis Laboratory, University Hospital Center and University of Lausanne (UNIL-CHUV), Switzerland -This software is distributed under the open-source BSD 3-Clause License. See LICENSE file for details. +This software is distributed under the open-source BSD 3-Clause License. See [LICENSE](LICENSE.txt) file for details. --- -[![DOI](https://zenodo.org/badge/85210898.svg)](https://zenodo.org/badge/latestdoi/85210898) [![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) +![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit?include_prereleases) [![DOI](https://zenodo.org/badge/85210898.svg)](https://zenodo.org/badge/latestdoi/85210898) ![Docker Pulls](https://img.shields.io/docker/pulls/sebastientourbier/mialsuperresolutiontoolkit) [![Build Status](https://travis-ci.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit.svg?branch=master)](https://travis-ci.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit) [![CircleCI](https://circleci.com/gh/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit.svg?style=shield)](https://app.circleci.com/pipelines/github/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit) [![Code Coverage](https://app.codacy.com/project/badge/Coverage/a27593d6fae7436eb2cd65b80f3342c3)](https://www.codacy.com/gh/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit?utm_source=github.com&utm_medium=referral&utm_content=Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit&utm_campaign=Badge_Coverage) [![Documentation Status](https://readthedocs.org/projects/mialsrtk/badge/?version=latest)](https://mialsrtk.readthedocs.io/en/latest/?badge=latest) [![Code Quality](https://app.codacy.com/project/badge/Grade/a27593d6fae7436eb2cd65b80f3342c3)](https://www.codacy.com/gh/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit?utm_source=github.com&utm_medium=referral&utm_content=Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit&utm_campaign=Badge_Grade) [![Github All Contributors](https://img.shields.io/github/all-contributors/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit)](#credits-) - -The Medical Image Analysis Laboratory Super-Resolution ToolKit (MIALSRTK) consists of a set of C++ image processing tools necessary to perform motion-robust super-resolution fetal MRI reconstruction. This toolkit, supported by the Swiss National Science Foundation (grant SNSF-141283), includes all algorithms and methods for brain extraction [1], intensity standardization [1,2], motion estimation and super-resolution [2] developed during my PhD. It uses the CMake build system and depends on the open-source image processing Insight ToolKit (ITK) library, the command line parser TCLAP library and OpenMP for multi-threading. The USAGE message of each tool can be obained using either the *-h* or *--help* flag. +The Medical Image Analysis Laboratory Super-Resolution ToolKit (MIALSRTK) provides a set of C++ and Python tools necessary to perform motion-robust super-resolution fetal MRI reconstruction. -A Docker image is provided to facilitate the deployment and freely available @ [Docker store](https://store.docker.com/community/images/sebastientourbier/mialsuperresolutiontoolkit). +The original C++ MIALSRTK library includes all algorithms and methods for brain extraction, intensity standardization, motion estimation and super-resolution. It uses the CMake build system and depends on the open-source image processing Insight ToolKit (ITK) library, the command line parser TCLAP library and OpenMP for multi-threading. -* Please acknowledge this software in any work reporting results using MIALSRTK by citing the following: +MIALSRTK has been recently extended with the `pymialsrtk` Python3 library following recent advances in standardization of neuroimaging data organization and processing workflows such as the [Brain Imaging Data Structure (BIDS)](https://bids.neuroimaging.io/) and [BIDS App](https://bids-apps.neuroimaging.io/) standards. This library has a modular architecture built on top of the Nipype dataflow library which consists of (1) processing nodes that interface with each of the MIALSRTK C++ tools and (2) a processing pipeline that links the interfaces in a common workflow. -[1] S. Tourbier, X. Bresson, P. Hagmann, M. B. Cuadra. (2019, March 19). sebastientourbier/mialsuperresolutiontoolkit: MIAL Super-Resolution Toolkit v1.0 (Version v1.0). Zenodo. http://doi.org/10.5281/zenodo.2598448 +The processing pipeline with all dependencies including the C++ MIALSRTK tools are encapsulated in a Docker image container, which is now distributed as a `BIDS App` which handles datasets organized following the BIDS standard. -[2] S. Tourbier, C. Velasco-Annis, V. Taimouri, P. Hagmann, R. Meuli, S. K. Warfield, M. B. Cuadra, -A. Gholipour, *Automated template-based brain localization and extraction for fetal brain MRI -reconstruction*, Neuroimage (2017) In Press. [DOI](https://doi.org/10.1016/j.neuroimage.2017.04.004) +All these design considerations allow us not only to (1) represent the entire processing pipeline as an *execution graph, where each MIALSRTK C++ tools are connected*, but also to (2) provide a *mecanism to record data provenance and execution details*, and to (3) easily customize the BIDS App to suit specific needs as interfaces with *new tools can be added with relatively little effort* to account for additional algorithms. -[3] S. Tourbier, X. Bresson, P. Hagmann, R. Meuli, M. B. Cuadra, *An efficient total variation -algorithm for super-resolution in fetal brain MRI with adaptive regularization*, Neuroimage 118 -(2015) 584-597. [DOI](https://doi.org/10.1016/j.neuroimage.2015.06.018) +The Docker image of the BIDS App is freely available @ [Docker store](https://store.docker.com/community/images/sebastientourbier/mialsuperresolutiontoolkit-bidsapp). -# Documentation # +## Resources -* FOR USERS: [How to run the Docker image](https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/userguide_docker.md) -* FOR DEVELOPERS/CONTRIBUTORS: [Installation instructions on Ubuntu](https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/devguide_ubuntu.md) / [Installation instructions on MACOSX](https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/devguide_mac.md) -* [Doxygen source code documentation](https://htmlpreview.github.io/?https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/doxygen_html/index.html) +* **BIDS App and `pymialsrtk` documentation:** [https://mialsrtk.readthedocs.io/](https://mialsrtk.readthedocs.io/) -# Credits # +* **Source:** [https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit](https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit) + +* **Bug reports:** [https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit/issues](https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit/issues) + +* **For C++ developers/contributors:** + * [Installation instructions on Ubuntu](https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/devguide_ubuntu.md) / [Installation instructions on MACOSX](https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/devguide_mac.md) + * [C++ code documentation](https://htmlpreview.github.io/?https://github.com/sebastientourbier/mialsuperresolutiontoolkit/blob/master/documentation/doxygen_html/index.html) + +## Usage + +The BIDS App of MIALSRTK has the following command line arguments: + + $ docker run -it sebastientourbier/mialsuperresolutiontoolkit-bidsapp --help + + usage: run.py [-h] + [--participant_label PARTICIPANT_LABEL [PARTICIPANT_LABEL ...]] + [--param_file PARAM_FILE] [--manual] [-v] + bids_dir output_dir {participant} + + Entrypoint script to the MIALSRTK BIDS App + + positional arguments: + bids_dir The directory with the input dataset formatted + according to the BIDS standard. + output_dir The directory where the output files should be stored. + If you are running group level analysis this folder + should be prepopulated with the results of + theparticipant level analysis. + {participant} Level of the analysis that will be performed. Only + participant is available + + optional arguments: + -h, --help show this help message and exit + --participant_label PARTICIPANT_LABEL [PARTICIPANT_LABEL ...] + The label(s) of the participant(s) that should be + analyzed. The label corresponds to + sub- from the BIDS spec (so it does + not include "sub-"). If this parameter is not provided + all subjects should be analyzed. Multiple participants + can be specified with a space separated list. + --param_file PARAM_FILE + Path to a JSON file containing subjects' exams + information and super-resolution total variation + parameters. + --manual Use manual brain masks found in + /manual_masks/ directory + -v, --version show program's version number and exit + +## Credits diff --git a/build_bidsapp.sh b/build_bidsapp.sh new file mode 100644 index 000000000..91fcaf07b --- /dev/null +++ b/build_bidsapp.sh @@ -0,0 +1,23 @@ +#! /bin/sh +CMP_BUILD_DATE="$(date -u +\"%Y-%m-%dT%H:%M:%SZ\")" +echo "$CMP_BUILD_DATE" + +VERSION="v$(python get_version.py)" +echo "$VERSION" + +VCS_REF="$(git rev-parse --verify HEAD)" +echo "$VCS_REF" + +MAIN_DOCKER="sebastientourbier/mialsuperresolutiontoolkit-ubuntu14.04:${VERSION}" +echo "$MAIN_DOCKER" + +docker build --rm --build-arg BUILD_DATE="$CMP_BUILD_DATE" \ + --build-arg VCS_REF="$VCS_REF" \ + --build-arg VERSION="$VERSION" \ + -t "${MAIN_DOCKER}" . \ + +docker build --no-cache --rm --build-arg BUILD_DATE="$CMP_BUILD_DATE" \ + --build-arg VERSION="$VERSION" \ + --build-arg VCS_REF="$VCS_REF" \ + --build-arg MAIN_DOCKER="$MAIN_DOCKER" \ + -t sebastientourbier/mialsuperresolutiontoolkit-bidsapp:"${VERSION}" ./docker/bidsapp diff --git a/build_jupyter.sh b/build_jupyter.sh new file mode 100644 index 000000000..fce42eb62 --- /dev/null +++ b/build_jupyter.sh @@ -0,0 +1,25 @@ +#! /bin/sh +CMP_BUILD_DATE="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" +echo "$CMP_BUILD_DATE" + +VERSION="v$(python get_version.py)" +echo "$VERSION" + +VCS_REF="$(git rev-parse --verify HEAD)" +echo "$VCS_REF" + +MAIN_DOCKER="sebastientourbier/mialsuperresolutiontoolkit-ubuntu14.04:${VERSION}" +echo "$MAIN_DOCKER" + +docker build --rm --build-arg BUILD_DATE="$CMP_BUILD_DATE" \ + --build-arg VCS_REF="$VCS_REF" \ + --build-arg VERSION="$VERSION" \ + -t "${MAIN_DOCKER}" . \ + +JUPYTER_DOCKER="sebastientourbier/mialsuperresolutiontoolkit-jupyter:${VERSION}" + +docker build --rm --build-arg BUILD_DATE="$CMP_BUILD_DATE" \ + --build-arg VERSION="$VERSION" \ + --build-arg VCS_REF="$VCS_REF" \ + --build-arg MAIN_DOCKER="$MAIN_DOCKER" \ + -t "${JUPYTER_DOCKER}" ./docker/jupyter diff --git a/build_sphinx_docs.sh b/build_sphinx_docs.sh new file mode 100644 index 000000000..127560f1b --- /dev/null +++ b/build_sphinx_docs.sh @@ -0,0 +1,23 @@ +#!/usr/bin/bash + +realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +if [[ "$OSTYPE" == "linux-gnu" ]]; then + # Linux + DIR="$(dirname $(readlink -f "$0"))" +elif [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + DIR="$(dirname $(realpath "$0"))" +fi + +echo "Building documentation in $DIR/documentation/_build/html" + +OLDPWD="$PWD" + +cd "$DIR/documentation" +make clean +make html + +cd "$OLDPWD" \ No newline at end of file diff --git a/data/.bidsignore b/data/.bidsignore new file mode 100644 index 000000000..8ac9b3095 --- /dev/null +++ b/data/.bidsignore @@ -0,0 +1,3 @@ +{ + "ignoredFiles": ["*/tmp/**"] +} \ No newline at end of file diff --git a/data/CHANGES b/data/CHANGES new file mode 100644 index 000000000..e5fce6b27 --- /dev/null +++ b/data/CHANGES @@ -0,0 +1,3 @@ +1.0.0 2019-05-10 + +- initial release \ No newline at end of file diff --git a/data/README b/data/README new file mode 100644 index 000000000..996f693e1 --- /dev/null +++ b/data/README @@ -0,0 +1,10 @@ +This sample BIDS dataset contains a set of three orthogonal MRI +with anisotropic resolution (1x1x2mm^3) of the fetal brain of subject "sub-01" +acquired with a fast multi-slice sequence. + +Manually drawn brain masks can be found in derivatives/manual_masks/sub-01/anat folder + +The text file listing the scans used by the supperresolution_pipeline.sh script +can be found in code/ as sub-01_ses-01_scans.txt + +- Sebastien Tourbier (May 10, 2019) \ No newline at end of file diff --git a/data/T30template/axial1_lr.nii.gz b/data/T30template/axial1_lr.nii.gz deleted file mode 100644 index 227761471..000000000 Binary files a/data/T30template/axial1_lr.nii.gz and /dev/null differ diff --git a/data/T30template/axial1_lr_brain_mask.nii.gz b/data/T30template/axial1_lr_brain_mask.nii.gz deleted file mode 100644 index b83bf7a40..000000000 Binary files a/data/T30template/axial1_lr_brain_mask.nii.gz and /dev/null differ diff --git a/data/T30template/coronal1_lr.nii.gz b/data/T30template/coronal1_lr.nii.gz deleted file mode 100644 index b82c00a67..000000000 Binary files a/data/T30template/coronal1_lr.nii.gz and /dev/null differ diff --git a/data/T30template/coronal1_lr_brain_mask.nii.gz b/data/T30template/coronal1_lr_brain_mask.nii.gz deleted file mode 100644 index dca630f8e..000000000 Binary files a/data/T30template/coronal1_lr_brain_mask.nii.gz and /dev/null differ diff --git a/data/T30template/sagittal1_lr.nii.gz b/data/T30template/sagittal1_lr.nii.gz deleted file mode 100644 index 2cff86dc8..000000000 Binary files a/data/T30template/sagittal1_lr.nii.gz and /dev/null differ diff --git a/data/T30template/sagittal1_lr_brain_mask.nii.gz b/data/T30template/sagittal1_lr_brain_mask.nii.gz deleted file mode 100644 index 65f3c9c79..000000000 Binary files a/data/T30template/sagittal1_lr_brain_mask.nii.gz and /dev/null differ diff --git a/data/code/batch_list.txt b/data/code/batch_list.txt new file mode 100644 index 000000000..35aff5601 --- /dev/null +++ b/data/code/batch_list.txt @@ -0,0 +1 @@ +sub-01 ses-01 0.75 0.01 diff --git a/data/code/create_dataset_description_json.sh b/data/code/create_dataset_description_json.sh new file mode 100644 index 000000000..90cfc4e64 --- /dev/null +++ b/data/code/create_dataset_description_json.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# +# Usage: +# sh create_dataset_description_json output.json v1.1.0 +# +# Author: Sebastien Tourbier +# +################################################################### + +OUTPUT_JSON=$1 + +( +cat < $OUTPUT_JSON diff --git a/data/code/create_scan_preproc_json.sh b/data/code/create_scan_preproc_json.sh new file mode 100644 index 000000000..4b5585e4b --- /dev/null +++ b/data/code/create_scan_preproc_json.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Usage: +# sh create_scan_preproc_json output.json source.nii.gz +# +# Author: Sebastien Tourbier +# +################################################################### + +OUTPUT_JSON=$1 + +( +cat < $OUTPUT_JSON diff --git a/data/code/participants_params.json b/data/code/participants_params.json new file mode 100644 index 000000000..1abaaa081 --- /dev/null +++ b/data/code/participants_params.json @@ -0,0 +1,9 @@ +{ + "01": [ + { "sr-id":1, + "stacksOrder": [1, 3, 5], + "paramTV": { + "lambdaTV": 0.75, + "deltatTV": 0.01 } + }] +} \ No newline at end of file diff --git a/data/code/sub-01_ses-01_scans.txt b/data/code/sub-01_ses-01_scans.txt new file mode 100644 index 000000000..199a8a8c9 --- /dev/null +++ b/data/code/sub-01_ses-01_scans.txt @@ -0,0 +1,6 @@ +run-1 axial +run-3 coronal +run-5 sagittal +run-2 axial +run-4 coronal +run-6 sagittal diff --git a/data/code/sub-01_ses-02_scans.txt b/data/code/sub-01_ses-02_scans.txt new file mode 100644 index 000000000..e3004367e --- /dev/null +++ b/data/code/sub-01_ses-02_scans.txt @@ -0,0 +1,6 @@ +run-1 axial +run-2 coronal +run-3 sagittal +run-4 coronal +run-5 sagittal +run-6 sagittal diff --git a/data/code/superresolution_batch.sh b/data/code/superresolution_batch.sh new file mode 100644 index 000000000..cf360b248 --- /dev/null +++ b/data/code/superresolution_batch.sh @@ -0,0 +1,118 @@ +#!/bin/sh +# usage: +# sh superresolution_batch.sh /path/to/batch_list.txt +# +# Author: Sebastien Tourbier +# +################################################################### + +# Use the latest stable release version of the docker image +VERSION_TAG="v1.1.0" + +# Get the directory where the script is stored, +# which is supposed to be in the code folder of the dataset root directory) +# and get absolute path +SCRIPT_DIR="$(dirname "$0")" + +if [[ "$OSTYPE" == "linux-gnu" ]]; then + # Linux + echo "INFO: Linux OS detected!" + SCRIPT_DIR="$(readlink -f $SCRIPT_DIR)" +elif [[ "$OSTYPE" == "darwin" ]]; then + # MacOSX + echo "INFO: MacOSX detected!" +fi + +# Get BIDS dataset root directory +DATASET_DIR="$(dirname "${SCRIPT_DIR}")" + +echo "Dataset root directory : $DATASET_DIR" + + + +#from each line of the subject_parameters.txt given as input +while read -r line + do + #Extract PATIENT, LAMBDA_TV and DELTA_T and the scan list sub-01_ses-01_scans.txt + set -- $line + PATIENT=$1 + LAMBDA_TV=$3 + DELTA_T=$4 + RECON_SESSION=$2 + SCANS_LIST="${PATIENT}_${RECON_SESSION}_scans.txt" + + echo "> Process subject ${PATIENT} with lambda_tv = ${LAMBDA_TV} and delta_t = ${DELTA_T}" + + PATIENT_DIR="$DATASET_DIR/${PATIENT}" + echo " ... Subject directory : ${PATIENT_DIR}" + + # Get the number of scans in the list + # Can be used to differentiate output folders + # i.e. line RESULTS="derivatives/mialsrtk/$PATIENT/${RECON_SESSION}" would become + # RESULTS="derivatives/mialsrtk_scans-${VOLS}/$PATIENT/${RECON_SESSION}" + + VOLS=0 + while read -r line + do + VOLS=$((VOLS+1)) + done < "${DATASET_DIR}/code/${SCANS_LIST}" + + echo " ... Number of scans : ${VOLS}" + echo + + # Create the output directory for results (if not existing). + # run-XX is used to identify different list of scans: + # sub-01_ses-01_scans.txt, sub-01_ses-02_scans.txt, ..., sub-01_ses-XX_scans.txt + # The final superesolution is saved in derivatives/mialsrtk/$PATIENT/ses-XX/anat folder + # All intermediate outputs are saved in a tmp folder (see below). + + if [ ! -d "${DATASET_DIR}/derivatives/mialsrtk" ]; then + mkdir -p "${DATASET_DIR}/derivatives/mialsrtk"; + echo " * Folder ${DATASET_DIR}/derivatives/mialsrtk created" + fi + + if [ ! -f "${DATASET_DIR}/derivatives/mialsrtk/dataset_description.json" ]; + then + sh ${DATASET_DIR}/code/create_dataset_description_json.sh "${DATASET_DIR}/derivatives/mialsrtk/dataset_description.json" "$VERSION_TAG" + fi + + RESULTS="derivatives/mialsrtk/$PATIENT/${RECON_SESSION}" + echo " ... Reconstruction tmp directory: ${DATASET_DIR}/${RESULTS}" + if [ ! -d "${DATASET_DIR}/${RESULTS}" ]; then + mkdir -p "${DATASET_DIR}/${RESULTS}"; + echo " * Folder ${DATASET_DIR}/${RESULTS} created" + fi + if [ ! -d "${DATASET_DIR}/${RESULTS}/tmp" ]; then + mkdir -p "${DATASET_DIR}/${RESULTS}/tmp"; + echo " * Folder ${DATASET_DIR}/${RESULTS}/tmp created" + fi + if [ ! -d "${DATASET_DIR}/${RESULTS}/anat" ]; then + mkdir -p "${DATASET_DIR}/${RESULTS}/anat"; + echo " * Folder ${DATASET_DIR}/${RESULTS}/anat created" + fi + if [ ! -d "${DATASET_DIR}/${RESULTS}/xfm" ]; then + mkdir -p "${DATASET_DIR}/${RESULTS}/xfm"; + echo " * Folder ${DATASET_DIR}/${RESULTS}/xfm created" + fi + + PATIENT_MASK_DIR="derivatives/manual_masks/$PATIENT" + + + # Run the super-resolution pipeline + + docker run --rm -u $(id -u):$(id -g) \ + -v $DATASET_DIR:/fetaldata \ + --entrypoint /fetaldata/code/superresolution_pipeline.sh \ + --env PATIENT="$PATIENT" \ + --env RECON_SESSION="${RECON_SESSION}" \ + --env DELTA_T="$DELTA_T" \ + --env LAMBDA_TV="$LAMBDA_TV "\ + --env PATIENT_DIR="/fetaldata/${PATIENT}/anat" \ + --env PATIENT_MASK_DIR="/fetaldata/${PATIENT_MASK_DIR}/anat" \ + --env RESULTS="/fetaldata/${RESULTS}" \ + -t sebastientourbier/mialsuperresolutiontoolkit:"$VERSION_TAG" \ + "/fetaldata/code/${SCANS_LIST}" + + + +done < "$1" diff --git a/data/superresolution_autoloc.sh b/data/code/superresolution_pipeline.sh old mode 100644 new mode 100755 similarity index 56% rename from data/superresolution_autoloc.sh rename to data/code/superresolution_pipeline.sh index 9f77c06f0..bd0416d07 --- a/data/superresolution_autoloc.sh +++ b/data/code/superresolution_pipeline.sh @@ -1,31 +1,39 @@ -#! Script: Brain image reconstruction / Brain superresolution image using BTK -# Run with log saved: sh reconstruction.sh > reconstruction_original_images.log +#!/bin/sh +# +# Script: Superresolution pipeline for fetal brain MRI +# +# Usage: Run with log saved: sh superresolution_pipeline.sh list_of_scans.txt > reconstruction_original_images.log +# +# Note: $PATIENT $RECON_SESSION $DELTA_T $LAMBDA_TV $PATIENT_DIR $PATIENT_MASK_DIR and $RESULTS are supposed to be defined before calling the script +# +# Author: Sebastien Tourbier +# +######################################################################################################################## + #Tune the number of cores used by the OpenMP library for multi-threading purposes export OMP_NUM_THREADS=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) -PATIENT=$(basename "$PWD") -GA=30 +ANAT_DIR=$RESULTS/anat +XFM_DIR=$RESULTS/xfm +RESULTS=$RESULTS/tmp echo echo "-----------------------------------------------" echo -echo "Processing patient $PATIENT (GA=${GA})" +echo "Starting superresolution pipeline for patient $PATIENT " echo echo "-----------------------------------------------" echo -LAMBDA_TV=0.25 #0.75 -DELTA_T=0.1 +#LAMBDA_TV=0.25 #0.75 +#DELTA_T=0.1 LOOPS=10 RAD_DILATION=1 START_ITER=1 -MAX_ITER=3 -#maskType="_SSMMI_CompositeVersor2DBSplineNCC" # masks after automatic template-based localization and deformable slice-to-template extraction -#maskType="_SSMMI_VersorOnlyNCC" # masks after automatic template-based localization and rigid slice-to-template extraction -#maskType="" # masks after automatic template-based localization -maskType="" # manually drawn masks +MAX_ITER=1 + echo echo "Automated brain localization and extraction parameters" @@ -46,7 +54,6 @@ echo echo "-----------------------------------------------" echo - echo "Initialization..." START1=$(date +%s) @@ -58,42 +65,12 @@ echo echo "OMP # of cores set to ${OMP_NUM_THREADS}!" echo - - - -#export DIR_PREFIX=$(dirname "$0") -#export DIR_PREFIX=$(dirname "$DIR_PREFIX") -#DIR_PREFIX=/media/MYPASSPORT2/Professional/CRL/06-BrainExtraction6_rad1 - #export BIN_DIR="/usr/local/bin" printf "BIN_DIR=${BIN_DIR} \n" -PATIENT_DIR="$(dirname "$0")" -echo "Scan list file : ${1}" -echo "Working directory : $PATIENT_DIR" - -RESULTS=${PATIENT_DIR}/RECON -if [ ! -d "${RESULTS}" ]; then - mkdir -p "${RESULTS}"; - echo "Folder ${RESULTS} created" -fi -echo "Reconstruction directory: $RESULTS" - SCANS="${1}" echo "List of scans : $SCANS" -##Localization -templateName="T${GA}template" -BRAIN_LOC="${PATIENT_DIR}/${templateName}" - -if [ ! -d "${BRAIN_LOC}" ]; then - mkdir -p "${BRAIN_LOC}"; - echo "Folder ${BRAIN_LOC} created" -fi - -template="${ATLAS_DIR}/${templateName}.nii" -templateMask="${ATLAS_DIR}/${templateName}_brain_mask.nii" -echo "Brain localization directory: $BRAIN_LOC" echo "Everything set!" echo @@ -108,7 +85,7 @@ echo echo "-----------------------------------------------" echo -##Count number of scans used for reconstruction + VOLS=0 while read -r line do @@ -132,6 +109,8 @@ do cmdIntensity="mialsrtkIntensityStandardization" cmdIntensityNLM="mialsrtkIntensityStandardization" + cmdHistogramNormalization="python ${BIN_DIR}/mialsrtkHistogramNormalization.py" + cmdHistogramNormalizationNLM="python ${BIN_DIR}/mialsrtkHistogramNormalization.py" if [ "$ITER" -eq "1" ]; then @@ -139,33 +118,41 @@ do while read -r line do set -- $line - stack=$1 + run=$1 + orig_stack="${PATIENT}_${run}_T2w" + stack="${PATIENT}_${RECON_SESSION}_${run}_T2w" orientation=$2 echo "Process stack $stack with $orientation orientation..." #Reorient the image - mialsrtkOrientImage -i $BRAIN_LOC/${stack}.nii.gz -o $RESULTS/${stack}_reo_iteration_${ITER}.nii.gz -O "$orientation" - mialsrtkOrientImage -i $BRAIN_LOC/${stack}_brain_mask${maskType}.nii.gz -o $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz -O "$orientation" + #mialsrtkOrientImage -i ${PATIENT_DIR}/${stack}.nii.gz -o $RESULTS/${stack}_reo_iteration_${ITER}.nii.gz -O "$orientation" + #mialsrtkOrientImage -i ${PATIENT_MASK_DIR}/${stack}_desc-brain_mask.nii.gz -o $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -O "$orientation" + + cp "${PATIENT_DIR}/${orig_stack}.nii.gz" "$RESULTS/${stack}_reo_iteration_${ITER}.nii.gz" + cp "${PATIENT_MASK_DIR}/${orig_stack}_desc-brain_mask.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" #denoising on reoriented images weight="0.1" btkNLMDenoising -i "$RESULTS/${stack}_reo_iteration_${ITER}.nii.gz" -o "$RESULTS/${stack}_nlm_reo_iteration_${ITER}.nii.gz" -b $weight #Make slice intensities uniform in the stack - mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_nlm_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" - mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" + mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_nlm_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" + mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" #bias field correction slice by slice - mialsrtkSliceBySliceN4BiasFieldCorrection "$RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_n4bias.nii.gz" - mialsrtkSliceBySliceCorrectBiasField "$RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_n4bias.nii.gz" "$RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" + mialsrtkSliceBySliceN4BiasFieldCorrection "$RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_n4bias.nii.gz" + mialsrtkSliceBySliceCorrectBiasField "$RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_n4bias.nii.gz" "$RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" - mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" - mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" + mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" + mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" #Intensity rescaling cmd preparation cmdIntensityNLM="$cmdIntensityNLM -i $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" cmdIntensity="$cmdIntensity -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" + cmdHistogramNormalization="$cmdHistogramNormalization -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" + cmdHistogramNormalizationNLM="$cmdHistogramNormalizationNLM -i $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" + done < "$SCANS" echo "$cmdIntensity" @@ -175,14 +162,15 @@ do while read -r line do set -- $line - stack=$1 + run=$1 + stack="${PATIENT}_${RECON_SESSION}_${run}_T2w" #Make slice intensities uniform in the stack - mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_nlm_reo_iteration_1.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" - mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_reo_iteration_1.nii.gz" "$RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" + mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_nlm_reo_iteration_1.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" + mialsrtkCorrectSliceIntensity "$RESULTS/${stack}_reo_iteration_1.nii.gz" "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "$RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" cmdCorrectBiasField="mialsrtkCorrectBiasFieldWithMotionApplied -i $RESULTS/${stack}_nlm_uni_reo_iteration_${ITER}.nii.gz" - cmdCorrectBiasField="$cmdCorrectBiasField -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" + cmdCorrectBiasField="$cmdCorrectBiasField -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" cmdCorrectBiasField="$cmdCorrectBiasField -o $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" cmdCorrectBiasField="$cmdCorrectBiasField --input-bias-field $RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${ITER}_gbcorrfield.nii.gz" cmdCorrectBiasField="$cmdCorrectBiasField --output-bias-field $RESULTS/${stack}_nlm_n4bias_iteration_${ITER}.nii.gz" @@ -190,7 +178,7 @@ do eval "$cmdCorrectBiasField" cmdCorrectBiasField="mialsrtkCorrectBiasFieldWithMotionApplied -i $RESULTS/${stack}_uni_reo_iteration_${ITER}.nii.gz" - cmdCorrectBiasField="$cmdCorrectBiasField -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" + cmdCorrectBiasField="$cmdCorrectBiasField -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" cmdCorrectBiasField="$cmdCorrectBiasField -o $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" cmdCorrectBiasField="$cmdCorrectBiasField --input-bias-field $RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${ITER}_gbcorrfield.nii.gz" cmdCorrectBiasField="$cmdCorrectBiasField --output-bias-field $RESULTS/${stack}_n4bias_iteration_${ITER}.nii.gz" @@ -200,6 +188,9 @@ do cmdIntensityNLM="$cmdIntensityNLM -i $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz" cmdIntensity="$cmdIntensity -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz" + cmdHistogramNormalization="$cmdHistogramNormalization -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}.nii.gz -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" + cmdHistogramNormalizationNLM="$cmdHistogramNormalizationNLM -i $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}.nii.gz -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -o $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" + done < "$SCANS" fi @@ -210,15 +201,16 @@ do eval "$cmdIntensity" #histogram normalization - need to change the brain mask name expected according to the one used (full auto/localization and rigid extraction/localization only/manual) - python ${BIN_DIR}/mialsrtkHistogramNormalization.py -i "${RESULTS}" -m "${RESULTS}" -t "${maskType}" -o "${RESULTS}" -I "${ITER}" -S "nlm_uni_bcorr_reo" - python ${BIN_DIR}/mialsrtkHistogramNormalization.py -i "${RESULTS}" -m "${RESULTS}" -t "${maskType}" -o "${RESULTS}" -I "${ITER}" -S "uni_bcorr_reo" + eval "$cmdHistogramNormalization" + eval "$cmdHistogramNormalizationNLM" cmdIntensity="mialsrtkIntensityStandardization" cmdIntensityNLM="mialsrtkIntensityStandardization" while read -r line do set -- $line - stack=$1 + run=$1 + stack="${PATIENT}_${RECON_SESSION}_${run}_T2w" #Intensity rescaling cmd preparation cmdIntensityNLM="$cmdIntensityNLM -i $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz -o $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" cmdIntensity="$cmdIntensity -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz -o $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" @@ -238,17 +230,18 @@ do while read -r line do set -- $line - stack=$1 - mialsrtkMaskImage -i "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz -o "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" + run=$1 + stack="${PATIENT}_${RECON_SESSION}_${run}_T2w" + mialsrtkMaskImage -i "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -o "$RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" cmdImageRECON="$cmdImageRECON -i $RESULTS/${stack}_nlm_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" - cmdImageRECON="$cmdImageRECON -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" + cmdImageRECON="$cmdImageRECON -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" cmdImageRECON="$cmdImageRECON -t $RESULTS/${stack}_transform_${VOLS}V_${ITER}.txt" cmdSuperResolution="$cmdSuperResolution -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" - cmdSuperResolution="$cmdSuperResolution -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" + cmdSuperResolution="$cmdSuperResolution -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" cmdSuperResolution="$cmdSuperResolution -t $RESULTS/${stack}_transform_${VOLS}V_${ITER}.txt" - #cmdRobustSuperResolution="$cmdRobustSuperResolution -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz -t $RESULTS/${stack}_transform_${VOLS}V_${ITER}.txt" + #cmdRobustSuperResolution="$cmdRobustSuperResolution -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz -t $RESULTS/${stack}_transform_${VOLS}V_${ITER}.txt" done < "$SCANS" #Run motion estimation and SDI reconstruction @@ -265,10 +258,11 @@ do #Brain image super-reconstruction echo "Reconstruct the super-resolution image with initial brain masks- Iteration ${ITER}..." - cmdSuperResolution="$cmdSuperResolution -o $RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${ITER}.nii.gz" + cmdSuperResolution="$cmdSuperResolution -o $RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}.nii.gz" cmdSuperResolution="$cmdSuperResolution -r $RESULTS/SDI_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}.nii.gz" cmdSuperResolution="$cmdSuperResolution --bregman-loop 1 --loop ${LOOPS} --iter 50 --step-scale 10 --gamma 10 --deltat ${DELTA_T}" cmdSuperResolution="$cmdSuperResolution --lambda ${LAMBDA_TV} --inner-thresh 0.00001 --outer-thresh 0.000001" + echo "CMD: $cmdSuperResolution" eval "$cmdSuperResolution" echo "Done" @@ -295,11 +289,12 @@ do while read -r line do set -- $line - stack=$1 + run=$1 + stack="${PATIENT}_${RECON_SESSION}_${run}_T2w" cmdRefineMasks="$cmdRefineMasks -i $RESULTS/${stack}_uni_bcorr_reo_iteration_${ITER}_histnorm.nii.gz" - cmdRefineMasks="$cmdRefineMasks -m $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${ITER}.nii.gz" + cmdRefineMasks="$cmdRefineMasks -m $RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" cmdRefineMasks="$cmdRefineMasks -t $RESULTS/${stack}_transform_${VOLS}V_${ITER}.txt" - cmdRefineMasks="$cmdRefineMasks -O $RESULTS/${stack}_brain_mask${maskType}_reo_iteration_${NEXT_ITER}.nii.gz" + cmdRefineMasks="$cmdRefineMasks -O $RESULTS/${stack}_desc-brain_mask_reo_iteration_${NEXT_ITER}.nii.gz" done < "$SCANS" #Brain mask refinement @@ -308,11 +303,11 @@ do eval "$cmdRefineMasks" #Bias field refinement - mialsrtkN4BiasFieldCorrection "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${ITER}.nii.gz" "$RESULTS/SDI_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_brain_mask.nii.gz" "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${NEXT_ITER}_gbcorr.nii.gz" "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${NEXT_ITER}_gbcorrfield.nii.gz" + mialsrtkN4BiasFieldCorrection "$RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}.nii.gz" "$RESULTS/SDI_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_brain_mask.nii.gz" "$RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_gbcorr.nii.gz" "$RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_gbcorrfield.nii.gz" #Brain masking of the reconstructed image - mialsrtkMaskImage -i "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${ITER}.nii.gz" -m "$RESULTS/SDI_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_brain_mask.nii.gz" -o "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${ITER}_masked.nii.gz" + mialsrtkMaskImage -i "$RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}.nii.gz" -m "$RESULTS/SDI_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_brain_mask.nii.gz" -o $RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${ITER}_masked.nii.gz echo echo "##########################################################################################################################" @@ -322,9 +317,70 @@ do ITER=$((ITER+1)) done +#LAST_ITER=1 + + +# Extract absolute path of the folder containing the scripts (i.e. /fetaldata/code) +CODE_DIR="$(dirname "$0")" +CODE_DIR="$(readlink -f $CODE_DIR)" + +echo "Dataset code directory: ${CODE_DIR}" + +# Move the preprocessed input scans to anat and their associated slice-to-volume transform and +# create their respective json file (BIDS Common Derivatives RC1) + +SOURCES="" +while read -r line +do + set -- $line + run=$1 + orig_stack="${PATIENT}_${run}_T2w" + stack="${PATIENT}_${RECON_SESSION}_${run}_T2w" + + # Copy and rename the transform, the image, and the brain mask + cp "$RESULTS/${stack}_transform_${VOLS}V_${LAST_ITER}.txt" "${XFM_DIR}/${stack}_from-orig_to-SDI_mode-image_xfm.txt" + cp "$RESULTS/${stack}_uni_bcorr_reo_iteration_${LAST_ITER}_histnorm.nii.gz" "${ANAT_DIR}/${stack}_preproc.nii.gz" + cp "$RESULTS/${stack}_desc-brain_mask_reo_iteration_${ITER}.nii.gz" "${ANAT_DIR}/${stack}_desc-brain_mask.nii.gz" + + # Create the BIDS json sidecar (image) and copy/rename BIDS json sidecar of manual mask + sh ${CODE_DIR}/create_scan_preproc_json.sh "${ANAT_DIR}/${stack}_preproc.json" "${PATIENT_DIR}/${stack}.nii.gz" + cp "${PATIENT_MASK_DIR}/${orig_stack}_desc-brain_mask.nii.gz" "${ANAT_DIR}/${stack}_desc-brain_mask.json" + + SOURCES="${SOURCES} \"${ANAT_DIR}/${stack}_preproc.nii.gz\", \"${XFM_DIR}/${stack}_from-orig_to-SDI_mode-image_xfm.txt\" ," + +done < "$SCANS" -cp "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${LAST_ITER}.nii.gz" "$PATIENT_DIR/superresolution.nii.gz" -cp "$RESULTS/SRTV_${PATIENT}_${VOLS}V_lambda_${LAMBDA_TV}_deltat_${DELTA_T}_loops_${LOOPS}_rad${RAD_DILATION}_it${LAST_ITER}_masked.nii.gz" "$PATIENT_DIR/superresolution_masked.nii.gz" +# Move the reconstructed images to anat and create the json file (BIDS Common Derivatives RC1) + +ANAT_DIR="$(dirname "$RESULTS")/anat" +echo "Copy final outputs to ${ANAT_DIR}" +cp "$RESULTS/SDI_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${LAST_ITER}.nii.gz" "${ANAT_DIR}/${PATIENT}_${RECON_SESSION}_rec-SDI_T2w.nii.gz" +cp "$RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${LAST_ITER}.nii.gz" "${ANAT_DIR}/${PATIENT}_${RECON_SESSION}_rec-SR_T2w.nii.gz" +cp "$RESULTS/SRTV_${PATIENT}_${VOLS}V_rad${RAD_DILATION}_it${LAST_ITER}_masked.nii.gz" "${ANAT_DIR}/${PATIENT}_${RECON_SESSION}_rec-SR_desc-masked_T2w.nii.gz" + + +# Create the json file for the super-resolution images +OUTPUT_JSON="${ANAT_DIR}/${PATIENT}_${RECON_SESSION}_rec-SR.json" +( +cat < $OUTPUT_JSON + +echo +echo "##########################################################################################################################" +echo END1=$(date +%s) diff --git a/data/dataset_description.json b/data/dataset_description.json new file mode 100644 index 000000000..3f6c2ad54 --- /dev/null +++ b/data/dataset_description.json @@ -0,0 +1,6 @@ +{ + "Name": "MIALSRTK sample fetal BIDS dataset", + "BIDSVersion": "1.2.0", + "License": "CCO", + "ReferencesAndLinks": [""] +} \ No newline at end of file diff --git a/data/derivatives/manual_masks/dataset_description.json b/data/derivatives/manual_masks/dataset_description.json new file mode 100644 index 000000000..1e9809ff7 --- /dev/null +++ b/data/derivatives/manual_masks/dataset_description.json @@ -0,0 +1,7 @@ +{ + "PipelineDescription": { + "Name": "Manually-drawn brain masks" + }, + "Name": "Manually-drawn brain masks", + "BIDSVersion": "1.2.0" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.json b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.json new file mode 100644 index 000000000..7d037111c --- /dev/null +++ b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.json @@ -0,0 +1,5 @@ +{ + "Rawsources" : "sub-01/anat/sub-01_run-1_T2w.nii.gz", + "Space": "orig", + "Type": "Brain" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.nii.gz b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.nii.gz new file mode 100755 index 000000000..9e7945a8a Binary files /dev/null and b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.nii.gz differ diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.json b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.json new file mode 100644 index 000000000..c2fa9aff1 --- /dev/null +++ b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.json @@ -0,0 +1,5 @@ +{ + "Rawsources" : "sub-01/anat/sub-01_run-2_T2w.nii.gz", + "Space": "orig", + "Type": "Brain" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.nii.gz b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.nii.gz new file mode 100755 index 000000000..6dc3af5a0 Binary files /dev/null and b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.nii.gz differ diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.json b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.json new file mode 100644 index 000000000..b31638b3d --- /dev/null +++ b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.json @@ -0,0 +1,5 @@ +{ + "Rawsources" : "sub-01/anat/sub-01_run-3_T2w.nii.gz", + "Space": "orig", + "Type": "Brain" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.nii.gz b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.nii.gz new file mode 100755 index 000000000..1e37ffb55 Binary files /dev/null and b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.nii.gz differ diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.json b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.json new file mode 100644 index 000000000..44a75c0d2 --- /dev/null +++ b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.json @@ -0,0 +1,5 @@ +{ + "Rawsources" : "sub-01/anat/sub-01_run-4_T2w.nii.gz", + "Space": "orig", + "Type": "Brain" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.nii.gz b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.nii.gz new file mode 100755 index 000000000..1708e017d Binary files /dev/null and b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.nii.gz differ diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.json b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.json new file mode 100644 index 000000000..47cbc8fb0 --- /dev/null +++ b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.json @@ -0,0 +1,5 @@ +{ + "Rawsources" : "sub-01/anat/sub-01_run-5_T2w.nii.gz", + "Space": "orig", + "Type": "Brain" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.nii.gz b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.nii.gz new file mode 100755 index 000000000..ca495ca31 Binary files /dev/null and b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.nii.gz differ diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.json b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.json new file mode 100644 index 000000000..8747273f2 --- /dev/null +++ b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.json @@ -0,0 +1,5 @@ +{ + "Rawsources" : "sub-01/anat/sub-01_run-6_T2w.nii.gz", + "Space": "orig", + "Type": "Brain" +} diff --git a/data/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.nii.gz b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.nii.gz new file mode 100755 index 000000000..5cf9e0aa7 Binary files /dev/null and b/data/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.nii.gz differ diff --git a/data/listScansRECONauto.txt b/data/listScansRECONauto.txt deleted file mode 100644 index 976fa0e15..000000000 --- a/data/listScansRECONauto.txt +++ /dev/null @@ -1,3 +0,0 @@ -axial1_lr axial -coronal1_lr coronal -sagittal1_lr sagittal diff --git a/data/participants.json b/data/participants.json new file mode 100644 index 000000000..d0c0b068a --- /dev/null +++ b/data/participants.json @@ -0,0 +1,16 @@ +{ + "age": { + "Description": "Gestational age", + "Units": "weeks" + }, + + "sex": { + "Description": "sex of the fetus", + "Levels": { + "m": "male", + "f": "female", + "na": "not attributed" + } + } +} + diff --git a/data/participants.tsv b/data/participants.tsv new file mode 100644 index 000000000..9f59220b8 --- /dev/null +++ b/data/participants.tsv @@ -0,0 +1,3 @@ +participant_id sex age +sub-01 n/a n/a + diff --git a/data/sub-01/anat/sub-01_run-1_T2w.json b/data/sub-01/anat/sub-01_run-1_T2w.json new file mode 100755 index 000000000..86d011a90 --- /dev/null +++ b/data/sub-01/anat/sub-01_run-1_T2w.json @@ -0,0 +1,72 @@ +{ + "Modality": "MR", + "MagneticFieldStrength": 1.5, + "ImagingFrequency": 63.6693, + "Manufacturer": "Siemens", + "ManufacturersModelName": "Aera", + "InstitutionName": "Radiologie_CHUV", + "InstitutionalDepartmentName": "Radiodiagnostic", + "InstitutionAddress": "Rue_du_Bugnon_21_Lausanne_District_CH_1011", + "DeviceSerialNumber": "41200", + "StationName": "AWP41200", + "BodyPartExamined": "ABDOMENPELVIS", + "PatientPosition": "HFS", + "ProcedureStepDescription": "IRM_FOETALE", + "SoftwareVersions": "syngo_MR_E11", + "MRAcquisitionType": "2D", + "SeriesDescription": "T2_haste_3mm", + "ProtocolName": "T2_haste_3mm", + "ScanningSequence": "SE", + "SequenceVariant": "SK_SP_OSP", + "ScanOptions": "PFP", + "SequenceName": "_h2d1_224", + "ImageType": ["ORIGINAL", "PRIMARY", "M", "NORM", "DIS2D"], + "SeriesNumber": 2, + "AcquisitionTime": "17:00:58.777500", + "AcquisitionNumber": 1, + "SliceThickness": 3, + "SpacingBetweenSlices": 3.3, + "SAR": 2, + "EchoTime": 0.09, + "RepetitionTime": 1.2, + "FlipAngle": 167, + "PartialFourier": 0.5, + "BaseResolution": 320, + "ShimSetting": [ + -888, + 5, + 4578, + -1465, + -48, + 13, + 19, + 132 ], + "TxRefAmp": 362.247, + "PhaseResolution": 0.7, + "PhaseOversampling": 0.8, + "ReceiveCoilName": "Spine_32", + "ReceiveCoilActiveElements": "BO1-3;SP3-5", + "PulseSequenceDetails": "%SiemensSeq%_haste", + "ConsistencyInfo": "N4_VE11A_LATEST_20140830", + "PercentPhaseFOV": 100, + "EchoTrainLength": 134, + "PhaseEncodingSteps": 225, + "AcquisitionMatrixPE": 224, + "ReconMatrixPE": 320, + "ParallelReductionFactorInPlane": 2, + "PixelBandwidth": 710, + "DwellTime": 2.2e-06, + "PhaseEncodingDirection": "i", + "SliceTiming": [ + ], + "ImageOrientationPatientDICOM": [ + 0.118404, + 0.992966, + -4.35961e-10, + 0.0294575, + -0.0035126, + -0.99956 ], + "InPlanePhaseEncodingDirectionDICOM": "ROW", + "ConversionSoftware": "dcm2niix", + "ConversionSoftwareVersion": "v1.0.20181125 GCC5.3.1" +} diff --git a/data/sub-01/anat/sub-01_run-1_T2w.nii.gz b/data/sub-01/anat/sub-01_run-1_T2w.nii.gz new file mode 100755 index 000000000..3db4db7a8 Binary files /dev/null and b/data/sub-01/anat/sub-01_run-1_T2w.nii.gz differ diff --git a/data/sub-01/anat/sub-01_run-2_T2w.json b/data/sub-01/anat/sub-01_run-2_T2w.json new file mode 100755 index 000000000..b8e0806f9 --- /dev/null +++ b/data/sub-01/anat/sub-01_run-2_T2w.json @@ -0,0 +1,72 @@ +{ + "Modality": "MR", + "MagneticFieldStrength": 1.5, + "ImagingFrequency": 63.6693, + "Manufacturer": "Siemens", + "ManufacturersModelName": "Aera", + "InstitutionName": "Radiologie_CHUV", + "InstitutionalDepartmentName": "Radiodiagnostic", + "InstitutionAddress": "Rue_du_Bugnon_21_Lausanne_District_CH_1011", + "DeviceSerialNumber": "41200", + "StationName": "AWP41200", + "BodyPartExamined": "ABDOMENPELVIS", + "PatientPosition": "HFS", + "ProcedureStepDescription": "IRM_FOETALE", + "SoftwareVersions": "syngo_MR_E11", + "MRAcquisitionType": "2D", + "SeriesDescription": "T2_haste_3mm", + "ProtocolName": "T2_haste_3mm", + "ScanningSequence": "SE", + "SequenceVariant": "SK_SP_OSP", + "ScanOptions": "PFP", + "SequenceName": "_h2d1_224", + "ImageType": ["ORIGINAL", "PRIMARY", "M", "NORM", "DIS2D"], + "SeriesNumber": 3, + "AcquisitionTime": "17:01:58.207500", + "AcquisitionNumber": 1, + "SliceThickness": 3, + "SpacingBetweenSlices": 3.3, + "SAR": 2, + "EchoTime": 0.09, + "RepetitionTime": 1.2, + "FlipAngle": 167, + "PartialFourier": 0.5, + "BaseResolution": 320, + "ShimSetting": [ + -888, + 5, + 4578, + -1465, + -48, + 13, + 19, + 132 ], + "TxRefAmp": 362.247, + "PhaseResolution": 0.7, + "PhaseOversampling": 0.8, + "ReceiveCoilName": "Spine_32", + "ReceiveCoilActiveElements": "BO1-3;SP3-5", + "PulseSequenceDetails": "%SiemensSeq%_haste", + "ConsistencyInfo": "N4_VE11A_LATEST_20140830", + "PercentPhaseFOV": 100, + "EchoTrainLength": 134, + "PhaseEncodingSteps": 225, + "AcquisitionMatrixPE": 224, + "ReconMatrixPE": 320, + "ParallelReductionFactorInPlane": 2, + "PixelBandwidth": 710, + "DwellTime": 2.2e-06, + "PhaseEncodingDirection": "i", + "SliceTiming": [ + ], + "ImageOrientationPatientDICOM": [ + 0.118404, + 0.992966, + -4.35961e-10, + 0.0294575, + -0.0035126, + -0.99956 ], + "InPlanePhaseEncodingDirectionDICOM": "ROW", + "ConversionSoftware": "dcm2niix", + "ConversionSoftwareVersion": "v1.0.20181125 GCC5.3.1" +} diff --git a/data/sub-01/anat/sub-01_run-2_T2w.nii.gz b/data/sub-01/anat/sub-01_run-2_T2w.nii.gz new file mode 100755 index 000000000..9a984f67d Binary files /dev/null and b/data/sub-01/anat/sub-01_run-2_T2w.nii.gz differ diff --git a/data/sub-01/anat/sub-01_run-3_T2w.json b/data/sub-01/anat/sub-01_run-3_T2w.json new file mode 100755 index 000000000..cdbb078ce --- /dev/null +++ b/data/sub-01/anat/sub-01_run-3_T2w.json @@ -0,0 +1,73 @@ +{ + "Modality": "MR", + "MagneticFieldStrength": 1.5, + "ImagingFrequency": 63.6693, + "Manufacturer": "Siemens", + "ManufacturersModelName": "Aera", + "InstitutionName": "Radiologie_CHUV", + "InstitutionalDepartmentName": "Radiodiagnostic", + "InstitutionAddress": "Rue_du_Bugnon_21_Lausanne_District_CH_1011", + "DeviceSerialNumber": "41200", + "StationName": "AWP41200", + "BodyPartExamined": "ABDOMENPELVIS", + "PatientPosition": "HFS", + "ProcedureStepDescription": "IRM_FOETALE", + "SoftwareVersions": "syngo_MR_E11", + "MRAcquisitionType": "2D", + "SeriesDescription": "T2_haste_3mm", + "ProtocolName": "T2_haste_3mm", + "ScanningSequence": "SE", + "SequenceVariant": "SK_SP_OSP", + "ScanOptions": "PFP", + "SequenceName": "_h2d1_224", + "ImageType": ["ORIGINAL", "PRIMARY", "M", "NORM", "DIS2D"], + "SeriesNumber": 4, + "AcquisitionTime": "17:03:12.657500", + "AcquisitionNumber": 1, + "SliceThickness": 3, + "SpacingBetweenSlices": 3.3, + "SAR": 2, + "EchoTime": 0.09, + "RepetitionTime": 1.2, + "FlipAngle": 168, + "PartialFourier": 0.5, + "BaseResolution": 320, + "ShimSetting": [ + -888, + 5, + 4578, + -1465, + -48, + 13, + 19, + 132 ], + "TxRefAmp": 360.391, + "PhaseResolution": 0.7, + "PhaseOversampling": 0.8, + "ReceiveCoilName": "Body_18", + "ReceiveCoilActiveElements": "BO2,3;SP4", + "CoilString": "BO2_3;SP4", + "PulseSequenceDetails": "%SiemensSeq%_haste", + "ConsistencyInfo": "N4_VE11A_LATEST_20140830", + "PercentPhaseFOV": 100, + "EchoTrainLength": 134, + "PhaseEncodingSteps": 225, + "AcquisitionMatrixPE": 224, + "ReconMatrixPE": 320, + "ParallelReductionFactorInPlane": 2, + "PixelBandwidth": 710, + "DwellTime": 2.2e-06, + "PhaseEncodingDirection": "j-", + "SliceTiming": [ + ], + "ImageOrientationPatientDICOM": [ + 0.999566, + 0.000103509, + 0.0294573, + 8.02429e-09, + 0.999994, + -0.00351412 ], + "InPlanePhaseEncodingDirectionDICOM": "COL", + "ConversionSoftware": "dcm2niix", + "ConversionSoftwareVersion": "v1.0.20181125 GCC5.3.1" +} diff --git a/data/sub-01/anat/sub-01_run-3_T2w.nii.gz b/data/sub-01/anat/sub-01_run-3_T2w.nii.gz new file mode 100755 index 000000000..f4ced1e96 Binary files /dev/null and b/data/sub-01/anat/sub-01_run-3_T2w.nii.gz differ diff --git a/data/sub-01/anat/sub-01_run-4_T2w.json b/data/sub-01/anat/sub-01_run-4_T2w.json new file mode 100755 index 000000000..2c0134d86 --- /dev/null +++ b/data/sub-01/anat/sub-01_run-4_T2w.json @@ -0,0 +1,73 @@ +{ + "Modality": "MR", + "MagneticFieldStrength": 1.5, + "ImagingFrequency": 63.6693, + "Manufacturer": "Siemens", + "ManufacturersModelName": "Aera", + "InstitutionName": "Radiologie_CHUV", + "InstitutionalDepartmentName": "Radiodiagnostic", + "InstitutionAddress": "Rue_du_Bugnon_21_Lausanne_District_CH_1011", + "DeviceSerialNumber": "41200", + "StationName": "AWP41200", + "BodyPartExamined": "ABDOMENPELVIS", + "PatientPosition": "HFS", + "ProcedureStepDescription": "IRM_FOETALE", + "SoftwareVersions": "syngo_MR_E11", + "MRAcquisitionType": "2D", + "SeriesDescription": "T2_haste_3mm", + "ProtocolName": "T2_haste_3mm", + "ScanningSequence": "SE", + "SequenceVariant": "SK_SP_OSP", + "ScanOptions": "PFP", + "SequenceName": "_h2d1_224", + "ImageType": ["ORIGINAL", "PRIMARY", "M", "NORM", "DIS2D"], + "SeriesNumber": 5, + "AcquisitionTime": "17:04:11.085000", + "AcquisitionNumber": 1, + "SliceThickness": 3, + "SpacingBetweenSlices": 3.3, + "SAR": 2, + "EchoTime": 0.09, + "RepetitionTime": 1.2, + "FlipAngle": 168, + "PartialFourier": 0.5, + "BaseResolution": 320, + "ShimSetting": [ + -888, + 5, + 4578, + -1465, + -48, + 13, + 19, + 132 ], + "TxRefAmp": 360.391, + "PhaseResolution": 0.7, + "PhaseOversampling": 0.8, + "ReceiveCoilName": "Body_18", + "ReceiveCoilActiveElements": "BO2,3;SP4", + "CoilString": "BO2_3;SP4", + "PulseSequenceDetails": "%SiemensSeq%_haste", + "ConsistencyInfo": "N4_VE11A_LATEST_20140830", + "PercentPhaseFOV": 100, + "EchoTrainLength": 134, + "PhaseEncodingSteps": 225, + "AcquisitionMatrixPE": 224, + "ReconMatrixPE": 320, + "ParallelReductionFactorInPlane": 2, + "PixelBandwidth": 710, + "DwellTime": 2.2e-06, + "PhaseEncodingDirection": "j-", + "SliceTiming": [ + ], + "ImageOrientationPatientDICOM": [ + 0.999566, + 0.000103509, + 0.0294573, + 8.02429e-09, + 0.999994, + -0.00351412 ], + "InPlanePhaseEncodingDirectionDICOM": "COL", + "ConversionSoftware": "dcm2niix", + "ConversionSoftwareVersion": "v1.0.20181125 GCC5.3.1" +} diff --git a/data/sub-01/anat/sub-01_run-4_T2w.nii.gz b/data/sub-01/anat/sub-01_run-4_T2w.nii.gz new file mode 100755 index 000000000..4c3319072 Binary files /dev/null and b/data/sub-01/anat/sub-01_run-4_T2w.nii.gz differ diff --git a/data/sub-01/anat/sub-01_run-5_T2w.json b/data/sub-01/anat/sub-01_run-5_T2w.json new file mode 100755 index 000000000..1b8b7ff2f --- /dev/null +++ b/data/sub-01/anat/sub-01_run-5_T2w.json @@ -0,0 +1,72 @@ +{ + "Modality": "MR", + "MagneticFieldStrength": 1.5, + "ImagingFrequency": 63.6693, + "Manufacturer": "Siemens", + "ManufacturersModelName": "Aera", + "InstitutionName": "Radiologie_CHUV", + "InstitutionalDepartmentName": "Radiodiagnostic", + "InstitutionAddress": "Rue_du_Bugnon_21_Lausanne_District_CH_1011", + "DeviceSerialNumber": "41200", + "StationName": "AWP41200", + "BodyPartExamined": "ABDOMENPELVIS", + "PatientPosition": "HFS", + "ProcedureStepDescription": "IRM_FOETALE", + "SoftwareVersions": "syngo_MR_E11", + "MRAcquisitionType": "2D", + "SeriesDescription": "T2_haste_3mm", + "ProtocolName": "T2_haste_3mm", + "ScanningSequence": "SE", + "SequenceVariant": "SK_SP_OSP", + "ScanOptions": "PFP", + "SequenceName": "_h2d1_224", + "ImageType": ["ORIGINAL", "PRIMARY", "M", "NORM", "DIS2D"], + "SeriesNumber": 6, + "AcquisitionTime": "17:05:12.380000", + "AcquisitionNumber": 1, + "SliceThickness": 3, + "SpacingBetweenSlices": 3.3, + "SAR": 2, + "EchoTime": 0.09, + "RepetitionTime": 1.2, + "FlipAngle": 168, + "PartialFourier": 0.5, + "BaseResolution": 320, + "ShimSetting": [ + -888, + 5, + 4578, + -1465, + -48, + 13, + 19, + 132 ], + "TxRefAmp": 360.391, + "PhaseResolution": 0.7, + "PhaseOversampling": 0.8, + "ReceiveCoilName": "Spine_32", + "ReceiveCoilActiveElements": "BO1-3;SP3-5", + "PulseSequenceDetails": "%SiemensSeq%_haste", + "ConsistencyInfo": "N4_VE11A_LATEST_20140830", + "PercentPhaseFOV": 100, + "EchoTrainLength": 134, + "PhaseEncodingSteps": 225, + "AcquisitionMatrixPE": 224, + "ReconMatrixPE": 320, + "ParallelReductionFactorInPlane": 2, + "PixelBandwidth": 710, + "DwellTime": 2.2e-06, + "PhaseEncodingDirection": "i", + "SliceTiming": [ + ], + "ImageOrientationPatientDICOM": [ + 0.992879, + -0.119124, + 2.97176e-09, + -0.00290917, + -0.0242476, + -0.999702 ], + "InPlanePhaseEncodingDirectionDICOM": "ROW", + "ConversionSoftware": "dcm2niix", + "ConversionSoftwareVersion": "v1.0.20181125 GCC5.3.1" +} diff --git a/data/sub-01/anat/sub-01_run-5_T2w.nii.gz b/data/sub-01/anat/sub-01_run-5_T2w.nii.gz new file mode 100755 index 000000000..91ef55682 Binary files /dev/null and b/data/sub-01/anat/sub-01_run-5_T2w.nii.gz differ diff --git a/data/sub-01/anat/sub-01_run-6_T2w.json b/data/sub-01/anat/sub-01_run-6_T2w.json new file mode 100755 index 000000000..972eca371 --- /dev/null +++ b/data/sub-01/anat/sub-01_run-6_T2w.json @@ -0,0 +1,72 @@ +{ + "Modality": "MR", + "MagneticFieldStrength": 1.5, + "ImagingFrequency": 63.6693, + "Manufacturer": "Siemens", + "ManufacturersModelName": "Aera", + "InstitutionName": "Radiologie_CHUV", + "InstitutionalDepartmentName": "Radiodiagnostic", + "InstitutionAddress": "Rue_du_Bugnon_21_Lausanne_District_CH_1011", + "DeviceSerialNumber": "41200", + "StationName": "AWP41200", + "BodyPartExamined": "ABDOMENPELVIS", + "PatientPosition": "HFS", + "ProcedureStepDescription": "IRM_FOETALE", + "SoftwareVersions": "syngo_MR_E11", + "MRAcquisitionType": "2D", + "SeriesDescription": "T2_haste_3mm", + "ProtocolName": "T2_haste_3mm", + "ScanningSequence": "SE", + "SequenceVariant": "SK_SP_OSP", + "ScanOptions": "PFP", + "SequenceName": "_h2d1_224", + "ImageType": ["ORIGINAL", "PRIMARY", "M", "NORM", "DIS2D"], + "SeriesNumber": 7, + "AcquisitionTime": "17:06:17.047500", + "AcquisitionNumber": 1, + "SliceThickness": 3, + "SpacingBetweenSlices": 3.3, + "SAR": 2, + "EchoTime": 0.09, + "RepetitionTime": 1.2, + "FlipAngle": 168, + "PartialFourier": 0.5, + "BaseResolution": 320, + "ShimSetting": [ + -888, + 5, + 4578, + -1465, + -48, + 13, + 19, + 132 ], + "TxRefAmp": 360.391, + "PhaseResolution": 0.7, + "PhaseOversampling": 0.8, + "ReceiveCoilName": "Spine_32", + "ReceiveCoilActiveElements": "BO1-3;SP3-5", + "PulseSequenceDetails": "%SiemensSeq%_haste", + "ConsistencyInfo": "N4_VE11A_LATEST_20140830", + "PercentPhaseFOV": 100, + "EchoTrainLength": 134, + "PhaseEncodingSteps": 225, + "AcquisitionMatrixPE": 224, + "ReconMatrixPE": 320, + "ParallelReductionFactorInPlane": 2, + "PixelBandwidth": 710, + "DwellTime": 2.2e-06, + "PhaseEncodingDirection": "i", + "SliceTiming": [ + ], + "ImageOrientationPatientDICOM": [ + 0.992879, + -0.119124, + 2.97176e-09, + -0.00290917, + -0.0242476, + -0.999702 ], + "InPlanePhaseEncodingDirectionDICOM": "ROW", + "ConversionSoftware": "dcm2niix", + "ConversionSoftwareVersion": "v1.0.20181125 GCC5.3.1" +} diff --git a/data/sub-01/anat/sub-01_run-6_T2w.nii.gz b/data/sub-01/anat/sub-01_run-6_T2w.nii.gz new file mode 100755 index 000000000..f2057080d Binary files /dev/null and b/data/sub-01/anat/sub-01_run-6_T2w.nii.gz differ diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 917f1e36d..000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,45 +0,0 @@ -FROM ubuntu:14.04 -MAINTAINER sebastientourbier -RUN apt-get update && apt-get install software-properties-common -y && apt-add-repository ppa:saiarcot895/myppa -y && apt-get update && apt-get -y install apt-fast \ -&& apt-fast install -y \ - build-essential \ - x11-apps \ - git \ - gcc-4.8 \ - g++-4.8 \ - cmake \ - libtclap-dev \ - libinsighttoolkit4.5 \ - libinsighttoolkit4-dev \ - libvtk5-dev \ - libvtk5-qt4-dev \ - libvtk5.8 \ - libvtk5.8-qt4 \ - tcl-vtk \ - libvtk-java \ - python-vtk \ - python-vtkgdcm \ - libncurses5 \ - libncurses5-dev \ - libann-dev \ - python-qt4 \ - python-nibabel \ - python-numpy \ - python-scipy \ - python-matplotlib \ -&& apt-get clean - -# # Git clone the repo from MIALSRTK official repository on GitHub. # -RUN mkdir /opt/mialsrtk-build && cd /opt/mialsrtk-build \ -&& git clone https://github.com/sebastientourbier/mialsuperresolutiontoolkit.git \ -&& cd mialsuperresolutiontoolkit \ -&& git checkout master && mkdir build - -WORKDIR /opt/mialsrtk-build/mialsuperresolutiontoolkit/build - -RUN cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D USE_OMP:BOOL=ON ../src \ -&& make -j2 && sudo make install && cd .. - -ENV BIN_DIR "/usr/local/bin" -ENV DISPLAY :0 -#&& make install && make clean && cd .. && rm -rf build diff --git a/docker/bidsapp/Dockerfile b/docker/bidsapp/Dockerfile new file mode 100644 index 000000000..850dc3433 --- /dev/null +++ b/docker/bidsapp/Dockerfile @@ -0,0 +1,126 @@ +############################################################## +# Use an initial image, where all MIAL Super-Resolution BIDSApp dependencies are installed, as a parent image +############################################################## +ARG MAIN_DOCKER +FROM "${MAIN_DOCKER}" + +############################################################## +# HPC +############################################################## +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 + +############################################################## +# Create input and output directories of the BIDS App +############################################################## +RUN mkdir /bids_dir && \ + chmod -R 777 /bids_dir + +RUN mkdir /output_dir && \ + chmod -R 777 /output_dir + +############################################################## +# Installation of pyMIALSRTK +############################################################## +WORKDIR /app + +# Store command related variables +ENV CONDA_ENV_PATH /opt/conda +ENV MY_CONDA_PY3ENV "pymialsrtk-env" +# This is how you will activate this conda environment +ENV CONDA_ACTIVATE "source $CONDA_ENV_PATH/bin/activate $MY_CONDA_PY3ENV" + +# Create the conda environment +COPY environment.yml /app/environment.yml +RUN conda env create -f /app/environment.yml + +# Install pymialsrtk +WORKDIR /opt/mialsuperresolutiontoolkit +RUN /bin/bash -c '$CONDA_ACTIVATE && python setup.py install' + +WORKDIR /app + +# # Create entrypoint script +# RUN echo '#! /bin/bash \n \ +# $CONDA_ACTIVATE \ +# && xvfb-run -a python /opt/mialsuperresolutiontoolkit/docker/bidsapp/run.py $@' > /app/run_srr.sh + +# # Create entrypoint script +# RUN echo '#! /bin/bash \n \ +# $CONDA_ACTIVATE \ +# && xvfb-run -a coverage run --source=pymialsrtk \ +# /opt/mialsuperresolutiontoolkit/docker/bidsapp/run.py $@\ +# && coverage html -d /bids_dir/code/coverage_html' > /app/run_srr_coverage.sh + +# Create content of entrypoint script +ENV content="#! /bin/bash\n" +ENV content="${content}echo User: \$(id -un \$USER) && echo Group: \$(id -gn \$USER) &&" +ENV content="${content} . activate \"${MY_CONDA_PY3ENV}\" &&" +ENV content="${content} xvfb-run -a python /opt/mialsuperresolutiontoolkit/docker/bidsapp/run.py \$@" + +# Write content to BIDSapp entrypoint script +RUN printf "$content" > /app/run_srr.sh +RUN cat /app/run_srr.sh + +# Create content of entrypoint script with coverage +ENV content_cov="#! /bin/bash\n" +ENV content_cov="${content_cov}echo User: \$(id -un \$USER) && echo Group: \$(id -gn \$USER) &&" +ENV content_cov="${content_cov} . activate \"${MY_CONDA_PY3ENV}\" &&" +ENV content_cov="${content_cov} xvfb-run -a coverage run --source=pymialsrtk \ +/opt/mialsuperresolutiontoolkit/docker/bidsapp/run.py \$@ \ +|& tee /bids_dir/code/log.txt &&" +ENV content_cov="${content_cov} coverage html -d /bids_dir/code/coverage_html &&" +ENV content_cov="${content_cov} coverage xml -o /bids_dir/code/coverage.xml &&" +ENV content_cov="${content_cov} coverage json -o /bids_dir/code/coverage.json" + +# Write content to BIDSapp entrypoint script +RUN printf "$content_cov" > /app/run_srr_coverage.sh +RUN cat /app/run_srr_coverage.sh + +## FOR DEBUG +# RUN echo '#! /bin/bash \n \ +# echo "User: $USER" \ +# && echo "Group:"$(id -g -n $USER) \ +# && export && $CONDA_ACTIVATE \ +# && xvfb-run -a python /opt/mialsuperresolutiontoolkit/pymialsrtk/pipelines/anatomical/srr.py $@' > /app/run_srr.sh + +# Set the working directory back to /app +# Acquire script to be executed +RUN chmod 775 /app/run_srr.sh +RUN chmod 775 /app/run_srr_coverage.sh + +# Display all environment variables +RUN export + +############################################################## +# Make singularity happy +############################################################## +RUN ldconfig + +############################################################## +# BIDS App entrypoint script +############################################################## +ENTRYPOINT ["/app/run_srr.sh"] + +############################################################## +# Build arguments +############################################################## +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION + +############################################################## +# Metadata +############################################################## +LABEL org.label-schema.build-date=$BUILD_DATE +LABEL org.label-schema.name="MIAL Super-Resolution ToolKit BIDS App" +LABEL org.label-schema.description="Docker image of the MIAL Super-Resolution BIDS App based on Ubuntu 14.04." +LABEL org.label-schema.url="https://mialsuperresolutiontoolkit.readthedocs.io" +LABEL org.label-schema.vcs-ref=$VCS_REF +LABEL org.label-schema.vcs-url="https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit" +LABEL org.label-schema.version=$VERSION +LABEL org.label-schema.maintainer="Sebastien Tourbier " +LABEL org.label-schema.vendor="Centre Hospitalier Universitaire Vaudois (CHUV), Lausanne, Switzerland" +LABEL org.label-schema.schema-version="1.0" +LABEL org.label-schema.docker.cmd="docker run --rm -v ~/data/bids_dataset:/tmp -t sebastientourbier/mialsuperresolutiontoolkit-ubuntu16.04:${VERSION}" + diff --git a/docker/bidsapp/environment.yml b/docker/bidsapp/environment.yml new file mode 100644 index 000000000..1f093554e --- /dev/null +++ b/docker/bidsapp/environment.yml @@ -0,0 +1,38 @@ +name: pymialsrtk-env + +channels: +- conda-forge +- defaults +- anaconda + +dependencies: +- python=3.6.8 +- pip=19.0.3 +- nibabel=3.0.1 +- nipype=1.5.1 +- traits=5.1.2 +- traitsui=6.0.0 +- pyface=7.0.0 +- pydotplus=2.0.2 +- pandoc=2.11.0.1 + +- pip: + - coverage==5.1 + - duecredit==0.8.0 + - apptools==4.4.0 + # - niworkflows==0.10.2 + - graphviz + - numpy==1.16.4 # numpy 1.18.5 caused error (fix: https://github.com/DeepLabCut/Docker4DeepLabCut2.0/issues/26) + - tensorflow==1.13.1 # https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.1.0-cp36-cp36m-linux_x86_64.whl # tensorflow==1.15 # tflearn needs tensorflow 1.0+ + - tensorflow-estimator==1.13.0 + - tensorboard==1.13.1 + - tflearn==0.3.2 + - MedPy==0.4.0 + - opencv-python==4.1.0.25 + - scikit-learn==0.20.3 + - scikit-image==0.14.2 + - sphinx==1.8.5 + - sphinx_rtd_theme==0.4.3 + - sphinx-argparse==0.2.5 + - nbsphinx==0.7.1 + - recommonmark==0.5.0 diff --git a/docker/bidsapp/run.py b/docker/bidsapp/run.py new file mode 100644 index 000000000..31a2c5e7d --- /dev/null +++ b/docker/bidsapp/run.py @@ -0,0 +1,138 @@ +# Copyright © 2016-2020 Medical Image Analysis Laboratory, University Hospital Center and University of Lausanne (UNIL-CHUV), Switzerland +# +# This software is distributed under the open-source license Modified BSD. + +"""Entrypoint point script of the BIDS APP.""" + +import os +import sys +import json +# from traits.api import * + +# Import the super-resolution pipeline +from pymialsrtk.parser import get_parser +from pymialsrtk.pipelines.anatomical.srr import AnatomicalPipeline + + +def main(bids_dir, output_dir, subject, p_stacksOrder, session, paramTV=None, number_of_cores=1, srID=None, use_manual_masks=False): + """Main function that creates and executes the workflow of the BIDS App on one subject. + + It creates an instance of the class :class:`pymialsrtk.pipelines.anatomical.srr.AnatomicalPipeline`, + which is then used to create and execute the workflow of the super-resolution reconstruction pipeline. + + Parameters + ---------- + bids_dir + BIDS root directory (required) + + output_dir + Output derivatives directory (required) + + subject + Subject ID (in the form ``sub-XX``) + + p_stacks_order list<> + List of stack indices that specify the order of the stacks + + session + Session ID if applicable (in the form ``ses-YY``) + + paramTV dict<'deltatTV': float, 'lambdaTV': float, 'primal_dual_loops': int>> + Dictionary of Total-Variation super-resolution optimizer parameters + + number_of_cores + Number of cores / CPUs used by the worflow execution engine + + srID + ID of the reconstruction useful to distinguish when multiple reconstructions + with different order of stacks are run on the same subject + + use_manual_masks + If set to True, use manual masks expected to be in ``/output_dir/manual_masks``. + + """ + + if paramTV is None: + paramTV = dict() + + subject = 'sub-' + subject + if session is not None: + session = 'ses-' + session + + if srID is None: + srID = "01" + # Initialize an instance of AnatomicalPipeline + pipeline = AnatomicalPipeline(bids_dir, + output_dir, + subject, + p_stacksOrder, + srID, + session, + paramTV, + use_manual_masks) + # Create the super resolution Nipype workflow + pipeline.create_workflow() + + # Execute the workflow + res = pipeline.run(number_of_cores) + + return res + + +if __name__ == '__main__': + + bids_dir = os.path.join('/fetaldata') + + parser = get_parser() + args = parser.parse_args() + + print(args.param_file) + with open(args.param_file, 'r') as f: + participants_params = json.load(f) + print(participants_params) + print(participants_params.keys()) + print() + + if len(args.participant_label) >= 1: + for sub in args.participant_label: + + if sub in participants_params.keys(): + sr_list = participants_params[sub] + print(sr_list) + + for sr_params in sr_list: + + ses = sr_params["session"] if "session" in sr_params.keys() else None + + print('sr_params') + if ("stacksOrder" not in sr_params.keys()) or ("sr-id" not in sr_params.keys()): + print('Do not process subjects %s because of missing parameters.' % sub) + continue + + if 'paramTV' in sr_params.keys(): + + res = main(bids_dir=args.bids_dir, + output_dir=args.output_dir, + subject=sub, + p_stacksOrder=sr_params['stacksOrder'], + session=ses, + paramTV=sr_params['paramTV'], + srID=sr_params['sr-id'], + use_manual_masks=args.manual) + + # sys.exit(0) + + else: + + res = main(bids_dir=args.bids_dir, + output_dir=args.output_dir, + subject=sub, + p_stacksOrder=sr_params['stacksOrder'], + session=ses, + srID=sr_params['sr-id'], + use_manual_masks=args.manual) + + # sys.exit(0) + else: + print('ERROR: Processing of all dataset not implemented yet\n At least one participant label should be provided') + sys.exit(2) diff --git a/docker/jupyter/.dockerignore b/docker/jupyter/.dockerignore new file mode 100644 index 000000000..3f60a8cbd --- /dev/null +++ b/docker/jupyter/.dockerignore @@ -0,0 +1,33 @@ +*.pklz +*.pyc +*.npz +*.xdebug_tkmedit +*.mp4 +atom-config.txt + +.DS_Store? +.DS_Store +ehthumbs.db +Icon? +Thumbs.db + +docs +docs/* + +docker +docker/* + +debian +debian/* + +dist +dist/* + +build +build/* + +_build +_static +_templates + +*.ipynb_checkpoints diff --git a/docker/jupyter/.gitkeep b/docker/jupyter/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docker/jupyter/Dockerfile b/docker/jupyter/Dockerfile new file mode 100644 index 000000000..ea62ff050 --- /dev/null +++ b/docker/jupyter/Dockerfile @@ -0,0 +1,58 @@ +# Use an initial image, where all MIAL Super-Resolution BIDSApp dependencies are installed, as a parent image + +ARG MAIN_DOCKER +FROM $MAIN_DOCKER + +############################### +## A little Docker magic here +# Force bash always +#RUN rm /bin/sh && ln -s /bin/bash /bin/sh +# Default miniconda installation +ENV CONDA_ENV_PATH /opt/conda +ENV MY_CONDA_PY3ENV "pymialsrtk-env" +# This is how you will activate this conda environment +ENV CONDA_ACTIVATE "source $CONDA_ENV_PATH/bin/activate $MY_CONDA_PY3ENV" + +# Pull the environment name out of the environment.yml +COPY environment.yml /app/environment.yml +RUN conda env create -f /app/environment.yml + +# Install pymialsrtk inside installed conda environment (see environment.yml) +#RUN /bin/bash -c "$CONDA_ACTIVATE && conda update jupyter_core jupyter_client" + +# Install jupyter extensions +RUN bash -c '$CONDA_ACTIVATE && jupyter nbextension enable exercise2/main && jupyter nbextension enable spellchecker/main' +RUN bash -c '$CONDA_ACTIVATE && jupyter nbextension install --py jupyter_highlight_selected_word && jupyter nbextension enable highlight_selected_word/main' + +# Install niwidget from nipy and create the jupyter notebook kernel linked to the conda environment +RUN bash -c "$CONDA_ACTIVATE && pip install git+git://github.com/nipy/niwidgets && python3 -m ipykernel install --prefix=/opt/conda --name $MY_CONDA_PY3ENV" + +RUN mkdir -p /app/notebooks +COPY . /app/notebooks + +WORKDIR /app/notebooks + +RUN printf '#!/bin/bash \n %s && jupyter-notebook --allow-root --no-browser --ip=\"0.0.0.0\" --NotebookApp.token=\'mial\'' "$CONDA_ACTIVATE" > /app/launch_jupyter_notebook.sh +RUN chmod 755 /app/launch_jupyter_notebook.sh + +ENTRYPOINT ["/app/launch_jupyter_notebook.sh"] + +#ENTRYPOINT ["/opt/mialsuperresolutiontoolkit/run.py"] + +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION + +#Metadata +LABEL org.label-schema.build-date=$BUILD_DATE +LABEL org.label-schema.name="MIAL Super-Resolution Toolkit Jupyter Notebooks" +LABEL org.label-schema.description="Provides a jupyter notebook environment for developing notebooks" +LABEL org.label-schema.url="https://mialsuperresolutiontoolkit.readthedocs.io" +LABEL org.label-schema.vcs-ref=$VCS_REF +LABEL org.label-schema.vcs-url="https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit" +LABEL org.label-schema.version=$VERSION +LABEL org.label-schema.maintainer="Sebastien Tourbier " +LABEL org.label-schema.vendor="Centre Hospitalier Universitaire Vaudois (CHUV), Lausanne, Switzerland" +LABEL org.label-schema.schema-version="1.0" +LABEL org.label-schema.docker.cmd="docker run --rm -v ~/data/bids_dataset:/tmp -t sebastientourbier/mialsuperresolutionbidsapp:${VERSION}" + diff --git a/docker/jupyter/environment.yml b/docker/jupyter/environment.yml new file mode 100644 index 000000000..931e0f84b --- /dev/null +++ b/docker/jupyter/environment.yml @@ -0,0 +1,26 @@ +name: pymialsrtk-env + +channels: +- anaconda +- conda-forge +- defaults + +dependencies: +- python=3.7.2 +- pip=19.0.3 +- git-annex=7.20190219 +- nibabel=2.3.3 +- nipype=1.2.0 +- traitsui=6.0.0 +- jupyter=1.0.0 +- jupyterlab=1.1.3 +- matplotlib=2.2.3 +- graphviz=2.40.1 + +- pip: + - duecredit==0.7.0 + - apptools==4.4.0 + - niworkflows==0.10.2 + - jupyter_contrib_nbextensions==0.5.1 + - scikit-learn==0.21.3 + - pybids==0.9.1 diff --git a/documentation/LICENSE.rst b/documentation/LICENSE.rst new file mode 100644 index 000000000..c8c764b5c --- /dev/null +++ b/documentation/LICENSE.rst @@ -0,0 +1,33 @@ +.. _LICENSE: + +BSD 3-Clause License +======================================================= + +Copyright (c) 2012-2020, Medical Image Analysis Laboratory (MIAL) - University and University Hospital Center of Lausanne (UNIL-CHUV), Switzerland +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/documentation/Makefile b/documentation/Makefile new file mode 100644 index 000000000..90953be95 --- /dev/null +++ b/documentation/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CMA.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CMA.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/CMA" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CMA" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/documentation/__init__.py b/documentation/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/documentation/_static/sphinxdoc.css_t b/documentation/_static/sphinxdoc.css_t new file mode 100644 index 000000000..5a1b66153 --- /dev/null +++ b/documentation/_static/sphinxdoc.css_t @@ -0,0 +1,340 @@ +/* + * sphinxdoc.css_t + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 14px; + letter-spacing: -0.01em; + line-height: 150%; + text-align: center; + background-color: #BFD1D4; + color: black; + padding: 0; + border: 1px solid #aaa; + + margin: 0px 80px 0px 80px; + min-width: 740px; +} + +div.document { + background-color: white; + text-align: left; + background-image: url(contents.png); + background-repeat: repeat-x; +} + +div.bodywrapper { + margin: 0 {{ theme_sidebarwidth|toint + 10 }}px 0 0; + border-right: 1px solid #ccc; +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} + +div.related { + font-size: 1em; +} + +div.related ul { + background-image: url(navigation.png); + height: 2em; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +div.related ul li { + margin: 0; + padding: 0; + height: 2em; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: #EE9816; +} + +div.related ul li a:hover { + color: #3CA8E7; +} + +div.sphinxsidebarwrapper { + position: relative; + padding: 0; +} + +div.sphinxsidebar { + margin: 0; + padding: 0.5em 15px 15px 0; + width: {{ theme_sidebarwidth|toint - 20 }}px; + float: right; + font-size: 1em; + text-align: left; +} + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + margin: 1em 0 0.5em 0; + font-size: 1em; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border: 1px solid #86989B; + background-color: #AFC1C4; +} + +div.sphinxsidebar h3 a { + color: white; +} + +div.sphinxsidebar ul { + padding-left: 1.5em; + margin-top: 7px; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + margin-left: 20px; +} + +div.footer { + background-color: #E3EFF1; + color: #86989B; + padding: 3px 8px 3px 0; + clear: both; + font-size: 0.8em; + text-align: right; +} + +div.footer a { + color: #86989B; + text-decoration: underline; +} + +/* -- body styles ----------------------------------------------------------- */ + +p { + margin: 0.8em 0 0.5em 0; +} + +a { + color: #CA7900; + text-decoration: none; +} + +a:hover { + color: #2491CF; +} + +div.body a { + text-decoration: underline; +} + +h1 { + margin: 0; + padding: 0.7em 0 0.3em 0; + font-size: 1.5em; + color: #11557C; +} + +h2 { + margin: 1.3em 0 0.2em 0; + font-size: 1.35em; + padding: 0; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + color: black!important; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #aaa!important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + +a.headerlink { + color: #c60f0f!important; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none!important; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +cite, code, tt { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.01em; +} + +tt { + background-color: #f2f2f2; + border-bottom: 1px solid #ddd; + color: #333; +} + +tt.descname, tt.descclassname, tt.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +a tt { + border: 0; + color: #CA7900; +} + +a tt:hover { + color: #2491CF; +} + +pre { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; + background-color: #f8f8f8; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + padding: 0.5em 0; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 2px 7px; + border: 1px solid #ccc; +} + +div.topic { + background-color: #f8f8f8; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + +div.admonition, div.warning { + font-size: 0.9em; + margin: 1em 0 1em 0; + border: 1px solid #86989B; + background-color: #f7f7f7; + padding: 0; +} + +div.admonition p, div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition pre, div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} + +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border-bottom: 1px solid #86989B; + font-weight: bold; + background-color: #AFC1C4; +} + +div.warning { + border: 1px solid #940000; +} + +div.warning p.admonition-title { + background-color: #CF0000; + border-bottom-color: #940000; +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + +.viewcode-back { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} diff --git a/documentation/_templates/layout.html b/documentation/_templates/layout.html new file mode 100644 index 000000000..2b8f52600 --- /dev/null +++ b/documentation/_templates/layout.html @@ -0,0 +1,170 @@ +{% extends "!layout.html" %} + + +{% block menu %} + {{ super() }} + +{% endblock %} + +{% block extrahead %} + + + + + + + +{% endblock %} + +{% block extratail %} + + + + + + + +{% endblock %} + +{% block footer %} + + + + + +{% endblock %} diff --git a/documentation/api_pipelines.rst b/documentation/api_pipelines.rst new file mode 100644 index 000000000..8e0930b61 --- /dev/null +++ b/documentation/api_pipelines.rst @@ -0,0 +1,8 @@ +.. _apidoc_pipelines: + +****************** +Pipelines module +****************** + +.. automodule:: pymialsrtk.pipelines.anatomical.srr + :members: \ No newline at end of file diff --git a/documentation/api_postprocess.rst b/documentation/api_postprocess.rst new file mode 100644 index 000000000..2eed7a767 --- /dev/null +++ b/documentation/api_postprocess.rst @@ -0,0 +1,8 @@ +.. _apidoc_postprocess: + +******************* +Postprocess module +******************* + +.. automodule:: pymialsrtk.interfaces.postprocess + :members: \ No newline at end of file diff --git a/documentation/api_preprocess.rst b/documentation/api_preprocess.rst new file mode 100644 index 000000000..50b473d34 --- /dev/null +++ b/documentation/api_preprocess.rst @@ -0,0 +1,8 @@ +.. _apidoc_preprocess: + +******************* +Preprocess module +******************* + +.. automodule:: pymialsrtk.interfaces.preprocess + :members: diff --git a/documentation/api_reconstruction.rst b/documentation/api_reconstruction.rst new file mode 100644 index 000000000..14b905387 --- /dev/null +++ b/documentation/api_reconstruction.rst @@ -0,0 +1,8 @@ +.. _apidoc_recon: + +********************** +Reconstruction module +********************** + +.. automodule:: pymialsrtk.interfaces.reconstruction + :members: \ No newline at end of file diff --git a/documentation/api_utils.rst b/documentation/api_utils.rst new file mode 100644 index 000000000..a0de671fd --- /dev/null +++ b/documentation/api_utils.rst @@ -0,0 +1,8 @@ +.. _apidoc_utils: + +*********************** +Utility (utils) module +*********************** + +.. automodule:: pymialsrtk.interfaces.utils + :members: \ No newline at end of file diff --git a/documentation/bids.rst b/documentation/bids.rst new file mode 100644 index 000000000..3d4afe216 --- /dev/null +++ b/documentation/bids.rst @@ -0,0 +1,52 @@ + +.. _cmpbids: + +******************************************* +BIDS and BIDS App standards +******************************************* + +`MIALSRTK BIDS App` adopts the :abbr:`BIDS (Brain Imaging Data Structure)` standard for data organization and is developed following the BIDS App standard. This means that `MIALSRTK BIDS App` handles dataset formatted following the BIDS App standard and provides a processing workflow containerized in Docker container image (promoting portability and reproduciblity) that can be run with a set of arguments defined by the BIDS App standard directly from the terminal or a script (See :ref:`cmdusage` section for more details). + +For more information about BIDS and BIDS-Apps, please consult the `BIDS Website `_, the `Online BIDS Specifications `_, and the `BIDSApps Website `_. `HeuDiConv `_ can assist you in converting DICOM brain imaging data to BIDS. A nice tutorial can be found @ `BIDS Tutorial Series: HeuDiConv Walkthrough `_ . + +.. _bidsexample: + +BIDS dataset schema +======================= + +The BIDS App accepts BIDS datasets that adopt the following organization, naming, and file formats:: + + ds-example/ + + README + CHANGES + participants.tsv + dataset_description.json + + sub-01/ + anat/ + sub-01_run-1_T2w.nii.gz + sub-01_run-1_T2w.json + sub-01_run-2_T2w.nii.gz + sub-01_run-2_T2w.json + ... + + ... + + sub-/ + anat/ + sub-_run-1_T2w.nii.gz + sub-_run-1_T2w.json + sub-_run-2_T2w.nii.gz + sub-_run-2_T2w.json + ... + ... + ... + + code/ + participants_params.json + +where ``participants_params.json`` is the MIALSRTK BIDS App configuration file, which follows a specific schema (See :ref:`config schema `), and which defines multiple processing parameters (such as the ordered list of scans or the weight of regularization). + +.. important:: + Before using any BIDS App, we highly recommend you to validate your BIDS structured dataset with the free, online `BIDS Validator `_. diff --git a/documentation/citing.rst b/documentation/citing.rst new file mode 100644 index 000000000..40de087fd --- /dev/null +++ b/documentation/citing.rst @@ -0,0 +1,14 @@ +.. _citing: + +********* +Citing +********* + +.. important:: + * If your are using the MIALSRTK BIDS App, a manuscript is in preparation, but for now, please acknowledge this software with the following three entries: + + 1. Tourbier S, Bresson X, Hagmann P, Bach Cuadra M. (2019, March 19). sebastientourbier/mialsuperresolutiontoolkit: MIAL Super-Resolution Toolkit v1.0 (Version v1.0). Zenodo. http://doi.org/10.5281/zenodo.2598448 + + 2. Tourbier S, Bresson X, Hagmann P, Meuli R, Bach Cuadra M, *An efficient total variation algorithm for super-resolution in fetal brain MRI with adaptive regularization*, Neuroimage 118 (2015) 584-597. doi:10.1016/j.neuroimage.2015.06.018 + + 3. Tourbier S, Velasco-Annis C, Taimouri V, Hagmann P, Meuli R, Warfield SK, Bach Cuadra M, A. Gholipour, *Automated template-based brain localization and extraction for fetal brain MRI reconstruction*, Neuroimage (2017) In Press. doi:10.1016/j.neuroimage.2017.04.004 diff --git a/documentation/conf.py b/documentation/conf.py new file mode 100644 index 000000000..7256aff60 --- /dev/null +++ b/documentation/conf.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# +# CMA documentation build configuration file, created by +# sphinx-quickstart on Fri Mar 15 10:49:53 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + + +import os +import sys + +sys.path.append('../') +#sys.path.insert(0,"'../pymialsrtk/'") + +from pymialsrtk.info import __minor_version__ +from pymialsrtk.info import __version__ +from pymialsrtk.info import __release_date__ + +import time + +from recommonmark.parser import CommonMarkParser + +# Workaround: https://github.com/readthedocs/recommonmark/issues/177#issuecomment-555553053 +class CustomCommonMarkParser(CommonMarkParser): + def visit_document(self, node): + pass + +# Use Markdown and reStructuredText in the same Sphinx project +source_parsers = { + '.md': CustomCommonMarkParser, +} +source_suffix = ['.rst', '.md'] + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('../pymialsrtk')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autosectionlabel', + 'sphinx.ext.autodoc', + 'sphinx.ext.napoleon', + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinxarg.ext', + 'nbsphinx'] + +# autodoc_default_options = { +# 'autosummary': True, +# } + +autodoc_mock_imports = ['nipype','cv2', 'skimage'] + +# Allow errors in notebooks for doc +nbsphinx_allow_errors = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = ['.rst', '.md'] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Medical Image Analysis Laboratory Super-Resolution Toolkit' +copyright = u'2016-{}, Medical Image Analysis Laboratory (MIAL) & Contributors'.format(time.strftime("%Y")) + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = __minor_version__ +# The full version, including alpha/beta/rc tags. +release = __version__ + +rst_prolog = """ +.. |release| replace:: {} +""".format(release) + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%b %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] +default_role = 'obj' + +# The reST default role (used for this markup: `text`) to use for all documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +gettext_compact = False + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' # 'sphinxdoc' +# html_theme = 'alabaster'#'sphinxdoc' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + 'logo_only': True, # should be commented if html_theme = 'alabaster' + 'display_version': False +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = 'The MIAL Super-Resolution Toolkit' + +# A shorter title for the navigation bar. Default is the same as html_title. +html_short_title = u'MIALSRTK' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = 'images/mialsrtk-logo.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) 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 = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {'**': ['sidebar_version.html', 'localtoc.html','relations.html', 'sourcelink.html', 'searchbox.html']} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +html_domain_indices = True + +# If false, no index is generated. +html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'MIALSRTKdoc' + +html_context = {'release_date': __release_date__} + +# Activate autosectionlabel plugin +autosectionlabel_prefix_document = True + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + 'papersize': 'a4paper', + + # The font size ('10pt', '11pt' or '12pt'). + 'pointsize': '10pt', + + # Additional package + # 'extrapackages': r'', + + # Font settings +# 'fontpkg': r''' +# \setmainfont{DejaVu Serif} +# \setsansfont{DejaVu Sans} +# \setmonofont{DejaVu Sans Mono} +# ''', + + # Additional stuff for the LaTeX preamble. + 'preamble': r''' +\usepackage{dejavu} +''', + + # Use Fancy chapter + 'fncychap': r'\usepackage[Bjornstrup]{fncychap}', + + # Adjust for the large character width of the monospace font, used in code-blocks + # 'fvset': r'\\fvset{fontsize=\\footnotesize}', Seems not working! + + # Adjust size for long module name in generated index + 'printindex': r''' +\tiny\raggedright\printindex +''', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'MIALSRTK.tex', u'MIALSRTK Documentation', + u'Medical Image Analysis Laboratory and Contributors', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = 'images/mialsrtk-logo.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +latex_use_parts = True + +# If true, show page references after internal links. +latex_show_pagerefs = True + +# Specify Latex engine +# latex_engine = 'xelatex' + +latex_show_urls = 'footnote' + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'MIALSRTK', u'MIALSRTK Documentation', + [u'Medical Image Analysis Laboratory and Contributors'], 1) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'MIALSRTK', u'MIALSRTK Documentation', + u'Medical Image Analysis Laboratory and Contributors', 'MIALSRTK', + 'Set of C++ image processing and Python workflow tools necessary to perform motion-robust super-resolution fetal MRI reconstruction.', + 'Science'), +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' diff --git a/documentation/contributing.rst b/documentation/contributing.rst new file mode 100644 index 000000000..63d1833a6 --- /dev/null +++ b/documentation/contributing.rst @@ -0,0 +1,148 @@ +.. _contributing: + +************* +Contributing +************* + +This project follows the `all contributors specification `_. +Contributions in many different ways are welcome! + +Contribution Types +------------------ + +Report Bugs +~~~~~~~~~~~ + +Report bugs at https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit/issues. + +If you are reporting a bug, please include: + +* Your operating system name and version. +* Any details about your local setup that might be helpful in troubleshooting. +* Detailed steps to reproduce the bug. + +Fix Bugs +~~~~~~~~ + +Look through the GitHub issues for bugs. Anything tagged with "bug" +and "help wanted" is open to whoever wants to implement it. + +Implement Features +~~~~~~~~~~~~~~~~~~ + +Look through the GitHub issues for features. Anything tagged with "enhancement" +and "help wanted" is open to whoever wants to implement it. + +Write Documentation +~~~~~~~~~~~~~~~~~~~ + +MIALSRTK could always use more documentation, whether as part of the +official MIALSRTK docs, in docstrings, or even on the web in blog posts, +articles, and such. + +Submit Feedback +~~~~~~~~~~~~~~~ + +The best way to send feedback is to create an issue at https://github.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that contributions + are welcome :) + +Get Started! +------------ + +Ready to contribute? Here's how to set up `MIALSRTK` for local development. + +1. Fork the `mialsuperresolutiontoolkit` repo on GitHub. + +2. Clone your fork locally:: + + git clone git@github.com:your_name_here/mialsuperresolutiontoolkit.git + cd mialsuperresolutiontoolkit + +3. Create a branch for local development:: + + git checkout -b name-of-your-bugfix-or-feature + +4. Now you can make your changes locally. If you add a new node in a pipeline or a completely new pipeline, we encourage you to rebuild the BIDS App Docker image (See :ref:`BIDS App build instructions `) and test it on the sample dataset (`mialsuperresolutiontoolkit/data/`). + +.. note:: + Please keep your commit the most specific to a change it describes. It is highly advice to track unstaged files with ``git status``, add a file involved in the change to the stage one by one with ``git add ``. The use of ``git add .`` is highly disencouraged. When all the files for a given change are staged, commit the files with a brieg message using ``git commit -m "[COMMIT_TYPE]: Your detailed description of the change."`` that describes your change and where ``[COMMIT_TYPE]`` can be ``[FIX]`` for a bug fix, ``[ENH]`` for a new feature, ``[MAINT]`` for code maintenance and typo fix, ``[DOC]`` for documentation, ``[CI]`` for continuous integration testing. + +5. When you're done making changes, push your branch to GitHub:: + + git push origin name-of-your-bugfix-or-feature + +6. Submit a pull request through the GitHub website. + +Pull Request Guidelines +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Before you submit a pull request, check that it meets these guidelines: + +1. If the pull request adds functionality, the docs should be updated (See :ref:`documentation build instructions `). + +2. The pull request should work for Python 3.6. Check + https://app.circleci.com/pipelines/github/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit + and make sure that the tests pass. + +.. _instructions_bisapp_build: + +How to build the BIDS App locally +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Go to the clone directory of your fork and run the script `build_bidsapp.sh` :: + + cd mialsuperresolutiontoolkit + sh build_bidsapp.sh + +Note that the tag of the version of the image will be extracted from ``pymialsrtk/info.py`` where you might need to change the version to not overwrite an other existing image with the same version. + +.. _instructions_docs_build: + +How to build the documentation locally +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Install the `MIALSRTK` conda environment `pymialsrtk-env` with sphinx and all extensions to generate the documentation:: + + cd mialsuperresolutiontoolkit + conda env create -f docker/bidsapp/environment.yml + +2. Activate the MIALSRTK conda environment `pymialsrtk-env` and install `pymialsrtk` :: + + conda activate pymialsrtk-env + python setup.py install + +3. Run the script `build_sphinx_docs.sh` to generate the HTML documentation in ``documentation/_build/html``:: + + bash build_sphinx_docs.sh + +.. note:: + Make sure to have activated the conda environment `pymialsrtk-env` before running the script `build_sphinx_docs.sh`. + +Not listed as a contributor? +---------------------------- + +This is easy, `MIALSRTK` has the `all contributors bot `_ installed. + +Just comment on Issue or Pull Request (PR), asking `@all-contributors` to add you as contributor:: + + @all-contributors please add for + +``: See the `Emoji Key Contribution Types Reference `_ for a list of valid `contribution` types. + +The all-contributors bot will create a PR to add you in the README and reply with the pull request details. + +When the PR is merged you will have to make an extra Pull Request where you have to: + + 1. add your entry in the `.zenodo.json` (for that you will need an ORCID ID - https://orcid.org/). Doing so, you will appear as a contributor on Zenodo in the future version releases of MIALSRTK. Zenodo is used by MIALSRTK to publish and archive each of the version release with a unique Digital Object Identifier (DOI), which can then be used for citation. + + 2. update the content of the table in `documentation/contributors.rst` with the new content generated by the bot in the README. Doing so, you will appear in the :ref:`Contributing Page `. + +------------ + +This document has been inspired and adapted from `these great contributing guidelines `_. \ No newline at end of file diff --git a/documentation/contributors.rst b/documentation/contributors.rst new file mode 100644 index 000000000..c12a88b8d --- /dev/null +++ b/documentation/contributors.rst @@ -0,0 +1,16 @@ +.. _contributors: + +************** +Contributors +************** + +.. raw:: html + + + + + + + + +

Sébastien Tourbier

🎨 ⚠️ 💻 💡 📖 👀

Priscille de Dumast

💡 ⚠️ 💻

Hamza Kebiri

💡 ⚠️ 💻

Meritxell Bach

🔍
diff --git a/documentation/images/mialsrtk-logo.png b/documentation/images/mialsrtk-logo.png new file mode 100644 index 000000000..084b9e4c3 Binary files /dev/null and b/documentation/images/mialsrtk-logo.png differ diff --git a/documentation/images/mialsrtk-logo.svg b/documentation/images/mialsrtk-logo.svg new file mode 100644 index 000000000..378e83689 --- /dev/null +++ b/documentation/images/mialsrtk-logo.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/documentation/images/nipype_wf_graph.png b/documentation/images/nipype_wf_graph.png new file mode 100644 index 000000000..9cd332154 Binary files /dev/null and b/documentation/images/nipype_wf_graph.png differ diff --git a/documentation/index.rst b/documentation/index.rst new file mode 100644 index 000000000..f92772c81 --- /dev/null +++ b/documentation/index.rst @@ -0,0 +1,133 @@ + +MIAL Super-Resolution Toolkit +************************************ + +.. image:: images/mialsrtk-logo.png + :width: 600 + :align: center + +**Latest released version:** |release| + +This neuroimaging processing pipeline software is developed by the Medical Image Analysis Laboratory (MIAL) at the University Hospital of Lausanne (CHUV) for use within the lab, as well as for open-source software distribution. + +.. image:: https://img.shields.io/github/v/release/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit?include_prereleases + :alt: GitHub release (latest by date including pre-releases) +.. image:: https://zenodo.org/badge/183162514.svg + :target: https://zenodo.org/badge/latestdoi/183162514 + :alt: Digital Object Identifier +.. image:: https://img.shields.io/docker/pulls/sebastientourbier/mialsuperresolutiontoolkit + :target: + :alt: Docker Pulls +.. image:: https://travis-ci.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit.svg?branch=master + :target: https://travis-ci.com/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit + :alt: TravisCI Status (C++) +.. image:: https://circleci.com/gh/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit.svg?style=shield + :target: https://app.circleci.com/pipelines/github/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit + :alt: CircleCI Status (BIDS-App) +.. image:: https://app.codacy.com/project/badge/Coverage/a27593d6fae7436eb2cd65b80f3342c3 + :target: https://www.codacy.com/gh/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit?utm_source=github.com&utm_medium=referral&utm_content=Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit&utm_campaign=Badge_Coverage + :alt: Code Coverage +.. image:: https://readthedocs.org/projects/mialsrtk/badge/?version=latest + :target: https://mialsrtk.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status +.. image:: https://app.codacy.com/project/badge/Grade/a27593d6fae7436eb2cd65b80f3342c3 + :target: https://www.codacy.com/gh/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit?utm_source=github.com&utm_medium=referral&utm_content=Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit&utm_campaign=Badge_Grade + :alt: Code Quality +.. image:: https://img.shields.io/github/all-contributors/Medical-Image-Analysis-Laboratory/mialsuperresolutiontoolkit + :target: + :alt: Github All Contributors + +.. warning:: THIS SOFTWARE IS FOR RESEARCH PURPOSES ONLY AND SHALL NOT BE USED FOR ANY CLINICAL USE. THIS SOFTWARE HAS NOT BEEN REVIEWED OR APPROVED BY THE FOOD AND DRUG ADMINISTRATION OR EQUIVALENT AUTHORITY, AND IS FOR NON-CLINICAL, IRB-APPROVED RESEARCH USE ONLY. IN NO EVENT SHALL DATA OR IMAGES GENERATED THROUGH THE USE OF THE SOFTWARE BE USED IN THE PROVISION OF PATIENT CARE. + + +Introduction +============= + +The `Medical Image Analysis Laboratory Super-Resolution ToolKit (MIALSRTK)` consists of a set of C++ and Python3 image processing and worflow tools necessary to perform motion-robust super-resolution fetal MRI reconstruction. + +The *original* `C++ MIALSRTK` library includes all algorithms and methods for brain extraction, intensity standardization, motion estimation and super-resolution. It uses the CMake build system and depends on the open-source image processing Insight ToolKit (ITK) library, the command line parser TCLAP library and OpenMP for multi-threading. + +`MIALSRTK` has been extended with the `pymialsrtk` Python3 library following recent advances in standardization of neuroimaging data organization and processing workflows (See :ref:`BIDS and BIDS App standards `). This library has a modular architecture built on top of the Nipype dataflow library which consists of (1) processing nodes that interface with each of the MIALSRTK C++ tools and (2) a processing pipeline that links the interfaces in a common workflow. + +The processing pipeline with all dependencies including the C++ MIALSRTK tools are encapsulated in a Docker image container, which is now distributed as a `BIDS App` which handles datasets organized following the BIDS standard. See :ref:`BIDS App usage ` for more details. + +All these design considerations allow us not only to (1) represent the entire processing pipeline as an *execution graph, where each MIALSRTK C++ tools are connected*, but also to (2) provide a *mecanism to record data provenance and execution details*, and to (3) easily customize the BIDS App to suit specific needs as interfaces with *new tools can be added with relatively little effort* to account for additional algorithms. + +Aknowledgment +-------------- + +If your are using `MIALSRTK` in your work, please acknowledge this software and its dependencies. See :ref:`Citing ` for more details. + +License information +-------------------- + +This software is distributed under the open-source license Modified BSD. See :ref:`license ` for more details. + +All trademarks referenced herein are property of their respective holders. + +Help/Questions +--------------- + +If you run into any problems or have any code bugs or questions, please create a new `GitHub Issue `_. + +Eager to contribute? +--------------------- + +See :ref:`Contributing ` for more details. + +Funding +-------- + +Originally supported by the Swiss National Science Foundation (grant SNSF-141283). + +Contents +========= + +.. _getting_started: + +.. toctree:: + :maxdepth: 2 + :caption: Getting started + + installation + +.. _user-docs: + +.. toctree:: + :maxdepth: 2 + :caption: User Documentation + + bids + usage + outputs + +.. _api-doc: + +.. toctree:: + :maxdepth: 5 + :caption: API Documentation + + api_preprocess + api_postprocess + api_reconstruction + api_utils + api_pipelines + +.. _user-usecases: + +.. toctree:: + :maxdepth: 1 + :caption: Examples & Tutorials + +.. NLM denoising + +.. _about-docs: + +.. toctree:: + :maxdepth: 1 + :caption: About MIALSRTK + + LICENSE + citing + contributing + contributors diff --git a/documentation/installation.rst b/documentation/installation.rst new file mode 100644 index 000000000..d0aceabfd --- /dev/null +++ b/documentation/installation.rst @@ -0,0 +1,93 @@ +.. _installation: + +************************************ +Installation Instructions for Users +************************************ + +.. warning:: This software is for research purposes only and shall not be used for + any clinical use. This software has not been reviewed or approved by + the Food and Drug Administration or equivalent authority, and is for + non-clinical, IRB-approved Research Use Only. In no event shall data + or images generated through the use of the Software be used in the + provision of patient care. + + +* Installation instructions for the MIALSRTK BIDS App are found in :ref:`manual-install-bidsapp` + +.. + The steps to add the NeuroDebian repository are explained here:: + + $ firefox http://neuro.debian.net/ + +Make sure that you have installed the following prerequisites. + +The MIALSRTK BIDSApp +=============================== + +Prerequisites +------------- + +* Installed Docker Engine corresponding to your system: + + * For Ubuntu 14.04/16.04/18.04, follow the instructions from the web page:: + + $ firefox https://docs.docker.com/install/linux/docker-ce/ubuntu/ + + * For Mac OSX (>=10.10.3), get the .dmg installer from the web page:: + + $ firefox https://store.docker.com/editions/community/docker-ce-desktop-mac + + * For Windows (>=10), get the installer from the web page:: + + $ firefox https://store.docker.com/editions/community/docker-ce-desktop-windows + +.. note:: The MIALSRTK BIDSApp has been tested only on Ubuntu and MacOSX. For Windows users, it might be required to make few patches in the Dockerfile. + + +* Docker managed as a non-root user + + * Open a terminal + + * Create the docker group:: + + $ sudo groupadd docker + + * Add the current user to the docker group:: + + $ sudo usermod -G docker -a $USER + + * Reboot + + After reboot, test if docker is managed as non-root:: + + $ docker run hello-world + + +.. _manual-install-bidsapp: + +Installation +--------------------------------------- + +Installation of the MIALSRTK pipeline has been facilitated through the distribution of a BIDSApp relying on the Docker software container technology. + +* Open a terminal + +* Get the latest release (|release|) of the BIDS App: + + .. parsed-literal:: + + $ docker pull sebastientourbier/mialsuperresolutiontoolkit-bidsapp:|release| + +* To display all docker images available:: + + $ docker images + +You should see the docker image "mialsuperresolutiontoolkit-bidsapp" with tag "|release|" is now available. + +* You are ready to use the MIALSRTK BIDS App from the terminal. See its `commandline usage `_. + + +Help/Questions +-------------- + +Code bugs can be reported by creating a new `GitHub Issue `_. diff --git a/documentation/make.bat b/documentation/make.bat new file mode 100644 index 000000000..d2b63f15b --- /dev/null +++ b/documentation/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\CMA.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\CMA.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/documentation/notebooks/brainHack.ipynb b/documentation/notebooks/brainHack.ipynb new file mode 100644 index 000000000..5c4b1131e --- /dev/null +++ b/documentation/notebooks/brainHack.ipynb @@ -0,0 +1,675 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Nipype Interface to BLM denoising\n", + "\n", + "This notebooks was used to design the nipype inteface to BLM denoising program available in MIALSRTK.\n", + "It shows you how to run this interface independently (outside the BIDS App workflow)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "from bids import BIDSLayout\n", + "\n", + "from glob import glob\n", + "\n", + "from nipype.interfaces.io import BIDSDataGrabber\n", + "from nipype.pipeline import Node, MapNode, Workflow\n", + "from nipype.interfaces.utility import Function" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BIDS Layout: .../fetaldata | Subjects: 1 | Sessions: 2 | Runs: 6\n" + ] + } + ], + "source": [ + "bids_dir = os.path.join('/fetaldata')\n", + "output_dir = os.path.join('/fetaldata','derivatives','mialsrtk')\n", + "mask_dir = os.path.join('/fetaldata','derivatives','manual_masks')\n", + "\n", + "subject = '01'\n", + "\n", + "layout = BIDSLayout(bids_dir,derivatives=mask_dir)\n", + "print(layout)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: niworkflows in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (0.10.2)\n", + "Requirement already satisfied: seaborn in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.9.0)\n", + "Requirement already satisfied: pandas in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.25.2)\n", + "Requirement already satisfied: PyYAML in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (5.1.2)\n", + "Requirement already satisfied: packaging in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (19.2)\n", + "Requirement already satisfied: scipy in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (1.3.1)\n", + "Requirement already satisfied: pybids~=0.9.2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.9.4)\n", + "Requirement already satisfied: jinja2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (2.10.3)\n", + "Requirement already satisfied: nilearn!=0.5.0,!=0.5.1,>=0.2.6 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.5.2)\n", + "Requirement already satisfied: scikit-image in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.16.1)\n", + "Requirement already satisfied: templateflow~=0.4.1 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.4.1)\n", + "Requirement already satisfied: svgutils in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.3.1)\n", + "Requirement already satisfied: matplotlib>=2.2.0; python_version >= \"3.6\" in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (3.1.1)\n", + "Requirement already satisfied: nipype>=1.1.6 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (1.2.0)\n", + "Requirement already satisfied: scikit-learn>=0.19 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from niworkflows) (0.20.4)\n", + "Requirement already satisfied: numpy>=1.9.3 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from seaborn->niworkflows) (1.17.2)\n", + "Requirement already satisfied: pytz>=2017.2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pandas->niworkflows) (2019.3)\n", + "Requirement already satisfied: python-dateutil>=2.6.1 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pandas->niworkflows) (2.8.0)\n", + "Requirement already satisfied: six in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from packaging->niworkflows) (1.12.0)\n", + "Requirement already satisfied: pyparsing>=2.0.2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from packaging->niworkflows) (2.4.2)\n", + "Requirement already satisfied: sqlalchemy in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pybids~=0.9.2->niworkflows) (1.3.10)\n", + "Requirement already satisfied: patsy in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pybids~=0.9.2->niworkflows) (0.5.1)\n", + "Requirement already satisfied: num2words in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pybids~=0.9.2->niworkflows) (0.5.10)\n", + "Requirement already satisfied: bids-validator in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pybids~=0.9.2->niworkflows) (1.2.4)\n", + "Requirement already satisfied: nibabel>=2.1 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from pybids~=0.9.2->niworkflows) (2.5.1)\n", + "Requirement already satisfied: MarkupSafe>=0.23 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from jinja2->niworkflows) (1.1.1)\n", + "Requirement already satisfied: networkx>=2.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from scikit-image->niworkflows) (2.4)\n", + "Requirement already satisfied: PyWavelets>=0.4.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from scikit-image->niworkflows) (1.1.1)\n", + "Requirement already satisfied: pillow>=4.3.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from scikit-image->niworkflows) (6.2.0)\n", + "Requirement already satisfied: imageio>=2.3.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from scikit-image->niworkflows) (2.6.1)\n", + "Requirement already satisfied: tqdm in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from templateflow~=0.4.1->niworkflows) (4.36.1)\n", + "Requirement already satisfied: requests in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from templateflow~=0.4.1->niworkflows) (2.22.0)\n", + "Requirement already satisfied: lxml in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from svgutils->niworkflows) (4.4.1)\n", + "Requirement already satisfied: cycler>=0.10 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from matplotlib>=2.2.0; python_version >= \"3.6\"->niworkflows) (0.10.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from matplotlib>=2.2.0; python_version >= \"3.6\"->niworkflows) (1.1.0)\n", + "Requirement already satisfied: prov>=1.5.2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (1.5.3)\n", + "Requirement already satisfied: pydotplus in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (2.0.2)\n", + "Requirement already satisfied: pydot>=1.2.3 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (1.4.1)\n", + "Requirement already satisfied: neurdflib in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (5.0.0.post1)\n", + "Requirement already satisfied: funcsigs in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (1.0.2)\n", + "Requirement already satisfied: future>=0.16.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (0.18.1)\n", + "Requirement already satisfied: click>=6.6.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (7.0)\n", + "Requirement already satisfied: traits!=5.0,>=4.6 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (5.1.2)\n", + "Requirement already satisfied: simplejson>=3.8.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from nipype>=1.1.6->niworkflows) (3.16.0)\n", + "Requirement already satisfied: docopt>=0.6.2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from num2words->pybids~=0.9.2->niworkflows) (0.6.2)\n", + "Requirement already satisfied: decorator>=4.3.0 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from networkx>=2.0->scikit-image->niworkflows) (4.4.0)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from requests->templateflow~=0.4.1->niworkflows) (2019.9.11)\n", + "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from requests->templateflow~=0.4.1->niworkflows) (3.0.4)\n", + "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from requests->templateflow~=0.4.1->niworkflows) (1.25.6)\n", + "Requirement already satisfied: idna<2.9,>=2.5 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from requests->templateflow~=0.4.1->niworkflows) (2.8)\n", + "Requirement already satisfied: setuptools in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from kiwisolver>=1.0.1->matplotlib>=2.2.0; python_version >= \"3.6\"->niworkflows) (41.4.0)\n", + "Requirement already satisfied: rdflib>=4.2.1 in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from prov>=1.5.2->nipype>=1.1.6->niworkflows) (4.2.2)\n", + "Requirement already satisfied: isodate in /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages (from neurdflib->nipype>=1.1.6->niworkflows) (0.6.0)\n" + ] + } + ], + "source": [ + "%%bash\n", + "pip install niworkflows" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import subprocess\n", + "def run(self, command, env={}, cwd=os.getcwd()):\n", + " merged_env = os.environ\n", + " merged_env.update(env)\n", + " process = subprocess.run(command, shell=True,\n", + " env=merged_env, cwd=cwd, capture_output=True)\n", + " return process" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "from traits.api import *\n", + "\n", + "import nibabel as nib\n", + "\n", + "from nipype.utils.filemanip import split_filename\n", + "from nipype.interfaces.base import traits, isdefined, CommandLine, CommandLineInputSpec,\\\n", + " TraitedSpec, File, InputMultiPath, OutputMultiPath, BaseInterface, BaseInterfaceInputSpec\n", + "\n", + "from nipype.interfaces.mixins import reporting\n", + "\n", + "from niworkflows.interfaces import report_base as nrc\n", + "from niworkflows.viz.utils import cuts_from_bbox, compose_view, plot_registration, plot_segs\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "class BtkNLMDenoisingInputSpec(BaseInterfaceInputSpec):\n", + " bids_dir = Directory(desc='BIDS root directory',mandatory=True,exists=True)\n", + " in_file = File(desc='Input image',mandatory=True)\n", + " in_mask = File(desc='Input mask',mandatory=False)\n", + " out_postfix = traits.Str(\"_nlm\", usedefault=True)\n", + " weight = traits.Float(0.1,desc='NLM weight (0.1 by default)')\n", + "\n", + "class BtkNLMDenoisingOutputSpec(TraitedSpec):\n", + " out_file = File(desc='Denoised image')\n", + "\n", + "class BtkNLMDenoising(BaseInterface):\n", + "\n", + " input_spec = BtkNLMDenoisingInputSpec\n", + " output_spec = BtkNLMDenoisingOutputSpec\n", + " \n", + " def _run_interface(self, runtime): \n", + " _, name, ext = split_filename(os.path.abspath(self.inputs.in_file))\n", + " out_file = os.path.join(os.getcwd().replace(self.inputs.bids_dir,'/fetaldata'), ''.join((name, self.inputs.out_postfix, ext)))\n", + "\n", + " if self.inputs.in_mask:\n", + " cmd = 'btkNLMDenoising -i \"{}\" -o \"{}'.format(self.inputs.in_file,self.inputs.in_mask,out_file,self.inputs.weight)\n", + " else:\n", + " cmd = 'btkNLMDenoising -i \"{}\" -o \"{}\" -b {}'.format(self.inputs.in_file,out_file,self.inputs.weight)\n", + " \n", + " try:\n", + " print('... cmd: {}'.format(cmd))\n", + " run(self, cmd, env={}, cwd=os.path.abspath(self.inputs.bids_dir))\n", + " except:\n", + " print('Failed')\n", + " return runtime\n", + "\n", + " def _list_outputs(self):\n", + " outputs = self._outputs().get()\n", + " _, name, ext = split_filename(os.path.abspath(self.inputs.in_file))\n", + " outputs['out_file'] = os.path.join(os.getcwd().replace(self.inputs.bids_dir,'/fetaldata'), ''.join((name, self.inputs.out_postfix, ext)))\n", + " return outputs\n", + " \n", + "class MultipleBtkNLMDenoisingInputSpec(BaseInterfaceInputSpec):\n", + " bids_dir = Directory(desc='BIDS root directory',mandatory=True,exists=True)\n", + " input_images = InputMultiPath(File(desc='files to be denoised', mandatory = True))\n", + " input_masks = InputMultiPath(File(desc='mask of files to be denoised', mandatory = False))\n", + " weight = traits.Float(0.1)\n", + " out_postfix = traits.Str(\"_nlm\", usedefault=True)\n", + " \n", + "class MultipleBtkNLMDenoisingOutputSpec(TraitedSpec):\n", + " output_images = OutputMultiPath(File())\n", + "\n", + "class MultipleBtkNLMDenoising(BaseInterface):\n", + " input_spec = MultipleBtkNLMDenoisingInputSpec\n", + " output_spec = MultipleBtkNLMDenoisingOutputSpec\n", + "\n", + " def _run_interface(self, runtime):\n", + " if len(self.inputs.input_images)>0:\n", + " for input_image, input_mask in zip(self.inputs.input_images,self.inputs.input_masks):\n", + " ax = BtkNLMDenoising(bids_dir = self.inputs.bids_dir, in_file = input_image, in_mask = input_mask, out_postfix=self.inputs.out_postfix, weight = self.inputs.weight)\n", + " ax.run()\n", + " else:\n", + " for input_image in self.inputs.input_images:\n", + " ax = BtkNLMDenoising(bids_dir = self.inputs.bids_dir, in_file = input_image, out_postfix=self.inputs.out_postfix, weight = self.inputs.weight)\n", + " ax.run()\n", + " return runtime\n", + "\n", + " def _list_outputs(self):\n", + " outputs = self._outputs().get()\n", + " outputs['output_images'] = glob(os.path.abspath(\"*.nii.gz\"))\n", + " return outputs" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Check for /fetaldata/derivatives/mialsrtk/dataset_description.json\n", + "File /fetaldata/derivatives/mialsrtk/dataset_description.json was created\n", + "191021-13:39:18,640 nipype.workflow INFO:\n", + "\t Workflow nlm_denoising settings: ['check', 'execution', 'logging', 'monitoring']\n", + "191021-13:39:18,644 nipype.workflow INFO:\n", + "\t Running serially.\n", + "191021-13:39:18,645 nipype.workflow INFO:\n", + "\t [Node] Setting-up \"nlm_denoising.bids_grabber\" in \"/fetaldata/derivatives/mialsrtk/sub-01/nipype/nlm_denoising/bids_grabber\".\n", + "191021-13:39:18,648 nipype.workflow INFO:\n", + "\t [Node] Running \"bids_grabber\" (\"nipype.interfaces.io.BIDSDataGrabber\")\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/bids/layout/layout.py:659: UserWarning: In pybids 0.9.0, the 'extensions' filter was deprecated in favor of 'extension'. The former will stop working in 0.11.0.\n", + " (False) or regex search (True) when comparing the query string\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "191021-13:39:19,833 nipype.workflow INFO:\n", + "\t [Node] Finished \"nlm_denoising.bids_grabber\".\n", + "191021-13:39:19,834 nipype.workflow INFO:\n", + "\t [Node] Setting-up \"nlm_denoising.nlmDenoise\" in \"/fetaldata/derivatives/mialsrtk/sub-01/nipype/nlm_denoising/nlmDenoise\".\n", + "191021-13:39:19,839 nipype.workflow INFO:\n", + "\t [Node] Running \"nlmDenoise\" (\"__main__.MultipleBtkNLMDenoising\")\n", + "... cmd: mialsrtkOrientImage -i \"/fetaldata/sub-01/anat/sub-01_run-1_T2w.nii.gz\" -o \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.nii.gz\n", + "... cmd: mialsrtkOrientImage -i \"/fetaldata/sub-01/anat/sub-01_run-2_T2w.nii.gz\" -o \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.nii.gz\n", + "... cmd: mialsrtkOrientImage -i \"/fetaldata/sub-01/anat/sub-01_run-3_T2w.nii.gz\" -o \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.nii.gz\n", + "... cmd: mialsrtkOrientImage -i \"/fetaldata/sub-01/anat/sub-01_run-4_T2w.nii.gz\" -o \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.nii.gz\n", + "... cmd: mialsrtkOrientImage -i \"/fetaldata/sub-01/anat/sub-01_run-5_T2w.nii.gz\" -o \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.nii.gz\n", + "... cmd: mialsrtkOrientImage -i \"/fetaldata/sub-01/anat/sub-01_run-6_T2w.nii.gz\" -o \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.nii.gz\n", + "191021-13:39:19,917 nipype.workflow INFO:\n", + "\t [Node] Finished \"nlm_denoising.nlmDenoise\".\n" + ] + } + ], + "source": [ + "#Check if mandatory derivatives dataset_description.json exists in derivatives/mialsrtk.\n", + "# If not, it is created before running the workflow, otherwise BIDSDataGrabber is not happy and raises an error. \n", + "\n", + "mialsrtk_dataset_description_json = os.path.join(output_dir,'dataset_description.json')\n", + "\n", + "print('Check for {}'.format(mialsrtk_dataset_description_json))\n", + "if not os.access(mialsrtk_dataset_description_json, os.R_OK):\n", + " import json\n", + " data = {'PipelineDescription':{'Name': 'MIAL Super-Resolution ToolKit', \n", + " 'Version': 'v2.0.0-beta', \n", + " 'CodeURL': 'https://github.com/sebastientourbier/mialsuperresolutiontoolkit'\n", + " },\n", + " 'Name': 'MIAL Super-Resolution ToolKit',\n", + " 'BIDSVersion': '1.2.0'\n", + " }\n", + " os.makedirs(output_dir)\n", + " with open(mialsrtk_dataset_description_json, 'w+') as outfile:\n", + " json.dump(data, outfile, indent=4)\n", + " print('File {} was created'.format(mialsrtk_dataset_description_json))\n", + "else:\n", + " print('File {} already exists'.format(mialsrtk_dataset_description_json))\n", + " \n", + "\n", + "wf = Workflow(name=\"nlm_denoising\",base_dir=os.path.join(output_dir,'sub-{}'.format(subject),'nipype'))\n", + "\n", + "bg = Node(interface=BIDSDataGrabber(infields = ['subject']),name='bids_grabber')\n", + "bg.inputs.base_dir = bids_dir\n", + "bg.inputs.subject = subject\n", + "bg.inputs.index_derivatives = True\n", + "bg.inputs.raise_on_empty = False\n", + "bg.inputs.output_query = {'T2ws': dict(suffix='T2w',datatype='anat',extensions=[\".nii\",\".nii.gz\"]),\n", + " 'masks': dict(suffix='mask',datatype='anat',extensions=[\".nii\",\".nii.gz\"])}\n", + "\n", + "nlmDenoise = Node(interface=MultipleBtkNLMDenoising(),name='nlmDenoise')\n", + "nlmDenoise.inputs.bids_dir = bids_dir\n", + "nlmDenoise.inputs.weight = 1\n", + " \n", + "wf.connect(bg, \"T2ws\", nlmDenoise, \"input_images\")\n", + "wf.connect(bg, \"masks\", nlmDenoise, \"input_masks\")\n", + "\n", + "res = wf.run()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "wf.write_graph()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## When this works, the implemented interfaces should be copied to the module pymialsrtk.interfaces.preprocess\n", + "\n", + "\n", + "The next cells should be executed after the copy is done. Please restart and clear the outputs to make sure to start from a clean environment." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Installation of pymialsrtk as python modules" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "running install\n", + "running build\n", + "running build_py\n", + "copying pymialsrtk/interfaces/utils.py -> build/lib/pymialsrtk/interfaces\n", + "running build_scripts\n", + "running install_lib\n", + "copying build/lib/pymialsrtk/interfaces/utils.py -> /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/pymialsrtk/interfaces\n", + "byte-compiling /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/pymialsrtk/interfaces/utils.py to utils.cpython-37.pyc\n", + "running install_scripts\n", + "changing mode of /opt/conda/envs/pymialsrtk-env/bin/superresolution to 755\n", + "running install_egg_info\n", + "Removing /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/pymialsrtk-2.0.0_beta_20190906-py3.7.egg-info\n", + "Writing /opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/pymialsrtk-2.0.0_beta_20190906-py3.7.egg-info\n" + ] + } + ], + "source": [ + "%%bash\n", + "# Go to folder containing the source code\n", + "cd /app/mialsuperresolutiontoolkit/\n", + "# Install the pymialsrtk package inside the python/conda environment\n", + "python setup.py install" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example of pipeline importing the interface MultipleBtkNLMDenoising from the installed module `pymialsrtk.interfaces.preprocess`" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Check for /fetaldata/derivatives/mialsrtk/dataset_description.json\n", + "File /fetaldata/derivatives/mialsrtk/dataset_description.json was created\n", + "190917-14:24:44,95 nipype.workflow INFO:\n", + "\t Workflow nlm_denoising2 settings: ['check', 'execution', 'logging', 'monitoring']\n", + "190917-14:24:44,159 nipype.workflow INFO:\n", + "\t Running serially.\n", + "190917-14:24:44,162 nipype.workflow INFO:\n", + "\t [Node] Setting-up \"nlm_denoising2.bids_grabber\" in \"/fetaldata/derivatives/mialsrtk/sub-01/nipype/nlm_denoising2/bids_grabber\".\n", + "190917-14:24:44,213 nipype.workflow INFO:\n", + "\t [Node] Running \"bids_grabber\" (\"nipype.interfaces.io.BIDSDataGrabber\")\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/bids/layout/layout.py:659: UserWarning: In pybids 0.9.0, the 'extensions' filter was deprecated in favor of 'extension'. The former will stop working in 0.11.0.\n", + " warnings.warn(\"In pybids 0.9.0, the 'extensions' filter was \"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "190917-14:24:46,751 nipype.workflow INFO:\n", + "\t [Node] Finished \"nlm_denoising2.bids_grabber\".\n", + "190917-14:24:46,754 nipype.workflow INFO:\n", + "\t [Node] Setting-up \"nlm_denoising2.nlmDenoise\" in \"/fetaldata/derivatives/mialsrtk/sub-01/nipype/nlm_denoising2/nlmDenoise\".\n", + "190917-14:24:46,894 nipype.workflow INFO:\n", + "\t [Node] Running \"nlmDenoise\" (\"pymialsrtk.interfaces.preprocess.MultipleBtkNLMDenoising\")\n", + "out_file: /fetaldata/sub-01_run-1_T2w_nlm.nii.gz\n", + "... cmd: btkNLMDenoising -i \"/fetaldata/sub-01/anat/sub-01_run-1_T2w.nii.gz\" -m \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-1_T2w_desc-brain_mask.nii.gz\" -o \"/fetaldata/sub-01_run-1_T2w_nlm.nii.gz\" -b 1.0\n", + "out_file: /fetaldata/sub-01_run-2_T2w_nlm.nii.gz\n", + "... cmd: btkNLMDenoising -i \"/fetaldata/sub-01/anat/sub-01_run-2_T2w.nii.gz\" -m \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-2_T2w_desc-brain_mask.nii.gz\" -o \"/fetaldata/sub-01_run-2_T2w_nlm.nii.gz\" -b 1.0\n", + "out_file: /fetaldata/sub-01_run-3_T2w_nlm.nii.gz\n", + "... cmd: btkNLMDenoising -i \"/fetaldata/sub-01/anat/sub-01_run-3_T2w.nii.gz\" -m \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-3_T2w_desc-brain_mask.nii.gz\" -o \"/fetaldata/sub-01_run-3_T2w_nlm.nii.gz\" -b 1.0\n", + "out_file: /fetaldata/sub-01_run-4_T2w_nlm.nii.gz\n", + "... cmd: btkNLMDenoising -i \"/fetaldata/sub-01/anat/sub-01_run-4_T2w.nii.gz\" -m \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-4_T2w_desc-brain_mask.nii.gz\" -o \"/fetaldata/sub-01_run-4_T2w_nlm.nii.gz\" -b 1.0\n", + "out_file: /fetaldata/sub-01_run-5_T2w_nlm.nii.gz\n", + "... cmd: btkNLMDenoising -i \"/fetaldata/sub-01/anat/sub-01_run-5_T2w.nii.gz\" -m \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-5_T2w_desc-brain_mask.nii.gz\" -o \"/fetaldata/sub-01_run-5_T2w_nlm.nii.gz\" -b 1.0\n", + "out_file: /fetaldata/sub-01_run-6_T2w_nlm.nii.gz\n", + "... cmd: btkNLMDenoising -i \"/fetaldata/sub-01/anat/sub-01_run-6_T2w.nii.gz\" -m \"/fetaldata/derivatives/manual_masks/sub-01/anat/sub-01_run-6_T2w_desc-brain_mask.nii.gz\" -o \"/fetaldata/sub-01_run-6_T2w_nlm.nii.gz\" -b 1.0\n", + "190917-14:24:57,280 nipype.workflow INFO:\n", + "\t [Node] Finished \"nlm_denoising2.nlmDenoise\".\n", + "190917-14:24:57,462 nipype.workflow INFO:\n", + "\t Generated workflow graph: /fetaldata/derivatives/mialsrtk/sub-01/nipype/nlm_denoising2/graph.png (graph2use=hierarchical, simple_form=True).\n" + ] + } + ], + "source": [ + "import os\n", + "import json\n", + "\n", + "# Imports from nipype\n", + "from nipype.interfaces.io import BIDSDataGrabber\n", + "from nipype.pipeline import Node, Workflow\n", + "\n", + "# Import the implemented interface from pymialsrtk\n", + "import pymialsrtk.interfaces.preprocess as preprocess\n", + "\n", + "# Set different variables (defined in cell 2) such that we do not have to rerun cell 2\n", + "bids_dir = os.path.join('/fetaldata')\n", + "output_dir = os.path.join('/fetaldata','derivatives','mialsrtk')\n", + "mask_dir = os.path.join('/fetaldata','derivatives','manual_masks')\n", + "subject = '01'\n", + "\n", + "#Make sure we start from empty derivatives\n", + "import shutil\n", + "shutil.rmtree(output_dir)\n", + "\n", + "#Check if mandatory derivatives dataset_description.json exists in derivatives/mialsrtk.\n", + "# If not, it is created before running the workflow, otherwise BIDSDataGrabber is not happy and raises an error. \n", + "\n", + "mialsrtk_dataset_description_json = os.path.join(output_dir,'dataset_description.json')\n", + "\n", + "print('Check for {}'.format(mialsrtk_dataset_description_json))\n", + "if not os.access(mialsrtk_dataset_description_json, os.R_OK):\n", + " data = {'PipelineDescription':{'Name': 'MIAL Super-Resolution ToolKit', \n", + " 'Version': 'v2.0.0-beta', \n", + " 'CodeURL': 'https://github.com/sebastientourbier/mialsuperresolutiontoolkit'\n", + " },\n", + " 'Name': 'MIAL Super-Resolution ToolKit',\n", + " 'BIDSVersion': '1.2.0'\n", + " }\n", + " os.makedirs(output_dir)\n", + " with open(mialsrtk_dataset_description_json, 'w+') as outfile:\n", + " json.dump(data, outfile, indent=4)\n", + " print('File {} was created'.format(mialsrtk_dataset_description_json))\n", + "else:\n", + " print('File {} already exists'.format(mialsrtk_dataset_description_json))\n", + "\n", + "# Construct the workflow\n", + "wf2 = Workflow(name=\"nlm_denoising2\",base_dir=os.path.join(output_dir,'sub-{}'.format(subject),'nipype'))\n", + "\n", + "bg2 = Node(interface=BIDSDataGrabber(infields = ['subject']),name='bids_grabber')\n", + "bg2.inputs.base_dir = bids_dir\n", + "bg2.inputs.subject = subject\n", + "bg2.inputs.index_derivatives = True\n", + "bg2.inputs.raise_on_empty = False\n", + "bg2.inputs.output_query = {'T2ws': dict(suffix='T2w',datatype='anat',extensions=[\".nii\",\".nii.gz\"]),\n", + " 'masks': dict(suffix='mask',datatype='anat',extensions=[\".nii\",\".nii.gz\"])}\n", + "\n", + "nlmDenoise2 = Node(interface=preprocess.MultipleBtkNLMDenoising(),name='nlmDenoise')\n", + "nlmDenoise2.inputs.bids_dir = bids_dir\n", + "nlmDenoise2.inputs.weight = 1\n", + "\n", + "# Connect outputs of bids grabber interface to inputs of NLM denoise interface \n", + "wf2.connect(bg2, \"T2ws\", nlmDenoise2, \"input_images\")\n", + "wf2.connect(bg2, \"masks\", nlmDenoise2, \"input_masks\")\n", + "\n", + "# Run the workflow/pipeline\n", + "res2 = wf2.run()\n", + "graph_img = wf2.write_graph()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Display the graph of the processing workflow" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAV0AAAC5CAYAAACLKuyXAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO29e1zT593//woBAgGSEIRwhoAcFBUsrVKUm1pQVDxU1NnNetd1ds7eW2dd1287t7Z3t7Zr10f32PZw6+Ye3dS7rbWeWsW1inXeouCpgBXkIAgqBAgQciAQSPL+/eEvn5uQgIRTAl7Px+PzSHJ93p/rel+fw+tz5TryiIjAYDAYjIlgn5uzPWAwGIwHCSa6DAaDMYEw0WUwGIwJxN3ZDjAeHMxmM9RqNQBArVbDbDZDp9Ohr68PANDT04Pu7m67xw61DwDEYjHc3OyXISQSCXg8HgDAx8cHnp6e8PLygre3Nzw8PODr6zuabDEYDsFElzEoer0e7e3t6OjoQHt7O9RqNXQ6HXQ6HTQaDdRqNbq6uqDVaqHT6dDZ2cnt7+rq4oSyr68POp3O2dkZEh6PB4lEAuD/BNzf3x++vr7cJhaLIRKJuN9+fn6QSCTcPqlUioCAAEilUri7s0eLYR8e673w4NDe3o7m5mY0NzdDoVCgtbUV7e3taGtrQ3t7u5XAtre3o6enxyYOLy8v+Pj4WAmQj48PRCIRxGKxlUh5enrCx8cHfD4fIpEIwP+VOv38/ODu7g6hUAiBQAAAVnYDGWqfyWSCRqOxu89oNEKr1XK/tVotjEYj9Ho9DAYDDAYD9Hq9lZ1KpeJK5ZYXysAXjU6ng1arRWdnJ+w9QmKxGAEBAZg2bZqVGAcEBCAgIABhYWGQyWQICQlBcHAwvL29h7hyjCnEPia6U4Cenh40NDTg9u3baGhowN27d9HS0oKmpia0traisbERra2tMBgM3DGenp4ICgrCtGnTbMShv0D0DxOLxawEZ4euri6o1WqrF1ZHR4fdl1lHRweUSiWUSqVVHCKRCKGhoQgKCrIS5IiICERFRSE6OhohISFcNQlj0sJEdzLQ29uL2tpa1NbWoqGhgdssIqtQKDhbX19fREREQCaTISwsDEFBQQgNDeUe4pCQEAQFBSEwMNCJOWL09vaitbUVTU1NaGlpgUKhgEKhsHpZ3r17FwqFAkajEcC9F2VkZCSioqIQFRWFyMhIyOVyREVFYfr06QgLC3NyrhjDgImuK6FSqVBeXo6KigrU1dWhrq4O5eXlqK6u5h48f39/hISEIDQ0FDExMdxmCZPL5aw0NMVQqVTc/VBXV4empiYoFArU1dWhurqaqxYRCASIjY1FUlKS1b0xe/ZsyGQyJ+eC8f/DRNcZKJVKlJWVoaysDNeuXcO3336LyspKrnVeKpUiLi4OCQkJiI+PR3x8POLi4jB9+nTW0s6wQaFQoKamBtXV1aiurkZNTQ2qqqpQW1uL3t5eAEBQUBBmzZqFOXPmYM6cOUhOTkZSUhJXn86YMJjojjfV1dW4cuWKlchaqgOCg4MxZ84cpKSkIDExkRPZadOmOdlrxlTAZDKhoaEB1dXVqKqqwvXr11FWVoby8nLo9Xq4u7sjPj6eE+GUlBTMmzcPUqnU2a5PZZjojiVarRZlZWU4f/48CgsLcfHiRSiVSu7mTkpKwsyZM5GamoqHH34YISEhznaZ8YDS1NSEq1ev4urVq6ioqEB5eTlu3LgBIkJISAgWLlyIBQsWIDU1FfPmzYOnp6ezXZ4qMNEdDc3NzTh9+jS+/vprFBcXo7KyEmazGXK5HGlpaUhLS8P8+fMxd+5cdtMyXJ62tjZcvHgRxcXFKC4uxqVLl6DRaODj44PU1FQsXLgQ2dnZSE9PZ9USI4eJriN0dXXh7NmzKCgoQEFBAa5fvw4PDw+kpaVhwYIFnMiyRgvGVMBsNqOiogIXL15EUVER/vd//xc1NTUQCoXIyMhAdnY2srOzkZyczBpvhw8T3fvR2NiIQ4cO4ciRI7hw4QJ6e3sxa9YsLF68GNnZ2cjMzISPj4+z3WQwJoT6+nqu0HH69Gm0tbUhKCgIS5cuxdq1a7FkyRJ4eXk5201XhomuPW7fvo1Dhw7h4MGDKC4uhq+vL3Jzc7F8+XJkZWWxulgGA/dKwqWlpSgoKMAXX3yBoqIi+Pr6YsWKFVi7di2WLVvGRtrZwkTXQnd3Nz755BPs3r0bFy9ehFgsxqpVq7Bu3TosXryYvb0ZjPvQ2NiIw4cP49ChQygsLISXlxfWrFmDbdu2IT093dnuuQpMdGtqavDBBx/gH//4B/R6PdatW4eNGzciKyuLNX4xGCOkpaUFhw8fxocffogrV64gOTkZzz33HDZu3PigV8c9uKJ78eJFvPbaazh58iSioqKwdetW/OAHP2DDYxmMMebSpUv4y1/+gv3790MgEODZZ5/Fyy+/jICAAGe75gwevOV6qqursX79ejz66KPo7u7G559/jtraWrz88ssTIrjvvfceeDweeDwewsPDxzz+/fv3c/FP5SoRR8/jeJ/3saKhoQGrVq0adNa0kfDyyy/j008/HbP4HGXevHn4xz/+gbt372Lnzp3Yt28fpk+fjnfeeWfIOZKnLPSAoFKp6LnnniMPDw9KSkqiY8eOOdWf5ORkCgsLG5atVqul6dOnU25u7rDjz8rKIoFAMFL3Jg2OnMeR2E8kJSUlNG3aNPrTn/7EhY3k2g/k5s2bJJfL6Ze//OVYuDlqtFotvfbaa+Tr60vh4eG0d+9eZ7s0kex9IEq6Z8+eRXJyMg4fPoy//OUvKCsrw4oVK5zt1rAhIpjNZpjNZme7whgnNBoNVq5cibVr1+LHP/4xFz4W1z42NhZHjhzBm2++iQMHDoyFu6PC19cXr7/+OmpqarBixQps3rwZa9euRUdHh7NdmxicLfvjzYcffkgeHh60Zs0aUiqVznaHY7xLXKykOzb2E8XOnTvJ3d2dGhsbxy2N9evXU3h4OPX19Y1bGiPh66+/pvDwcIqPj6ebN286253xZmqXdP/+97/jmWeewbZt23Do0CE2kQzDJSEi/P3vf8f8+fMRGho6bumsWbMGd+/eRX5+/rilMRIWLVqEy5cvQywW4z/+4z9QX1/vbJfGlSkruufPn8e2bdvw+uuv4w9/+IPLDlOsrKxEbm4uxGIxhEIhFi1ahPPnz3P7jx49yjUA8Xg8myV0Kisr8cQTT0AsFsPHxwcZGRkoLCy0m5bBYMCrr76KxMRECIVCSKVSrFy5El988QVMJtOI/bekLxQKMW/ePBw/fhzZ2dmcz1u2bLHJR1VVFb7zne8gICCAC2tra4PRaMSnn36KxYsXc8vYzJ49G3/4wx+G/It9v/M4UnulUonnn38e0dHR8PT0RGBgIPLy8lBaWsrZDDdvg1FWVoaWlhYkJydbhd/v2re3t2PHjh2IjY2Fp6cn/P39sWzZMpw5c8ZuOikpKQCAr776alBfnEVwcDAKCgoQGBiIVatWcVNSTkmcXdYeD8xmM82aNYuWL1/ubFcGJTk5mcRiMS1atIgKCwtJq9XS5cuXac6cOeTp6Un//ve/rexXr15NAKi7u5sLq6mpIYlEQmFhYXTy5EnSarV07do1WrJkCUVHR9tUL2zZsoXEYjGdPHmS9Ho9NTc304svvkgA6MyZMw7nwV76169fp+zsbAoMDLRbvWHJR2ZmJp05c4a6urqouLiY+Hw+KZVKOnbsGAGgt956izo6OkipVNIf//hHcnNzoxdffHHU59ER+6amJoqKiiKZTEb5+flc/jIzM8nLy4suXLjgUN4GY9++fVye7WHv2isUCpLL5SSTyejYsWOkVqupqqqK8vLyiMfj0e7du23iUavVBIAyMjIG9cXZ1NXVkY+PD/32t791tivjxd4pKbpff/01AaDy8nJnuzIoycnJBICKioqswq9du0YAKDk52Src3oO3fv16AkAHDx60sm1sbCSBQGAjenK5nNLT0218iY+PH5HoDpZ+a2srCYXCIUX3xIkTduM8duwYPfbYYzbhTz31FHl4eJBarbYKd/Q8OmL/9NNPEwD66KOPrGwVCgUJBAJKTU11KG+D8e677xIA2rVrl9399q795s2bCQB98sknVrY9PT0UGhpK3t7e1NzcbBMXj8ej6dOnO+TfRPPSSy9RVFQUmUwmZ7syHkxN0X3jjTcoPj7e2W4MSXJyMnl5eZHZbLbZFxoaSgCoqamJC7P34Pn5+REA0mq1NnHMnj3bRvS2bdtGAOjZZ5+loqIiMhqNo8rDUOk/9NBDQ4puW1ubQ2n97ne/IwA2pUtHz6Mj9mKxmNzc3GyE3pI/AHTnzp1R5+2NN94gAPS3v/3N7n57114sFhMA0mg0NvabNm0iALRnzx6bfR4eHi7ZkNifoqIiAkD19fXOdmU8mJoNaR0dHZNitIulzm8gQUFBAIDW1tZBjzUYDNBqtfDy8rK7hI8ljv7s2rULe/fuRV1dHbKysiASibB06VIcOXLEYd/vl76/v/+Qxw82FFStVuPVV1/F7Nmz4e/vz9Vn/vznPwcA6PV6m2McPY/DsTcYDFCr1TCbzRCLxVZ1qzweD9988w2Ae8PIh5u3wbAMYunr6xuWvcU3Ly8v+Pn52ey3TC3a3Nxss89oNLr8JDSWBu/29nYnezI+TEnRjYqKws2bN7nFHF0VtVptN9wiEvaE04JAIICfnx96enqg0+ls9tvr88jj8bBp0yYUFBSgs7MTR48eBREhLy8P77//vkO+3y/9oV4YQ7Fy5Ur8+te/xrPPPovq6mqYzWYQEX7/+98DuNfSPxBHz+Nw7AUCASQSCdzd3dHX1wcisrstWrRoRPnsj2XWusH8GohAIIBYLEZPTw+3KGV/WlpaANxrnOqPRqPhVoZwZSoqKsDj8RAVFeVsV8aFKSm6q1evRltbG44ePepsV4ZEp9OhrKzMKuzbb79FU1MTkpOT7/twLFu2DADw5ZdfWoW3tbWhqqrKxl4ikaCyshIA4OHhgcWLF3Mt5CPpRjRY+s3NzaiurnY4PpPJhPPnzyM4OBjPP/88AgMDuRLpUMNFHT2Pw7XPy8uD0Wi026vhnXfeQWRk5Ji82GfNmgUAuHv37rCPWbNmDQDYXDeDwYDTp0/D29sbOTk5VvsaGxut0nNVdu/ejYyMjEnxb3VEOKtiY7x56qmnKCIiwuH6tYkiOTmZfHx8aOHChVRcXEw6nc7h3gs3b94kqVRq1XugvLyccnJyKCgoyKZOVSwWU2ZmJpWVlVFPTw+1tLTQ66+/TgDoN7/5jcN5sJf+t99+S0uXLqWoqKgh63T756M/jz/+OAGgd999l5RKJen1evr6668pMjKSANCpU6dGdR4dsW9paaHY2FiKiYmhEydOUGdnJ7W3t9MHH3xAQqGQPv30U4fyNhhms5mCgoJowYIFdvcPp/eCRqOx6r1gr374448/JgB05MgRh/ybSA4cOEA8Ho9OnjzpbFfGi6nZkEZ0rwU9Ojqa0tPT7Tb0OAtLgxAACgsLo0uXLtGiRYvI19eXvL29KTMzkwoLCzn7I0eOcPaWbePGjdz+qqoqeuKJJ0gkEpG3tzc98sgjdPz4ccrKyuLsf/CDHxARUWlpKW3dupVmzJhBQqGQpFIppaWl0e7du+02LA2H/ukLhUJKT0+ns2fP0mOPPUZCoZCzszSODNwGolQqaevWrRQREUEeHh4kk8lo8+bN9PLLL3PHpKamOnweHbW30N7eTjt27KCYmBjy8PCgwMBAWrJkiZX4DzdvQ/GLX/zCZkTa/a59W1sbbd++neRyOXl4eJBYLKacnBw6ffq03TTWr19PYWFh1Nvb65BvE8W5c+dIKBTSc88952xXxpOpK7pERDdu3CCZTEYpKSlWrcyM8SchIYEiIyOd7cakobOzk8LCwmjr1q3jEn9paSnxeDybLmauwqeffkre3t6Ul5c36l41Ls7U7L1gITExEcXFxejt7UVycrJLTPYxlWhuboZUKrVpda+vr0dtbS0ef/xxJ3k2+RCLxTh27BgOHjyIXbt2jWncdXV1yMvLwyuvvIInn3xyTOMeLV1dXdi6dSs2bNiALVu24MCBA+Dz+c52a3xxtuxPBHq9np5//nni8XiUlZVFV69edbZLUwKFQkEA6Pvf/z7dvn2burq66OLFizRv3jySSqVUW1vrbBcnHbdu3aLc3Fy7fYNHyksvveRyJVyTyUR79uyh0NBQkkgkNgNQpjBTu3phIMXFxZSRkUE8Ho/Wr1/PRMEOsFM3OXB77bXXOPuCggJas2YNRUdHk6enJ8lkMtq4ceODMFsUY4ScOnWK5syZQx4eHvTDH/7Q7si5KczeB265HiLC4cOH8corr+D27dtYt24dnnvuObZwHoMxjuj1euzfvx9//vOf8c0332Dt2rV46623EBcX52zXJpoHb7keHo+HtWvXory8HH/5y19QVVWFBQsWICUlBX/729/sdvRnMBgjo7q6Gjt27EB4eDiee+45JCQk4OLFi/jss88eRMEFADxwJV179F84z9PTE6tXr8a6deuwZMmSKb3OGIMxHliWYj948CDOnTvHLfz6zDPPDDnK8gHhwV0N2B4dHR3Yt28fPvvsMxQVFcHX1xcrVqzA2rVrsWzZMpcfs85gOIvbt2/j0KFDOHjwIIqLi+Hr64uVK1fiu9/9LpYtWwY3twfuT/VgMNEdjP5v68LCQnh7e+Oxxx5DdnY2srOzXX4oJYMxnnR3d6OwsBAFBQU4deoUSktLIRaLsWrVKu5fokAgcLabrggT3eHQ3NyMzz//HKdOncLXX38NlUqFkJAQZGVlYfHixcjKykJYWJiz3WQwxg2TyYSSkhIUFBSgoKAA58+fR09PDxITE5GdnY3ly5cjKysLnp6eznbV1WGi6yhms9nq5issLERPTw9CQkKQmpqKhQsXYsGCBXj44YdZfTBj0qLRaHDp0iUUFhbi6tWruHDhAjo6OhAUFITMzExkZ2cjJydnys4ENo4w0R0ter0eFy5cQFFREYqLi3Hx4kW0t7fDy8sLDz30ENLS0jBv3jykpKRg+vTpU3+0DWPSodPp8O2336KkpATFxcUoLi5GTU0NeDwe4uPjkZaWhrS0NCxcuBBJSUkuu97gJIGJ7lhDRKiursbFixdRXFyMoqIiXL9+nZs8OikpCcnJyZgzZw7mzJmD5OTk+074zWCMBUSEuro6XLt2jdvKyspQV1cHIoJYLMb8+fM5kZ0/fz6kUqmz3Z5qMNGdCAwGA8rLy21udssKsREREZgxYwbi4+ORkJCA+Ph4xMXFISoqirX6MhxGr9ejpqYG1dXV3FZVVYWKigpotVq4ubkhNjbW6uU/Z84cyOVyZ7v+IMBE15k0NTVxAlxVVYWqqipUV1dzYiwQCBAXF4f4+HjEx8dj+vTpiIyMRFRUFCIjI1md8QNMe3s7bt++jYaGBtTX13PiWlNTgzt37oCIwOfzER0djbi4OCQkJHD/spKSkhxeUogxZjDRdUU6OjpQU1PDCbGl1FJbW2s1Yi4kJASRkZFWQhwdHY2IiAjIZDLIZDJWUp6EdHd3Q6FQQKFQcMJq+bRsA++DuLg4qxd0QkICYmNjWW8C14OJ7mSjfwnHUsrp/9tSSgYAPp+PoKAgBAcHIzQ0FDKZDGFhYQgKCkJYWBhkMhkCAgIQEBAAqVTKBHoc6enpQXt7Ozo6OqBUKtHU1ISWlhY0NjaitbUVjY2NaGlpQVNTk9Vaae7u7ggPD+deqFFRUdwLlv3jmZQw0Z1q6PV63Llzh3uALZ/Nzc1obm7mwpRKpc2xUqmUE+D+3y2fIpEIvr6+EIlEEIvF8PX15bap3hhoMBig0+mgVquh0Wig0+nQ1dUFjUbDhVlEtb29ndssvweuYuzp6Wn18gsNDUVwcLDVCzI0NBQhISGsx8vUgonug0pvby9aW1uthKGtrQ0dHR3c74GfWq12yAUifXx8OBGWSCQA/m8pdpFIBD6fDx8fH3h6ekIgEEAoFMLd3d1qGfGBv/vj6+sLDw8Pm/Curi709vbahJvNZqtSY//fnZ2dICJotVoYjUZ0d3ejp6cHvb296OrqQl9fH3Q6HVQqFXQ63ZDLo4vFYohEIu4F1f/fw8BPqVSKadOmITAwcND4GFMaJroMxzCZTFzpTqfTQafTQavVorOzE1qtlgvTaDQOiZyF7u5u6PV69PX12QwjtcQxEIuA9/fRaDRCIBBwYm9huC8BPp8PkUgEiURiVaKXSCTw8/PjfotEojE9v4wpDxNdhuuxb98+bNmyBT09PSPqiL9//3489dRT6O3tZfXUDFfjwZtPl+H6tLW1Ydq0aSMe+TRt2jSYTCZ0dnaOsWcMxuhhostwOdrb2zFt2rQRH285tr29faxcYjDGDCa6DJdjtKIbEBAAAFbd5xgMV4GJLsPlsFQvjBRW0mW4Mkx0GS7HaEXX29sbQqGQlXQZLgkTXYbLMVrRBe6VdllJl+GKMNFluBwqlWrUI9wCAgKY6DJcEia6DJdDq9UOOiptuPj6+loNumAwXAUmugyXQ6/Xj3rqQaFQyESX4ZIw0WW4FAaDAUaj0WpY70jw8fFhostwSZjoMlwKy2xcrKTLmKow0WW4FBahHIuS7sDpFBkMV4CJLsOlsIjuaEu6rHqB4aow0WW4FGNV0mXVCwxXhYkuw6UYqzpdVtJluCpMdBkuhcFgAIBRL6goEAi4uBgMV4KJLsOlMJlMAO4t2zMa3NzcYDabx8IlBmNMYaLLcCksojvaFR/4fD4XF4PhSjDRZbgUltLpaFfAZSVdhqvCRJfhUlhKp6MVXVbSZbgqTHQZLsVYVS+wki7DVWGiy3Apxqp6gZV0Ga4KE12GS8Ea0hhTHSa6DJfCbDaPWnABVr3AcF2Y6DJcCj6fD7PZDCIaVTwmk2nUVRQMxnjARJfhUnh4eAAAjEbjqOLp6+vj4mIwXAkmugyXwiKUvb29o4qHiS7DVWGiy3ApLHMu9PX1jSoeJroMV4WJLsOlsAglE13GVIWJLsOlYNULjKkOE12GS8FKuoypzujmz2MwxpDOzk4olUoAwLlz51BSUoLOzk50dnZCp9Phl7/8JXg8ns1x165dw7FjxyCRSLitrq4OJpMJTU1NkEgko16JgsEYK3g02g6RDMYIMRgMmDdvHurq6qDT6ezaWPrtpqeno7Cw0K5NQ0MDoqOjuUEV9gZFuLu7QyQS4Uc/+hHefPPNscsEg+EY+1j1AsNpCAQCZGZmDrmsjslkgru7O5YvXz6oTVRUFGJiYmA2mwcdhWY0GtHR0YEnnnhi1H4zGKOBiS7DqfzkJz+5r01fXx+WLl06pM3KlSuHXOLHzc0NqampeOSRRxz2kcEYS5joMpxKXFwcFi1aNOTyPBKJBCkpKUPGk5OTc98eD9u3bx+RjwzGWMJEl+F0tm/fPuiwX3d3d+Tm5t53EpzHHntsyJKuWCzGunXrRuUngzEWMNFlOJ3c3FxERETY3Wc2m+9btQAA3t7eWLhwoV1x9vDwwI9//GN4eXmN2lcGY7Qw0WU4HTc3Nzz//PN2qxiICEuWLBlWPIOViM1mM374wx+O2k8GYyxgostwCbZs2WJXdGfNmoWgoKBhxbF06VKbagoPDw888cQTCA8PHxM/GYzRwkSX4RJIJBJs3LjRahSZp6cnVq1aNew4Zs6cieDgYKuwvr4+/PSnPx0zPxmM0cJEl+EybN++3Wr4b29vL3JychyKo3/XMR6Ph4SEBGRkZIypnwzGaGCiy3AZZs2ahUcffZRb8UEoFCItLc2hOHJycjjhdnNzw89+9rMx95PBGA1MdBkuxfbt27l10rKzsx2etCYrK4trTBMKhdi4ceN4uMlgjBgmugyXIi8vD0FBQTCbzcjNzXX4eIlEgtTUVADA1q1b2UQ3DJeDzTLGGFP0ej0MBgMAoLu7Gz09PQDuTW6j1+utbDUajd1l0pcuXYo9e/bAx8cHBQUFUKlUw0rb09MTPj4+mDlzJi5fvozZs2ejoKDAxs7b29umz65EIuFmMBOLxVxp2c/Pb8jRcgyGo7BZxqYwPT090Gq10Gq16OzshFarhcFggFqtRl9fH3Q6HXp6etDd3c2JpVarhdFoRGdnJ0wmk11bAJwdAOh0ulHPfzsZ8PX15ao7hEIhBAIBgHuCzefzIRaL4eHhAV9fXwgEAgiFQs7OIt79bd3d3eHn5wdfX1/4+vrCz88PIpHISvQZU459THRdFK1WC5VKhY6ODqhUKm7r6OjghFSn00GtVkOj0XC/+wvsUCvq8vl8iEQirnTo5eUFb29v+Pj4wNPTEyKRCHw+H/7+/ja2gLXo9C85WuIBYGVvEaP+9LcdyJUrV/Dwww/bpHW/c2Y0GmE2m1FaWoqHHnrIrl1nZ6fVEu9msxlqtZr73b9k3d+2f8nckhYRobOzE0ajkXup6fV6rpRveSGp1WqYTCYr26EQCoWcIEskEohEIitx9vf3h6+vL0QiEfz9/eHv7w+pVMp99/f3H9Y5Y0w4THTHG6PRCKVSiba2NrS0tKClpQVKpdJKTO0Jqz3BFIlEkEql8PPz4x5IsVjMPZCWMMsDadnEYjHEYjFXAvP393fCmWAMxCLQGo0GOp3O6qVp+d7/xdo/TKVSQafTQaPRQKVScdU4/fHx8RlUkKVSKaRSKYKDgxEYGIjAwEAEBwdDLBY74Uw8UDDRHQm9vb1QKBS4e/culEolJ6YDhdWy9cfDwwOBgYHcTW/vobD3gFhKnAyGPbq7u+/7Ih/4vb29He3t7VbxCAQCBAYGIigoCDKZjBPkkJAQ7ntoaChCQkKGPVKQYQUT3YF0d3dDoVCgqakJCoUCdXV13HfLZ0NDg1UDkJeXF/z9/bmbcajvMpmMiSfDpVCpVGhqaoJKpeLuc4tA9//d2NhoVQ3j6emJgIAA7v4ODQ1FTEwM9z0kJARRUVE21UoPOA+e6La1teHWrVs2W319Pe7cucM1FAH36tXCw8MREhKCiIgIhIaGIiwsjAuLjIxEYGDgkFMKMhhTCa1Wi8bGRu6fXmNjI5qamnD37l0oFArcuXMHLS0tVtVjQUFBiIiIQHR0NORyuc6WxP0AAB5dSURBVNUWHR39oM3+NvVE12g0or6+HlVVVaitrbURV0sDBp/PR1hYmNXFj4yMtBJYVvfJYDiOyWRCS0uLlRDfvn2bK9zcunWLq9bg8XgICQmxEePY2FjMmDEDgYGBTs7NmDN5RddgMODmzZuoqKhAXV0dysvLUVFRgRs3bnD9Qf39/RETE8Nt/f8CzZgxg3WcZzCcRE9PD5qamlBXV2ezVVdXc4UjiUSC2NhYxMTEYObMmUhKSkJMTAySkpImawnZ9UW3p6cH169fR0lJCUpLS1FZWYnKyko0NTUBuFfxHx8fj4SEBCQkJCAxMRGJiYlISEiAn5+fk71nMBgj4e7du6iqqkJVVRVu3LjBfb99+zaAew3SltLwzJkzMXfuXMydOxdyuZwb5OKiuJboqlQqTlxLS0tRUlKCyspKGI1G+Pr6Ijk5GTNnzkRCQgJmzJiBhIQEREdHs4YpBuMBoaury0aMv/32W1RXV8NkMkEsFiM5ORlz585FSkoKUlJSkJSU5PAcHuOI80TXaDTim2++wYULF1BYWIirV6+ivr4eACCTyZCSksK9vVJSUjB9+nQ2SofBYNhFr9fj2rVrXGGtpKQE169fR3d3Nzw9PTFr1iykpaUhPT0dGRkZiIyMdJarEye6Go0GRUVFOH/+PAoLC3Hp0iV0dXVh2rRpSE9Px/z58zmhDQkJmQiXGAzGFMZoNKKqqooT4QsXLuDq1avo6+tDeHg4Fi5ciAULFmDhwoWYPXv2RP1jHj/RNZlMKCoqQn5+Pr766itcu3YNJpMJcXFxSE9P5zKcmJjo6nUwDAZjitDd3Y3Lly/j3LlzuHDhAs6fPw+1Wg2RSISFCxciNzcXy5cvR3R09Hi5MLai29HRga+++grHjx/HV199hfb2dkyfPh3Lly9HZmYm0tPTbZZTYTAYDGdhNptRXl6Oc+fO4euvv8bJkyeh1WqRlJSEFStWIDc3F+np6WNZCh696La2tuLTTz/FZ599hgsXLsDNzQ0ZGRlYvnw5VqxYgYSEhLFylsFgMMaV3t5enDt3DsePH0d+fj5qamoglUqxbNkyfPe738WSJUtG2yi3DzQC+vr66NChQ7R8+XJyd3cnPz8/euqpp+jAgQPU2dk5kihdgt/97ncEgABQWFjYuKTh4+PDpWHZeDweSSQSmjNnDm3bto2uXLkyLmlPVerr62nlypWkVqud7QrDAf7f//t/tH//fme7MSRVVVX0/vvv08KFC4nH41FgYCD95Cc/ofLy8pFGudch0VWpVPTmm29SeHg4ubm50fLly+njjz+mrq6ukTrgkiQnJ4+b6BIRlZSUEABavXo1EREZjUZqbm6mo0eP0qJFiwgAbd682WXPq1arpenTp1Nubq6zXaGSkhKaNm0a/elPf3K2KwwHuXnzJsnlcvrlL3/pbFeGxa1bt+g3v/kNTZ8+nXg8Hi1atIg+//xzMpvNjkQzPNHVaDT02muvkUQiIX9/f/r5z39OtbW1I/N8EjDRojuQl156iQDQqlWrHL2gE4JGo6GYmBhatmyZU/1Qq9UUHh5OW7dudaofjJFTWlpKPB6PPv30U2e7MmxMJhN9+eWXtGLFCuLxeDR37lz64osvhnv4/UX38OHDFB4eTv7+/vTGG29M6uqD4eJs0TWbzTR//nwCQB9//PG4+THZ2blzJ7m7u1NjY6OzXWGMgvXr11N4eDj19fU52xWHKS0tpby8POLxeJSbm0u3bt263yF7Bx1tYDAY8NOf/hR5eXl49NFHUVlZiV/96ldskuMJgMfj4cc//jEA4M9//rOTvXFNiAh///vfMX/+fISGhjrbHcYoWLNmDe7evYv8/Hxnu+IwycnJOHToEM6ePYuGhgbMmTMHhw4dGvIYu6JrMBiwbNky7NmzB59//jkOHDgwKScsPnr0KHg8HrfV19djw4YNkEgkCAgIwIoVK1BbW+twPA0NDdiwYQP8/PwQEBCATZs2QaVSob6+HitXroSfnx9CQkLw7LPP3ndZlsFYuHAhAKC4uNhq/TGlUonnn38e0dHR8PT0RGBgIPLy8lBaWjrqfLe3t2PHjh2IjY2Fp6cn/P39sWzZMpw5c2bQuPuvWGAwGPDqq68iMTERQqEQUqkUK1euxBdffGGzAOVw8jEUZWVlaGlpQXJyslX4e++9x/kWHh6Oy5cvIysrC35+fhAKhVi0aBHOnz8/aH6qqqrwne98BwEBAVxYW1vbsH0ez/SHc33sXUuBQIDw8HBkZ2fjn//8p9X0pY5ci+FeX0fuAwBISUkBAHz11VdDX3QXJiMjA1evXsX3vvc9rF+/Hn/9618HN7ZX/t28eTNJJBK6du3aWJfGncLq1au5v/MXLlwgnU5Hp06dIm9vb3rkkUds7AerXrDEk5eXR1euXCGdTkd79+4lALRs2TJavXo1lZSUkFarpQ8++IAA0AsvvGATz/2qF4iIuru7ud4NTU1NRETU1NREUVFRJJPJKD8/n7RaLV2/fp0yMzPJy8uLLly4MOJ8KxQKksvlJJPJ6NixY6RWq6mqqor767R79267cXd3d3NhW7ZsIbFYTCdPniS9Xk/Nzc304osvEgA6c+YMZ+doPuyxb98+AkBvvfWW3f3Jycnk4+NDjz76KJf3y5cv05w5c8jT05P+/e9/281PZmYmnTlzhrq6uqi4uJj4fD4plUqHfR7r9B25Phbb4OBgOnbsGGk0GmpubqZf//rXBIB+//vfj+haDPf6DtfOglqtJgCUkZFx3+s+Gfj1r39NfD6fTp06ZW+3bZ3ulStXiMfj0dGjR8ffuwnCckMfO3bMKnzdunUEgJRKpVX4/UQ3Pz/fKjwpKYkA0NmzZ63C5XI5JSQk2MQzHNHV6/U2ovv0008TAProo4+sbBUKBQkEAkpNTR1xvjdv3kwA6JNPPrGy7enpodDQUPL29qbm5mabuPuLrlwup/T0dJu8xMfHWz1sjubDHu+++y4BoF27dtndn5ycTACopKTEKvzatWsEgJKTk63CLfk5ceKE3fgc9Xms03fk+lhs7TVOLV261Ep0HcnXcK/vcO36w+PxaPr06Xb3TUbWrFlDc+bMsdcQbiu6r776KiUmJk6MZxOE5YbuLxpERC+88AIBoLKyMqvw+4luS0uLVfjixYsJgE0Xr4ULF5Kfn59NPMMR3draWgJAHh4e1NvbS0REYrGY3Nzc7PZHfeihhwgA3blzZ0T5FovFBIA0Go1N3Js2bSIAtGfPHpu4+4vutm3bCAA9++yzVFRUREaj0W7eHM2HPd544w0CQH/729/s7reUNO0RGhpq9TLrn5+2trYx8Xk80h/u9RnKdjT5Gu71Ha5dfzw8PMa18XqiuXjxIgGgmzdvDtxl25CmUCgQERExeH3EJGZgI6BlmR2z2exQPCKRyOq3m5sb+Hy+zaTofD7f4bgtFBYWAgAeffRReHh4wGAwQK1Ww2w2QywWW9UD8ng8fPPNNwCAmpoam7jul29L3F5eXnbnIJbJZACA5ubmIX3etWsX9u7di7q6OmRlZUEkEmHp0qU4cuQIZzOafPTHMoF1//rugUgkErvhlvaJ1tZWm32WJeP7M1Kfxzr94Vyf+9mOJl/Dub6O2PXHaDTC29t7SH8nExYNtcz73R8b0Z05cya++eYbdHV1jb9nDLuYzWbs2rULAPBf//VfAO5N1i6RSODu7o6+vj4Qkd1t0aJFDqcnEAggFovR09Njt+GvpaUFAO47bwaPx8OmTZtQUFCAzs5OHD16FESEvLw8vP/++2OaD8tMdP0XShxIe3s7yM4od4vYDbdxeKQ+j2X6w70+97MdTb6Gc30dsbOg0WhARFNqdsFz587Bzc0NM2fOtNlnI7qbNm2C0WjEq6++OiHOMWx55ZVXcOnSJaxZswbr16/nwvPy8mA0Gq1avy288847iIyMtFoQ0BHWrFkDADbddgwGA06fPg1vb2/k5OQMGYdEIkFlZSWAezP7L168mGud7x/vWORj1qxZAO6tMDAYPT09uHz5slXYt99+i6amJiQnJzv0kI/E57FM35HrY7E9ceKETTxz587FCy+8MKJ8Dff6DtfOQmNjI4D/u6aTHZVKhZ07d+K73/0uAgICbA3s1Ufs27ePeDwevf3222NRveF07NU/Et0b+w07jR33q9MdGE9OTg7x+Xwb+8zMTLv1egPrdE0mE7W0tNDRo0fp8ccfJwD0zDPPkF6vtzqupaWFYmNjKSYmhk6cOEGdnZ3U3t5OH3zwAQmFQpuGE0fyPbB1XKPRWLWOD6w7tRe3WCymzMxMKisro56eHmppaaHXX3+dANBvfvObEefDHmazmYKCgmjBggV29ycnJ5NYLKasrCyHeg8MPFcj9Xms03fk+lhsQ0JC6Pjx46TRaOjOnTu0bds2kslk1NDQMKJ8Dff6DtfOwscff0wA6MiRI3bzPploa2ujBQsWUGRk5GCDdgYfkfbHP/6R+Hw+fe973yOVSjV+Xo4jRUVFNpPL7Ny5k4jIJjw3N9dqwpv+9oPFc/nyZZvwt99+m86dO2cT/tprrxHR4BPeiMVimj17Nm3bto2uXr06aJ7a29tpx44dFBMTQx4eHhQYGEhLliyx6p7iaL4ttLW10fbt20kul5OHhweJxWLKycmh06dPczZHjhyxiWPjxo1EdG90ztatW2nGjBkkFApJKpVSWloa7d6926YVdzj5uB+/+MUvBh2RZnlxVlRUUE5ODvn5+ZG3tzdlZmZSYWHhkOdqkLKIQz6PR/rDuT6D2YaEhNCTTz5J1dXVI87XcK+vI/cB0b0RaWFhYVyD8WSluLiY5HI5RUVFUUVFxWBmQw8DPnnyJMlkMpLJZLRnzx4ymUxj7ymDMUI6OzspLCzM7twL4z2U+344O/3JgmXuhYFd4SYTSqWStm3bRm5ubrRkyRKbLqgDGHwYMAAsXrwYlZWVyMvLw/e//33Mnj0b+/fvtzuqhMGYaMRiMY4dO4aDBw9yDY+MyUNdXR3y8vLwyiuv4Mknn3S2Ow6jVCrxyiuvQC6X48iRI9i7dy++/PJLTJs2bcjj7rvSo0QiwZ///Gdcv34dKSkpeOqppxATE4O3337bbpcXBmMimTt3Lq5cuYJ//etf0Gg0znaH4QB//etf8eabb+LNN990tisOcfHiRTz99NOIjIzEhx9+iFdffRU3b97Exo0bh7f0mKNF6Zs3b9LPfvYz8vf3J09PT1q1ahUdOHBg0AYABmMiGaxe/kFJnzE+3L59m377299yo09TUlJo9+7dI5nzeu+Il+vR6/U4fPgw/ud//gcFBQUQCoVYsmQJli9fjtzcXK7DNoPBYEw2iAglJSXIz89Hfn4+Ll++DIlEgg0bNuA///M/kZaWNtKox2ZhSoVCgcOHD+P48eP497//jd7eXqSmpiI3Nxe5ublITU1lK/4yGAyXRqfT4dSpUzhx4gTy8/OhUCgQFhaG5cuXY+XKlcjJyeFGc46CsV+CXa/X4/Tp08jPz8eJEydw584dyGQyZGRkcMuup6SkwN3dfSyTZTAYDIdQqVTcMuyFhYW4dOkS+vr6MG/ePKxYsQLLly9HSkrKWBcYx150B1JWVoaTJ09y68y3t7fDx8cHaWlpnAinpaXdd5w4g8FgjIb6+noUFhZyIltRUQEiQmJiIhYsWIDMzEzk5OQgMDBwPN0Yf9HtDxHhxo0bXKbPnz+P2tpa8Pl8zJw5EykpKZg7dy5SUlKQkpICf3//iXKNwWBMEYgIt27dQklJCUpLS1FSUoKSkhI0NTXB09MTDz/8MNLT05GRkYH09PT7dvEaYyZWdO2hUChw/vx5XLlyhTtJlq5o0dHRNkIcGRnpTHcZDIYL0dvbi4qKCk5cS0tLUVZWBrVaDT6fj7i4OE4/0tLS8Mgjjzh7NjPni649VCoVysvLcfXqVW6rrKyE2WyGQCBAbGwskpKSEBMTg5kzZyIpKQkzZsywmVqRwWBMDTo7O1FbW4u6ujqUl5ejoqICdXV1uH79OgwGAzw8PBAXF4fU1FRumzt3rt2pMp2Ma4quPTQaDa5du4YbN26gqqoKFRUVqKqqQn19PcxmM/h8PuRyORITE5GYmIiEhATExsZCLpcjPDycNdwxGC6OTqdDfX09bt26herqalRVVaGqqgo3btyAUqkEAAiFQiQkJCAhIQEzZsxAYmIikpKSkJCQMFme8ckjuoNhMBi4i1NZWcmJclVVFTcnsLu7OyIiIiCXyyGXyxEdHc19l8vlU2oeTwbDVTEYDGhoaOCE9datW1bfLcIK3Jsv2VJ4SkxMxIwZM5CQkIDIyMjJ3v108ovuULS0tNi9uLdu3cLt27e5VQe8vLy4EnFoaCgiIiIQEhKCiIgIhIaGIiwsDDKZbLJfbAZj3Ojp6UFTUxMaGxtx9+5dKBQK3LlzhwtraGhAU1MTt1qJSCSyKvgM3KZwVeHUFt2hMJlMaGxstBJly01y9+5dNDU1oaOjg7P38PBAcHCwlRCHh4dDJpNh2rRpCA4ORlBQEAIDA8eiAzWD4RJotVo0NzdDqVRCqVSitbWVE9KmpibcuXMHCoXCqpTq7u4OmUzGFV7Cw8Ot/mnK5XJIpVIn5sqpPLiiOxy6u7u5t/bt27ehUChw9+5dqxtOqVTCYDBYHSeRSCCTyRAYGIjAwEAEBwdz32UyGWQyGfz9/SGVSuHv7z+V3+oMF6OzsxMdHR3o6OjghLStrQ3Nzc1obW3lhLWlpQVKpRI9PT1Wx4tEIoSFhSEkJIQreISEhCAyMpITWJlMBj6f76QcujxMdMcCjUZjVRpoaWnhbmClUmm1T6lU2qyb5eXlZSXC/b/b+/Tz84Ovry/8/PwgkUhYtccDhMFggE6ng1qthkajgVarRUdHB1Qq1bA+7d17gYGBCAoKGrKgYPkXJxAInJTzKQMT3YnGZDKhra2NexCG+7CoVKpBV7718fGBr68vfH19IZFIOFH29fWFSCSCWCzmfvv6+kIoFEIgEMDPzw/u7u6QSCTg8/kQi8Xw9PSEj48PvL29uRV3GY6jVqthMpnQ2dkJo9EIrVYLg8EAvV4PvV4Pg8EArVaLvr4+dHZ2QqvVQqfTQafTQaPRQK1Wc791Oh1UKhV0Ot2Q98BQL2p7n4GBgWwk6MTDRHcyodVqoVKpuAdUq9XaPLCWEpBlf/8HVqfTQa/XQ6vVDnsBS19fX3h4eEAsFoPP53PLiru5uXFLu/N4PKvlxvuXvsViMdzc7k3bLBKJbP528vl8myXt7XG/Er1F0IbCIn4DsYggcK9BqLu72ybO3t5erjdM/3gs4d3d3ejp6RlSGAfi4+MDT09PmxelWCyGSCTi/s34+vrC39/f6sVpsfHz84NUKmXtCJMHJroPMp2dnTCZTFCr1ejr64NOp+NEp6urC729vdBoNDCZTFCpVDCZTNxE4RZ7AFbhZrPZall0lUplld7A280iVkPRP63BGCj8g2FP+L28vLhRSpaSPnCv8dTX1xeA9cuh/wvH3d0dfn5+EAgEEAqFQ/6LsMTXPz3GAwcTXQaDwZhA9t13uR4Gg8FgjB1MdBkMBmMCYaLLYDAYEwgTXQaDwZhAmOgyGAzGBMJEdxLz3nvvgcfjgcfjITw83Nnu2LB//37OPzbQYmxRqVT44IMP8Pjjj0MqlcLb2xtxcXHYuHEjysrKnO0eYwiY6E5iXnzxRRARkpOTne2KXZ588kkQEbKyspztyqDodDrExcVhxYoVTjl+pPz85z/HT37yE6xevRoVFRVob2/Hhx9+iNLSUqSmpuLo0aMT6g9j+DDRZTzQEBHMZjM35eBEHz8annnmGfz0pz9FcHAwhEIhMjIy8PHHH8NkMuGll16acH8Yw4MNjpgCpKSkoK2tDXfv3nW2K3bJzs5GYWHhfUeeMcYGoVAIg8EAo9HIJkNyPdjgCAZjKmGZB2LWrFlMcF0UJrouxNGjR7mGJx6Ph/r6emzYsAESiQQBAQFYsWIFamtrHY6noaEBGzZsgJ+fHwICArBp0yaoVCrU19dj5cqV8PPzQ0hICJ599lm7E8IMl8rKSjzxxBMQi8Xw8fFBRkYGCgsLB7VXKpV4/vnnER0dDU9PTwQGBiIvLw+lpaWjPift7e3YsWMHYmNj4enpCX9/fyxbtgxnzpwZNO7+JXGDwYBXX30ViYmJEAqFkEqlWLlyJb744guYTKYhjx+pz/3Pn1AoxLx583D8+HFkZ2dzcW3ZsmXIa/DZZ58BAHbu3DmkHcOJEMPlWL16NQGg1atX04ULF0in09GpU6fI29ubHnnkERv75ORkCgsLGzSevLw8unLlCul0Otq7dy8BoGXLltHq1auppKSEtFotffDBBwSAXnjhhRH5XFNTQxKJhMLCwujkyZOk1Wrp2rVrtGTJEoqOjiaBQGBl39TURFFRUSSTySg/P5+0Wi1dv36dMjMzycvLiy5cuDDic6JQKEgul5NMJqNjx46RWq2mqqoqysvLIx6PR7t377Ybd3d3Nxe2ZcsWEovFdPLkSdLr9dTc3EwvvvgiAaAzZ87c93hHfbZ3/q5fv07Z2dkUGBhoc/7s0dzcTDKZjLZs2XJfW4bT2MtE1wWxPKzHjh2zCl+3bh0BIKVSaRV+P9HNz8+3Ck9KSiIAdPbsWatwuVxOCQkJI/J5/fr1BIAOHjxoFd7Y2EgCgcBGNJ5++mkCQB999JFVuEKhIIFAQKmpqXbzMpxzsnnzZgJAn3zyiZVtT08PhYaGkre3NzU3N9vE3V805XI5paen2+QzPj7eYdEdjs+Dnb/W1lYSCoX3Fd22tjZKSUmhDRs2kNFoHNKW4VT2suoFF+aRRx6x+h0REQEAaGpqciiehx9+2Op3aGio3fCwsDCH47bw5ZdfAgBycnJs0oqPj7exP3r0KNzc3Gy6WgUHByMpKQlXr1612zA4nHNy5MgRAEBubq6VrUAgQFZWFrq7u/HVV18NmZ+lS5fiwoUL+OEPf4ji4mKuSqGqqgqPPfbYkMeOxOfBzl9gYCASExOHjL+rqws5OTmYOXMmPvroI7ZUjovDRNeFsczZasEyUbWj3ZMGThLu5uYGPp9vszYbn88fUdcnyyoIXl5e3Pyz/QkKCrKxV6vVMJvNEIvFVvWfPB4P33zzDQCgpqbGJq77nRNL3F5eXnZXRZDJZACA5ubmIfO0a9cu7N27F3V1dcjKyoJIJMLSpUs5QXeE4fg81Pnz9/cfNG6j0Yj169cjLCwMe/bsYYI7CWCiyxg1lkm7LSsnDKT/qsoWe4lEAnd3d/T19YGI7G6LFi0akS9isRg9PT12GwVbWloA3CtRDwWPx8OmTZtQUFCAzs5OHD16FESEvLw8vP/++w77dT+fhzp/ra2tgx67detWGAwGHDhwAO7u7lz49OnTUVxcPKZ+MsYGJrqMMWHZsmUA/u9vsoW2tjZUVVXZ2Ofl5cFoNOL8+fM2+9555x1ERkYOe0mhgaxZswYAkJ+fbxVuMBhw+vRpeHt72/yNH4hEIkFlZSWAeytILF68mOuVMDDesWCw89fc3Izq6mq7x7z++usoLy/H559/zhaMnEQw0WWMCW+99RakUim2b9+OU6dOQafToaKiAk899ZTdv8xvv/02YmNj8cwzz+Bf//oX1Go1Ojo68Ne//hVvvPEG3nvvPauSmyO8/fbbkMvl2L59O44fPw6tVovq6mp873vfg0KhwB/+8AeummEofvSjH+HatWswGAxobW3Fu+++CyLC448/PiK/hsLe+bt+/Tq+//3v2y2V//Of/8R///d/4+LFi/Dz87OpohlO10KGk3BeIx5jIEVFRQTAatu5cycRkU14bm4u/e53v7NrP1g8ly9ftgl/++236dy5czbhr732msP+V1VV0RNPPEEikYjrFnX8+HHKysri4v3BD37A2be3t9OOHTsoJiaGPDw8KDAwkJYsWUKnTp0a8Tmx0NbWRtu3bye5XE4eHh4kFospJyeHTp8+zdkcOXLEJo6NGzcSEVFpaSlt3bqVZsyYQUKhkKRSKaWlpdHu3bvJbDYPefxIfe5//oRCIaWnp9PZs2fpscceI6FQaHWuc3NzbeIauBUVFTl8DRnjzl42DJjBcHESExPR3d2NhoYGZ7vCGD1sGDCD4Qo0NzdDKpXaLN9eX1+P2tracanSYDgHJroMhougUqmwdetW3LlzB3q9HpcuXcKGDRsgEonwq1/9ytnuMcYIJrqMQRnYOGNve/31153t5pQgODiY6572H//xH/D398eqVasQFxeHS5cuISYmxtkuMsYIVqfLYDAYEwer02UwGIyJhIkug8FgTCBMdBkMBmMCYaLLYDAYEwgTXQaDwZhAmOgyGAzGBMJEl8FgMCYQJroMBoMxgTDRZTAYjAmEiS6DwWBMIP8fq+D18H9BytYAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import Image, display\n", + "display(Image(filename=graph_img))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Content of `pymialsrtk/interfaces/preprocess.py`" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# %load '/opt/conda/envs/pymialsrtk-env/lib/python3.7/site-packages/pymialsrtk/interfaces/preprocess.py'\n", + "# Copyright © 2016-2019 Medical Image Analysis Laboratory, University Hospital Center and University of Lausanne (UNIL-CHUV), Switzerland\n", + "#\n", + "# This software is distributed under the open-source license Modified BSD.\n", + "\n", + "\"\"\" PyMIALSRTK preprocessing interfaces\n", + "\"\"\"\n", + "\n", + "import os\n", + "\n", + "from glob import glob\n", + "\n", + "from traits.api import *\n", + "\n", + "import nibabel as nib\n", + "\n", + "from nipype.utils.filemanip import split_filename\n", + "from nipype.interfaces.base import traits, isdefined, CommandLine, CommandLineInputSpec,\\\n", + " TraitedSpec, File, InputMultiPath, OutputMultiPath, BaseInterface, BaseInterfaceInputSpec\n", + "\n", + "from pymialsrtk.interfaces.utils import run\n", + "\n", + "class BtkNLMDenoisingInputSpec(BaseInterfaceInputSpec):\n", + " bids_dir = Directory(desc='BIDS root directory',mandatory=True,exists=True)\n", + " in_file = File(desc='Input image',mandatory=True)\n", + " in_mask = File(desc='Input mask',mandatory=False)\n", + " out_postfix = traits.Str(\"_nlm\", usedefault=True)\n", + " weight = traits.Float(0.1,desc='NLM weight (0.1 by default)')\n", + "\n", + "class BtkNLMDenoisingOutputSpec(TraitedSpec):\n", + " out_file = File(desc='Denoised image')\n", + "\n", + "class BtkNLMDenoising(BaseInterface):\n", + "\n", + " input_spec = BtkNLMDenoisingInputSpec\n", + " output_spec = BtkNLMDenoisingOutputSpec\n", + " \n", + " def _run_interface(self, runtime): \n", + " _, name, ext = split_filename(os.path.abspath(self.inputs.in_file))\n", + " out_file = os.path.join(self.inputs.bids_dir, ''.join((name, self.inputs.out_postfix, ext)))\n", + " print('out_file: {}'.format(out_file))\n", + "\n", + " if self.inputs.in_mask:\n", + " cmd = 'btkNLMDenoising -i \"{}\" -m \"{}\" -o \"{}\" -b {}'.format(self.inputs.in_file,self.inputs.in_mask,out_file,self.inputs.weight)\n", + " else:\n", + " cmd = 'btkNLMDenoising -i \"{}\" -o \"{}\" -b {}'.format(self.inputs.in_file,out_file,self.inputs.weight)\n", + " \n", + " try:\n", + " print('... cmd: {}'.format(cmd))\n", + " run(self, cmd, env={}, cwd=os.path.abspath(self.inputs.bids_dir))\n", + " except:\n", + " print('Failed')\n", + " return runtime\n", + "\n", + " def _list_outputs(self):\n", + " outputs = self._outputs().get()\n", + " _, name, ext = split_filename(os.path.abspath(self.inputs.in_file))\n", + " outputs['out_file'] = os.path.join(self.inputs.bids_dir, ''.join((name, self.inputs.out_postfix, ext)))\n", + " return outputs\n", + "\n", + "class MultipleBtkNLMDenoisingInputSpec(BaseInterfaceInputSpec):\n", + " bids_dir = Directory(desc='BIDS root directory',mandatory=True,exists=True)\n", + " input_images = InputMultiPath(File(desc='files to be denoised', mandatory = True))\n", + " input_masks = InputMultiPath(File(desc='mask of files to be denoised', mandatory = False))\n", + " weight = traits.Float(0.1)\n", + " out_postfix = traits.Str(\"_nlm\", usedefault=True)\n", + " \n", + "class MultipleBtkNLMDenoisingOutputSpec(TraitedSpec):\n", + " output_images = OutputMultiPath(File())\n", + "\n", + "class MultipleBtkNLMDenoising(BaseInterface):\n", + " input_spec = MultipleBtkNLMDenoisingInputSpec\n", + " output_spec = MultipleBtkNLMDenoisingOutputSpec\n", + "\n", + " def _run_interface(self, runtime):\n", + " if len(self.inputs.input_images)>0:\n", + " for input_image, input_mask in zip(self.inputs.input_images,self.inputs.input_masks):\n", + " ax = BtkNLMDenoising(bids_dir = self.inputs.bids_dir, in_file = input_image, in_mask = input_mask, out_postfix=self.inputs.out_postfix, weight = self.inputs.weight)\n", + " ax.run()\n", + " else:\n", + " for input_image in self.inputs.input_images:\n", + " ax = BtkNLMDenoising(bids_dir = self.inputs.bids_dir, in_file = input_image, out_postfix=self.inputs.out_postfix, weight = self.inputs.weight)\n", + " ax.run()\n", + " return runtime\n", + "\n", + " def _list_outputs(self):\n", + " outputs = self._outputs().get()\n", + " outputs['output_images'] = glob(os.path.abspath(\"*.nii.gz\"))\n", + " return outputs" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/documentation/outputs.rst b/documentation/outputs.rst new file mode 100644 index 000000000..64221bd88 --- /dev/null +++ b/documentation/outputs.rst @@ -0,0 +1,96 @@ +***************************************** +Outputs of MIALSRTK BIDS App +***************************************** + +Processed, or derivative, data are outputed to ``/`` and follow the :abbr:`BIDS (Brain Imaging Data Structure)` v1.4.1 standard (see `BIDS Derivatives `_) whenever possible. + +BIDS derivatives entities +-------------------------- + +.. tabularcolumns:: |l|p{5cm}| + ++--------------------------+------------------------------------------------------------------------------------------------------------+ +| **Entity** | **Description** | ++==========================+============================================================================================================+ +| ``sub-