diff --git a/Makefile b/Makefile index 1f97711a0..126881b89 100644 --- a/Makefile +++ b/Makefile @@ -272,7 +272,7 @@ TNUM=fft fftmod fftshift noise bench threshold conv rss filter nlmeans mandelbro TRECO=pics pocsense sqpics itsense nlinv moba nufft nufftbase rof tgv ictv sake wave lrmatrix estdims estshift estdelay wavepsf wshfl rtnlinv mobafit grog TCALIB=ecalib ecaltwo caldir walsh cc ccapply rovir calmat svd estvar whiten rmfreq ssa bin psf ncalib TMRI=homodyne poisson twixread fakeksp looklocker upat fovshift -TSIM=phantom traj signal epg sim +TSIM=phantom traj signal epg sim raga TIO=toimg TNN=reconet nnet onehotenc measure mnist tensorflow nlinvnet TMOTION=affinereg interpolate estmotion @@ -312,6 +312,7 @@ MODULES_phantom = -lsimu -lgeom MODULES_bart = -lbox -lgrecon -lsense -lnoir -liter -llinops -lwavelet -llowrank -lnoncart -lcalib -lsimu -lsake -lnlops -lnetworks -lnoir -lnn -liter -lmoba -lgeom -lnn -lmotion -lnlops MODULES_sake = -lsake MODULES_traj = -lnoncart +MODULES_raga = -lnoncart MODULES_wave = -liter -lwavelet -llinops -llowrank MODULES_threshold = -llowrank -liter -llinops -lwavelet MODULES_fakeksp = -lsense -llinops diff --git a/src/raga.c b/src/raga.c new file mode 100644 index 000000000..959250441 --- /dev/null +++ b/src/raga.c @@ -0,0 +1,103 @@ +/* Copyright 2024. Institute for Biomedical Imaging. TU Graz. + * + * Authors: Nick Scholand + */ + +#include +#include +#include + +#include "num/flpmath.h" + +#include "num/multind.h" +#include "num/init.h" + +#include "misc/mmio.h" +#include "misc/misc.h" +#include "misc/mri.h" +#include "misc/opts.h" +#include "misc/debug.h" + +#include "noncart/traj.h" + +static const char help_str[] = "Generate file with RAGA indices for given approximated tiny golden ratio angle/raga increment and full frame spokes."; + + +int main_raga(int argc, char* argv[argc]) +{ + const char* out_file= NULL; + int Y; + + struct arg_s args[] = { + + ARG_INT(true, &Y, "spokes"), + ARG_OUTFILE(true, &out_file, "output"), + }; + + int raga_inc = 0; + int tiny_gold = 0; + bool double_base = true; + + const struct opt_s opts[] = { + + OPTL_INT('s', "tiny-angle", &tiny_gold, "# Tiny GA", "tiny (small) golden ratio angle"), + OPTL_INT('r', "raga-inc", &raga_inc, "d", "Increment of RAGA Sampling"), + OPTL_CLEAR(0, "no-double-base", &double_base, "Define GA over Pi base instead of 2Pi."), + }; + + cmdline(&argc, argv, ARRAY_SIZE(args), args, help_str, ARRAY_SIZE(opts), opts); + + num_init(); + + assert(0 < Y); + assert(raga_inc < Y); + + // Recover tiny golden angle from raga_inc if it was not passed + + if ((0 == tiny_gold) && (0 == raga_inc)) + tiny_gold = 1; + + assert((0 == Y % 2) || double_base); + + if ((0 == tiny_gold) && (0 != raga_inc)) + tiny_gold = recover_gen_fib_ind(Y / (double_base ? 1 : 2), raga_inc); + + if (-1 == tiny_gold) + error("Could not recover index of approximated golden ratio angle!\n"); + + if ((0 < tiny_gold) && (0 != raga_inc)) + assert(tiny_gold == recover_gen_fib_ind(Y / (double_base ? 1 : 2), raga_inc)); + + debug_printf(DP_INFO, "Golden Ratio Index is set to:\t%d\n", tiny_gold); + + assert(0 < tiny_gold); + + // Generate index file + + long dims[DIMS] = { [0 ... DIMS - 1] = 1 }; + dims[PHS2_DIM] = Y; + + complex float* indices = create_cfl(out_file, DIMS, dims); + md_clear(DIMS, dims, indices, CFL_SIZE); + + int p = 0; + long pos[DIMS] = { 0 }; + + do { + int j = pos[PHS2_DIM]; + + indices[p] = (j * raga_increment(Y / (double_base ? 1 : 2), tiny_gold)) % Y; + + p++; + + } while (md_next(DIMS, dims, ~1UL, pos)); + + assert(p == Y); + + unmap_cfl(DIMS, dims, indices); + + return 0; +} + + + diff --git a/tests/raga.mk b/tests/raga.mk new file mode 100644 index 000000000..0d47d309c --- /dev/null +++ b/tests/raga.mk @@ -0,0 +1,61 @@ + +tests/test-raga: raga extract vec transpose nrmse + set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ + $(TOOLDIR)/raga 377 i.ra ;\ + $(TOOLDIR)/extract 2 0 5 i.ra ie.ra ;\ + $(TOOLDIR)/vec 0 233 89 322 178 v.ra ;\ + $(TOOLDIR)/transpose 0 2 v.ra v2.ra ;\ + $(TOOLDIR)/nrmse -t 0. ie.ra v2.ra ;\ + rm *.ra ; cd .. ; rmdir $(TESTS_TMP) + touch $@ + +tests/test-raga-tiny: raga extract vec transpose nrmse + set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ + $(TOOLDIR)/raga -s 7 419 i.ra ;\ + $(TOOLDIR)/extract 2 0 5 i.ra ie.ra ;\ + $(TOOLDIR)/vec 0 55 110 165 220 v.ra ;\ + $(TOOLDIR)/transpose 0 2 v.ra v2.ra ;\ + $(TOOLDIR)/nrmse -t 0. ie.ra v2.ra ;\ + rm *.ra ; cd .. ; rmdir $(TESTS_TMP) + touch $@ + +tests/test-raga-inc: raga nrmse + set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ + $(TOOLDIR)/raga -r 55 419 i.ra ;\ + $(TOOLDIR)/raga -s 7 419 i2.ra ;\ + $(TOOLDIR)/nrmse -t 0. i.ra i2.ra ;\ + rm *.ra ; cd .. ; rmdir $(TESTS_TMP) + touch $@ + +tests/test-raga-single: raga extract vec transpose nrmse + set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ + $(TOOLDIR)/raga -s 7 --no-double-base 838 i.ra ;\ + $(TOOLDIR)/extract 2 0 5 i.ra ie.ra ;\ + $(TOOLDIR)/raga -s 7 419 i2.ra ;\ + $(TOOLDIR)/extract 2 0 5 i2.ra i2e.ra ;\ + $(TOOLDIR)/nrmse -t 0.000001 ie.ra i2e.ra ;\ + rm *.ra ; cd .. ; rmdir $(TESTS_TMP) + touch $@ + +TESTS += tests/test-raga tests/test-raga-tiny +TESTS += tests/test-raga-inc tests/test-raga-single + +# Depreciated Part! +tests/test-raga-old: raga traj nrmse + set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ + $(TOOLDIR)/raga 377 i.ra ;\ + $(TOOLDIR)/traj -y 377 -s 1 --double-base --raga-index-file i2.ra t.ra ;\ + $(TOOLDIR)/nrmse -t 0.000001 i.ra i2.ra ;\ + rm *.ra ; cd .. ; rmdir $(TESTS_TMP) + touch $@ + +tests/test-raga-old-tiny-single: raga traj nrmse + set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ + $(TOOLDIR)/raga --no-double-base -s 7 838 i.ra ;\ + $(TOOLDIR)/traj -y 838 -s 7 --raga-index-file i2.ra t.ra ;\ + $(TOOLDIR)/nrmse -t 0.000001 i.ra i2.ra ;\ + rm *.ra ; cd .. ; rmdir $(TESTS_TMP) + touch $@ + +TESTS += tests/test-raga-old tests/test-raga-old-tiny-single +