diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..68019cc --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,72 @@ +name: CI +on: + pull_request: + branches: + - master + push: + branches: + - master + tags: '*' +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - '1.6' + - '1' + - 'nightly' + os: + - ubuntu-latest + - macOS-latest + arch: + - x64 + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: actions/cache@v1 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + continue-on-error: ${{ matrix.version == 'nightly' }} + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v1 + with: + file: lcov.info + docs: + name: Documentation + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: '1.6' + arch: x64 + - run: | + julia --project=docs -e ' + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate()' + - run: | + julia --project=docs -e ' + using Documenter: DocMeta, doctest + using MRFingerprintingRecon + DocMeta.setdocmeta!(MRFingerprintingRecon, :DocTestSetup, :(using MRFingerprintingRecon); recursive=true) + # doctest(MRFingerprintingRecon)' + - run: julia --project=docs docs/make.jl + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml new file mode 100644 index 0000000..cba9134 --- /dev/null +++ b/.github/workflows/CompatHelper.yml @@ -0,0 +1,16 @@ +name: CompatHelper +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 0000000..f49313b --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,15 @@ +name: TagBot +on: + issue_comment: + types: + - created + workflow_dispatch: +jobs: + TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.gitignore b/.gitignore index 5bf4af9..98f2129 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ +*.out +.vscode/ +docs/build +docs/src/build* +docs/Manifest.toml /Manifest.toml -.vscode \ No newline at end of file +.DS_Store \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9b79cfa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Jakob Asslaender and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..66f8846 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# MRFingerprintingRecon.jl + + +| **Documentation** | **Paper** | **Build Status** | +|:------------------------- |:--------------------------- |:------------------------------------- | +| [![][docs-img]][docs-url] | [![][paper-img]][paper-url] | [![][gh-actions-img]][gh-actions-url] | +| | [![][arXiv-img]][arXiv-url] | [![][codecov-img]][codecov-url] | + + +MRFingerprintingRecon.jl is a Julia package that implements--so far--the *low rank inversion* reconstruction described in the paper [Low rank alternating direction method of multipliers reconstruction for MR fingerprinting](https://doi.org/10.1002/mrm.26639). This package is still work in progress and the interface will likely change over time. The ultimate goal of this package is to reproduce the [Matlab code](https://bitbucket.org/asslaender/nyu_mrf_recon) of the ADMM algorithm to Julia. + + +[docs-img]: https://img.shields.io/badge/docs-latest%20release-blue.svg +[docs-url]: https://JakobAsslaender.github.io/MRFingerprintingRecon.jl/stable + +[gh-actions-img]: https://github.com/JakobAsslaender/MRFingerprintingRecon.jl/workflows/CI/badge.svg +[gh-actions-url]: https://github.com/JakobAsslaender/MRFingerprintingRecon.jl/actions + +[codecov-img]: https://codecov.io/gh/JakobAsslaender/MRFingerprintingRecon.jl/branch/master/graph/badge.svg +[codecov-url]: https://codecov.io/gh/JakobAsslaender/MRFingerprintingRecon.jl + +[arXiv-img]: https://img.shields.io/badge/arXiv-2107.11000-blue.svg +[arXiv-url]: https://arxiv.org/pdf/1608.06974.pdf + +[paper-img]: https://img.shields.io/badge/doi-10.1002/mrm.29071-blue.svg +[paper-url]: https://doi.org/10.1002/mrm.26639 diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..44c3212 --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,12 @@ +[deps] +BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" +IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +MRFingerprintingRecon = "f4798e02-a7e0-47f5-a571-12dd775704d3" +PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +WebIO = "0f1e0344-ec1d-5b48-a673-e5cf874b6c29" diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..0b95183 --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,75 @@ +using Pkg +Pkg.activate("docs") +Pkg.develop(PackageSpec(path=pwd())) +Pkg.instantiate() + +using MRFingerprintingRecon +using Documenter +using Literate +using Plots # to not capture precompilation output + +# HTML Plotting Functionality +struct HTMLPlot + p # :: Plots.Plot +end +const ROOT_DIR = joinpath(@__DIR__, "build") +const PLOT_DIR = joinpath(ROOT_DIR, "plots") +function Base.show(io::IO, ::MIME"text/html", p::HTMLPlot) + mkpath(PLOT_DIR) + path = joinpath(PLOT_DIR, string(UInt32(floor(rand()*1e9)), ".html")) + Plots.savefig(p.p, path) + if get(ENV, "CI", "false") == "true" # for prettyurl + print(io, "") + else + print(io, "") + end +end + +# Notebook hack to display inline math correctly +function notebook_filter(str) + re = r"(? "\$") +end + +# Literate +OUTPUT = joinpath(@__DIR__, "src/build_literate") + +files = [ + "tutorial.jl", +] + +for file in files + file_path = joinpath(@__DIR__, "src/", file) + Literate.markdown(file_path, OUTPUT) + Literate.notebook(file_path, OUTPUT, preprocess=notebook_filter; execute=false) + Literate.script( file_path, OUTPUT) +end + +DocMeta.setdocmeta!(MRFingerprintingRecon, :DocTestSetup, :(using MRFingerprintingRecon); recursive=true) + +makedocs(; + doctest = false, + modules=[MRFingerprintingRecon], + authors="Jakob Asslaender and contributors", + repo="https://github.com/JakobAsslaender/MRFingerprintingRecon.jl/blob/{commit}{path}#{line}", + sitename="MRFingerprintingRecon.jl", + format=Documenter.HTML(; + prettyurls=get(ENV, "CI", "false") == "true", + canonical="https://JakobAsslaender.github.io/MRFingerprintingRecon.jl", + assets=String[], + ), + pages=[ + "Home" => "index.md", + "Quick Start Tutorial" => Any[ + "build_literate/tutorial.md", + ], + "API" => "api.md", + ], +) + +# Set dark theme as default independent of the OS's settings +run(`sed -i'.old' 's/var darkPreference = false/var darkPreference = true/g' docs/build/assets/themeswap.js`) + +deploydocs(; + repo="github.com/JakobAsslaender/MRFingerprintingRecon.jl", +) diff --git a/docs/src/api.md b/docs/src/api.md new file mode 100644 index 0000000..1d1160d --- /dev/null +++ b/docs/src/api.md @@ -0,0 +1,15 @@ +```@meta +Author = "Jakob Assländer" +CurrentModule = MRFingerprintingRecon +``` + +# API + +In the following, you find the documentation of all exported functions of the [MRFingerprintingRecon.jl](https://github.com/JakobAsslaender/MRFingerprintingRecon.jl) package: + +```@index +``` + +```@autodocs +Modules = [MRFingerprintingRecon] +``` \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..3dbee4e --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,10 @@ +```@meta +CurrentModule = MRFingerprintingRecon +``` + +# MRFingerprintingRecon.jl + +Documentation for the [MRFingerprintingRecon.jl](https://github.com/JakobAsslaender/MRFingerprintingRecon.jl) package. Stay tuned for the documentation... + + +The documentation of all exported functions can be found in the [API](@ref) Section. \ No newline at end of file diff --git a/docs/src/tutorial.jl b/docs/src/tutorial.jl new file mode 100644 index 0000000..8e67621 --- /dev/null +++ b/docs/src/tutorial.jl @@ -0,0 +1,11 @@ +#md # [![](https://mybinder.org/badge_logo.svg)](@__BINDER_ROOT_URL__/build_literate/tutorial.ipynb) + +# # Tutorial + +# TODO + +# For this example, we need the following packages: +using MRFingerprintingRecon +using Plots +plotlyjs(bg = RGBA(31/255,36/255,36/255,1.0), ticks=:native); #hide #!nb + diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..802ac0b --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,4 @@ +[deps] +BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/cmaps.jl b/test/cmaps.jl new file mode 100644 index 0000000..f48dd5a --- /dev/null +++ b/test/cmaps.jl @@ -0,0 +1,6 @@ +using BenchmarkTools +using MRFingerprintingRecon +using Test + +# TODO +@test 1 == 1 \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 0000000..43b4ce4 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,6 @@ +using MRFingerprintingRecon +using Test + +@testset "Greens_Interpolation" begin + include("cmaps.jl") +end \ No newline at end of file