diff --git a/README.md b/README.md
index 7c10b51..b212ecd 100644
--- a/README.md
+++ b/README.md
@@ -12,16 +12,48 @@ This project is an improvement of the [Python source code](http://www.neuroimagi
- Langkammer, C., Bredies, K., Poser, B. A., Barth, M., Reishofer, G., Fan, A. P., ... & Ropele, S. (2015). Fast quantitative susceptibility mapping using 3D EPI and total generalized variation. Neuroimage, 111, 622-630.
-## Setup
+## Command line usage
+
+### Command line Setup
+
+1. Install [Julia](https://julialang.org/downloads/) (v1.9+ recommended)
+2. Make sure `julia` can be executed from the command line
+3. Download the single file tgv_qsm.jl (Download tgv_qsm.jl)
+
+### Run script
+
+```bash
+julia /tgv_qsm.jl --help
+```
+
+On the first usage, the script will download all dependencies.
+
+### Optional configuration
+
+Under Linux: Make the file executable with `chmod +x tgv_qsm.jl` and run via
+
+```bash
+/tgv_qsm.jl --help
+```
+
+## Run in Julia
+
+### Setup
1. Install [Julia](https://julialang.org/downloads/) (v1.9+ recommended)
2. Install this package
Open the julia REPL and type:
+ ```julia
+ julia> ] # enters package manager
+ pkg> add QuantitativeSusceptibilityMappingTGV MriResearchTools
+ ```
+
+ or
+
```julia
import Pkg
- Pkg.add(url="https://github.com/korbinian90/QuantitativeSusceptibilityMappingTGV.jl")
- Pkg.add("MriResearchTools") # for nifti handling
+ Pkg.add(["QuantitativeSusceptibilityMappingTGV", "MriResearchTools"])
```
## Example to run TGV
@@ -61,10 +93,6 @@ This project is an improvement of the [Python source code](http://www.neuroimagi
The first execution might take some time to compile the kernels (~1min).
-## Command Line Interface
-
-Coming soon
-
## Settings
The default settings were optimized for brain QSM and should lead to good results independently of the acquired resolution.
@@ -91,7 +119,7 @@ It uses the number of CPU threads julia was started with. You can use `julia --t
This implementation doesn't support data with an oblique angle acquisition yet. For rotated data, it is recommended to use the [QSMxT pipeline](https://qsmxt.github.io/QSMxT/) for susceptibility mapping, which applies TGV internally
-## Self contained example to test if everything works
+## Self contained example to test if package works
```julia
using QuantitativeSusceptibilityMappingTGV
@@ -120,7 +148,7 @@ The parallel CPU version is about twice as fast as the Cython version, the GPU v
## Run with other GPU types
-Other GPU types should be supported, however are only minimally tested.
+Other GPU types don't work with the command line script. They have to be accessed via Julia (or the command line script modified).
```julia
using AMDGPU
diff --git a/src/tgv.jl b/src/tgv.jl
index fdf8ab5..cfe401b 100644
--- a/src/tgv.jl
+++ b/src/tgv.jl
@@ -1,3 +1,12 @@
+"""
+qsm_tgv(phase, mask, res; TE, kwargs...)
+
+Optional arguments:
+
+Example:
+ chi = qsm_tgv(randn(20,20,20), trues(20,20,20), [1,1,2]; TE=0.025, fieldstrength=3)
+
+"""
function qsm_tgv(phase, mask, res; TE, B0_dir=[0, 0, 1], fieldstrength=3, regularization=2, alpha=get_default_alpha(regularization), step_size=3, iterations=get_default_iterations(res, step_size), erosions=3, dedimensionalize=false, correct_laplacian=true, laplacian=get_laplace_phase_del, type=Float32, gpu=CUDA.functional(), nblocks=32)
device, cu = select_device(gpu)
phase, res, alpha, fieldstrength, mask = adjust_types(type, phase, res, alpha, fieldstrength, mask)
@@ -176,7 +185,7 @@ function select_device(library::Module)
println("Using the GPU via Metal")
return library.MetalKernels.MetalBackend(), library.MtlArray
else
- println("Using $(Threads.nthreads()) CPU cores")
+ println("Using $(Threads.nthreads()) CPU threads")
return CPU(), identity
end
end
@@ -186,7 +195,7 @@ function select_device(gpu)
println("Using the GPU")
return CUDA.CUDAKernels.CUDABackend(), CUDA.cu
else
- println("Using $(Threads.nthreads()) CPU cores")
+ println("Using $(Threads.nthreads()) CPU threads")
return CPU(), identity
end
end
diff --git a/tgv_qsm.jl b/tgv_qsm.jl
new file mode 100644
index 0000000..c02defa
--- /dev/null
+++ b/tgv_qsm.jl
@@ -0,0 +1,37 @@
+#!/usr/bin/env -S julia --color=yes --startup-file=no --threads=auto
+
+## Usage
+
+# Call with: `/tgv_qsm.jl ARGS`
+# On windows use: `julia --threads=auto /tgv_qsm.jl ARGS`
+
+# Example call:
+# `./tgv_qsm.jl phase.nii.gz mask.nii.gz --TE 0.025 --output output.nii.gz --no-gpu
+
+import Pkg
+
+## Uncomment to use a local julia package directory instead of the global one
+# package_dir = joinpath(@__DIR__, ".tgv_cmd_packages")
+# mkpath(package_dir)
+# Pkg.activate(package_dir)
+
+try
+ using QuantitativeSusceptibilityMappingTGV, MriResearchTools, Comonicon
+catch
+ Pkg.add(["QuantitativeSusceptibilityMappingTGV", "MriResearchTools", "Comonicon"])
+ using QuantitativeSusceptibilityMappingTGV, MriResearchTools, Comonicon
+end
+
+version = Comonicon.get_version(QuantitativeSusceptibilityMappingTGV)
+Comonicon.get_version(::Module) = version
+
+@main function tgv_qsm(fn_phase, fn_mask; TE::Float64, output::String="output.nii.gz", fieldstrength::Float64=3.0, regularization::Float64=2.0, erosions::Int=3, B0_dir::Array{Int}=[0,0,1], dedimensionalize::Bool=false, no_laplacian_correction::Bool=false, step_size::Float64=3.0, no_gpu::Bool=false, type::DataType=Float32, nblocks::Int=32)
+ println("Starting calculation...")
+ phase = readphase(fn_phase)
+ mask = niread(fn_mask) .!= 0
+ res = header(phase).pixdim[2:4]
+ println("Resolution from NIfTI header [mm]: $(round.(Float64.(res); digits=2))")
+ chi = qsm_tgv(phase, mask, res; TE, B0_dir, fieldstrength, regularization, erosions, dedimensionalize, correct_laplacian=!no_laplacian_correction, gpu=!no_gpu, step_size, type, nblocks)
+ println("Writing output")
+ savenii(chi, output; header=header(phase))
+end